Format code using clang-format-5.0

Once merged, this repository will have CI enforce
the coding guidelines in the .clang-format file.

Change-Id: I96a05972665f9c67625c6850c3da25edc540be06
Signed-off-by: Andrew Geissler <geissonator@yahoo.com>
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..c246548
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,4 @@
+---
+Language:        JavaScript
+BasedOnStyle:    Google
+ColumnLimit:     80
diff --git a/app/common/directives/app-header.js b/app/common/directives/app-header.js
index 31f683c..d15697b 100644
--- a/app/common/directives/app-header.js
+++ b/app/common/directives/app-header.js
@@ -1,17 +1,18 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.common.directives')
-    .directive('appHeader', ['APIUtils', function(APIUtils) {
+  angular.module('app.common.directives').directive('appHeader', [
+    'APIUtils',
+    function(APIUtils) {
       return {
         'restrict': 'E',
         'template': require('./app-header.html'),
-        'scope': {
-          'path': '='
-        },
-        'controller': ['$rootScope', '$scope', 'dataService', 'userModel', '$location', '$route',
-          function($rootScope, $scope, dataService, userModel, $location, $route) {
+        'scope': {'path': '='},
+        'controller': [
+          '$rootScope', '$scope', 'dataService', 'userModel', '$location',
+          '$route',
+          function(
+              $rootScope, $scope, dataService, userModel, $location, $route) {
             $scope.dataService = dataService;
 
             $scope.loadServerHealth = function() {
@@ -24,19 +25,22 @@
               if (!userModel.isLoggedIn()) {
                 return;
               }
-              APIUtils.getHostState().then(function(status) {
-                if (status == 'xyz.openbmc_project.State.Host.HostState.Off') {
-                  dataService.setPowerOffState();
-                }
-                else if (status == 'xyz.openbmc_project.State.Host.HostState.Running') {
-                  dataService.setPowerOnState();
-                }
-                else {
-                  dataService.setErrorState();
-                }
-              }, function(error) {
-                dataService.activateErrorModal();
-              });
+              APIUtils.getHostState().then(
+                  function(status) {
+                    if (status ==
+                        'xyz.openbmc_project.State.Host.HostState.Off') {
+                      dataService.setPowerOffState();
+                    } else if (
+                        status ==
+                        'xyz.openbmc_project.State.Host.HostState.Running') {
+                      dataService.setPowerOnState();
+                    } else {
+                      dataService.setErrorState();
+                    }
+                  },
+                  function(error) {
+                    dataService.activateErrorModal();
+                  });
             };
 
             $scope.loadNetworkInfo = function() {
@@ -60,19 +64,19 @@
               userModel.logout(function(status, error) {
                 if (status) {
                   $location.path('/logout');
-                }
-                else {
+                } else {
                   console.log(error);
                 }
               });
             };
 
             $scope.refresh = function() {
-              //reload current page controllers and header
+              // reload current page controllers and header
               loadData();
               $route.reload();
-              //Add flash class to header timestamp on click of refresh
-              var myEl = angular.element(document.querySelector('.header__refresh'));
+              // Add flash class to header timestamp on click of refresh
+              var myEl =
+                  angular.element(document.querySelector('.header__refresh'));
               myEl.addClass('flash');
               setTimeout(function() {
                 myEl.removeClass('flash');
@@ -80,9 +84,10 @@
 
             };
 
-            var loginListener = $rootScope.$on('user-logged-in', function(event, arg) {
-              loadData();
-            });
+            var loginListener =
+                $rootScope.$on('user-logged-in', function(event, arg) {
+                  loadData();
+                });
 
             $scope.$on('$destroy', function() {
               loginListener();
@@ -94,5 +99,6 @@
           }
         ]
       };
-    }]);
+    }
+  ]);
 })(window.angular);
diff --git a/app/common/directives/app-navigation.js b/app/common/directives/app-navigation.js
index 80d09ec..c1272de 100644
--- a/app/common/directives/app-navigation.js
+++ b/app/common/directives/app-navigation.js
@@ -1,75 +1,67 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.common.directives')
-    .directive('appNavigation', function() {
-      return {
-        'restrict': 'E',
-        'template': require('./app-navigation.html'),
-        'scope': {
-          'path': '=',
-          'showNavigation': '='
-        },
-        'controller': ['$scope', '$location', 'dataService', function($scope, $location, dataService) {
-          $scope.dataService = dataService;
-          $scope.showSubMenu = false;
-          $scope.change = function(firstLevel) {
-            if (firstLevel != $scope.firstLevel) {
-              $scope.firstLevel = firstLevel;
-              $scope.showSubMenu = true;
-            }
-            else {
-              $scope.showSubMenu = !$scope.showSubMenu;
-            }
-          };
-          $scope.closeSubnav = function() {
-            $scope.showSubMenu = false;
-          };
-          $scope.$watch('path', function() {
-            var urlRoot = $location.path().split('/')[1];
-            if (urlRoot != '') {
-              $scope.firstLevel = urlRoot;
-            }
-            else {
-              $scope.firstLevel = 'overview';
-            }
-            $scope.showSubMenu = false;
-          });
-          $scope.$watch('showNavigation', function() {
-            var paddingTop = 0;
-            var urlRoot = $location.path().split('/')[1];
-            if (urlRoot != '') {
-              $scope.firstLevel = urlRoot;
-            }
-            else {
-              $scope.firstLevel = 'overview';
-            }
+  angular.module('app.common.directives')
+      .directive('appNavigation', function() {
+        return {
+          'restrict': 'E',
+          'template': require('./app-navigation.html'),
+          'scope': {'path': '=', 'showNavigation': '='},
+          'controller': [
+            '$scope', '$location', 'dataService',
+            function($scope, $location, dataService) {
+              $scope.dataService = dataService;
+              $scope.showSubMenu = false;
+              $scope.change = function(firstLevel) {
+                if (firstLevel != $scope.firstLevel) {
+                  $scope.firstLevel = firstLevel;
+                  $scope.showSubMenu = true;
+                } else {
+                  $scope.showSubMenu = !$scope.showSubMenu;
+                }
+              };
+              $scope.closeSubnav = function() {
+                $scope.showSubMenu = false;
+              };
+              $scope.$watch('path', function() {
+                var urlRoot = $location.path().split('/')[1];
+                if (urlRoot != '') {
+                  $scope.firstLevel = urlRoot;
+                } else {
+                  $scope.firstLevel = 'overview';
+                }
+                $scope.showSubMenu = false;
+              });
+              $scope.$watch('showNavigation', function() {
+                var paddingTop = 0;
+                var urlRoot = $location.path().split('/')[1];
+                if (urlRoot != '') {
+                  $scope.firstLevel = urlRoot;
+                } else {
+                  $scope.firstLevel = 'overview';
+                }
 
-            if ($scope.showNavigation) {
-              paddingTop = document.getElementById('header__wrapper').offsetHeight;
-            }
-            dataService.bodyStyle = {
-              'padding-top': paddingTop + 'px'
-            };
-            $scope.navStyle = {
-              'top': paddingTop + 'px'
-            };
-          });
-        }],
-        link: function(scope, element, attributes) {
-          var rawNavElement = angular.element(element)[0];
-          angular.element(window.document).bind('click', function(event) {
-            if (rawNavElement.contains(event.target))
-              return;
-
-            if (scope.showSubMenu) {
-              scope.$apply(function() {
-                scope.showSubMenu = false;
+                if ($scope.showNavigation) {
+                  paddingTop =
+                      document.getElementById('header__wrapper').offsetHeight;
+                }
+                dataService.bodyStyle = {'padding-top': paddingTop + 'px'};
+                $scope.navStyle = {'top': paddingTop + 'px'};
               });
             }
-          });
-        }
-      };
-    });
+          ],
+          link: function(scope, element, attributes) {
+            var rawNavElement = angular.element(element)[0];
+            angular.element(window.document).bind('click', function(event) {
+              if (rawNavElement.contains(event.target)) return;
+
+              if (scope.showSubMenu) {
+                scope.$apply(function() {
+                  scope.showSubMenu = false;
+                });
+              }
+            });
+          }
+        };
+      });
 })(window.angular);
diff --git a/app/common/directives/confirm.js b/app/common/directives/confirm.js
index a542783..b537905 100644
--- a/app/common/directives/confirm.js
+++ b/app/common/directives/confirm.js
@@ -1,44 +1,42 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.common.directives')
-    .directive('confirm', ['$timeout', function($timeout) {
+  angular.module('app.common.directives').directive('confirm', [
+    '$timeout',
+    function($timeout) {
       return {
         'restrict': 'E',
         'template': require('./confirm.html'),
-        'scope': {
-          'title': '@',
-          'message': '@',
-          'confirm': '=',
-          'callback': '='
-        },
-        'controller': ['$scope', function($scope) {
-          $scope.cancel = function() {
-            $scope.confirm = false;
-            $scope.$parent.confirm = false;
-          };
-          $scope.accept = function() {
-            $scope.callback();
-            $scope.cancel();
-          };
-        }],
+        'scope':
+            {'title': '@', 'message': '@', 'confirm': '=', 'callback': '='},
+        'controller': [
+          '$scope',
+          function($scope) {
+            $scope.cancel = function() {
+              $scope.confirm = false;
+              $scope.$parent.confirm = false;
+            };
+            $scope.accept = function() {
+              $scope.callback();
+              $scope.cancel();
+            };
+          }
+        ],
         link: function(scope, e) {
           scope.$watch('confirm', function() {
             if (scope.confirm) {
               $timeout(function() {
                 angular.element(e[0].parentNode).css({
-                  'min-height': e[0].querySelector('.inline__confirm').offsetHeight + 'px'
+                  'min-height':
+                      e[0].querySelector('.inline__confirm').offsetHeight + 'px'
                 });
               }, 0);
-            }
-            else {
-              angular.element(e[0].parentNode).css({
-                'min-height': 0 + 'px'
-              });
+            } else {
+              angular.element(e[0].parentNode).css({'min-height': 0 + 'px'});
             }
           });
         }
       };
-    }]);
+    }
+  ]);
 })(window.angular);
diff --git a/app/common/directives/errors.js b/app/common/directives/errors.js
index 8123694..5bd1e52 100644
--- a/app/common/directives/errors.js
+++ b/app/common/directives/errors.js
@@ -1,18 +1,20 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.common.directives')
-    .directive('errors', ['APIUtils', function(APIUtils) {
+  angular.module('app.common.directives').directive('errors', [
+    'APIUtils',
+    function(APIUtils) {
       return {
         'restrict': 'E',
         'template': require('./errors.html'),
-        'scope': {
-          'path': '='
-        },
-        'controller': ['$scope', 'dataService', function($scope, dataService) {
-          $scope.dataService = dataService;
-        }]
+        'scope': {'path': '='},
+        'controller': [
+          '$scope', 'dataService',
+          function($scope, dataService) {
+            $scope.dataService = dataService;
+          }
+        ]
       };
-    }]);
+    }
+  ]);
 })(window.angular);
diff --git a/app/common/directives/file.js b/app/common/directives/file.js
index 8ed6c2e..b0f5289 100644
--- a/app/common/directives/file.js
+++ b/app/common/directives/file.js
@@ -1,21 +1,17 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.common.directives')
-    .directive('file', function() {
-      return {
-        scope: {
-          file: '='
-        },
-        link: function(scope, el, attrs) {
-          el.bind('change', function(event) {
-            var file = event.target.files[0];
-            scope.file = file ? file : undefined;
-            scope.$apply();
-          });
-        }
-      };
-    });
+  angular.module('app.common.directives').directive('file', function() {
+    return {
+      scope: {file: '='},
+      link: function(scope, el, attrs) {
+        el.bind('change', function(event) {
+          var file = event.target.files[0];
+          scope.file = file ? file : undefined;
+          scope.$apply();
+        });
+      }
+    };
+  });
 
 })(window.angular);
diff --git a/app/common/directives/firmware-list.js b/app/common/directives/firmware-list.js
index 163df82..a08ef8d 100644
--- a/app/common/directives/firmware-list.js
+++ b/app/common/directives/firmware-list.js
@@ -1,32 +1,32 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.common.directives')
-    .directive('firmwareList', ['APIUtils', function(APIUtils) {
+  angular.module('app.common.directives').directive('firmwareList', [
+    'APIUtils',
+    function(APIUtils) {
       return {
         'restrict': 'E',
         'template': require('./firmware-list.html'),
-        'scope': {
-          'title': '@',
-          'firmwares': '=',
-          'filterBy': '=',
-          'version': '='
-        },
-        'controller': ['$rootScope', '$scope', 'dataService', '$location', '$timeout', function($rootScope, $scope, dataService, $location, $timeout) {
-          $scope.dataService = dataService;
-          $scope.activate = function(imageId, imageVersion, imageType) {
-            $scope.$parent.activateImage(imageId, imageVersion, imageType);
-          };
+        'scope':
+            {'title': '@', 'firmwares': '=', 'filterBy': '=', 'version': '='},
+        'controller': [
+          '$rootScope', '$scope', 'dataService', '$location', '$timeout',
+          function($rootScope, $scope, dataService, $location, $timeout) {
+            $scope.dataService = dataService;
+            $scope.activate = function(imageId, imageVersion, imageType) {
+              $scope.$parent.activateImage(imageId, imageVersion, imageType);
+            };
 
-          $scope.delete = function(imageId, imageVersion) {
-            $scope.$parent.deleteImage(imageId, imageVersion);
-          };
+            $scope.delete = function(imageId, imageVersion) {
+              $scope.$parent.deleteImage(imageId, imageVersion);
+            };
 
-          $scope.changePriority = function(imageId, imageVersion, from, to) {
-            $scope.$parent.changePriority(imageId, imageVersion, from, to);
-          };
-        }]
+            $scope.changePriority = function(imageId, imageVersion, from, to) {
+              $scope.$parent.changePriority(imageId, imageVersion, from, to);
+            };
+          }
+        ]
       };
-    }]);
+    }
+  ]);
 })(window.angular);
diff --git a/app/common/directives/index.js b/app/common/directives/index.js
index 33155f4..150b43f 100644
--- a/app/common/directives/index.js
+++ b/app/common/directives/index.js
@@ -1,9 +1,6 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.common.directives', [
-      'app.common.services'
-    ]);
+  angular.module('app.common.directives', ['app.common.services']);
 
 })(window.angular);
diff --git a/app/common/directives/loader.js b/app/common/directives/loader.js
index 8edc128..46fba9a 100644
--- a/app/common/directives/loader.js
+++ b/app/common/directives/loader.js
@@ -1,16 +1,12 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.common.directives')
-    .directive('loader', function() {
-      return {
-        'restrict': 'E',
-        'template': require('./loader.html'),
-        scope: {
-          loading: '='
-        }
-      };
-    });
+  angular.module('app.common.directives').directive('loader', function() {
+    return {
+      'restrict': 'E',
+      'template': require('./loader.html'),
+      scope: {loading: '='}
+    };
+  });
 
 })(window.angular);
diff --git a/app/common/directives/log-event.js b/app/common/directives/log-event.js
index c48a3ee..2a71164 100644
--- a/app/common/directives/log-event.js
+++ b/app/common/directives/log-event.js
@@ -1,43 +1,41 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.common.directives')
-    .directive('logEvent', ['APIUtils', function(APIUtils) {
+  angular.module('app.common.directives').directive('logEvent', [
+    'APIUtils',
+    function(APIUtils) {
       return {
         'restrict': 'E',
         'template': require('./log-event.html'),
-        'scope': {
-          'event': '=',
-          'tmz': '=',
-          'multiSelected': '='
-        },
-        'controller': ['$rootScope', '$scope', 'dataService', '$location', '$timeout', function($rootScope, $scope, dataService, $location, $timeout) {
-          $scope.dataService = dataService;
-          $scope.copySuccess = function(event) {
-            event.copied = true;
-            $timeout(function() {
-              event.copied = false;
-            }, 5000);
-          };
-          $scope.copyFailed = function(err) {
-            console.error('Error!', err);
-          };
-          $scope.resolveEvent = function(event) {
-            APIUtils.resolveLogs([{
-              Id: event.Id
-            }]).then(function() {
-              event.Resolved = 1;
-            });
-          };
+        'scope': {'event': '=', 'tmz': '=', 'multiSelected': '='},
+        'controller': [
+          '$rootScope', '$scope', 'dataService', '$location', '$timeout',
+          function($rootScope, $scope, dataService, $location, $timeout) {
+            $scope.dataService = dataService;
+            $scope.copySuccess = function(event) {
+              event.copied = true;
+              $timeout(function() {
+                event.copied = false;
+              }, 5000);
+            };
+            $scope.copyFailed = function(err) {
+              console.error('Error!', err);
+            };
+            $scope.resolveEvent = function(event) {
+              APIUtils.resolveLogs([{Id: event.Id}]).then(function() {
+                event.Resolved = 1;
+              });
+            };
 
-          $scope.accept = function() {
-            $scope.event.selected = true;
-            $timeout(function() {
-              $scope.$parent.accept();
-            }, 10);
-          };
-        }]
+            $scope.accept = function() {
+              $scope.event.selected = true;
+              $timeout(function() {
+                $scope.$parent.accept();
+              }, 10);
+            };
+          }
+        ]
       };
-    }]);
+    }
+  ]);
 })(window.angular);
diff --git a/app/common/directives/log-filter.js b/app/common/directives/log-filter.js
index 69bb8e3..fcbe0b3 100644
--- a/app/common/directives/log-filter.js
+++ b/app/common/directives/log-filter.js
@@ -1,51 +1,54 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.common.directives')
-    .directive('logFilter', ['APIUtils', function(APIUtils) {
+  angular.module('app.common.directives').directive('logFilter', [
+    'APIUtils',
+    function(APIUtils) {
       return {
         'restrict': 'E',
         'template': require('./log-filter.html'),
-        'controller': ['$rootScope', '$scope', 'dataService', '$location', function($rootScope, $scope, dataService, $location) {
-          $scope.dataService = dataService;
-          $scope.toggleSeverityAll = function() {
-            $scope.selectedSeverity.all = !$scope.selectedSeverity.all;
+        'controller': [
+          '$rootScope', '$scope', 'dataService', '$location',
+          function($rootScope, $scope, dataService, $location) {
+            $scope.dataService = dataService;
+            $scope.toggleSeverityAll = function() {
+              $scope.selectedSeverity.all = !$scope.selectedSeverity.all;
 
-            if ($scope.selectedSeverity.all) {
-              $scope.selectedSeverity.low = false;
-              $scope.selectedSeverity.medium = false;
-              $scope.selectedSeverity.high = false;
-            }
-          };
-
-          $scope.toggleSeverity = function(severity) {
-            $scope.selectedSeverity[severity] = !$scope.selectedSeverity[severity];
-
-            if (['high', 'medium', 'low'].indexOf(severity) > -1) {
-              if ($scope.selectedSeverity[severity] == false &&
-                (!$scope.selectedSeverity.low &&
-                  !$scope.selectedSeverity.medium &&
-                  !$scope.selectedSeverity.high
-                )) {
-                $scope.selectedSeverity.all = true;
-                return;
+              if ($scope.selectedSeverity.all) {
+                $scope.selectedSeverity.low = false;
+                $scope.selectedSeverity.medium = false;
+                $scope.selectedSeverity.high = false;
               }
-            }
+            };
 
-            if ($scope.selectedSeverity.low &&
-              $scope.selectedSeverity.medium &&
-              $scope.selectedSeverity.high) {
-              $scope.selectedSeverity.all = true;
-              $scope.selectedSeverity.low = false;
-              $scope.selectedSeverity.medium = false;
-              $scope.selectedSeverity.high = false;
-            }
-            else {
-              $scope.selectedSeverity.all = false;
-            }
-          };
-        }]
+            $scope.toggleSeverity = function(severity) {
+              $scope.selectedSeverity[severity] =
+                  !$scope.selectedSeverity[severity];
+
+              if (['high', 'medium', 'low'].indexOf(severity) > -1) {
+                if ($scope.selectedSeverity[severity] == false &&
+                    (!$scope.selectedSeverity.low &&
+                     !$scope.selectedSeverity.medium &&
+                     !$scope.selectedSeverity.high)) {
+                  $scope.selectedSeverity.all = true;
+                  return;
+                }
+              }
+
+              if ($scope.selectedSeverity.low &&
+                  $scope.selectedSeverity.medium &&
+                  $scope.selectedSeverity.high) {
+                $scope.selectedSeverity.all = true;
+                $scope.selectedSeverity.low = false;
+                $scope.selectedSeverity.medium = false;
+                $scope.selectedSeverity.high = false;
+              } else {
+                $scope.selectedSeverity.all = false;
+              }
+            };
+          }
+        ]
       };
-    }]);
+    }
+  ]);
 })(window.angular);
diff --git a/app/common/directives/log-search-control.js b/app/common/directives/log-search-control.js
index f262f5f..abdc9ff 100644
--- a/app/common/directives/log-search-control.js
+++ b/app/common/directives/log-search-control.js
@@ -1,46 +1,49 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.common.directives')
-    .directive('logSearchControl', ['APIUtils', function(APIUtils) {
+  angular.module('app.common.directives').directive('logSearchControl', [
+    'APIUtils',
+    function(APIUtils) {
       return {
         'restrict': 'E',
         'template': require('./log-search-control.html'),
-        'controller': ['$rootScope', '$scope', 'dataService', '$location', function($rootScope, $scope, dataService, $location) {
-          $scope.dataService = dataService;
-          $scope.doSearchOnEnter = function(event) {
-            var search = $scope.customSearch.replace(/^\s+/g, '').replace(/\s+$/g, '');
-            if (event.keyCode === 13 &&
-              search.length >= 2) {
-              $scope.clearSearchItem();
-              $scope.addSearchItem(search);
-            }
-            else {
-              if (search.length == 0) {
+        'controller': [
+          '$rootScope', '$scope', 'dataService', '$location',
+          function($rootScope, $scope, dataService, $location) {
+            $scope.dataService = dataService;
+            $scope.doSearchOnEnter = function(event) {
+              var search =
+                  $scope.customSearch.replace(/^\s+/g, '').replace(/\s+$/g, '');
+              if (event.keyCode === 13 && search.length >= 2) {
                 $scope.clearSearchItem();
+                $scope.addSearchItem(search);
+              } else {
+                if (search.length == 0) {
+                  $scope.clearSearchItem();
+                }
               }
-            }
-          };
+            };
 
-          $scope.clear = function() {
-            $scope.customSearch = '';
-            $scope.clearSearchItem();
-          };
-
-          $scope.doSearchOnClick = function() {
-            var search = $scope.customSearch.replace(/^\s+/g, '').replace(/\s+$/g, '');
-            if (search.length >= 2) {
+            $scope.clear = function() {
+              $scope.customSearch = '';
               $scope.clearSearchItem();
-              $scope.addSearchItem(search);
-            }
-            else {
-              if (search.length == 0) {
+            };
+
+            $scope.doSearchOnClick = function() {
+              var search =
+                  $scope.customSearch.replace(/^\s+/g, '').replace(/\s+$/g, '');
+              if (search.length >= 2) {
                 $scope.clearSearchItem();
+                $scope.addSearchItem(search);
+              } else {
+                if (search.length == 0) {
+                  $scope.clearSearchItem();
+                }
               }
-            }
-          };
-        }]
+            };
+          }
+        ]
       };
-    }]);
+    }
+  ]);
 })(window.angular);
diff --git a/app/common/directives/toggle-flag.js b/app/common/directives/toggle-flag.js
index 4a4e454..0869af3 100644
--- a/app/common/directives/toggle-flag.js
+++ b/app/common/directives/toggle-flag.js
@@ -1,31 +1,30 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.common.directives')
-    .directive('toggleFlag', function($document) {
-      return {
-        restrict: 'A',
-        link: function(scope, element, attrs) {
+  angular.module('app.common.directives')
+      .directive('toggleFlag', function($document) {
+        return {
+          restrict: 'A',
+          link: function(scope, element, attrs) {
 
-          function elementClick(e) {
-            e.stopPropagation();
+            function elementClick(e) {
+              e.stopPropagation();
+            }
+
+            function documentClick(e) {
+              scope[attrs.toggleFlag] = false;
+              scope.$apply();
+            }
+
+            element.on('click', elementClick);
+            $document.on('click', documentClick);
+
+            // remove event handlers when directive is destroyed
+            scope.$on('$destroy', function() {
+              element.off('click', elementClick);
+              $document.off('click', documentClick);
+            });
           }
-
-          function documentClick(e) {
-            scope[attrs.toggleFlag] = false;
-            scope.$apply();
-          }
-
-          element.on('click', elementClick);
-          $document.on('click', documentClick);
-
-          // remove event handlers when directive is destroyed
-          scope.$on('$destroy', function() {
-            element.off('click', elementClick);
-            $document.off('click', documentClick);
-          });
-        }
-      };
-    });
+        };
+      });
 })(window.angular);
diff --git a/app/common/filters/index.js b/app/common/filters/index.js
index f3de907..743bd4e 100644
--- a/app/common/filters/index.js
+++ b/app/common/filters/index.js
@@ -1,25 +1,25 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.common.filters', [])
-    .filter('unResolvedCount', function() {
-      return function(data) {
-        data = data.filter(function(item) {
-          return item.Resolved == 0;
-        });
-        return data.length;
-      }
-    })
-    .filter('quiescedToError', function() {
-      return function(state) {
-        if (state.toLowerCase() == 'quiesced') {
-          return 'Error';
+  angular.module('app.common.filters', [])
+      .filter(
+          'unResolvedCount',
+          function() {
+            return function(data) {
+              data = data.filter(function(item) {
+                return item.Resolved == 0;
+              });
+              return data.length;
+            }
+          })
+      .filter('quiescedToError', function() {
+        return function(state) {
+          if (state.toLowerCase() == 'quiesced') {
+            return 'Error';
+          } else {
+            return state;
+          }
         }
-        else {
-          return state;
-        }
-      }
-    });
+      });
 
 })(window.angular);
diff --git a/app/common/services/api-utils.js b/app/common/services/api-utils.js
index a024142..7354385 100644
--- a/app/common/services/api-utils.js
+++ b/app/common/services/api-utils.js
@@ -8,9 +8,9 @@
 
 window.angular && (function(angular) {
   'use strict';
-  angular
-    .module('app.common.services')
-    .factory('APIUtils', ['$http', 'Constants', '$q', 'dataService', function($http, Constants, $q, DataService) {
+  angular.module('app.common.services').factory('APIUtils', [
+    '$http', 'Constants', '$q', 'dataService',
+    function($http, Constants, $q, DataService) {
       var getScaledValue = function(value, scale) {
         scale = scale + '';
         scale = parseInt(scale, 10);
@@ -18,8 +18,7 @@
 
         if (scale > 0) {
           value = value * Math.pow(10, power);
-        }
-        else if (scale < 0) {
+        } else if (scale < 0) {
           value = value / Math.pow(10, power);
         }
         return value;
@@ -37,155 +36,175 @@
           var deferred = $q.defer();
           $http({
             method: 'GET',
-            url: DataService.getHost() + '/xyz/openbmc_project/state/chassis0/attr/CurrentPowerState',
+            url: DataService.getHost() +
+                '/xyz/openbmc_project/state/chassis0/attr/CurrentPowerState',
             headers: {
               'Accept': 'application/json',
               'Content-Type': 'application/json'
             },
             withCredentials: true
-          }).then(function(response) {
-            var json = JSON.stringify(response.data);
-            var content = JSON.parse(json);
-            deferred.resolve(content.data);
-          }, function(error) {
-            console.log(error);
-            deferred.reject(error);
-          });
+          })
+              .then(
+                  function(response) {
+                    var json = JSON.stringify(response.data);
+                    var content = JSON.parse(json);
+                    deferred.resolve(content.data);
+                  },
+                  function(error) {
+                    console.log(error);
+                    deferred.reject(error);
+                  });
           return deferred.promise;
         },
         getHostState: function() {
           var deferred = $q.defer();
           $http({
             method: 'GET',
-            url: DataService.getHost() + '/xyz/openbmc_project/state/host0/attr/CurrentHostState',
+            url: DataService.getHost() +
+                '/xyz/openbmc_project/state/host0/attr/CurrentHostState',
             headers: {
               'Accept': 'application/json',
               'Content-Type': 'application/json'
             },
             withCredentials: true
-          }).then(function(response) {
-            var json = JSON.stringify(response.data);
-            var content = JSON.parse(json);
-            deferred.resolve(content.data);
-          }, function(error) {
-            console.log(error);
-            deferred.reject(error);
-          });
+          })
+              .then(
+                  function(response) {
+                    var json = JSON.stringify(response.data);
+                    var content = JSON.parse(json);
+                    deferred.resolve(content.data);
+                  },
+                  function(error) {
+                    console.log(error);
+                    deferred.reject(error);
+                  });
           return deferred.promise;
         },
         getNetworkInfo: function() {
           var deferred = $q.defer();
           $http({
             method: 'GET',
-            url: DataService.getHost() + '/xyz/openbmc_project/network/enumerate',
+            url: DataService.getHost() +
+                '/xyz/openbmc_project/network/enumerate',
             headers: {
               'Accept': 'application/json',
               'Content-Type': 'application/json'
             },
             withCredentials: true
-          }).then(function(response) {
-            var json = JSON.stringify(response.data);
-            var content = JSON.parse(json);
-            var hostname = '';
-            var macAddress = '';
+          })
+              .then(
+                  function(response) {
+                    var json = JSON.stringify(response.data);
+                    var content = JSON.parse(json);
+                    var hostname = '';
+                    var macAddress = '';
 
-            function parseNetworkData(content) {
-              var data = {
-                interface_ids: [],
-                interfaces: {},
-                ip_addresses: {
-                  ipv4: [],
-                  ipv6: []
-                },
-              };
-              var interfaceId = '',
-                keyParts = [],
-                interfaceHash = '',
-                interfaceType = '';
-              for (var key in content.data) {
-                if (key.match(/network\/eth\d+$/ig)) {
-                  interfaceId = key.split('/').pop();
-                  if (data.interface_ids.indexOf(interfaceId) == -1) {
-                    data.interface_ids.push(interfaceId);
-                    data.interfaces[interfaceId] = {
-                      interfaceIname: '',
-                      DomainName: '',
-                      MACAddress: '',
-                      Nameservers: [],
-                      DHCPEnabled: 0,
-                      ipv4: {
-                        ids: [],
-                        values: []
-                      },
-                      ipv6: {
-                        ids: [],
-                        values: []
+                    function parseNetworkData(content) {
+                      var data = {
+                        interface_ids: [],
+                        interfaces: {},
+                        ip_addresses: {ipv4: [], ipv6: []},
+                      };
+                      var interfaceId = '', keyParts = [], interfaceHash = '',
+                          interfaceType = '';
+                      for (var key in content.data) {
+                        if (key.match(/network\/eth\d+$/ig)) {
+                          interfaceId = key.split('/').pop();
+                          if (data.interface_ids.indexOf(interfaceId) == -1) {
+                            data.interface_ids.push(interfaceId);
+                            data.interfaces[interfaceId] = {
+                              interfaceIname: '',
+                              DomainName: '',
+                              MACAddress: '',
+                              Nameservers: [],
+                              DHCPEnabled: 0,
+                              ipv4: {ids: [], values: []},
+                              ipv6: {ids: [], values: []}
+                            };
+                            data.interfaces[interfaceId].MACAddress =
+                                content.data[key].MACAddress;
+                            data.interfaces[interfaceId].DomainName =
+                                content.data[key].DomainName.join(' ');
+                            data.interfaces[interfaceId].Nameservers =
+                                content.data[key].Nameservers;
+                            data.interfaces[interfaceId].DHCPEnabled =
+                                content.data[key].DHCPEnabled;
+                          }
+                        } else if (
+                            key.match(
+                                /network\/eth\d+\/ipv[4|6]\/[a-z0-9]+$/ig)) {
+                          keyParts = key.split('/');
+                          interfaceHash = keyParts.pop();
+                          interfaceType = keyParts.pop();
+                          interfaceId = keyParts.pop();
+
+                          if (data.interfaces[interfaceId][interfaceType]
+                                  .ids.indexOf(interfaceHash) == -1) {
+                            data.interfaces[interfaceId][interfaceType]
+                                .ids.push(interfaceHash);
+                            data.interfaces[interfaceId][interfaceType]
+                                .values.push(content.data[key]);
+                            data.ip_addresses[interfaceType].push(
+                                content.data[key]['Address']);
+                          }
+                        }
                       }
-                    };
-                    data.interfaces[interfaceId].MACAddress = content.data[key].MACAddress;
-                    data.interfaces[interfaceId].DomainName = content.data[key].DomainName.join(' ');
-                    data.interfaces[interfaceId].Nameservers = content.data[key].Nameservers;
-                    data.interfaces[interfaceId].DHCPEnabled = content.data[key].DHCPEnabled;
-                  }
-                }
-                else if (key.match(/network\/eth\d+\/ipv[4|6]\/[a-z0-9]+$/ig)) {
-                  keyParts = key.split('/');
-                  interfaceHash = keyParts.pop();
-                  interfaceType = keyParts.pop();
-                  interfaceId = keyParts.pop();
+                      return data;
+                    }
 
-                  if (data.interfaces[interfaceId][interfaceType].ids.indexOf(interfaceHash) == -1) {
-                    data.interfaces[interfaceId][interfaceType].ids.push(interfaceHash);
-                    data.interfaces[interfaceId][interfaceType].values.push(content.data[key]);
-                    data.ip_addresses[interfaceType].push(content.data[key]['Address']);
-                  }
-                }
-              }
-              return data;
-            }
+                    if (content.data.hasOwnProperty(
+                            '/xyz/openbmc_project/network/config') &&
+                        content.data['/xyz/openbmc_project/network/config']
+                            .hasOwnProperty('HostName')) {
+                      hostname =
+                          content.data['/xyz/openbmc_project/network/config']
+                              .HostName;
+                    }
 
-            if (content.data.hasOwnProperty('/xyz/openbmc_project/network/config') &&
-              content.data['/xyz/openbmc_project/network/config'].hasOwnProperty('HostName')
-            ) {
-              hostname = content.data['/xyz/openbmc_project/network/config'].HostName;
-            }
+                    if (content.data.hasOwnProperty(
+                            '/xyz/openbmc_project/network/eth0') &&
+                        content.data['/xyz/openbmc_project/network/eth0']
+                            .hasOwnProperty('MACAddress')) {
+                      macAddress =
+                          content.data['/xyz/openbmc_project/network/eth0']
+                              .MACAddress;
+                    }
 
-            if (content.data.hasOwnProperty('/xyz/openbmc_project/network/eth0') &&
-              content.data['/xyz/openbmc_project/network/eth0'].hasOwnProperty('MACAddress')
-            ) {
-              macAddress = content.data['/xyz/openbmc_project/network/eth0'].MACAddress;
-            }
-
-            deferred.resolve({
-              data: content.data,
-              hostname: hostname,
-              mac_address: macAddress,
-              formatted_data: parseNetworkData(content)
-            });
-          }, function(error) {
-            console.log(error);
-            deferred.reject(error);
-          });
+                    deferred.resolve({
+                      data: content.data,
+                      hostname: hostname,
+                      mac_address: macAddress,
+                      formatted_data: parseNetworkData(content)
+                    });
+                  },
+                  function(error) {
+                    console.log(error);
+                    deferred.reject(error);
+                  });
           return deferred.promise;
         },
         getLEDState: function() {
           var deferred = $q.defer();
           $http({
             method: 'GET',
-            url: DataService.getHost() + '/xyz/openbmc_project/led/groups/enclosure_identify',
+            url: DataService.getHost() +
+                '/xyz/openbmc_project/led/groups/enclosure_identify',
             headers: {
               'Accept': 'application/json',
               'Content-Type': 'application/json'
             },
             withCredentials: true
-          }).then(function(response) {
-            var json = JSON.stringify(response.data);
-            var content = JSON.parse(json);
-            deferred.resolve(content.data.Asserted);
-          }, function(error) {
-            console.log(error);
-            deferred.reject(error);
-          });
+          })
+              .then(
+                  function(response) {
+                    var json = JSON.stringify(response.data);
+                    var content = JSON.parse(json);
+                    deferred.resolve(content.data.Asserted);
+                  },
+                  function(error) {
+                    console.log(error);
+                    deferred.reject(error);
+                  });
           return deferred.promise;
         },
         login: function(username, password, callback) {
@@ -197,43 +216,42 @@
               'Content-Type': 'application/json'
             },
             withCredentials: true,
-            data: JSON.stringify({
-              'data': [username, password]
-            })
-          }).then(function(response) {
-            if (callback) {
-              callback(response.data);
-            }
-          }, function(error) {
-            if (callback) {
-              if (error && error.status && error.status == 'error') {
-                callback(error);
-              }
-              else {
-                callback(error, true);
-              }
-            }
-            console.log(error);
-          });
+            data: JSON.stringify({'data': [username, password]})
+          })
+              .then(
+                  function(response) {
+                    if (callback) {
+                      callback(response.data);
+                    }
+                  },
+                  function(error) {
+                    if (callback) {
+                      if (error && error.status && error.status == 'error') {
+                        callback(error);
+                      } else {
+                        callback(error, true);
+                      }
+                    }
+                    console.log(error);
+                  });
         },
         testPassword: function(username, password) {
-          // Calls /login without the current session to verify the given password is correct
-          // ignore the interceptor logout on a bad password
+          // Calls /login without the current session to verify the given
+          // password is correct ignore the interceptor logout on a bad password
           DataService.ignoreHttpError = true;
           return $http({
-            method: 'POST',
-            url: DataService.getHost() + '/login',
-            headers: {
-              'Accept': 'application/json',
-              'Content-Type': 'application/json'
-            },
-            withCredentials: false,
-            data: JSON.stringify({
-              'data': [username, password]
-            })
-          }).then(function(response) {
-            return response.data;
-          });
+                   method: 'POST',
+                   url: DataService.getHost() + '/login',
+                   headers: {
+                     'Accept': 'application/json',
+                     'Content-Type': 'application/json'
+                   },
+                   withCredentials: false,
+                   data: JSON.stringify({'data': [username, password]})
+                 })
+              .then(function(response) {
+                return response.data;
+              });
         },
         logout: function(callback) {
           $http({
@@ -244,44 +262,44 @@
               'Content-Type': 'application/json'
             },
             withCredentials: true,
-            data: JSON.stringify({
-              'data': []
-            })
-          }).then(function(response) {
-            if (callback) {
-              callback(response.data);
-            }
-          }, function(error) {
-            if (callback) {
-              callback(null, error);
-            }
-            console.log(error);
-          });
+            data: JSON.stringify({'data': []})
+          })
+              .then(
+                  function(response) {
+                    if (callback) {
+                      callback(response.data);
+                    }
+                  },
+                  function(error) {
+                    if (callback) {
+                      callback(null, error);
+                    }
+                    console.log(error);
+                  });
         },
         changePassword: function(user, newPassword) {
           var deferred = $q.defer();
           $http({
             method: 'POST',
-            url: DataService.getHost() + '/xyz/openbmc_project/user/' + user + '/action/SetPassword',
+            url: DataService.getHost() + '/xyz/openbmc_project/user/' + user +
+                '/action/SetPassword',
             headers: {
               'Accept': 'application/json',
               'Content-Type': 'application/json'
             },
             withCredentials: true,
-            data: JSON.stringify({
-              'data': [newPassword]
-            }),
+            data: JSON.stringify({'data': [newPassword]}),
             responseType: 'arraybuffer'
-          }).then(function(response, status, headers) {
-            deferred.resolve({
-              data: response,
-              status: status,
-              headers: headers
-            });
-          }, function(error) {
-            console.log(error);
-            deferred.reject(error);
-          });
+          })
+              .then(
+                  function(response, status, headers) {
+                    deferred.resolve(
+                        {data: response, status: status, headers: headers});
+                  },
+                  function(error) {
+                    console.log(error);
+                    deferred.reject(error);
+                  });
           return deferred.promise;
         },
         chassisPowerOn: function(callback) {
@@ -293,168 +311,183 @@
               'Content-Type': 'application/json'
             },
             withCredentials: true,
-            data: JSON.stringify({
-              'data': []
-            })
-          }).then(function(response) {
-            var json = JSON.stringify(response.data);
-            var content = JSON.parse(json);
-            if (callback) {
-              return callback(content.data.CurrentPowerState);
-            }
-          }, function(error) {
-            if (callback) {
-              callback(error);
-            }
-            else {
-              console.log(error);
-            }
-          });
+            data: JSON.stringify({'data': []})
+          })
+              .then(
+                  function(response) {
+                    var json = JSON.stringify(response.data);
+                    var content = JSON.parse(json);
+                    if (callback) {
+                      return callback(content.data.CurrentPowerState);
+                    }
+                  },
+                  function(error) {
+                    if (callback) {
+                      callback(error);
+                    } else {
+                      console.log(error);
+                    }
+                  });
         },
         chassisPowerOff: function() {
           var deferred = $q.defer();
           $http({
             method: 'PUT',
-            url: DataService.getHost() + '/xyz/openbmc_project/state/chassis0/attr/RequestedPowerTransition',
+            url: DataService.getHost() +
+                '/xyz/openbmc_project/state/chassis0/attr/RequestedPowerTransition',
             headers: {
               'Accept': 'application/json',
               'Content-Type': 'application/json'
             },
             withCredentials: true,
-            data: JSON.stringify({
-              'data': 'xyz.openbmc_project.State.Chassis.Transition.Off'
-            })
-          }).then(function(response) {
-            var json = JSON.stringify(response.data);
-            var content = JSON.parse(json);
-            deferred.resolve(content.status);
-          }, function(error) {
-            console.log(error);
-            deferred.reject(error);
-          });
+            data: JSON.stringify(
+                {'data': 'xyz.openbmc_project.State.Chassis.Transition.Off'})
+          })
+              .then(
+                  function(response) {
+                    var json = JSON.stringify(response.data);
+                    var content = JSON.parse(json);
+                    deferred.resolve(content.status);
+                  },
+                  function(error) {
+                    console.log(error);
+                    deferred.reject(error);
+                  });
           return deferred.promise;
         },
         setLEDState: function(state, callback) {
           $http({
             method: 'PUT',
-            url: DataService.getHost() + '/xyz/openbmc_project/led/groups/enclosure_identify/attr/Asserted',
+            url: DataService.getHost() +
+                '/xyz/openbmc_project/led/groups/enclosure_identify/attr/Asserted',
             headers: {
               'Accept': 'application/json',
               'Content-Type': 'application/json'
             },
             withCredentials: true,
-            data: JSON.stringify({
-              'data': state
-            })
-          }).then(function(response) {
-            var json = JSON.stringify(response.data);
-            var content = JSON.parse(json);
-            if (callback) {
-              return callback(content.status);
-            }
-          }, function(error) {
-            if (callback) {
-              callback(error);
-            }
-            else {
-              console.log(error);
-            }
-          });
+            data: JSON.stringify({'data': state})
+          })
+              .then(
+                  function(response) {
+                    var json = JSON.stringify(response.data);
+                    var content = JSON.parse(json);
+                    if (callback) {
+                      return callback(content.status);
+                    }
+                  },
+                  function(error) {
+                    if (callback) {
+                      callback(error);
+                    } else {
+                      console.log(error);
+                    }
+                  });
         },
         bmcReboot: function(callback) {
           $http({
             method: 'PUT',
-            url: DataService.getHost() + '/xyz/openbmc_project/state/bmc0/attr/RequestedBmcTransition',
+            url: DataService.getHost() +
+                '/xyz/openbmc_project/state/bmc0/attr/RequestedBmcTransition',
             headers: {
               'Accept': 'application/json',
               'Content-Type': 'application/json'
             },
             withCredentials: true,
-            data: JSON.stringify({
-              'data': 'xyz.openbmc_project.State.BMC.Transition.Reboot'
-            })
-          }).then(function(response) {
-            var json = JSON.stringify(response.data);
-            var content = JSON.parse(json);
-            if (callback) {
-              return callback(content.status);
-            }
-          }, function(error) {
-            if (callback) {
-              callback(error);
-            }
-            else {
-              console.log(error);
-            }
-          });
+            data: JSON.stringify(
+                {'data': 'xyz.openbmc_project.State.BMC.Transition.Reboot'})
+          })
+              .then(
+                  function(response) {
+                    var json = JSON.stringify(response.data);
+                    var content = JSON.parse(json);
+                    if (callback) {
+                      return callback(content.status);
+                    }
+                  },
+                  function(error) {
+                    if (callback) {
+                      callback(error);
+                    } else {
+                      console.log(error);
+                    }
+                  });
         },
         hostPowerOn: function() {
           var deferred = $q.defer();
           $http({
             method: 'PUT',
-            url: DataService.getHost() + '/xyz/openbmc_project/state/host0/attr/RequestedHostTransition',
+            url: DataService.getHost() +
+                '/xyz/openbmc_project/state/host0/attr/RequestedHostTransition',
             headers: {
               'Accept': 'application/json',
               'Content-Type': 'application/json'
             },
             withCredentials: true,
-            data: JSON.stringify({
-              'data': 'xyz.openbmc_project.State.Host.Transition.On'
-            })
-          }).then(function(response) {
-            var json = JSON.stringify(response.data);
-            var content = JSON.parse(json);
-            deferred.resolve(content.status);
-          }, function(error) {
-            console.log(error);
-            deferred.reject(error);
-          });
+            data: JSON.stringify(
+                {'data': 'xyz.openbmc_project.State.Host.Transition.On'})
+          })
+              .then(
+                  function(response) {
+                    var json = JSON.stringify(response.data);
+                    var content = JSON.parse(json);
+                    deferred.resolve(content.status);
+                  },
+                  function(error) {
+                    console.log(error);
+                    deferred.reject(error);
+                  });
           return deferred.promise;
         },
         hostPowerOff: function() {
           var deferred = $q.defer();
           $http({
             method: 'PUT',
-            url: DataService.getHost() + '/xyz/openbmc_project/state/host0/attr/RequestedHostTransition',
+            url: DataService.getHost() +
+                '/xyz/openbmc_project/state/host0/attr/RequestedHostTransition',
             headers: {
               'Accept': 'application/json',
               'Content-Type': 'application/json'
             },
             withCredentials: true,
-            data: JSON.stringify({
-              'data': 'xyz.openbmc_project.State.Host.Transition.Off'
-            })
-          }).then(function(response) {
-            var json = JSON.stringify(response.data);
-            var content = JSON.parse(json);
-            deferred.resolve(content.status);
-          }, function(error) {
-            console.log(error);
-            deferred.reject(error);
-          });
+            data: JSON.stringify(
+                {'data': 'xyz.openbmc_project.State.Host.Transition.Off'})
+          })
+              .then(
+                  function(response) {
+                    var json = JSON.stringify(response.data);
+                    var content = JSON.parse(json);
+                    deferred.resolve(content.status);
+                  },
+                  function(error) {
+                    console.log(error);
+                    deferred.reject(error);
+                  });
           return deferred.promise;
         },
         hostReboot: function() {
           var deferred = $q.defer();
           $http({
             method: 'PUT',
-            url: DataService.getHost() + '/xyz/openbmc_project/state/host0/attr/RequestedHostTransition',
+            url: DataService.getHost() +
+                '/xyz/openbmc_project/state/host0/attr/RequestedHostTransition',
             headers: {
               'Accept': 'application/json',
               'Content-Type': 'application/json'
             },
             withCredentials: true,
-            data: JSON.stringify({
-              'data': 'xyz.openbmc_project.State.Host.Transition.Reboot'
-            })
-          }).then(function(response) {
-            var json = JSON.stringify(response.data);
-            var content = JSON.parse(json);
-            deferred.resolve(content.status);
-          }, function(error) {
-            console.log(error);
-            deferred.reject(error);
-          });
+            data: JSON.stringify(
+                {'data': 'xyz.openbmc_project.State.Host.Transition.Reboot'})
+          })
+              .then(
+                  function(response) {
+                    var json = JSON.stringify(response.data);
+                    var content = JSON.parse(json);
+                    deferred.resolve(content.status);
+                  },
+                  function(error) {
+                    console.log(error);
+                    deferred.reject(error);
+                  });
 
           return deferred.promise;
         },
@@ -467,350 +500,391 @@
               'Content-Type': 'application/json'
             },
             withCredentials: true,
-            data: JSON.stringify({
-              'data': []
-            })
-          }).then(function(response) {
-            var json = JSON.stringify(response.data);
-            var content = JSON.parse(json);
-            if (callback) {
-              return callback(content);
-            }
-          }, function(error) {
-            if (callback) {
-              callback(error);
-            }
-            else {
-              console.log(error);
-            }
-          });
+            data: JSON.stringify({'data': []})
+          })
+              .then(
+                  function(response) {
+                    var json = JSON.stringify(response.data);
+                    var content = JSON.parse(json);
+                    if (callback) {
+                      return callback(content);
+                    }
+                  },
+                  function(error) {
+                    if (callback) {
+                      callback(error);
+                    } else {
+                      console.log(error);
+                    }
+                  });
         },
         getLogs: function() {
           var deferred = $q.defer();
           $http({
             method: 'GET',
-            url: DataService.getHost() + '/xyz/openbmc_project/logging/enumerate',
+            url: DataService.getHost() +
+                '/xyz/openbmc_project/logging/enumerate',
             headers: {
               'Accept': 'application/json',
               'Content-Type': 'application/json'
             },
             withCredentials: true
-          }).then(function(response) {
-            var json = JSON.stringify(response.data);
-            var content = JSON.parse(json);
-            var dataClone = JSON.parse(JSON.stringify(content.data));
-            var data = [];
-            var severityCode = '';
-            var priority = '';
-            var health = '';
-            var relatedItems = [];
+          })
+              .then(
+                  function(response) {
+                    var json = JSON.stringify(response.data);
+                    var content = JSON.parse(json);
+                    var dataClone = JSON.parse(JSON.stringify(content.data));
+                    var data = [];
+                    var severityCode = '';
+                    var priority = '';
+                    var health = '';
+                    var relatedItems = [];
 
-            for (var key in content.data) {
-              if (content.data.hasOwnProperty(key) && content.data[key].hasOwnProperty('Id')) {
-                var severityFlags = {
-                  low: false,
-                  medium: false,
-                  high: false
-                };
-                var healthFlags = {
-                  critical: false,
-                  warning: false,
-                  good: false
-                };
-                severityCode = content.data[key].Severity.split('.').pop();
-                priority = Constants.SEVERITY_TO_PRIORITY_MAP[severityCode];
-                severityFlags[priority.toLowerCase()] = true;
-                health = Constants.SEVERITY_TO_HEALTH_MAP[severityCode];
-                healthFlags[health.toLowerCase()] = true;
-                relatedItems = [];
-                content.data[key].associations.forEach(function(item) {
-                  relatedItems.push(item[2]);
-                });
+                    for (var key in content.data) {
+                      if (content.data.hasOwnProperty(key) &&
+                          content.data[key].hasOwnProperty('Id')) {
+                        var severityFlags = {
+                          low: false,
+                          medium: false,
+                          high: false
+                        };
+                        var healthFlags = {
+                          critical: false,
+                          warning: false,
+                          good: false
+                        };
+                        severityCode =
+                            content.data[key].Severity.split('.').pop();
+                        priority =
+                            Constants.SEVERITY_TO_PRIORITY_MAP[severityCode];
+                        severityFlags[priority.toLowerCase()] = true;
+                        health = Constants.SEVERITY_TO_HEALTH_MAP[severityCode];
+                        healthFlags[health.toLowerCase()] = true;
+                        relatedItems = [];
+                        content.data[key].associations.forEach(function(item) {
+                          relatedItems.push(item[2]);
+                        });
 
-                data.push(Object.assign({
-                  path: key,
-                  copied: false,
-                  priority: priority,
-                  severity_code: severityCode,
-                  severity_flags: severityFlags,
-                  health_flags: healthFlags,
-                  additional_data: content.data[key].AdditionalData.join('\n'),
-                  type: content.data[key].Message,
-                  selected: false,
-                  search_text: ('#' + content.data[key].Id + ' ' + severityCode + ' ' + content.data[key].Severity + ' ' + content.data[key].AdditionalData.join(' ')).toLowerCase(),
-                  meta: false,
-                  confirm: false,
-                  related_items: relatedItems,
-                  data: {
-                    key: key,
-                    value: content.data[key]
-                  }
-                }, content.data[key]));
-              }
-            }
-            deferred.resolve({
-              data: data,
-              original: dataClone
-            });
-          }, function(error) {
-            console.log(error);
-            deferred.reject(error);
-          });
+                        data.push(Object.assign(
+                            {
+                              path: key,
+                              copied: false,
+                              priority: priority,
+                              severity_code: severityCode,
+                              severity_flags: severityFlags,
+                              health_flags: healthFlags,
+                              additional_data:
+                                  content.data[key].AdditionalData.join('\n'),
+                              type: content.data[key].Message,
+                              selected: false,
+                              search_text:
+                                  ('#' + content.data[key].Id + ' ' +
+                                   severityCode + ' ' +
+                                   content.data[key].Severity + ' ' +
+                                   content.data[key].AdditionalData.join(' '))
+                                      .toLowerCase(),
+                              meta: false,
+                              confirm: false,
+                              related_items: relatedItems,
+                              data: {key: key, value: content.data[key]}
+                            },
+                            content.data[key]));
+                      }
+                    }
+                    deferred.resolve({data: data, original: dataClone});
+                  },
+                  function(error) {
+                    console.log(error);
+                    deferred.reject(error);
+                  });
 
           return deferred.promise;
         },
         getAllSensorStatus: function(callback) {
           $http({
             method: 'GET',
-            url: DataService.getHost() + '/xyz/openbmc_project/sensors/enumerate',
+            url: DataService.getHost() +
+                '/xyz/openbmc_project/sensors/enumerate',
             headers: {
               'Accept': 'application/json',
               'Content-Type': 'application/json'
             },
             withCredentials: true
-          }).then(function(response) {
-            var json = JSON.stringify(response.data);
-            var content = JSON.parse(json);
-            var dataClone = JSON.parse(JSON.stringify(content.data));
-            var sensorData = [];
-            var severity = {};
-            var title = '';
-            var tempKeyParts = [];
-            var order = 0;
-            var customOrder = 0;
+          })
+              .then(
+                  function(response) {
+                    var json = JSON.stringify(response.data);
+                    var content = JSON.parse(json);
+                    var dataClone = JSON.parse(JSON.stringify(content.data));
+                    var sensorData = [];
+                    var severity = {};
+                    var title = '';
+                    var tempKeyParts = [];
+                    var order = 0;
+                    var customOrder = 0;
 
-            function getSensorStatus(reading) {
-              var severityFlags = {
-                  critical: false,
-                  warning: false,
-                  normal: false
-                },
-                severityText = '',
-                order = 0;
+                    function getSensorStatus(reading) {
+                      var severityFlags = {
+                        critical: false,
+                        warning: false,
+                        normal: false
+                      },
+                          severityText = '', order = 0;
 
-              if (reading.hasOwnProperty('CriticalLow') &&
-                reading.Value < reading.CriticalLow
-              ) {
-                severityFlags.critical = true;
-                severityText = 'critical';
-                order = 2;
-              }
-              else if (reading.hasOwnProperty('CriticalHigh') &&
-                reading.Value > reading.CriticalHigh
-              ) {
-                severityFlags.critical = true;
-                severityText = 'critical';
-                order = 2;
-              }
-              else if (reading.hasOwnProperty('CriticalLow') &&
-                reading.hasOwnProperty('WarningLow') &&
-                reading.Value >= reading.CriticalLow && reading.Value <= reading.WarningLow) {
-                severityFlags.warning = true;
-                severityText = 'warning';
-                order = 1;
-              }
-              else if (reading.hasOwnProperty('WarningHigh') &&
-                reading.hasOwnProperty('CriticalHigh') &&
-                reading.Value >= reading.WarningHigh && reading.Value <= reading.CriticalHigh) {
-                severityFlags.warning = true;
-                severityText = 'warning';
-                order = 1;
-              }
-              else {
-                severityFlags.normal = true;
-                severityText = 'normal';
-              }
-              return {
-                flags: severityFlags,
-                severityText: severityText,
-                order: order
-              };
-            }
+                      if (reading.hasOwnProperty('CriticalLow') &&
+                          reading.Value < reading.CriticalLow) {
+                        severityFlags.critical = true;
+                        severityText = 'critical';
+                        order = 2;
+                      } else if (
+                          reading.hasOwnProperty('CriticalHigh') &&
+                          reading.Value > reading.CriticalHigh) {
+                        severityFlags.critical = true;
+                        severityText = 'critical';
+                        order = 2;
+                      } else if (
+                          reading.hasOwnProperty('CriticalLow') &&
+                          reading.hasOwnProperty('WarningLow') &&
+                          reading.Value >= reading.CriticalLow &&
+                          reading.Value <= reading.WarningLow) {
+                        severityFlags.warning = true;
+                        severityText = 'warning';
+                        order = 1;
+                      } else if (
+                          reading.hasOwnProperty('WarningHigh') &&
+                          reading.hasOwnProperty('CriticalHigh') &&
+                          reading.Value >= reading.WarningHigh &&
+                          reading.Value <= reading.CriticalHigh) {
+                        severityFlags.warning = true;
+                        severityText = 'warning';
+                        order = 1;
+                      } else {
+                        severityFlags.normal = true;
+                        severityText = 'normal';
+                      }
+                      return {
+                        flags: severityFlags,
+                        severityText: severityText,
+                        order: order
+                      };
+                    }
 
-            for (var key in content.data) {
-              if (content.data.hasOwnProperty(key) && content.data[key].hasOwnProperty('Unit')) {
+                    for (var key in content.data) {
+                      if (content.data.hasOwnProperty(key) &&
+                          content.data[key].hasOwnProperty('Unit')) {
+                        severity = getSensorStatus(content.data[key]);
 
-                severity = getSensorStatus(content.data[key]);
+                        if (!content.data[key].hasOwnProperty('CriticalLow')) {
+                          content.data[key].CriticalLow = '--';
+                          content.data[key].CriticalHigh = '--';
+                        }
 
-                if (!content.data[key].hasOwnProperty('CriticalLow')) {
-                  content.data[key].CriticalLow = '--';
-                  content.data[key].CriticalHigh = '--';
-                }
+                        if (!content.data[key].hasOwnProperty('WarningLow')) {
+                          content.data[key].WarningLow = '--';
+                          content.data[key].WarningHigh = '--';
+                        }
 
-                if (!content.data[key].hasOwnProperty('WarningLow')) {
-                  content.data[key].WarningLow = '--';
-                  content.data[key].WarningHigh = '--';
-                }
+                        tempKeyParts = key.split('/');
+                        title = tempKeyParts.pop();
+                        title = tempKeyParts.pop() + '_' + title;
+                        title = title.split('_')
+                                    .map(function(item) {
+                                      return item.toLowerCase()
+                                                 .charAt(0)
+                                                 .toUpperCase() +
+                                          item.slice(1);
+                                    })
+                                    .reduce(function(prev, el) {
+                                      return prev + ' ' + el;
+                                    });
 
-                tempKeyParts = key.split('/');
-                title = tempKeyParts.pop();
-                title = tempKeyParts.pop() + '_' + title;
-                title = title.split('_').map(function(item) {
-                  return item.toLowerCase().charAt(0).toUpperCase() + item.slice(1);
-                }).reduce(function(prev, el) {
-                  return prev + ' ' + el;
-                });
+                        content.data[key].Value = getScaledValue(
+                            content.data[key].Value, content.data[key].Scale);
+                        content.data[key].CriticalLow = getScaledValue(
+                            content.data[key].CriticalLow,
+                            content.data[key].Scale);
+                        content.data[key].CriticalHigh = getScaledValue(
+                            content.data[key].CriticalHigh,
+                            content.data[key].Scale);
+                        content.data[key].WarningLow = getScaledValue(
+                            content.data[key].WarningLow,
+                            content.data[key].Scale);
+                        content.data[key].WarningHigh = getScaledValue(
+                            content.data[key].WarningHigh,
+                            content.data[key].Scale);
+                        if (Constants.SENSOR_SORT_ORDER.indexOf(
+                                content.data[key].Unit) > -1) {
+                          customOrder = Constants.SENSOR_SORT_ORDER.indexOf(
+                              content.data[key].Unit);
+                        } else {
+                          customOrder = Constants.SENSOR_SORT_ORDER_DEFAULT;
+                        }
 
-                content.data[key].Value = getScaledValue(content.data[key].Value, content.data[key].Scale);
-                content.data[key].CriticalLow = getScaledValue(content.data[key].CriticalLow, content.data[key].Scale);
-                content.data[key].CriticalHigh = getScaledValue(content.data[key].CriticalHigh, content.data[key].Scale);
-                content.data[key].WarningLow = getScaledValue(content.data[key].WarningLow, content.data[key].Scale);
-                content.data[key].WarningHigh = getScaledValue(content.data[key].WarningHigh, content.data[key].Scale);
-                if (Constants.SENSOR_SORT_ORDER.indexOf(content.data[key].Unit) > -1) {
-                  customOrder = Constants.SENSOR_SORT_ORDER.indexOf(content.data[key].Unit);
-                }
-                else {
-                  customOrder = Constants.SENSOR_SORT_ORDER_DEFAULT;
-                }
+                        sensorData.push(Object.assign(
+                            {
+                              path: key,
+                              selected: false,
+                              confirm: false,
+                              copied: false,
+                              title: title,
+                              unit:
+                                  Constants
+                                      .SENSOR_UNIT_MAP[content.data[key].Unit],
+                              severity_flags: severity.flags,
+                              status: severity.severityText,
+                              order: severity.order,
+                              custom_order: customOrder,
+                              search_text:
+                                  (title + ' ' + content.data[key].Value + ' ' +
+                                   Constants.SENSOR_UNIT_MAP[content.data[key]
+                                                                 .Unit] +
+                                   ' ' + severity.severityText + ' ' +
+                                   content.data[key].CriticalLow + ' ' +
+                                   content.data[key].CriticalHigh + ' ' +
+                                   content.data[key].WarningLow + ' ' +
+                                   content.data[key].WarningHigh + ' ')
+                                      .toLowerCase(),
+                              original_data:
+                                  {key: key, value: content.data[key]}
+                            },
+                            content.data[key]));
+                      }
+                    }
 
-                sensorData.push(Object.assign({
-                  path: key,
-                  selected: false,
-                  confirm: false,
-                  copied: false,
-                  title: title,
-                  unit: Constants.SENSOR_UNIT_MAP[content.data[key].Unit],
-                  severity_flags: severity.flags,
-                  status: severity.severityText,
-                  order: severity.order,
-                  custom_order: customOrder,
-                  search_text: (title + ' ' + content.data[key].Value + ' ' +
-                    Constants.SENSOR_UNIT_MAP[content.data[key].Unit] + ' ' +
-                    severity.severityText + ' ' +
-                    content.data[key].CriticalLow + ' ' +
-                    content.data[key].CriticalHigh + ' ' +
-                    content.data[key].WarningLow + ' ' +
-                    content.data[key].WarningHigh + ' '
-                  ).toLowerCase(),
-                  original_data: {
-                    key: key,
-                    value: content.data[key]
-                  }
-                }, content.data[key]));
-              }
-            }
-
-            callback(sensorData, dataClone);
-          }, function(error) {
-            console.log(error);
-          });
+                    callback(sensorData, dataClone);
+                  },
+                  function(error) {
+                    console.log(error);
+                  });
         },
         getActivation: function(imageId) {
           return $http({
-            method: 'GET',
-            url: DataService.getHost() + '/xyz/openbmc_project/software/' + imageId + '/attr/Activation',
-            headers: {
-              'Accept': 'application/json',
-              'Content-Type': 'application/json'
-            },
-            withCredentials: true
-          }).then(function(response) {
-            return response.data;
-          });
+                   method: 'GET',
+                   url: DataService.getHost() +
+                       '/xyz/openbmc_project/software/' + imageId +
+                       '/attr/Activation',
+                   headers: {
+                     'Accept': 'application/json',
+                     'Content-Type': 'application/json'
+                   },
+                   withCredentials: true
+                 })
+              .then(function(response) {
+                return response.data;
+              });
         },
         getFirmwares: function() {
           var deferred = $q.defer();
           $http({
             method: 'GET',
-            url: DataService.getHost() + '/xyz/openbmc_project/software/enumerate',
+            url: DataService.getHost() +
+                '/xyz/openbmc_project/software/enumerate',
             headers: {
               'Accept': 'application/json',
               'Content-Type': 'application/json'
             },
             withCredentials: true
-          }).then(function(response) {
-            var json = JSON.stringify(response.data);
-            var content = JSON.parse(json);
-            var data = [];
-            var activationStatus = '';
-            var isExtended = false;
-            var bmcActiveVersion = '';
-            var hostActiveVersion = '';
-            var imageType = '';
-            var extendedVersions = [];
-            var functionalImages = [];
+          })
+              .then(
+                  function(response) {
+                    var json = JSON.stringify(response.data);
+                    var content = JSON.parse(json);
+                    var data = [];
+                    var activationStatus = '';
+                    var isExtended = false;
+                    var bmcActiveVersion = '';
+                    var hostActiveVersion = '';
+                    var imageType = '';
+                    var extendedVersions = [];
+                    var functionalImages = [];
 
-            function getFormatedExtendedVersions(extendedVersion) {
-              var versions = [];
-              extendedVersion = extendedVersion.split(',');
+                    function getFormatedExtendedVersions(extendedVersion) {
+                      var versions = [];
+                      extendedVersion = extendedVersion.split(',');
 
-              extendedVersion.forEach(function(item) {
-                var parts = item.split('-');
-                var numberIndex = 0;
-                for (var i = 0; i < parts.length; i++) {
-                  if (/[0-9]/.test(parts[i])) {
-                    numberIndex = i;
-                    break;
-                  }
-                }
-                var titlePart = parts.splice(0, numberIndex);
-                titlePart = titlePart.join('');
-                titlePart = titlePart[0].toUpperCase() + titlePart.substr(1, titlePart.length);
-                var versionPart = parts.join('-');
-                versions.push({
-                  title: titlePart,
-                  version: versionPart
-                });
-              });
+                      extendedVersion.forEach(function(item) {
+                        var parts = item.split('-');
+                        var numberIndex = 0;
+                        for (var i = 0; i < parts.length; i++) {
+                          if (/[0-9]/.test(parts[i])) {
+                            numberIndex = i;
+                            break;
+                          }
+                        }
+                        var titlePart = parts.splice(0, numberIndex);
+                        titlePart = titlePart.join('');
+                        titlePart = titlePart[0].toUpperCase() +
+                            titlePart.substr(1, titlePart.length);
+                        var versionPart = parts.join('-');
+                        versions.push({title: titlePart, version: versionPart});
+                      });
 
-              return versions;
-            }
+                      return versions;
+                    }
 
-            // Get the list of functional images so we can compare
-            // later if an image is functional
-            if (content.data[Constants.FIRMWARE.FUNCTIONAL_OBJPATH]) {
-              functionalImages = content.data[Constants.FIRMWARE.FUNCTIONAL_OBJPATH].endpoints;
-            }
-            for (var key in content.data) {
-              if (content.data.hasOwnProperty(key) && content.data[key].hasOwnProperty('Version')) {
-                // If the image is "Functional" use that for the
-                // activation status, else use the value of "Activation"
-                // github.com/openbmc/phosphor-dbus-interfaces/blob/master/xyz/openbmc_project/Software/Activation.interface.yaml
-                activationStatus = content.data[key].Activation.split('.').pop();
-                if (functionalImages.includes(key)) {
-                  activationStatus = 'Functional';
-                }
+                    // Get the list of functional images so we can compare
+                    // later if an image is functional
+                    if (content.data[Constants.FIRMWARE.FUNCTIONAL_OBJPATH]) {
+                      functionalImages =
+                          content.data[Constants.FIRMWARE.FUNCTIONAL_OBJPATH]
+                              .endpoints;
+                    }
+                    for (var key in content.data) {
+                      if (content.data.hasOwnProperty(key) &&
+                          content.data[key].hasOwnProperty('Version')) {
+                        // If the image is "Functional" use that for the
+                        // activation status, else use the value of "Activation"
+                        // github.com/openbmc/phosphor-dbus-interfaces/blob/master/xyz/openbmc_project/Software/Activation.interface.yaml
+                        activationStatus =
+                            content.data[key].Activation.split('.').pop();
+                        if (functionalImages.includes(key)) {
+                          activationStatus = 'Functional';
+                        }
 
-                imageType = content.data[key].Purpose.split('.').pop();
-                isExtended = content.data[key].hasOwnProperty('ExtendedVersion') && content.data[key].ExtendedVersion != '';
-                if (isExtended) {
-                  extendedVersions = getFormatedExtendedVersions(content.data[key].ExtendedVersion);
-                }
-                data.push(Object.assign({
-                  path: key,
-                  activationStatus: activationStatus,
-                  imageId: key.split('/').pop(),
-                  imageType: imageType,
-                  isExtended: isExtended,
-                  extended: {
-                    show: false,
-                    versions: extendedVersions
+                        imageType = content.data[key].Purpose.split('.').pop();
+                        isExtended = content.data[key].hasOwnProperty(
+                                         'ExtendedVersion') &&
+                            content.data[key].ExtendedVersion != '';
+                        if (isExtended) {
+                          extendedVersions = getFormatedExtendedVersions(
+                              content.data[key].ExtendedVersion);
+                        }
+                        data.push(Object.assign(
+                            {
+                              path: key,
+                              activationStatus: activationStatus,
+                              imageId: key.split('/').pop(),
+                              imageType: imageType,
+                              isExtended: isExtended,
+                              extended:
+                                  {show: false, versions: extendedVersions},
+                              data: {key: key, value: content.data[key]}
+                            },
+                            content.data[key]));
+
+                        if (activationStatus == 'Functional' &&
+                            imageType == 'BMC') {
+                          bmcActiveVersion = content.data[key].Version;
+                        }
+
+                        if (activationStatus == 'Functional' &&
+                            imageType == 'Host') {
+                          hostActiveVersion = content.data[key].Version;
+                        }
+                      }
+                    }
+
+                    deferred.resolve({
+                      data: data,
+                      bmcActiveVersion: bmcActiveVersion,
+                      hostActiveVersion: hostActiveVersion
+                    });
                   },
-                  data: {
-                    key: key,
-                    value: content.data[key]
-                  }
-                }, content.data[key]));
-
-                if (activationStatus == 'Functional' && imageType == 'BMC') {
-                  bmcActiveVersion = content.data[key].Version;
-                }
-
-                if (activationStatus == 'Functional' && imageType == 'Host') {
-                  hostActiveVersion = content.data[key].Version;
-                }
-              }
-            }
-
-            deferred.resolve({
-              data: data,
-              bmcActiveVersion: bmcActiveVersion,
-              hostActiveVersion: hostActiveVersion
-            });
-          }, function(error) {
-            console.log(error);
-            deferred.reject(error);
-          });
+                  function(error) {
+                    console.log(error);
+                    deferred.reject(error);
+                  });
 
           return deferred.promise;
         },
@@ -818,23 +892,25 @@
           var deferred = $q.defer();
           $http({
             method: 'PUT',
-            url: DataService.getHost() + '/xyz/openbmc_project/software/' + imageId + '/attr/Priority',
+            url: DataService.getHost() + '/xyz/openbmc_project/software/' +
+                imageId + '/attr/Priority',
             headers: {
               'Accept': 'application/json',
               'Content-Type': 'application/json'
             },
             withCredentials: true,
-            data: JSON.stringify({
-              'data': priority
-            })
-          }).then(function(response) {
-            var json = JSON.stringify(response.data);
-            var content = JSON.parse(json);
-            deferred.resolve(content);
-          }, function(error) {
-            console.log(error);
-            deferred.reject(error);
-          });
+            data: JSON.stringify({'data': priority})
+          })
+              .then(
+                  function(response) {
+                    var json = JSON.stringify(response.data);
+                    var content = JSON.parse(json);
+                    deferred.resolve(content);
+                  },
+                  function(error) {
+                    console.log(error);
+                    deferred.reject(error);
+                  });
 
           return deferred.promise;
         },
@@ -842,23 +918,25 @@
           var deferred = $q.defer();
           $http({
             method: 'POST',
-            url: DataService.getHost() + '/xyz/openbmc_project/software/' + imageId + '/action/Delete',
+            url: DataService.getHost() + '/xyz/openbmc_project/software/' +
+                imageId + '/action/Delete',
             headers: {
               'Accept': 'application/json',
               'Content-Type': 'application/json'
             },
             withCredentials: true,
-            data: JSON.stringify({
-              'data': []
-            })
-          }).then(function(response) {
-            var json = JSON.stringify(response.data);
-            var content = JSON.parse(json);
-            deferred.resolve(content);
-          }, function(error) {
-            console.log(error);
-            deferred.reject(error);
-          });
+            data: JSON.stringify({'data': []})
+          })
+              .then(
+                  function(response) {
+                    var json = JSON.stringify(response.data);
+                    var content = JSON.parse(json);
+                    deferred.resolve(content);
+                  },
+                  function(error) {
+                    console.log(error);
+                    deferred.reject(error);
+                  });
 
           return deferred.promise;
         },
@@ -866,75 +944,81 @@
           var deferred = $q.defer();
           $http({
             method: 'PUT',
-            url: DataService.getHost() + '/xyz/openbmc_project/software/' + imageId + '/attr/RequestedActivation',
+            url: DataService.getHost() + '/xyz/openbmc_project/software/' +
+                imageId + '/attr/RequestedActivation',
             headers: {
               'Accept': 'application/json',
               'Content-Type': 'application/json'
             },
             withCredentials: true,
-            data: JSON.stringify({
-              'data': Constants.FIRMWARE.ACTIVATE_FIRMWARE
-            })
-          }).then(function(response) {
-            var json = JSON.stringify(response.data);
-            var content = JSON.parse(json);
-            deferred.resolve(content);
-          }, function(error) {
-            console.log(error);
-            deferred.reject(error);
-          });
+            data:
+                JSON.stringify({'data': Constants.FIRMWARE.ACTIVATE_FIRMWARE})
+          })
+              .then(
+                  function(response) {
+                    var json = JSON.stringify(response.data);
+                    var content = JSON.parse(json);
+                    deferred.resolve(content);
+                  },
+                  function(error) {
+                    console.log(error);
+                    deferred.reject(error);
+                  });
 
           return deferred.promise;
         },
         uploadImage: function(file) {
           return $http({
-            method: 'POST',
-            timeout: 5 * 60 * 1000,
-            url: DataService.getHost() + '/upload/image',
-            headers: {
-              'Content-Type': 'application/octet-stream'
-            },
-            withCredentials: true,
-            data: file
-          }).then(function(response) {
-            return response.data;
-          });
+                   method: 'POST',
+                   timeout: 5 * 60 * 1000,
+                   url: DataService.getHost() + '/upload/image',
+                   headers: {'Content-Type': 'application/octet-stream'},
+                   withCredentials: true,
+                   data: file
+                 })
+              .then(function(response) {
+                return response.data;
+              });
         },
         downloadImage: function(host, filename) {
           return $http({
-            method: 'POST',
-            url: DataService.getHost() + '/xyz/openbmc_project/software/action/DownloadViaTFTP',
-            headers: {
-              'Accept': 'application/json',
-              'Content-Type': 'application/json'
-            },
-            withCredentials: true,
-            data: JSON.stringify({
-              'data': [filename, host]
-            }),
-            responseType: 'arraybuffer'
-          }).then(function(response) {
-            return response.data;
-          });
+                   method: 'POST',
+                   url: DataService.getHost() +
+                       '/xyz/openbmc_project/software/action/DownloadViaTFTP',
+                   headers: {
+                     'Accept': 'application/json',
+                     'Content-Type': 'application/json'
+                   },
+                   withCredentials: true,
+                   data: JSON.stringify({'data': [filename, host]}),
+                   responseType: 'arraybuffer'
+                 })
+              .then(function(response) {
+                return response.data;
+              });
         },
         getBMCEthernetInfo: function() {
           var deferred = $q.defer();
           $http({
             method: 'GET',
-            url: DataService.getHost() + '/xyz/openbmc_project/inventory/system/chassis/motherboard/boxelder/bmc/ethernet',
+            url: DataService.getHost() +
+                '/xyz/openbmc_project/inventory/system/chassis/motherboard/boxelder/bmc/ethernet',
             headers: {
               'Accept': 'application/json',
               'Content-Type': 'application/json'
             },
             withCredentials: true
-          }).then(function(response) {
-            var json = JSON.stringify(response.data);
-            var content = JSON.parse(json);
-            deferred.resolve(content.data);
-          }, function(error) {
-            console.log(error);
-            deferred.reject(error);
-          });
+          })
+              .then(
+                  function(response) {
+                    var json = JSON.stringify(response.data);
+                    var content = JSON.parse(json);
+                    deferred.resolve(content.data);
+                  },
+                  function(error) {
+                    console.log(error);
+                    deferred.reject(error);
+                  });
 
           return deferred.promise;
         },
@@ -942,20 +1026,24 @@
           var deferred = $q.defer();
           $http({
             method: 'GET',
-            url: DataService.getHost() + '/xyz/openbmc_project/inventory/system/chassis/motherboard/boxelder/bmc',
+            url: DataService.getHost() +
+                '/xyz/openbmc_project/inventory/system/chassis/motherboard/boxelder/bmc',
             headers: {
               'Accept': 'application/json',
               'Content-Type': 'application/json'
             },
             withCredentials: true
-          }).then(function(response) {
-            var json = JSON.stringify(response.data);
-            var content = JSON.parse(json);
-            deferred.resolve(content.data);
-          }, function(error) {
-            console.log(error);
-            deferred.reject(error);
-          });
+          })
+              .then(
+                  function(response) {
+                    var json = JSON.stringify(response.data);
+                    var content = JSON.parse(json);
+                    deferred.resolve(content.data);
+                  },
+                  function(error) {
+                    console.log(error);
+                    deferred.reject(error);
+                  });
           return deferred.promise;
         },
         getServerInfo: function() {
@@ -963,34 +1051,38 @@
           // interfaces so we can get the system object(s) by the looking
           // for the system interface.
           return $http({
-            method: 'GET',
-            url: DataService.getHost() + '/xyz/openbmc_project/inventory/system',
-            headers: {
-              'Accept': 'application/json',
-              'Content-Type': 'application/json'
-            },
-            withCredentials: true
-          }).then(function(response) {
-            return response.data;
-          });
+                   method: 'GET',
+                   url: DataService.getHost() +
+                       '/xyz/openbmc_project/inventory/system',
+                   headers: {
+                     'Accept': 'application/json',
+                     'Content-Type': 'application/json'
+                   },
+                   withCredentials: true
+                 })
+              .then(function(response) {
+                return response.data;
+              });
         },
         getBMCTime: function() {
           return $http({
-            method: 'GET',
-            url: DataService.getHost() + '/xyz/openbmc_project/time/bmc',
-            headers: {
-              'Accept': 'application/json',
-              'Content-Type': 'application/json'
-            },
-            withCredentials: true
-          }).then(function(response) {
-            return response.data;
-          });
+                   method: 'GET',
+                   url: DataService.getHost() + '/xyz/openbmc_project/time/bmc',
+                   headers: {
+                     'Accept': 'application/json',
+                     'Content-Type': 'application/json'
+                   },
+                   withCredentials: true
+                 })
+              .then(function(response) {
+                return response.data;
+              });
         },
         getHardwares: function(callback) {
           $http({
             method: 'GET',
-            url: DataService.getHost() + '/xyz/openbmc_project/inventory/enumerate',
+            url: DataService.getHost() +
+                '/xyz/openbmc_project/inventory/enumerate',
             headers: {
               'Accept': 'application/json',
               'Content-Type': 'application/json'
@@ -1007,11 +1099,12 @@
             var componentIndex = -1;
             var tempParts = [];
 
-
             function isSubComponent(key) {
-
-              for (var i = 0; i < Constants.HARDWARE.parent_components.length; i++) {
-                if (key.split(Constants.HARDWARE.parent_components[i]).length == 2) return true;
+              for (var i = 0; i < Constants.HARDWARE.parent_components.length;
+                   i++) {
+                if (key.split(Constants.HARDWARE.parent_components[i]).length ==
+                    2)
+                  return true;
               }
 
               return false;
@@ -1019,8 +1112,10 @@
 
             function titlelize(title) {
               title = title.replace(/([A-Z0-9]+)/g, ' $1').replace(/^\s+/, '');
-              for (var i = 0; i < Constants.HARDWARE.uppercase_titles.length; i++) {
-                if (title.toLowerCase().indexOf((Constants.HARDWARE.uppercase_titles[i] + ' ')) > -1) {
+              for (var i = 0; i < Constants.HARDWARE.uppercase_titles.length;
+                   i++) {
+                if (title.toLowerCase().indexOf(
+                        (Constants.HARDWARE.uppercase_titles[i] + ' ')) > -1) {
                   return title.toUpperCase();
                 }
               }
@@ -1029,9 +1124,7 @@
             }
 
             function camelcaseToLabel(obj) {
-              var transformed = [],
-                label = '',
-                value = '';
+              var transformed = [], label = '', value = '';
               for (var key in obj) {
                 label = key.replace(/([A-Z0-9]+)/g, ' $1').replace(/^\s+/, '');
                 if (obj[key] !== '') {
@@ -1039,10 +1132,7 @@
                   if (value == 1 || value == 0) {
                     value = (value == 1) ? 'Yes' : 'No';
                   }
-                  transformed.push({
-                    key: label,
-                    value: value
-                  });
+                  transformed.push({key: label, value: value});
                 }
               }
 
@@ -1060,8 +1150,7 @@
 
             for (var key in content.data) {
               if (content.data.hasOwnProperty(key) &&
-                key.indexOf(Constants.HARDWARE.component_key_filter) == 0) {
-
+                  key.indexOf(Constants.HARDWARE.component_key_filter) == 0) {
                 data = camelcaseToLabel(content.data[key]);
                 searchText = getSearchText(data);
                 title = key.split('/').pop();
@@ -1069,24 +1158,21 @@
                 title = titlelize(title);
 
                 if (!isSubComponent(key)) {
-                  hardwareData.push(Object.assign({
-                    path: key,
-                    title: title,
-                    selected: false,
-                    expanded: false,
-                    search_text: title.toLowerCase() + ' ' + searchText.toLowerCase(),
-                    sub_components: [],
-                    original_data: {
-                      key: key,
-                      value: content.data[key]
-                    }
-                  }, {
-                    items: data
-                  }));
+                  hardwareData.push(Object.assign(
+                      {
+                        path: key,
+                        title: title,
+                        selected: false,
+                        expanded: false,
+                        search_text: title.toLowerCase() + ' ' +
+                            searchText.toLowerCase(),
+                        sub_components: [],
+                        original_data: {key: key, value: content.data[key]}
+                      },
+                      {items: data}));
 
                   keyIndexMap[key] = hardwareData.length - 1;
-                }
-                else {
+                } else {
                   var tempParts = key.split('/');
                   tempParts.pop();
                   tempParts = tempParts.join('/');
@@ -1094,14 +1180,16 @@
                   data = content.data[key];
                   data.title = title;
                   hardwareData[componentIndex].sub_components.push(data);
-                  hardwareData[componentIndex].search_text += ' ' + title.toLowerCase();
+                  hardwareData[componentIndex].search_text +=
+                      ' ' + title.toLowerCase();
 
-                  // Sort the subcomponents alphanumeric so they are displayed on the
-                  // inventory page in order (e.g. core 0, core 1, core 2, ... core 12, core 13)
-                  hardwareData[componentIndex].sub_components.sort(function(a, b) {
-                    return a.title.localeCompare(b.title, 'en', {
-                      numeric: true
-                    });
+                  // Sort the subcomponents alphanumeric so they are displayed
+                  // on the inventory page in order (e.g. core 0, core 1, core
+                  // 2, ... core 12, core 13)
+                  hardwareData[componentIndex].sub_components.sort(function(
+                      a, b) {
+                    return a.title.localeCompare(
+                        b.title, 'en', {numeric: true});
                   });
                 }
               }
@@ -1109,12 +1197,8 @@
 
             if (callback) {
               callback(hardwareData, content.data);
-            }
-            else {
-              return {
-                data: hardwareData,
-                original_data: content.data
-              };
+            } else {
+              return {data: hardwareData, original_data: content.data};
             }
           });
         },
@@ -1129,15 +1213,15 @@
           logs.forEach(function(item) {
             promises.push($http({
               method: 'POST',
-              url: DataService.getHost() + '/xyz/openbmc_project/logging/entry/' + item.Id + '/action/Delete',
+              url: DataService.getHost() +
+                  '/xyz/openbmc_project/logging/entry/' + item.Id +
+                  '/action/Delete',
               headers: {
                 'Accept': 'application/json',
                 'Content-Type': 'application/json'
               },
               withCredentials: true,
-              data: JSON.stringify({
-                'data': []
-              })
+              data: JSON.stringify({'data': []})
             }));
           });
 
@@ -1156,15 +1240,15 @@
           logs.forEach(function(item) {
             promises.push($http({
               method: 'PUT',
-              url: DataService.getHost() + '/xyz/openbmc_project/logging/entry/' + item.Id + '/attr/Resolved',
+              url: DataService.getHost() +
+                  '/xyz/openbmc_project/logging/entry/' + item.Id +
+                  '/attr/Resolved',
               headers: {
                 'Accept': 'application/json',
                 'Content-Type': 'application/json'
               },
               withCredentials: true,
-              data: JSON.stringify({
-                'data': '1'
-              })
+              data: JSON.stringify({'data': '1'})
             }));
           });
 
@@ -1174,65 +1258,72 @@
         },
         getPowerConsumption: function() {
           return $http({
-            method: 'GET',
-            url: DataService.getHost() + '/xyz/openbmc_project/sensors/power/total_power',
-            headers: {
-              'Accept': 'application/json',
-              'Content-Type': 'application/json'
-            },
-            withCredentials: true
-          }).then(function(response) {
-            var json = JSON.stringify(response.data);
-            var content = JSON.parse(json);
+                   method: 'GET',
+                   url: DataService.getHost() +
+                       '/xyz/openbmc_project/sensors/power/total_power',
+                   headers: {
+                     'Accept': 'application/json',
+                     'Content-Type': 'application/json'
+                   },
+                   withCredentials: true
+                 })
+              .then(
+                  function(response) {
+                    var json = JSON.stringify(response.data);
+                    var content = JSON.parse(json);
 
-            return getScaledValue(content.data.Value,
-                content.data.Scale) + ' ' +
-              Constants.POWER_CONSUMPTION_TEXT[content.data.Unit];
-          }, function(error) {
-            if ('Not Found' == error.statusText) {
-              return Constants.POWER_CONSUMPTION_TEXT.notavailable;
-            }
-            else {
-              throw error;
-            }
-          });
+                    return getScaledValue(
+                               content.data.Value, content.data.Scale) +
+                        ' ' +
+                        Constants.POWER_CONSUMPTION_TEXT[content.data.Unit];
+                  },
+                  function(error) {
+                    if ('Not Found' == error.statusText) {
+                      return Constants.POWER_CONSUMPTION_TEXT.notavailable;
+                    } else {
+                      throw error;
+                    }
+                  });
         },
         getPowerCap: function() {
           return $http({
-            method: 'GET',
-            url: DataService.getHost() + '/xyz/openbmc_project/control/host0/power_cap',
-            headers: {
-              'Accept': 'application/json',
-              'Content-Type': 'application/json'
-            },
-            withCredentials: true
-          }).then(function(response) {
-            var json = JSON.stringify(response.data);
-            var content = JSON.parse(json);
+                   method: 'GET',
+                   url: DataService.getHost() +
+                       '/xyz/openbmc_project/control/host0/power_cap',
+                   headers: {
+                     'Accept': 'application/json',
+                     'Content-Type': 'application/json'
+                   },
+                   withCredentials: true
+                 })
+              .then(function(response) {
+                var json = JSON.stringify(response.data);
+                var content = JSON.parse(json);
 
-            return (false == content.data.PowerCapEnable) ?
-              Constants.POWER_CAP_TEXT.disabled :
-              content.data.PowerCap + ' ' + Constants.POWER_CAP_TEXT.unit;
-          });
+                return (false == content.data.PowerCapEnable) ?
+                    Constants.POWER_CAP_TEXT.disabled :
+                    content.data.PowerCap + ' ' + Constants.POWER_CAP_TEXT.unit;
+              });
         },
         setHostname: function(hostname) {
           return $http({
-            method: 'PUT',
-            url: DataService.getHost() + '/xyz/openbmc_project/network/config/attr/HostName',
-            headers: {
-              'Accept': 'application/json',
-              'Content-Type': 'application/json'
-            },
-            withCredentials: true,
-            data: JSON.stringify({
-              'data': hostname
-            })
-          }).then(function(response) {
-            return response.data;
-          });
+                   method: 'PUT',
+                   url: DataService.getHost() +
+                       '/xyz/openbmc_project/network/config/attr/HostName',
+                   headers: {
+                     'Accept': 'application/json',
+                     'Content-Type': 'application/json'
+                   },
+                   withCredentials: true,
+                   data: JSON.stringify({'data': hostname})
+                 })
+              .then(function(response) {
+                return response.data;
+              });
         },
       };
       return SERVICE;
-    }]);
+    }
+  ]);
 
 })(window.angular);
diff --git a/app/common/services/apiInterceptor.js b/app/common/services/apiInterceptor.js
index b3f2ff4..03a43a3 100644
--- a/app/common/services/apiInterceptor.js
+++ b/app/common/services/apiInterceptor.js
@@ -10,9 +10,9 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.common.services')
-    .service('apiInterceptor', ['$q', '$rootScope', 'dataService', function($q, $rootScope, dataService) {
+  angular.module('app.common.services').service('apiInterceptor', [
+    '$q', '$rootScope', 'dataService',
+    function($q, $rootScope, dataService) {
       return {
         'request': function(config) {
           dataService.loading = true;
@@ -25,7 +25,7 @@
         'response': function(response) {
           dataService.loading = false;
 
-          //not interested in template requests
+          // not interested in template requests
           if (!/^https?\:/i.test(response.config.url)) {
             return response;
           }
@@ -33,13 +33,12 @@
           dataService.last_updated = new Date();
           if (!response) {
             dataService.server_unreachable = true;
-          }
-          else {
+          } else {
             dataService.server_unreachable = false;
           }
 
           if (response && response.status == 'error' &&
-            dataService.path != '/login') {
+              dataService.path != '/login') {
             $rootScope.$emit('timedout-user', {});
           }
 
@@ -52,8 +51,7 @@
               if (dataService.path != '/login') {
                 $rootScope.$emit('timedout-user', {});
               }
-            }
-            else if (rejection.status == -1) {
+            } else if (rejection.status == -1) {
               dataService.server_unreachable = true;
             }
 
@@ -62,6 +60,7 @@
           return $q.reject(rejection);
         }
       };
-    }]);
+    }
+  ]);
 
 })(window.angular);
diff --git a/app/common/services/constants.js b/app/common/services/constants.js
index d749ea8..112c90e 100644
--- a/app/common/services/constants.js
+++ b/app/common/services/constants.js
@@ -10,158 +10,142 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.common.services', [])
-    .service('Constants', function() {
-      return {
-        API_CREDENTIALS: {
-          host_storage_key: 'API_HOST_KEY',
-          default_protocol: 'https'
-        },
-        API_RESPONSE: {
-          ERROR_STATUS: 'error',
-          ERROR_MESSAGE: '401 Unauthorized',
-          SUCCESS_STATUS: 'ok',
-          SUCCESS_MESSAGE: '200 OK'
-        },
-        CHASSIS_POWER_STATE: {
-          on: 'On',
-          on_code: 'xyz.openbmc_project.State.Chassis.PowerState.On',
-          off: 'Off',
-          off_code: 'xyz.openbmc_project.State.Chassis.PowerState.Off'
-        },
-        HOST_STATE_TEXT: {
-          on: 'Running',
-          on_code: 'xyz.openbmc_project.State.Host.HostState.Running',
-          off: 'Off',
-          off_code: 'xyz.openbmc_project.State.Host.HostState.Off',
-          error: 'Quiesced',
-          error_code: 'xyz.openbmc_project.State.Host.HostState.Quiesced',
-          unreachable: 'Unreachable'
-        },
-        HOST_STATE: {
-          on: 1,
-          off: -1,
-          error: 0,
-          unreachable: -2
-        },
-        LED_STATE: {
-          on: true,
-          off: false
-        },
-        LED_STATE_TEXT: {
-          on: 'on',
-          off: 'off'
-        },
-        SEVERITY_TO_HEALTH_MAP: {
-          Emergency: 'Critical',
-          Alert: 'Critical',
-          Critical: 'Critical',
-          Error: 'Warning',
-          Warning: 'Warning',
-          Notice: 'Good',
-          Debug: 'Good',
-          Informational: 'Good'
-        },
-        SEVERITY_TO_PRIORITY_MAP: {
-          Emergency: 'High',
-          Alert: 'High',
-          Critical: 'High',
-          Error: 'High',
-          Warning: 'Medium',
-          Notice: 'Low',
-          Debug: 'Low',
-          Informational: 'Low'
-        },
-        PAGINATION: {
-          LOG_ITEMS_PER_PAGE: 25
-        },
-        HARDWARE: {
-          component_key_filter: '/xyz/openbmc_project/inventory/system',
-          parent_components: [
-            /xyz\/openbmc_project\/inventory\/system\/chassis\/motherboard\/cpu\d+\//
-          ],
-          uppercase_titles: [
-            'cpu', 'dimm'
-          ]
-        },
-        SENSOR_UNIT_MAP: {
-          'xyz.openbmc_project.Sensor.Value.Unit.RPMS': 'rpms',
-          'xyz.openbmc_project.Sensor.Value.Unit.DegreesC': 'C',
-          'xyz.openbmc_project.Sensor.Value.Unit.Volts': 'volts',
-          'xyz.openbmc_project.Sensor.Value.Unit.Meters': 'meters',
-          'xyz.openbmc_project.Sensor.Value.Unit.Watts': 'watts',
-          'xyz.openbmc_project.Sensor.Value.Unit.Amperes': 'amperes',
-          'xyz.openbmc_project.Sensor.Value.Unit.Joules': 'joules'
-        },
-        SERVER_HEALTH: {
-          critical: 'Critical',
-          warning: 'Warning',
-          good: 'Good',
-          unknown: 'Unknown'
-        },
-        SENSOR_SORT_ORDER: [
-          'xyz.openbmc_project.Sensor.Value.Unit.DegreesC',
-          'xyz.openbmc_project.Sensor.Value.Unit.RPMS',
-          'xyz.openbmc_project.Sensor.Value.Unit.Meters',
-          'xyz.openbmc_project.Sensor.Value.Unit.Volts',
-          'xyz.openbmc_project.Sensor.Value.Unit.Amperes',
-          'xyz.openbmc_project.Sensor.Value.Unit.Joules',
-          'xyz.openbmc_project.Sensor.Value.Unit.Meters'
+  angular.module('app.common.services', []).service('Constants', function() {
+    return {
+      API_CREDENTIALS:
+          {host_storage_key: 'API_HOST_KEY', default_protocol: 'https'},
+      API_RESPONSE: {
+        ERROR_STATUS: 'error',
+        ERROR_MESSAGE: '401 Unauthorized',
+        SUCCESS_STATUS: 'ok',
+        SUCCESS_MESSAGE: '200 OK'
+      },
+      CHASSIS_POWER_STATE: {
+        on: 'On',
+        on_code: 'xyz.openbmc_project.State.Chassis.PowerState.On',
+        off: 'Off',
+        off_code: 'xyz.openbmc_project.State.Chassis.PowerState.Off'
+      },
+      HOST_STATE_TEXT: {
+        on: 'Running',
+        on_code: 'xyz.openbmc_project.State.Host.HostState.Running',
+        off: 'Off',
+        off_code: 'xyz.openbmc_project.State.Host.HostState.Off',
+        error: 'Quiesced',
+        error_code: 'xyz.openbmc_project.State.Host.HostState.Quiesced',
+        unreachable: 'Unreachable'
+      },
+      HOST_STATE: {on: 1, off: -1, error: 0, unreachable: -2},
+      LED_STATE: {on: true, off: false},
+      LED_STATE_TEXT: {on: 'on', off: 'off'},
+      SEVERITY_TO_HEALTH_MAP: {
+        Emergency: 'Critical',
+        Alert: 'Critical',
+        Critical: 'Critical',
+        Error: 'Warning',
+        Warning: 'Warning',
+        Notice: 'Good',
+        Debug: 'Good',
+        Informational: 'Good'
+      },
+      SEVERITY_TO_PRIORITY_MAP: {
+        Emergency: 'High',
+        Alert: 'High',
+        Critical: 'High',
+        Error: 'High',
+        Warning: 'Medium',
+        Notice: 'Low',
+        Debug: 'Low',
+        Informational: 'Low'
+      },
+      PAGINATION: {LOG_ITEMS_PER_PAGE: 25},
+      HARDWARE: {
+        component_key_filter: '/xyz/openbmc_project/inventory/system',
+        parent_components: [
+          /xyz\/openbmc_project\/inventory\/system\/chassis\/motherboard\/cpu\d+\//
         ],
-        SENSOR_SORT_ORDER_DEFAULT: 8,
-        FIRMWARE: {
-          ACTIVATE_FIRMWARE: 'xyz.openbmc_project.Software.Activation.RequestedActivations.Active',
-          FUNCTIONAL_OBJPATH: '/xyz/openbmc_project/software/functional'
+        uppercase_titles: ['cpu', 'dimm']
+      },
+      SENSOR_UNIT_MAP: {
+        'xyz.openbmc_project.Sensor.Value.Unit.RPMS': 'rpms',
+        'xyz.openbmc_project.Sensor.Value.Unit.DegreesC': 'C',
+        'xyz.openbmc_project.Sensor.Value.Unit.Volts': 'volts',
+        'xyz.openbmc_project.Sensor.Value.Unit.Meters': 'meters',
+        'xyz.openbmc_project.Sensor.Value.Unit.Watts': 'watts',
+        'xyz.openbmc_project.Sensor.Value.Unit.Amperes': 'amperes',
+        'xyz.openbmc_project.Sensor.Value.Unit.Joules': 'joules'
+      },
+      SERVER_HEALTH: {
+        critical: 'Critical',
+        warning: 'Warning',
+        good: 'Good',
+        unknown: 'Unknown'
+      },
+      SENSOR_SORT_ORDER: [
+        'xyz.openbmc_project.Sensor.Value.Unit.DegreesC',
+        'xyz.openbmc_project.Sensor.Value.Unit.RPMS',
+        'xyz.openbmc_project.Sensor.Value.Unit.Meters',
+        'xyz.openbmc_project.Sensor.Value.Unit.Volts',
+        'xyz.openbmc_project.Sensor.Value.Unit.Amperes',
+        'xyz.openbmc_project.Sensor.Value.Unit.Joules',
+        'xyz.openbmc_project.Sensor.Value.Unit.Meters'
+      ],
+      SENSOR_SORT_ORDER_DEFAULT: 8,
+      FIRMWARE: {
+        ACTIVATE_FIRMWARE:
+            'xyz.openbmc_project.Software.Activation.RequestedActivations.Active',
+        FUNCTIONAL_OBJPATH: '/xyz/openbmc_project/software/functional'
+      },
+      POLL_INTERVALS: {
+        ACTIVATION: 5000,
+        DOWNLOAD_IMAGE: 5000,
+        POWER_OP: 5000,
+      },
+      TIMEOUT: {
+        ACTIVATION: 1000 * 60 * 10,     // 10 mins
+        DOWNLOAD_IMAGE: 1000 * 60 * 2,  // 2 mins
+        CHASSIS_OFF: 1000 * 60 * 5,     // 5 mins
+        HOST_ON: 1000 * 60 * 5,         // 5 mins
+        HOST_OFF: 1000 * 60 * 5,        // 5 mins
+      },
+      MESSAGES: {
+        POLL: {
+          CHASSIS_OFF_TIMEOUT:
+              'Time out. Chassis did not reach power off state in allotted time.',
+          HOST_ON_TIMEOUT:
+              'Time out. System did not reach Running state in allotted time.',
+          HOST_OFF_TIMEOUT:
+              'Time out. System did not reach Off state in allotted time.',
+          HOST_QUIESCED: 'System is in Error state.',
+          DOWNLOAD_IMAGE_TIMEOUT:
+              'Time out. Did not download image in allotted time.',
         },
-        POLL_INTERVALS: {
-          ACTIVATION: 5000,
-          DOWNLOAD_IMAGE: 5000,
-          POWER_OP: 5000,
+        POWER_OP: {
+          POWER_ON_FAILED: 'Power On Failed',
+          WARM_REBOOT_FAILED: 'Warm Reboot Failed',
+          COLD_REBOOT_FAILED: 'Cold Reboot Failed',
+          ORDERLY_SHUTDOWN_FAILED: 'Orderly Shutdown Failed',
+          IMMEDIATE_SHUTDOWN_FAILED: 'Immediate Shutdown Failed',
         },
-        TIMEOUT: {
-          ACTIVATION: 1000 * 60 * 10, // 10 mins
-          DOWNLOAD_IMAGE: 1000 * 60 * 2, // 2 mins
-          CHASSIS_OFF: 1000 * 60 * 5, // 5 mins
-          HOST_ON: 1000 * 60 * 5, // 5 mins
-          HOST_OFF: 1000 * 60 * 5, // 5 mins
+        SENSOR: {
+          NO_SENSOR_DATA: 'There are no sensors found.',
+          CRITICAL_NO_SENSOR_DATA: 'There are no sensors in Critical state.',
+          WARNING_NO_SENSOR_DATA: 'There are no sensors in Warning state.',
+          NORMAL_NO_SENSOR_DATA: 'There are no sensors in Normal state.'
         },
-        MESSAGES: {
-          POLL: {
-            CHASSIS_OFF_TIMEOUT: 'Time out. Chassis did not reach power off state in allotted time.',
-            HOST_ON_TIMEOUT: 'Time out. System did not reach Running state in allotted time.',
-            HOST_OFF_TIMEOUT: 'Time out. System did not reach Off state in allotted time.',
-            HOST_QUIESCED: 'System is in Error state.',
-            DOWNLOAD_IMAGE_TIMEOUT: 'Time out. Did not download image in allotted time.',
-          },
-          POWER_OP: {
-            POWER_ON_FAILED: 'Power On Failed',
-            WARM_REBOOT_FAILED: 'Warm Reboot Failed',
-            COLD_REBOOT_FAILED: 'Cold Reboot Failed',
-            ORDERLY_SHUTDOWN_FAILED: 'Orderly Shutdown Failed',
-            IMMEDIATE_SHUTDOWN_FAILED: 'Immediate Shutdown Failed',
-          },
-          SENSOR: {
-            NO_SENSOR_DATA: 'There are no sensors found.',
-            CRITICAL_NO_SENSOR_DATA: 'There are no sensors in Critical state.',
-            WARNING_NO_SENSOR_DATA: 'There are no sensors in Warning state.',
-            NORMAL_NO_SENSOR_DATA: 'There are no sensors in Normal state.'
-          },
-          ERROR_MODAL: {
-            TITLE: 'Unexpected error',
-            DESCRIPTION: 'Oops! An unexpected error occurred. Record specific details of the issue, then contact your company support services.'
-          },
-          ERROR_MESSAGE_DESC_TEMPLATE: '{{status}} - {{description}}',
+        ERROR_MODAL: {
+          TITLE: 'Unexpected error',
+          DESCRIPTION:
+              'Oops! An unexpected error occurred. Record specific details of the issue, then contact your company support services.'
         },
-        POWER_CAP_TEXT: {
-          unit: 'W',
-          disabled: 'Not Enabled'
-        },
-        POWER_CONSUMPTION_TEXT: {
-          'xyz.openbmc_project.Sensor.Value.Unit.Watts': 'W',
-          notavailable: 'Not Available'
-        },
-      };
-    });
+        ERROR_MESSAGE_DESC_TEMPLATE: '{{status}} - {{description}}',
+      },
+      POWER_CAP_TEXT: {unit: 'W', disabled: 'Not Enabled'},
+      POWER_CONSUMPTION_TEXT: {
+        'xyz.openbmc_project.Sensor.Value.Unit.Watts': 'W',
+        notavailable: 'Not Available'
+      },
+    };
+  });
 
 })(window.angular);
diff --git a/app/common/services/dataService.js b/app/common/services/dataService.js
index 79a3a0e..ffe15a2 100644
--- a/app/common/services/dataService.js
+++ b/app/common/services/dataService.js
@@ -10,9 +10,9 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.common.services')
-    .service('dataService', ['Constants', function(Constants) {
+  angular.module('app.common.services').service('dataService', [
+    'Constants',
+    function(Constants) {
       this.server_health = Constants.SERVER_HEALTH.unknown;
       this.server_state = 'Unreachable';
       this.server_status = -2;
@@ -45,20 +45,23 @@
       };
 
       this.getHost = function() {
-        if (sessionStorage.getItem(Constants.API_CREDENTIALS.host_storage_key) !== null) {
-          return sessionStorage.getItem(Constants.API_CREDENTIALS.host_storage_key);
-        }
-        else {
+        if (sessionStorage.getItem(
+                Constants.API_CREDENTIALS.host_storage_key) !== null) {
+          return sessionStorage.getItem(
+              Constants.API_CREDENTIALS.host_storage_key);
+        } else {
           return Constants.API_CREDENTIALS.default_protocol + '://' +
-            window.location.hostname +
-            (window.location.port ? ':' + window.location.port : '');
+              window.location.hostname +
+              (window.location.port ? ':' + window.location.port : '');
         }
       };
 
       this.setHost = function(hostWithPort) {
         hostWithPort = hostWithPort.replace(/^https?\:\/\//ig, '');
-        var hostURL = Constants.API_CREDENTIALS.default_protocol + '://' + hostWithPort;
-        sessionStorage.setItem(Constants.API_CREDENTIALS.host_storage_key, hostURL);
+        var hostURL =
+            Constants.API_CREDENTIALS.default_protocol + '://' + hostWithPort;
+        sessionStorage.setItem(
+            Constants.API_CREDENTIALS.host_storage_key, hostURL);
         this.host = hostURL;
         this.reloadServerId();
       };
@@ -128,16 +131,15 @@
       this.activateErrorModal = function(data) {
         if (data && data.hasOwnProperty('title')) {
           this.errorModalDetails.title = data.title;
-        }
-        else {
+        } else {
           this.errorModalDetails.title = Constants.MESSAGES.ERROR_MODAL.TITLE;
         }
 
         if (data && data.hasOwnProperty('description')) {
           this.errorModalDetails.description = data.description;
-        }
-        else {
-          this.errorModalDetails.description = Constants.MESSAGES.ERROR_MODAL.DESCRIPTION;
+        } else {
+          this.errorModalDetails.description =
+              Constants.MESSAGES.ERROR_MODAL.DESCRIPTION;
         }
         this.displayErrorModal = true;
       };
@@ -145,6 +147,7 @@
       this.deactivateErrorModal = function() {
         this.displayErrorModal = false;
       };
-    }]);
+    }
+  ]);
 
 })(window.angular);
diff --git a/app/common/services/index.js b/app/common/services/index.js
index d234069..a56dce1 100644
--- a/app/common/services/index.js
+++ b/app/common/services/index.js
@@ -8,10 +8,9 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.common.services', [
-      // Dependencies
-      // Basic resources
-    ]);
+  angular.module('app.common.services', [
+    // Dependencies
+    // Basic resources
+  ]);
 
 })(window.angular);
diff --git a/app/common/services/userModel.js b/app/common/services/userModel.js
index cd943f9..0232200 100644
--- a/app/common/services/userModel.js
+++ b/app/common/services/userModel.js
@@ -10,29 +10,26 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.common.services')
-    .service('userModel', ['APIUtils', function(APIUtils) {
+  angular.module('app.common.services').service('userModel', [
+    'APIUtils',
+    function(APIUtils) {
       return {
         login: function(username, password, callback) {
           APIUtils.login(username, password, function(response, error) {
             if (response &&
-              (response.status == APIUtils.API_RESPONSE.SUCCESS_STATUS ||
-                response.status === undefined)) {
+                (response.status == APIUtils.API_RESPONSE.SUCCESS_STATUS ||
+                 response.status === undefined)) {
               sessionStorage.setItem('LOGIN_ID', username);
               callback(true);
-            }
-            else if (response && response.data && response.data.data &&
-              response.data.data.description) {
+            } else if (
+                response && response.data && response.data.data &&
+                response.data.data.description) {
               callback(false, response.data.data.description);
-            }
-            else if (response && response.message) {
+            } else if (response && response.message) {
               callback(false, response.message);
-            }
-            else if (error) {
+            } else if (error) {
               callback(false, 'Server unreachable');
-            }
-            else {
+            } else {
               callback(false, 'Internal error');
             }
           });
@@ -46,20 +43,19 @@
         logout: function(callback) {
           APIUtils.logout(function(response, error) {
             if (response &&
-              response.status == APIUtils.API_RESPONSE.SUCCESS_STATUS) {
+                response.status == APIUtils.API_RESPONSE.SUCCESS_STATUS) {
               sessionStorage.removeItem('LOGIN_ID');
               sessionStorage.removeItem(APIUtils.HOST_SESSION_STORAGE_KEY);
               callback(true);
-            }
-            else if (response.status == APIUtils.API_RESPONSE.ERROR_STATUS) {
+            } else if (response.status == APIUtils.API_RESPONSE.ERROR_STATUS) {
               callback(false);
-            }
-            else {
+            } else {
               callback(false, error);
             }
           });
         }
       };
-    }]);
+    }
+  ]);
 
 })(window.angular);
diff --git a/app/configuration/controllers/date-time-controller.js b/app/configuration/controllers/date-time-controller.js
index 341d175..5ec89ef 100644
--- a/app/configuration/controllers/date-time-controller.js
+++ b/app/configuration/controllers/date-time-controller.js
@@ -9,16 +9,11 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.configuration')
-    .controller('dateTimeController', [
-      '$scope',
-      '$window',
-      'APIUtils',
-      'dataService',
-      function($scope, $window, APIUtils, dataService) {
-        $scope.dataService = dataService;
-      }
-    ]);
+  angular.module('app.configuration').controller('dateTimeController', [
+    '$scope', '$window', 'APIUtils', 'dataService',
+    function($scope, $window, APIUtils, dataService) {
+      $scope.dataService = dataService;
+    }
+  ]);
 
 })(angular);
diff --git a/app/configuration/controllers/file-controller.js b/app/configuration/controllers/file-controller.js
index 37c7ffb..300cb37 100644
--- a/app/configuration/controllers/file-controller.js
+++ b/app/configuration/controllers/file-controller.js
@@ -9,16 +9,11 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.configuration')
-    .controller('fileController', [
-      '$scope',
-      '$window',
-      'APIUtils',
-      'dataService',
-      function($scope, $window, APIUtils, dataService) {
-        $scope.dataService = dataService;
-      }
-    ]);
+  angular.module('app.configuration').controller('fileController', [
+    '$scope', '$window', 'APIUtils', 'dataService',
+    function($scope, $window, APIUtils, dataService) {
+      $scope.dataService = dataService;
+    }
+  ]);
 
 })(angular);
diff --git a/app/configuration/controllers/firmware-controller.js b/app/configuration/controllers/firmware-controller.js
index cf838ec..f11edf9 100644
--- a/app/configuration/controllers/firmware-controller.js
+++ b/app/configuration/controllers/firmware-controller.js
@@ -9,310 +9,320 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.configuration')
-    .controller('firmwareController', [
-      '$scope',
-      '$window',
-      'APIUtils',
-      'dataService',
-      '$location',
-      '$anchorScroll',
-      'Constants',
-      '$interval',
-      '$q',
-      '$timeout',
-      function($scope, $window, APIUtils, dataService, $location, $anchorScroll, Constants, $interval, $q, $timeout) {
-        $scope.dataService = dataService;
+  angular.module('app.configuration').controller('firmwareController', [
+    '$scope', '$window', 'APIUtils', 'dataService', '$location',
+    '$anchorScroll', 'Constants', '$interval', '$q', '$timeout',
+    function(
+        $scope, $window, APIUtils, dataService, $location, $anchorScroll,
+        Constants, $interval, $q, $timeout) {
+      $scope.dataService = dataService;
 
-        //Scroll to target anchor
-        $scope.gotoAnchor = function() {
-          $location.hash('upload');
-          $anchorScroll();
-        };
+      // Scroll to target anchor
+      $scope.gotoAnchor = function() {
+        $location.hash('upload');
+        $anchorScroll();
+      };
 
-        $scope.firmwares = [];
-        $scope.bmcActiveVersion = '';
-        $scope.hostActiveVersion = '';
-        $scope.display_error = false;
-        $scope.activate_confirm = false;
-        $scope.delete_image_id = '';
-        $scope.delete_image_version = '';
-        $scope.activate_image_id = '';
-        $scope.activate_image_version = '';
-        $scope.activate_image_type = '';
-        $scope.priority_image_id = '';
-        $scope.priority_image_version = '';
-        $scope.priority_from = -1;
-        $scope.priority_to = -1;
-        $scope.confirm_priority = false;
-        $scope.file_empty = true;
-        $scope.uploading = false;
-        $scope.upload_success = false;
-        $scope.activate = {
-          reboot: true
-        };
-        $scope.download_error_msg = '';
-        $scope.download_success = false;
+      $scope.firmwares = [];
+      $scope.bmcActiveVersion = '';
+      $scope.hostActiveVersion = '';
+      $scope.display_error = false;
+      $scope.activate_confirm = false;
+      $scope.delete_image_id = '';
+      $scope.delete_image_version = '';
+      $scope.activate_image_id = '';
+      $scope.activate_image_version = '';
+      $scope.activate_image_type = '';
+      $scope.priority_image_id = '';
+      $scope.priority_image_version = '';
+      $scope.priority_from = -1;
+      $scope.priority_to = -1;
+      $scope.confirm_priority = false;
+      $scope.file_empty = true;
+      $scope.uploading = false;
+      $scope.upload_success = false;
+      $scope.activate = {reboot: true};
+      $scope.download_error_msg = '';
+      $scope.download_success = false;
 
-        var pollActivationTimer = undefined;
-        var pollDownloadTimer = undefined;
+      var pollActivationTimer = undefined;
+      var pollDownloadTimer = undefined;
 
-        $scope.error = {
-          modal_title: '',
-          title: '',
-          desc: '',
-          type: 'warning'
-        };
+      $scope.error = {modal_title: '', title: '', desc: '', type: 'warning'};
 
-        $scope.activateImage = function(imageId, imageVersion, imageType) {
-          $scope.activate_image_id = imageId;
-          $scope.activate_image_version = imageVersion;
-          $scope.activate_image_type = imageType;
-          $scope.activate_confirm = true;
-        };
+      $scope.activateImage = function(imageId, imageVersion, imageType) {
+        $scope.activate_image_id = imageId;
+        $scope.activate_image_version = imageVersion;
+        $scope.activate_image_type = imageType;
+        $scope.activate_confirm = true;
+      };
 
-        $scope.displayError = function(data) {
-          $scope.error = data;
-          $scope.display_error = true;
-        };
+      $scope.displayError = function(data) {
+        $scope.error = data;
+        $scope.display_error = true;
+      };
 
-        function waitForActive(imageId) {
-          var deferred = $q.defer();
-          var startTime = new Date();
-          pollActivationTimer = $interval(function() {
-            APIUtils.getActivation(imageId).then(function(state) {
-              //@TODO: display an error message if image "Failed"
-              if (((/\.Active$/).test(state.data)) || ((/\.Failed$/).test(state.data))) {
+      function waitForActive(imageId) {
+        var deferred = $q.defer();
+        var startTime = new Date();
+        pollActivationTimer = $interval(function() {
+          APIUtils.getActivation(imageId).then(
+              function(state) {
+                //@TODO: display an error message if image "Failed"
+                if (((/\.Active$/).test(state.data)) ||
+                    ((/\.Failed$/).test(state.data))) {
+                  $interval.cancel(pollActivationTimer);
+                  pollActivationTimer = undefined;
+                  deferred.resolve(state);
+                }
+              },
+              function(error) {
                 $interval.cancel(pollActivationTimer);
                 pollActivationTimer = undefined;
-                deferred.resolve(state);
-              }
-            }, function(error) {
-              $interval.cancel(pollActivationTimer);
-              pollActivationTimer = undefined;
-              console.log(error);
-              deferred.reject(error);
-            });
-            var now = new Date();
-            if ((now.getTime() - startTime.getTime()) >= Constants.TIMEOUT.ACTIVATION) {
-              $interval.cancel(pollActivationTimer);
-              pollActivationTimer = undefined;
-              console.log('Time out activating image, ' + imageId);
-              deferred.reject('Time out. Image did not activate in allotted time.');
-            }
-          }, Constants.POLL_INTERVALS.ACTIVATION);
-          return deferred.promise;
-        }
-
-        $scope.activateConfirmed = function() {
-          APIUtils.activateImage($scope.activate_image_id).then(function(state) {
-            $scope.loadFirmwares();
-            return state;
-          }, function(error) {
-            $scope.displayError({
-              modal_title: 'Error during activation call',
-              title: 'Error during activation call',
-              desc: JSON.stringify(error.data),
-              type: 'Error'
-            });
-          }).then(function(activationState) {
-            waitForActive($scope.activate_image_id).then(function(state) {
-              $scope.loadFirmwares();
-            }, function(error) {
-              $scope.displayError({
-                modal_title: 'Error during image activation',
-                title: 'Error during image activation',
-                desc: JSON.stringify(error.data),
-                type: 'Error'
+                console.log(error);
+                deferred.reject(error);
               });
-            }).then(function(state) {
-              // Only look at reboot if it's a BMC image
-              if ($scope.activate.reboot && ($scope.activate_image_type == 'BMC')) {
-                // Despite the new image being active, issue,
-                // https://github.com/openbmc/openbmc/issues/2764, can cause a
-                // system to brick, if the system reboots before the service to set
-                // the U-Boot variables is complete. Wait 10 seconds before rebooting
-                // to ensure this service is complete. This issue is fixed in newer images, but
-                // the user may be updating from an older image that does not that have this fix.
-                // TODO: remove this timeout after sufficient time has passed.
-                $timeout(function() {
-                  APIUtils.bmcReboot(function(response) {}, function(error) {
+          var now = new Date();
+          if ((now.getTime() - startTime.getTime()) >=
+              Constants.TIMEOUT.ACTIVATION) {
+            $interval.cancel(pollActivationTimer);
+            pollActivationTimer = undefined;
+            console.log('Time out activating image, ' + imageId);
+            deferred.reject(
+                'Time out. Image did not activate in allotted time.');
+          }
+        }, Constants.POLL_INTERVALS.ACTIVATION);
+        return deferred.promise;
+      }
+
+      $scope.activateConfirmed = function() {
+        APIUtils.activateImage($scope.activate_image_id)
+            .then(
+                function(state) {
+                  $scope.loadFirmwares();
+                  return state;
+                },
+                function(error) {
+                  $scope.displayError({
+                    modal_title: 'Error during activation call',
+                    title: 'Error during activation call',
+                    desc: JSON.stringify(error.data),
+                    type: 'Error'
+                  });
+                })
+            .then(function(activationState) {
+              waitForActive($scope.activate_image_id)
+                  .then(
+                      function(state) {
+                        $scope.loadFirmwares();
+                      },
+                      function(error) {
+                        $scope.displayError({
+                          modal_title: 'Error during image activation',
+                          title: 'Error during image activation',
+                          desc: JSON.stringify(error.data),
+                          type: 'Error'
+                        });
+                      })
+                  .then(function(state) {
+                    // Only look at reboot if it's a BMC image
+                    if ($scope.activate.reboot &&
+                        ($scope.activate_image_type == 'BMC')) {
+                      // Despite the new image being active, issue,
+                      // https://github.com/openbmc/openbmc/issues/2764, can
+                      // cause a system to brick, if the system reboots before
+                      // the service to set the U-Boot variables is complete.
+                      // Wait 10 seconds before rebooting to ensure this service
+                      // is complete. This issue is fixed in newer images, but
+                      // the user may be updating from an older image that does
+                      // not that have this fix.
+                      // TODO: remove this timeout after sufficient time has
+                      // passed.
+                      $timeout(function() {
+                        APIUtils.bmcReboot(
+                            function(response) {},
+                            function(error) {
+                              $scope.displayError({
+                                modal_title: 'Error during BMC reboot',
+                                title: 'Error during BMC reboot',
+                                desc: JSON.stringify(error.data),
+                                type: 'Error'
+                              });
+                            });
+                      }, 10000);
+                    }
+                  });
+            });
+        $scope.activate_confirm = false;
+      };
+
+      $scope.upload = function() {
+        if ($scope.file) {
+          $scope.uploading = true;
+          $scope.upload_success = false;
+          APIUtils.uploadImage($scope.file)
+              .then(
+                  function(response) {
+                    $scope.file = '';
+                    $scope.uploading = false;
+                    $scope.upload_success = true;
+                    $scope.loadFirmwares();
+                  },
+                  function(error) {
+                    $scope.uploading = false;
+                    console.log(error);
                     $scope.displayError({
-                      modal_title: 'Error during BMC reboot',
-                      title: 'Error during BMC reboot',
-                      desc: JSON.stringify(error.data),
+                      modal_title: 'Error during image upload',
+                      title: 'Error during image upload',
+                      desc: error,
                       type: 'Error'
                     });
                   });
-                }, 10000);
-              }
-            });
-          });
-          $scope.activate_confirm = false;
-        };
+        }
+      };
 
-        $scope.upload = function() {
-          if ($scope.file) {
-            $scope.uploading = true;
-            $scope.upload_success = false;
-            APIUtils.uploadImage($scope.file).then(function(response) {
-              $scope.file = '';
-              $scope.uploading = false;
-              $scope.upload_success = true;
-              $scope.loadFirmwares();
-            }, function(error) {
-              $scope.uploading = false;
-              console.log(error);
-              $scope.displayError({
-                modal_title: 'Error during image upload',
-                title: 'Error during image upload',
-                desc: error,
-                type: 'Error'
-              });
-            });
+      // TODO: openbmc/openbmc#1691 Add support to return
+      // the id of the newly created image, downloaded via
+      // tftp. Polling the number of software objects is a
+      // near term solution.
+      function waitForDownload() {
+        var deferred = $q.defer();
+        var startTime = new Date();
+        pollDownloadTimer = $interval(function() {
+          var now = new Date();
+          if ((now.getTime() - startTime.getTime()) >=
+              Constants.TIMEOUT.DOWNLOAD_IMAGE) {
+            $interval.cancel(pollDownloadTimer);
+            pollDownloadTimer = undefined;
+            deferred.reject(
+                new Error(Constants.MESSAGES.POLL.DOWNLOAD_IMAGE_TIMEOUT));
           }
-        };
 
-        //TODO: openbmc/openbmc#1691 Add support to return
-        //the id of the newly created image, downloaded via
-        //tftp. Polling the number of software objects is a
-        //near term solution.
-        function waitForDownload() {
-          var deferred = $q.defer();
-          var startTime = new Date();
-          pollDownloadTimer = $interval(function() {
-            var now = new Date();
-            if ((now.getTime() - startTime.getTime()) >= Constants.TIMEOUT.DOWNLOAD_IMAGE) {
-              $interval.cancel(pollDownloadTimer);
-              pollDownloadTimer = undefined;
-              deferred.reject(new Error(Constants.MESSAGES.POLL.DOWNLOAD_IMAGE_TIMEOUT));
-            }
-
-            APIUtils.getFirmwares().then(function(response) {
-              if (response.data.length === $scope.firmwares.length + 1) {
+          APIUtils.getFirmwares().then(
+              function(response) {
+                if (response.data.length === $scope.firmwares.length + 1) {
+                  $interval.cancel(pollDownloadTimer);
+                  pollDownloadTimer = undefined;
+                  deferred.resolve(response.data);
+                }
+              },
+              function(error) {
                 $interval.cancel(pollDownloadTimer);
                 pollDownloadTimer = undefined;
-                deferred.resolve(response.data);
-              }
-            }, function(error) {
-              $interval.cancel(pollDownloadTimer);
-              pollDownloadTimer = undefined;
-              deferred.reject(error);
-            });
-          }, Constants.POLL_INTERVALS.DOWNLOAD_IMAGE);
+                deferred.reject(error);
+              });
+        }, Constants.POLL_INTERVALS.DOWNLOAD_IMAGE);
 
-          return deferred.promise;
+        return deferred.promise;
+      }
+
+      $scope.download = function() {
+        $scope.download_success = false;
+        $scope.download_error_msg = '';
+        if (!$scope.download_host || !$scope.download_filename) {
+          $scope.download_error_msg = 'Field is required!';
+          return false;
         }
 
-        $scope.download = function() {
-          $scope.download_success = false;
-          $scope.download_error_msg = '';
-          if (!$scope.download_host || !$scope.download_filename) {
-            $scope.download_error_msg = 'Field is required!';
-            return false;
-          }
+        $scope.downloading = true;
+        APIUtils.getFirmwares()
+            .then(function(response) {
+              $scope.firmwares = response.data;
+            })
+            .then(function() {
+              return APIUtils
+                  .downloadImage($scope.download_host, $scope.download_filename)
+                  .then(function(downloadStatus) {
+                    return downloadStatus;
+                  });
+            })
+            .then(function(downloadStatus) {
+              return waitForDownload();
+            })
+            .then(
+                function(newFirmwareList) {
+                  $scope.download_host = '';
+                  $scope.download_filename = '';
+                  $scope.downloading = false;
+                  $scope.download_success = true;
+                  $scope.loadFirmwares();
+                },
+                function(error) {
+                  console.log(error);
+                  $scope.displayError({
+                    modal_title: 'Error during downloading Image',
+                    title: 'Error during downloading Image',
+                    desc: error,
+                    type: 'Error'
+                  });
+                  $scope.downloading = false;
+                });
+      };
 
-          $scope.downloading = true;
-          APIUtils.getFirmwares().then(function(response) {
-            $scope.firmwares = response.data;
-          }).then(function() {
-            return APIUtils.downloadImage($scope.download_host,
-              $scope.download_filename).then(function(downloadStatus) {
-              return downloadStatus;
+      $scope.changePriority = function(imageId, imageVersion, from, to) {
+        $scope.priority_image_id = imageId;
+        $scope.priority_image_version = imageVersion;
+        $scope.priority_from = from;
+        $scope.priority_to = to;
+        $scope.confirm_priority = true;
+      };
+
+      $scope.confirmChangePriority = function() {
+        $scope.loading = true;
+        APIUtils.changePriority($scope.priority_image_id, $scope.priority_to)
+            .then(function(response) {
+              $scope.loading = false;
+              if (response.status == 'error') {
+                $scope.displayError({
+                  modal_title: response.data.description,
+                  title: response.data.description,
+                  desc: response.data.exception,
+                  type: 'Error'
+                });
+              } else {
+                $scope.loadFirmwares();
+              }
             });
-          }).then(function(downloadStatus) {
-            return waitForDownload();
-          }).then(function(newFirmwareList) {
-            $scope.download_host = '';
-            $scope.download_filename = '';
-            $scope.downloading = false;
-            $scope.download_success = true;
-            $scope.loadFirmwares();
-          }, function(error) {
-            console.log(error);
+        $scope.confirm_priority = false;
+      };
+      $scope.deleteImage = function(imageId, imageVersion) {
+        $scope.delete_image_id = imageId;
+        $scope.delete_image_version = imageVersion;
+        $scope.confirm_delete = true;
+      };
+      $scope.confirmDeleteImage = function() {
+        $scope.loading = true;
+        APIUtils.deleteImage($scope.delete_image_id).then(function(response) {
+          $scope.loading = false;
+          if (response.status == 'error') {
             $scope.displayError({
-              modal_title: 'Error during downloading Image',
-              title: 'Error during downloading Image',
-              desc: error,
+              modal_title: response.data.description,
+              title: response.data.description,
+              desc: response.data.exception,
               type: 'Error'
             });
-            $scope.downloading = false;
-          });
-        };
-
-        $scope.changePriority = function(imageId, imageVersion, from, to) {
-          $scope.priority_image_id = imageId;
-          $scope.priority_image_version = imageVersion;
-          $scope.priority_from = from;
-          $scope.priority_to = to;
-          $scope.confirm_priority = true;
-        };
-
-        $scope.confirmChangePriority = function() {
-          $scope.loading = true;
-          APIUtils.changePriority($scope.priority_image_id, $scope.priority_to).then(function(response) {
-            $scope.loading = false;
-            if (response.status == 'error') {
-              $scope.displayError({
-                modal_title: response.data.description,
-                title: response.data.description,
-                desc: response.data.exception,
-                type: 'Error'
-              });
-            }
-            else {
-              $scope.loadFirmwares();
-            }
-          });
-          $scope.confirm_priority = false;
-        };
-        $scope.deleteImage = function(imageId, imageVersion) {
-          $scope.delete_image_id = imageId;
-          $scope.delete_image_version = imageVersion;
-          $scope.confirm_delete = true;
-        };
-        $scope.confirmDeleteImage = function() {
-          $scope.loading = true;
-          APIUtils.deleteImage($scope.delete_image_id).then(function(response) {
-            $scope.loading = false;
-            if (response.status == 'error') {
-              $scope.displayError({
-                modal_title: response.data.description,
-                title: response.data.description,
-                desc: response.data.exception,
-                type: 'Error'
-              });
-            }
-            else {
-              $scope.loadFirmwares();
-            }
-          });
-          $scope.confirm_delete = false;
-        };
-        $scope.fileNameChanged = function() {
-          $scope.file_empty = false;
-        };
-
-        $scope.filters = {
-          bmc: {
-            imageType: 'BMC'
-          },
-          host: {
-            imageType: 'Host'
+          } else {
+            $scope.loadFirmwares();
           }
-        };
+        });
+        $scope.confirm_delete = false;
+      };
+      $scope.fileNameChanged = function() {
+        $scope.file_empty = false;
+      };
 
-        $scope.loadFirmwares = function() {
-          APIUtils.getFirmwares().then(function(result) {
-            $scope.firmwares = result.data;
-            $scope.bmcActiveVersion = result.bmcActiveVersion;
-            $scope.hostActiveVersion = result.hostActiveVersion;
-          });
-        };
+      $scope.filters = {bmc: {imageType: 'BMC'}, host: {imageType: 'Host'}};
 
-        $scope.loadFirmwares();
-      }
-    ]);
+      $scope.loadFirmwares = function() {
+        APIUtils.getFirmwares().then(function(result) {
+          $scope.firmwares = result.data;
+          $scope.bmcActiveVersion = result.bmcActiveVersion;
+          $scope.hostActiveVersion = result.hostActiveVersion;
+        });
+      };
+
+      $scope.loadFirmwares();
+    }
+  ]);
 
 })(angular);
diff --git a/app/configuration/controllers/network-controller.js b/app/configuration/controllers/network-controller.js
index 4eff0cd..e764de8 100644
--- a/app/configuration/controllers/network-controller.js
+++ b/app/configuration/controllers/network-controller.js
@@ -9,34 +9,30 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.configuration')
-    .controller('networkController', [
-      '$scope',
-      '$window',
-      'APIUtils',
-      'dataService',
-      function($scope, $window, APIUtils, dataService) {
-        $scope.dataService = dataService;
-        $scope.network = {};
-        $scope.interface = {};
-        $scope.networkDevice = false;
-        $scope.hostname = '';
+  angular.module('app.configuration').controller('networkController', [
+    '$scope', '$window', 'APIUtils', 'dataService',
+    function($scope, $window, APIUtils, dataService) {
+      $scope.dataService = dataService;
+      $scope.network = {};
+      $scope.interface = {};
+      $scope.networkDevice = false;
+      $scope.hostname = '';
 
-        $scope.selectInterface = function(interfaceId) {
-          $scope.interface = $scope.network.interfaces[interfaceId];
-          $scope.selectedInterface = interfaceId;
-          $scope.networkDevice = false;
-        };
-        APIUtils.getNetworkInfo().then(function(data) {
-          $scope.network = data.formatted_data;
-          $scope.hostname = data.hostname;
-          if ($scope.network.interface_ids.length) {
-            $scope.selectedInterface = $scope.network.interface_ids[0];
-            $scope.interface = $scope.network.interfaces[$scope.selectedInterface];
-          }
-        });
-      }
-    ]);
+      $scope.selectInterface = function(interfaceId) {
+        $scope.interface = $scope.network.interfaces[interfaceId];
+        $scope.selectedInterface = interfaceId;
+        $scope.networkDevice = false;
+      };
+      APIUtils.getNetworkInfo().then(function(data) {
+        $scope.network = data.formatted_data;
+        $scope.hostname = data.hostname;
+        if ($scope.network.interface_ids.length) {
+          $scope.selectedInterface = $scope.network.interface_ids[0];
+          $scope.interface =
+              $scope.network.interfaces[$scope.selectedInterface];
+        }
+      });
+    }
+  ]);
 
 })(angular);
diff --git a/app/configuration/controllers/security-controller.js b/app/configuration/controllers/security-controller.js
index d250ac7..e04bdfa 100644
--- a/app/configuration/controllers/security-controller.js
+++ b/app/configuration/controllers/security-controller.js
@@ -9,16 +9,11 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.configuration')
-    .controller('securityController', [
-      '$scope',
-      '$window',
-      'APIUtils',
-      'dataService',
-      function($scope, $window, APIUtils, dataService) {
-        $scope.dataService = dataService;
-      }
-    ]);
+  angular.module('app.configuration').controller('securityController', [
+    '$scope', '$window', 'APIUtils', 'dataService',
+    function($scope, $window, APIUtils, dataService) {
+      $scope.dataService = dataService;
+    }
+  ]);
 
 })(angular);
diff --git a/app/configuration/index.js b/app/configuration/index.js
index 869af04..abe0190 100644
--- a/app/configuration/index.js
+++ b/app/configuration/index.js
@@ -9,41 +9,45 @@
   'use strict';
 
   angular
-    .module('app.configuration', [
-      'ngRoute',
-      'app.constants',
-      'app.common.services'
-    ])
-    // Route configuration
-    .config(['$routeProvider', function($routeProvider) {
-      $routeProvider
-        .when('/configuration/network', {
-          'template': require('./controllers/network-controller.html'),
-          'controller': 'networkController',
-          authenticated: true
-        })
-        .when('/configuration/security', {
-          'template': require('./controllers/security-controller.html'),
-          'controller': 'securityController',
-          authenticated: true
-        }).when('/configuration/date-time', {
-          'template': require('./controllers/date-time-controller.html'),
-          'controller': 'dateTimeController',
-          authenticated: true
-        })
-        .when('/configuration/file', {
-          'template': require('./controllers/file-controller.html'),
-          'controller': 'fileController',
-          authenticated: true
-        }).when('/configuration', {
-          'template': require('./controllers/network-controller.html'),
-          'controller': 'networkController',
-          authenticated: true
-        }).when('/configuration/firmware', {
-          'template': require('./controllers/firmware-controller.html'),
-          'controller': 'firmwareController',
-          authenticated: true
-        });
-    }]);
+      .module(
+          'app.configuration',
+          ['ngRoute', 'app.constants', 'app.common.services'])
+      // Route configuration
+      .config([
+        '$routeProvider',
+        function($routeProvider) {
+          $routeProvider
+              .when('/configuration/network', {
+                'template': require('./controllers/network-controller.html'),
+                'controller': 'networkController',
+                authenticated: true
+              })
+              .when('/configuration/security', {
+                'template': require('./controllers/security-controller.html'),
+                'controller': 'securityController',
+                authenticated: true
+              })
+              .when('/configuration/date-time', {
+                'template': require('./controllers/date-time-controller.html'),
+                'controller': 'dateTimeController',
+                authenticated: true
+              })
+              .when('/configuration/file', {
+                'template': require('./controllers/file-controller.html'),
+                'controller': 'fileController',
+                authenticated: true
+              })
+              .when('/configuration', {
+                'template': require('./controllers/network-controller.html'),
+                'controller': 'networkController',
+                authenticated: true
+              })
+              .when('/configuration/firmware', {
+                'template': require('./controllers/firmware-controller.html'),
+                'controller': 'firmwareController',
+                authenticated: true
+              });
+        }
+      ]);
 
 })(window.angular);
diff --git a/app/constants/environment-constants.js b/app/constants/environment-constants.js
index a40beb5..26986fc 100644
--- a/app/constants/environment-constants.js
+++ b/app/constants/environment-constants.js
@@ -9,20 +9,18 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.constants')
-    .constant('EnvironmentConstants', {
-      'inDevelopmentMode': true,
-      'RestConstants': {},
-      FLASH_MESSAGE: {
-        duration: 2000,
-        classes: {
-          warning: 'message-warning',
-          info: 'message-info',
-          error: 'message-error',
-          success: 'message-success'
-        }
+  angular.module('app.constants').constant('EnvironmentConstants', {
+    'inDevelopmentMode': true,
+    'RestConstants': {},
+    FLASH_MESSAGE: {
+      duration: 2000,
+      classes: {
+        warning: 'message-warning',
+        info: 'message-info',
+        error: 'message-error',
+        success: 'message-success'
       }
-    });
+    }
+  });
 
 })(window.angular);
diff --git a/app/constants/index.js b/app/constants/index.js
index 5d7e18c..cc46665 100644
--- a/app/constants/index.js
+++ b/app/constants/index.js
@@ -8,8 +8,6 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.constants', [])
-    .constant('AppConstants', {});
+  angular.module('app.constants', []).constant('AppConstants', {});
 
 })(window.angular);
diff --git a/app/firmware/controllers/bmc-controller.js b/app/firmware/controllers/bmc-controller.js
index 78e87a7..3d38672 100644
--- a/app/firmware/controllers/bmc-controller.js
+++ b/app/firmware/controllers/bmc-controller.js
@@ -9,16 +9,11 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.firmware')
-    .controller('bmcController', [
-      '$scope',
-      '$window',
-      'APIUtils',
-      'dataService',
-      function($scope, $window, APIUtils, dataService) {
-        $scope.dataService = dataService;
-      }
-    ]);
+  angular.module('app.firmware').controller('bmcController', [
+    '$scope', '$window', 'APIUtils', 'dataService',
+    function($scope, $window, APIUtils, dataService) {
+      $scope.dataService = dataService;
+    }
+  ]);
 
 })(angular);
diff --git a/app/firmware/controllers/server-controller.js b/app/firmware/controllers/server-controller.js
index 2b1a673..b57241b 100644
--- a/app/firmware/controllers/server-controller.js
+++ b/app/firmware/controllers/server-controller.js
@@ -9,16 +9,11 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.firmware')
-    .controller('serverController', [
-      '$scope',
-      '$window',
-      'APIUtils',
-      'dataService',
-      function($scope, $window, APIUtils, dataService) {
-        $scope.dataService = dataService;
-      }
-    ]);
+  angular.module('app.firmware').controller('serverController', [
+    '$scope', '$window', 'APIUtils', 'dataService',
+    function($scope, $window, APIUtils, dataService) {
+      $scope.dataService = dataService;
+    }
+  ]);
 
 })(angular);
diff --git a/app/firmware/index.js b/app/firmware/index.js
index 3e4189c..f25e18e 100644
--- a/app/firmware/index.js
+++ b/app/firmware/index.js
@@ -9,29 +9,29 @@
   'use strict';
 
   angular
-    .module('app.firmware', [
-      'ngRoute',
-      'app.constants',
-      'app.common.services'
-    ])
-    // Route configuration
-    .config(['$routeProvider', function($routeProvider) {
-      $routeProvider
-        .when('/firmware/bmc', {
-          'template': require('./controllers/bmc-controller.html'),
-          'controller': 'bmcController',
-          authenticated: true
-        })
-        .when('/firmware/server', {
-          'template': require('./controllers/server-controller.html'),
-          'controller': 'serverController',
-          authenticated: true
-        })
-        .when('/firmware', {
-          'template': reqire('./controllers/bmc-controller.html'),
-          'controller': 'bmcController',
-          authenticated: true
-        });
-    }]);
+      .module(
+          'app.firmware', ['ngRoute', 'app.constants', 'app.common.services'])
+      // Route configuration
+      .config([
+        '$routeProvider',
+        function($routeProvider) {
+          $routeProvider
+              .when('/firmware/bmc', {
+                'template': require('./controllers/bmc-controller.html'),
+                'controller': 'bmcController',
+                authenticated: true
+              })
+              .when('/firmware/server', {
+                'template': require('./controllers/server-controller.html'),
+                'controller': 'serverController',
+                authenticated: true
+              })
+              .when('/firmware', {
+                'template': reqire('./controllers/bmc-controller.html'),
+                'controller': 'bmcController',
+                authenticated: true
+              });
+        }
+      ]);
 
 })(window.angular);
diff --git a/app/index.js b/app/index.js
index 5797ec4..c3c1630 100644
--- a/app/index.js
+++ b/app/index.js
@@ -1,5 +1,6 @@
 /**
- * A module which contains the definition of the application and the base of configuration
+ * A module which contains the definition of the application and the base of
+ * configuration
  *
  * @module app/index/services/index
  * @exports app/index
@@ -10,16 +11,18 @@
 import 'bootstrap/dist/css/bootstrap.css';
 import 'bootstrap/dist/css/bootstrap-theme.css';
 import 'font-awesome/css/font-awesome.css';
+
 import angular from 'angular';
-import angular_cookies from 'angular-cookies';
-import angular_sanitize from 'angular-sanitize';
-import angular_ui_router from 'angular-ui-router';
 import angular_animate from 'angular-animate';
 import angular_clipboard from 'angular-clipboard';
-import angular_ui_bootstrap from 'angular-ui-bootstrap';
+import angular_cookies from 'angular-cookies';
 import angular_route from 'angular-route';
+import angular_sanitize from 'angular-sanitize';
+import angular_ui_bootstrap from 'angular-ui-bootstrap';
+import angular_ui_router from 'angular-ui-router';
 import angular_utils from 'angularUtils/src/angularUtils.js';
 import angular_utils_pagination from 'angularUtils/src/directives/pagination/dirPagination.js';
+
 require('./styles/index.scss');
 
 // TODO(Ed)  clean this up, add the appropriate imports to phosphor-webui
@@ -96,82 +99,82 @@
   'use strict';
 
   angular
-    .module('app', [
-      // Dependencies
-      'ngRoute',
-      'angular-clipboard',
-      'angularUtils.directives.dirPagination',
-      // Basic resources
-      'app.constants',
-      'app.templates',
-      'app.vendors',
-      'app.common.services',
-      'app.common.directives',
-      'app.common.filters',
-      // Model resources
-      'app.login',
-      'app.overview',
-      'app.serverControl',
-      'app.serverHealth',
-      'app.configuration',
-      'app.users',
-      'app.multiServer'
-    ])
-    // Route configuration
-    .config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
-      $locationProvider.hashPrefix('');
-      $routeProvider
-        .otherwise({
-          'redirectTo': '/login'
-        });
-    }])
-    .config(['$compileProvider', function($compileProvider) {
-      $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|file|data|blob):/);
-    }])
-    .config(['$httpProvider', function($httpProvider) {
-      $httpProvider.interceptors.push('apiInterceptor');
-    }])
-    .run(['$rootScope', '$location', 'dataService', 'userModel',
-      function($rootScope, $location, dataService, userModel) {
-        $rootScope.dataService = dataService;
-        dataService.path = $location.path();
-        $rootScope.$on('$routeChangeStart', function(event, next, current) {
-          if (next.$$route == null || next.$$route == undefined) return;
-          if (next.$$route.authenticated) {
-            if (!userModel.isLoggedIn()) {
-              $location.path('/login');
-            }
-          }
-
-          if (next.$$route.originalPath == '/' ||
-            next.$$route.originalPath == '/login') {
-            if (userModel.isLoggedIn()) {
-              if (current && current.$$route) {
-                $location.path(current.$$route.originalPath);
-              }
-              else {
-                $location.path('/overview/server');
+      .module(
+          'app',
+          [
+            // Dependencies
+            'ngRoute', 'angular-clipboard',
+            'angularUtils.directives.dirPagination',
+            // Basic resources
+            'app.constants', 'app.templates', 'app.vendors',
+            'app.common.services', 'app.common.directives',
+            'app.common.filters',
+            // Model resources
+            'app.login', 'app.overview', 'app.serverControl',
+            'app.serverHealth', 'app.configuration', 'app.users',
+            'app.multiServer'
+          ])
+      // Route configuration
+      .config([
+        '$routeProvider', '$locationProvider',
+        function($routeProvider, $locationProvider) {
+          $locationProvider.hashPrefix('');
+          $routeProvider.otherwise({'redirectTo': '/login'});
+        }
+      ])
+      .config([
+        '$compileProvider',
+        function($compileProvider) {
+          $compileProvider.aHrefSanitizationWhitelist(
+              /^\s*(https?|ftp|mailto|tel|file|data|blob):/);
+        }
+      ])
+      .config([
+        '$httpProvider',
+        function($httpProvider) {
+          $httpProvider.interceptors.push('apiInterceptor');
+        }
+      ])
+      .run([
+        '$rootScope', '$location', 'dataService', 'userModel',
+        function($rootScope, $location, dataService, userModel) {
+          $rootScope.dataService = dataService;
+          dataService.path = $location.path();
+          $rootScope.$on('$routeChangeStart', function(event, next, current) {
+            if (next.$$route == null || next.$$route == undefined) return;
+            if (next.$$route.authenticated) {
+              if (!userModel.isLoggedIn()) {
+                $location.path('/login');
               }
             }
-          }
-        });
-        $rootScope.$on('$locationChangeSuccess', function(event) {
-          var path = $location.path();
-          dataService.path = path;
-          if (['/', '/login', '/logout'].indexOf(path) == -1 &&
-            path.indexOf('/login') == -1) {
-            dataService.showNavigation = true;
-          }
-          else {
-            dataService.showNavigation = false;
-          }
-        });
 
-        $rootScope.$on('timedout-user', function() {
-          sessionStorage.removeItem('LOGIN_ID');
-          $location.path('/login');
-        });
-      }
-    ]);
+            if (next.$$route.originalPath == '/' ||
+                next.$$route.originalPath == '/login') {
+              if (userModel.isLoggedIn()) {
+                if (current && current.$$route) {
+                  $location.path(current.$$route.originalPath);
+                } else {
+                  $location.path('/overview/server');
+                }
+              }
+            }
+          });
+          $rootScope.$on('$locationChangeSuccess', function(event) {
+            var path = $location.path();
+            dataService.path = path;
+            if (['/', '/login', '/logout'].indexOf(path) == -1 &&
+                path.indexOf('/login') == -1) {
+              dataService.showNavigation = true;
+            } else {
+              dataService.showNavigation = false;
+            }
+          });
+
+          $rootScope.$on('timedout-user', function() {
+            sessionStorage.removeItem('LOGIN_ID');
+            $location.path('/login');
+          });
+        }
+      ]);
 
 })(window.angular);
diff --git a/app/login/controllers/login-controller.js b/app/login/controllers/login-controller.js
index 03bbc15..be79bb6 100644
--- a/app/login/controllers/login-controller.js
+++ b/app/login/controllers/login-controller.js
@@ -9,51 +9,40 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.login')
-    .controller('LoginController', [
-      '$scope',
-      '$window',
-      'APIUtils',
-      'dataService',
-      'userModel',
-      '$routeParams',
-      function($scope, $window, APIUtils, dataService, userModel, $routeParams) {
-        $scope.dataService = dataService;
-        $scope.host = $scope.dataService.host.replace(/^https?\:\/\//ig, '');
+  angular.module('app.login').controller('LoginController', [
+    '$scope', '$window', 'APIUtils', 'dataService', 'userModel', '$routeParams',
+    function($scope, $window, APIUtils, dataService, userModel, $routeParams) {
+      $scope.dataService = dataService;
+      $scope.host = $scope.dataService.host.replace(/^https?\:\/\//ig, '');
 
-        $scope.tryLogin = function(host, username, password, event) {
-          if (event.keyCode === 13) {
-            $scope.login(host, username, password);
-          }
-        };
-        $scope.login = function(host, username, password) {
-          $scope.error = false;
-          $scope.description = false;
+      $scope.tryLogin = function(host, username, password, event) {
+        if (event.keyCode === 13) {
+          $scope.login(host, username, password);
+        }
+      };
+      $scope.login = function(host, username, password) {
+        $scope.error = false;
+        $scope.description = false;
 
-          if (!username || username == '' ||
-            !password || password == '' ||
-            !host || host == ''
-          ) {
-            return false;
-          }
-          else {
-            $scope.dataService.setHost(host);
-            userModel.login(username, password, function(status, description) {
-              if (status) {
-                $scope.$emit('user-logged-in', {});
-                $window.location.hash = '#/overview/server';
+        if (!username || username == '' || !password || password == '' ||
+            !host || host == '') {
+          return false;
+        } else {
+          $scope.dataService.setHost(host);
+          userModel.login(username, password, function(status, description) {
+            if (status) {
+              $scope.$emit('user-logged-in', {});
+              $window.location.hash = '#/overview/server';
+            } else {
+              $scope.error = true;
+              if (description) {
+                $scope.description = description;
               }
-              else {
-                $scope.error = true;
-                if (description) {
-                  $scope.description = description;
-                }
-              }
-            });
-          }
-        };
-      }
-    ]);
+            }
+          });
+        }
+      };
+    }
+  ]);
 
 })(angular);
diff --git a/app/login/index.js b/app/login/index.js
index 04343f5..9ec06bf 100644
--- a/app/login/index.js
+++ b/app/login/index.js
@@ -9,19 +9,17 @@
   'use strict';
 
   angular
-    .module('app.login', [
-      'ngRoute',
-      'app.constants',
-      'app.common.services'
-    ])
-    // Route configuration
-    .config(['$routeProvider', function($routeProvider) {
-      $routeProvider
-        .when('/login', {
-          'template': require('./controllers/login-controller.html'),
-          'controller': 'LoginController',
-          authenticated: false
-        });
-    }]);
+      .module('app.login', ['ngRoute', 'app.constants', 'app.common.services'])
+      // Route configuration
+      .config([
+        '$routeProvider',
+        function($routeProvider) {
+          $routeProvider.when('/login', {
+            'template': require('./controllers/login-controller.html'),
+            'controller': 'LoginController',
+            authenticated: false
+          });
+        }
+      ]);
 
 })(window.angular);
diff --git a/app/multi-server/controllers/multi-server-controller.js b/app/multi-server/controllers/multi-server-controller.js
index 71ec3ac..fc69f81 100644
--- a/app/multi-server/controllers/multi-server-controller.js
+++ b/app/multi-server/controllers/multi-server-controller.js
@@ -9,51 +9,45 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.overview')
-    .controller('multiServerController', [
-      '$scope',
-      '$window',
-      'APIUtils',
-      'dataService',
-      function($scope, $window, APIUtils, dataService) {
-        $scope.dataService = dataService;
+  angular.module('app.overview').controller('multiServerController', [
+    '$scope', '$window', 'APIUtils', 'dataService',
+    function($scope, $window, APIUtils, dataService) {
+      $scope.dataService = dataService;
+      $scope.customSearch = '';
+      $scope.searchTerms = [];
+      $scope.loading = false;
+      $scope.clear = function() {
         $scope.customSearch = '';
         $scope.searchTerms = [];
-        $scope.loading = false;
-        $scope.clear = function() {
-          $scope.customSearch = '';
-          $scope.searchTerms = [];
-        };
+      };
 
-        $scope.doSearchOnEnter = function(event) {
-          var search = $scope.customSearch.replace(/^\s+/g, '').replace(/\s+$/g, '');
-          if (event.keyCode === 13 &&
-            search.length >= 2) {
-            $scope.searchTerms = $scope.customSearch.split(' ');
+      $scope.doSearchOnEnter = function(event) {
+        var search =
+            $scope.customSearch.replace(/^\s+/g, '').replace(/\s+$/g, '');
+        if (event.keyCode === 13 && search.length >= 2) {
+          $scope.searchTerms = $scope.customSearch.split(' ');
+        } else {
+          if (search.length == 0) {
+            $scope.searchTerms = [];
           }
-          else {
-            if (search.length == 0) {
-              $scope.searchTerms = [];
-            }
-          }
-        };
+        }
+      };
 
-        $scope.doSearchOnClick = function() {
-          var search = $scope.customSearch.replace(/^\s+/g, '').replace(/\s+$/g, '');
-          if (search.length >= 2) {
-            $scope.searchTerms = $scope.customSearch.split(' ');
+      $scope.doSearchOnClick = function() {
+        var search =
+            $scope.customSearch.replace(/^\s+/g, '').replace(/\s+$/g, '');
+        if (search.length >= 2) {
+          $scope.searchTerms = $scope.customSearch.split(' ');
+        } else {
+          if (search.length == 0) {
+            $scope.searchTerms = [];
           }
-          else {
-            if (search.length == 0) {
-              $scope.searchTerms = [];
-            }
-          }
-        };
-        $scope.addServer = function() {
-          $scope.multi_server_add = !$scope.multi_server_add;
-        };
-      }
-    ]);
+        }
+      };
+      $scope.addServer = function() {
+        $scope.multi_server_add = !$scope.multi_server_add;
+      };
+    }
+  ]);
 
 })(angular);
diff --git a/app/multi-server/index.js b/app/multi-server/index.js
index 97bd67a..b96ebb5 100644
--- a/app/multi-server/index.js
+++ b/app/multi-server/index.js
@@ -9,19 +9,19 @@
   'use strict';
 
   angular
-    .module('app.multiServer', [
-      'ngRoute',
-      'app.constants',
-      'app.common.services'
-    ])
-    // Route configuration
-    .config(['$routeProvider', function($routeProvider) {
-      $routeProvider
-        .when('/multi-server/overview', {
-          'template': require('./controllers/multi-server-controller.html'),
-          'controller': 'multiServerController',
-          authenticated: true
-        });
-    }]);
+      .module(
+          'app.multiServer',
+          ['ngRoute', 'app.constants', 'app.common.services'])
+      // Route configuration
+      .config([
+        '$routeProvider',
+        function($routeProvider) {
+          $routeProvider.when('/multi-server/overview', {
+            'template': require('./controllers/multi-server-controller.html'),
+            'controller': 'multiServerController',
+            authenticated: true
+          });
+        }
+      ]);
 
 })(window.angular);
diff --git a/app/overview/controllers/system-overview-controller.js b/app/overview/controllers/system-overview-controller.js
index c37765c..ece0bde 100644
--- a/app/overview/controllers/system-overview-controller.js
+++ b/app/overview/controllers/system-overview-controller.js
@@ -9,129 +9,134 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.overview')
-    .controller('systemOverviewController', [
-      '$scope',
-      '$window',
-      'APIUtils',
-      'dataService',
-      '$q',
-      function($scope, $window, APIUtils, dataService, $q) {
-        $scope.dataService = dataService;
-        $scope.dropdown_selected = false;
-        $scope.tmz = 'EDT';
-        $scope.logs = [];
-        $scope.server_info = {};
-        $scope.bmc_firmware = '';
-        $scope.bmc_time = '';
-        $scope.server_firmware = '';
-        $scope.power_consumption = '';
-        $scope.power_cap = '';
-        $scope.bmc_ip_addresses = [];
-        $scope.loading = false;
-        $scope.edit_hostname = false;
+  angular.module('app.overview').controller('systemOverviewController', [
+    '$scope', '$window', 'APIUtils', 'dataService', '$q',
+    function($scope, $window, APIUtils, dataService, $q) {
+      $scope.dataService = dataService;
+      $scope.dropdown_selected = false;
+      $scope.tmz = 'EDT';
+      $scope.logs = [];
+      $scope.server_info = {};
+      $scope.bmc_firmware = '';
+      $scope.bmc_time = '';
+      $scope.server_firmware = '';
+      $scope.power_consumption = '';
+      $scope.power_cap = '';
+      $scope.bmc_ip_addresses = [];
+      $scope.loading = false;
+      $scope.edit_hostname = false;
 
-        loadOverviewData();
+      loadOverviewData();
 
-        function loadOverviewData() {
-          $scope.loading = true;
+      function loadOverviewData() {
+        $scope.loading = true;
 
-          var getLogsPromise =
-            APIUtils.getLogs().then(function(data) {
+        var getLogsPromise = APIUtils.getLogs().then(
+            function(data) {
               $scope.logs = data.data.filter(function(log) {
                 return log.severity_flags.high == true;
               });
-            }, function(error) {
+            },
+            function(error) {
               console.log(JSON.stringify(error));
             });
 
-          var getFirmwaresPromise =
-            APIUtils.getFirmwares().then(function(data) {
+        var getFirmwaresPromise = APIUtils.getFirmwares().then(
+            function(data) {
               $scope.bmc_firmware = data.bmcActiveVersion;
               $scope.server_firmware = data.hostActiveVersion;
-            }, function(error) {
+            },
+            function(error) {
               console.log(JSON.stringify(error));
             });
 
-          var getLEDStatePromise =
-            APIUtils.getLEDState().then(function(data) {
+        var getLEDStatePromise = APIUtils.getLEDState().then(
+            function(data) {
               if (data == APIUtils.LED_STATE.on) {
                 dataService.LED_state = APIUtils.LED_STATE_TEXT.on;
-              }
-              else {
+              } else {
                 dataService.LED_state = APIUtils.LED_STATE_TEXT.off;
               }
-            }, function(error) {
+            },
+            function(error) {
               console.log(JSON.stringify(error));
             });
 
-          var getBMCTimePromise =
-            APIUtils.getBMCTime().then(function(data) {
+        var getBMCTimePromise = APIUtils.getBMCTime().then(
+            function(data) {
               $scope.bmc_time = data.data.Elapsed / 1000;
-            }, function(error) {
+            },
+            function(error) {
               console.log(JSON.stringify(error));
             });
 
-          var getServerInfoPromise =
-            APIUtils.getServerInfo().then(function(data) {
+        var getServerInfoPromise = APIUtils.getServerInfo().then(
+            function(data) {
               $scope.server_info = data.data;
-            }, function(error) {
+            },
+            function(error) {
               console.log(JSON.stringify(error));
             });
 
-          var getPowerConsumptionPromise =
-            APIUtils.getPowerConsumption().then(function(data) {
+        var getPowerConsumptionPromise = APIUtils.getPowerConsumption().then(
+            function(data) {
               $scope.power_consumption = data;
-            }, function(error) {
+            },
+            function(error) {
               console.log(JSON.stringify(error));
             });
 
-          var getPowerCapPromise =
-            APIUtils.getPowerCap().then(function(data) {
+        var getPowerCapPromise = APIUtils.getPowerCap().then(
+            function(data) {
               $scope.power_cap = data;
-            }, function(error) {
+            },
+            function(error) {
               console.log(JSON.stringify(error));
             });
 
-          var getNetworkInfoPromise =
-            APIUtils.getNetworkInfo().then(function(data) {
+        var getNetworkInfoPromise = APIUtils.getNetworkInfo().then(
+            function(data) {
               // TODO: openbmc/openbmc#3150 Support IPV6 when
               // officially supported by the backend
-              $scope.bmc_ip_addresses =
-                data.formatted_data.ip_addresses.ipv4;
-            }, function(error) {
+              $scope.bmc_ip_addresses = data.formatted_data.ip_addresses.ipv4;
+            },
+            function(error) {
               console.log(JSON.stringify(error));
             });
 
-          var promises = [
-            getLogsPromise,
-            getFirmwaresPromise,
-            getLEDStatePromise,
-            getBMCTimePromise,
-            getServerInfoPromise,
-            getPowerConsumptionPromise,
-            getPowerCapPromise,
-            getNetworkInfoPromise,
-          ];
+        var promises = [
+          getLogsPromise,
+          getFirmwaresPromise,
+          getLEDStatePromise,
+          getBMCTimePromise,
+          getServerInfoPromise,
+          getPowerConsumptionPromise,
+          getPowerCapPromise,
+          getNetworkInfoPromise,
+        ];
 
-          $q.all(promises).finally(function() {
-            $scope.loading = false;
-          });
-        }
+        $q.all(promises).finally(function() {
+          $scope.loading = false;
+        });
+      }
 
-        $scope.toggleLED = function() {
-          var toggleState = (dataService.LED_state == APIUtils.LED_STATE_TEXT.on) ?
-            APIUtils.LED_STATE.off : APIUtils.LED_STATE.on;
-          dataService.LED_state = (dataService.LED_state == APIUtils.LED_STATE_TEXT.on) ?
-            APIUtils.LED_STATE_TEXT.off : APIUtils.LED_STATE_TEXT.on;
-          APIUtils.setLEDState(toggleState, function(status) {});
-        };
+      $scope.toggleLED = function() {
+        var toggleState =
+            (dataService.LED_state == APIUtils.LED_STATE_TEXT.on) ?
+            APIUtils.LED_STATE.off :
+            APIUtils.LED_STATE.on;
+        dataService.LED_state =
+            (dataService.LED_state == APIUtils.LED_STATE_TEXT.on) ?
+            APIUtils.LED_STATE_TEXT.off :
+            APIUtils.LED_STATE_TEXT.on;
+        APIUtils.setLEDState(toggleState, function(status) {});
+      };
 
-        $scope.saveHostname = function(hostname) {
-          $scope.edit_hostname = false;
-          $scope.loading = true;
-          APIUtils.setHostname(hostname).then(function(data) {
+      $scope.saveHostname = function(hostname) {
+        $scope.edit_hostname = false;
+        $scope.loading = true;
+        APIUtils.setHostname(hostname).then(
+            function(data) {
               APIUtils.getNetworkInfo().then(function(data) {
                 dataService.setNetworkInfo(data);
               });
@@ -139,9 +144,9 @@
             function(error) {
               console.log(error);
             });
-          $scope.loading = false;
-        };
-      }
-    ]);
+        $scope.loading = false;
+      };
+    }
+  ]);
 
 })(angular);
diff --git a/app/overview/index.js b/app/overview/index.js
index aa3f023..81c357d 100644
--- a/app/overview/index.js
+++ b/app/overview/index.js
@@ -9,24 +9,26 @@
   'use strict';
 
   angular
-    .module('app.overview', [
-      'ngRoute',
-      'app.constants',
-      'app.common.services'
-    ])
-    // Route configuration
-    .config(['$routeProvider', function($routeProvider) {
-      $routeProvider
-        .when('/overview/server', {
-          'template': require('./controllers/system-overview-controller.html'),
-          'controller': 'systemOverviewController',
-          authenticated: true
-        })
-        .when('/overview', {
-          'template': require('./controllers/system-overview-controller.html'),
-          'controller': 'systemOverviewController',
-          authenticated: true
-        });
-    }]);
+      .module(
+          'app.overview', ['ngRoute', 'app.constants', 'app.common.services'])
+      // Route configuration
+      .config([
+        '$routeProvider',
+        function($routeProvider) {
+          $routeProvider
+              .when('/overview/server', {
+                'template':
+                    require('./controllers/system-overview-controller.html'),
+                'controller': 'systemOverviewController',
+                authenticated: true
+              })
+              .when('/overview', {
+                'template':
+                    require('./controllers/system-overview-controller.html'),
+                'controller': 'systemOverviewController',
+                authenticated: true
+              });
+        }
+      ]);
 
 })(window.angular);
diff --git a/app/server-control/controllers/bmc-reboot-controller.js b/app/server-control/controllers/bmc-reboot-controller.js
index 8be09eb..06097b8 100644
--- a/app/server-control/controllers/bmc-reboot-controller.js
+++ b/app/server-control/controllers/bmc-reboot-controller.js
@@ -9,30 +9,26 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.serverControl')
-    .controller('bmcRebootController', [
-      '$scope',
-      '$window',
-      'APIUtils',
-      'dataService',
-      function($scope, $window, APIUtils, dataService) {
-        $scope.dataService = dataService;
-        $scope.confirm = false;
-        $scope.rebootConfirm = function() {
-          if ($scope.confirm) {
-            return;
-          }
-          $scope.confirm = true;
-        };
-        $scope.reboot = function() {
-          dataService.setUnreachableState();
-          APIUtils.bmcReboot(function(response) {
-            //@NOTE: using common event to reload server status, may be a better event listener name?
-            $scope.$emit('user-logged-in', {});
-          });
-        };
-      }
-    ]);
+  angular.module('app.serverControl').controller('bmcRebootController', [
+    '$scope', '$window', 'APIUtils', 'dataService',
+    function($scope, $window, APIUtils, dataService) {
+      $scope.dataService = dataService;
+      $scope.confirm = false;
+      $scope.rebootConfirm = function() {
+        if ($scope.confirm) {
+          return;
+        }
+        $scope.confirm = true;
+      };
+      $scope.reboot = function() {
+        dataService.setUnreachableState();
+        APIUtils.bmcReboot(function(response) {
+          //@NOTE: using common event to reload server status, may be a better
+          // event listener name?
+          $scope.$emit('user-logged-in', {});
+        });
+      };
+    }
+  ]);
 
 })(angular);
diff --git a/app/server-control/controllers/power-operations-controller.js b/app/server-control/controllers/power-operations-controller.js
index 06fb371..4ae732f 100644
--- a/app/server-control/controllers/power-operations-controller.js
+++ b/app/server-control/controllers/power-operations-controller.js
@@ -9,302 +9,329 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.serverControl')
-    .controller('powerOperationsController', [
-      '$scope',
-      'APIUtils',
-      'dataService',
-      'Constants',
-      '$timeout',
-      '$interval',
-      '$interpolate',
-      '$q',
-      function($scope, APIUtils, dataService, Constants, $timeout,
-        $interval, $interpolate, $q) {
-        $scope.dataService = dataService;
-        $scope.confirm = false;
-        $scope.power_confirm = false;
-        $scope.warmboot_confirm = false;
-        $scope.coldboot_confirm = false;
-        $scope.orderly_confirm = false;
-        $scope.immediately_confirm = false;
-        $scope.loading = false;
+  angular.module('app.serverControl').controller('powerOperationsController', [
+    '$scope', 'APIUtils', 'dataService', 'Constants', '$timeout', '$interval',
+    '$interpolate', '$q',
+    function(
+        $scope, APIUtils, dataService, Constants, $timeout, $interval,
+        $interpolate, $q) {
+      $scope.dataService = dataService;
+      $scope.confirm = false;
+      $scope.power_confirm = false;
+      $scope.warmboot_confirm = false;
+      $scope.coldboot_confirm = false;
+      $scope.orderly_confirm = false;
+      $scope.immediately_confirm = false;
+      $scope.loading = false;
 
-        var pollChassisStatusTimer = undefined;
-        var pollHostStatusTimer = undefined;
-        var pollStartTime = null;
+      var pollChassisStatusTimer = undefined;
+      var pollHostStatusTimer = undefined;
+      var pollStartTime = null;
 
-        //@TODO: call api and get proper state
-        $scope.toggleState = function() {
-          dataService.server_state = (dataService.server_state == 'Running') ? 'Off' : 'Running';
-        };
+      //@TODO: call api and get proper state
+      $scope.toggleState = function() {
+        dataService.server_state =
+            (dataService.server_state == 'Running') ? 'Off' : 'Running';
+      };
 
-        $scope.powerOn = function() {
-          $scope.loading = true;
-          dataService.setUnreachableState();
-          APIUtils.hostPowerOn().then(function(response) {
-            return response;
-          }).then(function(lastStatus) {
-            pollStartTime = new Date();
-            return pollHostStatusTillOn();
-          }).then(function(hostState) {
-            $scope.loading = false;
-          }).catch(function(error) {
-            dataService.activateErrorModal({
-              title: Constants.MESSAGES.POWER_OP.POWER_ON_FAILED,
-              description: error.statusText ?
-                $interpolate(Constants.MESSAGES.ERROR_MESSAGE_DESC_TEMPLATE)({
-                  status: error.status,
-                  description: error.statusText
-                }) : error
+      $scope.powerOn = function() {
+        $scope.loading = true;
+        dataService.setUnreachableState();
+        APIUtils.hostPowerOn()
+            .then(function(response) {
+              return response;
+            })
+            .then(function(lastStatus) {
+              pollStartTime = new Date();
+              return pollHostStatusTillOn();
+            })
+            .then(function(hostState) {
+              $scope.loading = false;
+            })
+            .catch(function(error) {
+              dataService.activateErrorModal({
+                title: Constants.MESSAGES.POWER_OP.POWER_ON_FAILED,
+                description: error.statusText ?
+                    $interpolate(
+                        Constants.MESSAGES.ERROR_MESSAGE_DESC_TEMPLATE)(
+                        {status: error.status, description: error.statusText}) :
+                    error
+              });
+              $scope.loading = false;
             });
-            $scope.loading = false;
-          });
-        };
-        $scope.powerOnConfirm = function() {
-          if ($scope.confirm) {
-            return;
-          }
-          $scope.confirm = true;
-          $scope.power_confirm = true;
-        };
-
-        function setHostState(state) {
-          if (state == Constants.HOST_STATE_TEXT.off_code) {
-            dataService.setPowerOffState();
-          }
-          else if (state == Constants.HOST_STATE_TEXT.on_code) {
-            dataService.setPowerOnState();
-          }
-          else {
-            dataService.setErrorState();
-          }
+      };
+      $scope.powerOnConfirm = function() {
+        if ($scope.confirm) {
+          return;
         }
+        $scope.confirm = true;
+        $scope.power_confirm = true;
+      };
 
-        function pollChassisStatusTillOff() {
-          var deferred = $q.defer();
-          pollChassisStatusTimer = $interval(function() {
-            var now = new Date();
-            if ((now.getTime() - pollStartTime.getTime()) >= Constants.TIMEOUT.CHASSIS_OFF) {
-              $interval.cancel(pollChassisStatusTimer);
-              pollChassisStatusTimer = undefined;
-              deferred.reject(new Error(Constants.MESSAGES.POLL.CHASSIS_OFF_TIMEOUT));
-            }
-            APIUtils.getChassisState().then(function(state) {
-              if (state === Constants.CHASSIS_POWER_STATE.off_code) {
+      function setHostState(state) {
+        if (state == Constants.HOST_STATE_TEXT.off_code) {
+          dataService.setPowerOffState();
+        } else if (state == Constants.HOST_STATE_TEXT.on_code) {
+          dataService.setPowerOnState();
+        } else {
+          dataService.setErrorState();
+        }
+      }
+
+      function pollChassisStatusTillOff() {
+        var deferred = $q.defer();
+        pollChassisStatusTimer = $interval(function() {
+          var now = new Date();
+          if ((now.getTime() - pollStartTime.getTime()) >=
+              Constants.TIMEOUT.CHASSIS_OFF) {
+            $interval.cancel(pollChassisStatusTimer);
+            pollChassisStatusTimer = undefined;
+            deferred.reject(
+                new Error(Constants.MESSAGES.POLL.CHASSIS_OFF_TIMEOUT));
+          }
+          APIUtils.getChassisState()
+              .then(function(state) {
+                if (state === Constants.CHASSIS_POWER_STATE.off_code) {
+                  $interval.cancel(pollChassisStatusTimer);
+                  pollChassisStatusTimer = undefined;
+                  deferred.resolve(state);
+                }
+              })
+              .catch(function(error) {
                 $interval.cancel(pollChassisStatusTimer);
                 pollChassisStatusTimer = undefined;
-                deferred.resolve(state);
-              }
-            }).catch(function(error) {
-              $interval.cancel(pollChassisStatusTimer);
-              pollChassisStatusTimer = undefined;
-              deferred.reject(error);
-            });
-          }, Constants.POLL_INTERVALS.POWER_OP);
+                deferred.reject(error);
+              });
+        }, Constants.POLL_INTERVALS.POWER_OP);
 
-          return deferred.promise;
-        }
-
-        function pollHostStatusTillOn() {
-          var deferred = $q.defer();
-          pollHostStatusTimer = $interval(function() {
-            var now = new Date();
-            if ((now.getTime() - pollStartTime.getTime()) >= Constants.TIMEOUT.HOST_ON) {
-              $interval.cancel(pollHostStatusTimer);
-              pollHostStatusTimer = undefined;
-              deferred.reject(new Error(Constants.MESSAGES.POLL.HOST_ON_TIMEOUT));
-            }
-            APIUtils.getHostState().then(function(state) {
-              setHostState(state);
-              if (state === Constants.HOST_STATE_TEXT.on_code) {
-                $interval.cancel(pollHostStatusTimer);
-                pollHostStatusTimer = undefined;
-                deferred.resolve(state);
-              }
-              else if (state === Constants.HOST_STATE_TEXT.error_code) {
-                $interval.cancel(pollHostStatusTimer);
-                pollHostStatusTimer = undefined;
-                deferred.reject(new Error(Constants.MESSAGES.POLL.HOST_QUIESCED));
-              }
-            }).catch(function(error) {
-              $interval.cancel(pollHostStatusTimer);
-              pollHostStatusTimer = undefined;
-              deferred.reject(error);
-            });
-          }, Constants.POLL_INTERVALS.POWER_OP);
-
-          return deferred.promise;
-        }
-
-        function pollHostStatusTillOff() {
-          var deferred = $q.defer();
-          pollHostStatusTimer = $interval(function() {
-            var now = new Date();
-            if ((now.getTime() - pollStartTime.getTime()) >= Constants.TIMEOUT.HOST_OFF) {
-              $interval.cancel(pollHostStatusTimer);
-              pollHostStatusTimer = undefined;
-              deferred.reject(new Error(Constants.MESSAGES.POLL.HOST_OFF_TIMEOUT));
-            }
-            APIUtils.getHostState().then(function(state) {
-              setHostState(state);
-              if (state === Constants.HOST_STATE_TEXT.off_code) {
-                $interval.cancel(pollHostStatusTimer);
-                pollHostStatusTimer = undefined;
-                deferred.resolve(state);
-              }
-            }).catch(function(error) {
-              $interval.cancel(pollHostStatusTimer);
-              pollHostStatusTimer = undefined;
-              deferred.reject(error);
-            });
-          }, Constants.POLL_INTERVALS.POWER_OP);
-
-          return deferred.promise;
-        }
-        $scope.warmReboot = function() {
-          $scope.loading = true;
-          dataService.setUnreachableState();
-          APIUtils.hostReboot().then(function(response) {
-            return response;
-          }).then(function(lastStatus) {
-            pollStartTime = new Date();
-            return pollHostStatusTillOff();
-          }).then(function(hostState) {
-            pollStartTime = new Date();
-            return pollHostStatusTillOn();
-          }).then(function(hostState) {
-            $scope.loading = false;
-          }).catch(function(error) {
-            dataService.activateErrorModal({
-              title: Constants.MESSAGES.POWER_OP.WARM_REBOOT_FAILED,
-              description: error.statusText ?
-                $interpolate(Constants.MESSAGES.ERROR_MESSAGE_DESC_TEMPLATE)({
-                  status: error.status,
-                  description: error.statusText
-                }) : error
-            });
-            $scope.loading = false;
-          });
-        };
-        $scope.testState = function() {
-          $timeout(function() {
-            dataService.setPowerOffState();
-            $timeout(function() {
-              dataService.setPowerOnState();
-            }, 2000);
-          }, 1000);
-        };
-        $scope.warmRebootConfirm = function() {
-          if ($scope.confirm) {
-            return;
-          }
-          $scope.confirm = true;
-          $scope.warmboot_confirm = true;
-        };
-
-        $scope.coldReboot = function() {
-          $scope.loading = true;
-          dataService.setUnreachableState();
-          APIUtils.chassisPowerOff().then(function(state) {
-            return state;
-          }).then(function(lastState) {
-            pollStartTime = new Date();
-            return pollChassisStatusTillOff();
-          }).then(function(chassisState) {
-            return APIUtils.hostPowerOn().then(function(hostState) {
-              return hostState;
-            });
-          }).then(function(hostState) {
-            pollStartTime = new Date();
-            return pollHostStatusTillOn();
-          }).then(function(state) {
-            $scope.loading = false;
-          }).catch(function(error) {
-            dataService.activateErrorModal({
-              title: Constants.MESSAGES.POWER_OP.COLD_REBOOT_FAILED,
-              description: error.statusText ?
-                $interpolate(Constants.MESSAGES.ERROR_MESSAGE_DESC_TEMPLATE)({
-                  status: error.status,
-                  description: error.statusText
-                }) : error
-            });
-            $scope.loading = false;
-          });
-        };
-        $scope.coldRebootConfirm = function() {
-          if ($scope.confirm) {
-            return;
-          }
-          $scope.confirm = true;
-          $scope.coldboot_confirm = true;
-        };
-
-        $scope.orderlyShutdown = function() {
-          $scope.loading = true;
-          dataService.setUnreachableState();
-          APIUtils.hostPowerOff().then(function(response) {
-            return response;
-          }).then(function(lastStatus) {
-            pollStartTime = new Date();
-            return pollHostStatusTillOff();
-          }).then(function(hostState) {
-            pollStartTime = new Date();
-            return pollChassisStatusTillOff();
-          }).then(function(chassisState) {
-            $scope.loading = false;
-          }).catch(function(error) {
-            dataService.activateErrorModal({
-              title: Constants.MESSAGES.POWER_OP.ORDERLY_SHUTDOWN_FAILED,
-              description: error.statusText ?
-                $interpolate(Constants.MESSAGES.ERROR_MESSAGE_DESC_TEMPLATE)({
-                  status: error.status,
-                  description: error.statusText
-                }) : error
-            });
-            $scope.loading = false;
-          });
-        };
-        $scope.orderlyShutdownConfirm = function() {
-          if ($scope.confirm) {
-            return;
-          }
-          $scope.confirm = true;
-          $scope.orderly_confirm = true;
-        };
-
-        $scope.immediateShutdown = function() {
-          $scope.loading = true;
-          dataService.setUnreachableState();
-          APIUtils.chassisPowerOff().then(function(response) {
-            return response;
-          }).then(function(lastStatus) {
-            pollStartTime = new Date();
-            return pollChassisStatusTillOff();
-          }).then(function(chassisState) {
-            dataService.setPowerOffState();
-            $scope.loading = false;
-          }).catch(function(error) {
-            dataService.activateErrorModal({
-              title: Constants.MESSAGES.POWER_OP.IMMEDIATE_SHUTDOWN_FAILED,
-              description: error.statusText ?
-                $interpolate(Constants.MESSAGES.ERROR_MESSAGE_DESC_TEMPLATE)({
-                  status: error.status,
-                  description: error.statusText
-                }) : error
-            });
-            $scope.loading = false;
-          });
-        };
-        $scope.immediateShutdownConfirm = function() {
-          if ($scope.confirm) {
-            return;
-          }
-          $scope.confirm = true;
-          $scope.immediately_confirm = true;
-        };
+        return deferred.promise;
       }
-    ]);
+
+      function pollHostStatusTillOn() {
+        var deferred = $q.defer();
+        pollHostStatusTimer = $interval(function() {
+          var now = new Date();
+          if ((now.getTime() - pollStartTime.getTime()) >=
+              Constants.TIMEOUT.HOST_ON) {
+            $interval.cancel(pollHostStatusTimer);
+            pollHostStatusTimer = undefined;
+            deferred.reject(new Error(Constants.MESSAGES.POLL.HOST_ON_TIMEOUT));
+          }
+          APIUtils.getHostState()
+              .then(function(state) {
+                setHostState(state);
+                if (state === Constants.HOST_STATE_TEXT.on_code) {
+                  $interval.cancel(pollHostStatusTimer);
+                  pollHostStatusTimer = undefined;
+                  deferred.resolve(state);
+                } else if (state === Constants.HOST_STATE_TEXT.error_code) {
+                  $interval.cancel(pollHostStatusTimer);
+                  pollHostStatusTimer = undefined;
+                  deferred.reject(
+                      new Error(Constants.MESSAGES.POLL.HOST_QUIESCED));
+                }
+              })
+              .catch(function(error) {
+                $interval.cancel(pollHostStatusTimer);
+                pollHostStatusTimer = undefined;
+                deferred.reject(error);
+              });
+        }, Constants.POLL_INTERVALS.POWER_OP);
+
+        return deferred.promise;
+      }
+
+      function pollHostStatusTillOff() {
+        var deferred = $q.defer();
+        pollHostStatusTimer = $interval(function() {
+          var now = new Date();
+          if ((now.getTime() - pollStartTime.getTime()) >=
+              Constants.TIMEOUT.HOST_OFF) {
+            $interval.cancel(pollHostStatusTimer);
+            pollHostStatusTimer = undefined;
+            deferred.reject(
+                new Error(Constants.MESSAGES.POLL.HOST_OFF_TIMEOUT));
+          }
+          APIUtils.getHostState()
+              .then(function(state) {
+                setHostState(state);
+                if (state === Constants.HOST_STATE_TEXT.off_code) {
+                  $interval.cancel(pollHostStatusTimer);
+                  pollHostStatusTimer = undefined;
+                  deferred.resolve(state);
+                }
+              })
+              .catch(function(error) {
+                $interval.cancel(pollHostStatusTimer);
+                pollHostStatusTimer = undefined;
+                deferred.reject(error);
+              });
+        }, Constants.POLL_INTERVALS.POWER_OP);
+
+        return deferred.promise;
+      }
+      $scope.warmReboot = function() {
+        $scope.loading = true;
+        dataService.setUnreachableState();
+        APIUtils.hostReboot()
+            .then(function(response) {
+              return response;
+            })
+            .then(function(lastStatus) {
+              pollStartTime = new Date();
+              return pollHostStatusTillOff();
+            })
+            .then(function(hostState) {
+              pollStartTime = new Date();
+              return pollHostStatusTillOn();
+            })
+            .then(function(hostState) {
+              $scope.loading = false;
+            })
+            .catch(function(error) {
+              dataService.activateErrorModal({
+                title: Constants.MESSAGES.POWER_OP.WARM_REBOOT_FAILED,
+                description: error.statusText ?
+                    $interpolate(
+                        Constants.MESSAGES.ERROR_MESSAGE_DESC_TEMPLATE)(
+                        {status: error.status, description: error.statusText}) :
+                    error
+              });
+              $scope.loading = false;
+            });
+      };
+      $scope.testState = function() {
+        $timeout(function() {
+          dataService.setPowerOffState();
+          $timeout(function() {
+            dataService.setPowerOnState();
+          }, 2000);
+        }, 1000);
+      };
+      $scope.warmRebootConfirm = function() {
+        if ($scope.confirm) {
+          return;
+        }
+        $scope.confirm = true;
+        $scope.warmboot_confirm = true;
+      };
+
+      $scope.coldReboot = function() {
+        $scope.loading = true;
+        dataService.setUnreachableState();
+        APIUtils.chassisPowerOff()
+            .then(function(state) {
+              return state;
+            })
+            .then(function(lastState) {
+              pollStartTime = new Date();
+              return pollChassisStatusTillOff();
+            })
+            .then(function(chassisState) {
+              return APIUtils.hostPowerOn().then(function(hostState) {
+                return hostState;
+              });
+            })
+            .then(function(hostState) {
+              pollStartTime = new Date();
+              return pollHostStatusTillOn();
+            })
+            .then(function(state) {
+              $scope.loading = false;
+            })
+            .catch(function(error) {
+              dataService.activateErrorModal({
+                title: Constants.MESSAGES.POWER_OP.COLD_REBOOT_FAILED,
+                description: error.statusText ?
+                    $interpolate(
+                        Constants.MESSAGES.ERROR_MESSAGE_DESC_TEMPLATE)(
+                        {status: error.status, description: error.statusText}) :
+                    error
+              });
+              $scope.loading = false;
+            });
+      };
+      $scope.coldRebootConfirm = function() {
+        if ($scope.confirm) {
+          return;
+        }
+        $scope.confirm = true;
+        $scope.coldboot_confirm = true;
+      };
+
+      $scope.orderlyShutdown = function() {
+        $scope.loading = true;
+        dataService.setUnreachableState();
+        APIUtils.hostPowerOff()
+            .then(function(response) {
+              return response;
+            })
+            .then(function(lastStatus) {
+              pollStartTime = new Date();
+              return pollHostStatusTillOff();
+            })
+            .then(function(hostState) {
+              pollStartTime = new Date();
+              return pollChassisStatusTillOff();
+            })
+            .then(function(chassisState) {
+              $scope.loading = false;
+            })
+            .catch(function(error) {
+              dataService.activateErrorModal({
+                title: Constants.MESSAGES.POWER_OP.ORDERLY_SHUTDOWN_FAILED,
+                description: error.statusText ?
+                    $interpolate(
+                        Constants.MESSAGES.ERROR_MESSAGE_DESC_TEMPLATE)(
+                        {status: error.status, description: error.statusText}) :
+                    error
+              });
+              $scope.loading = false;
+            });
+      };
+      $scope.orderlyShutdownConfirm = function() {
+        if ($scope.confirm) {
+          return;
+        }
+        $scope.confirm = true;
+        $scope.orderly_confirm = true;
+      };
+
+      $scope.immediateShutdown = function() {
+        $scope.loading = true;
+        dataService.setUnreachableState();
+        APIUtils.chassisPowerOff()
+            .then(function(response) {
+              return response;
+            })
+            .then(function(lastStatus) {
+              pollStartTime = new Date();
+              return pollChassisStatusTillOff();
+            })
+            .then(function(chassisState) {
+              dataService.setPowerOffState();
+              $scope.loading = false;
+            })
+            .catch(function(error) {
+              dataService.activateErrorModal({
+                title: Constants.MESSAGES.POWER_OP.IMMEDIATE_SHUTDOWN_FAILED,
+                description: error.statusText ?
+                    $interpolate(
+                        Constants.MESSAGES.ERROR_MESSAGE_DESC_TEMPLATE)(
+                        {status: error.status, description: error.statusText}) :
+                    error
+              });
+              $scope.loading = false;
+            });
+      };
+      $scope.immediateShutdownConfirm = function() {
+        if ($scope.confirm) {
+          return;
+        }
+        $scope.confirm = true;
+        $scope.immediately_confirm = true;
+      };
+    }
+  ]);
 
 })(angular);
diff --git a/app/server-control/controllers/remote-console-controller.js b/app/server-control/controllers/remote-console-controller.js
index c2e1435..45156fb 100644
--- a/app/server-control/controllers/remote-console-controller.js
+++ b/app/server-control/controllers/remote-console-controller.js
@@ -6,75 +6,68 @@
  * @name remoteConsoleController
  */
 
-import {
-  hterm,
-  lib
-}
-from 'hterm-umdjs';
+import {hterm, lib} from 'hterm-umdjs';
 
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.serverControl')
-    .controller('remoteConsoleController', [
-      '$scope',
-      '$window',
-      'APIUtils',
-      'dataService',
-      function($scope, $window, APIUtils, dataService) {
-        $scope.dataService = dataService;
+  angular.module('app.serverControl').controller('remoteConsoleController', [
+    '$scope', '$window', 'APIUtils', 'dataService',
+    function($scope, $window, APIUtils, dataService) {
+      $scope.dataService = dataService;
 
-        // See https://github.com/macton/hterm for available hterm options
+      // See https://github.com/macton/hterm for available hterm options
 
-        hterm.defaultStorage = new lib.Storage.Local();
-        var term = new hterm.Terminal('host-console');
-        term.decorate(document.querySelector('#terminal'));
-        //Set cursor color
-        term.prefs_.set('cursor-color', 'rgba(83, 146, 255, .5)');
-        //Set background color
-        term.prefs_.set('background-color', '#19273c');
-        //Allows keyboard input
-        term.installKeyboard();
+      hterm.defaultStorage = new lib.Storage.Local();
+      var term = new hterm.Terminal('host-console');
+      term.decorate(document.querySelector('#terminal'));
+      // Set cursor color
+      term.prefs_.set('cursor-color', 'rgba(83, 146, 255, .5)');
+      // Set background color
+      term.prefs_.set('background-color', '#19273c');
+      // Allows keyboard input
+      term.installKeyboard();
 
-        //The BMC exposes a websocket at /console0. This can be read
-        //or written to access the host serial console.
-        var hostname = dataService.getHost().replace('https://', '');
-        var host = 'wss://' + hostname + '/console0';
-        var ws = new WebSocket(host);
-        ws.onmessage = function(evt) {
-          //websocket -> terminal
-          term.io.print(evt.data);
+      // The BMC exposes a websocket at /console0. This can be read
+      // or written to access the host serial console.
+      var hostname = dataService.getHost().replace('https://', '');
+      var host = 'wss://' + hostname + '/console0';
+      var ws = new WebSocket(host);
+      ws.onmessage = function(evt) {
+        // websocket -> terminal
+        term.io.print(evt.data);
+      };
+
+      // terminal -> websocket
+      term.onTerminalReady = function() {
+        var io = term.io.push();
+        io.onVTKeystroke = function(str) {
+          ws.send(str);
         };
+        io.sendString = function(str) {
+          ws.send(str);
+        };
+      };
 
-        //terminal -> websocket
-        term.onTerminalReady = function() {
-          var io = term.io.push();
-          io.onVTKeystroke = function(str) {
-            ws.send(str);
-          };
-          io.sendString = function(str) {
-            ws.send(str);
-          };
-        };
+      ws.onopen = function() {
+        console.log('websocket opened');
+      };
+      ws.onclose = function() {
+        console.log('websocket closed');
+      };
+      $scope.$on('$destroy', function() {
+        if (ws) {
+          ws.close();
+        }
+      });
 
-        ws.onopen = function() {
-          console.log('websocket opened');
-        };
-        ws.onclose = function() {
-          console.log('websocket closed');
-        };
-        $scope.$on('$destroy', function() {
-          if (ws) {
-            ws.close();
-          }
-        });
-
-        $scope.openTerminalWindow = function() {
-          dataService.setRemoteWindowActive();
-          $window.open('#/server-control/remote-console-window', 'Remote Console Window', 'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no,width=600,height=400');
-        };
-      }
-    ]);
+      $scope.openTerminalWindow = function() {
+        dataService.setRemoteWindowActive();
+        $window.open(
+            '#/server-control/remote-console-window', 'Remote Console Window',
+            'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no,width=600,height=400');
+      };
+    }
+  ]);
 
 })(angular);
diff --git a/app/server-control/controllers/remote-console-window-controller.js b/app/server-control/controllers/remote-console-window-controller.js
index 685b45e..bcf311b 100644
--- a/app/server-control/controllers/remote-console-window-controller.js
+++ b/app/server-control/controllers/remote-console-window-controller.js
@@ -9,54 +9,50 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.serverControl')
-    .controller('remoteConsoleWindowController', [
-      '$scope',
-      '$window',
-      'APIUtils',
-      'dataService',
-      function($scope, $window, APIUtils, dataService) {
-        $scope.dataService = dataService;
-        dataService.showNavigation = false;
+  angular.module('app.serverControl')
+      .controller('remoteConsoleWindowController', [
+        '$scope', '$window', 'APIUtils', 'dataService',
+        function($scope, $window, APIUtils, dataService) {
+          $scope.dataService = dataService;
+          dataService.showNavigation = false;
 
-        // See https://github.com/macton/hterm for available hterm options
+          // See https://github.com/macton/hterm for available hterm options
 
-        //Storage
-        hterm.defaultStorage = new lib.Storage.Local();
+          // Storage
+          hterm.defaultStorage = new lib.Storage.Local();
 
-        var term = new hterm.Terminal('foo');
-        term.onTerminalReady = function() {
-          var io = term.io.push();
-          io.onVTKeystroke = function(str) {
-            console.log(str);
-            term.io.print(str);
+          var term = new hterm.Terminal('foo');
+          term.onTerminalReady = function() {
+            var io = term.io.push();
+            io.onVTKeystroke = function(str) {
+              console.log(str);
+              term.io.print(str);
+            };
+            io.sendString = function(str) {
+              console.log(str);
+            };
           };
-          io.sendString = function(str) {
-            console.log(str);
+          term.decorate(document.querySelector('#terminal'));
+
+          // Set cursor color
+          term.prefs_.set('cursor-color', 'rgba(83, 146, 255, .5)');
+
+          // Set background color
+          term.prefs_.set('background-color', '#19273c');
+
+          // Print to console window
+          term.io.println('OpenBMC ver.00');
+          term.io.println('This is not an actual live connection.');
+          term.io.print('root@IBM:');
+
+          // Allows keyboard input
+          term.installKeyboard();
+
+          $scope.close = function() {
+            dataService.setRemoteWindowInactive();
+            $window.close();
           };
-        };
-        term.decorate(document.querySelector('#terminal'));
-
-        //Set cursor color
-        term.prefs_.set('cursor-color', 'rgba(83, 146, 255, .5)');
-
-        //Set background color
-        term.prefs_.set('background-color', '#19273c');
-
-        //Print to console window
-        term.io.println('OpenBMC ver.00');
-        term.io.println('This is not an actual live connection.');
-        term.io.print('root@IBM:');
-
-        //Allows keyboard input
-        term.installKeyboard();
-
-        $scope.close = function() {
-          dataService.setRemoteWindowInactive();
-          $window.close();
-        };
-      }
-    ]);
+        }
+      ]);
 
 })(angular);
diff --git a/app/server-control/index.js b/app/server-control/index.js
index 12debcf..797f144 100644
--- a/app/server-control/index.js
+++ b/app/server-control/index.js
@@ -9,44 +9,50 @@
   'use strict';
 
   angular
-    .module('app.serverControl', [
-      'ngRoute',
-      'app.constants',
-      'app.common.services'
-    ])
-    // Route configuration
-    .config(['$routeProvider', function($routeProvider) {
-      $routeProvider
-        .when('/server-control/bmc-reboot', {
-          'template': require('./controllers/bmc-reboot-controller.html'),
-          'controller': 'bmcRebootController',
-          authenticated: true
-        })
-        .when('/server-control/server-led', {
-          'template': require('../server-health/controllers/unit-id-controller.html'),
-          'controller': 'unitIdController',
-          authenticated: true
-        })
-        .when('/server-control/power-operations', {
-          'template': require('./controllers/power-operations-controller.html'),
-          'controller': 'powerOperationsController',
-          authenticated: true
-        })
-        .when('/server-control/remote-console', {
-          'template': require('./controllers/remote-console-controller.html'),
-          'controller': 'remoteConsoleController',
-          authenticated: true
-        })
-        .when('/server-control/remote-console-window', {
-          'template': require('./controllers/remote-console-window-controller.html'),
-          'controller': 'remoteConsoleWindowController',
-          authenticated: true
-        })
-        .when('/server-control', {
-          'template': require('./controllers/power-operations-controller.html'),
-          'controller': 'powerOperationsController',
-          authenticated: true
-        });
-    }]);
+      .module(
+          'app.serverControl',
+          ['ngRoute', 'app.constants', 'app.common.services'])
+      // Route configuration
+      .config([
+        '$routeProvider',
+        function($routeProvider) {
+          $routeProvider
+              .when('/server-control/bmc-reboot', {
+                'template': require('./controllers/bmc-reboot-controller.html'),
+                'controller': 'bmcRebootController',
+                authenticated: true
+              })
+              .when('/server-control/server-led', {
+                'template': require(
+                    '../server-health/controllers/unit-id-controller.html'),
+                'controller': 'unitIdController',
+                authenticated: true
+              })
+              .when('/server-control/power-operations', {
+                'template':
+                    require('./controllers/power-operations-controller.html'),
+                'controller': 'powerOperationsController',
+                authenticated: true
+              })
+              .when('/server-control/remote-console', {
+                'template':
+                    require('./controllers/remote-console-controller.html'),
+                'controller': 'remoteConsoleController',
+                authenticated: true
+              })
+              .when('/server-control/remote-console-window', {
+                'template': require(
+                    './controllers/remote-console-window-controller.html'),
+                'controller': 'remoteConsoleWindowController',
+                authenticated: true
+              })
+              .when('/server-control', {
+                'template':
+                    require('./controllers/power-operations-controller.html'),
+                'controller': 'powerOperationsController',
+                authenticated: true
+              });
+        }
+      ]);
 
 })(window.angular);
diff --git a/app/server-health/controllers/diagnostics-controller.js b/app/server-health/controllers/diagnostics-controller.js
index b28d61f..0f6763f 100644
--- a/app/server-health/controllers/diagnostics-controller.js
+++ b/app/server-health/controllers/diagnostics-controller.js
@@ -9,16 +9,11 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.serverHealth')
-    .controller('diagnosticsController', [
-      '$scope',
-      '$window',
-      'APIUtils',
-      'dataService',
-      function($scope, $window, APIUtils, dataService) {
-        $scope.dataService = dataService;
-      }
-    ]);
+  angular.module('app.serverHealth').controller('diagnosticsController', [
+    '$scope', '$window', 'APIUtils', 'dataService',
+    function($scope, $window, APIUtils, dataService) {
+      $scope.dataService = dataService;
+    }
+  ]);
 
 })(angular);
diff --git a/app/server-health/controllers/inventory-controller.js b/app/server-health/controllers/inventory-controller.js
index 17c9057..df9ca1c 100644
--- a/app/server-health/controllers/inventory-controller.js
+++ b/app/server-health/controllers/inventory-controller.js
@@ -9,19 +9,14 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.serverHealth')
-    .controller('inventoryController', [
-      '$scope',
-      '$window',
-      'APIUtils',
-      'dataService',
-      function($scope, $window, APIUtils, dataService) {
-        $scope.dataService = dataService;
+  angular.module('app.serverHealth').controller('inventoryController', [
+    '$scope', '$window', 'APIUtils', 'dataService',
+    function($scope, $window, APIUtils, dataService) {
+      $scope.dataService = dataService;
 
-        // Force to top of page when viewing single group
-        $window.scrollTo(0, 0);
-      }
-    ]);
+      // Force to top of page when viewing single group
+      $window.scrollTo(0, 0);
+    }
+  ]);
 
 })(angular);
diff --git a/app/server-health/controllers/inventory-overview-controller.js b/app/server-health/controllers/inventory-overview-controller.js
index a0dad75..9705395 100644
--- a/app/server-health/controllers/inventory-overview-controller.js
+++ b/app/server-health/controllers/inventory-overview-controller.js
@@ -9,68 +9,64 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.serverHealth')
-    .controller('inventoryOverviewController', [
-      '$scope',
-      '$window',
-      'APIUtils',
-      'dataService',
-      function($scope, $window, APIUtils, dataService) {
-        $scope.dataService = dataService;
-        $scope.hardwares = [];
-        $scope.originalData = {};
+  angular.module('app.serverHealth').controller('inventoryOverviewController', [
+    '$scope', '$window', 'APIUtils', 'dataService',
+    function($scope, $window, APIUtils, dataService) {
+      $scope.dataService = dataService;
+      $scope.hardwares = [];
+      $scope.originalData = {};
+      $scope.customSearch = '';
+      $scope.searchTerms = [];
+      $scope.loading = false;
+
+      $scope.loading = true;
+      APIUtils.getHardwares(function(data, originalData) {
+        $scope.hardwares = data;
+        $scope.originalData = JSON.stringify(originalData);
+        $scope.loading = false;
+      });
+
+      $scope.clear = function() {
         $scope.customSearch = '';
         $scope.searchTerms = [];
-        $scope.loading = false;
+      };
 
-        $scope.loading = true;
-        APIUtils.getHardwares(function(data, originalData) {
-          $scope.hardwares = data;
-          $scope.originalData = JSON.stringify(originalData);
-          $scope.loading = false;
-        });
-
-        $scope.clear = function() {
-          $scope.customSearch = '';
-          $scope.searchTerms = [];
-        };
-
-        $scope.doSearchOnEnter = function(event) {
-          var search = $scope.customSearch.replace(/^\s+/g, '').replace(/\s+$/g, '');
-          if (event.keyCode === 13 &&
-            search.length >= 2) {
-            $scope.searchTerms = $scope.customSearch.split(' ');
+      $scope.doSearchOnEnter = function(event) {
+        var search =
+            $scope.customSearch.replace(/^\s+/g, '').replace(/\s+$/g, '');
+        if (event.keyCode === 13 && search.length >= 2) {
+          $scope.searchTerms = $scope.customSearch.split(' ');
+        } else {
+          if (search.length == 0) {
+            $scope.searchTerms = [];
           }
-          else {
-            if (search.length == 0) {
-              $scope.searchTerms = [];
-            }
-          }
-        };
+        }
+      };
 
-        $scope.doSearchOnClick = function() {
-          var search = $scope.customSearch.replace(/^\s+/g, '').replace(/\s+$/g, '');
-          if (search.length >= 2) {
-            $scope.searchTerms = $scope.customSearch.split(' ');
+      $scope.doSearchOnClick = function() {
+        var search =
+            $scope.customSearch.replace(/^\s+/g, '').replace(/\s+$/g, '');
+        if (search.length >= 2) {
+          $scope.searchTerms = $scope.customSearch.split(' ');
+        } else {
+          if (search.length == 0) {
+            $scope.searchTerms = [];
           }
-          else {
-            if (search.length == 0) {
-              $scope.searchTerms = [];
-            }
-          }
-        };
+        }
+      };
 
-        $scope.filterBySearchTerms = function(hardware) {
+      $scope.filterBySearchTerms = function(hardware) {
 
-          if (!$scope.searchTerms.length) return true;
+        if (!$scope.searchTerms.length) return true;
 
-          for (var i = 0, length = $scope.searchTerms.length; i < length; i++) {
-            if (hardware.search_text.indexOf($scope.searchTerms[i].toLowerCase()) == -1) return false;
-          }
-          return true;
-        };
-      }
-    ]);
+        for (var i = 0, length = $scope.searchTerms.length; i < length; i++) {
+          if (hardware.search_text.indexOf(
+                  $scope.searchTerms[i].toLowerCase()) == -1)
+            return false;
+        }
+        return true;
+      };
+    }
+  ]);
 
 })(angular);
diff --git a/app/server-health/controllers/log-controller.js b/app/server-health/controllers/log-controller.js
index 1a01242..4359c9c 100644
--- a/app/server-health/controllers/log-controller.js
+++ b/app/server-health/controllers/log-controller.js
@@ -8,190 +8,183 @@
 
 window.angular && (function(angular) {
   'use strict';
-  angular
-    .module('app.serverHealth')
-    .config(function(paginationTemplateProvider) {
-      paginationTemplateProvider.setString(require('../../common/directives/dirPagination.tpl.html'));
-    })
-    .controller('logController', [
-      '$scope',
-      '$window',
-      'APIUtils',
-      'dataService',
-      'Constants',
-      '$routeParams',
-      '$filter',
-      function($scope, $window, APIUtils, dataService, Constants, $routeParams, $filter) {
-        $scope.dataService = dataService;
-        $scope.logs = [];
-        $scope.tmz = 'EDT';
-        $scope.itemsPerPage = Constants.PAGINATION.LOG_ITEMS_PER_PAGE;
-        $scope.loading = false;
-        var expandedSelectedIdOnce = false;
+  angular.module('app.serverHealth')
+      .config(function(paginationTemplateProvider) {
+        paginationTemplateProvider.setString(
+            require('../../common/directives/dirPagination.tpl.html'));
+      })
+      .controller('logController', [
+        '$scope', '$window', 'APIUtils', 'dataService', 'Constants',
+        '$routeParams', '$filter',
+        function(
+            $scope, $window, APIUtils, dataService, Constants, $routeParams,
+            $filter) {
+          $scope.dataService = dataService;
+          $scope.logs = [];
+          $scope.tmz = 'EDT';
+          $scope.itemsPerPage = Constants.PAGINATION.LOG_ITEMS_PER_PAGE;
+          $scope.loading = false;
+          var expandedSelectedIdOnce = false;
 
-        var sensorType = $routeParams.type;
-        var eventId = $routeParams.id;
+          var sensorType = $routeParams.type;
+          var eventId = $routeParams.id;
 
-        // priority buttons
-        $scope.selectedSeverity = {
-          all: true,
-          low: false,
-          medium: false,
-          high: false
-        };
+          // priority buttons
+          $scope.selectedSeverity =
+              {all: true, low: false, medium: false, high: false};
 
-        if (sensorType == 'high') {
-          $scope.selectedSeverity.all = false;
-          $scope.selectedSeverity.high = true;
-        }
-
-        $scope.selectedStatus = {
-          all: true,
-          resolved: false
-        };
-
-        $scope.customSearch = '';
-        $scope.searchItems = [];
-        $scope.selectedEvents = [];
-
-
-        if (eventId) {
-          $scope.customSearch = '#' + eventId;
-          $scope.searchItems.push('#' + eventId);
-        }
-
-        $scope.loadLogs = function() {
-          $scope.loading = true;
-          APIUtils.getLogs().then(function(result) {
-            if (eventId && expandedSelectedIdOnce == false) {
-              var log = result.data.filter(function(item) {
-                return item.Id == eventId;
-              });
-
-              if (log.length) {
-                log[0].meta = true;
-              }
-              expandedSelectedIdOnce = true;
-            }
-            dataService.updateServerHealth(result.data);
-            $scope.logs = result.data;
-            $scope.originalData = result.original;
-            $scope.loading = false;
-          });
-        };
-        $scope.jsonData = function(data) {
-          return JSON.stringify(data);
-        };
-
-        $scope.filterBySeverity = function(log) {
-          if ($scope.selectedSeverity.all) return true;
-
-          return ((log.severity_flags.low && $scope.selectedSeverity.low) ||
-            (log.severity_flags.medium && $scope.selectedSeverity.medium) ||
-            (log.severity_flags.high && $scope.selectedSeverity.high)
-          );
-        };
-
-        $scope.filterByStatus = function(log) {
-          if ($scope.selectedStatus.all) return true;
-          return ((log.Resolved && $scope.selectedStatus.resolved) ||
-            (!log.Resolved && !$scope.selectedStatus.resolved)
-          );
-        };
-
-        $scope.filterByDate = function(log) {
-          var endDate;
-          if ($scope.end_date && typeof $scope.end_date.getTime === 'function') {
-            endDate = new Date($scope.end_date.getTime());
-            endDate.setTime(endDate.getTime() + 86399000);
+          if (sensorType == 'high') {
+            $scope.selectedSeverity.all = false;
+            $scope.selectedSeverity.high = true;
           }
 
-          if ($scope.start_date && endDate) {
-            var date = new Date($filter('date')(log.Timestamp, 'MM/dd/yyyy  HH:mm:ss', $scope.tmz));
-            return (date >= $scope.start_date &&
-              date <= endDate);
-          }
-          else {
-            return true;
-          }
-        };
+          $scope.selectedStatus = {all: true, resolved: false};
 
-        $scope.filterBySearchTerms = function(log) {
-          if (!$scope.searchItems.length) return true;
-
-          for (var i = 0, length = $scope.searchItems.length; i < length; i++) {
-            if (log.search_text.indexOf($scope.searchItems[i].toLowerCase()) == -1) return false;
-          }
-          return true;
-        };
-
-        $scope.addSearchItem = function(searchTerms) {
-          var terms = searchTerms.split(' ');
-          terms.forEach(function(searchTerm) {
-            if ($scope.searchItems.indexOf(searchTerm) == -1) {
-              $scope.searchItems.push(searchTerm);
-            }
-          });
-        };
-
-        $scope.clearSearchItem = function(searchTerm) {
+          $scope.customSearch = '';
           $scope.searchItems = [];
-        };
+          $scope.selectedEvents = [];
 
-        $scope.removeSearchItem = function(searchTerm) {
-          var termIndex = $scope.searchItems.indexOf(searchTerm);
-
-          if (termIndex > -1) {
-            $scope.searchItems.splice(termIndex, 1);
+          if (eventId) {
+            $scope.customSearch = '#' + eventId;
+            $scope.searchItems.push('#' + eventId);
           }
-        };
 
-        $scope.$watch('all', function() {
-          $scope.logs.forEach(function(item) {
-            item.selected = $scope.all;
-          });
-        });
+          $scope.loadLogs = function() {
+            $scope.loading = true;
+            APIUtils.getLogs().then(function(result) {
+              if (eventId && expandedSelectedIdOnce == false) {
+                var log = result.data.filter(function(item) {
+                  return item.Id == eventId;
+                });
 
-        function updateExportData() {
-          $scope.export_name = ($scope.selectedEvents.length == 1) ? $scope.selectedEvents[0].Id + '.json' : 'export.json';
-          var data = {};
-          $scope.selectedEvents.forEach(function(item) {
-            data[item.data.key] = item.data.value;
-          });
-          $scope.export_data = JSON.stringify(data);
-        }
+                if (log.length) {
+                  log[0].meta = true;
+                }
+                expandedSelectedIdOnce = true;
+              }
+              dataService.updateServerHealth(result.data);
+              $scope.logs = result.data;
+              $scope.originalData = result.original;
+              $scope.loading = false;
+            });
+          };
+          $scope.jsonData = function(data) {
+            return JSON.stringify(data);
+          };
 
+          $scope.filterBySeverity = function(log) {
+            if ($scope.selectedSeverity.all) return true;
 
-        $scope.accept = function() {
-          APIUtils.deleteLogs($scope.selectedEvents).then(function() {
-            $scope.confirm = false;
-            $scope.loadLogs();
-          });
-        };
+            return (
+                (log.severity_flags.low && $scope.selectedSeverity.low) ||
+                (log.severity_flags.medium && $scope.selectedSeverity.medium) ||
+                (log.severity_flags.high && $scope.selectedSeverity.high));
+          };
 
-        $scope.resolve = function() {
-          var events = $scope.selectedEvents.filter(function(item) {
-            return item.Resolved != 1;
-          });
+          $scope.filterByStatus = function(log) {
+            if ($scope.selectedStatus.all) return true;
+            return (
+                (log.Resolved && $scope.selectedStatus.resolved) ||
+                (!log.Resolved && !$scope.selectedStatus.resolved));
+          };
 
-          if (!events.length) return;
+          $scope.filterByDate = function(log) {
+            var endDate;
+            if ($scope.end_date &&
+                typeof $scope.end_date.getTime === 'function') {
+              endDate = new Date($scope.end_date.getTime());
+              endDate.setTime(endDate.getTime() + 86399000);
+            }
 
-          APIUtils.resolveLogs(events).then(function() {
-            events.forEach(function(item) {
-              item.Resolved = 1;
+            if ($scope.start_date && endDate) {
+              var date = new Date($filter('date')(
+                  log.Timestamp, 'MM/dd/yyyy  HH:mm:ss', $scope.tmz));
+              return (date >= $scope.start_date && date <= endDate);
+            } else {
+              return true;
+            }
+          };
+
+          $scope.filterBySearchTerms = function(log) {
+            if (!$scope.searchItems.length) return true;
+
+            for (var i = 0, length = $scope.searchItems.length; i < length;
+                 i++) {
+              if (log.search_text.indexOf(
+                      $scope.searchItems[i].toLowerCase()) == -1)
+                return false;
+            }
+            return true;
+          };
+
+          $scope.addSearchItem = function(searchTerms) {
+            var terms = searchTerms.split(' ');
+            terms.forEach(function(searchTerm) {
+              if ($scope.searchItems.indexOf(searchTerm) == -1) {
+                $scope.searchItems.push(searchTerm);
+              }
+            });
+          };
+
+          $scope.clearSearchItem = function(searchTerm) {
+            $scope.searchItems = [];
+          };
+
+          $scope.removeSearchItem = function(searchTerm) {
+            var termIndex = $scope.searchItems.indexOf(searchTerm);
+
+            if (termIndex > -1) {
+              $scope.searchItems.splice(termIndex, 1);
+            }
+          };
+
+          $scope.$watch('all', function() {
+            $scope.logs.forEach(function(item) {
+              item.selected = $scope.all;
             });
           });
-        };
 
-        $scope.$watch('logs', function() {
-          $scope.selectedEvents = $scope.logs.filter(function(item) {
-            return item.selected;
-          });
-          updateExportData();
-        }, true);
+          function updateExportData() {
+            $scope.export_name = ($scope.selectedEvents.length == 1) ?
+                $scope.selectedEvents[0].Id + '.json' :
+                'export.json';
+            var data = {};
+            $scope.selectedEvents.forEach(function(item) {
+              data[item.data.key] = item.data.value;
+            });
+            $scope.export_data = JSON.stringify(data);
+          }
 
-        $scope.loadLogs();
-      }
-    ]);
+          $scope.accept = function() {
+            APIUtils.deleteLogs($scope.selectedEvents).then(function() {
+              $scope.confirm = false;
+              $scope.loadLogs();
+            });
+          };
+
+          $scope.resolve = function() {
+            var events = $scope.selectedEvents.filter(function(item) {
+              return item.Resolved != 1;
+            });
+
+            if (!events.length) return;
+
+            APIUtils.resolveLogs(events).then(function() {
+              events.forEach(function(item) {
+                item.Resolved = 1;
+              });
+            });
+          };
+
+          $scope.$watch('logs', function() {
+            $scope.selectedEvents = $scope.logs.filter(function(item) {
+              return item.selected;
+            });
+            updateExportData();
+          }, true);
+
+          $scope.loadLogs();
+        }
+      ]);
 
 })(angular);
diff --git a/app/server-health/controllers/power-consumption-controller.js b/app/server-health/controllers/power-consumption-controller.js
index 9a74e6d..51882e4 100644
--- a/app/server-health/controllers/power-consumption-controller.js
+++ b/app/server-health/controllers/power-consumption-controller.js
@@ -9,16 +9,11 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.serverHealth')
-    .controller('powerConsumptionController', [
-      '$scope',
-      '$window',
-      'APIUtils',
-      'dataService',
-      function($scope, $window, APIUtils, dataService) {
-        $scope.dataService = dataService;
-      }
-    ]);
+  angular.module('app.serverHealth').controller('powerConsumptionController', [
+    '$scope', '$window', 'APIUtils', 'dataService',
+    function($scope, $window, APIUtils, dataService) {
+      $scope.dataService = dataService;
+    }
+  ]);
 
 })(angular);
diff --git a/app/server-health/controllers/sensors-controller.js b/app/server-health/controllers/sensors-controller.js
index 70f3e9c..5f687a0 100644
--- a/app/server-health/controllers/sensors-controller.js
+++ b/app/server-health/controllers/sensors-controller.js
@@ -9,133 +9,122 @@
 window.angular && (function(angular) {
   'use strict';
   var sensorData = [];
-  angular
-    .module('app.overview')
-    .controller('sensorsController', [
-      '$scope',
-      '$log',
-      '$window',
-      'APIUtils',
-      'dataService',
-      '$routeParams',
-      function($scope, $log, $window, APIUtils, dataService, $routeParams) {
-        $scope.dataService = dataService;
-        $scope.customSearch = '';
-        $scope.dropdown_selected = false;
-        $scope.$log = $log;
-        $scope.data = {};
-        $scope.searchTerms = [];
+  angular.module('app.overview').controller('sensorsController', [
+    '$scope', '$log', '$window', 'APIUtils', 'dataService', '$routeParams',
+    function($scope, $log, $window, APIUtils, dataService, $routeParams) {
+      $scope.dataService = dataService;
+      $scope.customSearch = '';
+      $scope.dropdown_selected = false;
+      $scope.$log = $log;
+      $scope.data = {};
+      $scope.searchTerms = [];
 
-        $scope.selectedSeverity = {
-          all: true,
-          normal: false,
-          warning: false,
-          critical: false
-        };
+      $scope.selectedSeverity =
+          {all: true, normal: false, warning: false, critical: false};
 
-        var sensorType = $routeParams.type;
+      var sensorType = $routeParams.type;
 
-        $scope.export_name = sensorType + '_sensors.json';
+      $scope.export_name = sensorType + '_sensors.json';
 
-        $scope.toggleSeverityAll = function() {
-          $scope.selectedSeverity.all = !$scope.selectedSeverity.all;
+      $scope.toggleSeverityAll = function() {
+        $scope.selectedSeverity.all = !$scope.selectedSeverity.all;
 
-          if ($scope.selectedSeverity.all) {
-            $scope.selectedSeverity.normal = false;
-            $scope.selectedSeverity.warning = false;
-            $scope.selectedSeverity.critical = false;
-          }
-        };
+        if ($scope.selectedSeverity.all) {
+          $scope.selectedSeverity.normal = false;
+          $scope.selectedSeverity.warning = false;
+          $scope.selectedSeverity.critical = false;
+        }
+      };
 
-        $scope.toggleSeverity = function(severity) {
-          $scope.selectedSeverity[severity] = !$scope.selectedSeverity[severity];
+      $scope.toggleSeverity = function(severity) {
+        $scope.selectedSeverity[severity] = !$scope.selectedSeverity[severity];
 
-          if ($scope.selectedSeverity.normal &&
-            $scope.selectedSeverity.warning &&
+        if ($scope.selectedSeverity.normal && $scope.selectedSeverity.warning &&
             $scope.selectedSeverity.critical) {
-            $scope.selectedSeverity.all = true;
-            $scope.selectedSeverity.normal = false;
-            $scope.selectedSeverity.warning = false;
-            $scope.selectedSeverity.critical = false;
-          }
-          else {
-            $scope.selectedSeverity.all = false;
-          }
-        };
+          $scope.selectedSeverity.all = true;
+          $scope.selectedSeverity.normal = false;
+          $scope.selectedSeverity.warning = false;
+          $scope.selectedSeverity.critical = false;
+        } else {
+          $scope.selectedSeverity.all = false;
+        }
+      };
 
-        $scope.doSearchOnEnter = function(event) {
-          var search = $scope.customSearch.replace(/^\s+/g, '').replace(/\s+$/g, '');
-          if (event.keyCode === 13 &&
-            search.length >= 2) {
-            $scope.searchTerms = $scope.customSearch.split(' ');
-          }
-          else {
-            if (search.length == 0) {
-              $scope.searchTerms = [];
-            }
-          }
-        };
-
-        $scope.doSearchOnClick = function() {
-          var search = $scope.customSearch.replace(/^\s+/g, '').replace(/\s+$/g, '');
-          if (search.length >= 2) {
-            $scope.searchTerms = $scope.customSearch.split(' ');
-          }
-          else {
-            if (search.length == 0) {
-              $scope.searchTerms = [];
-            }
-          }
-        };
-
-        $scope.jsonData = function(data) {
-          var dt = {};
-          data.data.forEach(function(item) {
-            dt[item.original_data.key] = item.original_data.value;
-          });
-          return JSON.stringify(dt);
-        };
-
-        $scope.filterBySeverity = function(sensor) {
-          if ($scope.selectedSeverity.all) return true;
-
-          return ((sensor.severity_flags.normal && $scope.selectedSeverity.normal) ||
-            (sensor.severity_flags.warning && $scope.selectedSeverity.warning) ||
-            (sensor.severity_flags.critical && $scope.selectedSeverity.critical)
-          );
-        };
-        $scope.filterBySearchTerms = function(sensor) {
-
-          if (!$scope.searchTerms.length) return true;
-
-          for (var i = 0, length = $scope.searchTerms.length; i < length; i++) {
-            if (sensor.search_text.indexOf($scope.searchTerms[i].toLowerCase()) == -1) return false;
-          }
-          return true;
-        };
-
-        function setSensorData() {
-          var data = dataService.sensorData.sensors.filter(function(item) {
-            return item.type == sensorType;
-          });
-          if (data.length) {
-            sensorData = data[0];
-            $scope.data = sensorData;
-            $scope.export_data = $scope.jsonData($scope.data);
+      $scope.doSearchOnEnter = function(event) {
+        var search =
+            $scope.customSearch.replace(/^\s+/g, '').replace(/\s+$/g, '');
+        if (event.keyCode === 13 && search.length >= 2) {
+          $scope.searchTerms = $scope.customSearch.split(' ');
+        } else {
+          if (search.length == 0) {
+            $scope.searchTerms = [];
           }
         }
+      };
 
-        if (!dataService.sensorData.sensors) {
-          APIUtils.getAllSensorStatus(function(data, originalData) {
-            dataService.sensorData = data;
-            setSensorData();
-          });
+      $scope.doSearchOnClick = function() {
+        var search =
+            $scope.customSearch.replace(/^\s+/g, '').replace(/\s+$/g, '');
+        if (search.length >= 2) {
+          $scope.searchTerms = $scope.customSearch.split(' ');
+        } else {
+          if (search.length == 0) {
+            $scope.searchTerms = [];
+          }
         }
-        else {
-          setSensorData();
-        }
+      };
 
+      $scope.jsonData = function(data) {
+        var dt = {};
+        data.data.forEach(function(item) {
+          dt[item.original_data.key] = item.original_data.value;
+        });
+        return JSON.stringify(dt);
+      };
+
+      $scope.filterBySeverity = function(sensor) {
+        if ($scope.selectedSeverity.all) return true;
+
+        return (
+            (sensor.severity_flags.normal && $scope.selectedSeverity.normal) ||
+            (sensor.severity_flags.warning &&
+             $scope.selectedSeverity.warning) ||
+            (sensor.severity_flags.critical &&
+             $scope.selectedSeverity.critical));
+      };
+      $scope.filterBySearchTerms = function(sensor) {
+
+        if (!$scope.searchTerms.length) return true;
+
+        for (var i = 0, length = $scope.searchTerms.length; i < length; i++) {
+          if (sensor.search_text.indexOf($scope.searchTerms[i].toLowerCase()) ==
+              -1)
+            return false;
+        }
+        return true;
+      };
+
+      function setSensorData() {
+        var data = dataService.sensorData.sensors.filter(function(item) {
+          return item.type == sensorType;
+        });
+        if (data.length) {
+          sensorData = data[0];
+          $scope.data = sensorData;
+          $scope.export_data = $scope.jsonData($scope.data);
+        }
       }
-    ]);
+
+      if (!dataService.sensorData.sensors) {
+        APIUtils.getAllSensorStatus(function(data, originalData) {
+          dataService.sensorData = data;
+          setSensorData();
+        });
+      } else {
+        setSensorData();
+      }
+
+    }
+  ]);
 
 })(angular);
diff --git a/app/server-health/controllers/sensors-overview-controller.js b/app/server-health/controllers/sensors-overview-controller.js
index 683d071..77d2978 100644
--- a/app/server-health/controllers/sensors-overview-controller.js
+++ b/app/server-health/controllers/sensors-overview-controller.js
@@ -8,138 +8,127 @@
 
 window.angular && (function(angular) {
   'use strict';
-  angular
-    .module('app.overview')
-    .controller('sensorsOverviewController', [
-      '$scope',
-      '$log',
-      '$window',
-      'APIUtils',
-      'dataService',
-      'Constants',
-      function($scope, $log, $window, APIUtils, dataService, Constants) {
-        $scope.dataService = dataService;
+  angular.module('app.overview').controller('sensorsOverviewController', [
+    '$scope', '$log', '$window', 'APIUtils', 'dataService', 'Constants',
+    function($scope, $log, $window, APIUtils, dataService, Constants) {
+      $scope.dataService = dataService;
 
-        $scope.dropdown_selected = false;
+      $scope.dropdown_selected = false;
 
-        $scope.$log = $log;
+      $scope.$log = $log;
+      $scope.customSearch = '';
+      $scope.searchTerms = [];
+      $scope.messages = Constants.MESSAGES.SENSOR;
+      $scope.selectedSeverity =
+          {all: true, normal: false, warning: false, critical: false};
+      $scope.export_name = 'sensors.json';
+      $scope.loading = false;
+      $scope.jsonData = function(data) {
+        var dt = {};
+        data.data.forEach(function(item) {
+          dt[item.original_data.key] = item.original_data.value;
+        });
+        return JSON.stringify(dt);
+      };
+
+      $scope.clear = function() {
         $scope.customSearch = '';
         $scope.searchTerms = [];
-        $scope.messages = Constants.MESSAGES.SENSOR;
-        $scope.selectedSeverity = {
-          all: true,
-          normal: false,
-          warning: false,
-          critical: false
-        };
-        $scope.export_name = 'sensors.json';
-        $scope.loading = false;
-        $scope.jsonData = function(data) {
-          var dt = {};
-          data.data.forEach(function(item) {
-            dt[item.original_data.key] = item.original_data.value;
-          });
-          return JSON.stringify(dt);
-        };
+      };
 
-        $scope.clear = function() {
-          $scope.customSearch = '';
-          $scope.searchTerms = [];
-        };
-
-        $scope.doSearchOnEnter = function(event) {
-          var search = $scope.customSearch.replace(/^\s+/g, '').replace(/\s+$/g, '');
-          if (event.keyCode === 13 &&
-            search.length >= 2) {
-            $scope.searchTerms = $scope.customSearch.split(' ');
+      $scope.doSearchOnEnter = function(event) {
+        var search =
+            $scope.customSearch.replace(/^\s+/g, '').replace(/\s+$/g, '');
+        if (event.keyCode === 13 && search.length >= 2) {
+          $scope.searchTerms = $scope.customSearch.split(' ');
+        } else {
+          if (search.length == 0) {
+            $scope.searchTerms = [];
           }
-          else {
-            if (search.length == 0) {
-              $scope.searchTerms = [];
-            }
+        }
+      };
+
+      $scope.doSearchOnClick = function() {
+        var search =
+            $scope.customSearch.replace(/^\s+/g, '').replace(/\s+$/g, '');
+        if (search.length >= 2) {
+          $scope.searchTerms = $scope.customSearch.split(' ');
+        } else {
+          if (search.length == 0) {
+            $scope.searchTerms = [];
           }
-        };
+        }
+      };
 
-        $scope.doSearchOnClick = function() {
-          var search = $scope.customSearch.replace(/^\s+/g, '').replace(/\s+$/g, '');
-          if (search.length >= 2) {
-            $scope.searchTerms = $scope.customSearch.split(' ');
-          }
-          else {
-            if (search.length == 0) {
-              $scope.searchTerms = [];
-            }
-          }
-        };
+      $scope.toggleSeverityAll = function() {
+        $scope.selectedSeverity.all = !$scope.selectedSeverity.all;
 
-        $scope.toggleSeverityAll = function() {
-          $scope.selectedSeverity.all = !$scope.selectedSeverity.all;
+        if ($scope.selectedSeverity.all) {
+          $scope.selectedSeverity.normal = false;
+          $scope.selectedSeverity.warning = false;
+          $scope.selectedSeverity.critical = false;
+        }
+      };
 
-          if ($scope.selectedSeverity.all) {
-            $scope.selectedSeverity.normal = false;
-            $scope.selectedSeverity.warning = false;
-            $scope.selectedSeverity.critical = false;
-          }
-        };
+      $scope.toggleSeverity = function(severity) {
+        $scope.selectedSeverity[severity] = !$scope.selectedSeverity[severity];
 
-        $scope.toggleSeverity = function(severity) {
-          $scope.selectedSeverity[severity] = !$scope.selectedSeverity[severity];
-
-          if (['normal', 'warning', 'critical'].indexOf(severity) > -1) {
-            if ($scope.selectedSeverity[severity] == false &&
+        if (['normal', 'warning', 'critical'].indexOf(severity) > -1) {
+          if ($scope.selectedSeverity[severity] == false &&
               (!$scope.selectedSeverity.normal &&
-                !$scope.selectedSeverity.warning &&
-                !$scope.selectedSeverity.critical
-              )) {
-              $scope.selectedSeverity.all = true;
-              return;
-            }
-          }
-
-          if ($scope.selectedSeverity.normal &&
-            $scope.selectedSeverity.warning &&
-            $scope.selectedSeverity.critical) {
+               !$scope.selectedSeverity.warning &&
+               !$scope.selectedSeverity.critical)) {
             $scope.selectedSeverity.all = true;
-            $scope.selectedSeverity.normal = false;
-            $scope.selectedSeverity.warning = false;
-            $scope.selectedSeverity.critical = false;
+            return;
           }
-          else {
-            $scope.selectedSeverity.all = false;
-          }
-        };
+        }
 
-        $scope.filterBySeverity = function(sensor) {
-          if ($scope.selectedSeverity.all) return true;
+        if ($scope.selectedSeverity.normal && $scope.selectedSeverity.warning &&
+            $scope.selectedSeverity.critical) {
+          $scope.selectedSeverity.all = true;
+          $scope.selectedSeverity.normal = false;
+          $scope.selectedSeverity.warning = false;
+          $scope.selectedSeverity.critical = false;
+        } else {
+          $scope.selectedSeverity.all = false;
+        }
+      };
 
-          return ((sensor.severity_flags.normal && $scope.selectedSeverity.normal) ||
-            (sensor.severity_flags.warning && $scope.selectedSeverity.warning) ||
-            (sensor.severity_flags.critical && $scope.selectedSeverity.critical)
-          );
-        };
-        $scope.filterBySearchTerms = function(sensor) {
+      $scope.filterBySeverity = function(sensor) {
+        if ($scope.selectedSeverity.all) return true;
 
-          if (!$scope.searchTerms.length) return true;
+        return (
+            (sensor.severity_flags.normal && $scope.selectedSeverity.normal) ||
+            (sensor.severity_flags.warning &&
+             $scope.selectedSeverity.warning) ||
+            (sensor.severity_flags.critical &&
+             $scope.selectedSeverity.critical));
+      };
+      $scope.filterBySearchTerms = function(sensor) {
 
-          for (var i = 0, length = $scope.searchTerms.length; i < length; i++) {
-            if (sensor.search_text.indexOf($scope.searchTerms[i].toLowerCase()) == -1) return false;
-          }
-          return true;
-        };
+        if (!$scope.searchTerms.length) return true;
 
-        $scope.loadSensorData = function() {
-          $scope.loading = true;
-          APIUtils.getAllSensorStatus(function(data, originalData) {
-            $scope.data = data;
-            $scope.originalData = originalData;
-            dataService.sensorData = data;
-            $scope.export_data = JSON.stringify(originalData);
-            $scope.loading = false;
-          });
-        };
+        for (var i = 0, length = $scope.searchTerms.length; i < length; i++) {
+          if (sensor.search_text.indexOf($scope.searchTerms[i].toLowerCase()) ==
+              -1)
+            return false;
+        }
+        return true;
+      };
 
-        $scope.loadSensorData();
-      }
-    ]);
+      $scope.loadSensorData = function() {
+        $scope.loading = true;
+        APIUtils.getAllSensorStatus(function(data, originalData) {
+          $scope.data = data;
+          $scope.originalData = originalData;
+          dataService.sensorData = data;
+          $scope.export_data = JSON.stringify(originalData);
+          $scope.loading = false;
+        });
+      };
+
+      $scope.loadSensorData();
+    }
+  ]);
 
 })(angular);
diff --git a/app/server-health/controllers/unit-id-controller.js b/app/server-health/controllers/unit-id-controller.js
index 4cd8055..7af4ca1 100644
--- a/app/server-health/controllers/unit-id-controller.js
+++ b/app/server-health/controllers/unit-id-controller.js
@@ -9,37 +9,35 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.serverHealth')
-    .controller('unitIdController', [
-      '$scope',
-      '$window',
-      'APIUtils',
-      'dataService',
-      function($scope, $window, APIUtils, dataService) {
-        $scope.dataService = dataService;
+  angular.module('app.serverHealth').controller('unitIdController', [
+    '$scope', '$window', 'APIUtils', 'dataService',
+    function($scope, $window, APIUtils, dataService) {
+      $scope.dataService = dataService;
 
-        APIUtils.getLEDState().then(function(state) {
-          $scope.displayLEDState(state);
-        });
+      APIUtils.getLEDState().then(function(state) {
+        $scope.displayLEDState(state);
+      });
 
-        $scope.displayLEDState = function(state) {
-          if (state == APIUtils.LED_STATE.on) {
-            dataService.LED_state = APIUtils.LED_STATE_TEXT.on;
-          }
-          else {
-            dataService.LED_state = APIUtils.LED_STATE_TEXT.off;
-          }
-        };
+      $scope.displayLEDState = function(state) {
+        if (state == APIUtils.LED_STATE.on) {
+          dataService.LED_state = APIUtils.LED_STATE_TEXT.on;
+        } else {
+          dataService.LED_state = APIUtils.LED_STATE_TEXT.off;
+        }
+      };
 
-        $scope.toggleLED = function() {
-          var toggleState = (dataService.LED_state == APIUtils.LED_STATE_TEXT.on) ?
-            APIUtils.LED_STATE.off : APIUtils.LED_STATE.on;
-          dataService.LED_state = (dataService.LED_state == APIUtils.LED_STATE_TEXT.on) ?
-            APIUtils.LED_STATE_TEXT.off : APIUtils.LED_STATE_TEXT.on;
-          APIUtils.setLEDState(toggleState, function(status) {});
-        };
-      }
-    ]);
+      $scope.toggleLED = function() {
+        var toggleState =
+            (dataService.LED_state == APIUtils.LED_STATE_TEXT.on) ?
+            APIUtils.LED_STATE.off :
+            APIUtils.LED_STATE.on;
+        dataService.LED_state =
+            (dataService.LED_state == APIUtils.LED_STATE_TEXT.on) ?
+            APIUtils.LED_STATE_TEXT.off :
+            APIUtils.LED_STATE_TEXT.on;
+        APIUtils.setLEDState(toggleState, function(status) {});
+      };
+    }
+  ]);
 
 })(angular);
diff --git a/app/server-health/index.js b/app/server-health/index.js
index c090f82..c5bdd28 100644
--- a/app/server-health/index.js
+++ b/app/server-health/index.js
@@ -9,64 +9,69 @@
   'use strict';
 
   angular
-    .module('app.serverHealth', [
-      'ngRoute',
-      'app.constants',
-      'app.common.services'
-    ])
-    // Route configuration
-    .config(['$routeProvider', function($routeProvider) {
-      $routeProvider
-        .when('/server-health/event-log', {
-          'template': require('./controllers/log-controller.html'),
-          'controller': 'logController',
-          authenticated: true
-        })
-        .when('/server-health/event-log/:type', {
-          'template': require('./controllers/log-controller.html'),
-          'controller': 'logController',
-          authenticated: true
-        })
-        .when('/server-health/event-log/:type/:id', {
-          'template': require('./controllers/log-controller.html'),
-          'controller': 'logController',
-          authenticated: true
-        })
-        .when('/server-health/inventory-overview', {
-          'template': require('./controllers/inventory-overview-controller.html'),
-          'controller': 'inventoryOverviewController',
-          authenticated: true
-        })
-        .when('/server-health/inventory', {
-          'template': require('./controllers/inventory-controller.html'),
-          'controller': 'inventoryController',
-          authenticated: true
-        })
-        .when('/server-health/sensors-overview', {
-          'template': require('./controllers/sensors-overview-controller.html'),
-          'controller': 'sensorsOverviewController',
-          authenticated: true
-        })
-        .when('/server-health/sensors/:type', {
-          'template': require('./controllers/sensors-controller.html'),
-          'controller': 'sensorsController',
-          authenticated: true
-        })
-        .when('/server-health/power-consumption', {
-          'template': require('./controllers/power-consumption-controller.html'),
-          'controller': 'powerConsumptionController',
-          authenticated: true
-        })
-        .when('/server-health/diagnostics', {
-          'template': require('./controllers/diagnostics-controller.html'),
-          'controller': 'diagnosticsController',
-          authenticated: true
-        })
-        .when('/server-health', {
-          'template': require('./controllers/log-controller.html'),
-          'controller': 'logController',
-          authenticated: true
-        });
-    }]);
+      .module(
+          'app.serverHealth',
+          ['ngRoute', 'app.constants', 'app.common.services'])
+      // Route configuration
+      .config([
+        '$routeProvider',
+        function($routeProvider) {
+          $routeProvider
+              .when('/server-health/event-log', {
+                'template': require('./controllers/log-controller.html'),
+                'controller': 'logController',
+                authenticated: true
+              })
+              .when('/server-health/event-log/:type', {
+                'template': require('./controllers/log-controller.html'),
+                'controller': 'logController',
+                authenticated: true
+              })
+              .when('/server-health/event-log/:type/:id', {
+                'template': require('./controllers/log-controller.html'),
+                'controller': 'logController',
+                authenticated: true
+              })
+              .when('/server-health/inventory-overview', {
+                'template':
+                    require('./controllers/inventory-overview-controller.html'),
+                'controller': 'inventoryOverviewController',
+                authenticated: true
+              })
+              .when('/server-health/inventory', {
+                'template': require('./controllers/inventory-controller.html'),
+                'controller': 'inventoryController',
+                authenticated: true
+              })
+              .when('/server-health/sensors-overview', {
+                'template':
+                    require('./controllers/sensors-overview-controller.html'),
+                'controller': 'sensorsOverviewController',
+                authenticated: true
+              })
+              .when('/server-health/sensors/:type', {
+                'template': require('./controllers/sensors-controller.html'),
+                'controller': 'sensorsController',
+                authenticated: true
+              })
+              .when('/server-health/power-consumption', {
+                'template':
+                    require('./controllers/power-consumption-controller.html'),
+                'controller': 'powerConsumptionController',
+                authenticated: true
+              })
+              .when('/server-health/diagnostics', {
+                'template':
+                    require('./controllers/diagnostics-controller.html'),
+                'controller': 'diagnosticsController',
+                authenticated: true
+              })
+              .when('/server-health', {
+                'template': require('./controllers/log-controller.html'),
+                'controller': 'logController',
+                authenticated: true
+              });
+        }
+      ]);
 
 })(window.angular);
diff --git a/app/templates.js b/app/templates.js
index 5cc6852..03fc0bc 100644
--- a/app/templates.js
+++ b/app/templates.js
@@ -11,7 +11,6 @@
   /**
    * Used for gulp template cache plugin.
    */
-  angular
-    .module('app.templates', []);
+  angular.module('app.templates', []);
 
 })(window.angular);
diff --git a/app/users/controllers/user-accounts-controller.js b/app/users/controllers/user-accounts-controller.js
index 2d65d8a..868407b 100644
--- a/app/users/controllers/user-accounts-controller.js
+++ b/app/users/controllers/user-accounts-controller.js
@@ -9,53 +9,55 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.users')
-    .controller('userAccountsController', [
-      '$scope',
-      '$window',
-      'APIUtils',
-      'dataService',
-      function($scope, $window, APIUtils, dataService) {
-        $scope.dataService = dataService;
-        $scope.state = 'none';
-        $scope.errorMsg = '';
+  angular.module('app.users').controller('userAccountsController', [
+    '$scope', '$window', 'APIUtils', 'dataService',
+    function($scope, $window, APIUtils, dataService) {
+      $scope.dataService = dataService;
+      $scope.state = 'none';
+      $scope.errorMsg = '';
 
-        $scope.changePassword = function(oldPassword, newPassword, confirmNewPassword) {
-          var user = $scope.dataService.getUser();
-          if (!oldPassword || !newPassword || !confirmNewPassword) {
-            $scope.state = 'error';
-            $scope.errorMsg = 'Field is required!';
-            return false;
-          }
-          if (newPassword !== confirmNewPassword) {
-            $scope.state = 'error';
-            $scope.errorMsg = 'New passwords do not match!';
-            return false;
-          }
-          if (newPassword === oldPassword) {
-            $scope.state = 'error';
-            $scope.errorMsg = 'New password and old password match!';
-            return false;
-          }
+      $scope.changePassword = function(
+          oldPassword, newPassword, confirmNewPassword) {
+        var user = $scope.dataService.getUser();
+        if (!oldPassword || !newPassword || !confirmNewPassword) {
+          $scope.state = 'error';
+          $scope.errorMsg = 'Field is required!';
+          return false;
+        }
+        if (newPassword !== confirmNewPassword) {
+          $scope.state = 'error';
+          $scope.errorMsg = 'New passwords do not match!';
+          return false;
+        }
+        if (newPassword === oldPassword) {
+          $scope.state = 'error';
+          $scope.errorMsg = 'New password and old password match!';
+          return false;
+        }
 
-          // Verify the oldPassword is correct
-          APIUtils.testPassword(user, oldPassword).then(function(state) {
-            APIUtils.changePassword(user, newPassword).then(function(response) {
-              // Clear the textboxes on a success
-              $scope.passwordVerify = '';
-              $scope.password = '';
-              $scope.oldPassword = '';
-              $scope.state = 'success';
-            }, function(error) {
-              $scope.state = 'error';
-              $scope.errorMsg = 'Error changing password!';
-            });
-          }, function(error) {
-            $scope.state = 'error';
-            $scope.errorMsg = 'Old password is not correct!';
-          });
-        };
-      }
-    ]);
+        // Verify the oldPassword is correct
+        APIUtils.testPassword(user, oldPassword)
+            .then(
+                function(state) {
+                  APIUtils.changePassword(user, newPassword)
+                      .then(
+                          function(response) {
+                            // Clear the textboxes on a success
+                            $scope.passwordVerify = '';
+                            $scope.password = '';
+                            $scope.oldPassword = '';
+                            $scope.state = 'success';
+                          },
+                          function(error) {
+                            $scope.state = 'error';
+                            $scope.errorMsg = 'Error changing password!';
+                          });
+                },
+                function(error) {
+                  $scope.state = 'error';
+                  $scope.errorMsg = 'Old password is not correct!';
+                });
+      };
+    }
+  ]);
 })(angular);
diff --git a/app/users/index.js b/app/users/index.js
index 4dfa1f2..695c294 100644
--- a/app/users/index.js
+++ b/app/users/index.js
@@ -9,24 +9,25 @@
   'use strict';
 
   angular
-    .module('app.users', [
-      'ngRoute',
-      'app.constants',
-      'app.common.services'
-    ])
-    // Route configuration
-    .config(['$routeProvider', function($routeProvider) {
-      $routeProvider
-        .when('/users/manage-accounts', {
-          'template': require('./controllers/user-accounts-controller.html'),
-          'controller': 'userAccountsController',
-          authenticated: true
-        })
-        .when('/users', {
-          'template': require('./controllers/user-accounts-controller.html'),
-          'controller': 'userAccountsController',
-          authenticated: true
-        });
-    }]);
+      .module('app.users', ['ngRoute', 'app.constants', 'app.common.services'])
+      // Route configuration
+      .config([
+        '$routeProvider',
+        function($routeProvider) {
+          $routeProvider
+              .when('/users/manage-accounts', {
+                'template':
+                    require('./controllers/user-accounts-controller.html'),
+                'controller': 'userAccountsController',
+                authenticated: true
+              })
+              .when('/users', {
+                'template':
+                    require('./controllers/user-accounts-controller.html'),
+                'controller': 'userAccountsController',
+                authenticated: true
+              });
+        }
+      ]);
 
 })(window.angular);
diff --git a/app/vendors.js b/app/vendors.js
index 232abde..410520a 100644
--- a/app/vendors.js
+++ b/app/vendors.js
@@ -8,6 +8,5 @@
 window.angular && (function(angular) {
   'use strict';
 
-  angular
-    .module('app.vendors', []);
+  angular.module('app.vendors', []);
 })(window.angular);
diff --git a/app/vendors/hterm/hterm_all.js b/app/vendors/hterm/hterm_all.js
index 2c551c2..a4b6fbf 100644
--- a/app/vendors/hterm/hterm_all.js
+++ b/app/vendors/hterm/hterm_all.js
@@ -90,15 +90,13 @@
 
   try {
     throw new Error();
-  }
-  catch (ex) {
+  } catch (ex) {
     var stackArray = ex.stack.split('\n');
     // In Safari, the resulting stackArray will only have 2 elements and the
     // individual strings are formatted differently.
     if (stackArray.length >= 3) {
       source = stackArray[2].replace(/^\s*at\s+/, '');
-    }
-    else {
+    } else {
       source = stackArray[1].replace(/^\s*global code@/, '');
     }
   }
@@ -107,11 +105,9 @@
     var path = arguments[i];
     if (path instanceof Array) {
       lib.rtdep.apply(lib, path);
-    }
-    else {
+    } else {
       var ary = this.runtimeDependencies_[path];
-      if (!ary)
-        ary = this.runtimeDependencies_[path] = [];
+      if (!ary) ary = this.runtimeDependencies_[path] = [];
       ary.push(source);
     }
   }
@@ -144,8 +140,7 @@
     }
   }
 
-  if (!passed)
-    throw new Error('Failed runtime dependency check');
+  if (!passed) throw new Error('Failed runtime dependency check');
 };
 
 /**
@@ -185,11 +180,9 @@
   var initNext = function() {
     if (ary.length) {
       var rec = ary.shift();
-      if (opt_logFunction)
-        opt_logFunction('init: ' + rec[0]);
+      if (opt_logFunction) opt_logFunction('init: ' + rec[0]);
       rec[1](lib.f.alarm(initNext));
-    }
-    else {
+    } else {
       onInit();
     }
   };
@@ -244,23 +237,26 @@
 
   // 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'),
+      ('^/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'),
+      ('^/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'),
+      ('^/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,
@@ -287,8 +283,7 @@
   }
 
   var ary = value.match(lib.colors.re_.rgbx);
-  if (!ary)
-    return null;
+  if (!ary) return null;
 
   return 'rgb:' + scale(ary[1]) + '/' + scale(ary[2]) + '/' + scale(ary[3]);
 };
@@ -306,18 +301,15 @@
  * Truncate values back down to 24 bit since that's all CSS supports.
  */
 lib.colors.x11HexToCSS = function(v) {
-  if (!v.startsWith('#'))
-    return null;
+  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;
+  if ([3, 6, 9, 12].indexOf(v.length) == -1) return null;
 
   // Reject non-hex values.
-  if (v.match(/[^a-f0-9]/i))
-    return null;
+  if (v.match(/[^a-f0-9]/i)) return null;
 
   // Split the colors out.
   var size = v.length / 3;
@@ -328,9 +320,9 @@
   // 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 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));
 };
@@ -413,20 +405,17 @@
       });
     }
     var ary = hex.match(hex24);
-    if (!ary)
-      return null;
+    if (!ary) return null;
 
-    return 'rgb(' + parseInt(ary[1], 16) + ', ' +
-      parseInt(ary[2], 16) + ', ' +
-      parseInt(ary[3], 16) + ')';
+    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 {
+  } else {
     arg = convert(arg);
   }
 
@@ -448,19 +437,20 @@
 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 (!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 {
+  } else {
     arg = convert(arg);
   }
 
@@ -473,11 +463,9 @@
  * Returns null if the value could not be normalized.
  */
 lib.colors.normalizeCSS = function(def) {
-  if (def.substr(0, 1) == '#')
-    return lib.colors.hexToRGB(def);
+  if (def.substr(0, 1) == '#') return lib.colors.hexToRGB(def);
 
-  if (lib.colors.re_.rgbx.test(def))
-    return def;
+  if (lib.colors.re_.rgbx.test(def)) return def;
 
   return lib.colors.nameToRGB(def);
 };
@@ -527,8 +515,7 @@
       ary.shift();
       return ary;
     }
-  }
-  else {
+  } else {
     var ary = color.match(lib.colors.re_.rgb);
     if (ary) {
       ary.shift();
@@ -554,16 +541,13 @@
  * @return {string} The corresponding CSS rgb(...) value.
  */
 lib.colors.nameToRGB = function(name) {
-  if (name in lib.colors.colorNames)
-    return lib.colors.colorNames[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];
+  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];
+  if (name in lib.colors.colorNames) return lib.colors.colorNames[name];
 
   return null;
 };
@@ -1329,8 +1313,7 @@
 
     if (fn in lib.f.replaceVars.functions) {
       rv = lib.f.replaceVars.functions[fn](rv);
-    }
-    else if (fn) {
+    } else if (fn) {
       throw 'Unknown escape function: ' + fn;
     }
 
@@ -1347,13 +1330,8 @@
   encodeURI: encodeURI,
   encodeURIComponent: encodeURIComponent,
   escapeHTML: function(str) {
-    var map = {
-      '<': '&lt;',
-      '>': '&gt;',
-      '&': '&amp;',
-      '"': '&quot;',
-      "'": '&#39;'
-    };
+    var map =
+        {'<': '&lt;', '>': '&gt;', '&': '&amp;', '"': '&quot;', '\'': '&#39;'};
 
     return str.replace(/[<>&\"\']/g, function(m) {
       return map[m];
@@ -1370,8 +1348,7 @@
 lib.f.getAcceptLanguages = function(callback) {
   if (lib.f.getAcceptLanguages.chromeSupported()) {
     chrome.i18n.getAcceptLanguages(callback);
-  }
-  else {
+  } else {
     setTimeout(function() {
       callback([navigator.language.replace(/-/g, '_')]);
     }, 0);
@@ -1397,8 +1374,7 @@
  *     leading '?', the '?' will be ignored.
  */
 lib.f.parseQuery = function(queryString) {
-  if (queryString.substr(0, 1) == '?')
-    queryString = queryString.substr(1);
+  if (queryString.substr(0, 1) == '?') queryString = queryString.substr(1);
 
   var rv = {};
 
@@ -1412,8 +1388,7 @@
 };
 
 lib.f.getURL = function(path) {
-  if (lib.f.getURL.chromeSupported())
-    return chrome.runtime.getURL(path);
+  if (lib.f.getURL.chromeSupported()) return chrome.runtime.getURL(path);
 
   return path;
 };
@@ -1430,10 +1405,8 @@
  * @param {integer} max The maximum acceptable value.
  */
 lib.f.clamp = function(v, min, max) {
-  if (v < min)
-    return min;
-  if (v > max)
-    return max;
+  if (v < min) return min;
+  if (v > max) return max;
   return v;
 };
 
@@ -1449,8 +1422,7 @@
   str = String(str);
   opt_ch = opt_ch || ' ';
 
-  while (str.length < length)
-    str = opt_ch + str;
+  while (str.length < length) str = opt_ch + str;
 
   return str;
 };
@@ -1477,12 +1449,10 @@
  * @param {string} A string of spaces of the requested length.
  */
 lib.f.getWhitespace = function(length) {
-  if (length <= 0)
-    return '';
+  if (length <= 0) return '';
 
   var f = this.getWhitespace;
-  if (!f.whitespace)
-    f.whitespace = '          ';
+  if (!f.whitespace) f.whitespace = '          ';
 
   while (length > f.whitespace.length) {
     f.whitespace += f.whitespace;
@@ -1549,8 +1519,7 @@
       }
     };
 
-    if (typeof callback == 'string')
-      return wrapperGenerator;
+    if (typeof callback == 'string') return wrapperGenerator;
 
     return wrapperGenerator(callback);
   })();
@@ -1581,8 +1550,7 @@
 
   try {
     throw new Error();
-  }
-  catch (ex) {
+  } catch (ex) {
     stackArray = ex.stack.split('\n');
   }
 
@@ -1610,8 +1578,7 @@
   var ceiling = Math.ceil(val);
   if (ceiling - val < .0001) {
     return ceiling;
-  }
-  else {
+  } else {
     return Math.floor(val);
   }
 };
@@ -1637,13 +1604,11 @@
  *     automatically added as the first language if it is not already present.
  */
 lib.MessageManager = function(languages) {
-  this.languages_ = languages.map(
-    function(el) {
-      return el.replace(/-/g, '_');
-    });
+  this.languages_ = languages.map(function(el) {
+    return el.replace(/-/g, '_');
+  });
 
-  if (this.languages_.indexOf('en') == -1)
-    this.languages_.unshift('en');
+  if (this.languages_.indexOf('en') == -1) this.languages_.unshift('en');
 
   this.messages = {};
 };
@@ -1660,14 +1625,12 @@
 
     if (!def.placeholders) {
       this.messages[key] = def.message;
-    }
-    else {
+    } 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;
-        });
+      this.messages[key] =
+          def.message.replace(/\$([a-z][^\s\$]+)\$/ig, function(m, name) {
+            return defs[key].placeholders[name.toLowerCase()].content;
+          });
     }
   }
 };
@@ -1683,7 +1646,7 @@
  *     loaded.
  */
 lib.MessageManager.prototype.findAndLoadMessages = function(
-  pattern, onComplete) {
+    pattern, onComplete) {
   var languages = this.languages_.concat();
   var loaded = [];
   var failed = [];
@@ -1691,23 +1654,22 @@
   function onLanguageComplete(state) {
     if (state) {
       loaded = languages.shift();
-    }
-    else {
+    } else {
       failed = languages.shift();
     }
 
     if (languages.length) {
       tryNextLanguage();
-    }
-    else {
+    } else {
       onComplete(loaded, failed);
     }
   }
 
   var tryNextLanguage = function() {
-    this.loadMessages(this.replaceReferences(pattern, languages),
-      onLanguageComplete.bind(this, true),
-      onLanguageComplete.bind(this, false));
+    this.loadMessages(
+        this.replaceReferences(pattern, languages),
+        onLanguageComplete.bind(this, true),
+        onLanguageComplete.bind(this, false));
   }.bind(this);
 
   tryNextLanguage();
@@ -1717,13 +1679,12 @@
  * Load messages from a messages.json file.
  */
 lib.MessageManager.prototype.loadMessages = function(
-  url, onSuccess, opt_onError) {
+    url, onSuccess, opt_onError) {
   var xhr = new XMLHttpRequest();
 
   xhr.onloadend = function() {
     if (xhr.status != 200) {
-      if (opt_onError)
-        opt_onError(xhr.status);
+      if (opt_onError) opt_onError(xhr.status);
 
       return;
     }
@@ -1752,7 +1713,7 @@
  * Per-instance copy of replaceReferences.
  */
 lib.MessageManager.prototype.replaceReferences =
-  lib.MessageManager.replaceReferences;
+    lib.MessageManager.replaceReferences;
 
 /**
  * Get a message by name, optionally replacing arguments too.
@@ -1768,10 +1729,8 @@
   if (msgname in this.messages) {
     message = this.messages[msgname];
 
-  }
-  else {
-    if (window.chrome.i18n)
-      message = chrome.i18n.getMessage(msgname);
+  } else {
+    if (window.chrome.i18n) message = chrome.i18n.getMessage(msgname);
 
     if (!message) {
       console.warn('Unknown message: ' + msgname);
@@ -1779,11 +1738,9 @@
     }
   }
 
-  if (!opt_args)
-    return message;
+  if (!opt_args) return message;
 
-  if (!(opt_args instanceof Array))
-    opt_args = [opt_args];
+  if (!(opt_args instanceof Array)) opt_args = [opt_args];
 
   return this.replaceReferences(message, opt_args);
 };
@@ -1821,15 +1778,13 @@
     var node = nodes[i];
     var i18n = node.getAttribute('i18n');
 
-    if (!i18n)
-      continue;
+    if (!i18n) continue;
 
     try {
       i18n = JSON.parse(i18n);
-    }
-    catch (ex) {
-      console.error('Can\'t parse ' + node.tagName + '#' + node.id + ': ' +
-        i18n);
+    } catch (ex) {
+      console.error(
+          'Can\'t parse ' + node.tagName + '#' + node.id + ': ' + i18n);
       throw ex;
     }
 
@@ -1841,8 +1796,7 @@
       var msg = this.get(msgname);
       if (key == '_') {
         node.textContent = msg;
-      }
-      else {
+      } else {
         node.setAttribute(key, msg);
       }
     }
@@ -1883,8 +1837,7 @@
   this.trace = false;
 
   var prefix = opt_prefix || '/';
-  if (prefix.substr(prefix.length - 1) != '/')
-    prefix += '/';
+  if (prefix.substr(prefix.length - 1) != '/') prefix += '/';
 
   this.prefix = prefix;
 
@@ -1935,7 +1888,7 @@
  * A local copy of the DEFAULT_VALUE constant to make it less verbose.
  */
 lib.PreferenceManager.Record.prototype.DEFAULT_VALUE =
-  lib.PreferenceManager.prototype.DEFAULT_VALUE;
+    lib.PreferenceManager.prototype.DEFAULT_VALUE;
 
 /**
  * Register a callback to be invoked when this preference changes.
@@ -1955,8 +1908,7 @@
  */
 lib.PreferenceManager.Record.prototype.removeObserver = function(observer) {
   var i = this.observers.indexOf(observer);
-  if (i >= 0)
-    this.observers.splice(i, 1);
+  if (i >= 0) this.observers.splice(i, 1);
 };
 
 /**
@@ -1986,8 +1938,7 @@
  * that you don't get notified about irrelevant changes.
  */
 lib.PreferenceManager.prototype.deactivate = function() {
-  if (!this.isActive_)
-    throw new Error('Not activated');
+  if (!this.isActive_) throw new Error('Not activated');
 
   this.isActive_ = false;
   this.storage.removeObserver(this.storageObserver_);
@@ -2001,8 +1952,7 @@
  * it's automatically called as part of the constructor.
  */
 lib.PreferenceManager.prototype.activate = function() {
-  if (this.isActive_)
-    throw new Error('Already activated');
+  if (this.isActive_) throw new Error('Already activated');
 
   this.isActive_ = true;
   this.storage.addObserver(this.storageObserver_);
@@ -2028,17 +1978,14 @@
   var pendingChildren = 0;
 
   function onChildComplete() {
-    if (--pendingChildren == 0 && opt_callback)
-      opt_callback();
+    if (--pendingChildren == 0 && opt_callback) opt_callback();
   }
 
-  var keys = Object.keys(this.prefRecords_).map(
-    function(el) {
-      return this.prefix + el;
-    }.bind(this));
+  var keys = Object.keys(this.prefRecords_).map(function(el) {
+    return this.prefix + el;
+  }.bind(this));
 
-  if (this.trace)
-    console.log('Preferences read: ' + this.prefix);
+  if (this.trace) console.log('Preferences read: ' + this.prefix);
 
   this.storage.getItems(keys, function(items) {
     var prefixLength = this.prefix.length;
@@ -2046,9 +1993,10 @@
     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)));
+      var needSync =
+          (name in this.childLists_ &&
+           (JSON.stringify(value) !=
+            JSON.stringify(this.prefRecords_[name].currentValue)));
 
       this.prefRecords_[name].currentValue = value;
 
@@ -2058,8 +2006,7 @@
       }
     }
 
-    if (pendingChildren == 0 && opt_callback)
-      setTimeout(opt_callback);
+    if (pendingChildren == 0 && opt_callback) setTimeout(opt_callback);
   }.bind(this));
 };
 
@@ -2079,19 +2026,17 @@
  *     PreferenceManager as parameters.
  */
 lib.PreferenceManager.prototype.definePreference = function(
-  name, value, opt_onChange) {
+    name, value, opt_onChange) {
 
   var record = this.prefRecords_[name];
   if (record) {
     this.changeDefault(name, value);
-  }
-  else {
+  } else {
     record = this.prefRecords_[name] =
-      new lib.PreferenceManager.Record(name, value);
+        new lib.PreferenceManager.Record(name, value);
   }
 
-  if (opt_onChange)
-    record.addObserver(opt_onChange);
+  if (opt_onChange) record.addObserver(opt_onChange);
 };
 
 /**
@@ -2126,11 +2071,11 @@
  *     preferences.
  */
 lib.PreferenceManager.prototype.defineChildren = function(
-  listName, childFactory) {
+    listName, childFactory) {
 
   // Define a preference to hold the ordered list of child ids.
-  this.definePreference(listName, [],
-    this.onChildListChange_.bind(this, listName));
+  this.definePreference(
+      listName, [], this.onChildListChange_.bind(this, listName));
   this.childFactories_[listName] = childFactory;
   this.childLists_[listName] = {};
 };
@@ -2147,11 +2092,9 @@
   if (global && typeof global != 'function')
     throw new Error('Invalid param: globals');
 
-  if (global)
-    this.globalObservers_.push(global);
+  if (global) this.globalObservers_.push(global);
 
-  if (!map)
-    return;
+  if (!map) return;
 
   for (var name in map) {
     if (!(name in this.prefRecords_))
@@ -2183,8 +2126,7 @@
  */
 lib.PreferenceManager.prototype.notifyChange_ = function(name) {
   var record = this.prefRecords_[name];
-  if (!record)
-    throw new Error('Unknown preference: ' + name);
+  if (!record) throw new Error('Unknown preference: ' + name);
 
   var currentValue = record.get();
 
@@ -2207,8 +2149,8 @@
  * @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) {
+lib.PreferenceManager.prototype.createChild = function(
+    listName, opt_hint, opt_id) {
   var ids = this.get(listName);
   var id;
 
@@ -2217,14 +2159,12 @@
     if (ids.indexOf(id) != -1)
       throw new Error('Duplicate child: ' + listName + ': ' + id);
 
-  }
-  else {
+  } else {
     // Pick a random, unique 4-digit hex identifier for the new profile.
     while (!id || ids.indexOf(id) != -1) {
       id = Math.floor(Math.random() * 0xffff + 1).toString(16);
       id = lib.f.zpad(id, 4);
-      if (opt_hint)
-        id = opt_hint + ':' + id;
+      if (opt_hint) id = opt_hint + ':' + id;
     }
   }
 
@@ -2318,15 +2258,13 @@
   for (var i = 0; i < a.length; i++) {
     if (b.indexOf(a[i]) != -1) {
       rv.common[a[i]] = true;
-    }
-    else {
+    } 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;
+    if ((b[i] in rv.added) || (b[i] in rv.common)) continue;
 
     rv.removed[b[i]] = true;
   }
@@ -2347,13 +2285,12 @@
  *     is complete.
  */
 lib.PreferenceManager.prototype.syncChildList = function(
-  listName, opt_callback) {
+    listName, opt_callback) {
 
   var pendingChildren = 0;
 
   function onChildStorage() {
-    if (--pendingChildren == 0 && opt_callback)
-      opt_callback();
+    if (--pendingChildren == 0 && opt_callback) opt_callback();
   }
 
   // The list of child ids that we *should* have a manager for.
@@ -2369,8 +2306,7 @@
     var id = currentIds[i];
 
     var managerIndex = oldIds.indexOf(id);
-    if (managerIndex >= 0)
-      oldIds.splice(managerIndex, 1);
+    if (managerIndex >= 0) oldIds.splice(managerIndex, 1);
 
     if (!this.childLists_[listName][id]) {
       var childManager = this.childFactories_[listName](this, id);
@@ -2390,8 +2326,7 @@
     delete this.childLists_[listName][oldIds[i]];
   }
 
-  if (!pendingChildren && opt_callback)
-    setTimeout(opt_callback);
+  if (!pendingChildren && opt_callback) setTimeout(opt_callback);
 };
 
 /**
@@ -2404,8 +2339,7 @@
  */
 lib.PreferenceManager.prototype.reset = function(name) {
   var record = this.prefRecords_[name];
-  if (!record)
-    throw new Error('Unknown preference: ' + name);
+  if (!record) throw new Error('Unknown preference: ' + name);
 
   this.storage.removeItem(this.prefix + name);
 
@@ -2460,7 +2394,7 @@
 lib.PreferenceManager.prototype.diff = function(a, b) {
   // If the types are different, or the type is not a simple primitive one.
   if ((typeof a) !== (typeof b) ||
-    !(/^(undefined|boolean|number|string)$/.test(typeof a))) {
+      !(/^(undefined|boolean|number|string)$/.test(typeof a))) {
     return true;
   }
 
@@ -2481,8 +2415,7 @@
  */
 lib.PreferenceManager.prototype.changeDefault = function(name, newValue) {
   var record = this.prefRecords_[name];
-  if (!record)
-    throw new Error('Unknown preference: ' + name);
+  if (!record) throw new Error('Unknown preference: ' + name);
 
   if (!this.diff(record.defaultValue, newValue)) {
     // Default value hasn't changed.
@@ -2524,19 +2457,16 @@
  */
 lib.PreferenceManager.prototype.set = function(name, newValue) {
   var record = this.prefRecords_[name];
-  if (!record)
-    throw new Error('Unknown preference: ' + name);
+  if (!record) throw new Error('Unknown preference: ' + name);
 
   var oldValue = record.get();
 
-  if (!this.diff(oldValue, newValue))
-    return;
+  if (!this.diff(oldValue, newValue)) return;
 
   if (this.diff(record.defaultValue, newValue)) {
     record.currentValue = newValue;
     this.storage.setItem(this.prefix + name, newValue);
-  }
-  else {
+  } else {
     record.currentValue = this.DEFAULT_VALUE;
     this.storage.removeItem(this.prefix + name);
   }
@@ -2559,8 +2489,7 @@
  */
 lib.PreferenceManager.prototype.get = function(name) {
   var record = this.prefRecords_[name];
-  if (!record)
-    throw new Error('Unknown preference: ' + name);
+  if (!record) throw new Error('Unknown preference: ' + name);
 
   return record.get();
 };
@@ -2579,14 +2508,10 @@
       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()
-        });
+        rv[name].push({id: id, json: this.getChild(name, id).exportAsJson()});
       }
 
-    }
-    else {
+    } else {
       var record = this.prefRecords_[name];
       if (record.currentValue != this.DEFAULT_VALUE)
         rv[name] = record.currentValue;
@@ -2615,8 +2540,7 @@
         childPrefManager.importFromJson(childList[i].json);
       }
 
-    }
-    else {
+    } else {
       this.set(name, json[name]);
     }
   }
@@ -2635,8 +2559,7 @@
 lib.PreferenceManager.prototype.onStorageChange_ = function(map) {
   for (var key in map) {
     if (this.prefix) {
-      if (key.lastIndexOf(this.prefix, 0) != 0)
-        continue;
+      if (key.lastIndexOf(this.prefix, 0) != 0) continue;
     }
 
     var name = key.substr(this.prefix.length);
@@ -2650,14 +2573,12 @@
 
     var newValue = map[key].newValue;
     var currentValue = record.currentValue;
-    if (currentValue === record.DEFAULT_VALUE)
-      currentValue = (void 0);
+    if (currentValue === record.DEFAULT_VALUE) currentValue = (void 0);
 
     if (this.diff(currentValue, newValue)) {
       if (typeof newValue == 'undefined') {
         record.currentValue = record.DEFAULT_VALUE;
-      }
-      else {
+      } else {
         record.currentValue = newValue;
       }
 
@@ -2697,11 +2618,7 @@
  * @param {*} data The value of the resource.
  */
 lib.resource.add = function(name, type, data) {
-  lib.resource.resources_[name] = {
-    type: type,
-    name: name,
-    data: data
-  };
+  lib.resource.resources_[name] = {type: type, name: name, data: data};
 };
 
 /**
@@ -2790,8 +2707,7 @@
  * 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;
+  if (chrome.storage[areaname] != this.storage_) return;
 
   for (var i = 0; i < this.observers_.length; i++) {
     this.observers_[i](changes);
@@ -2815,8 +2731,7 @@
  */
 lib.Storage.Chrome.prototype.removeObserver = function(callback) {
   var i = this.observers_.indexOf(callback);
-  if (i != -1)
-    this.observers_.splice(i, 1);
+  if (i != -1) this.observers_.splice(i, 1);
 };
 
 /**
@@ -2828,8 +2743,7 @@
 lib.Storage.Chrome.prototype.clear = function(opt_callback) {
   this.storage_.clear();
 
-  if (opt_callback)
-    setTimeout(opt_callback, 0);
+  if (opt_callback) setTimeout(opt_callback, 0);
 };
 
 /**
@@ -2926,17 +2840,13 @@
  * Called by the storage implementation when the storage is modified.
  */
 lib.Storage.Local.prototype.onStorage_ = function(e) {
-  if (e.storageArea != this.storage_)
-    return;
+  if (e.storageArea != this.storage_) return;
 
   // IE throws an exception if JSON.parse is given an empty string.
   var prevValue = e.oldValue ? JSON.parse(e.oldValue) : '';
   var curValue = e.newValue ? JSON.parse(e.newValue) : '';
   var o = {};
-  o[e.key] = {
-    oldValue: prevValue,
-    newValue: curValue
-  };
+  o[e.key] = {oldValue: prevValue, newValue: curValue};
 
   for (var i = 0; i < this.observers_.length; i++) {
     this.observers_[i](o);
@@ -2960,8 +2870,7 @@
  */
 lib.Storage.Local.prototype.removeObserver = function(callback) {
   var i = this.observers_.indexOf(callback);
-  if (i != -1)
-    this.observers_.splice(i, 1);
+  if (i != -1) this.observers_.splice(i, 1);
 };
 
 /**
@@ -2973,8 +2882,7 @@
 lib.Storage.Local.prototype.clear = function(opt_callback) {
   this.storage_.clear();
 
-  if (opt_callback)
-    setTimeout(opt_callback, 0);
+  if (opt_callback) setTimeout(opt_callback, 0);
 };
 
 /**
@@ -2990,8 +2898,7 @@
   if (typeof value == 'string') {
     try {
       value = JSON.parse(value);
-    }
-    catch (e) {
+    } catch (e) {
       // If we can't parse the value, just return it unparsed.
     }
   }
@@ -3015,13 +2922,11 @@
     if (typeof value == 'string') {
       try {
         rv[key] = JSON.parse(value);
-      }
-      catch (e) {
+      } catch (e) {
         // If we can't parse the value, just return it unparsed.
         rv[key] = value;
       }
-    }
-    else {
+    } else {
       keys.splice(i, 1);
     }
   }
@@ -3042,8 +2947,7 @@
 lib.Storage.Local.prototype.setItem = function(key, value, opt_callback) {
   this.storage_.setItem(key, JSON.stringify(value));
 
-  if (opt_callback)
-    setTimeout(opt_callback, 0);
+  if (opt_callback) setTimeout(opt_callback, 0);
 };
 
 /**
@@ -3059,8 +2963,7 @@
     this.storage_.setItem(key, JSON.stringify(obj[key]));
   }
 
-  if (opt_callback)
-    setTimeout(opt_callback, 0);
+  if (opt_callback) setTimeout(opt_callback, 0);
 };
 
 /**
@@ -3074,8 +2977,7 @@
 lib.Storage.Local.prototype.removeItem = function(key, opt_callback) {
   this.storage_.removeItem(key);
 
-  if (opt_callback)
-    setTimeout(opt_callback, 0);
+  if (opt_callback) setTimeout(opt_callback, 0);
 };
 
 /**
@@ -3091,8 +2993,7 @@
     this.storage_.removeItem(ary[i]);
   }
 
-  if (opt_callback)
-    setTimeout(opt_callback, 0);
+  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.
@@ -3127,8 +3028,7 @@
  */
 lib.Storage.Memory.prototype.removeObserver = function(callback) {
   var i = this.observers_.indexOf(callback);
-  if (i != -1)
-    this.observers_.splice(i, 1);
+  if (i != -1) this.observers_.splice(i, 1);
 };
 
 /**
@@ -3140,10 +3040,7 @@
 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)
-    };
+    e[key] = {oldValue: this.storage_[key], newValue: (void 0)};
   }
 
   this.storage_ = {};
@@ -3154,8 +3051,7 @@
     }
   }.bind(this), 0);
 
-  if (opt_callback)
-    setTimeout(opt_callback, 0);
+  if (opt_callback) setTimeout(opt_callback, 0);
 };
 
 /**
@@ -3171,8 +3067,7 @@
   if (typeof value == 'string') {
     try {
       value = JSON.parse(value);
-    }
-    catch (e) {
+    } catch (e) {
       // If we can't parse the value, just return it unparsed.
     }
   }
@@ -3196,13 +3091,11 @@
     if (typeof value == 'string') {
       try {
         rv[key] = JSON.parse(value);
-      }
-      catch (e) {
+      } catch (e) {
         // If we can't parse the value, just return it unparsed.
         rv[key] = value;
       }
-    }
-    else {
+    } else {
       keys.splice(i, 1);
     }
   }
@@ -3225,10 +3118,7 @@
   this.storage_[key] = JSON.stringify(value);
 
   var e = {};
-  e[key] = {
-    oldValue: oldValue,
-    newValue: value
-  };
+  e[key] = {oldValue: oldValue, newValue: value};
 
   setTimeout(function() {
     for (var i = 0; i < this.observers_.length; i++) {
@@ -3236,8 +3126,7 @@
     }
   }.bind(this), 0);
 
-  if (opt_callback)
-    setTimeout(opt_callback, 0);
+  if (opt_callback) setTimeout(opt_callback, 0);
 };
 
 /**
@@ -3252,10 +3141,7 @@
   var e = {};
 
   for (var key in obj) {
-    e[key] = {
-      oldValue: this.storage_[key],
-      newValue: obj[key]
-    };
+    e[key] = {oldValue: this.storage_[key], newValue: obj[key]};
     this.storage_[key] = JSON.stringify(obj[key]);
   }
 
@@ -3265,8 +3151,7 @@
     }
   }.bind(this));
 
-  if (opt_callback)
-    setTimeout(opt_callback, 0);
+  if (opt_callback) setTimeout(opt_callback, 0);
 };
 
 /**
@@ -3280,8 +3165,7 @@
 lib.Storage.Memory.prototype.removeItem = function(key, opt_callback) {
   delete this.storage_[key];
 
-  if (opt_callback)
-    setTimeout(opt_callback, 0);
+  if (opt_callback) setTimeout(opt_callback, 0);
 };
 
 /**
@@ -3297,8 +3181,7 @@
     delete this.storage_[ary[i]];
   }
 
-  if (opt_callback)
-    setTimeout(opt_callback, 0);
+  if (opt_callback) setTimeout(opt_callback, 0);
 };
 // SOURCE FILE: libdot/js/lib_test_manager.js
 // Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
@@ -3383,8 +3266,7 @@
   this.save = false;
   this.data = '';
   this.logFunction_ = opt_logFunction || function(s) {
-    if (this.save)
-      this.data += s + '\n';
+    if (this.save) this.data += s + '\n';
     console.log(s);
   };
   this.pending_ = '';
@@ -3433,8 +3315,7 @@
 lib.TestManager.Log.prototype.print = function(str) {
   if (this.pending_) {
     this.pending_ += str;
-  }
-  else {
+  } else {
     this.pending_ = this.prefix_ + str;
   }
 };
@@ -3445,8 +3326,7 @@
  * @param {string} str The string to add to the log.
  */
 lib.TestManager.Log.prototype.println = function(str) {
-  if (this.pending_)
-    this.flush();
+  if (this.pending_) this.flush();
 
   this.logFunction_(this.prefix_ + str);
 };
@@ -3455,8 +3335,7 @@
  * Flush any pending log message.
  */
 lib.TestManager.Log.prototype.flush = function() {
-  if (!this.pending_)
-    return;
+  if (!this.pending_) return;
 
   this.logFunction_(this.pending_);
   this.pending_ = '';
@@ -3538,9 +3417,7 @@
   ctor.getTestList = lib.TestManager.Suite.getTestList;
   ctor.testList_ = [];
   ctor.testMap_ = {};
-  ctor.prototype = {
-    __proto__: lib.TestManager.Suite.prototype
-  };
+  ctor.prototype = {__proto__: lib.TestManager.Suite.prototype};
 
   lib.TestManager.Suite.subclasses.push(ctor);
 
@@ -3558,8 +3435,7 @@
  * This method is copied to new subclasses when they are created.
  */
 lib.TestManager.Suite.addTest = function(testName, testFunction) {
-  if (testName in this.testMap_)
-    throw 'Duplicate test name: ' + testName;
+  if (testName in this.testMap_) throw 'Duplicate test name: ' + testName;
 
   var test = new lib.TestManager.Test(this, testName, testFunction);
   this.testMap_[testName] = test;
@@ -3570,8 +3446,7 @@
  * Defines a disabled test.
  */
 lib.TestManager.Suite.disableTest = function(testName, testFunction) {
-  if (testName in this.testMap_)
-    throw 'Duplicate test name: ' + testName;
+  if (testName in this.testMap_) throw 'Duplicate test name: ' + testName;
 
   var test = new lib.TestManager.Test(this, testName, testFunction);
   console.log('Disabled test: ' + test.fullName);
@@ -3729,18 +3604,15 @@
   try {
     // Tests are applied to the parent lib.TestManager.Suite subclass.
     this.testFunction_.apply(result.suite, [result, result.testRun.cx]);
-  }
-  catch (ex) {
-    if (ex instanceof lib.TestManager.Result.TestComplete)
-      return;
+  } catch (ex) {
+    if (ex instanceof lib.TestManager.Result.TestComplete) return;
 
     result.println('Test raised an exception: ' + ex);
 
     if (ex.stack) {
       if (ex.stack instanceof Array) {
         result.println(ex.stack.join('\n'));
-      }
-      else {
+      } else {
         result.println(ex.stack);
       }
     }
@@ -3836,7 +3708,7 @@
 };
 
 lib.TestManager.TestRun.prototype.selectSuite = function(
-  suiteClass, opt_pattern) {
+    suiteClass, opt_pattern) {
   var pattern = opt_pattern || this.ALL_TESTS;
   var selectCount = 0;
   var testList = suiteClass.getTestList();
@@ -3847,10 +3719,8 @@
     // the ALL_TESTS String object, rather than the contents of the string.
     if (pattern !== this.ALL_TESTS) {
       if (pattern instanceof RegExp) {
-        if (!pattern.test(test.testName))
-          continue;
-      }
-      else if (test.testName != pattern) {
+        if (!pattern.test(test.testName)) continue;
+      } else if (test.testName != pattern) {
         continue;
       }
     }
@@ -3879,8 +3749,8 @@
   var selectCount = 0;
 
   for (var i = 0; i < lib.TestManager.Suite.subclasses.length; i++) {
-    selectCount += this.selectSuite(lib.TestManager.Suite.subclasses[i],
-      pattern);
+    selectCount +=
+        this.selectSuite(lib.TestManager.Suite.subclasses[i], pattern);
   }
 
   if (!selectCount) {
@@ -3895,18 +3765,17 @@
  * that would otherwise go uncaught.
  */
 lib.TestManager.TestRun.prototype.onUncaughtException_ = function(
-  message, file, line) {
+    message, file, line) {
 
   if (message.indexOf('Uncaught lib.TestManager.Result.TestComplete') == 0 ||
-    message.indexOf('status: passed') != -1) {
+      message.indexOf('status: passed') != -1) {
     // This is a result.pass() or result.fail() call from a callback.  We're
     // already going to deal with it as part of the completeTest_() call
     // that raised it.  We can safely squelch this error message.
     return true;
   }
 
-  if (!this.currentResult)
-    return;
+  if (!this.currentResult) return;
 
   if (message == 'Uncaught ' + this.currentResult.expectedErrorMessage_) {
     // Test cases may need to raise an unhandled exception as part of the test.
@@ -3915,11 +3784,11 @@
 
   var when = 'during';
 
-  if (this.currentResult.status != this.currentResult.PENDING)
-    when = 'after';
+  if (this.currentResult.status != this.currentResult.PENDING) when = 'after';
 
-  this.log.println('Uncaught exception ' + when + ' test case: ' +
-    this.currentResult.test.fullName);
+  this.log.println(
+      'Uncaught exception ' + when +
+      ' test case: ' + this.currentResult.test.fullName);
   this.log.println(message + ', ' + file + ':' + line);
 
   this.currentResult.completeTest_(this.currentResult.FAILED, false);
@@ -3939,7 +3808,7 @@
  *     this function.
  */
 lib.TestManager.TestRun.prototype.onTestRunComplete_ = function(
-  opt_skipTimeout) {
+    opt_skipTimeout) {
   if (!opt_skipTimeout) {
     // The final test may have left a lingering setTimeout(..., 0), or maybe
     // poked at the DOM in a way that will trigger a event to fire at the end
@@ -3952,9 +3821,9 @@
   this.duration = (new Date()) - this.startDate;
 
   this.log.popPrefix();
-  this.log.println('} ' + this.passes.length + ' passed, ' +
-    this.failures.length + ' failed, ' +
-    this.msToSeconds_(this.duration));
+  this.log.println(
+      '} ' + this.passes.length + ' passed, ' + this.failures.length +
+      ' failed, ' + this.msToSeconds_(this.duration));
   this.log.println('');
 
   this.summarize();
@@ -3974,28 +3843,26 @@
   try {
     this.testManager.testPostamble(result, this.cx);
     result.suite.postamble(result, this.ctx);
-  }
-  catch (ex) {
-    this.log.println('Unexpected exception in postamble: ' +
-      (ex.stack ? ex.stack : ex));
+  } catch (ex) {
+    this.log.println(
+        'Unexpected exception in postamble: ' + (ex.stack ? ex.stack : ex));
     this.panic = true;
   }
 
   this.log.popPrefix();
-  this.log.print('} ' + result.status + ', ' +
-    this.msToSeconds_(result.duration));
+  this.log.print(
+      '} ' + result.status + ', ' + this.msToSeconds_(result.duration));
   this.log.flush();
 
   if (result.status == result.FAILED) {
     this.failures.push(result);
     this.currentSuite = null;
-  }
-  else if (result.status == result.PASSED) {
+  } else if (result.status == result.PASSED) {
     this.passes.push(result);
-  }
-  else {
-    this.log.println('Unknown result status: ' + result.test.fullName + ': ' +
-      result.status);
+  } else {
+    this.log.println(
+        'Unknown result status: ' + result.test.fullName + ': ' +
+        result.status);
     return this.panic = true;
   }
 
@@ -4022,9 +3889,9 @@
  *     time around.
  */
 lib.TestManager.TestRun.prototype.onResultReComplete = function(
-  result, lateStatus) {
-  this.log.println('Late complete for test: ' + result.test.fullName + ': ' +
-    lateStatus);
+    result, lateStatus) {
+  this.log.println(
+      'Late complete for test: ' + result.test.fullName + ': ' + lateStatus);
 
   // Consider any late completion a failure, even if it's a double-pass, since
   // it's a misuse of the testing API.
@@ -4039,8 +3906,7 @@
  * Run the next test in the queue.
  */
 lib.TestManager.TestRun.prototype.runNextTest_ = function() {
-  if (this.panic || !this.testQueue_.length)
-    return this.onTestRunComplete_();
+  if (this.panic || !this.testQueue_.length) return this.onTestRunComplete_();
 
   if (this.maxFailures && this.failures.length >= this.maxFailures) {
     this.log.println('Maximum failure count reached, aborting test run.');
@@ -4058,8 +3924,7 @@
       this.log.println('Initializing suite: ' + test.suiteClass.suiteName);
       suite = new test.suiteClass(this.testManager, this.cx);
     }
-  }
-  catch (ex) {
+  } catch (ex) {
     // If test suite setup fails we're not even going to try to run the tests.
     this.log.println('Exception during setup: ' + (ex.stack ? ex.stack : ex));
     this.panic = true;
@@ -4076,10 +3941,10 @@
     suite.preamble(this.currentResult, this.cx);
 
     this.testQueue_.shift();
-  }
-  catch (ex) {
-    this.log.println('Unexpected exception during test preamble: ' +
-      (ex.stack ? ex.stack : ex));
+  } catch (ex) {
+    this.log.println(
+        'Unexpected exception during test preamble: ' +
+        (ex.stack ? ex.stack : ex));
     this.log.popPrefix();
     this.log.println('}');
 
@@ -4090,12 +3955,11 @@
 
   try {
     this.currentResult.run();
-  }
-  catch (ex) {
+  } catch (ex) {
     // Result.run() should catch test exceptions and turn them into failures.
     // If we got here, it means there is trouble in the testing framework.
-    this.log.println('Unexpected exception during test run: ' +
-      (ex.stack ? ex.stack : ex));
+    this.log.println(
+        'Unexpected exception during test run: ' + (ex.stack ? ex.stack : ex));
     this.panic = true;
   }
 };
@@ -4146,8 +4010,9 @@
   }
 
   if (this.testQueue_.length) {
-    this.log.println('Test run incomplete: ' + this.testQueue_.length +
-      ' test(s) were not run.');
+    this.log.println(
+        'Test run incomplete: ' + this.testQueue_.length +
+        ' test(s) were not run.');
   }
 };
 
@@ -4221,7 +4086,7 @@
 
 lib.TestManager.Result.TestComplete.prototype.toString = function() {
   return 'lib.TestManager.Result.TestComplete: ' + this.result.test.fullName +
-    ', status: ' + this.result.status;
+      ', status: ' + this.result.status;
 };
 
 /**
@@ -4258,8 +4123,7 @@
 lib.TestManager.Result.prototype.onTimeout_ = function() {
   this.timeout_ = null;
 
-  if (this.status != this.PENDING)
-    return;
+  if (this.status != this.PENDING) return;
 
   this.println('Test timed out.');
   this.completeTest_(this.FAILED, false);
@@ -4282,8 +4146,7 @@
  * @param {int} ms Number of milliseconds requested.
  */
 lib.TestManager.Result.prototype.requestTime = function(ms) {
-  if (this.timeout_)
-    clearTimeout(this.timeout_);
+  if (this.timeout_) clearTimeout(this.timeout_);
 
   this.timeout_ = setTimeout(this.onTimeout_.bind(this), ms);
 };
@@ -4301,8 +4164,7 @@
     this.status = status;
 
     this.testRun.onResultComplete(this);
-  }
-  else {
+  } else {
     this.testRun.onResultReComplete(this, status);
   }
 
@@ -4314,15 +4176,12 @@
  * Check that two arrays are equal.
  */
 lib.TestManager.Result.prototype.arrayEQ_ = function(actual, expected) {
-  if (!actual || !expected)
-    return (!actual && !expected);
+  if (!actual || !expected) return (!actual && !expected);
 
-  if (actual.length != expected.length)
-    return false;
+  if (actual.length != expected.length) return false;
 
   for (var i = 0; i < actual.length; ++i)
-    if (actual[i] != expected[i])
-      return false;
+    if (actual[i] != expected[i]) return false;
 
   return true;
 };
@@ -4342,11 +4201,10 @@
  *     of the caller.
  */
 lib.TestManager.Result.prototype.assertEQ = function(
-  actual, expected, opt_name) {
+    actual, expected, opt_name) {
   // Utility function to pretty up the log.
   function format(value) {
-    if (typeof value == 'number')
-      return value;
+    if (typeof value == 'number') return value;
 
     var str = String(value);
     var ary = str.split('\n').map(function(e) {
@@ -4356,24 +4214,22 @@
       // If the string has newlines, start it off on its own line so that
       // it's easier to compare against another string with newlines.
       return '\n' + ary.join('\n');
-    }
-    else {
+    } else {
       return ary.join('\n');
     }
   }
 
-  if (actual === expected)
-    return;
+  if (actual === expected) return;
 
   // Deal with common object types since JavaScript can't.
   if (expected instanceof Array)
-    if (this.arrayEQ_(actual, expected))
-      return;
+    if (this.arrayEQ_(actual, expected)) return;
 
   var name = opt_name ? '[' + opt_name + ']' : '';
 
-  this.fail('assertEQ' + name + ': ' + this.getCallerLocation_(1) + ': ' +
-    format(actual) + ' !== ' + format(expected));
+  this.fail(
+      'assertEQ' + name + ': ' + this.getCallerLocation_(1) + ': ' +
+      format(actual) + ' !== ' + format(expected));
 };
 
 /**
@@ -4391,13 +4247,13 @@
  *     of the caller.
  */
 lib.TestManager.Result.prototype.assert = function(actual, opt_name) {
-  if (actual === true)
-    return;
+  if (actual === true) return;
 
   var name = opt_name ? '[' + opt_name + ']' : '';
 
-  this.fail('assert' + name + ': ' + this.getCallerLocation_(1) + ': ' +
-    String(actual));
+  this.fail(
+      'assert' + name + ': ' + this.getCallerLocation_(1) + ': ' +
+      String(actual));
 };
 
 /**
@@ -4413,8 +4269,7 @@
 lib.TestManager.Result.prototype.getCallerLocation_ = function(frameIndex) {
   try {
     throw new Error();
-  }
-  catch (ex) {
+  } catch (ex) {
     var frame = ex.stack.split('\n')[frameIndex + 2];
     var ary = frame.match(/([^/]+:\d+):\d+\)?$/);
     return ary ? ary[1] : '???';
@@ -4436,8 +4291,7 @@
  * @param {string} opt_message Optional message to add to the log.
  */
 lib.TestManager.Result.prototype.fail = function(opt_message) {
-  if (arguments.length)
-    this.println(opt_message);
+  if (arguments.length) this.println(opt_message);
 
   this.completeTest_(this.FAILED, true);
 };
@@ -4491,37 +4345,30 @@
     if (this.bytesLeft == 0) {
       if (c <= 0x7F) {
         ret += str.charAt(i);
-      }
-      else if (0xC0 <= c && c <= 0xDF) {
+      } else if (0xC0 <= c && c <= 0xDF) {
         this.codePoint = c - 0xC0;
         this.bytesLeft = 1;
         this.lowerBound = 0x80;
-      }
-      else if (0xE0 <= c && c <= 0xEF) {
+      } else if (0xE0 <= c && c <= 0xEF) {
         this.codePoint = c - 0xE0;
         this.bytesLeft = 2;
         this.lowerBound = 0x800;
-      }
-      else if (0xF0 <= c && c <= 0xF7) {
+      } else if (0xF0 <= c && c <= 0xF7) {
         this.codePoint = c - 0xF0;
         this.bytesLeft = 3;
         this.lowerBound = 0x10000;
-      }
-      else if (0xF8 <= c && c <= 0xFB) {
+      } else if (0xF8 <= c && c <= 0xFB) {
         this.codePoint = c - 0xF8;
         this.bytesLeft = 4;
         this.lowerBound = 0x200000;
-      }
-      else if (0xFC <= c && c <= 0xFD) {
+      } else if (0xFC <= c && c <= 0xFD) {
         this.codePoint = c - 0xFC;
         this.bytesLeft = 5;
         this.lowerBound = 0x4000000;
-      }
-      else {
+      } else {
         ret += '�';
       }
-    }
-    else {
+    } else {
       if (0x80 <= c && c <= 0xBF) {
         this.bytesLeft--;
         this.codePoint = (this.codePoint << 6) + (c - 0x80);
@@ -4530,26 +4377,23 @@
           // filter out surrogate pairs.
           var codePoint = this.codePoint;
           if (codePoint < this.lowerBound ||
-            (0xD800 <= codePoint && codePoint <= 0xDFFF) ||
-            codePoint > 0x10FFFF) {
+              (0xD800 <= codePoint && codePoint <= 0xDFFF) ||
+              codePoint > 0x10FFFF) {
             ret += '�';
-          }
-          else {
+          } else {
             // Encode as UTF-16 in the output.
             if (codePoint < 0x10000) {
               ret += String.fromCharCode(codePoint);
-            }
-            else {
+            } else {
               // Surrogate pair.
               codePoint -= 0x10000;
               ret += String.fromCharCode(
-                0xD800 + ((codePoint >>> 10) & 0x3FF),
-                0xDC00 + (codePoint & 0x3FF));
+                  0xD800 + ((codePoint >>> 10) & 0x3FF),
+                  0xDC00 + (codePoint & 0x3FF));
             }
           }
         }
-      }
-      else {
+      } else {
         // Too few bytes in multi-byte sequence. Rewind stream so we
         // don't lose the next byte.
         ret += '�';
@@ -4592,20 +4436,17 @@
     var c = str.charCodeAt(i);
     if (0xDC00 <= c && c <= 0xDFFF) {
       c = 0xFFFD;
-    }
-    else if (0xD800 <= c && c <= 0xDBFF) {
+    } else if (0xD800 <= c && c <= 0xDBFF) {
       if (i + 1 < str.length) {
         var d = str.charCodeAt(i + 1);
         if (0xDC00 <= d && d <= 0xDFFF) {
           // Swallow a surrogate pair.
           c = 0x10000 + ((c & 0x3FF) << 10) + (d & 0x3FF);
           i++;
-        }
-        else {
+        } else {
           c = 0xFFFD;
         }
-      }
-      else {
+      } else {
         c = 0xFFFD;
       }
     }
@@ -4615,16 +4456,13 @@
     if (c <= 0x7F) {
       ret += str.charAt(i);
       continue;
-    }
-    else if (c <= 0x7FF) {
+    } else if (c <= 0x7FF) {
       ret += String.fromCharCode(0xC0 | (c >>> 6));
       bytesLeft = 1;
-    }
-    else if (c <= 0xFFFF) {
+    } else if (c <= 0xFFFF) {
       ret += String.fromCharCode(0xE0 | (c >>> 12));
       bytesLeft = 2;
-    }
-    else /* if (c <= 0x10FFFF) */ {
+    } else /* if (c <= 0x10FFFF) */ {
       ret += String.fromCharCode(0xF0 | (c >>> 18));
       bytesLeft = 3;
     }
@@ -4745,7 +4583,7 @@
  */
 if (!String.prototype.codePointAt) {
   (function() {
-    'use strict'; // needed to support `apply`/`call` with `undefined`/`null`
+    'use strict';  // needed to support `apply`/`call` with `undefined`/`null`
     var codePointAt = function(position) {
       if (this == null) {
         throw TypeError();
@@ -4754,7 +4592,7 @@
       var size = string.length;
       // `ToInteger`
       var index = position ? Number(position) : 0;
-      if (index != index) { // better `isNaN`
+      if (index != index) {  // better `isNaN`
         index = 0;
       }
       // Account for out-of-bounds indices:
@@ -4764,12 +4602,13 @@
       // Get the first code unit
       var first = string.charCodeAt(index);
       var second;
-      if ( // check if it’s the start of a surrogate pair
-        first >= 0xD800 && first <= 0xDBFF && // high surrogate
-        size > index + 1 // there is a next code unit
+      if (
+          // check if it’s the start of a surrogate pair
+          first >= 0xD800 && first <= 0xDBFF &&  // high surrogate
+          size > index + 1                       // there is a next code unit
       ) {
         second = string.charCodeAt(index + 1);
-        if (second >= 0xDC00 && second <= 0xDFFF) { // low surrogate
+        if (second >= 0xDC00 && second <= 0xDFFF) {  // low surrogate
           // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
           return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
         }
@@ -4777,13 +4616,10 @@
       return first;
     };
     if (Object.defineProperty) {
-      Object.defineProperty(String.prototype, 'codePointAt', {
-        'value': codePointAt,
-        'configurable': true,
-        'writable': true
-      });
-    }
-    else {
+      Object.defineProperty(
+          String.prototype, 'codePointAt',
+          {'value': codePointAt, 'configurable': true, 'writable': true});
+    } else {
       String.prototype.codePointAt = codePointAt;
     }
   }());
@@ -4806,309 +4642,98 @@
 // Sorted list of non-overlapping intervals of non-spacing characters
 // generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c"
 lib.wc.combining = [
-  [0x0300, 0x036F],
-  [0x0483, 0x0486],
-  [0x0488, 0x0489],
-  [0x0591, 0x05BD],
-  [0x05BF, 0x05BF],
-  [0x05C1, 0x05C2],
-  [0x05C4, 0x05C5],
-  [0x05C7, 0x05C7],
-  [0x0600, 0x0603],
-  [0x0610, 0x0615],
-  [0x064B, 0x065E],
-  [0x0670, 0x0670],
-  [0x06D6, 0x06E4],
-  [0x06E7, 0x06E8],
-  [0x06EA, 0x06ED],
-  [0x070F, 0x070F],
-  [0x0711, 0x0711],
-  [0x0730, 0x074A],
-  [0x07A6, 0x07B0],
-  [0x07EB, 0x07F3],
-  [0x0901, 0x0902],
-  [0x093C, 0x093C],
-  [0x0941, 0x0948],
-  [0x094D, 0x094D],
-  [0x0951, 0x0954],
-  [0x0962, 0x0963],
-  [0x0981, 0x0981],
-  [0x09BC, 0x09BC],
-  [0x09C1, 0x09C4],
-  [0x09CD, 0x09CD],
-  [0x09E2, 0x09E3],
-  [0x0A01, 0x0A02],
-  [0x0A3C, 0x0A3C],
-  [0x0A41, 0x0A42],
-  [0x0A47, 0x0A48],
-  [0x0A4B, 0x0A4D],
-  [0x0A70, 0x0A71],
-  [0x0A81, 0x0A82],
-  [0x0ABC, 0x0ABC],
-  [0x0AC1, 0x0AC5],
-  [0x0AC7, 0x0AC8],
-  [0x0ACD, 0x0ACD],
-  [0x0AE2, 0x0AE3],
-  [0x0B01, 0x0B01],
-  [0x0B3C, 0x0B3C],
-  [0x0B3F, 0x0B3F],
-  [0x0B41, 0x0B43],
-  [0x0B4D, 0x0B4D],
-  [0x0B56, 0x0B56],
-  [0x0B82, 0x0B82],
-  [0x0BC0, 0x0BC0],
-  [0x0BCD, 0x0BCD],
-  [0x0C3E, 0x0C40],
-  [0x0C46, 0x0C48],
-  [0x0C4A, 0x0C4D],
-  [0x0C55, 0x0C56],
-  [0x0CBC, 0x0CBC],
-  [0x0CBF, 0x0CBF],
-  [0x0CC6, 0x0CC6],
-  [0x0CCC, 0x0CCD],
-  [0x0CE2, 0x0CE3],
-  [0x0D41, 0x0D43],
-  [0x0D4D, 0x0D4D],
-  [0x0DCA, 0x0DCA],
-  [0x0DD2, 0x0DD4],
-  [0x0DD6, 0x0DD6],
-  [0x0E31, 0x0E31],
-  [0x0E34, 0x0E3A],
-  [0x0E47, 0x0E4E],
-  [0x0EB1, 0x0EB1],
-  [0x0EB4, 0x0EB9],
-  [0x0EBB, 0x0EBC],
-  [0x0EC8, 0x0ECD],
-  [0x0F18, 0x0F19],
-  [0x0F35, 0x0F35],
-  [0x0F37, 0x0F37],
-  [0x0F39, 0x0F39],
-  [0x0F71, 0x0F7E],
-  [0x0F80, 0x0F84],
-  [0x0F86, 0x0F87],
-  [0x0F90, 0x0F97],
-  [0x0F99, 0x0FBC],
-  [0x0FC6, 0x0FC6],
-  [0x102D, 0x1030],
-  [0x1032, 0x1032],
-  [0x1036, 0x1037],
-  [0x1039, 0x1039],
-  [0x1058, 0x1059],
-  [0x1160, 0x11FF],
-  [0x135F, 0x135F],
-  [0x1712, 0x1714],
-  [0x1732, 0x1734],
-  [0x1752, 0x1753],
-  [0x1772, 0x1773],
-  [0x17B4, 0x17B5],
-  [0x17B7, 0x17BD],
-  [0x17C6, 0x17C6],
-  [0x17C9, 0x17D3],
-  [0x17DD, 0x17DD],
-  [0x180B, 0x180D],
-  [0x18A9, 0x18A9],
-  [0x1920, 0x1922],
-  [0x1927, 0x1928],
-  [0x1932, 0x1932],
-  [0x1939, 0x193B],
-  [0x1A17, 0x1A18],
-  [0x1B00, 0x1B03],
-  [0x1B34, 0x1B34],
-  [0x1B36, 0x1B3A],
-  [0x1B3C, 0x1B3C],
-  [0x1B42, 0x1B42],
-  [0x1B6B, 0x1B73],
-  [0x1DC0, 0x1DCA],
-  [0x1DFE, 0x1DFF],
-  [0x200B, 0x200F],
-  [0x202A, 0x202E],
-  [0x2060, 0x2063],
-  [0x206A, 0x206F],
-  [0x20D0, 0x20EF],
-  [0x302A, 0x302F],
-  [0x3099, 0x309A],
-  [0xA806, 0xA806],
-  [0xA80B, 0xA80B],
-  [0xA825, 0xA826],
-  [0xFB1E, 0xFB1E],
-  [0xFE00, 0xFE0F],
-  [0xFE20, 0xFE23],
-  [0xFEFF, 0xFEFF],
-  [0xFFF9, 0xFFFB],
-  [0x10A01, 0x10A03],
-  [0x10A05, 0x10A06],
-  [0x10A0C, 0x10A0F],
-  [0x10A38, 0x10A3A],
-  [0x10A3F, 0x10A3F],
-  [0x1D167, 0x1D169],
-  [0x1D173, 0x1D182],
-  [0x1D185, 0x1D18B],
-  [0x1D1AA, 0x1D1AD],
-  [0x1D242, 0x1D244],
-  [0xE0001, 0xE0001],
-  [0xE0020, 0xE007F],
+  [0x0300, 0x036F],   [0x0483, 0x0486],   [0x0488, 0x0489],
+  [0x0591, 0x05BD],   [0x05BF, 0x05BF],   [0x05C1, 0x05C2],
+  [0x05C4, 0x05C5],   [0x05C7, 0x05C7],   [0x0600, 0x0603],
+  [0x0610, 0x0615],   [0x064B, 0x065E],   [0x0670, 0x0670],
+  [0x06D6, 0x06E4],   [0x06E7, 0x06E8],   [0x06EA, 0x06ED],
+  [0x070F, 0x070F],   [0x0711, 0x0711],   [0x0730, 0x074A],
+  [0x07A6, 0x07B0],   [0x07EB, 0x07F3],   [0x0901, 0x0902],
+  [0x093C, 0x093C],   [0x0941, 0x0948],   [0x094D, 0x094D],
+  [0x0951, 0x0954],   [0x0962, 0x0963],   [0x0981, 0x0981],
+  [0x09BC, 0x09BC],   [0x09C1, 0x09C4],   [0x09CD, 0x09CD],
+  [0x09E2, 0x09E3],   [0x0A01, 0x0A02],   [0x0A3C, 0x0A3C],
+  [0x0A41, 0x0A42],   [0x0A47, 0x0A48],   [0x0A4B, 0x0A4D],
+  [0x0A70, 0x0A71],   [0x0A81, 0x0A82],   [0x0ABC, 0x0ABC],
+  [0x0AC1, 0x0AC5],   [0x0AC7, 0x0AC8],   [0x0ACD, 0x0ACD],
+  [0x0AE2, 0x0AE3],   [0x0B01, 0x0B01],   [0x0B3C, 0x0B3C],
+  [0x0B3F, 0x0B3F],   [0x0B41, 0x0B43],   [0x0B4D, 0x0B4D],
+  [0x0B56, 0x0B56],   [0x0B82, 0x0B82],   [0x0BC0, 0x0BC0],
+  [0x0BCD, 0x0BCD],   [0x0C3E, 0x0C40],   [0x0C46, 0x0C48],
+  [0x0C4A, 0x0C4D],   [0x0C55, 0x0C56],   [0x0CBC, 0x0CBC],
+  [0x0CBF, 0x0CBF],   [0x0CC6, 0x0CC6],   [0x0CCC, 0x0CCD],
+  [0x0CE2, 0x0CE3],   [0x0D41, 0x0D43],   [0x0D4D, 0x0D4D],
+  [0x0DCA, 0x0DCA],   [0x0DD2, 0x0DD4],   [0x0DD6, 0x0DD6],
+  [0x0E31, 0x0E31],   [0x0E34, 0x0E3A],   [0x0E47, 0x0E4E],
+  [0x0EB1, 0x0EB1],   [0x0EB4, 0x0EB9],   [0x0EBB, 0x0EBC],
+  [0x0EC8, 0x0ECD],   [0x0F18, 0x0F19],   [0x0F35, 0x0F35],
+  [0x0F37, 0x0F37],   [0x0F39, 0x0F39],   [0x0F71, 0x0F7E],
+  [0x0F80, 0x0F84],   [0x0F86, 0x0F87],   [0x0F90, 0x0F97],
+  [0x0F99, 0x0FBC],   [0x0FC6, 0x0FC6],   [0x102D, 0x1030],
+  [0x1032, 0x1032],   [0x1036, 0x1037],   [0x1039, 0x1039],
+  [0x1058, 0x1059],   [0x1160, 0x11FF],   [0x135F, 0x135F],
+  [0x1712, 0x1714],   [0x1732, 0x1734],   [0x1752, 0x1753],
+  [0x1772, 0x1773],   [0x17B4, 0x17B5],   [0x17B7, 0x17BD],
+  [0x17C6, 0x17C6],   [0x17C9, 0x17D3],   [0x17DD, 0x17DD],
+  [0x180B, 0x180D],   [0x18A9, 0x18A9],   [0x1920, 0x1922],
+  [0x1927, 0x1928],   [0x1932, 0x1932],   [0x1939, 0x193B],
+  [0x1A17, 0x1A18],   [0x1B00, 0x1B03],   [0x1B34, 0x1B34],
+  [0x1B36, 0x1B3A],   [0x1B3C, 0x1B3C],   [0x1B42, 0x1B42],
+  [0x1B6B, 0x1B73],   [0x1DC0, 0x1DCA],   [0x1DFE, 0x1DFF],
+  [0x200B, 0x200F],   [0x202A, 0x202E],   [0x2060, 0x2063],
+  [0x206A, 0x206F],   [0x20D0, 0x20EF],   [0x302A, 0x302F],
+  [0x3099, 0x309A],   [0xA806, 0xA806],   [0xA80B, 0xA80B],
+  [0xA825, 0xA826],   [0xFB1E, 0xFB1E],   [0xFE00, 0xFE0F],
+  [0xFE20, 0xFE23],   [0xFEFF, 0xFEFF],   [0xFFF9, 0xFFFB],
+  [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F],
+  [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169],
+  [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD],
+  [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F],
   [0xE0100, 0xE01EF]
 ];
 
 // Sorted list of non-overlapping intervals of East Asian Ambiguous characters
 // generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c"
 lib.wc.ambiguous = [
-  [0x00A1, 0x00A1],
-  [0x00A4, 0x00A4],
-  [0x00A7, 0x00A8],
-  [0x00AA, 0x00AA],
-  [0x00AE, 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],
-  [0x0391, 0x03A1],
-  [0x03A3, 0x03A9],
-  [0x03B1, 0x03C1],
-  [0x03C3, 0x03C9],
-  [0x0401, 0x0401],
-  [0x0410, 0x044F],
-  [0x0451, 0x0451],
-  [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],
-  [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],
-  [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],
-  [0x2605, 0x2606],
-  [0x2609, 0x2609],
-  [0x260E, 0x260F],
-  [0x2614, 0x2615],
-  [0x261C, 0x261C],
-  [0x261E, 0x261E],
-  [0x2640, 0x2640],
-  [0x2642, 0x2642],
-  [0x2660, 0x2661],
-  [0x2663, 0x2665],
-  [0x2667, 0x266A],
-  [0x266C, 0x266D],
-  [0x266F, 0x266F],
-  [0x273D, 0x273D],
-  [0x2776, 0x277F],
-  [0xE000, 0xF8FF],
-  [0xFFFD, 0xFFFD],
-  [0xF0000, 0xFFFFD],
-  [0x100000, 0x10FFFD]
+  [0x00A1, 0x00A1], [0x00A4, 0x00A4], [0x00A7, 0x00A8],   [0x00AA, 0x00AA],
+  [0x00AE, 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], [0x0391, 0x03A1], [0x03A3, 0x03A9],   [0x03B1, 0x03C1],
+  [0x03C3, 0x03C9], [0x0401, 0x0401], [0x0410, 0x044F],   [0x0451, 0x0451],
+  [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],   [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], [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], [0x2605, 0x2606], [0x2609, 0x2609],   [0x260E, 0x260F],
+  [0x2614, 0x2615], [0x261C, 0x261C], [0x261E, 0x261E],   [0x2640, 0x2640],
+  [0x2642, 0x2642], [0x2660, 0x2661], [0x2663, 0x2665],   [0x2667, 0x266A],
+  [0x266C, 0x266D], [0x266F, 0x266F], [0x273D, 0x273D],   [0x2776, 0x277F],
+  [0xE000, 0xF8FF], [0xFFFD, 0xFFFD], [0xF0000, 0xFFFFD], [0x100000, 0x10FFFD]
 ];
 
 /**
@@ -5121,8 +4746,7 @@
  */
 lib.wc.isSpace = function(ucs) {
   // Auxiliary function for binary search in interval table.
-  var min = 0,
-    max = lib.wc.combining.length - 1;
+  var min = 0, max = lib.wc.combining.length - 1;
   var mid;
 
   if (ucs < lib.wc.combining[0][0] || ucs > lib.wc.combining[max][1])
@@ -5131,11 +4755,9 @@
     mid = Math.floor((min + max) / 2);
     if (ucs > lib.wc.combining[mid][1]) {
       min = mid + 1;
-    }
-    else if (ucs < lib.wc.combining[mid][0]) {
+    } else if (ucs < lib.wc.combining[mid][0]) {
       max = mid - 1;
-    }
-    else {
+    } else {
       return true;
     }
   }
@@ -5153,8 +4775,7 @@
  * character.
  */
 lib.wc.isCjkAmbiguous = function(ucs) {
-  var min = 0,
-    max = lib.wc.ambiguous.length - 1;
+  var min = 0, max = lib.wc.ambiguous.length - 1;
   var mid;
 
   if (ucs < lib.wc.ambiguous[0][0] || ucs > lib.wc.ambiguous[max][1])
@@ -5163,11 +4784,9 @@
     mid = Math.floor((min + max) / 2);
     if (ucs > lib.wc.ambiguous[mid][1]) {
       min = mid + 1;
-    }
-    else if (ucs < lib.wc.ambiguous[mid][0]) {
+    } else if (ucs < lib.wc.ambiguous[mid][0]) {
       max = mid - 1;
-    }
-    else {
+    } else {
       return true;
     }
   }
@@ -5185,8 +4804,7 @@
 lib.wc.charWidth = function(ucs) {
   if (lib.wc.regardCjkAmbiguous) {
     return lib.wc.charWidthRegardAmbiguous(ucs);
-  }
-  else {
+  } else {
     return lib.wc.charWidthDisregardAmbiguous(ucs);
   }
 };
@@ -5201,31 +4819,26 @@
  */
 lib.wc.charWidthDisregardAmbiguous = function(ucs) {
   // Test for 8-bit control characters.
-  if (ucs === 0)
-    return lib.wc.nulWidth;
-  if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))
-    return lib.wc.controlWidth;
+  if (ucs === 0) return lib.wc.nulWidth;
+  if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) return lib.wc.controlWidth;
 
   // Optimize for ASCII characters.
-  if (ucs < 0x7f)
-    return 1;
+  if (ucs < 0x7f) return 1;
 
   // Binary search in table of non-spacing characters.
-  if (lib.wc.isSpace(ucs))
-    return 0;
+  if (lib.wc.isSpace(ucs)) return 0;
 
   // If we arrive here, ucs is not a combining or C0/C1 control character.
   return 1 +
-    (ucs >= 0x1100 &&
-      (ucs <= 0x115f || // Hangul Jamo init. consonants
+      (ucs >= 0x1100 &&
+       (ucs <= 0x115f ||  // Hangul Jamo init. consonants
         ucs == 0x2329 || ucs == 0x232a ||
-        (ucs >= 0x2e80 && ucs <= 0xa4cf &&
-          ucs != 0x303f) || // CJK ... Yi
-        (ucs >= 0xac00 && ucs <= 0xd7a3) || // Hangul Syllables
-        (ucs >= 0xf900 && ucs <= 0xfaff) || // CJK Compatibility Ideographs
-        (ucs >= 0xfe10 && ucs <= 0xfe19) || // Vertical forms
-        (ucs >= 0xfe30 && ucs <= 0xfe6f) || // CJK Compatibility Forms
-        (ucs >= 0xff00 && ucs <= 0xff60) || // Fullwidth Forms
+        (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs != 0x303f) ||  // CJK ... Yi
+        (ucs >= 0xac00 && ucs <= 0xd7a3) ||  // Hangul Syllables
+        (ucs >= 0xf900 && ucs <= 0xfaff) ||  // CJK Compatibility Ideographs
+        (ucs >= 0xfe10 && ucs <= 0xfe19) ||  // Vertical forms
+        (ucs >= 0xfe30 && ucs <= 0xfe6f) ||  // CJK Compatibility Forms
+        (ucs >= 0xff00 && ucs <= 0xff60) ||  // Fullwidth Forms
         (ucs >= 0xffe0 && ucs <= 0xffe6) ||
         (ucs >= 0x20000 && ucs <= 0x2fffd) ||
         (ucs >= 0x30000 && ucs <= 0x3fffd)));
@@ -5242,8 +4855,7 @@
  * @return {integer} The column width of the given character.
  */
 lib.wc.charWidthRegardAmbiguous = function(ucs) {
-  if (lib.wc.isCjkAmbiguous(ucs))
-    return lib.wc.cjkAmbiguousWidth;
+  if (lib.wc.isCjkAmbiguous(ucs)) return lib.wc.cjkAmbiguousWidth;
 
   return lib.wc.charWidthDisregardAmbiguous(ucs);
 };
@@ -5261,8 +4873,7 @@
   for (var i = 0; i < str.length;) {
     var codePoint = str.codePointAt(i);
     width = lib.wc.charWidth(codePoint);
-    if (width < 0)
-      return -1;
+    if (width < 0) return -1;
     rv += width;
     i += (codePoint <= 0xffff) ? 1 : 2;
   }
@@ -5284,14 +4895,15 @@
 
   for (startIndex = 0, width = 0; startIndex < str.length; startIndex++) {
     width += lib.wc.charWidth(str.charCodeAt(startIndex));
-    if (width > start)
-      break;
+    if (width > start) break;
   }
 
   if (opt_width != undefined) {
-    for (endIndex = startIndex, width = 0; endIndex < str.length && width < opt_width; width += lib.wc.charWidth(str.charCodeAt(endIndex)), endIndex++);
-    if (width > opt_width)
-      endIndex--;
+    for (endIndex = startIndex, width = 0;
+         endIndex < str.length && width < opt_width;
+         width += lib.wc.charWidth(str.charCodeAt(endIndex)), endIndex++)
+      ;
+    if (width > opt_width) endIndex--;
     return str.substring(startIndex, endIndex);
   }
 
@@ -5310,15 +4922,15 @@
 lib.wc.substring = function(str, start, end) {
   return lib.wc.substr(str, start, end - start);
 };
-lib.resource.add('libdot/changelog/version', 'text/plain',
-  '1.11' +
-  ''
-);
+lib.resource.add(
+    'libdot/changelog/version', 'text/plain',
+    '1.11' +
+        '');
 
-lib.resource.add('libdot/changelog/date', 'text/plain',
-  '2017-04-17' +
-  ''
-);
+lib.resource.add(
+    'libdot/changelog/date', 'text/plain',
+    '2017-04-17' +
+        '');
 
 // SOURCE FILE: hterm/js/hterm.js
 // Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
@@ -5361,7 +4973,6 @@
  */
 hterm.notifyCopyMessage = '✂';
 
-
 /**
  * Text shown in a desktop notification for the terminal
  * bell.  \u226a is a unicode EIGHTH NOTE, %(title) will
@@ -5374,9 +4985,9 @@
  *
  * A test harness should ensure that they all exist before running.
  */
-hterm.testDeps = ['hterm.ScrollPort.Tests', 'hterm.Screen.Tests',
-  'hterm.Terminal.Tests', 'hterm.VT.Tests',
-  'hterm.VT.CannedTests'
+hterm.testDeps = [
+  'hterm.ScrollPort.Tests', 'hterm.Screen.Tests', 'hterm.Terminal.Tests',
+  'hterm.VT.Tests', 'hterm.VT.CannedTests'
 ];
 
 /**
@@ -5396,8 +5007,7 @@
   function onTab(tab) {
     if (tab && window.chrome) {
       chrome.windows.get(tab.windowId, null, onWindow);
-    }
-    else {
+    } 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';
@@ -5409,10 +5019,9 @@
     var ary = navigator.userAgent.match(/\sChrome\/(\d\d)/);
     var version = ary ? parseInt(ary[1]) : -1;
     if (window.chrome && chrome.storage && chrome.storage.sync &&
-      version > 21) {
+        version > 21) {
       hterm.defaultStorage = new lib.Storage.Chrome(chrome.storage.sync);
-    }
-    else {
+    } else {
       hterm.defaultStorage = new lib.Storage.Local();
     }
   }
@@ -5427,20 +5036,14 @@
 
   if (isPackagedApp) {
     // Packaged apps are never displayed in browser tabs.
-    setTimeout(onWindow.bind(null, {
-      type: 'popup'
-    }), 0);
-  }
-  else {
+    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);
+    } else {
+      setTimeout(onWindow.bind(null, {type: 'normal'}), 0);
     }
   }
 });
@@ -5474,8 +5077,7 @@
 hterm.copySelectionToClipboard = function(document) {
   try {
     document.execCommand('copy');
-  }
-  catch (firefoxException) {
+  } catch (firefoxException) {
     // Ignore this. FF throws an exception if there was an error, even though
     // the spec says just return false.
   }
@@ -5489,8 +5091,7 @@
 hterm.pasteFromClipboard = function(document) {
   try {
     document.execCommand('paste');
-  }
-  catch (firefoxException) {
+  } catch (firefoxException) {
     // Ignore this. FF throws an exception if there was an error, even though
     // the spec says just return false.
   }
@@ -5627,8 +5228,9 @@
  *     otherwise.
  */
 hterm.RowCol.prototype.equals = function(that) {
-  return (this.row == that.row && this.column == that.column &&
-    this.overflow == that.overflow);
+  return (
+      this.row == that.row && this.column == that.column &&
+      this.overflow == that.overflow);
 };
 
 /**
@@ -5638,8 +5240,9 @@
  *     instance.
  */
 hterm.RowCol.prototype.toString = function() {
-  return ('[hterm.RowCol: ' + this.row + ', ' + this.column + ', ' +
-    this.overflow + ']');
+  return (
+      '[hterm.RowCol: ' + this.row + ', ' + this.column + ', ' + this.overflow +
+      ']');
 };
 // SOURCE FILE: hterm/js/hterm_frame.js
 // Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
@@ -5706,13 +5309,9 @@
   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]);
+  this.iframe_.contentWindow.postMessage(
+      {name: 'ipc-init', argv: [{messagePort: this.messageChannel_.port2}]},
+      this.url, [this.messageChannel_.port2]);
 };
 
 /**
@@ -5726,14 +5325,14 @@
 hterm.Frame.prototype.sendTerminalInfo_ = function() {
   lib.f.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('/')
-    }]);
+                       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));
 };
 
@@ -5748,14 +5347,12 @@
  * Close this frame.
  */
 hterm.Frame.prototype.close = function() {
-  if (!this.container_ || !this.container_.parentNode)
-    return;
+  if (!this.container_ || !this.container_.parentNode) return;
 
   this.container_.parentNode.removeChild(this.container_);
   this.onClose();
 };
 
-
 /**
  * Clients may override this.
  */
@@ -5765,13 +5362,9 @@
  * 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.');
+  if (!this.messageChannel_) throw new Error('Message channel is not set up.');
 
-  this.messageChannel_.port1.postMessage({
-    name: name,
-    argv: argv
-  });
+  this.messageChannel_.port1.postMessage({name: name, argv: argv});
 };
 
 /**
@@ -5783,8 +5376,7 @@
   var self = this;
 
   function opt(name, defaultValue) {
-    if (name in self.options)
-      return self.options[name];
+    if (name in self.options) return self.options[name];
 
     return defaultValue;
   }
@@ -5808,36 +5400,36 @@
   var document = this.terminal_.document_;
 
   var container = this.container_ = document.createElement('div');
-  container.style.cssText = (
-    'position: absolute;' +
-    'display: -webkit-flex;' +
-    '-webkit-flex-direction: column;' +
-    'top: 10%;' +
-    'left: 4%;' +
-    'width: 90%;' +
-    'height: 80%;' +
-    'box-shadow: 0 0 2px ' + this.terminal_.getForegroundColor() + ';' +
-    'border: 2px ' + this.terminal_.getForegroundColor() + ' solid;');
+  container.style.cssText =
+      ('position: absolute;' +
+       'display: -webkit-flex;' +
+       '-webkit-flex-direction: column;' +
+       'top: 10%;' +
+       'left: 4%;' +
+       'width: 90%;' +
+       'height: 80%;' +
+       'box-shadow: 0 0 2px ' + this.terminal_.getForegroundColor() + ';' +
+       'border: 2px ' + this.terminal_.getForegroundColor() + ' solid;');
 
   var header = document.createElement('div');
-  header.style.cssText = (
-    'display: -webkit-flex;' +
-    '-webkit-justify-content: flex-end;' +
-    'height: ' + headerHeight + ';' +
-    'background-color: ' + this.terminal_.getForegroundColor() + ';' +
-    'color: ' + this.terminal_.getBackgroundColor() + ';' +
-    'font-size: 16px;' +
-    'font-family: ' + this.terminal_.getFontFamily());
+  header.style.cssText =
+      ('display: -webkit-flex;' +
+       '-webkit-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);
 
   if (false) {
     // No use for the close button.
     var button = document.createElement('div');
     button.setAttribute('role', 'button');
-    button.style.cssText = (
-      'margin-top: -3px;' +
-      'margin-right: 3px;' +
-      'cursor: pointer;');
+    button.style.cssText =
+        ('margin-top: -3px;' +
+         'margin-right: 3px;' +
+         'cursor: pointer;');
     button.textContent = '⨯';
     button.addEventListener('click', this.onCloseClicked_.bind(this));
     header.appendChild(button);
@@ -5845,10 +5437,10 @@
 
   var iframe = this.iframe_ = document.createElement('iframe');
   iframe.onload = this.onLoad_.bind(this);
-  iframe.style.cssText = (
-    'display: -webkit-flex;' +
-    '-webkit-flex: 1;' +
-    'width: 100%');
+  iframe.style.cssText =
+      ('display: -webkit-flex;' +
+       '-webkit-flex: 1;' +
+       'width: 100%');
   iframe.setAttribute('src', this.url);
   iframe.setAttribute('seamless', true);
   container.appendChild(iframe);
@@ -6110,18 +5702,15 @@
  *     null to disable the keyboard.
  */
 hterm.Keyboard.prototype.installKeyboard = function(element) {
-  if (element == this.keyboardElement_)
-    return;
+  if (element == this.keyboardElement_) return;
 
-  if (element && this.keyboardElement_)
-    this.installKeyboard(null);
+  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 {
+    } else {
       this.keyboardElement_.removeEventListener(handler[0], handler[1]);
     }
   }
@@ -6145,8 +5734,7 @@
  * where a third party app sends synthetic keystrokes to Chrome.
  */
 hterm.Keyboard.prototype.onTextInput_ = function(e) {
-  if (!e.data)
-    return;
+  if (!e.data) return;
 
   e.data.split('').forEach(this.terminal.onVTKeystroke.bind(this.terminal));
 };
@@ -6174,17 +5762,14 @@
     // 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();
+    if (!e.shiftKey) ch = ch.toLowerCase();
     code = ch.charCodeAt(0) + 128;
 
-  }
-  else if (e.charCode >= 32) {
+  } else if (e.charCode >= 32) {
     ch = e.charCode;
   }
 
-  if (ch)
-    this.terminal.onVTKeystroke(String.fromCharCode(ch));
+  if (ch) this.terminal.onVTKeystroke(String.fromCharCode(ch));
 
   e.preventDefault();
   e.stopPropagation();
@@ -6198,10 +5783,8 @@
  * 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();
+  if (!window.chrome || !window.chrome.app || !window.chrome.app.window) return;
+  if (!e.ctrlKey || !e.shiftKey) e.preventDefault();
 };
 
 hterm.Keyboard.prototype.onFocusOut_ = function(e) {
@@ -6212,8 +5795,7 @@
   if (e.keyCode == 18)
     this.altKeyPressed = this.altKeyPressed & ~(1 << (e.location - 1));
 
-  if (e.keyCode == 27)
-    this.preventChromeAppNonCtrlShiftDefault_(e);
+  if (e.keyCode == 27) this.preventChromeAppNonCtrlShiftDefault_(e);
 };
 
 /**
@@ -6223,8 +5805,7 @@
   if (e.keyCode == 18)
     this.altKeyPressed = this.altKeyPressed | (1 << (e.location - 1));
 
-  if (e.keyCode == 27)
-    this.preventChromeAppNonCtrlShiftDefault_(e);
+  if (e.keyCode == 27) this.preventChromeAppNonCtrlShiftDefault_(e);
 
   var keyDef = this.keyMap.keyDefs[e.keyCode];
   if (!keyDef) {
@@ -6248,8 +5829,7 @@
     if (typeof action == 'function')
       action = action.apply(self.keyMap, [e, keyDef]);
 
-    if (action === DEFAULT && name != 'normal')
-      action = getAction('normal');
+    if (action === DEFAULT && name != 'normal') action = getAction('normal');
 
     return action;
   }
@@ -6298,14 +5878,11 @@
 
   if (control) {
     action = getAction('control');
-  }
-  else if (alt) {
+  } else if (alt) {
     action = getAction('alt');
-  }
-  else if (meta) {
+  } else if (meta) {
     action = getAction('meta');
-  }
-  else {
+  } else {
     action = getAction('normal');
   }
 
@@ -6317,7 +5894,7 @@
 
   var keyDown = {
     keyCode: e.keyCode,
-    shift: e.shiftKey, // not `var shift` from above.
+    shift: e.shiftKey,  // not `var shift` from above.
     ctrl: control,
     alt: alt,
     meta: meta
@@ -6370,8 +5947,7 @@
   e.preventDefault();
   e.stopPropagation();
 
-  if (action === CANCEL)
-    return;
+  if (action === CANCEL) return;
 
   if (action !== DEFAULT && typeof action != 'string') {
     console.warn('Invalid action: ' + JSON.stringify(action));
@@ -6382,11 +5958,9 @@
   // modifier has already been accounted for in the action.
   if (resolvedActionType == 'control') {
     control = false;
-  }
-  else if (resolvedActionType == 'alt') {
+  } else if (resolvedActionType == 'alt') {
     alt = false;
-  }
-  else if (resolvedActionType == 'meta') {
+  } else if (resolvedActionType == 'meta') {
     meta = false;
   }
 
@@ -6399,38 +5973,30 @@
 
     if (shift && !(alt || control)) {
       mod = ';2';
-    }
-    else if (alt && !(shift || control)) {
+    } else if (alt && !(shift || control)) {
       mod = ';3';
-    }
-    else if (shift && alt && !control) {
+    } else if (shift && alt && !control) {
       mod = ';4';
-    }
-    else if (control && !(shift || alt)) {
+    } else if (control && !(shift || alt)) {
       mod = ';5';
-    }
-    else if (shift && control && !alt) {
+    } else if (shift && control && !alt) {
       mod = ';6';
-    }
-    else if (alt && control && !shift) {
+    } else if (alt && control && !shift) {
       mod = ';7';
-    }
-    else if (shift && alt && control) {
+    } else if (shift && alt && control) {
       mod = ';8';
     }
 
     if (action.length == 3) {
       // Some of the CSI sequences have zero parameters unless modified.
       action = '\x1b[1' + mod + action.substr(2, 1);
-    }
-    else {
+    } else {
       // Others always have at least one parameter.
       action = action.substr(0, action.length - 1) + mod +
-        action.substr(action.length - 1);
+          action.substr(action.length - 1);
     }
 
-  }
-  else {
+  } else {
     if (action === DEFAULT) {
       action = keyDef.keyCap.substr((shift ? 1 : 0), 1);
 
@@ -6452,7 +6018,7 @@
     // string.  Otherwise, every overridden alt/meta action would have to
     // check alt/metaSendsEscape.
     if ((alt && this.altSendsWhat == 'escape') ||
-      (meta && this.metaSendsEscape)) {
+        (meta && this.metaSendsEscape)) {
       action = '\x1b' + action;
     }
   }
@@ -6507,22 +6073,17 @@
 
   if (binding) {
     binding.action = action;
-  }
-  else {
-    binding = {
-      keyPattern: keyPattern,
-      action: action
-    };
+  } else {
+    binding = {keyPattern: keyPattern, action: action};
 
     if (!list) {
       this.bindings_[keyPattern.keyCode] = [binding];
-    }
-    else {
+    } else {
       this.bindings_[keyPattern.keyCode].push(binding);
 
       list.sort(function(a, b) {
         return hterm.Keyboard.KeyPattern.sortCompare(
-          a.keyPattern, b.keyPattern);
+            a.keyPattern, b.keyPattern);
       });
     }
   }
@@ -6568,8 +6129,7 @@
 
   try {
     sequence = p.parseKeySequence();
-  }
-  catch (ex) {
+  } catch (ex) {
     console.error(ex);
     return;
   }
@@ -6584,8 +6144,7 @@
     p.reset(action);
     try {
       action = p.parseKeyAction();
-    }
-    catch (ex) {
+    } catch (ex) {
       console.error(ex);
       return;
     }
@@ -6631,13 +6190,11 @@
  */
 hterm.Keyboard.Bindings.prototype.getBinding = function(keyDown) {
   var list = this.bindings_[keyDown.keyCode];
-  if (!list)
-    return null;
+  if (!list) return null;
 
   for (var i = 0; i < list.length; i++) {
     var binding = list[i];
-    if (binding.keyPattern.matchKeyDown(keyDown))
-      return binding;
+    if (binding.keyPattern.matchKeyDown(keyDown)) return binding;
   }
 
   return null;
@@ -6712,8 +6269,7 @@
  * Function Keys" from [XTERM].
  */
 hterm.Keyboard.KeyMap.prototype.addKeyDef = function(keyCode, def) {
-  if (keyCode in this.keyDefs)
-    console.warn('Duplicate keyCode: ' + keyCode);
+  if (keyCode in this.keyDefs) console.warn('Duplicate keyCode: ' + keyCode);
 
   this.keyDefs[keyCode] = def;
 };
@@ -6754,8 +6310,7 @@
   // 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]);
+    if (typeof action == 'function') return action.apply(self, [e, k]);
 
     return action;
   }
@@ -6765,7 +6320,9 @@
   function ak(a, b) {
     return function(e, k) {
       var action = (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey ||
-        !self.keyboard.applicationKeypad) ? a : b;
+                    !self.keyboard.applicationKeypad) ?
+          a :
+          b;
       return resolve(action, e, k);
     };
   }
@@ -6775,7 +6332,9 @@
   function ac(a, b) {
     return function(e, k) {
       var action = (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey ||
-        !self.keyboard.applicationCursor) ? a : b;
+                    !self.keyboard.applicationCursor) ?
+          a :
+          b;
       return resolve(action, e, k);
     };
   }
@@ -6832,8 +6391,8 @@
         // 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;
+            hterm.Keyboard.KeyActions.CANCEL :
+            hterm.Keyboard.KeyActions.PASS;
       }
       return resolve(fn, e, k);
     };
@@ -6849,64 +6408,194 @@
   var STRIP = hterm.Keyboard.KeyActions.STRIP;
 
   this.addKeyDefs(
-    // These fields are: [keycode, keycap, normal, control, alt, meta]
+      // 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],
+      // 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.
-    [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]', CSI + '23~', DEFAULT, CSI + '42~', DEFAULT], [123, '[F12]', CSI + '24~', DEFAULT, CSI + '43~', DEFAULT],
+      // First row.
+      [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]', CSI + '23~', 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_')], [189, '-_', DEFAULT, c('onPlusMinusZero_'), DEFAULT, c('onPlusMinusZero_')], [187, '=+', DEFAULT, c('onPlusMinusZero_'), DEFAULT, c('onPlusMinusZero_')],
-    // Firefox -_ and =+
-    [173, '-_', DEFAULT, c('onPlusMinusZero_'), DEFAULT, c('onPlusMinusZero_')], [61, '=+', DEFAULT, c('onPlusMinusZero_'), DEFAULT, c('onPlusMinusZero_')],
-    // Firefox Italian +*
-    [171, '+*', DEFAULT, c('onPlusMinusZero_'), DEFAULT, c('onPlusMinusZero_')],
+      // 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_')
+      ],
+      [
+        189, '-_', DEFAULT, c('onPlusMinusZero_'), DEFAULT,
+        c('onPlusMinusZero_')
+      ],
+      [
+        187, '=+', DEFAULT, c('onPlusMinusZero_'), DEFAULT,
+        c('onPlusMinusZero_')
+      ],
+      // Firefox -_ and =+
+      [
+        173, '-_', DEFAULT, c('onPlusMinusZero_'), DEFAULT,
+        c('onPlusMinusZero_')
+      ],
+      [
+        61, '=+', DEFAULT, c('onPlusMinusZero_'), DEFAULT, c('onPlusMinusZero_')
+      ],
+      // Firefox Italian +*
+      [
+        171, '+*', DEFAULT, c('onPlusMinusZero_'), DEFAULT,
+        c('onPlusMinusZero_')
+      ],
 
-    [8, '[BKSP]', bs('\x7f', '\b'), bs('\b', '\x7f'), DEFAULT, DEFAULT],
+      [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],
+      // 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.)
-    [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], [186, ';:', DEFAULT, STRIP, DEFAULT, DEFAULT], [222, '\'"', DEFAULT, STRIP, DEFAULT, DEFAULT], [13, '[ENTER]', '\r', CANCEL, CANCEL, DEFAULT],
+      // Fourth row. (We let Ctrl-Shift-J pass for Chrome DevTools.)
+      [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],
+      [186, ';:', DEFAULT, STRIP, DEFAULT, DEFAULT],
+      [222, '\'"', DEFAULT, STRIP, DEFAULT, DEFAULT],
+      [13, '[ENTER]', '\r', CANCEL, CANCEL, 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],
+      // 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],
+      // 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],
+      // 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],
+      // 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]', ac(CSI + 'A', SS3 + 'A'), DEFAULT, DEFAULT, DEFAULT], [40, '[DOWN]', ac(CSI + 'B', SS3 + 'B'), DEFAULT, DEFAULT, DEFAULT], [39, '[RIGHT]', ac(CSI + 'C', SS3 + 'C'), DEFAULT, DEFAULT, DEFAULT], [37, '[LEFT]', ac(CSI + 'D', SS3 + 'D'), DEFAULT, DEFAULT, DEFAULT],
+      // Arrow keys.  When unmodified they respect the application cursor state,
+      // otherwise they always send the CSI codes.
+      [38, '[UP]', ac(CSI + 'A', SS3 + 'A'), DEFAULT, DEFAULT, DEFAULT],
+      [40, '[DOWN]', ac(CSI + 'B', SS3 + 'B'), 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],
+      [144, '[NUMLOCK]', 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.
+      // 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],
+      // 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],
 
-    // Chrome OS keyboard top row.
-    [166, '[BACK]', med(mod(SS3 + 'P', CSI + 'P')), DEFAULT, CSI + '23~', DEFAULT], [167, '[FWD]', med(mod(SS3 + 'Q', CSI + 'Q')), DEFAULT, CSI + '24~', DEFAULT], [168, '[RELOAD]', med(mod(SS3 + 'R', CSI + 'R')), DEFAULT, CSI + '25~', DEFAULT], [183, '[FSCR]', med(mod(SS3 + 'S', CSI + 'S')), DEFAULT, CSI + '26~', DEFAULT], [182, '[WINS]', med(CSI + '15~'), DEFAULT, CSI + '28~', DEFAULT], [216, '[BRIT-]', med(CSI + '17~'), DEFAULT, CSI + '29~', DEFAULT], [217, '[BRIT+]', med(CSI + '18~'), DEFAULT, CSI + '31~', DEFAULT]
+      // Chrome OS keyboard top row.
+      [
+        166, '[BACK]', med(mod(SS3 + 'P', CSI + 'P')), DEFAULT, CSI + '23~',
+        DEFAULT
+      ],
+      [
+        167, '[FWD]', med(mod(SS3 + 'Q', CSI + 'Q')), DEFAULT, CSI + '24~',
+        DEFAULT
+      ],
+      [
+        168, '[RELOAD]', med(mod(SS3 + 'R', CSI + 'R')), DEFAULT, CSI + '25~',
+        DEFAULT
+      ],
+      [
+        183, '[FSCR]', med(mod(SS3 + 'S', CSI + 'S')), DEFAULT, CSI + '26~',
+        DEFAULT
+      ],
+      [182, '[WINS]', med(CSI + '15~'), DEFAULT, CSI + '28~', DEFAULT],
+      [216, '[BRIT-]', med(CSI + '17~'), DEFAULT, CSI + '29~', DEFAULT],
+      [217, '[BRIT+]', med(CSI + '18~'), DEFAULT, CSI + '31~', DEFAULT]
 
-    // 173 [MUTE], 174 [VOL-] and 175 [VOL+] are trapped by the Chrome OS
-    // window manager, so we'll never see them. Note that 173 is also
-    // Firefox's -_ keycode.
+      // 173 [MUTE], 174 [VOL-] and 175 [VOL+] are trapped by the Chrome OS
+      // window manager, so we'll never see them. Note that 173 is also
+      // Firefox's -_ keycode.
   );
 };
 
@@ -6926,7 +6615,7 @@
 hterm.Keyboard.KeyMap.prototype.onKeyHome_ = function(e) {
   if (!this.keyboard.homeKeysScroll ^ e.shiftKey) {
     if ((e.altey || e.ctrlKey || e.shiftKey) ||
-      !this.keyboard.applicationCursor) {
+        !this.keyboard.applicationCursor) {
       return '\x1b[H';
     }
 
@@ -6943,7 +6632,7 @@
 hterm.Keyboard.KeyMap.prototype.onKeyEnd_ = function(e) {
   if (!this.keyboard.homeKeysScroll ^ e.shiftKey) {
     if ((e.altKey || e.ctrlKey || e.shiftKey) ||
-      !this.keyboard.applicationCursor) {
+        !this.keyboard.applicationCursor) {
       return '\x1b[F';
     }
 
@@ -6958,8 +6647,7 @@
  * 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~';
+  if (!this.keyboard.pageKeysScroll ^ e.shiftKey) return '\x1b[5~';
 
   this.keyboard.terminal.scrollPageUp();
   return hterm.Keyboard.KeyActions.CANCEL;
@@ -6975,7 +6663,7 @@
  */
 hterm.Keyboard.KeyMap.prototype.onKeyDel_ = function(e) {
   if (this.keyboard.altBackspaceIsMetaBackspace &&
-    this.keyboard.altKeyPressed && !e.altKey)
+      this.keyboard.altKeyPressed && !e.altKey)
     return '\x1b\x7f';
   return '\x1b[3~';
 };
@@ -6984,8 +6672,7 @@
  * 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~';
+  if (!this.keyboard.pageKeysScroll ^ e.shiftKey) return '\x1b[6~';
 
   this.keyboard.terminal.scrollPageDown();
   return hterm.Keyboard.KeyActions.CANCEL;
@@ -7095,10 +6782,11 @@
  */
 hterm.Keyboard.KeyMap.prototype.onCtrlN_ = function(e, keyDef) {
   if (e.shiftKey) {
-    window.open(document.location.href, '',
-      'chrome=no,close=yes,resize=yes,scrollbars=yes,' +
-      'minimizable=yes,width=' + window.innerWidth +
-      ',height=' + window.innerHeight);
+    window.open(
+        document.location.href, '',
+        'chrome=no,close=yes,resize=yes,scrollbars=yes,' +
+            'minimizable=yes,width=' + window.innerWidth +
+            ',height=' + window.innerHeight);
     return hterm.Keyboard.KeyActions.CANCEL;
   }
 
@@ -7115,7 +6803,7 @@
  */
 hterm.Keyboard.KeyMap.prototype.onCtrlV_ = function(e, keyDef) {
   if ((!e.shiftKey && this.keyboard.ctrlVPaste) ||
-    (e.shiftKey && !this.keyboard.ctrlVPaste)) {
+      (e.shiftKey && !this.keyboard.ctrlVPaste)) {
     return hterm.Keyboard.KeyActions.PASS;
   }
 
@@ -7127,10 +6815,11 @@
  */
 hterm.Keyboard.KeyMap.prototype.onMetaN_ = function(e, keyDef) {
   if (e.shiftKey) {
-    window.open(document.location.href, '',
-      'chrome=no,close=yes,resize=yes,scrollbars=yes,' +
-      'minimizable=yes,width=' + window.outerWidth +
-      ',height=' + window.outerHeight);
+    window.open(
+        document.location.href, '',
+        'chrome=no,close=yes,resize=yes,scrollbars=yes,' +
+            'minimizable=yes,width=' + window.outerWidth +
+            ',height=' + window.outerHeight);
     return hterm.Keyboard.KeyActions.CANCEL;
   }
 
@@ -7173,12 +6862,10 @@
  * a paste command.
  */
 hterm.Keyboard.KeyMap.prototype.onMetaV_ = function(e, keyDef) {
-  if (e.shiftKey)
-    return hterm.Keyboard.KeyActions.PASS;
+  if (e.shiftKey) return hterm.Keyboard.KeyActions.PASS;
 
-  return this.keyboard.passMetaV ?
-    hterm.Keyboard.KeyActions.PASS :
-    hterm.Keyboard.KeyActions.DEFAULT;
+  return this.keyboard.passMetaV ? hterm.Keyboard.KeyActions.PASS :
+                                   hterm.Keyboard.KeyActions.DEFAULT;
 };
 
 /**
@@ -7196,8 +6883,7 @@
     // 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'; // ^_
+    if (keyDef.keyCap == '-_') return '\x1f';  // ^_
 
     // Only ^_ is valid, the other sequences have no meaning.
     return hterm.Keyboard.KeyActions.CANCEL;
@@ -7212,14 +6898,12 @@
   var cap = keyDef.keyCap.substr(0, 1);
   if (cap == '0') {
     this.keyboard.terminal.setFontSize(0);
-  }
-  else {
+  } else {
     var size = this.keyboard.terminal.getFontSize();
 
     if (cap == '-' || keyDef.keyCap == '[KP-]') {
       size -= 1;
-    }
-    else {
+    } else {
       size += 1;
     }
 
@@ -7249,17 +6933,14 @@
 
   hterm.Keyboard.KeyPattern.modifiers.forEach(function(mod) {
     this[mod] = spec[mod] || false;
-    if (this[mod] == '*')
-      this.wildcardCount++;
+    if (this[mod] == '*') this.wildcardCount++;
   }.bind(this));
 };
 
 /**
  * Valid modifier names.
  */
-hterm.Keyboard.KeyPattern.modifiers = [
-  'shift', 'ctrl', 'alt', 'meta'
-];
+hterm.Keyboard.KeyPattern.modifiers = ['shift', 'ctrl', 'alt', 'meta'];
 
 /**
  * A compare callback for Array.prototype.sort().
@@ -7272,11 +6953,9 @@
  * @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;
 
-  if (a.wildcardCount > b.wildcardCount)
-    return 1;
+  if (a.wildcardCount > b.wildcardCount) return 1;
 
   return 0;
 };
@@ -7290,8 +6969,7 @@
  *   to perform and exact match against another key pattern.
  */
 hterm.Keyboard.KeyPattern.prototype.match_ = function(obj, exactMatch) {
-  if (this.keyCode != obj.keyCode)
-    return false;
+  if (this.keyCode != obj.keyCode) return false;
 
   var rv = true;
 
@@ -7439,9 +7117,7 @@
  *   properties.
  */
 hterm.Parser.prototype.parseKeySequence = function() {
-  var rv = {
-    keyCode: null
-  };
+  var rv = {keyCode: null};
 
   for (var k in hterm.Parser.identifiers.modifierKeys) {
     rv[hterm.Parser.identifiers.modifierKeys[k]] = false;
@@ -7454,44 +7130,36 @@
     if (token.type == 'integer') {
       rv.keyCode = token.value;
 
-    }
-    else if (token.type == 'identifier') {
+    } else if (token.type == 'identifier') {
       if (token.value in hterm.Parser.identifiers.modifierKeys) {
         var mod = hterm.Parser.identifiers.modifierKeys[token.value];
         if (rv[mod] && rv[mod] != '*')
           throw this.error('Duplicate modifier: ' + token.value);
         rv[mod] = true;
 
-      }
-      else if (token.value in hterm.Parser.identifiers.keyCodes) {
+      } else if (token.value in hterm.Parser.identifiers.keyCodes) {
         rv.keyCode = hterm.Parser.identifiers.keyCodes[token.value];
 
-      }
-      else {
+      } else {
         throw this.error('Unknown key: ' + token.value);
       }
 
-    }
-    else if (token.type == 'symbol') {
+    } 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] = '*';
+          if (!rv[p]) rv[p] = '*';
         }
-      }
-      else {
+      } else {
         throw this.error('Unexpected symbol: ' + token.value);
       }
-    }
-    else {
+    } else {
       throw this.error('Expected integer or identifier');
     }
 
     this.skipSpace();
 
-    if (this.ch != '-')
-      break;
+    if (this.ch != '-') break;
 
     if (rv.keyCode != null)
       throw this.error('Extra definition after target key');
@@ -7499,8 +7167,7 @@
     this.advance(1);
   }
 
-  if (rv.keyCode == null)
-    throw this.error('Missing target key');
+  if (rv.keyCode == null) throw this.error('Missing target key');
 
   return rv;
 };
@@ -7510,8 +7177,7 @@
 
   var token = this.parseToken();
 
-  if (token.type == 'string')
-    return token.value;
+  if (token.type == 'string') return token.value;
 
   if (token.type == 'identifier') {
     if (token.value in hterm.Parser.identifiers.actions)
@@ -7538,39 +7204,23 @@
 
 hterm.Parser.prototype.parseToken = function() {
   if (this.ch == '*') {
-    var rv = {
-      type: 'symbol',
-      value: this.ch
-    };
+    var rv = {type: 'symbol', value: this.ch};
     this.advance(1);
     return rv;
   }
 
   if (this.peekIdentifier())
-    return {
-      type: 'identifier',
-      value: this.parseIdentifier()
-    };
+    return {type: 'identifier', value: this.parseIdentifier()};
 
-  if (this.peekString())
-    return {
-      type: 'string',
-      value: this.parseString()
-    };
+  if (this.peekString()) return {type: 'string', value: this.parseString()};
 
-  if (this.peekInteger())
-    return {
-      type: 'integer',
-      value: this.parseInteger()
-    };
-
+  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');
+  if (!this.peekIdentifier()) throw this.error('Expected identifier');
 
   return this.parsePattern(/[a-z0-9_]+/ig);
 };
@@ -7579,7 +7229,7 @@
   var base = 10;
 
   if (this.ch == '0' && this.pos < this.source.length - 1 &&
-    this.source.substr(this.pos + 1, 1) == 'x') {
+      this.source.substr(this.pos + 1, 1) == 'x') {
     return parseInt(this.parsePattern(/0x[0-9a-f]+/gi));
   }
 
@@ -7602,8 +7252,7 @@
   var result = '';
 
   var quote = this.ch;
-  if (quote != '"' && quote != '\'')
-    throw this.error('String expected');
+  if (quote != '"' && quote != '\'') throw this.error('String expected');
 
   this.advance(1);
 
@@ -7611,8 +7260,7 @@
 
   while (this.pos < this.source.length) {
     re.lastIndex = this.pos;
-    if (!re.exec(this.source))
-      throw this.error('Unterminated string literal');
+    if (!re.exec(this.source)) throw this.error('Unterminated string literal');
 
     result += this.source.substring(this.pos, re.lastIndex - 1);
 
@@ -7639,7 +7287,6 @@
   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.)
@@ -7669,14 +7316,12 @@
     }
   };
 
-  if (!(this.ch in map))
-    throw this.error('Unknown escape: ' + this.ch);
+  if (!(this.ch in map)) throw this.error('Unknown escape: ' + this.ch);
 
   var value = map[this.ch];
   this.advance(1);
 
-  if (typeof value == 'function')
-    value = value.call(this);
+  if (typeof value == 'function') value = value.call(this);
 
   return value;
 };
@@ -7704,7 +7349,6 @@
   return ary[0];
 };
 
-
 /**
  * Advance the current position.
  *
@@ -7721,22 +7365,19 @@
  * @return {void}
  */
 hterm.Parser.prototype.skipSpace = function(opt_expect) {
-  if (!/\s/.test(this.ch))
-    return;
+  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;
+  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);
+      throw this.error('Expected one of ' + opt_expect + ', found: ' + this.ch);
     }
   }
 };
@@ -7950,8 +7591,8 @@
  * This is currently just an ordered list of known connection profiles.
  */
 hterm.PreferenceManager = function(profileId) {
-  lib.PreferenceManager.call(this, hterm.defaultStorage,
-    '/hterm/profiles/' + profileId);
+  lib.PreferenceManager.call(
+      this, hterm.defaultStorage, '/hterm/profiles/' + profileId);
   var defs = hterm.PreferenceManager.defaultPreferences;
   Object.keys(defs).forEach(function(key) {
     this.definePreference(key, defs[key][1]);
@@ -7970,376 +7611,412 @@
 /**
  * List of categories, ordered by display order (top to bottom)
  */
-hterm.PreferenceManager.categoryDefinitions = [{
+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.Miscellaneous,
-    text: 'Misc.'
-  }
+  {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.Miscellaneous, text: 'Misc.'}
 ];
 
-
 hterm.PreferenceManager.defaultPreferences = {
-  'alt-gr-mode': [hterm.PreferenceManager.categories.Keyboard, null, [null, 'none', 'ctrl-alt', 'left-alt', 'right-alt'],
+  'alt-gr-mode': [
+    hterm.PreferenceManager.categories.Keyboard, null,
+    [null, 'none', 'ctrl-alt', 'left-alt', 'right-alt'],
     'Select an AltGr detection hack^Wheuristic.\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.\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.\n'
   ],
 
-  'alt-backspace-is-meta-backspace': [hterm.PreferenceManager.categories.Keyboard, false, 'bool',
+  '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-backspace indeed is alt-backspace.'
   ],
 
-  'alt-is-meta': [hterm.PreferenceManager.categories.Keyboard, false, 'bool',
+  'alt-is-meta': [
+    hterm.PreferenceManager.categories.Keyboard, false, 'bool',
     'Set whether the alt key acts as a meta key or as a distinct alt key.'
   ],
 
-  'alt-sends-what': [hterm.PreferenceManager.categories.Keyboard, 'escape', ['escape', '8-bit', 'browser-key'],
+  'alt-sends-what': [
+    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 unshifted 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 \n' +
-    '                browser performs a default action for some alt sequences.)'
+        '\n' +
+        '  escape....... Send an ESC prefix.\n' +
+        '  8-bit........ Add 128 to the unshifted 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 \n' +
+        '                browser performs a default action for some alt sequences.)'
   ],
 
-  'audible-bell-sound': [hterm.PreferenceManager.categories.Sounds, 'lib-resource:hterm/audio/bell',
-    'url',
-    'URL of the terminal bell sound.  Empty string for no audible bell.'
+  'audible-bell-sound': [
+    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.categories.Sounds, false, 'bool',
+  'desktop-notification-bell': [
+    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. Note browsers may not show this permission request if it ' +
-    'did not originate from a user action.\n' +
-    '\n' +
-    'Chrome extensions with the "notifications" permission have permission to ' +
-    'display notifications.'
+        '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. Note browsers may not show this permission request if it ' +
+        'did not originate from a user action.\n' +
+        '\n' +
+        'Chrome extensions with the "notifications" permission have permission to ' +
+        'display notifications.'
   ],
 
-  'background-color': [hterm.PreferenceManager.categories.Appearance, 'rgb(16, 16, 16)', 'color',
+  '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.categories.Appearance, '', 'string',
+  '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)'
+        '\n' +
+        'For example:\n' +
+        '  url(https://goo.gl/anedTK)\n' +
+        '  linear-gradient(top bottom, blue, red)'
   ],
 
-  'background-size': [hterm.PreferenceManager.categories.Appearance, '', 'string',
+  'background-size': [
+    hterm.PreferenceManager.categories.Appearance, '', 'string',
     'CSS value of the background image size.  Defaults to none.'
   ],
 
-  'background-position': [hterm.PreferenceManager.categories.Appearance, '', 'string',
+  'background-position': [
+    hterm.PreferenceManager.categories.Appearance, '', 'string',
     'CSS value of the background image position.\n' +
-    '\n' +
-    'For example:\n' +
-    '  10% 10%\n' +
-    '  center'
+        '\n' +
+        'For example:\n' +
+        '  10% 10%\n' +
+        '  center'
   ],
 
-  'backspace-sends-backspace': [hterm.PreferenceManager.categories.Keyboard, false, 'bool',
+  'backspace-sends-backspace': [
+    hterm.PreferenceManager.categories.Keyboard, false, 'bool',
     'If true, the backspace should send BS (\'\\x08\', aka ^H).  Otherwise ' +
-    'the backspace key should send \'\\x7f\'.'
+        'the backspace key should send \'\\x7f\'.'
   ],
 
-  'character-map-overrides': [hterm.PreferenceManager.categories.Appearance, null, 'value',
+  '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"}}'
+        '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.categories.Miscellaneous, true, 'bool',
+  'close-on-exit': [
+    hterm.PreferenceManager.categories.Miscellaneous, true, 'bool',
     'Whether or not to close the window when the command exits.'
   ],
 
-  'cursor-blink': [hterm.PreferenceManager.categories.Appearance, false, 'bool',
+  'cursor-blink': [
+    hterm.PreferenceManager.categories.Appearance, false, 'bool',
     'Whether or not to blink the cursor by default.'
   ],
 
-  'cursor-blink-cycle': [hterm.PreferenceManager.categories.Appearance, [1000, 500], 'value',
+  'cursor-blink-cycle': [
+    hterm.PreferenceManager.categories.Appearance, [1000, 500], 'value',
     'The cursor blink rate in milliseconds.\n' +
-    '\n' +
-    'A two element array, the first of which is how long the cursor should be ' +
-    'on, second is how long it should be off.'
+        '\n' +
+        'A two element array, the first of which is how long the cursor should be ' +
+        'on, second is how long it should be off.'
   ],
 
-  'cursor-color': [hterm.PreferenceManager.categories.Appearance, 'rgba(255, 0, 0, 0.5)',
-    'color',
-    'The color of the visible cursor.'
+  'cursor-color': [
+    hterm.PreferenceManager.categories.Appearance, 'rgba(255, 0, 0, 0.5)',
+    'color', 'The color of the visible cursor.'
   ],
 
-  'color-palette-overrides': [hterm.PreferenceManager.categories.Appearance, null, 'value',
+  'color-palette-overrides': [
+    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 stock 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' +
+        '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 stock 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.'
   ],
 
-  'copy-on-select': [hterm.PreferenceManager.categories.CopyPaste, true, 'bool',
+  'copy-on-select': [
+    hterm.PreferenceManager.categories.CopyPaste, true, 'bool',
     'Automatically copy mouse selection to the clipboard.'
   ],
 
-  'use-default-window-copy': [hterm.PreferenceManager.categories.CopyPaste, false, 'bool',
+  'use-default-window-copy': [
+    hterm.PreferenceManager.categories.CopyPaste, false, 'bool',
     'Whether to use the default window copy behavior'
   ],
 
-  'clear-selection-after-copy': [hterm.PreferenceManager.categories.CopyPaste, true, 'bool',
+  'clear-selection-after-copy': [
+    hterm.PreferenceManager.categories.CopyPaste, true, 'bool',
     'Whether to clear the selection after copying.'
   ],
 
-  'ctrl-plus-minus-zero-zoom': [hterm.PreferenceManager.categories.Keyboard, true, 'bool',
+  'ctrl-plus-minus-zero-zoom': [
+    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.'
+        'If false, Ctrl-Shift-Plus/Minus/Zero controls zoom, Ctrl-Minus sends ^_, ' +
+        'Ctrl-Plus/Zero do nothing.'
   ],
 
-  'ctrl-c-copy': [hterm.PreferenceManager.categories.Keyboard, false, 'bool',
+  'ctrl-c-copy': [
+    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+Shift+C sends ^C to host if true, copies if false.'
   ],
 
-  'ctrl-v-paste': [hterm.PreferenceManager.categories.Keyboard, false, 'bool',
+  'ctrl-v-paste': [
+    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.'
+        'Ctrl+Shift+V sends ^V to host if true, pastes if false.'
   ],
 
-  'east-asian-ambiguous-as-two-column': [hterm.PreferenceManager.categories.Keyboard, false, 'bool',
+  'east-asian-ambiguous-as-two-column': [
+    hterm.PreferenceManager.categories.Keyboard, false, 'bool',
     'Set whether East Asian Ambiguous characters have two column width.'
   ],
 
-  'enable-8-bit-control': [hterm.PreferenceManager.categories.Keyboard, false, 'bool',
+  'enable-8-bit-control': [
+    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.'
+        '\n' +
+        'We\'ll respect the two-byte versions of these control characters ' +
+        'regardless of this setting.'
   ],
 
-  'enable-bold': [hterm.PreferenceManager.categories.Appearance, null, 'tristate',
+  'enable-bold': [
+    hterm.PreferenceManager.categories.Appearance, null, 'tristate',
     'True if we should use bold weight font for text with the bold/bright ' +
-    'attribute.  False to use the normal weight font.  Null to autodetect.'
+        'attribute.  False to use the normal weight font.  Null to autodetect.'
   ],
 
-  'enable-bold-as-bright': [hterm.PreferenceManager.categories.Appearance, true, 'bool',
+  'enable-bold-as-bright': [
+    hterm.PreferenceManager.categories.Appearance, true, 'bool',
     'True if we should use bright colors (8-15 on a 16 color palette) ' +
-    'for any text with the bold attribute.  False otherwise.'
+        'for any text with the bold attribute.  False otherwise.'
   ],
 
-  'enable-blink': [hterm.PreferenceManager.categories.Appearance, true, 'bool',
+  'enable-blink': [
+    hterm.PreferenceManager.categories.Appearance, true, 'bool',
     'True if we should respect the blink attribute.  False to ignore it.  '
   ],
 
-  'enable-clipboard-notice': [hterm.PreferenceManager.categories.CopyPaste, true, 'bool',
+  'enable-clipboard-notice': [
+    hterm.PreferenceManager.categories.CopyPaste, true, 'bool',
     'Show a message in the terminal when the host writes to the clipboard.'
   ],
 
-  'enable-clipboard-write': [hterm.PreferenceManager.categories.CopyPaste, true, 'bool',
+  'enable-clipboard-write': [
+    hterm.PreferenceManager.categories.CopyPaste, true, 'bool',
     'Allow the host to write directly to the system clipboard.'
   ],
 
-  'enable-dec12': [hterm.PreferenceManager.categories.Miscellaneous, false, 'bool',
+  'enable-dec12': [
+    hterm.PreferenceManager.categories.Miscellaneous, false, 'bool',
     'Respect the host\'s attempt to change the cursor blink status using ' +
-    'DEC Private Mode 12.'
+        'DEC Private Mode 12.'
   ],
 
-  'environment': [hterm.PreferenceManager.categories.Miscellaneous, {
-      'TERM': 'xterm-256color'
-    },
-    'value',
+  'environment': [
+    hterm.PreferenceManager.categories.Miscellaneous,
+    {'TERM': 'xterm-256color'}, 'value',
     'The default environment variables, as an object.'
   ],
 
-  'font-family': [hterm.PreferenceManager.categories.Appearance,
+  'font-family': [
+    hterm.PreferenceManager.categories.Appearance,
     '"DejaVu Sans Mono", "Everson Mono", FreeMono, "Menlo", "Terminal", ' +
-    'monospace', 'string',
-    'Default font family for the terminal text.'
+        'monospace',
+    'string', 'Default font family for the terminal text.'
   ],
 
-  'font-size': [hterm.PreferenceManager.categories.Appearance, 15, 'int',
+  'font-size': [
+    hterm.PreferenceManager.categories.Appearance, 15, 'int',
     'The default font size in pixels.'
   ],
 
-  'font-smoothing': [hterm.PreferenceManager.categories.Appearance, 'antialiased', 'string',
+  'font-smoothing': [
+    hterm.PreferenceManager.categories.Appearance, 'antialiased', 'string',
     'CSS font-smoothing property.'
   ],
 
-  'foreground-color': [hterm.PreferenceManager.categories.Appearance, 'rgb(240, 240, 240)', 'color',
-    'The foreground color for text with no other color attributes.'
+  'foreground-color': [
+    hterm.PreferenceManager.categories.Appearance, 'rgb(240, 240, 240)',
+    'color', 'The foreground color for text with no other color attributes.'
   ],
 
-  'home-keys-scroll': [hterm.PreferenceManager.categories.Keyboard, false, 'bool',
+  'home-keys-scroll': [
+    hterm.PreferenceManager.categories.Keyboard, false, 'bool',
     '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.'
+        'will send the VT keycodes.  If false then home/end sends VT codes and ' +
+        'shift home/end scrolls.'
   ],
 
-  'keybindings': [hterm.PreferenceManager.categories.Keyboard, null, 'value',
+  'keybindings': [
+    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 ' +
-    'a string to send to the host, or an action identifier.  For a full ' +
-    'list of key code and action identifiers, see https://goo.gl/8AoD09.' +
-    '\n' +
-    '\n' +
-    'Sample keybindings:\n' +
-    '{ "Ctrl-Alt-K": "clearScrollback",\n' +
-    '  "Ctrl-Shift-L": "PASS",\n' +
-    '  "Ctrl-H": "\'HELLO\\n\'"\n' +
-    '}'
+        '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 ' +
+        'a string to send to the host, or an action identifier.  For a full ' +
+        'list of key code and action identifiers, see https://goo.gl/8AoD09.' +
+        '\n' +
+        '\n' +
+        'Sample keybindings:\n' +
+        '{ "Ctrl-Alt-K": "clearScrollback",\n' +
+        '  "Ctrl-Shift-L": "PASS",\n' +
+        '  "Ctrl-H": "\'HELLO\\n\'"\n' +
+        '}'
   ],
 
-  'max-string-sequence': [hterm.PreferenceManager.categories.Encoding, 100000, 'int',
+  'max-string-sequence': [
+    hterm.PreferenceManager.categories.Encoding, 100000, 'int',
     'Max length of a DCS, OSC, PM, or APS sequence before we give up and ' +
-    'ignore the code.'
+        'ignore the code.'
   ],
 
-  'media-keys-are-fkeys': [hterm.PreferenceManager.categories.Keyboard, false, 'bool',
+  '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.'
+        'the browser handle the keys.'
   ],
 
-  'meta-sends-escape': [hterm.PreferenceManager.categories.Keyboard, true, 'bool',
+  'meta-sends-escape': [
+    hterm.PreferenceManager.categories.Keyboard, true, 'bool',
     'Set whether the meta key sends a leading escape or not.'
   ],
 
-  'mouse-paste-button': [hterm.PreferenceManager.categories.CopyPaste, null, [null, 0, 1, 2, 3, 4, 5, 6],
+  'mouse-paste-button': [
+    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 try to enable middle button paste for non-X11 ' +
-    'platforms.  On X11 we move it to button 3.'
+        '\n' +
+        'For autodetect, we\'ll try to enable middle button paste for non-X11 ' +
+        'platforms.  On X11 we move it to button 3.'
   ],
 
-  'page-keys-scroll': [hterm.PreferenceManager.categories.Keyboard, false, 'bool',
+  'page-keys-scroll': [
+    hterm.PreferenceManager.categories.Keyboard, false, 'bool',
     'If true, page up/down will control the terminal scrollbar and shift ' +
-    'page up/down will send the VT keycodes.  If false then page up/down ' +
-    'sends VT codes and shift page up/down scrolls.'
+        'page up/down will send the VT keycodes.  If false then page up/down ' +
+        'sends VT codes and shift page up/down scrolls.'
   ],
 
-  'pass-alt-number': [hterm.PreferenceManager.categories.Keyboard, null, 'tristate',
+  'pass-alt-number': [
+    hterm.PreferenceManager.categories.Keyboard, null, 'tristate',
     'Set whether we should pass Alt-1..9 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.'
+        '\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.categories.Keyboard, null, 'tristate',
+  'pass-ctrl-number': [
+    hterm.PreferenceManager.categories.Keyboard, null, 'tristate',
     'Set whether we should pass Ctrl-1..9 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.'
+        '\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.categories.Keyboard, null, 'tristate',
+  'pass-meta-number': [
+    hterm.PreferenceManager.categories.Keyboard, null, 'tristate',
     'Set whether we should pass Meta-1..9 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.'
+        '\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.categories.Keyboard, true, 'bool',
+  'pass-meta-v': [
+    hterm.PreferenceManager.categories.Keyboard, true, 'bool',
     'Set whether meta-V gets passed to host.'
   ],
 
-  'receive-encoding': [hterm.PreferenceManager.categories.Encoding, 'utf-8', ['utf-8', 'raw'],
+  'receive-encoding': [
+    hterm.PreferenceManager.categories.Encoding, 'utf-8', ['utf-8', 'raw'],
     'Set the expected encoding for data received from the host.\n' +
-    '\n' +
-    'Valid values are \'utf-8\' and \'raw\'.'
+        '\n' +
+        'Valid values are \'utf-8\' and \'raw\'.'
   ],
 
-  'scroll-on-keystroke': [hterm.PreferenceManager.categories.Scrolling, true, 'bool',
+  'scroll-on-keystroke': [
+    hterm.PreferenceManager.categories.Scrolling, true, 'bool',
     'If true, scroll to the bottom on any keystroke.'
   ],
 
-  'scroll-on-output': [hterm.PreferenceManager.categories.Scrolling, false, 'bool',
+  'scroll-on-output': [
+    hterm.PreferenceManager.categories.Scrolling, false, 'bool',
     'If true, scroll to the bottom on terminal output.'
   ],
 
-  'scrollbar-visible': [hterm.PreferenceManager.categories.Scrolling, true, 'bool',
+  'scrollbar-visible': [
+    hterm.PreferenceManager.categories.Scrolling, true, 'bool',
     'The vertical scrollbar mode.'
   ],
 
-  'scroll-wheel-move-multiplier': [hterm.PreferenceManager.categories.Scrolling, 1, 'int',
+  'scroll-wheel-move-multiplier': [
+    hterm.PreferenceManager.categories.Scrolling, 1, 'int',
     'The multiplier for the pixel delta in mousewheel event caused by the ' +
-    'scroll wheel. Alters how fast the page scrolls.'
+        'scroll wheel. Alters how fast the page scrolls.'
   ],
 
-  'send-encoding': [hterm.PreferenceManager.categories.Encoding, 'utf-8', ['utf-8', 'raw'],
+  'send-encoding': [
+    hterm.PreferenceManager.categories.Encoding, 'utf-8', ['utf-8', 'raw'],
     'Set the encoding for data sent to host.'
   ],
 
-  'shift-insert-paste': [hterm.PreferenceManager.categories.Keyboard, true, 'bool',
+  'shift-insert-paste': [
+    hterm.PreferenceManager.categories.Keyboard, true, 'bool',
     'Shift + Insert pastes if true, sent to host if false.'
   ],
 
-  'user-css': [hterm.PreferenceManager.categories.Appearance, '', 'url',
+  'user-css': [
+    hterm.PreferenceManager.categories.Appearance, '', 'url',
     'URL of user stylesheet to include in the terminal document.'
   ]
 };
@@ -8384,8 +8061,7 @@
  * @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] = [];
+  if (!(subject in this.observers_)) this.observers_[subject] = [];
 
   this.observers_[subject].push(callback);
 };
@@ -8399,12 +8075,10 @@
  */
 hterm.PubSub.prototype.unsubscribe = function(subject, callback) {
   var list = this.observers_[subject];
-  if (!list)
-    throw 'Invalid subject: ' + subject;
+  if (!list) throw 'Invalid subject: ' + subject;
 
   var i = list.indexOf(callback);
-  if (i < 0)
-    throw 'Not subscribed: ' + subject;
+  if (i < 0) throw 'Not subscribed: ' + subject;
 
   list.splice(i, 1);
 };
@@ -8424,8 +8098,7 @@
   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);
+    if (i < list.length - 1) setTimeout(notifyList, 0, i + 1);
 
     list[i](e);
   }
@@ -8439,14 +8112,12 @@
   if (opt_lastCallback) {
     if (list) {
       list.push(opt_lastCallback);
-    }
-    else {
+    } else {
       list = [opt_lastCallback];
     }
   }
 
-  if (list)
-    setTimeout(notifyList, 0, 0);
+  if (list) setTimeout(notifyList, 0, 0);
 };
 // SOURCE FILE: hterm/js/hterm_screen.js
 // Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
@@ -8455,8 +8126,8 @@
 
 'use strict';
 
-lib.rtdep('lib.f', 'lib.wc',
-  'hterm.RowCol', 'hterm.Size', 'hterm.TextAttributes');
+lib.rtdep(
+    'lib.f', 'lib.wc', 'hterm.RowCol', 'hterm.Size', 'hterm.TextAttributes');
 
 /**
  * @fileoverview This class represents a single terminal screen full of text.
@@ -8709,8 +8380,7 @@
   var text;
   if (this.textAttributes.isDefault()) {
     text = '';
-  }
-  else {
+  } else {
     text = lib.f.getWhitespace(this.columnCount_);
   }
 
@@ -8759,8 +8429,7 @@
   if (row >= this.rowsArray.length) {
     console.error('Row out of bounds: ' + row);
     row = this.rowsArray.length - 1;
-  }
-  else if (row < 0) {
+  } else if (row < 0) {
     console.error('Row out of bounds: ' + row);
     row = 0;
   }
@@ -8768,8 +8437,7 @@
   if (column >= this.columnCount_) {
     console.error('Column out of bounds: ' + column);
     column = this.columnCount_ - 1;
-  }
-  else if (column < 0) {
+  } else if (column < 0) {
     console.error('Column out of bounds: ' + column);
     column = 0;
   }
@@ -8791,8 +8459,7 @@
       node = this.cursorNode_;
       currentColumn = this.cursorPosition.column - this.cursorOffset_;
     }
-  }
-  else {
+  } else {
     this.cursorRowNode_ = rowNode;
   }
 
@@ -8819,8 +8486,7 @@
 hterm.Screen.prototype.syncSelectionCaret = function(selection) {
   try {
     selection.collapse(this.cursorNode_, this.cursorOffset_);
-  }
-  catch (firefoxIgnoredException) {
+  } catch (firefoxIgnoredException) {
     // FF can throw an exception if the range is off, rather than just not
     // performing the collapse.
   }
@@ -8851,8 +8517,7 @@
 
   if (afterNode.textContent)
     node.parentNode.insertBefore(afterNode, node.nextSibling);
-  if (!node.textContent)
-    node.parentNode.removeChild(node);
+  if (!node.textContent) node.parentNode.removeChild(node);
 };
 
 /**
@@ -8882,7 +8547,7 @@
 
   if (this.cursorOffset_ < width - 1) {
     this.cursorNode_.textContent = hterm.TextAttributes.nodeSubstr(
-      this.cursorNode_, 0, this.cursorOffset_ + 1);
+        this.cursorNode_, 0, this.cursorOffset_ + 1);
   }
 
   // Remove all nodes after the cursor.
@@ -8898,8 +8563,7 @@
     // If the cursor was within the screen before we started then restore its
     // position.
     this.setCursorPosition(this.cursorPosition.row, currentColumn);
-  }
-  else {
+  } else {
     // Otherwise leave it at the the last column in the overflow state.
     this.cursorPosition.overflow = true;
   }
@@ -8945,24 +8609,20 @@
     // 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.tileData != null)) {
+    if (!(this.textAttributes.underline || this.textAttributes.strikethrough ||
+          this.textAttributes.background || this.textAttributes.wcNode ||
+          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 == 3 ||
-      !(cursorNode.wcNode ||
-        cursorNode.tileNode ||
-        cursorNode.style.textDecoration ||
-        cursorNode.style.backgroundColor)) {
+    } else if (
+        cursorNode.nodeType == 3 ||
+        !(cursorNode.wcNode || cursorNode.tileNode ||
+          cursorNode.style.textDecoration ||
+          cursorNode.style.backgroundColor)) {
       // Second best case, the current node is able to hold the whitespace.
       cursorNode.textContent = (cursorNodeText += ws);
-    }
-    else {
+    } 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);
@@ -8979,14 +8639,12 @@
     // The new text can be placed directly in the cursor node.
     if (reverseOffset == 0) {
       cursorNode.textContent = cursorNodeText + str;
-    }
-    else if (offset == 0) {
+    } else if (offset == 0) {
       cursorNode.textContent = str + cursorNodeText;
-    }
-    else {
+    } else {
       cursorNode.textContent =
-        hterm.TextAttributes.nodeSubstr(cursorNode, 0, offset) +
-        str + hterm.TextAttributes.nodeSubstr(cursorNode, offset);
+          hterm.TextAttributes.nodeSubstr(cursorNode, 0, offset) + str +
+          hterm.TextAttributes.nodeSubstr(cursorNode, offset);
     }
 
     this.cursorOffset_ += strWidth;
@@ -9001,7 +8659,7 @@
     // At the beginning of the cursor node, the check the previous sibling.
     var previousSibling = cursorNode.previousSibling;
     if (previousSibling &&
-      this.textAttributes.matchesContainer(previousSibling)) {
+        this.textAttributes.matchesContainer(previousSibling)) {
       previousSibling.textContent += str;
       this.cursorNode_ = previousSibling;
       this.cursorOffset_ = lib.wc.strWidth(previousSibling.textContent);
@@ -9018,8 +8676,7 @@
   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)) {
+    if (nextSibling && this.textAttributes.matchesContainer(nextSibling)) {
       nextSibling.textContent = str + nextSibling.textContent;
       this.cursorNode_ = nextSibling;
       this.cursorOffset_ = lib.wc.strWidth(str);
@@ -9055,12 +8712,11 @@
  */
 hterm.Screen.prototype.overwriteString = function(str) {
   var maxLength = this.columnCount_ - this.cursorPosition.column;
-  if (!maxLength)
-    return [str];
+  if (!maxLength) return [str];
 
   var width = lib.wc.strWidth(str);
   if (this.textAttributes.matchesContainer(this.cursorNode_) &&
-    this.cursorNode_.textContent.substr(this.cursorOffset_) == str) {
+      this.cursorNode_.textContent.substr(this.cursorOffset_) == str) {
     // This overwrite would be a no-op, just move the cursor and return.
     this.cursorOffset_ += width;
     this.cursorPosition.column += width;
@@ -9087,8 +8743,7 @@
 
   var currentCursorColumn = this.cursorPosition.column;
   count = Math.min(count, this.columnCount_ - currentCursorColumn);
-  if (!count)
-    return 0;
+  if (!count) return 0;
 
   var rv = count;
   var startLength, endLength;
@@ -9096,7 +8751,7 @@
   while (node && count) {
     startLength = hterm.TextAttributes.nodeWidth(node);
     node.textContent = hterm.TextAttributes.nodeSubstr(node, 0, offset) +
-      hterm.TextAttributes.nodeSubstr(node, offset + count);
+        hterm.TextAttributes.nodeSubstr(node, offset + count);
     endLength = hterm.TextAttributes.nodeWidth(node);
     count -= startLength - endLength;
     if (offset < startLength && endLength && startLength == endLength) {
@@ -9123,14 +8778,12 @@
     var cursorNode = this.cursorNode_;
     if (cursorNode.previousSibling) {
       this.cursorNode_ = cursorNode.previousSibling;
-      this.cursorOffset_ = hterm.TextAttributes.nodeWidth(
-        cursorNode.previousSibling);
-    }
-    else if (cursorNode.nextSibling) {
+      this.cursorOffset_ =
+          hterm.TextAttributes.nodeWidth(cursorNode.previousSibling);
+    } else if (cursorNode.nextSibling) {
       this.cursorNode_ = cursorNode.nextSibling;
       this.cursorOffset_ = 0;
-    }
-    else {
+    } else {
       var emptyNode = this.cursorRowNode_.ownerDocument.createTextNode('');
       this.cursorRowNode_.appendChild(emptyNode);
       this.cursorNode_ = emptyNode;
@@ -9151,7 +8804,7 @@
  **/
 hterm.Screen.prototype.getLineStartRow_ = function(row) {
   while (row.previousSibling &&
-    row.previousSibling.hasAttribute('line-overflow')) {
+         row.previousSibling.hasAttribute('line-overflow')) {
     row = row.previousSibling;
   }
   return row;
@@ -9170,8 +8823,7 @@
     rowText += row.textContent;
     if (row.hasAttribute('line-overflow')) {
       row = row.nextSibling;
-    }
-    else {
+    } else {
       break;
     }
   }
@@ -9186,8 +8838,7 @@
  **/
 hterm.Screen.prototype.getXRowAncestor_ = function(node) {
   while (node) {
-    if (node.nodeName === 'X-ROW')
-      break;
+    if (node.nodeName === 'X-ROW') break;
     node = node.parentNode;
   }
   return node;
@@ -9204,18 +8855,15 @@
  * @return {integer} Position within line of character at offset within node.
  **/
 hterm.Screen.prototype.getPositionWithOverflow_ = function(row, node, offset) {
-  if (!node)
-    return -1;
+  if (!node) return -1;
   var ancestorRow = this.getXRowAncestor_(node);
-  if (!ancestorRow)
-    return -1;
+  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 {
+    } else {
       return -1;
     }
   }
@@ -9234,13 +8882,12 @@
 hterm.Screen.prototype.getPositionWithinRow_ = function(row, node, offset) {
   if (node.parentNode != row) {
     return this.getPositionWithinRow_(node.parentNode, node, offset) +
-      this.getPositionWithinRow_(row, node.parentNode, 0);
+        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;
+    if (currentNode == node) return position + offset;
     position += hterm.TextAttributes.nodeWidth(currentNode);
   }
   return -1;
@@ -9259,8 +8906,7 @@
     if (row.hasAttribute('line-overflow') && row.nextSibling) {
       position -= hterm.TextAttributes.nodeWidth(row);
       row = row.nextSibling;
-    }
-    else {
+    } else {
       return -1;
     }
   }
@@ -9283,8 +8929,7 @@
       if (node.nodeName === 'SPAN') {
         /** Drill down to node contained by SPAN. **/
         return this.getNodeAndOffsetWithinRow_(node, position);
-      }
-      else {
+      } else {
         return [node, position];
       }
     }
@@ -9304,11 +8949,9 @@
  **/
 hterm.Screen.prototype.setRange_ = function(row, start, end, range) {
   var startNodeAndOffset = this.getNodeAndOffsetWithOverflow_(row, start);
-  if (startNodeAndOffset == null)
-    return;
+  if (startNodeAndOffset == null) return;
   var endNodeAndOffset = this.getNodeAndOffsetWithOverflow_(row, end);
-  if (endNodeAndOffset == null)
-    return;
+  if (endNodeAndOffset == null) return;
   range.setStart(startNodeAndOffset[0], startNodeAndOffset[1]);
   range.setEnd(endNodeAndOffset[0], endNodeAndOffset[1]);
 };
@@ -9319,51 +8962,41 @@
  * @param {Selection} selection Selection to expand.
  **/
 hterm.Screen.prototype.expandSelection = function(selection) {
-  if (!selection)
-    return;
+  if (!selection) return;
 
   var range = selection.getRangeAt(0);
-  if (!range || range.toString().match(/\s/))
-    return;
+  if (!range || range.toString().match(/\s/)) return;
 
   var row = this.getLineStartRow_(this.getXRowAncestor_(range.startContainer));
-  if (!row)
-    return;
+  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;
+  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;
 
   // Matches can start with '~' or '.', since paths frequently do.
   var leftMatch = '[^\\s\\[\\](){}<>"\'\\^!@#$%&*,;:`]';
   var rightMatch = '[^\\s\\[\\](){}<>"\'\\^!@#$%&*,;:~.`]';
   var insideMatch = '[^\\s\\[\\](){}<>"\'\\^]*';
 
-  //Move start to the left.
+  // 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;
+  if (expandedStart == -1 || expandedStart > startPosition) return;
 
-  //Move end to the right.
-  var lineFromRange = lib.wc.substring(rowText, startPosition,
-    lib.wc.strWidth(rowText));
+  // 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;
+  if (!found) return;
   var expandedEnd = startPosition + lib.wc.strWidth(found[0]);
-  if (expandedEnd == -1 || expandedEnd < endPosition)
-    return;
+  if (expandedEnd == -1 || expandedEnd < endPosition) return;
 
   this.setRange_(row, expandedStart, expandedEnd, range);
   selection.addRange(range);
@@ -9519,17 +9152,15 @@
  * Returns null if none of the children are found.
  */
 hterm.ScrollPort.Selection.prototype.findFirstChild = function(
-  parent, childAry) {
+    parent, childAry) {
   var node = parent.firstChild;
 
   while (node) {
-    if (childAry.indexOf(node) != -1)
-      return node;
+    if (childAry.indexOf(node) != -1) return node;
 
     if (node.childNodes.length) {
       var rv = this.findFirstChild(node, childAry);
-      if (rv)
-        return rv;
+      if (rv) return rv;
     }
 
     node = node.nextSibling;
@@ -9577,8 +9208,7 @@
   this.isMultiline = null;
   this.isCollapsed = !selection || selection.isCollapsed;
 
-  if (this.isCollapsed)
-    return;
+  if (this.isCollapsed) return;
 
   var anchorRow = selection.anchorNode;
   while (anchorRow && !('rowIndex' in anchorRow)) {
@@ -9586,8 +9216,9 @@
   }
 
   if (!anchorRow) {
-    console.error('Selection anchor is not rooted in a row node: ' +
-      selection.anchorNode.nodeName);
+    console.error(
+        'Selection anchor is not rooted in a row node: ' +
+        selection.anchorNode.nodeName);
     return;
   }
 
@@ -9597,41 +9228,36 @@
   }
 
   if (!focusRow) {
-    console.error('Selection focus is not rooted in a row node: ' +
-      selection.focusNode.nodeName);
+    console.error(
+        'Selection focus is not rooted in a row node: ' +
+        selection.focusNode.nodeName);
     return;
   }
 
   if (anchorRow.rowIndex < focusRow.rowIndex) {
     anchorFirst();
 
-  }
-  else if (anchorRow.rowIndex > focusRow.rowIndex) {
+  } else if (anchorRow.rowIndex > focusRow.rowIndex) {
     focusFirst();
 
-  }
-  else if (selection.focusNode == selection.anchorNode) {
+  } else if (selection.focusNode == selection.anchorNode) {
     if (selection.anchorOffset < selection.focusOffset) {
       anchorFirst();
-    }
-    else {
+    } else {
       focusFirst();
     }
 
-  }
-  else {
+  } 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]);
+        anchorRow, [selection.anchorNode, selection.focusNode]);
 
-    if (!firstNode)
-      throw new Error('Unexpected error syncing selection.');
+    if (!firstNode) throw new Error('Unexpected error syncing selection.');
 
     if (firstNode == selection.anchorNode) {
       anchorFirst();
-    }
-    else {
+    } else {
       focusFirst();
     }
   }
@@ -9639,7 +9265,6 @@
   this.isMultiline = anchorRow.rowIndex != focusRow.rowIndex;
 };
 
-
 /**
  * Turn a div into this hterm.ScrollPort.
  */
@@ -9647,32 +9272,32 @@
   this.div_ = div;
 
   this.iframe_ = div.ownerDocument.createElement('iframe');
-  this.iframe_.style.cssText = (
-    'border: 0;' +
-    'height: 100%;' +
-    'position: absolute;' +
-    'width: 100%');
+  this.iframe_.style.cssText =
+      ('border: 0;' +
+       'height: 100%;' +
+       'position: absolute;' +
+       'width: 100%');
 
   // Set the iframe src to # 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
+  if ('mozInnerScreenX' in window)  // detect a FF only property
     this.iframe_.src = '#';
 
   div.appendChild(this.iframe_);
 
-  this.iframe_.contentWindow.addEventListener('resize',
-    this.onResize_.bind(this));
+  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: text;' +
-    '-webkit-user-select: none;' +
-    '-moz-user-select: none;');
+  doc.body.style.cssText =
+      ('margin: 0px;' +
+       'padding: 0px;' +
+       'height: 100%;' +
+       'width: 100%;' +
+       'overflow: hidden;' +
+       'cursor: text;' +
+       '-webkit-user-select: none;' +
+       '-moz-user-select: none;');
 
   var style = doc.createElement('style');
   style.textContent = 'x-row {}';
@@ -9690,23 +9315,23 @@
   this.screen_ = doc.createElement('x-screen');
   this.screen_.setAttribute('role', 'textbox');
   this.screen_.setAttribute('tabindex', '-1');
-  this.screen_.style.cssText = (
-    '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');
+  this.screen_.style.cssText =
+      ('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('mousewheel', this.onScrollWheel_.bind(this));
   this.screen_.addEventListener(
-    'DOMMouseScroll', this.onScrollWheel_.bind(this));
+      'DOMMouseScroll', this.onScrollWheel_.bind(this));
   this.screen_.addEventListener('copy', this.onCopy_.bind(this));
   this.screen_.addEventListener('paste', this.onPaste_.bind(this));
 
@@ -9714,20 +9339,20 @@
 
   // This is the main container for the fixed rows.
   this.rowNodes_ = doc.createElement('div');
-  this.rowNodes_.style.cssText = (
-    'display: block;' +
-    'position: fixed;' +
-    'overflow: hidden;' +
-    '-webkit-user-select: text;' +
-    '-moz-user-select: text;');
+  this.rowNodes_.style.cssText =
+      ('display: block;' +
+       'position: fixed;' +
+       'overflow: hidden;' +
+       '-webkit-user-select: text;' +
+       '-moz-user-select: text;');
   this.screen_.appendChild(this.rowNodes_);
 
   // 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;' +
-    'white-space: pre;');
+  this.topSelectBag_.style.cssText =
+      ('display: block;' +
+       'overflow: hidden;' +
+       'white-space: pre;');
 
   this.bottomSelectBag_ = this.topSelectBag_.cloneNode();
 
@@ -9763,29 +9388,28 @@
   this.svg_ = this.div_.ownerDocument.createElementNS(xmlns, 'svg');
   this.svg_.setAttribute('xmlns', xmlns);
   this.svg_.setAttribute('version', '1.1');
-  this.svg_.style.cssText = (
-    'position: absolute;' +
-    'top: 0;' +
-    'left: 0;' +
-    'visibility: hidden');
-
+  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_.setAttribute('tabindex', '-1');
-  this.pasteTarget_.style.cssText = (
-    'position: absolute;' +
-    'height: 1px;' +
-    'width: 1px;' +
-    'left: 0px; ' +
-    'bottom: 0px;' +
-    'opacity: 0');
+  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));
+      'textInput', this.handlePasteTargetTextInput_.bind(this));
 
   this.resize();
 };
@@ -9802,8 +9426,7 @@
   this.screen_.style.fontFamily = fontFamily;
   if (opt_smoothing) {
     this.screen_.style.webkitFontSmoothing = opt_smoothing;
-  }
-  else {
+  } else {
     this.screen_.style.webkitFontSmoothing = '';
   }
 
@@ -9826,8 +9449,7 @@
 
     if (!this.userCssLink_.parentNode)
       this.document_.head.appendChild(this.userCssLink_);
-  }
-  else if (this.userCssLink_.parentNode) {
+  } else if (this.userCssLink_.parentNode) {
     this.document_.head.removeChild(this.userCssLink_);
   }
 };
@@ -9963,8 +9585,7 @@
 };
 
 hterm.ScrollPort.prototype.scheduleInvalidate = function() {
-  if (this.timeouts_.invalidate)
-    return;
+  if (this.timeouts_.invalidate) return;
 
   var self = this;
   this.timeouts_.invalidate = setTimeout(function() {
@@ -9998,20 +9619,21 @@
 hterm.ScrollPort.prototype.measureCharacterSize = function(opt_weight) {
   // Number of lines used to average the height of a single character.
   var numberOfLines = 100;
-  var rulerSingleLineContents = ('XXXXXXXXXXXXXXXXXXXX' +
-    'XXXXXXXXXXXXXXXXXXXX' +
-    'XXXXXXXXXXXXXXXXXXXX' +
-    'XXXXXXXXXXXXXXXXXXXX' +
-    'XXXXXXXXXXXXXXXXXXXX');
+  var rulerSingleLineContents =
+      ('XXXXXXXXXXXXXXXXXXXX' +
+       'XXXXXXXXXXXXXXXXXXXX' +
+       'XXXXXXXXXXXXXXXXXXXX' +
+       'XXXXXXXXXXXXXXXXXXXX' +
+       'XXXXXXXXXXXXXXXXXXXX');
   if (!this.ruler_) {
     this.ruler_ = this.document_.createElement('div');
-    this.ruler_.style.cssText = (
-      'position: absolute;' +
-      'top: 0;' +
-      'left: 0;' +
-      'visibility: hidden;' +
-      'height: auto !important;' +
-      'width: auto !important;');
+    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
@@ -10034,8 +9656,9 @@
   this.rowNodes_.appendChild(this.ruler_);
   var rulerSize = hterm.getClientSize(this.rulerSpan_);
 
-  var size = new hterm.Size(rulerSize.width / rulerSingleLineContents.length,
-    rulerSize.height / numberOfLines);
+  var size = new hterm.Size(
+      rulerSize.width / rulerSingleLineContents.length,
+      rulerSize.height / numberOfLines);
 
   this.ruler_.appendChild(this.rulerBaseline_);
   size.baseline = this.rulerBaseline_.offsetTop;
@@ -10070,8 +9693,8 @@
     // 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 =
-      3 * this.characterSize.height + 'px';
+        this.document_.body.style.paddingBottom =
+            3 * this.characterSize.height + 'px';
   }
 };
 
@@ -10080,21 +9703,17 @@
  * dimensions of the 'x-screen'.
  */
 hterm.ScrollPort.prototype.resize = function() {
-  this.currentScrollbarWidthPx = hterm.getClientWidth(this.screen_) -
-    this.screen_.clientWidth;
+  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();
-    });
+  this.publish('resize', {scrollPort: this}, function() {
+    self.scrollRowToBottom(self.rowProvider_.getRowCount());
+    self.scheduleRedraw();
+  });
 };
 
 /**
@@ -10108,8 +9727,8 @@
 
   // 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);
+  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;
@@ -10122,7 +9741,6 @@
 
   this.topFold_.style.marginBottom = this.visibleRowTopMargin + 'px';
 
-
   var topFoldOffset = 0;
   var node = this.topFold_.previousSibling;
   while (node) {
@@ -10140,11 +9758,9 @@
 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');
+  this.scrollArea_.style.height =
+      (this.characterSize.height * this.lastRowCount_ +
+       this.visibleRowTopMargin + this.visibleRowBottomMargin + 'px');
 };
 
 /**
@@ -10154,8 +9770,7 @@
  * run only one redraw occurs.
  */
 hterm.ScrollPort.prototype.scheduleRedraw = function() {
-  if (this.timeouts_.redraw)
-    return;
+  if (this.timeouts_.redraw) return;
 
   var self = this;
   this.timeouts_.redraw = setTimeout(function() {
@@ -10194,8 +9809,8 @@
   this.previousRowNodeCache_ = this.currentRowNodeCache_;
   this.currentRowNodeCache_ = null;
 
-  this.isScrolledEnd = (
-    this.getTopRowIndex() + this.visibleRowCount >= this.lastRowCount_);
+  this.isScrolledEnd =
+      (this.getTopRowIndex() + this.visibleRowCount >= this.lastRowCount_);
 };
 
 /**
@@ -10213,7 +9828,7 @@
  */
 hterm.ScrollPort.prototype.drawTopFold_ = function(topRowIndex) {
   if (!this.selection.startRow ||
-    this.selection.startRow.rowIndex >= topRowIndex) {
+      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_)
@@ -10223,22 +9838,20 @@
   }
 
   if (!this.selection.isMultiline ||
-    this.selection.endRow.rowIndex >= topRowIndex) {
+      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 {
+      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);
+      this.rowNodes_.insertBefore(
+          this.topFold_, this.selection.endRow.nextSibling);
     }
 
     // Trim any intermediate lines.
-    while (this.selection.startRow.nextSibling !=
-      this.selection.endRow) {
+    while (this.selection.startRow.nextSibling != this.selection.endRow) {
       this.rowNodes_.removeChild(this.selection.startRow.nextSibling);
     }
   }
@@ -10263,7 +9876,7 @@
  */
 hterm.ScrollPort.prototype.drawBottomFold_ = function(bottomRowIndex) {
   if (!this.selection.endRow ||
-    this.selection.endRow.rowIndex <= bottomRowIndex) {
+      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_)
@@ -10273,22 +9886,18 @@
   }
 
   if (!this.selection.isMultiline ||
-    this.selection.startRow.rowIndex <= bottomRowIndex) {
+      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 {
+      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);
+      this.rowNodes_.insertBefore(this.bottomFold_, this.selection.startRow);
     }
 
     // Trim any intermediate lines.
-    while (this.selection.startRow.nextSibling !=
-      this.selection.endRow) {
+    while (this.selection.startRow.nextSibling != this.selection.endRow) {
       this.rowNodes_.removeChild(this.selection.startRow.nextSibling);
     }
   }
@@ -10313,15 +9922,14 @@
  * adjusted around them.
  */
 hterm.ScrollPort.prototype.drawVisibleRows_ = function(
-  topRowIndex, bottomRowIndex) {
+    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) throw 'Did not encounter target node';
 
       if (currentNode == self.bottomFold_)
         throw 'Encountered bottom fold before target node';
@@ -10340,8 +9948,8 @@
   // The node we're examining during the current iteration.
   var node = this.topFold_.nextSibling;
 
-  var targetDrawCount = Math.min(this.visibleRowCount,
-    this.rowProvider_.getRowCount());
+  var targetDrawCount =
+      Math.min(this.visibleRowCount, this.rowProvider_.getRowCount());
 
   for (var drawCount = 0; drawCount < targetDrawCount; drawCount++) {
     var rowIndex = topRowIndex + drawCount;
@@ -10350,7 +9958,7 @@
       // 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);
+        console.log('Couldn\'t fetch row index: ' + rowIndex);
         break;
       }
 
@@ -10385,7 +9993,7 @@
       // yet.  Insert a new row instead.
       var newNode = this.fetchRowNode_(rowIndex);
       if (!newNode) {
-        console.log("Couldn't fetch row index: " + rowIndex);
+        console.log('Couldn\'t fetch row index: ' + rowIndex);
         break;
       }
 
@@ -10397,7 +10005,7 @@
     // it with the node that should be here.
     var newNode = this.fetchRowNode_(rowIndex);
     if (!newNode) {
-      console.log("Couldn't fetch row index: " + rowIndex);
+      console.log('Couldn\'t fetch row index: ' + rowIndex);
       break;
     }
 
@@ -10407,14 +10015,12 @@
     }
 
     this.rowNodes_.insertBefore(newNode, node);
-    if (!newNode.nextSibling)
-      debugger;
+    if (!newNode.nextSibling) debugger;
     this.rowNodes_.removeChild(node);
     node = newNode.nextSibling;
   }
 
-  if (node != this.bottomFold_)
-    removeUntilNode(node, bottomFold);
+  if (node != this.bottomFold_) removeUntilNode(node, bottomFold);
 };
 
 /**
@@ -10458,13 +10064,11 @@
 
   if (this.previousRowNodeCache_ && rowIndex in this.previousRowNodeCache_) {
     node = this.previousRowNodeCache_[rowIndex];
-  }
-  else {
+  } else {
     node = this.rowProvider_.getRowNode(rowIndex);
   }
 
-  if (this.currentRowNodeCache_)
-    this.cacheRowNode_(node);
+  if (this.currentRowNodeCache_) this.cacheRowNode_(node);
 
   return node;
 };
@@ -10483,8 +10087,7 @@
     firstRow = this.fetchRowNode_(0);
     this.rowNodes_.insertBefore(firstRow, this.topFold_);
     this.syncRowNodesDimensions_();
-  }
-  else {
+  } else {
     firstRow = this.topFold_.nextSibling;
   }
 
@@ -10498,8 +10101,7 @@
 
     lastRow = this.fetchRowNode_(lastRowIndex);
     this.rowNodes_.appendChild(lastRow);
-  }
-  else {
+  } else {
     lastRow = this.bottomFold_.previousSibling.rowIndex;
   }
 
@@ -10514,9 +10116,9 @@
  * 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_));
+  return (
+      hterm.getClientHeight(this.scrollArea_) + this.visibleRowTopMargin +
+      this.visibleRowBottomMargin - hterm.getClientHeight(this.screen_));
 };
 
 /**
@@ -10527,18 +10129,15 @@
 hterm.ScrollPort.prototype.scrollRowToTop = function(rowIndex) {
   this.syncScrollHeight();
 
-  this.isScrolledEnd = (
-    rowIndex + this.visibleRowCount >= this.lastRowCount_);
+  this.isScrolledEnd = (rowIndex + this.visibleRowCount >= this.lastRowCount_);
 
-  var scrollTop = rowIndex * this.characterSize.height +
-    this.visibleRowTopMargin;
+  var scrollTop =
+      rowIndex * this.characterSize.height + this.visibleRowTopMargin;
 
   var scrollMax = this.getScrollMax_();
-  if (scrollTop > scrollMax)
-    scrollTop = scrollMax;
+  if (scrollTop > scrollMax) scrollTop = scrollMax;
 
-  if (this.screen_.scrollTop == scrollTop)
-    return;
+  if (this.screen_.scrollTop == scrollTop) return;
 
   this.screen_.scrollTop = scrollTop;
   this.scheduleRedraw();
@@ -10552,18 +10151,15 @@
 hterm.ScrollPort.prototype.scrollRowToBottom = function(rowIndex) {
   this.syncScrollHeight();
 
-  this.isScrolledEnd = (
-    rowIndex + this.visibleRowCount >= this.lastRowCount_);
+  this.isScrolledEnd = (rowIndex + this.visibleRowCount >= this.lastRowCount_);
 
   var scrollTop = rowIndex * this.characterSize.height +
-    this.visibleRowTopMargin + this.visibleRowBottomMargin;
+      this.visibleRowTopMargin + this.visibleRowBottomMargin;
   scrollTop -= this.visibleRowCount * this.characterSize.height;
 
-  if (scrollTop < 0)
-    scrollTop = 0;
+  if (scrollTop < 0) scrollTop = 0;
 
-  if (this.screen_.scrollTop == scrollTop)
-    return;
+  if (this.screen_.scrollTop == scrollTop) return;
 
   this.screen_.scrollTop = scrollTop;
 };
@@ -10597,7 +10193,7 @@
 hterm.ScrollPort.prototype.onScroll_ = function(e) {
   var screenSize = this.getScreenSize();
   if (screenSize.width != this.lastScreenWidth_ ||
-    screenSize.height != this.lastScreenHeight_) {
+      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
@@ -10608,9 +10204,7 @@
   }
 
   this.redraw_();
-  this.publish('scroll', {
-    scrollPort: this
-  });
+  this.publish('scroll', {scrollPort: this});
 };
 
 /**
@@ -10632,8 +10226,7 @@
 hterm.ScrollPort.prototype.onScrollWheel_ = function(e) {
   this.onScrollWheel(e);
 
-  if (e.defaultPrevented)
-    return;
+  if (e.defaultPrevented) return;
 
   // In FF, the event is DOMMouseScroll and puts the scroll pixel delta in the
   // 'detail' field of the event.  It also flips the mapping of which direction
@@ -10642,12 +10235,10 @@
   delta *= this.scrollWheelMultiplier_;
 
   var top = this.screen_.scrollTop - delta;
-  if (top < 0)
-    top = 0;
+  if (top < 0) top = 0;
 
   var scrollMax = this.getScrollMax_();
-  if (top > scrollMax)
-    top = scrollMax;
+  if (top > scrollMax) top = scrollMax;
 
   if (top != this.screen_.scrollTop) {
     // Moving scrollTop causes a scroll event, which triggers the redraw.
@@ -10691,14 +10282,13 @@
 hterm.ScrollPort.prototype.onCopy_ = function(e) {
   this.onCopy(e);
 
-  if (e.defaultPrevented)
-    return;
+  if (e.defaultPrevented) return;
 
   this.resetSelectBags_();
   this.selection.sync();
 
   if (!this.selection.startRow ||
-    this.selection.endRow.rowIndex - this.selection.startRow.rowIndex < 2) {
+      this.selection.endRow.rowIndex - this.selection.startRow.rowIndex < 2) {
     return;
   }
 
@@ -10712,16 +10302,15 @@
     if (this.selection.endRow.rowIndex < topRowIndex) {
       // Entire selection is above the top fold.
       endBackfillIndex = this.selection.endRow.rowIndex;
-    }
-    else {
+    } 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.selection.startRow.rowIndex + 1, endBackfillIndex);
+    this.rowNodes_.insertBefore(
+        this.topSelectBag_, this.selection.startRow.nextSibling);
     this.syncRowNodesDimensions_();
   }
 
@@ -10732,14 +10321,13 @@
     if (this.selection.startRow.rowIndex > bottomRowIndex) {
       // Entire selection is below the bottom fold.
       startBackfillIndex = this.selection.startRow.rowIndex + 1;
-    }
-    else {
+    } else {
       // Selection starts above the bottom fold.
       startBackfillIndex = this.bottomFold_.previousSibling.rowIndex + 1;
     }
 
     this.bottomSelectBag_.textContent = this.rowProvider_.getRowsText(
-      startBackfillIndex, this.selection.endRow.rowIndex);
+        startBackfillIndex, this.selection.endRow.rowIndex);
     this.rowNodes_.insertBefore(this.bottomSelectBag_, this.selection.endRow);
   }
 };
@@ -10749,13 +10337,11 @@
  * FF a content editable element must be focused before the paste event.
  */
 hterm.ScrollPort.prototype.onBodyKeyDown_ = function(e) {
-  if (!this.ctrlVPaste)
-    return;
+  if (!this.ctrlVPaste) return;
 
   var key = String.fromCharCode(e.which);
   var lowerKey = key.toLowerCase();
-  if ((e.ctrlKey || e.metaKey) && lowerKey == 'v')
-    this.pasteTarget_.focus();
+  if ((e.ctrlKey || e.metaKey) && lowerKey == 'v') this.pasteTarget_.focus();
 };
 
 /**
@@ -10766,9 +10352,7 @@
 
   var self = this;
   setTimeout(function() {
-    self.publish('paste', {
-      text: self.pasteTarget_.value
-    });
+    self.publish('paste', {text: self.pasteTarget_.value});
     self.pasteTarget_.value = '';
     self.screen_.focus();
   }, 0);
@@ -10803,10 +10387,11 @@
 
 'use strict';
 
-lib.rtdep('lib.colors', 'lib.PreferenceManager', 'lib.resource', 'lib.wc',
-  'lib.f', 'hterm.Keyboard', 'hterm.Options', 'hterm.PreferenceManager',
-  'hterm.Screen', 'hterm.ScrollPort', 'hterm.Size',
-  'hterm.TextAttributes', 'hterm.VT');
+lib.rtdep(
+    'lib.colors', 'lib.PreferenceManager', 'lib.resource', 'lib.wc', 'lib.f',
+    'hterm.Keyboard', 'hterm.Options', 'hterm.PreferenceManager',
+    'hterm.Screen', 'hterm.ScrollPort', 'hterm.Size', 'hterm.TextAttributes',
+    'hterm.VT');
 
 /**
  * Constructor for the Terminal class.
@@ -10944,10 +10529,9 @@
   this.realizeSize_(80, 24);
   this.setDefaultTabStops();
 
-  this.setProfile(opt_profileId || 'default',
-    function() {
-      this.onTerminalReady();
-    }.bind(this));
+  this.setProfile(opt_profileId || 'default', function() {
+    this.onTerminalReady();
+  }.bind(this));
 };
 
 /**
@@ -10989,8 +10573,7 @@
 
   var terminal = this;
 
-  if (this.prefs_)
-    this.prefs_.deactivate();
+  if (this.prefs_) this.prefs_.deactivate();
 
   this.prefs_ = new hterm.PreferenceManager(this.profileId_);
   this.prefs_.addObservers(null, {
@@ -10998,20 +10581,16 @@
       if (v == null) {
         if (navigator.language.toLowerCase() == 'en-us') {
           v = 'none';
-        }
-        else {
+        } else {
           v = 'right-alt';
         }
-      }
-      else if (typeof v == 'string') {
+      } else if (typeof v == 'string') {
         v = v.toLowerCase();
-      }
-      else {
+      } else {
         v = 'none';
       }
 
-      if (!/^(none|ctrl-alt|left-alt|right-alt)$/.test(v))
-        v = 'none';
+      if (!/^(none|ctrl-alt|left-alt|right-alt)$/.test(v)) v = 'none';
 
       terminal.keyboard.altGrMode = v;
     },
@@ -11025,8 +10604,7 @@
     },
 
     'alt-sends-what': function(v) {
-      if (!/^(escape|8-bit|browser-key)$/.test(v))
-        v = 'escape';
+      if (!/^(escape|8-bit|browser-key)$/.test(v)) v = 'escape';
 
       terminal.keyboard.altSendsWhat = v;
     },
@@ -11034,10 +10612,9 @@
     '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', lib.resource.getDataUrl(ary[1]));
+      } else {
         terminal.bellAudio_.setAttribute('src', v);
       }
     },
@@ -11045,7 +10622,7 @@
     'desktop-notification-bell': function(v) {
       if (v && Notification) {
         terminal.desktopNotificationBell_ =
-          Notification.permission === 'granted';
+            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
@@ -11053,11 +10630,11 @@
           //
           // 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.');
+          console.warn(
+              'desktop-notification-bell is true but we do not have ' +
+              'permission to display notifications.');
         }
-      }
-      else {
+      } else {
         terminal.desktopNotificationBell_ = false;
       }
     },
@@ -11084,8 +10661,9 @@
 
     'character-map-overrides': function(v) {
       if (!(v == null || v instanceof Object)) {
-        console.warn('Preference character-map-modifications is not an ' +
-          'object: ' + v);
+        console.warn(
+            'Preference character-map-modifications is not an ' +
+            'object: ' + v);
         return;
       }
 
@@ -11103,15 +10681,12 @@
     },
 
     'cursor-blink-cycle': function(v) {
-      if (v instanceof Array &&
-        typeof v[0] == 'number' &&
-        typeof v[1] == 'number') {
+      if (v instanceof Array && typeof v[0] == 'number' &&
+          typeof v[1] == 'number') {
         terminal.cursorBlinkCycle_ = v;
-      }
-      else if (typeof v == 'number') {
+      } else if (typeof v == 'number') {
         terminal.cursorBlinkCycle_ = [v, v];
-      }
-      else {
+      } else {
         // Fast blink indicates an error.
         terminal.cursorBlinkCycle_ = [100, 100];
       }
@@ -11123,8 +10698,9 @@
 
     '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);
+        console.warn(
+            'Preference color-palette-overrides is not an array or ' +
+            'object: ' + v);
         return;
       }
 
@@ -11140,8 +10716,7 @@
 
           if (v[i]) {
             var rgb = lib.colors.normalizeCSS(v[i]);
-            if (rgb)
-              lib.colors.colorPalette[i] = rgb;
+            if (rgb) lib.colors.colorPalette[i] = rgb;
           }
         }
       }
@@ -11227,8 +10802,7 @@
     'keybindings': function(v) {
       terminal.keyboard.bindings.clear();
 
-      if (!v)
-        return;
+      if (!v) return;
 
       if (!(v instanceof Object)) {
         console.error('Error in keybindings preference: Expected object');
@@ -11237,8 +10811,7 @@
 
       try {
         terminal.keyboard.bindings.addBindings(v);
-      }
-      catch (ex) {
+      } catch (ex) {
         console.error('Error in keybindings preference: ' + ex);
       }
     },
@@ -11349,12 +10922,10 @@
   this.prefs_.readStorage(function() {
     this.prefs_.notifyAll();
 
-    if (opt_callback)
-      opt_callback();
+    if (opt_callback) opt_callback();
   }.bind(this));
 };
 
-
 /**
  * Returns the preferences manager used for configuring this terminal.
  *
@@ -11415,9 +10986,9 @@
 hterm.Terminal.prototype.setBackgroundColor = function(color) {
   this.backgroundColor_ = lib.colors.normalizeCSS(color);
   this.primaryScreen_.textAttributes.setDefaults(
-    this.foregroundColor_, this.backgroundColor_);
+      this.foregroundColor_, this.backgroundColor_);
   this.alternateScreen_.textAttributes.setDefaults(
-    this.foregroundColor_, this.backgroundColor_);
+      this.foregroundColor_, this.backgroundColor_);
   this.scrollPort_.setBackgroundColor(color);
 };
 
@@ -11444,9 +11015,9 @@
 hterm.Terminal.prototype.setForegroundColor = function(color) {
   this.foregroundColor_ = lib.colors.normalizeCSS(color);
   this.primaryScreen_.textAttributes.setDefaults(
-    this.foregroundColor_, this.backgroundColor_);
+      this.foregroundColor_, this.backgroundColor_);
   this.alternateScreen_.textAttributes.setDefaults(
-    this.foregroundColor_, this.backgroundColor_);
+      this.foregroundColor_, this.backgroundColor_);
   this.scrollPort_.setForegroundColor(color);
 };
 
@@ -11471,8 +11042,7 @@
  */
 hterm.Terminal.prototype.runCommandClass = function(commandClass, argString) {
   var environment = this.prefs_.get('environment');
-  if (typeof environment != 'object' || environment == null)
-    environment = {};
+  if (typeof environment != 'object' || environment == null) environment = {};
 
   var self = this;
   this.command = new commandClass({
@@ -11482,8 +11052,7 @@
     onExit: function(code) {
       self.io.pop();
       self.uninstallKeyboard();
-      if (self.prefs_.get('close-on-exit'))
-        window.close();
+      if (self.prefs_.get('close-on-exit')) window.close();
     }
   });
 
@@ -11527,13 +11096,12 @@
  * @param {number} px The desired font size, in pixels.
  */
 hterm.Terminal.prototype.setFontSize = function(px) {
-  if (px === 0)
-    px = this.prefs_.get('font-size');
+  if (px === 0) px = this.prefs_.get('font-size');
 
   this.scrollPort_.setFontSize(px);
   if (this.wcCssRule_) {
-    this.wcCssRule_.style.width = this.scrollPort_.characterSize.width * 2 +
-      'px';
+    this.wcCssRule_.style.width =
+        this.scrollPort_.characterSize.width * 2 + 'px';
   }
 };
 
@@ -11559,8 +11127,8 @@
  * 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.scrollPort_.setFontFamily(
+      this.prefs_.get('font-family'), this.prefs_.get('font-smoothing'));
   this.syncBoldSafeState();
 };
 
@@ -11578,8 +11146,7 @@
   var ary = navigator.userAgent.match(/\(X11;\s+(\S+)/);
   if (!ary || ary[2] == 'CrOS') {
     this.mousePasteButton = 2;
-  }
-  else {
+  } else {
     this.mousePasteButton = 3;
   }
 };
@@ -11601,9 +11168,9 @@
 
   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());
+    console.warn(
+        'Bold characters disabled: Size of bold weight differs ' +
+        'from normal.  Font family is: ' + this.scrollPort_.getFontFamily());
   }
 
   this.primaryScreen_.textAttributes.enableBold = isBoldSafe;
@@ -11615,8 +11182,8 @@
  */
 hterm.Terminal.prototype.syncBlinkState = function() {
   this.document_.documentElement.style.setProperty(
-    '--hterm-blink-node-duration',
-    this.prefs_.get('enable-blink') ? '0.7s' : '0');
+      '--hterm-blink-node-duration',
+      this.prefs_.get('enable-blink') ? '0.7s' : '0');
 };
 
 /**
@@ -11673,8 +11240,7 @@
   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) {
+  if (cursor.column > column || cursor.column == column && cursor.overflow) {
     this.screen_.cursorPosition.overflow = true;
   }
 };
@@ -11716,9 +11282,11 @@
     return;
   }
 
-  this.div_.style.width = Math.ceil(
-    this.scrollPort_.characterSize.width *
-    columnCount + this.scrollPort_.currentScrollbarWidthPx) + 'px';
+  this.div_.style.width =
+      Math.ceil(
+          this.scrollPort_.characterSize.width * columnCount +
+          this.scrollPort_.currentScrollbarWidthPx) +
+      'px';
   this.realizeSize_(columnCount, this.screenSize.height);
   this.scheduleSyncCursorPosition_();
 };
@@ -11735,7 +11303,7 @@
   }
 
   this.div_.style.height =
-    this.scrollPort_.characterSize.height * rowCount + 'px';
+      this.scrollPort_.characterSize.height * rowCount + 'px';
   this.realizeSize_(this.screenSize.width, rowCount);
   this.scheduleSyncCursorPosition_();
 };
@@ -11747,11 +11315,9 @@
  * @param {number} rowCount The number of rows.
  */
 hterm.Terminal.prototype.realizeSize_ = function(columnCount, rowCount) {
-  if (columnCount != this.screenSize.width)
-    this.realizeWidth_(columnCount);
+  if (columnCount != this.screenSize.width) this.realizeWidth_(columnCount);
 
-  if (rowCount != this.screenSize.height)
-    this.realizeHeight_(rowCount);
+  if (rowCount != this.screenSize.height) this.realizeHeight_(rowCount);
 
   // Send new terminal size to plugin.
   this.io.onTerminalResize_(columnCount, rowCount);
@@ -11782,11 +11348,9 @@
   if (deltaColumns > 0) {
     if (this.defaultTabStops)
       this.setDefaultTabStops(this.screenSize.width - deltaColumns);
-  }
-  else {
+  } else {
     for (var i = this.tabStops_.length - 1; i >= 0; i--) {
-      if (this.tabStops_[i] < columnCount)
-        break;
+      if (this.tabStops_[i] < columnCount) break;
 
       this.tabStops_.pop();
     }
@@ -11823,11 +11387,9 @@
     deltaRows *= -1;
     while (deltaRows) {
       var lastRow = this.getRowCount() - 1;
-      if (lastRow - this.scrollbackRows_.length == cursor.row)
-        break;
+      if (lastRow - this.scrollbackRows_.length == cursor.row) break;
 
-      if (this.getRowText(lastRow))
-        break;
+      if (this.getRowText(lastRow)) break;
 
       this.screen_.popRow();
       deltaRows--;
@@ -11839,21 +11401,19 @@
     // 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) {
+  } 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.scrollbackRows_.length - scrollbackCount, scrollbackCount);
       this.screen_.unshiftRows(rows);
       deltaRows -= scrollbackCount;
       cursor.row += scrollbackCount;
     }
 
-    if (deltaRows)
-      this.appendRows_(deltaRows);
+    if (deltaRows) this.appendRows_(deltaRows);
   }
 
   this.setVTScrollRegion(null, null);
@@ -12001,8 +11561,7 @@
  */
 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) return;
 
     if (this.tabStops_[i] < column) {
       this.tabStops_.splice(i + 1, 0, column);
@@ -12022,8 +11581,7 @@
   var column = this.screen_.cursorPosition.column;
 
   var i = this.tabStops_.indexOf(column);
-  if (i == -1)
-    return;
+  if (i == -1) return;
 
   this.tabStops_.splice(i, 1);
 };
@@ -12046,8 +11604,8 @@
  * 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.
+ * @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;
@@ -12085,7 +11643,7 @@
   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.prefs_.get('background-position'));
   this.scrollPort_.setUserCss(this.prefs_.get('user-css'));
 
   this.div_.focus = this.focus.bind(this);
@@ -12095,7 +11653,7 @@
 
   this.setScrollbarVisible(this.prefs_.get('scrollbar-visible'));
   this.setScrollWheelMoveMultipler(
-    this.prefs_.get('scroll-wheel-move-multiplier'));
+      this.prefs_.get('scroll-wheel-move-multiplier'));
 
   this.document_ = this.scrollPort_.getDocument();
 
@@ -12110,44 +11668,42 @@
   screenNode.addEventListener('mousemove', onMouse);
   this.scrollPort_.onScrollWheel = onMouse;
 
-  screenNode.addEventListener(
-    'focus', this.onFocusChange_.bind(this, true));
+  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));
+  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;' +
-      '}' +
-      '.wc-node {' +
-      '  display: inline-block;' +
-      '  text-align: center;' +
-      '  width: ' + this.scrollPort_.characterSize.width * 2 + 'px;' +
-      '}' +
-      ':root {' +
-      '  --hterm-blink-node-duration: 0.7s;' +
-      '}' +
-      '@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;' +
-      '}');
+      ('.cursor-node[focus="false"] {' +
+       '  box-sizing: border-box;' +
+       '  background-color: transparent !important;' +
+       '  border-width: 2px;' +
+       '  border-style: solid;' +
+       '}' +
+       '.wc-node {' +
+       '  display: inline-block;' +
+       '  text-align: center;' +
+       '  width: ' + this.scrollPort_.characterSize.width * 2 + 'px;' +
+       '}' +
+       ':root {' +
+       '  --hterm-blink-node-duration: 0.7s;' +
+       '}' +
+       '@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;' +
+       '}');
   this.document_.head.appendChild(style);
 
   var styleSheets = this.document_.styleSheets;
@@ -12157,13 +11713,13 @@
   this.cursorNode_ = this.document_.createElement('div');
   this.cursorNode_.className = 'cursor-node';
   this.cursorNode_.style.cssText =
-    ('position: absolute;' +
-      'top: -99px;' +
-      'display: block;' +
-      'width: ' + this.scrollPort_.characterSize.width + 'px;' +
-      'height: ' + this.scrollPort_.characterSize.height + 'px;' +
-      '-webkit-transition: opacity, background-color 100ms linear;' +
-      '-moz-transition: opacity, background-color 100ms linear;');
+      ('position: absolute;' +
+       'top: -99px;' +
+       'display: block;' +
+       'width: ' + this.scrollPort_.characterSize.width + 'px;' +
+       'height: ' + this.scrollPort_.characterSize.height + 'px;' +
+       '-webkit-transition: opacity, background-color 100ms linear;' +
+       '-moz-transition: opacity, background-color 100ms linear;');
 
   this.setCursorColor(this.prefs_.get('cursor-color'));
   this.setCursorBlink(!!this.prefs_.get('cursor-blink'));
@@ -12180,15 +11736,20 @@
   // It's a hack, but it's the cleanest way I could find.
   this.scrollBlockerNode_ = this.document_.createElement('div');
   this.scrollBlockerNode_.style.cssText =
-    ('position: absolute;' +
-      'top: -99px;' +
-      'display: block;' +
-      'width: 10px;' +
-      'height: 10px;');
+      ('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) {
+  ['mousedown',
+   'mouseup',
+   'mousemove',
+   'click',
+   'dblclick',
+  ].forEach(function(event) {
     this.scrollBlockerNode_.addEventListener(event, onMouse);
     this.cursorNode_.addEventListener(event, onMouse);
     this.document_.addEventListener(event, onMouse);
@@ -12235,8 +11796,7 @@
  * @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];
+  if (index < this.scrollbackRows_.length) return this.scrollbackRows_[index];
 
   var screenIndex = index - this.scrollbackRows_.length;
   return this.screen_.rowsArray[screenIndex];
@@ -12262,8 +11822,7 @@
   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');
+    if (i < end - 1 && !node.getAttribute('line-overflow')) ary.push('\n');
   }
 
   return ary.join('');
@@ -12330,8 +11889,7 @@
   if (extraRows > 0) {
     var ary = this.screen_.shiftRows(extraRows);
     Array.prototype.push.apply(this.scrollbackRows_, ary);
-    if (this.scrollPort_.isScrolledEnd)
-      this.scheduleScrollDown_();
+    if (this.scrollPort_.isScrolledEnd) this.scheduleScrollDown_();
   }
 
   if (cursorRow >= this.screen_.rowsArray.length)
@@ -12362,8 +11920,7 @@
   if (fromIndex < toIndex) {
     start = fromIndex;
     end = toIndex + count;
-  }
-  else {
+  } else {
     start = toIndex;
     end = fromIndex + count;
   }
@@ -12430,22 +11987,19 @@
       // 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);
+          lib.wc.substr(str, strWidth - 1);
       count = strWidth;
-    }
-    else {
+    } else {
       substr = lib.wc.substr(str, startOffset, count);
     }
 
     var tokens = hterm.TextAttributes.splitWidecharString(substr);
     for (var i = 0; i < tokens.length; i++) {
-      if (tokens[i].wcNode)
-        this.screen_.textAttributes.wcNode = true;
+      if (tokens[i].wcNode) this.screen_.textAttributes.wcNode = true;
 
       if (this.options_.insertMode) {
         this.screen_.insertString(tokens[i].str);
-      }
-      else {
+      } else {
         this.screen_.overwriteString(tokens[i].str);
       }
       this.screen_.textAttributes.wcNode = false;
@@ -12481,8 +12035,7 @@
   if (scrollTop == 0 && scrollBottom == this.screenSize.height - 1) {
     this.vtScrollTop_ = null;
     this.vtScrollBottom_ = null;
-  }
-  else {
+  } else {
     this.vtScrollTop_ = scrollTop;
     this.vtScrollBottom_ = scrollBottom;
   }
@@ -12498,8 +12051,7 @@
  * @return {integer} The topmost row in the terminal's scroll region.
  */
 hterm.Terminal.prototype.getVTScrollTop = function() {
-  if (this.vtScrollTop_ != null)
-    return this.vtScrollTop_;
+  if (this.vtScrollTop_ != null) return this.vtScrollTop_;
 
   return 0;
 };
@@ -12514,8 +12066,7 @@
  * @return {integer} The bottom most row in the terminal's scroll region.
  */
 hterm.Terminal.prototype.getVTScrollBottom = function() {
-  if (this.vtScrollBottom_ != null)
-    return this.vtScrollBottom_;
+  if (this.vtScrollBottom_ != null) return this.vtScrollBottom_;
 
   return this.screenSize.height - 1;
 };
@@ -12530,8 +12081,8 @@
  * Otherwise, this moves the cursor to column zero of the next row.
  */
 hterm.Terminal.prototype.newLine = function() {
-  var cursorAtEndOfScreen = (this.screen_.cursorPosition.row ==
-    this.screen_.rowsArray.length - 1);
+  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.
@@ -12539,23 +12090,19 @@
       // 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) {
+    } 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 {
+    } else {
       // Anywhere else, advance the cursor row, and reset the column.
       this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row + 1, 0);
     }
-  }
-  else if (cursorAtEndOfScreen) {
+  } 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 {
+  } else {
     // Anywhere else in the screen just moves the cursor.
     this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row + 1, 0);
   }
@@ -12576,8 +12123,7 @@
 hterm.Terminal.prototype.formFeed = function() {
   if (this.options_.autoCarriageReturn) {
     this.newLine();
-  }
-  else {
+  } else {
     this.lineFeed();
   }
 };
@@ -12593,8 +12139,7 @@
 
   if (currentRow == scrollTop) {
     this.insertLines(1);
-  }
-  else {
+  } else {
     this.setAbsoluteCursorRow(currentRow - 1);
   }
 };
@@ -12632,17 +12177,16 @@
  * @param {number} opt_count The number of characters to erase.
  */
 hterm.Terminal.prototype.eraseToRight = function(opt_count) {
-  if (this.screen_.cursorPosition.overflow)
-    return;
+  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) {
+      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_.cursorPosition.column + count) {
       this.screen_.deleteChars(count);
       this.clearCursorOverflow();
       return;
@@ -12787,8 +12331,7 @@
   // 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);
+  if (moveCount) this.moveRows_(cursorRow, moveCount, cursorRow + count);
 
   for (var i = count - 1; i >= 0; i--) {
     this.setAbsoluteCursorPosition(cursorRow + i, 0);
@@ -12814,8 +12357,7 @@
   count = Math.min(count, maxCount);
 
   var moveStart = bottom - count + 1;
-  if (count != maxCount)
-    this.moveRows_(top, count, moveStart);
+  if (count != maxCount) this.moveRows_(top, count, moveStart);
 
   for (var i = 0; i < count; i++) {
     this.setAbsoluteCursorPosition(moveStart + i, 0);
@@ -12906,7 +12448,6 @@
   this.restoreCursor(cursor);
 };
 
-
 /**
  * Set the cursor position.
  *
@@ -12919,8 +12460,7 @@
 hterm.Terminal.prototype.setCursorPosition = function(row, column) {
   if (this.options_.originMode) {
     this.setRelativeCursorPosition(row, column);
-  }
-  else {
+  } else {
     this.setAbsoluteCursorPosition(row, column);
   }
 };
@@ -12996,8 +12536,7 @@
  * Multiple calls will be coalesced into a single redraw.
  */
 hterm.Terminal.prototype.scheduleRedraw_ = function() {
-  if (this.timeouts_.redraw)
-    return;
+  if (this.timeouts_.redraw) return;
 
   var self = this;
   this.timeouts_.redraw = setTimeout(function() {
@@ -13016,8 +12555,7 @@
  * do with the VT scroll commands.
  */
 hterm.Terminal.prototype.scheduleScrollDown_ = function() {
-  if (this.timeouts_.scrollDown)
-    return;
+  if (this.timeouts_.scrollDown) return;
 
   var self = this;
   this.timeouts_.scrollDown = setTimeout(function() {
@@ -13043,11 +12581,12 @@
 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 maxHeight =
+      (this.options_.originMode ? this.getVTScrollBottom() :
+                                  this.screenSize.height - 1);
 
-  var row = lib.f.clamp(this.screen_.cursorPosition.row + count,
-    minHeight, maxHeight);
+  var row = lib.f.clamp(
+      this.screen_.cursorPosition.row + count, minHeight, maxHeight);
   this.setAbsoluteCursorRow(row);
 };
 
@@ -13062,8 +12601,7 @@
 hterm.Terminal.prototype.cursorLeft = function(count) {
   count = count || 1;
 
-  if (count < 1)
-    return;
+  if (count < 1) return;
 
   var currentColumn = this.screen_.cursorPosition.column;
   if (this.options_.reverseWraparound) {
@@ -13074,8 +12612,7 @@
       count--;
       this.clearCursorOverflow();
 
-      if (!count)
-        return;
+      if (!count) return;
     }
 
     var newRow = this.screen_.cursorPosition.row;
@@ -13091,8 +12628,7 @@
 
     this.setCursorPosition(Math.max(newRow, 0), newColumn);
 
-  }
-  else {
+  } else {
     var newColumn = Math.max(currentColumn - count, 0);
     this.setCursorColumn(newColumn);
   }
@@ -13106,11 +12642,10 @@
 hterm.Terminal.prototype.cursorRight = function(count) {
   count = count || 1;
 
-  if (count < 1)
-    return;
+  if (count < 1) return;
 
-  var column = lib.f.clamp(this.screen_.cursorPosition.column + count,
-    0, this.screenSize.width - 1);
+  var column = lib.f.clamp(
+      this.screen_.cursorPosition.column + count, 0, this.screenSize.width - 1);
   this.setCursorColumn(column);
 };
 
@@ -13130,8 +12665,7 @@
   if (state) {
     this.scrollPort_.setForegroundColor(this.prefs_.get('background-color'));
     this.scrollPort_.setBackgroundColor(this.prefs_.get('foreground-color'));
-  }
-  else {
+  } else {
     this.scrollPort_.setForegroundColor(this.prefs_.get('foreground-color'));
     this.scrollPort_.setBackgroundColor(this.prefs_.get('background-color'));
   }
@@ -13144,7 +12678,7 @@
  */
 hterm.Terminal.prototype.ringBell = function() {
   this.cursorNode_.style.backgroundColor =
-    this.scrollPort_.getForegroundColor();
+      this.scrollPort_.getForegroundColor();
 
   var self = this;
   setTimeout(function() {
@@ -13152,24 +12686,21 @@
   }, 200);
 
   // bellSquelchTimeout_ affects both audio and notification bells.
-  if (this.bellSquelchTimeout_)
-    return;
+  if (this.bellSquelchTimeout_) return;
 
   if (this.bellAudio_.getAttribute('src')) {
     this.bellAudio_.play();
     this.bellSequelchTimeout_ = setTimeout(function() {
       delete this.bellSquelchTimeout_;
     }.bind(this), 500);
-  }
-  else {
+  } else {
     delete this.bellSquelchTimeout_;
   }
 
   if (this.desktopNotificationBell_ && !this.document_.hasFocus()) {
-    var n = new Notification(
-      lib.f.replaceVars(hterm.desktopNotificationTitle, {
-        'title': window.document.title || 'hterm'
-      }));
+    var n = new Notification(lib.f.replaceVars(
+        hterm.desktopNotificationTitle,
+        {'title': window.document.title || 'hterm'}));
     this.bellNotificationList_.push(n);
     // TODO: Should we try to raise the window here?
     n.onclick = function() {
@@ -13271,7 +12802,7 @@
   this.screen_ = state ? this.alternateScreen_ : this.primaryScreen_;
 
   if (this.screen_.rowsArray.length &&
-    this.screen_.rowsArray[0].rowIndex != this.scrollbackRows_.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;
@@ -13311,8 +12842,7 @@
     delete this.timeouts_.cursorBlink;
   }
 
-  if (this.options_.cursorVisible)
-    this.setCursorVisible(true);
+  if (this.options_.cursorVisible) this.setCursorVisible(true);
 };
 
 /**
@@ -13341,12 +12871,10 @@
   this.cursorNode_.style.opacity = '1';
 
   if (this.options_.cursorBlink) {
-    if (this.timeouts_.cursorBlink)
-      return;
+    if (this.timeouts_.cursorBlink) return;
 
     this.onCursorBlink_();
-  }
-  else {
+  } else {
     if (this.timeouts_.cursorBlink) {
       clearTimeout(this.timeouts_.cursorBlink);
       delete this.timeouts_.cursorBlink;
@@ -13361,8 +12889,8 @@
 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;
+  var cursorRowIndex =
+      this.scrollbackRows_.length + this.screen_.cursorPosition.row;
 
   if (cursorRowIndex > bottomRowIndex) {
     // Cursor is scrolled off screen, move it outside of the visible area.
@@ -13370,23 +12898,22 @@
     return;
   }
 
-  if (this.options_.cursorVisible &&
-    this.cursorNode_.style.display == 'none') {
+  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 = '';
   }
 
-
   this.cursorNode_.style.top = this.scrollPort_.visibleRowTopMargin +
-    this.scrollPort_.characterSize.height * (cursorRowIndex - topRowIndex) +
-    'px';
+      this.scrollPort_.characterSize.height * (cursorRowIndex - topRowIndex) +
+      'px';
   this.cursorNode_.style.left = this.scrollPort_.characterSize.width *
-    this.screen_.cursorPosition.column + 'px';
+          this.screen_.cursorPosition.column +
+      'px';
 
-  this.cursorNode_.setAttribute('title',
-    '(' + this.screen_.cursorPosition.row +
-    ', ' + this.screen_.cursorPosition.column +
-    ')');
+  this.cursorNode_.setAttribute(
+      'title',
+      '(' + this.screen_.cursorPosition.row + ', ' +
+          this.screen_.cursorPosition.column + ')');
 
   // Update the caret for a11y purposes.
   var selection = this.document_.getSelection();
@@ -13442,8 +12969,7 @@
  * Multiple calls will be coalesced into a single sync.
  */
 hterm.Terminal.prototype.scheduleSyncCursorPosition_ = function() {
-  if (this.timeouts_.syncCursor)
-    return;
+  if (this.timeouts_.syncCursor) return;
 
   var self = this;
   this.timeouts_.syncCursor = setTimeout(function() {
@@ -13462,24 +12988,23 @@
  */
 hterm.Terminal.prototype.showZoomWarning_ = function(state) {
   if (!this.zoomWarningNode_) {
-    if (!state)
-      return;
+    if (!state) return;
 
     this.zoomWarningNode_ = this.document_.createElement('div');
-    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_.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);
@@ -13487,15 +13012,15 @@
   }
 
   this.zoomWarningNode_.textContent = lib.MessageManager.replaceReferences(
-    hterm.zoomWarningMessage, [parseInt(this.scrollPort_.characterSize.zoomFactor * 100)]);
+      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) {
+  } else if (this.zoomWarningNode_.parentNode) {
     this.zoomWarningNode_.parentNode.removeChild(this.zoomWarningNode_);
   }
 };
@@ -13515,20 +13040,19 @@
  */
 hterm.Terminal.prototype.showOverlay = function(msg, opt_timeout) {
   if (!this.overlayNode_) {
-    if (!this.div_)
-      return;
+    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_.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();
@@ -13543,24 +13067,23 @@
   this.overlayNode_.textContent = msg;
   this.overlayNode_.style.opacity = '0.75';
 
-  if (!this.overlayNode_.parentNode)
-    this.div_.appendChild(this.overlayNode_);
+  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';
+      (divSize.height - overlaySize.height) / 2 + 'px';
   this.overlayNode_.style.left = (divSize.width - overlaySize.width -
-    this.scrollPort_.currentScrollbarWidthPx) / 2 + 'px';
+                                  this.scrollPort_.currentScrollbarWidthPx) /
+          2 +
+      'px';
 
   var self = this;
 
-  if (this.overlayTimeout_)
-    clearTimeout(this.overlayTimeout_);
+  if (this.overlayTimeout_) clearTimeout(this.overlayTimeout_);
 
-  if (opt_timeout === null)
-    return;
+  if (opt_timeout === null) return;
 
   this.overlayTimeout_ = setTimeout(function() {
     self.overlayNode_.style.opacity = '0';
@@ -13593,11 +13116,11 @@
 
   var copySource = this.document_.createElement('pre');
   copySource.textContent = str;
-  copySource.style.cssText = (
-    '-webkit-user-select: text;' +
-    '-moz-user-select: text;' +
-    'position: absolute;' +
-    'top: -99px');
+  copySource.style.cssText =
+      ('-webkit-user-select: text;' +
+       '-moz-user-select: text;' +
+       'position: absolute;' +
+       'top: -99px');
 
   this.document_.body.appendChild(copySource);
 
@@ -13630,9 +13153,7 @@
   var selection = this.scrollPort_.selection;
   selection.sync();
 
-  if (selection.isCollapsed)
-    return null;
-
+  if (selection.isCollapsed) return null;
 
   // Start offset measures from the beginning of the line.
   var startOffset = selection.startOffset;
@@ -13655,8 +13176,8 @@
   }
 
   // End offset measures from the end of the line.
-  var endOffset = (hterm.TextAttributes.nodeWidth(selection.endNode) -
-    selection.endOffset);
+  var endOffset =
+      (hterm.TextAttributes.nodeWidth(selection.endNode) - selection.endOffset);
   node = selection.endNode;
 
   if (node.nodeName != 'X-ROW') {
@@ -13675,8 +13196,8 @@
     }
   }
 
-  var rv = this.getRowsText(selection.startRow.rowIndex,
-    selection.endRow.rowIndex + 1);
+  var rv = this.getRowsText(
+      selection.startRow.rowIndex, selection.endRow.rowIndex + 1);
   return lib.wc.substring(rv, startOffset, lib.wc.strWidth(rv) - endOffset);
 };
 
@@ -13686,8 +13207,7 @@
  */
 hterm.Terminal.prototype.copySelectionToClipboard = function() {
   var text = this.getSelectionText();
-  if (text != null)
-    this.copyStringToClipboard(text);
+  if (text != null) this.copyStringToClipboard(text);
 };
 
 hterm.Terminal.prototype.overlaySize = function() {
@@ -13729,17 +13249,14 @@
   }
 
   // Make sure URL is valid before opening.
-  if (str.length > 2048 || str.search(/[\s\[\](){}<>"'\\^`]/) >= 0)
-    return;
+  if (str.length > 2048 || str.search(/[\s\[\](){}<>"'\\^`]/) >= 0) return;
   // If the URL 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)
-    str = 'http://' + str;
+  if (str.search('^[a-zA-Z][a-zA-Z0-9+.-]*://') < 0) str = 'http://' + str;
 
   this.openUrl(str);
 };
 
-
 /**
  * Add the terminalRow and terminalColumn properties to mouse events and
  * then forward on to onMouse().
@@ -13761,16 +13278,19 @@
     return;
   }
 
-  var reportMouseEvents = (!this.defeatMouseReports_ &&
-    this.vt.mouseReport != this.vt.MOUSE_REPORT_DISABLED);
+  var reportMouseEvents =
+      (!this.defeatMouseReports_ &&
+       this.vt.mouseReport != this.vt.MOUSE_REPORT_DISABLED);
 
   e.processedByTerminalHandler_ = true;
 
   // 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;
+  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.
@@ -13783,10 +13303,9 @@
     // 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) {
+        e.terminalColumn - 1 == this.screen_.cursorPosition.column) {
       this.cursorNode_.style.display = 'none';
-    }
-    else if (this.cursorNode_.style.display == 'none') {
+    } else if (this.cursorNode_.style.display == 'none') {
       this.cursorNode_.style.display = '';
     }
   }
@@ -13797,8 +13316,7 @@
       // alt-mousedown, then the mouse will act on the local selection.
       this.defeatMouseReports_ = true;
       this.setSelectionEnabled(true);
-    }
-    else {
+    } else {
       // Otherwise we defer ownership of the mouse to the VT.
       this.defeatMouseReports_ = false;
       this.document_.getSelection().collapseToEnd();
@@ -13818,28 +13336,26 @@
       // 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);
+      this.timeouts_.openUrl =
+          setTimeout(this.openSelectedUrl_.bind(this), 500);
       return;
     }
 
-    if (e.type == 'mousedown' && e.which == this.mousePasteButton)
-      this.paste();
+    if (e.type == 'mousedown' && e.which == this.mousePasteButton) this.paste();
 
     if (e.type == 'mouseup' && e.which == 1 && this.copyOnSelect &&
-      !this.document_.getSelection().isCollapsed) {
+        !this.document_.getSelection().isCollapsed) {
       this.copySelectionToClipboard(this.document_);
     }
 
     if ((e.type == 'mousemove' || e.type == 'mouseup') &&
-      this.scrollBlockerNode_.engaged) {
+        this.scrollBlockerNode_.engaged) {
       // Disengage the scroll-blocker after one of these events.
       this.scrollBlockerNode_.engaged = false;
       this.scrollBlockerNode_.style.top = '-99px';
     }
 
-  }
-  else /* if (this.reportMouseEvents) */ {
+  } 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
@@ -13847,8 +13363,7 @@
         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') {
+      } 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();
@@ -13885,8 +13400,7 @@
 hterm.Terminal.prototype.onFocusChange_ = function(focused) {
   this.cursorNode_.setAttribute('focus', focused);
   this.restyleCursor_();
-  if (focused === true)
-    this.closeBellNotifications_();
+  if (focused === true) this.closeBellNotifications_();
 };
 
 /**
@@ -13904,8 +13418,7 @@
 hterm.Terminal.prototype.onPaste_ = function(e) {
   var data = e.text.replace(/\n/mg, '\r');
   data = this.keyboard.encode(data);
-  if (this.options_.bracketedPaste)
-    data = '\x1b[200~' + data + '\x1b[201~';
+  if (this.options_.bracketedPaste) data = '\x1b[200~' + data + '\x1b[201~';
 
   this.io.sendString(data);
 };
@@ -13931,10 +13444,14 @@
  * 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;
+  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
@@ -13945,16 +13462,16 @@
     return;
   }
 
-  var isNewSize = (columnCount != this.screenSize.width ||
-    rowCount != this.screenSize.height);
+  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();
+  if (isNewSize) this.overlaySize();
 
   this.restyleCursor_();
   this.scheduleSyncCursorPosition_();
@@ -13970,15 +13487,14 @@
   }
 
   if (this.cursorNode_.getAttribute('focus') == 'false' ||
-    this.cursorNode_.style.opacity == '0') {
+      this.cursorNode_.style.opacity == '0') {
     this.cursorNode_.style.opacity = '1';
-    this.timeouts_.cursorBlink = setTimeout(this.myOnCursorBlink_,
-      this.cursorBlinkCycle_[0]);
-  }
-  else {
+    this.timeouts_.cursorBlink =
+        setTimeout(this.myOnCursorBlink_, this.cursorBlinkCycle_[0]);
+  } else {
     this.cursorNode_.style.opacity = '0';
-    this.timeouts_.cursorBlink = setTimeout(this.myOnCursorBlink_,
-      this.cursorBlinkCycle_[1]);
+    this.timeouts_.cursorBlink =
+        setTimeout(this.myOnCursorBlink_, this.cursorBlinkCycle_[1]);
   }
 };
 
@@ -14201,9 +13717,9 @@
  * @param {string} string The string to print.
  */
 hterm.Terminal.IO.prototype.print =
-  hterm.Terminal.IO.prototype.writeUTF16 = function(string) {
-    this.writeUTF8(lib.encodeUTF8(string));
-  };
+    hterm.Terminal.IO.prototype.writeUTF16 = function(string) {
+      this.writeUTF8(lib.encodeUTF8(string));
+    };
 
 /**
  * Print a UTF-16 JavaScript string to the terminal followed by a newline.
@@ -14211,9 +13727,9 @@
  * @param {string} string The string to print.
  */
 hterm.Terminal.IO.prototype.println =
-  hterm.Terminal.IO.prototype.writelnUTF16 = function(string) {
-    this.writelnUTF8(lib.encodeUTF8(string));
-  };
+    hterm.Terminal.IO.prototype.writelnUTF16 = function(string) {
+      this.writelnUTF8(lib.encodeUTF8(string));
+    };
 // 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
@@ -14294,7 +13810,6 @@
  */
 hterm.TextAttributes.prototype.SRC_DEFAULT = 'default';
 
-
 /**
  * A constant string used to specify that the source of a color is a valid
  * rgb( r, g, b) specifier.
@@ -14362,18 +13877,12 @@
  * @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.tileData == null);
+  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.tileData == null);
 };
 
 /**
@@ -14392,27 +13901,22 @@
  *     attributes.
  */
 hterm.TextAttributes.prototype.createContainer = function(opt_textContent) {
-  if (this.isDefault())
-    return this.document_.createTextNode(opt_textContent);
+  if (this.isDefault()) return this.document_.createTextNode(opt_textContent);
 
   var span = this.document_.createElement('span');
   var style = span.style;
   var classes = [];
 
-  if (this.foreground != this.DEFAULT_COLOR)
-    style.color = this.foreground;
+  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.enableBold && this.bold) style.fontWeight = 'bold';
 
-  if (this.faint)
-    span.faint = true;
+  if (this.faint) span.faint = true;
 
-  if (this.italic)
-    style.fontStyle = 'italic';
+  if (this.italic) style.fontStyle = 'italic';
 
   if (this.blink) {
     classes.push('blink-node');
@@ -14443,11 +13947,9 @@
     span.tileNode = true;
   }
 
-  if (opt_textContent)
-    span.textContent = opt_textContent;
+  if (opt_textContent) span.textContent = opt_textContent;
 
-  if (classes.length)
-    span.className = classes.join(' ');
+  if (classes.length) span.className = classes.join(' ');
 
   return span;
 };
@@ -14466,22 +13968,21 @@
  *     this attributes instance.
  */
 hterm.TextAttributes.prototype.matchesContainer = function(obj) {
-  if (typeof obj == 'string' || obj.nodeType == 3)
-    return this.isDefault();
+  if (typeof obj == 'string' || obj.nodeType == 3) 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.
-  return (!(this.wcNode || obj.wcNode) &&
-    !(this.tileData != null || obj.tileNode) &&
-    this.foreground == style.color &&
-    this.background == style.backgroundColor &&
-    (this.enableBold && this.bold) == !!style.fontWeight &&
-    this.blink == obj.blinkNode &&
-    this.italic == !!style.fontStyle &&
-    !!this.underline == !!obj.underline &&
-    !!this.strikethrough == !!obj.strikethrough);
+  return (
+      !(this.wcNode || obj.wcNode) &&
+      !(this.tileData != null || obj.tileNode) &&
+      this.foreground == style.color &&
+      this.background == style.backgroundColor &&
+      (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) {
@@ -14528,7 +14029,7 @@
 
   if (this.enableBoldAsBright && this.bold) {
     if (foregroundSource != this.SRC_DEFAULT &&
-      foregroundSource != this.SRC_RGB) {
+        foregroundSource != this.SRC_RGB) {
       foregroundSource = getBrightIndex(foregroundSource);
     }
   }
@@ -14540,19 +14041,24 @@
 
   // Set fore/background colors unless already specified in rgb(r, g, b) form.
   if (foregroundSource != this.SRC_RGB) {
-    this.foreground = ((foregroundSource == this.SRC_DEFAULT) ?
-      defaultForeground : this.colorPalette[foregroundSource]);
+    this.foreground =
+        ((foregroundSource == this.SRC_DEFAULT) ?
+             defaultForeground :
+             this.colorPalette[foregroundSource]);
   }
 
   if (this.faint && !this.invisible) {
-    var colorToMakeFaint = ((this.foreground == this.DEFAULT_COLOR) ?
-      this.defaultForeground : this.foreground);
+    var colorToMakeFaint =
+        ((this.foreground == this.DEFAULT_COLOR) ? this.defaultForeground :
+                                                   this.foreground);
     this.foreground = lib.colors.mix(colorToMakeFaint, 'rgb(0, 0, 0)', 0.3333);
   }
 
   if (backgroundSource != this.SRC_RGB) {
-    this.background = ((backgroundSource == this.SRC_DEFAULT) ?
-      defaultBackground : this.colorPalette[backgroundSource]);
+    this.background =
+        ((backgroundSource == this.SRC_DEFAULT) ?
+             defaultBackground :
+             this.colorPalette[backgroundSource]);
   }
 };
 
@@ -14570,20 +14076,19 @@
   if (typeof obj1 == 'string')
     return hterm.TextAttributes.containerIsDefault(obj2);
 
-  if (obj1.nodeType != obj2.nodeType)
-    return false;
+  if (obj1.nodeType != obj2.nodeType) return false;
 
-  if (obj1.nodeType == 3)
-    return true;
+  if (obj1.nodeType == 3) return true;
 
   var style1 = obj1.style;
   var style2 = obj2.style;
 
-  return (style1.color == style2.color &&
-    style1.backgroundColor == style2.backgroundColor &&
-    style1.fontWeight == style2.fontWeight &&
-    style1.fontStyle == style2.fontStyle &&
-    style1.textDecoration == style2.textDecoration);
+  return (
+      style1.color == style2.color &&
+      style1.backgroundColor == style2.backgroundColor &&
+      style1.fontWeight == style2.fontWeight &&
+      style1.fontStyle == style2.fontStyle &&
+      style1.textDecoration == style2.textDecoration);
 };
 
 /**
@@ -14608,8 +14113,7 @@
 hterm.TextAttributes.nodeWidth = function(node) {
   if (node.wcNode) {
     return lib.wc.strWidth(node.textContent);
-  }
-  else {
+  } else {
     return node.textContent.length;
   }
 };
@@ -14627,8 +14131,7 @@
 hterm.TextAttributes.nodeSubstr = function(node, start, width) {
   if (node.wcNode) {
     return lib.wc.substr(node.textContent, start, width);
-  }
-  else {
+  } else {
     return node.textContent.substr(start, width);
   }
 };
@@ -14646,8 +14149,7 @@
 hterm.TextAttributes.nodeSubstring = function(node, start, end) {
   if (node.wcNode) {
     return lib.wc.substring(node.textContent, start, end);
-  }
-  else {
+  } else {
     return node.textContent.substring(start, end);
   }
 };
@@ -14664,35 +14166,25 @@
  */
 hterm.TextAttributes.splitWidecharString = function(str) {
   var rv = [];
-  var base = 0,
-    length = 0;
+  var base = 0, length = 0;
 
   for (var i = 0; i < str.length;) {
     var c = str.codePointAt(i);
     var increment = (c <= 0xffff) ? 1 : 2;
     if (c < 128 || lib.wc.charWidth(c) == 1) {
       length += increment;
-    }
-    else {
+    } else {
       if (length) {
-        rv.push({
-          str: str.substr(base, length)
-        });
+        rv.push({str: str.substr(base, length)});
       }
-      rv.push({
-        str: str.substr(i, increment),
-        wcNode: true
-      });
+      rv.push({str: str.substr(i, increment), wcNode: true});
       base = i + increment;
       length = 0;
     }
     i += increment;
   }
 
-  if (length)
-    rv.push({
-      str: str.substr(base, length)
-    });
+  if (length) rv.push({str: str.substr(base, length)});
 
   return rv;
 };
@@ -14703,8 +14195,7 @@
 
 'use strict';
 
-lib.rtdep('lib.colors', 'lib.f', 'lib.UTF8Decoder',
-  'hterm.VT.CharacterMap');
+lib.rtdep('lib.colors', 'lib.f', 'lib.UTF8Decoder', 'hterm.VT.CharacterMap');
 
 /**
  * Constructor for the VT escape sequence interpreter.
@@ -14767,10 +14258,11 @@
   // 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.
-  var cc1 = Object.keys(hterm.VT.CC1).map(
-    function(e) {
-      return '\\x' + lib.f.zpad(e.charCodeAt().toString(16), 2);
-    }).join('');
+  var cc1 = Object.keys(hterm.VT.CC1)
+                .map(function(e) {
+                  return '\\x' + lib.f.zpad(e.charCodeAt().toString(16), 2);
+                })
+                .join('');
   this.cc1Pattern_ = new RegExp('[' + cc1 + ']');
 
   // Decoder to maintain UTF-8 decode state.
@@ -14921,8 +14413,7 @@
  */
 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;
+  if (typeof opt_arg_zero != 'undefined') this.args[0] = opt_arg_zero;
 };
 
 /**
@@ -14935,8 +14426,7 @@
   if (str) {
     var ret = parseInt(str, 10);
     // An argument of zero is treated as the default value.
-    if (ret == 0)
-      ret = defaultValue;
+    if (ret == 0) ret = defaultValue;
     return ret;
   }
   return defaultValue;
@@ -15041,20 +14531,16 @@
  * See the "Mouse Tracking" section of [xterm].
  */
 hterm.VT.prototype.onTerminalMouse_ = function(e) {
-  if (this.mouseReport == this.MOUSE_REPORT_DISABLED)
-    return;
+  if (this.mouseReport == this.MOUSE_REPORT_DISABLED) return;
 
   // Temporary storage for our response.
   var response;
 
   // Modifier key state.
   var mod = 0;
-  if (e.shiftKey)
-    mod |= 4;
-  if (e.metaKey || (this.terminal.keyboard.altIsMeta && e.altKey))
-    mod |= 8;
-  if (e.ctrlKey)
-    mod |= 16;
+  if (e.shiftKey) mod |= 4;
+  if (e.metaKey || (this.terminal.keyboard.altIsMeta && e.altKey)) mod |= 8;
+  if (e.ctrlKey) mod |= 16;
 
   // TODO(rginda): We should also support mode 1005 and/or 1006 to extend the
   // coordinate space.  Though, after poking around just a little, I wasn't
@@ -15113,8 +14599,7 @@
       break;
   }
 
-  if (response)
-    this.terminal.io.sendString(response);
+  if (response) this.terminal.io.sendString(response);
 };
 
 /**
@@ -15134,7 +14619,7 @@
     this.parseState_.func.call(this, this.parseState_);
 
     if (this.parseState_.func == func && this.parseState_.pos == pos &&
-      this.parseState_.buf == buf) {
+        this.parseState_.buf == buf) {
       throw 'Parser did not alter the state!';
     }
   }
@@ -15144,8 +14629,7 @@
  * Decode a string according to the 'receive-encoding' preference.
  */
 hterm.VT.prototype.decode = function(str) {
-  if (this.characterEncoding == 'utf-8')
-    return this.decodeUTF8(str);
+  if (this.characterEncoding == 'utf-8') return this.decodeUTF8(str);
 
   return str;
 };
@@ -15177,11 +14661,9 @@
   var self = this;
 
   function print(str) {
-    if (self[self.GL].GL)
-      str = self[self.GL].GL(str);
+    if (self[self.GL].GL) str = self[self.GL].GL(str);
 
-    if (self[self.GR].GR)
-      str = self[self.GR].GR(str);
+    if (self[self.GR].GR) str = self[self.GR].GR(str);
 
     self.terminal.print(str);
   };
@@ -15220,19 +14702,17 @@
 
   if (ch >= '@' && ch <= '~') {
     // This is the final character.
-    this.dispatch('CSI', this.leadingModifier_ + this.trailingModifier_ + ch,
-      parseState);
+    this.dispatch(
+        'CSI', this.leadingModifier_ + this.trailingModifier_ + ch, parseState);
     parseState.resetParseFunction();
 
-  }
-  else if (ch == ';') {
+  } else if (ch == ';') {
     // Parameter delimiter.
     if (this.trailingModifier_) {
       // Parameter delimiter after the trailing modifier.  That's a paddlin'.
       parseState.resetParseFunction();
 
-    }
-    else {
+    } else {
       if (!args.length) {
         // They omitted the first param, we need to supply it.
         args.push('');
@@ -15241,40 +14721,33 @@
       args.push('');
     }
 
-  }
-  else if (ch >= '0' && ch <= '9') {
+  } else if (ch >= '0' && ch <= '9') {
     // Next byte in the current parameter.
 
     if (this.trailingModifier_) {
       // Numeric parameter after the trailing modifier.  That's a paddlin'.
       parseState.resetParseFunction();
-    }
-    else {
+    } else {
       if (!args.length) {
         args[0] = ch;
-      }
-      else {
+      } else {
         args[args.length - 1] += ch;
       }
     }
 
-  }
-  else if (ch >= ' ' && ch <= '?' && ch != ':') {
+  } else if (ch >= ' ' && ch <= '?' && ch != ':') {
     // Modifier character.
     if (!args.length) {
       this.leadingModifier_ += ch;
-    }
-    else {
+    } else {
       this.trailingModifier_ += ch;
     }
 
-  }
-  else if (this.cc1Pattern_.test(ch)) {
+  } else if (this.cc1Pattern_.test(ch)) {
     // Control character.
     this.dispatch('CC1', ch, parseState);
 
-  }
-  else {
+  } else {
     // Unexpected character in sequence, bail out.
     parseState.resetParseFunction();
   }
@@ -15325,8 +14798,8 @@
       abortReason = 'timeout expired: ' + new Date() - args[1];
 
     if (abortReason) {
-      console.log('parseUntilStringTerminator_: aborting: ' + abortReason,
-        args[0]);
+      console.log(
+          'parseUntilStringTerminator_: aborting: ' + abortReason, args[0]);
       parseState.reset(args[0]);
       return false;
     }
@@ -15344,8 +14817,8 @@
   args[0] += buf.substr(0, nextTerminator);
 
   parseState.resetParseFunction();
-  parseState.advance(nextTerminator +
-    (buf.substr(nextTerminator, 1) == '\x1b' ? 2 : 1));
+  parseState.advance(
+      nextTerminator + (buf.substr(nextTerminator, 1) == '\x1b' ? 2 : 1));
 
   return true;
 };
@@ -15376,8 +14849,8 @@
     // 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));
+    console.warn(
+        'Ignoring 8-bit control code: 0x' + code.charCodeAt(0).toString(16));
     return;
   }
 
@@ -15400,11 +14873,9 @@
 hterm.VT.prototype.setANSIMode = function(code, state) {
   if (code == '4') {
     this.terminal.setInsertMode(state);
-  }
-  else if (code == '20') {
+  } else if (code == '20') {
     this.terminal.setAutoCarriageReturn(state);
-  }
-  else if (this.warnUnimplemented) {
+  } else if (this.warnUnimplemented) {
     console.warn('Unimplemented ANSI Mode: ' + code);
   }
 };
@@ -15478,11 +14949,11 @@
  */
 hterm.VT.prototype.setDECMode = function(code, state) {
   switch (code) {
-    case '1': // DECCKM
+    case '1':  // DECCKM
       this.terminal.keyboard.applicationCursor = state;
       break;
 
-    case '3': // DECCOLM
+    case '3':  // DECCOLM
       if (this.allowColumnWidthChanges_) {
         this.terminal.setWidth(state ? 132 : 80);
 
@@ -15491,98 +14962,95 @@
       }
       break;
 
-    case '5': // DECSCNM
+    case '5':  // DECSCNM
       this.terminal.setReverseVideo(state);
       break;
 
-    case '6': // DECOM
+    case '6':  // DECOM
       this.terminal.setOriginMode(state);
       break;
 
-    case '7': // DECAWM
+    case '7':  // DECAWM
       this.terminal.setWraparound(state);
       break;
 
-    case '12': // att610
-      if (this.enableDec12)
-        this.terminal.setCursorBlink(state);
+    case '12':  // att610
+      if (this.enableDec12) this.terminal.setCursorBlink(state);
       break;
 
-    case '25': // DECTCEM
+    case '25':  // DECTCEM
       this.terminal.setCursorVisible(state);
       break;
 
-    case '40': // no-spec
+    case '40':  // no-spec
       this.terminal.allowColumnWidthChanges_ = state;
       break;
 
-    case '45': // no-spec
+    case '45':  // no-spec
       this.terminal.setReverseWraparound(state);
       break;
 
-    case '67': // DECBKM
+    case '67':  // DECBKM
       this.terminal.keyboard.backspaceSendsBackspace = state;
       break;
 
-    case '1000': // Report on mouse clicks only.
-      this.mouseReport = (
-        state ? this.MOUSE_REPORT_CLICK : this.MOUSE_REPORT_DISABLED);
+    case '1000':  // Report on mouse clicks only.
+      this.mouseReport =
+          (state ? this.MOUSE_REPORT_CLICK : this.MOUSE_REPORT_DISABLED);
       break;
 
-    case '1002': // Report on mouse clicks and drags
-      this.mouseReport = (
-        state ? this.MOUSE_REPORT_DRAG : this.MOUSE_REPORT_DISABLED);
+    case '1002':  // Report on mouse clicks and drags
+      this.mouseReport =
+          (state ? this.MOUSE_REPORT_DRAG : this.MOUSE_REPORT_DISABLED);
       break;
 
-    case '1010': // rxvt
+    case '1010':  // rxvt
       this.terminal.scrollOnOutput = state;
       break;
 
-    case '1011': // rxvt
+    case '1011':  // rxvt
       this.terminal.scrollOnKeystroke = state;
       break;
 
-    case '1036': // no-spec
+    case '1036':  // no-spec
       this.terminal.keyboard.metaSendsEscape = state;
       break;
 
-    case '1039': // no-spec
+    case '1039':  // no-spec
       if (state) {
         if (!this.terminal.keyboard.previousAltSendsWhat_) {
           this.terminal.keyboard.previousAltSendsWhat_ =
-            this.terminal.keyboard.altSendsWhat;
+              this.terminal.keyboard.altSendsWhat;
           this.terminal.keyboard.altSendsWhat = 'escape';
         }
-      }
-      else if (this.terminal.keyboard.previousAltSendsWhat_) {
+      } else if (this.terminal.keyboard.previousAltSendsWhat_) {
         this.terminal.keyboard.altSendsWhat =
-          this.terminal.keyboard.previousAltSendsWhat_;
+            this.terminal.keyboard.previousAltSendsWhat_;
         this.terminal.keyboard.previousAltSendsWhat_ = null;
       }
       break;
 
     case '47':
-    case '1047': // no-spec
+    case '1047':  // no-spec
       this.terminal.setAlternateMode(state);
       break;
 
-    case '1048': // Save cursor as in DECSC.
+    case '1048':  // Save cursor as in DECSC.
       this.savedState_.save();
 
-    case '1049': // 1047 + 1048 + clear.
+    case '1049':  // 1047 + 1048 + clear.
       if (state) {
         this.savedState_.save();
         this.terminal.setAlternateMode(state);
         this.terminal.clear();
-      }
-      else {
+      } else {
         this.terminal.setAlternateMode(state);
         this.savedState_.restore();
       }
 
       break;
 
-    case '2004': // Bracketed paste mode.
+    case '2004':  // Bracketed paste mode.
       this.terminal.setBracketedPaste(state);
       break;
 
@@ -15786,13 +15254,11 @@
   function parseESC(parseState) {
     var ch = parseState.consumeChar();
 
-    if (ch == '\x1b')
-      return;
+    if (ch == '\x1b') return;
 
     this.dispatch('ESC', ch, parseState);
 
-    if (parseState.func == parseESC)
-      parseState.resetParseFunction();
+    if (parseState.func == parseESC) parseState.resetParseFunction();
   };
 
   parseState.func = parseESC;
@@ -15810,39 +15276,35 @@
  *
  * Like newline, only keep the X position
  */
-hterm.VT.CC1['\x84'] =
-  hterm.VT.ESC['D'] = function() {
-    this.terminal.lineFeed();
-  };
+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);
-  };
+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());
-  };
+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();
-  };
+hterm.VT.CC1['\x8d'] = hterm.VT.ESC['M'] = function() {
+  this.terminal.reverseLineFeed();
+};
 
 /**
  * Single Shift 2 (SS2).
@@ -15851,8 +15313,7 @@
  *
  * Not currently implemented.
  */
-hterm.VT.CC1['\x8e'] =
-  hterm.VT.ESC['N'] = hterm.VT.ignore;
+hterm.VT.CC1['\x8e'] = hterm.VT.ESC['N'] = hterm.VT.ignore;
 
 /**
  * Single Shift 3 (SS3).
@@ -15861,8 +15322,7 @@
  *
  * Not currently implemented.
  */
-hterm.VT.CC1['\x8f'] =
-  hterm.VT.ESC['O'] = hterm.VT.ignore;
+hterm.VT.CC1['\x8f'] = hterm.VT.ESC['O'] = hterm.VT.ignore;
 
 /**
  * Device Control String (DCS).
@@ -15872,58 +15332,52 @@
  *
  * 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_;
-  };
+hterm.VT.CC1['\x90'] = hterm.VT.ESC['P'] = function(parseState) {
+  parseState.resetArguments();
+  parseState.func = this.parseUntilStringTerminator_;
+};
 
 /**
  * Start of Protected Area (SPA).
  *
  * Will not implement.
  */
-hterm.VT.CC1['\x96'] =
-  hterm.VT.ESC['V'] = hterm.VT.ignore;
+hterm.VT.CC1['\x96'] = hterm.VT.ESC['V'] = hterm.VT.ignore;
 
 /**
  * End of Protected Area (EPA).
  *
  * Will not implement.
  */
-hterm.VT.CC1['\x97'] =
-  hterm.VT.ESC['W'] = hterm.VT.ignore;
+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;
+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');
-  };
+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_;
-  };
+hterm.VT.CC1['\x9b'] = hterm.VT.ESC['['] = function(parseState) {
+  parseState.resetArguments();
+  this.leadingModifier_ = '';
+  this.trailingModifier_ = '';
+  parseState.func = this.parseCSI_;
+};
 
 /**
  * String Terminator (ST).
@@ -15933,64 +15387,59 @@
  * 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;
+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();
+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;
-      }
+  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;
-      }
+    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]));
-      }
-    };
-
-    parseState.func = parseOSC;
+    // 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]));
+    }
   };
 
+  parseState.func = parseOSC;
+};
+
 /**
  * Privacy Message (PM).
  *
  * Will not implement.
  */
-hterm.VT.CC1['\x9e'] =
-  hterm.VT.ESC['^'] = function(parseState) {
-    parseState.resetArguments();
-    parseState.func = this.parseUntilStringTerminator_;
-  };
+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_;
-  };
+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.
@@ -16030,8 +15479,7 @@
 hterm.VT.ESC['#'] = function(parseState) {
   parseState.func = function(parseState) {
     var ch = parseState.consumeChar();
-    if (ch == '8')
-      this.terminal.fill('E');
+    if (ch == '8') this.terminal.fill('E');
 
     parseState.resetParseFunction();
   };
@@ -16087,42 +15535,34 @@
  *
  * TODO(rginda): Implement.
  */
-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;
-      }
+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;
+            }
 
-      if (ch in hterm.VT.CharacterMap.maps) {
-        if (code == '(') {
-          this.G0 = hterm.VT.CharacterMap.maps[ch];
-        }
-        else if (code == ')' || code == '-') {
-          this.G1 = hterm.VT.CharacterMap.maps[ch];
-        }
-        else if (code == '*' || code == '.') {
-          this.G2 = hterm.VT.CharacterMap.maps[ch];
-        }
-        else if (code == '+' || code == '/') {
-          this.G3 = hterm.VT.CharacterMap.maps[ch];
-        }
-      }
-      else if (this.warnUnimplemented) {
-        console.log('Invalid character set for "' + code + '": ' + ch);
-      }
+            if (ch in hterm.VT.CharacterMap.maps) {
+              if (code == '(') {
+                this.G0 = hterm.VT.CharacterMap.maps[ch];
+              } else if (code == ')' || code == '-') {
+                this.G1 = hterm.VT.CharacterMap.maps[ch];
+              } else if (code == '*' || code == '.') {
+                this.G2 = hterm.VT.CharacterMap.maps[ch];
+              } else if (code == '+' || code == '/') {
+                this.G3 = hterm.VT.CharacterMap.maps[ch];
+              }
+            } else if (this.warnUnimplemented) {
+              console.log('Invalid character set for "' + code + '": ' + ch);
+            }
 
-      parseState.resetParseFunction();
-    };
-  };
+            parseState.resetParseFunction();
+          };
+        };
 
 /**
  * Back Index (DECBI).
@@ -16189,8 +15629,7 @@
  *
  * Will not implement.
  */
-hterm.VT.ESC['l'] =
-  hterm.VT.ESC['m'] = hterm.VT.ignore;
+hterm.VT.ESC['l'] = hterm.VT.ESC['m'] = hterm.VT.ignore;
 
 /**
  * Lock Shift 2 (LS2)
@@ -16267,21 +15706,18 @@
     var colorIndex = parseInt(args[pairNumber * 2]);
     var colorValue = args[pairNumber * 2 + 1];
 
-    if (colorIndex >= colorPalette.length)
-      continue;
+    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);
+      if (colorValue) responseArray.push(colorIndex + ';' + colorValue);
 
       continue;
     }
 
     colorValue = lib.colors.x11ToCSS(colorValue);
-    if (colorValue)
-      colorPalette[colorIndex] = colorValue;
+    if (colorValue) colorPalette[colorIndex] = colorValue;
   }
 
   if (responseArray.length)
@@ -16339,12 +15775,10 @@
   // 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;
+  if (!args) return;
 
   var data = window.atob(args[1]);
-  if (data)
-    this.terminal.copyStringToClipboard(this.decode(data));
+  if (data) this.terminal.copyStringToClipboard(this.decode(data));
 };
 
 /**
@@ -16415,8 +15849,8 @@
  * Cursor Position (CUP).
  */
 hterm.VT.CSI['H'] = function(parseState) {
-  this.terminal.setCursorPosition(parseState.iarg(0, 1) - 1,
-    parseState.iarg(1, 1) - 1);
+  this.terminal.setCursorPosition(
+      parseState.iarg(0, 1) - 1, parseState.iarg(1, 1) - 1);
 };
 
 /**
@@ -16433,43 +15867,36 @@
 /**
  * Erase in Display (ED, DECSED).
  */
-hterm.VT.CSI['J'] =
-  hterm.VT.CSI['?J'] = function(parseState, code) {
-    var arg = parseState.args[0];
+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') {
-      // The xterm docs say this means "Erase saved lines", but we'll just clear
-      // the display since killing the scrollback seems rude.
-      this.terminal.clear();
-    }
-  };
+  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') {
+    // The xterm docs say this means "Erase saved lines", but we'll just clear
+    // the display since killing the scrollback seems rude.
+    this.terminal.clear();
+  }
+};
 
 /**
  * Erase in line (EL, DECSEL).
  */
-hterm.VT.CSI['K'] =
-  hterm.VT.CSI['?K'] = function(parseState, code) {
-    var arg = parseState.args[0];
+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();
-    }
-  };
+  if (!arg || arg == '0') {
+    this.terminal.eraseToRight();
+  } else if (arg == '1') {
+    this.terminal.eraseToLeft();
+  } else if (arg == '2') {
+    this.terminal.eraseLine();
+  }
+};
 
 /**
  * Insert Lines (IL).
@@ -16606,8 +16033,7 @@
   if (!parseState.args[0] || parseState.args[0] == '0') {
     // Clear tab stop at cursor.
     this.terminal.clearTabStopAtCursor(false);
-  }
-  else if (parseState.args[0] == '3') {
+  } else if (parseState.args[0] == '3') {
     // Clear all tab stops.
     this.terminal.clearAllTabStops();
   }
@@ -16637,8 +16063,7 @@
  *
  * These commands control the printer.  Will not implement.
  */
-hterm.VT.CSI['i'] =
-  hterm.VT.CSI['?i'] = hterm.VT.ignore;
+hterm.VT.CSI['i'] = hterm.VT.CSI['?i'] = hterm.VT.ignore;
 
 /**
  * Reset Mode (RM).
@@ -16766,64 +16191,47 @@
     if (arg < 30) {
       if (arg == 0) {
         attrs.reset();
-      }
-      else if (arg == 1) {
+      } else if (arg == 1) {
         attrs.bold = true;
-      }
-      else if (arg == 2) {
+      } else if (arg == 2) {
         attrs.faint = true;
-      }
-      else if (arg == 3) {
+      } else if (arg == 3) {
         attrs.italic = true;
-      }
-      else if (arg == 4) {
+      } else if (arg == 4) {
         attrs.underline = true;
-      }
-      else if (arg == 5) {
+      } else if (arg == 5) {
         attrs.blink = true;
-      }
-      else if (arg == 7) { // Inverse.
+      } else if (arg == 7) {  // Inverse.
         attrs.inverse = true;
-      }
-      else if (arg == 8) { // Invisible.
+      } else if (arg == 8) {  // Invisible.
         attrs.invisible = true;
-      }
-      else if (arg == 9) {
+      } else if (arg == 9) {
         attrs.strikethrough = true;
-      }
-      else if (arg == 22) {
+      } else if (arg == 22) {
         attrs.bold = false;
         attrs.faint = false;
-      }
-      else if (arg == 23) {
+      } else if (arg == 23) {
         attrs.italic = false;
-      }
-      else if (arg == 24) {
+      } else if (arg == 24) {
         attrs.underline = false;
-      }
-      else if (arg == 25) {
+      } else if (arg == 25) {
         attrs.blink = false;
-      }
-      else if (arg == 27) {
+      } else if (arg == 27) {
         attrs.inverse = false;
-      }
-      else if (arg == 28) {
+      } else if (arg == 28) {
         attrs.invisible = false;
-      }
-      else if (arg == 29) {
+      } else if (arg == 29) {
         attrs.strikethrough = false;
       }
 
-    }
-    else if (arg < 50) {
+    } 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) {
+      } else if (arg == 38) {
         // First check for true color definition
         var trueColor = getTrueColor(i);
         if (trueColor != null) {
@@ -16831,31 +16239,25 @@
           attrs.foreground = trueColor;
 
           i += 5;
-        }
-        else {
+        } else {
           // Check for 256 color
           var c = get256(i);
-          if (c == null)
-            break;
+          if (c == null) break;
 
           i += 2;
 
-          if (c >= attrs.colorPalette.length)
-            continue;
+          if (c >= attrs.colorPalette.length) continue;
 
           attrs.foregroundSource = c;
         }
 
-      }
-      else if (arg == 39) {
+      } else if (arg == 39) {
         attrs.foregroundSource = attrs.SRC_DEFAULT;
 
-      }
-      else if (arg < 48) {
+      } else if (arg < 48) {
         attrs.backgroundSource = arg - 40;
 
-      }
-      else if (arg == 48) {
+      } else if (arg == 48) {
         // First check for true color definition
         var trueColor = getTrueColor(i);
         if (trueColor != null) {
@@ -16863,37 +16265,31 @@
           attrs.background = trueColor;
 
           i += 5;
-        }
-        else {
+        } else {
           // Check for 256 color
           var c = get256(i);
-          if (c == null)
-            break;
+          if (c == null) break;
 
           i += 2;
 
-          if (c >= attrs.colorPalette.length)
-            continue;
+          if (c >= attrs.colorPalette.length) continue;
 
           attrs.backgroundSource = c;
         }
-      }
-      else {
+      } else {
         attrs.backgroundSource = attrs.SRC_DEFAULT;
       }
 
-    }
-    else if (arg >= 90 && arg <= 97) {
+    } else if (arg >= 90 && arg <= 97) {
       attrs.foregroundSource = arg - 90 + 8;
 
-    }
-    else if (arg >= 100 && arg <= 107) {
+    } else if (arg >= 100 && arg <= 107) {
       attrs.backgroundSource = arg - 100 + 8;
     }
   }
 
-  attrs.setDefaults(this.terminal.getForegroundColor(),
-    this.terminal.getBackgroundColor());
+  attrs.setDefaults(
+      this.terminal.getForegroundColor(), this.terminal.getBackgroundColor());
 };
 
 /**
@@ -16912,8 +16308,7 @@
 hterm.VT.CSI['n'] = function(parseState) {
   if (parseState.args[0] == '5') {
     this.terminal.io.sendString('\x1b0n');
-  }
-  else if (parseState.args[0] == '6') {
+  } 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');
@@ -16945,17 +16340,13 @@
     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') {
+  } else if (parseState.args[0] == '15') {
     this.terminal.io.sendString('\x1b[?11n');
-  }
-  else if (parseState.args[0] == '25') {
+  } else if (parseState.args[0] == '25') {
     this.terminal.io.sendString('\x1b[?21n');
-  }
-  else if (parseState.args[0] == '26') {
+  } else if (parseState.args[0] == '26') {
     this.terminal.io.sendString('\x1b[?12;1;0;0n');
-  }
-  else if (parseState.args[0] == '53') {
+  } else if (parseState.args[0] == '53') {
     this.terminal.io.sendString('\x1b[?50n');
   }
 };
@@ -17021,20 +16412,16 @@
   if (arg == '0' || arg == '1') {
     this.terminal.setCursorShape(hterm.Terminal.cursorShape.BLOCK);
     this.terminal.setCursorBlink(true);
-  }
-  else if (arg == '2') {
+  } else if (arg == '2') {
     this.terminal.setCursorShape(hterm.Terminal.cursorShape.BLOCK);
     this.terminal.setCursorBlink(false);
-  }
-  else if (arg == '3') {
+  } else if (arg == '3') {
     this.terminal.setCursorShape(hterm.Terminal.cursorShape.UNDERLINE);
     this.terminal.setCursorBlink(true);
-  }
-  else if (arg == '4') {
+  } else if (arg == '4') {
     this.terminal.setCursorShape(hterm.Terminal.cursorShape.UNDERLINE);
     this.terminal.setCursorBlink(false);
-  }
-  else {
+  } else {
     console.warn('Unknown cursor style: ' + arg);
   }
 };
@@ -17169,16 +16556,13 @@
  * 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;
+  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;
+    if (parseState.args.length < 2) return;
     this.terminal.getTextAttributes().tileData = parseState.args[1];
-  }
-  else if (arg == '1') {
+  } else if (arg == '1') {
     // End a glyph.
     this.terminal.getTextAttributes().tileData = null;
   }
@@ -17256,8 +16640,7 @@
    */
   this.GR = null;
 
-  if (glmap)
-    this.reset(glmap);
+  if (glmap) this.reset(glmap);
 };
 
 /**
@@ -17290,17 +16673,15 @@
   this.grre = new RegExp('[' + grkeys.join('') + ']', 'g');
 
   this.GL = function(str) {
-    return str.replace(this.glre,
-      function(ch) {
-        return this.glmap[ch];
-      }.bind(this));
+    return str.replace(this.glre, function(ch) {
+      return this.glmap[ch];
+    }.bind(this));
   }.bind(this);
 
   this.GR = function(str) {
-    return str.replace(this.grre,
-      function(ch) {
-        return this.grmap[ch];
-      }.bind(this));
+    return str.replace(this.grre, function(ch) {
+      return this.grmap[ch];
+    }.bind(this));
   }.bind(this);
 };
 
@@ -17314,409 +16695,396 @@
  * VT100 Graphic character map.
  * http://vt100.net/docs/vt220-rm/table2-4.html
  */
-hterm.VT.CharacterMap.maps['0'] = new hterm.VT.CharacterMap(
-  'graphic', {
-    '`': '◆', // ` -> diamond
-    'a': '▒', // a -> grey-box
-    'b': '␉', // b -> h/t
-    'c': '␌', // c -> f/f
-    'd': '␍', // d -> c/r
-    'e': '␊', // e -> l/f
-    'f': '°', // f -> degree
-    'g': '±', // g -> +/-
-    'h': '␤', // h -> n/l
-    'i': '␋', // i -> v/t
-    'j': '┘', // j -> bottom-right
-    'k': '┐', // k -> top-right
-    'l': '┌', // l -> top-left
-    'm': '└', // m -> bottom-left
-    'n': '┼', // n -> line-cross
-    'o': '⎺', // o -> scan1
-    'p': '⎻', // p -> scan3
-    'q': '─', // q -> scan5
-    'r': '⎼', // r -> scan7
-    's': '⎽', // s -> scan9
-    't': '├', // t -> left-tee
-    'u': '┤', // u -> right-tee
-    'v': '┴', // v -> bottom-tee
-    'w': '┬', // w -> top-tee
-    'x': '│', // x -> vertical-line
-    'y': '≤', // y -> less-equal
-    'z': '≥', // z -> greater-equal
-    '{': 'π', // { -> pi
-    '|': '≠', // | -> not-equal
-    '}': '£', // } -> british-pound
-    '~': '·', // ~ -> dot
-  });
+hterm.VT.CharacterMap.maps['0'] = new hterm.VT.CharacterMap('graphic', {
+  '`': '◆',  // ` -> diamond
+  'a': '▒',  // a -> grey-box
+  'b': '␉',  // b -> h/t
+  'c': '␌',  // c -> f/f
+  'd': '␍',  // d -> c/r
+  'e': '␊',  // e -> l/f
+  'f': '°',  // f -> degree
+  'g': '±',  // g -> +/-
+  'h': '␤',  // h -> n/l
+  'i': '␋',  // i -> v/t
+  'j': '┘',  // j -> bottom-right
+  'k': '┐',  // k -> top-right
+  'l': '┌',  // l -> top-left
+  'm': '└',  // m -> bottom-left
+  'n': '┼',  // n -> line-cross
+  'o': '⎺',  // o -> scan1
+  'p': '⎻',  // p -> scan3
+  'q': '─',  // q -> scan5
+  'r': '⎼',  // r -> scan7
+  's': '⎽',  // s -> scan9
+  't': '├',  // t -> left-tee
+  'u': '┤',  // u -> right-tee
+  'v': '┴',  // v -> bottom-tee
+  'w': '┬',  // w -> top-tee
+  'x': '│',  // x -> vertical-line
+  'y': '≤',  // y -> less-equal
+  'z': '≥',  // z -> greater-equal
+  '{': 'π',  // { -> pi
+  '|': '≠',  // | -> not-equal
+  '}': '£',  // } -> british-pound
+  '~': '·',  // ~ -> dot
+});
 
 /**
  * British character map.
  * http://vt100.net/docs/vt220-rm/table2-5.html
  */
-hterm.VT.CharacterMap.maps['A'] = new hterm.VT.CharacterMap(
-  'british', {
-    '#': '£', // # -> british-pound
-  });
+hterm.VT.CharacterMap.maps['A'] = new hterm.VT.CharacterMap('british', {
+  '#': '£',  // # -> british-pound
+});
 
 /**
  * US ASCII map, no changes.
  */
-hterm.VT.CharacterMap.maps['B'] = new hterm.VT.CharacterMap(
-  'us', null);
+hterm.VT.CharacterMap.maps['B'] = new hterm.VT.CharacterMap('us', null);
 
 /**
  * Dutch character map.
  * http://vt100.net/docs/vt220-rm/table2-6.html
  */
-hterm.VT.CharacterMap.maps['4'] = new hterm.VT.CharacterMap(
-  'dutch', {
-    '#': '£', // # -> british-pound
+hterm.VT.CharacterMap.maps['4'] = new hterm.VT.CharacterMap('dutch', {
+  '#': '£',  // # -> british-pound
 
-    '@': '¾', // @ -> 3/4
+  '@': '¾',  // @ -> 3/4
 
-    '[': 'IJ', // [ -> 'ij' ligature (xterm goes with \u00ff?)
-    '\\': '½', // \ -> 1/2
-    ']': '|', // ] -> vertical bar
+  '[': 'IJ',   // [ -> 'ij' ligature (xterm goes with \u00ff?)
+  '\\': '½',  // \ -> 1/2
+  ']': '|',   // ] -> vertical bar
 
-    '{': '¨', // { -> two dots
-    '|': 'f', // | -> f
-    '}': '¼', // } -> 1/4
-    '~': '´', // ~ -> acute
-  });
+  '{': '¨',  // { -> two dots
+  '|': 'f',  // | -> f
+  '}': '¼',  // } -> 1/4
+  '~': '´',  // ~ -> acute
+});
 
 /**
  * Finnish character map.
  * http://vt100.net/docs/vt220-rm/table2-7.html
  */
-hterm.VT.CharacterMap.maps['C'] =
-  hterm.VT.CharacterMap.maps['5'] = new hterm.VT.CharacterMap(
-    'finnish', {
-      '[': 'Ä', // [ -> 'A' umlaut
-      '\\': 'Ö', // \ -> 'O' umlaut
-      ']': 'Å', // ] -> 'A' ring
-      '^': 'Ü', // ~ -> 'u' umlaut
+hterm.VT.CharacterMap.maps['C'] = hterm.VT.CharacterMap.maps['5'] =
+    new hterm.VT.CharacterMap('finnish', {
+      '[': 'Ä',   // [ -> 'A' umlaut
+      '\\': 'Ö',  // \ -> 'O' umlaut
+      ']': 'Å',   // ] -> 'A' ring
+      '^': 'Ü',   // ~ -> 'u' umlaut
 
-      '`': 'é', // ` -> 'e' acute
+      '`': 'é',  // ` -> 'e' acute
 
-      '{': 'ä', // { -> 'a' umlaut
-      '|': 'ö', // | -> 'o' umlaut
-      '}': 'å', // } -> 'a' ring
-      '~': 'ü', // ~ -> 'u' umlaut
+      '{': 'ä',  // { -> 'a' umlaut
+      '|': 'ö',  // | -> 'o' umlaut
+      '}': 'å',  // } -> 'a' ring
+      '~': 'ü',  // ~ -> 'u' umlaut
     });
 
 /**
  * French character map.
  * http://vt100.net/docs/vt220-rm/table2-8.html
  */
-hterm.VT.CharacterMap.maps['R'] = new hterm.VT.CharacterMap(
-  'french', {
-    '#': '£', // # -> british-pound
+hterm.VT.CharacterMap.maps['R'] = new hterm.VT.CharacterMap('french', {
+  '#': '£',  // # -> british-pound
 
-    '@': 'à', // @ -> 'a' grave
+  '@': 'à',  // @ -> 'a' grave
 
-    '[': '°', // [ -> ring
-    '\\': 'ç', // \ -> 'c' cedilla
-    ']': '§', // ] -> section symbol (double s)
+  '[': '°',   // [ -> ring
+  '\\': 'ç',  // \ -> 'c' cedilla
+  ']': '§',   // ] -> section symbol (double s)
 
-    '{': 'é', // { -> 'e' acute
-    '|': 'ù', // | -> 'u' grave
-    '}': 'è', // } -> 'e' grave
-    '~': '¨', // ~ -> umlaut
-  });
+  '{': 'é',  // { -> 'e' acute
+  '|': 'ù',  // | -> 'u' grave
+  '}': 'è',  // } -> 'e' grave
+  '~': '¨',  // ~ -> umlaut
+});
 
 /**
  * French Canadian character map.
  * http://vt100.net/docs/vt220-rm/table2-9.html
  */
-hterm.VT.CharacterMap.maps['Q'] = new hterm.VT.CharacterMap(
-  'french canadian', {
-    '@': 'à', // @ -> 'a' grave
+hterm.VT.CharacterMap.maps['Q'] = new hterm.VT.CharacterMap('french canadian', {
+  '@': 'à',  // @ -> 'a' grave
 
-    '[': 'â', // [ -> 'a' circumflex
-    '\\': 'ç', // \ -> 'c' cedilla
-    ']': 'ê', // ] -> 'e' circumflex
-    '^': 'î', // ^ -> 'i' circumflex
+  '[': 'â',   // [ -> 'a' circumflex
+  '\\': 'ç',  // \ -> 'c' cedilla
+  ']': 'ê',   // ] -> 'e' circumflex
+  '^': 'î',   // ^ -> 'i' circumflex
 
-    '`': 'ô', // ` -> 'o' circumflex
+  '`': 'ô',  // ` -> 'o' circumflex
 
-    '{': 'é', // { -> 'e' acute
-    '|': 'ù', // | -> 'u' grave
-    '}': 'è', // } -> 'e' grave
-    '~': 'û', // ~ -> 'u' circumflex
-  });
+  '{': 'é',  // { -> 'e' acute
+  '|': 'ù',  // | -> 'u' grave
+  '}': 'è',  // } -> 'e' grave
+  '~': 'û',  // ~ -> 'u' circumflex
+});
 
 /**
  * German character map.
  * http://vt100.net/docs/vt220-rm/table2-10.html
  */
-hterm.VT.CharacterMap.maps['K'] = new hterm.VT.CharacterMap(
-  'german', {
-    '@': '§', // @ -> section symbol (double s)
+hterm.VT.CharacterMap.maps['K'] = new hterm.VT.CharacterMap('german', {
+  '@': '§',  // @ -> section symbol (double s)
 
-    '[': 'Ä', // [ -> 'A' umlaut
-    '\\': 'Ö', // \ -> 'O' umlaut
-    ']': 'Ü', // ] -> 'U' umlaut
+  '[': 'Ä',   // [ -> 'A' umlaut
+  '\\': 'Ö',  // \ -> 'O' umlaut
+  ']': 'Ü',   // ] -> 'U' umlaut
 
-    '{': 'ä', // { -> 'a' umlaut
-    '|': 'ö', // | -> 'o' umlaut
-    '}': 'ü', // } -> 'u' umlaut
-    '~': 'ß', // ~ -> eszett
-  });
+  '{': 'ä',  // { -> 'a' umlaut
+  '|': 'ö',  // | -> 'o' umlaut
+  '}': 'ü',  // } -> 'u' umlaut
+  '~': 'ß',  // ~ -> eszett
+});
 
 /**
  * Italian character map.
  * http://vt100.net/docs/vt220-rm/table2-11.html
  */
-hterm.VT.CharacterMap.maps['Y'] = new hterm.VT.CharacterMap(
-  'italian', {
-    '#': '£', // # -> british-pound
+hterm.VT.CharacterMap.maps['Y'] = new hterm.VT.CharacterMap('italian', {
+  '#': '£',  // # -> british-pound
 
-    '@': '§', // @ -> section symbol (double s)
+  '@': '§',  // @ -> section symbol (double s)
 
-    '[': '°', // [ -> ring
-    '\\': 'ç', // \ -> 'c' cedilla
-    ']': 'é', // ] -> 'e' acute
+  '[': '°',   // [ -> ring
+  '\\': 'ç',  // \ -> 'c' cedilla
+  ']': 'é',   // ] -> 'e' acute
 
-    '`': 'ù', // ` -> 'u' grave
+  '`': 'ù',  // ` -> 'u' grave
 
-    '{': 'à', // { -> 'a' grave
-    '|': 'ò', // | -> 'o' grave
-    '}': 'è', // } -> 'e' grave
-    '~': 'ì', // ~ -> 'i' grave
-  });
+  '{': 'à',  // { -> 'a' grave
+  '|': 'ò',  // | -> 'o' grave
+  '}': 'è',  // } -> 'e' grave
+  '~': 'ì',  // ~ -> 'i' grave
+});
 
 /**
  * Norwegian/Danish character map.
  * http://vt100.net/docs/vt220-rm/table2-12.html
  */
-hterm.VT.CharacterMap.maps['E'] =
-  hterm.VT.CharacterMap.maps['6'] = new hterm.VT.CharacterMap(
-    'norwegian/danish', {
-      '@': 'Ä', // @ -> 'A' umlaut
+hterm.VT.CharacterMap.maps['E'] = hterm.VT.CharacterMap.maps['6'] =
+    new hterm.VT.CharacterMap('norwegian/danish', {
+      '@': 'Ä',  // @ -> 'A' umlaut
 
-      '[': 'Æ', // [ -> 'AE' ligature
-      '\\': 'Ø', // \ -> 'O' stroke
-      ']': 'Å', // ] -> 'A' ring
-      '^': 'Ü', // ^ -> 'U' umlaut
+      '[': 'Æ',   // [ -> 'AE' ligature
+      '\\': 'Ø',  // \ -> 'O' stroke
+      ']': 'Å',   // ] -> 'A' ring
+      '^': 'Ü',   // ^ -> 'U' umlaut
 
-      '`': 'ä', // ` -> 'a' umlaut
+      '`': 'ä',  // ` -> 'a' umlaut
 
-      '{': 'æ', // { -> 'ae' ligature
-      '|': 'ø', // | -> 'o' stroke
-      '}': 'å', // } -> 'a' ring
-      '~': 'ü', // ~ -> 'u' umlaut
+      '{': 'æ',  // { -> 'ae' ligature
+      '|': 'ø',  // | -> 'o' stroke
+      '}': 'å',  // } -> 'a' ring
+      '~': 'ü',  // ~ -> 'u' umlaut
     });
 
 /**
  * Spanish character map.
  * http://vt100.net/docs/vt220-rm/table2-13.html
  */
-hterm.VT.CharacterMap.maps['Z'] = new hterm.VT.CharacterMap(
-  'spanish', {
-    '#': '£', // # -> british-pound
+hterm.VT.CharacterMap.maps['Z'] = new hterm.VT.CharacterMap('spanish', {
+  '#': '£',  // # -> british-pound
 
-    '@': '§', // @ -> section symbol (double s)
+  '@': '§',  // @ -> section symbol (double s)
 
-    '[': '¡', // [ -> '!' inverted
-    '\\': 'Ñ', // \ -> 'N' tilde
-    ']': '¿', // ] -> '?' inverted
+  '[': '¡',   // [ -> '!' inverted
+  '\\': 'Ñ',  // \ -> 'N' tilde
+  ']': '¿',   // ] -> '?' inverted
 
-    '{': '°', // { -> ring
-    '|': 'ñ', // | -> 'n' tilde
-    '}': 'ç', // } -> 'c' cedilla
-  });
+  '{': '°',  // { -> ring
+  '|': 'ñ',  // | -> 'n' tilde
+  '}': 'ç',  // } -> 'c' cedilla
+});
 
 /**
  * Swedish character map.
  * http://vt100.net/docs/vt220-rm/table2-14.html
  */
-hterm.VT.CharacterMap.maps['7'] =
-  hterm.VT.CharacterMap.maps['H'] = new hterm.VT.CharacterMap(
-    'swedish', {
-      '@': 'É', // @ -> 'E' acute
+hterm.VT.CharacterMap.maps['7'] = hterm.VT.CharacterMap.maps['H'] =
+    new hterm.VT.CharacterMap('swedish', {
+      '@': 'É',  // @ -> 'E' acute
 
-      '[': 'Ä', // [ -> 'A' umlaut
-      '\\': 'Ö', // \ -> 'O' umlaut
-      ']': 'Å', // ] -> 'A' ring
-      '^': 'Ü', // ^ -> 'U' umlaut
+      '[': 'Ä',   // [ -> 'A' umlaut
+      '\\': 'Ö',  // \ -> 'O' umlaut
+      ']': 'Å',   // ] -> 'A' ring
+      '^': 'Ü',   // ^ -> 'U' umlaut
 
-      '`': 'é', // ` -> 'e' acute
+      '`': 'é',  // ` -> 'e' acute
 
-      '{': 'ä', // { -> 'a' umlaut
-      '|': 'ö', // | -> 'o' umlaut
-      '}': 'å', // } -> 'a' ring
-      '~': 'ü', // ~ -> 'u' umlaut
+      '{': 'ä',  // { -> 'a' umlaut
+      '|': 'ö',  // | -> 'o' umlaut
+      '}': 'å',  // } -> 'a' ring
+      '~': 'ü',  // ~ -> 'u' umlaut
     });
 
 /**
  * Swiss character map.
  * http://vt100.net/docs/vt220-rm/table2-15.html
  */
-hterm.VT.CharacterMap.maps['='] = new hterm.VT.CharacterMap(
-  'swiss', {
-    '#': 'ù', // # -> 'u' grave
+hterm.VT.CharacterMap.maps['='] = new hterm.VT.CharacterMap('swiss', {
+  '#': 'ù',  // # -> 'u' grave
 
-    '@': 'à', // @ -> 'a' grave
+  '@': 'à',  // @ -> 'a' grave
 
-    '[': 'é', // [ -> 'e' acute
-    '\\': 'ç', // \ -> 'c' cedilla
-    ']': 'ê', // ] -> 'e' circumflex
-    '^': 'î', // ^ -> 'i' circumflex
-    '_': 'è', // _ -> 'e' grave
+  '[': 'é',   // [ -> 'e' acute
+  '\\': 'ç',  // \ -> 'c' cedilla
+  ']': 'ê',   // ] -> 'e' circumflex
+  '^': 'î',   // ^ -> 'i' circumflex
+  '_': 'è',   // _ -> 'e' grave
 
-    '`': 'ô', // ` -> 'o' circumflex
+  '`': 'ô',  // ` -> 'o' circumflex
 
-    '{': 'ä', // { -> 'a' umlaut
-    '|': 'ö', // | -> 'o' umlaut
-    '}': 'ü', // } -> 'u' umlaut
-    '~': 'û', // ~ -> '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=' +
-  ''
-);
+  '{': 'ä',  // { -> 'a' umlaut
+  '|': 'ö',  // | -> 'o' umlaut
+  '}': 'ü',  // } -> 'u' umlaut
+  '~': 'û',  // ~ -> '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/concat/date', 'text/plain',
-  'Tue, 25 Apr 2017 15:12:45 +0000' +
-  ''
-);
+lib.resource.add(
+    'hterm/concat/date', 'text/plain',
+    'Tue, 25 Apr 2017 15:12:45 +0000' +
+        '');
 
-lib.resource.add('hterm/changelog/version', 'text/plain',
-  '1.62' +
-  ''
-);
+lib.resource.add(
+    'hterm/changelog/version', 'text/plain',
+    '1.62' +
+        '');
 
-lib.resource.add('hterm/changelog/date', 'text/plain',
-  '2017-04-17' +
-  ''
-);
+lib.resource.add(
+    'hterm/changelog/date', 'text/plain',
+    '2017-04-17' +
+        '');
 
-lib.resource.add('hterm/git/HEAD', 'text/plain',
-  'git rev-parse HEAD' +
-  ''
-);
+lib.resource.add(
+    'hterm/git/HEAD', 'text/plain',
+    'git rev-parse HEAD' +
+        '');
diff --git a/app/vendors/hterm/hterm_all.min.js b/app/vendors/hterm/hterm_all.min.js
index 208526d..8039c16 100644
--- a/app/vendors/hterm/hterm_all.min.js
+++ b/app/vendors/hterm/hterm_all.min.js
@@ -1,27 +1,33 @@
 'use strict';
-if ('undefined' != typeof lib) throw new Error('Global "lib" object already exists.');
+if ('undefined' != typeof lib)
+  throw new Error('Global "lib" object already exists.');
 var lib = {};
-lib.runtimeDependencies_ = {}, lib.initCallbacks_ = [], lib.rtdep = function(e) {
-  var t;
-  try {
-    throw new Error;
-  }
-  catch (r) {
-    var o = r.stack.split('\n');
-    t = o.length >= 3 ? o[2].replace(/^\s*at\s+/, '') : o[1].replace(/^\s*global code@/, '');
-  }
-  for (var i = 0; i < arguments.length; i++) {
-    var s = arguments[i];
-    if (s instanceof Array) lib.rtdep.apply(lib, s);
-    else {
-      var n = this.runtimeDependencies_[s];
-      n || (n = this.runtimeDependencies_[s] = []), n.push(t);
-    }
-  }
-};, lib.ensureRuntimeDependencies_ = function() {
+lib.runtimeDependencies_ = {},
+    lib.initCallbacks_ = [], lib.rtdep = function(e) {
+      var t;
+      try {
+        throw new Error;
+      } catch (r) {
+        var o = r.stack.split('\n');
+        t = o.length >= 3 ? o[2].replace(/^\s*at\s+/, '') :
+                            o[1].replace(/^\s*global code@/, '');
+      }
+      for (var i = 0; i < arguments.length; i++) {
+        var s = arguments[i];
+        if (s instanceof Array)
+          lib.rtdep.apply(lib, s);
+        else {
+          var n = this.runtimeDependencies_[s];
+          n || (n = this.runtimeDependencies_[s] = []), n.push(t);
+        }
+      }
+    };
+, lib.ensureRuntimeDependencies_ = function() {
   var e = !0;
   for (var t in lib.runtimeDependencies_)
-    for (var r = lib.runtimeDependencies_[t], o = t.split('.'), i = window || self, s = 0; s < o.length; s++) {
+    for (var r = lib.runtimeDependencies_[t], o = t.split('.'),
+             i = window || self, s = 0;
+         s < o.length; s++) {
       if (!(o[s] in i)) {
         console.warn('Missing "' + t + '" is needed by', r), e = !1;
         break;
@@ -29,889 +35,1007 @@
       i = i[o[s]];
     }
   if (!e) throw new Error('Failed runtime dependency check');
-};, lib.registerInit = function(e, t) {
+};
+, lib.registerInit = function(e, t) {
   return lib.initCallbacks_.push([e, t]), t;
-};, lib.init = function(e, t) {
-  var r = lib.initCallbacks_,
-    o = function() {
-      if (r.length) {
-        var i = r.shift();
-        t && t('init: ' + i[0]), i[1](lib.f.alarm(o));
-      }
-      else e();
-    };
-  if ('function' != typeof e) throw new Error('Missing or invalid argument: onInit');
+};
+, lib.init = function(e, t) {
+  var r = lib.initCallbacks_, o = function() {
+    if (r.length) {
+      var i = r.shift();
+      t && t('init: ' + i[0]), i[1](lib.f.alarm(o));
+    } else
+      e();
+  };
+  if ('function' != typeof e)
+    throw new Error('Missing or invalid argument: onInit');
   lib.ensureRuntimeDependencies_(), setTimeout(o, 0);
-};, lib.colors = {}, lib.colors.re_ = {
+};
+, lib.colors = {}, lib.colors.re_ = {
   hex16: /#([a-f0-9])([a-f0-9])([a-f0-9])/i,
   hex24: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/i,
-  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'),
-  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'),
-  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'),
+  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'),
+  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'),
+  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'),
   x11rgb: /^\s*rgb:([a-f0-9]{1,4})\/([a-f0-9]{1,4})\/([a-f0-9]{1,4})\s*$/i,
   name: /[a-z][a-z0-9\s]+/
-}, lib.colors.rgbToX11 = function(e) {
-  function t(e) {
-    return e = (257 * Math.min(e, 255)).toString(16), lib.f.zpad(e, 4);
-  }
-  var r = e.match(lib.colors.re_.rgbx);
-  return r ? 'rgb:' + t(r[1]) + '/' + t(r[2]) + '/' + t(r[3]) : null;
-};, lib.colors.x11HexToCSS = function(e) {
+},
+  lib.colors.rgbToX11 = function(e) {
+    function t(e) {
+      return e = (257 * Math.min(e, 255)).toString(16), lib.f.zpad(e, 4);
+    }
+    var r = e.match(lib.colors.re_.rgbx);
+    return r ? 'rgb:' + t(r[1]) + '/' + t(r[2]) + '/' + t(r[3]) : null;
+  };
+, lib.colors.x11HexToCSS = function(e) {
   function t(e) {
     return e = parseInt(e, 16), 2 == r ? e : 1 == r ? e << 4 : e >> 4 * (r - 2)
   }
   if (!e.startsWith('#')) return null;
   if (e = e.substr(1), -1 == [3, 6, 9, 12].indexOf(e.length)) return null;
   if (e.match(/[^a-f0-9]/i)) return null;
-  var r = e.length / 3,
-    o = e.substr(0, r),
-    i = e.substr(r, r),
-    s = e.substr(r + r, r);
+  var r = e.length / 3, o = e.substr(0, r), i = e.substr(r, r),
+      s = e.substr(r + r, r);
   return lib.colors.arrayToRGBA([o, i, s].map(t));
-};, lib.colors.x11ToCSS = function(e) {
+};
+, lib.colors.x11ToCSS = function(e) {
   function t(e) {
-    return 1 == e.length ? parseInt(e + e, 16) : 2 == e.length ? parseInt(e, 16) : (3 == e.length && (e += e.substr(2)), Math.round(parseInt(e, 16) / 257))
+    return 1 == e.length ?
+        parseInt(e + e, 16) :
+        2 == e.length ?
+        parseInt(e, 16) :
+        (3 == e.length && (e += e.substr(2)), Math.round(parseInt(e, 16) / 257))
   }
   var r = e.match(lib.colors.re_.x11rgb);
-  return r ? (r.splice(0, 1), lib.colors.arrayToRGBA(r.map(t))) : e.startsWith('#') ? lib.colors.x11HexToCSS(e) : lib.colors.nameToRGB(e)
-};, lib.colors.hexToRGB = function(e) {
+  return r ?
+      (r.splice(0, 1), lib.colors.arrayToRGBA(r.map(t))) :
+      e.startsWith('#') ? lib.colors.x11HexToCSS(e) : lib.colors.nameToRGB(e)
+};
+, lib.colors.hexToRGB = function(e) {
   function t(e) {
     4 == e.length && (e = e.replace(r, function(e, t, r, o) {
       return '#' + t + t + r + r + o + o;
     }));
     var t = e.match(o);
-    return t ? 'rgb(' + parseInt(t[1], 16) + ', ' + parseInt(t[2], 16) + ', ' + parseInt(t[3], 16) + ')' : null;
+    return t ? 'rgb(' + parseInt(t[1], 16) + ', ' + parseInt(t[2], 16) + ', ' +
+            parseInt(t[3], 16) + ')' :
+               null;
   }
-  var r = lib.colors.re_.hex16,
-    o = lib.colors.re_.hex24;
+  var r = lib.colors.re_.hex16, o = lib.colors.re_.hex24;
   if (e instanceof Array)
     for (var i = 0; i < e.length; i++) e[i] = t(e[i]);
-  else e = t(e);
+  else
+    e = t(e);
   return e;
-};, lib.colors.rgbToHex = function(e) {
+};
+, lib.colors.rgbToHex = function(e) {
   function t(e) {
     var t = lib.colors.crackRGB(e);
-    return t ? '#' + lib.f.zpad((parseInt(t[0]) << 16 | parseInt(t[1]) << 8 | parseInt(t[2]) << 0).toString(16), 6) : null;
+    return t ? '#' +
+            lib.f.zpad(
+                (parseInt(t[0]) << 16 | parseInt(t[1]) << 8 |
+                 parseInt(t[2]) << 0)
+                    .toString(16),
+                6) :
+               null;
   }
   if (e instanceof Array)
     for (var r = 0; r < e.length; r++) e[r] = t(e[r]);
-  else e = t(e);
+  else
+    e = t(e);
   return e;
-};, lib.colors.normalizeCSS = function(e) {
-  return '#' == e.substr(0, 1) ? lib.colors.hexToRGB(e) : lib.colors.re_.rgbx.test(e) ? e : lib.colors.nameToRGB(e)
-};, lib.colors.arrayToRGBA = function(e) {
+};
+, lib.colors.normalizeCSS = function(e) {
+  return '#' == e.substr(0, 1) ?
+      lib.colors.hexToRGB(e) :
+      lib.colors.re_.rgbx.test(e) ? e : lib.colors.nameToRGB(e)
+};
+, lib.colors.arrayToRGBA = function(e) {
   var t = e.length > 3 ? e[3] : 1;
   return 'rgba(' + e[0] + ', ' + e[1] + ', ' + e[2] + ', ' + t + ')';
-};, lib.colors.setAlpha = function(e, t) {
+};
+, lib.colors.setAlpha = function(e, t) {
   var r = lib.colors.crackRGB(e);
   return r[3] = t, lib.colors.arrayToRGBA(r);
-};, lib.colors.mix = function(e, t, r) {
-  for (var o = lib.colors.crackRGB(e), i = lib.colors.crackRGB(t), s = 0; 4 > s; ++s) {
+};
+, lib.colors.mix = function(e, t, r) {
+  for (var o = lib.colors.crackRGB(e), i = lib.colors.crackRGB(t), s = 0; 4 > s;
+       ++s) {
     var n = i[s] - o[s];
     o[s] = Math.round(parseInt(o[s]) + n * r);
   }
   return lib.colors.arrayToRGBA(o);
-};, lib.colors.crackRGB = function(e) {
+};
+, lib.colors.crackRGB = function(e) {
   if ('rgba' == e.substr(0, 4)) {
     var t = e.match(lib.colors.re_.rgba);
     if (t) return t.shift(), t;
-  }
-  else {
+  } else {
     var t = e.match(lib.colors.re_.rgb);
     if (t) return t.shift(), t.push(1), t;
   }
-  return console.error("Couldn't crack: " + e), null;
-};, lib.colors.nameToRGB = function(e) {
-  return e in lib.colors.colorNames ? lib.colors.colorNames[e] : (e = e.toLowerCase(), e in lib.colors.colorNames ? lib.colors.colorNames[e] : (e = e.replace(/\s+/g, ''), e in lib.colors.colorNames ? lib.colors.colorNames[e] : null));
-};, lib.colors.stockColorPalette = lib.colors.hexToRGB(['#000000', '#CC0000', '#4E9A06', '#C4A000', '#3465A4', '#75507B', '#06989A', '#D3D7CF', '#555753', '#EF2929', '#00BA13', '#FCE94F', '#729FCF', '#F200CB', '#00B5BD', '#EEEEEC', '#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', '#080808', '#121212', '#1C1C1C', '#262626', '#303030', '#3A3A3A', '#444444', '#4E4E4E', '#585858', '#626262', '#6C6C6C', '#767676', '#808080', '#8A8A8A', '#949494', '#9E9E9E', '#A8A8A8', '#B2B2B2', '#BCBCBC', '#C6C6C6', '#D0D0D0', '#DADADA', '#E4E4E4', '#EEEEEE']), lib.colors.colorPalette = lib.colors.stockColorPalette, 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)'
-}, lib.f = {}, lib.f.replaceVars = function(e, t) {
-  return e.replace(/%([a-z]*)\(([^\)]+)\)/gi, function(e, r, o) {
-    if ('undefined' == typeof t[o]) throw 'Unknown variable: ' + o;
-    var i = t[o];
-    if (r in lib.f.replaceVars.functions) i = lib.f.replaceVars.functions[r](i);
-    else if (r) throw 'Unknown escape function: ' + r;
-    return i;
-  });
-};, lib.f.replaceVars.functions = {
+  return console.error('Couldn\'t crack: ' + e), null;
+};
+, lib.colors.nameToRGB = function(e) {
+  return e in lib.colors.colorNames ?
+      lib.colors.colorNames[e] :
+      (e = e.toLowerCase(),
+       e in lib.colors.colorNames ?
+           lib.colors.colorNames[e] :
+           (e = e.replace(/\s+/g, ''),
+            e in lib.colors.colorNames ? lib.colors.colorNames[e] : null));
+};
+, lib.colors.stockColorPalette = lib.colors.hexToRGB([
+  '#000000', '#CC0000', '#4E9A06', '#C4A000', '#3465A4', '#75507B', '#06989A',
+  '#D3D7CF', '#555753', '#EF2929', '#00BA13', '#FCE94F', '#729FCF', '#F200CB',
+  '#00B5BD', '#EEEEEC', '#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', '#080808', '#121212', '#1C1C1C', '#262626', '#303030', '#3A3A3A',
+  '#444444', '#4E4E4E', '#585858', '#626262', '#6C6C6C', '#767676', '#808080',
+  '#8A8A8A', '#949494', '#9E9E9E', '#A8A8A8', '#B2B2B2', '#BCBCBC', '#C6C6C6',
+  '#D0D0D0', '#DADADA', '#E4E4E4', '#EEEEEE'
+]),
+  lib.colors.colorPalette = lib.colors.stockColorPalette,
+  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)'
+  },
+  lib.f = {}, lib.f.replaceVars = function(e, t) {
+    return e.replace(/%([a-z]*)\(([^\)]+)\)/gi, function(e, r, o) {
+      if ('undefined' == typeof t[o]) throw 'Unknown variable: ' + o;
+      var i = t[o];
+      if (r in lib.f.replaceVars.functions)
+        i = lib.f.replaceVars.functions[r](i);
+      else if (r)
+        throw 'Unknown escape function: ' + r;
+      return i;
+    });
+  };
+, lib.f.replaceVars.functions = {
   encodeURI: encodeURI,
   encodeURIComponent: encodeURIComponent,
   escapeHTML: function(e) {
-    var t = {
-      '<': '&lt;',
-      '>': '&gt;',
-      '&': '&amp;',
-      '"': '&quot;',
-      "'": '&#39;'
-    };
+    var t =
+        {'<': '&lt;', '>': '&gt;', '&': '&amp;', '"': '&quot;', '\'': '&#39;'};
     return e.replace(/[<>&\"\']/g, function(e) {
       return t[e];
     });
   }
-}, lib.f.getAcceptLanguages = function(e) {
-  lib.f.getAcceptLanguages.chromeSupported() ? chrome.i18n.getAcceptLanguages(e) : setTimeout(function() {
-    e([navigator.language.replace(/-/g, '_')]);
-  }, 0);
-};, lib.f.getAcceptLanguages.chromeSupported = function() {
+},
+  lib.f.getAcceptLanguages = function(e) {
+    lib.f.getAcceptLanguages.chromeSupported() ?
+        chrome.i18n.getAcceptLanguages(e) :
+        setTimeout(function() {
+          e([navigator.language.replace(/-/g, '_')]);
+        }, 0);
+  };
+, lib.f.getAcceptLanguages.chromeSupported = function() {
   return window.chrome && chrome.i18n;
-};, lib.f.parseQuery = function(e) {
+};
+, lib.f.parseQuery = function(e) {
   '?' == e.substr(0, 1) && (e = e.substr(1));
   for (var t = {}, r = e.split('&'), o = 0; o < r.length; o++) {
     var i = r[o].split('=');
     t[decodeURIComponent(i[0])] = decodeURIComponent(i[1]);
   }
   return t;
-};, lib.f.getURL = function(e) {
+};
+, lib.f.getURL = function(e) {
   return lib.f.getURL.chromeSupported() ? chrome.runtime.getURL(e) : e;
-};, lib.f.getURL.chromeSupported = function() {
+};
+, lib.f.getURL.chromeSupported = function() {
   return window.chrome && chrome.runtime && chrome.runtime.getURL;
-};, lib.f.clamp = function(e, t, r) {
+};
+, lib.f.clamp = function(e, t, r) {
   return t > e ? t : e > r ? r : e
-};, lib.f.lpad = function(e, t, r) {
+};
+, lib.f.lpad = function(e, t, r) {
   for (e = String(e), r = r || ' '; e.length < t;) e = r + e;
   return e;
-};, lib.f.zpad = function(e, t) {
+};
+, lib.f.zpad = function(e, t) {
   return lib.f.lpad(e, t, '0');
-};, lib.f.getWhitespace = function(e) {
+};
+, lib.f.getWhitespace = function(e) {
   if (0 >= e) return '';
   var t = this.getWhitespace;
-  for (t.whitespace || (t.whitespace = '          '); e > t.whitespace.length;) t.whitespace += t.whitespace;
+  for (t.whitespace || (t.whitespace = '          '); e > t.whitespace.length;)
+    t.whitespace += t.whitespace;
   return t.whitespace.substr(0, e);
-};, lib.f.alarm = function(e, t) {
-  var r = t || 5e3,
-    o = lib.f.getStack(1);
+};
+, lib.f.alarm = function(e, t) {
+  var r = t || 5e3, o = lib.f.getStack(1);
   return function() {
     var t = setTimeout(function() {
-        var i = 'string' == typeof e ? i : e.name;
-        i = i ? ': ' + i : '', console.warn('lib.f.alarm: timeout expired: ' + r / 1e3 + 's' + i), console.log(o), t = null;
-      }, r),
-      i = function(e) {
-        return function() {
-          return t && (clearTimeout(t), t = null), e.apply(null, arguments);
-        }
-      };
+      var i = 'string' == typeof e ? i : e.name;
+      i = i ? ': ' + i : '',
+      console.warn('lib.f.alarm: timeout expired: ' + r / 1e3 + 's' + i),
+      console.log(o), t = null;
+    }, r), i = function(e) {
+      return function() {
+        return t && (clearTimeout(t), t = null), e.apply(null, arguments);
+      }
+    };
     return 'string' == typeof e ? i : i(e);
   }();
-};, lib.f.getStack = function(e) {
+};
+, lib.f.getStack = function(e) {
   var t, r = e ? e + 2 : 2;
   try {
     throw new Error;
-  }
-  catch (o) {
+  } catch (o) {
     t = o.stack.split('\n');
   }
-  for (var i = {}, s = r; s < t.length; s++) i[s - r] = t[s].replace(/^\s*at\s+/, '');
+  for (var i = {}, s = r; s < t.length; s++)
+    i[s - r] = t[s].replace(/^\s*at\s+/, '');
   return i;
-};, lib.f.smartFloorDivide = function(e, t) {
-  var r = e / t,
-    o = Math.ceil(r);
+};
+, lib.f.smartFloorDivide = function(e, t) {
+  var r = e / t, o = Math.ceil(r);
   return 1e-4 > o - r ? o : Math.floor(r);
-};, lib.MessageManager = function(e) {
+};
+, lib.MessageManager = function(e) {
   this.languages_ = e.map(function(e) {
     return e.replace(/-/g, '_');
-  }), -1 == this.languages_.indexOf('en') && this.languages_.unshift('en'), this.messages = {};
-};, lib.MessageManager.prototype.addMessages = function(e) {
+  }),
+  -1 == this.languages_.indexOf('en') && this.languages_.unshift('en'),
+  this.messages = {};
+};
+, lib.MessageManager.prototype.addMessages = function(e) {
   for (var t in e) {
     var r = e[t];
-    r.placeholders ? this.messages[t] = r.message.replace(/\$([a-z][^\s\$]+)\$/gi, function(r, o) {
-      return e[t].placeholders[o.toLowerCase()].content;
-    }) : this.messages[t] = r.message;
+    r.placeholders ? this.messages[t] = r.message.replace(
+                         /\$([a-z][^\s\$]+)\$/gi,
+                         function(r, o) {
+                           return e[t].placeholders[o.toLowerCase()].content;
+                         }) :
+                     this.messages[t] = r.message;
   }
-};, lib.MessageManager.prototype.findAndLoadMessages = function(e, t) {
+};
+, lib.MessageManager.prototype.findAndLoadMessages = function(e, t) {
   function r(e) {
     e ? i = o.shift() : s = o.shift(), o.length ? n() : t(i, s);
   }
-  var o = this.languages_.concat(),
-    i = [],
-    s = [],
-    n = function() {
-      this.loadMessages(this.replaceReferences(e, o), r.bind(this, !0), r.bind(this, !1));
-    }.bind(this);
+  var o = this.languages_.concat(), i = [], s = [], n = function() {
+    this.loadMessages(
+        this.replaceReferences(e, o), r.bind(this, !0), r.bind(this, !1));
+  }.bind(this);
   n();
-};, lib.MessageManager.prototype.loadMessages = function(e, t, r) {
+};
+, lib.MessageManager.prototype.loadMessages = function(e, t, r) {
   var o = new XMLHttpRequest;
   o.onloadend = function() {
-    return 200 != o.status ? void(r && r(o.status)) : (this.addMessages(JSON.parse(o.responseText)), void t());
+    return 200 != o.status ?
+        void(r && r(o.status)) :
+        (this.addMessages(JSON.parse(o.responseText)), void t());
   }.bind(this), o.open('GET', e), o.send();
-};, lib.MessageManager.replaceReferences = function(e, t) {
+};
+, lib.MessageManager.replaceReferences = function(e, t) {
   return e.replace(/\$(\d+)/g, function(e, r) {
     return t[r - 1];
   });
-};, lib.MessageManager.prototype.replaceReferences = lib.MessageManager.replaceReferences, lib.MessageManager.prototype.get = function(e, t, r) {
-  var o;
-  if (e in this.messages) o = this.messages[e];
-  else if (window.chrome.i18n && (o = chrome.i18n.getMessage(e)), !o) return console.warn('Unknown message: ' + e), 'undefined' == typeof r ? e : r;
-  return t ? (t instanceof Array || (t = [t]), this.replaceReferences(o, t)) : o;
-};, lib.MessageManager.prototype.processI18nAttributes = function(e) {
+};
+,
+    lib.MessageManager.prototype.replaceReferences =
+        lib.MessageManager.replaceReferences,
+    lib.MessageManager.prototype.get = function(e, t, r) {
+      var o;
+      if (e in this.messages)
+        o = this.messages[e];
+      else if (window.chrome.i18n && (o = chrome.i18n.getMessage(e)), !o)
+        return console.warn('Unknown message: ' + e),
+               'undefined' == typeof r ? e : r;
+      return t ?
+          (t instanceof Array || (t = [t]), this.replaceReferences(o, t)) :
+          o;
+    };
+, lib.MessageManager.prototype.processI18nAttributes = function(e) {
   function t(e) {
     return e.replace(/-/g, '_').toUpperCase();
   }
   for (var r = e.querySelectorAll('[i18n]'), o = 0; o < r.length; o++) {
-    var i = r[o],
-      s = i.getAttribute('i18n');
+    var i = r[o], s = i.getAttribute('i18n');
     if (s) {
       try {
         s = JSON.parse(s);
-      }
-      catch (n) {
-        throw console.error("Can't parse " + i.tagName + '#' + i.id + ': ' + s), n;
+      } catch (n) {
+        throw console.error(
+            'Can\'t parse ' + i.tagName + '#' + i.id + ': ' + s),
+            n;
       }
       for (var a in s) {
         var l = s[a];
@@ -921,102 +1045,145 @@
       }
     }
   }
-};, lib.PreferenceManager = function(e, t) {
-  this.storage = e, this.storageObserver_ = this.onStorageChange_.bind(this), this.isActive_ = !1, this.activate(), this.trace = !1;
+};
+, lib.PreferenceManager = function(e, t) {
+  this.storage = e, this.storageObserver_ = this.onStorageChange_.bind(this),
+  this.isActive_ = !1, this.activate(), this.trace = !1;
   var r = t || '/';
-  '/' != r.substr(r.length - 1) && (r += '/'), this.prefix = r, this.prefRecords_ = {}, this.globalObservers_ = [], this.childFactories_ = {}, this.childLists_ = {};
-};, lib.PreferenceManager.prototype.DEFAULT_VALUE = new String('DEFAULT'), lib.PreferenceManager.Record = function(e, t) {
-  this.name = e, this.defaultValue = t, this.currentValue = this.DEFAULT_VALUE, this.observers = [];
-};, lib.PreferenceManager.Record.prototype.DEFAULT_VALUE = lib.PreferenceManager.prototype.DEFAULT_VALUE, lib.PreferenceManager.Record.prototype.addObserver = function(e) {
-  this.observers.push(e);
-};, lib.PreferenceManager.Record.prototype.removeObserver = function(e) {
+  '/' != r.substr(r.length - 1) && (r += '/'),
+      this.prefix = r, this.prefRecords_ = {}, this.globalObservers_ = [],
+      this.childFactories_ = {}, this.childLists_ = {};
+};
+, lib.PreferenceManager.prototype.DEFAULT_VALUE = new String('DEFAULT'),
+  lib.PreferenceManager.Record = function(e, t) {
+    this.name = e, this.defaultValue = t,
+    this.currentValue = this.DEFAULT_VALUE, this.observers = [];
+  };
+,
+    lib.PreferenceManager.Record.prototype.DEFAULT_VALUE =
+        lib.PreferenceManager.prototype.DEFAULT_VALUE,
+    lib.PreferenceManager.Record.prototype.addObserver = function(e) {
+      this.observers.push(e);
+    };
+, lib.PreferenceManager.Record.prototype.removeObserver = function(e) {
   var t = this.observers.indexOf(e);
   t >= 0 && this.observers.splice(t, 1);
-};, lib.PreferenceManager.Record.prototype.get = function() {
-  return this.currentValue === this.DEFAULT_VALUE ? /^(string|number)$/.test(typeof this.defaultValue) ? this.defaultValue : 'object' == typeof this.defaultValue ? JSON.parse(JSON.stringify(this.defaultValue)) : this.defaultValue : this.currentValue
-};, lib.PreferenceManager.prototype.deactivate = function() {
+};
+, lib.PreferenceManager.Record.prototype.get = function() {
+  return this.currentValue === this.DEFAULT_VALUE ?
+      /^(string|number)$/.test(typeof this.defaultValue) ?
+      this.defaultValue :
+      'object' == typeof this.defaultValue ?
+      JSON.parse(JSON.stringify(this.defaultValue)) :
+      this.defaultValue :
+      this.currentValue
+};
+, lib.PreferenceManager.prototype.deactivate = function() {
   if (!this.isActive_) throw new Error('Not activated');
   this.isActive_ = !1, this.storage.removeObserver(this.storageObserver_);
-};, lib.PreferenceManager.prototype.activate = function() {
+};
+, lib.PreferenceManager.prototype.activate = function() {
   if (this.isActive_) throw new Error('Already activated');
   this.isActive_ = !0, this.storage.addObserver(this.storageObserver_);
-};, lib.PreferenceManager.prototype.readStorage = function(e) {
+};
+, lib.PreferenceManager.prototype.readStorage = function(e) {
   function t() {
     0 == --r && e && e();
   }
-  var r = 0,
-    o = Object.keys(this.prefRecords_).map(function(e) {
-      return this.prefix + e;
-    }.bind(this));
+  var r = 0, o = Object.keys(this.prefRecords_).map(function(e) {
+    return this.prefix + e;
+  }.bind(this));
   this.trace && console.log('Preferences read: ' + this.prefix),
-    this.storage.getItems(o, function(o) {
-      var i = this.prefix.length;
-      for (var s in o) {
-        var n = o[s],
-          a = s.substr(i),
-          l = a in this.childLists_ && JSON.stringify(n) != JSON.stringify(this.prefRecords_[a].currentValue);
-        this.prefRecords_[a].currentValue = n, l && (r++, this.syncChildList(a, t));
-      }
-      0 == r && e && setTimeout(e);
-    }.bind(this));
-};, lib.PreferenceManager.prototype.definePreference = function(e, t, r) {
+      this.storage.getItems(o, function(o) {
+        var i = this.prefix.length;
+        for (var s in o) {
+          var n = o[s], a = s.substr(i),
+              l = a in this.childLists_ &&
+              JSON.stringify(n) !=
+                  JSON.stringify(this.prefRecords_[a].currentValue);
+          this.prefRecords_[a].currentValue = n,
+          l && (r++, this.syncChildList(a, t));
+        }
+        0 == r && e && setTimeout(e);
+      }.bind(this));
+};
+, lib.PreferenceManager.prototype.definePreference = function(e, t, r) {
   var o = this.prefRecords_[e];
-  o ? this.changeDefault(e, t) : o = this.prefRecords_[e] = new lib.PreferenceManager.Record(e, t), r && o.addObserver(r);
-};, lib.PreferenceManager.prototype.definePreferences = function(e) {
-  for (var t = 0; t < e.length; t++) this.definePreference(e[t][0], e[t][1], e[t][2]);
-};, lib.PreferenceManager.prototype.defineChildren = function(e, t) {
-  this.definePreference(e, [], this.onChildListChange_.bind(this, e)), this.childFactories_[e] = t, this.childLists_[e] = {};
-};, lib.PreferenceManager.prototype.addObservers = function(e, t) {
+  o ? this.changeDefault(e, t) :
+      o = this.prefRecords_[e] = new lib.PreferenceManager.Record(e, t),
+      r && o.addObserver(r);
+};
+, lib.PreferenceManager.prototype.definePreferences = function(e) {
+  for (var t = 0; t < e.length; t++)
+    this.definePreference(e[t][0], e[t][1], e[t][2]);
+};
+, lib.PreferenceManager.prototype.defineChildren = function(e, t) {
+  this.definePreference(e, [], this.onChildListChange_.bind(this, e)),
+      this.childFactories_[e] = t, this.childLists_[e] = {};
+};
+, lib.PreferenceManager.prototype.addObservers = function(e, t) {
   if (e && 'function' != typeof e) throw new Error('Invalid param: globals');
   if (e && this.globalObservers_.push(e), t)
     for (var r in t) {
-      if (!(r in this.prefRecords_)) throw new Error('Unknown preference: ' + r);
+      if (!(r in this.prefRecords_))
+        throw new Error('Unknown preference: ' + r);
       this.prefRecords_[r].addObserver(t[r]);
     }
-};, lib.PreferenceManager.prototype.notifyAll = function() {
+};
+, lib.PreferenceManager.prototype.notifyAll = function() {
   for (var e in this.prefRecords_) this.notifyChange_(e);
-};, lib.PreferenceManager.prototype.notifyChange_ = function(e) {
+};
+, lib.PreferenceManager.prototype.notifyChange_ = function(e) {
   var t = this.prefRecords_[e];
   if (!t) throw new Error('Unknown preference: ' + e);
-  for (var r = t.get(), o = 0; o < this.globalObservers_.length; o++) this.globalObservers_[o](e, r);
+  for (var r = t.get(), o = 0; o < this.globalObservers_.length; o++)
+    this.globalObservers_[o](e, r);
   for (var o = 0; o < t.observers.length; o++) t.observers[o](r, e, this);
-};, lib.PreferenceManager.prototype.createChild = function(e, t, r) {
+};
+, lib.PreferenceManager.prototype.createChild = function(e, t, r) {
   var o, i = this.get(e);
   if (r) {
-    if (o = r, -1 != i.indexOf(o)) throw new Error('Duplicate child: ' + e + ': ' + o);
-  }
-  else
-    for (; !o || -1 != i.indexOf(o);) o = Math.floor(65535 * Math.random() + 1).toString(16), o = lib.f.zpad(o, 4), t && (o = t + ':' + o);
+    if (o = r, -1 != i.indexOf(o))
+      throw new Error('Duplicate child: ' + e + ': ' + o);
+  } else
+    for (; !o || -1 != i.indexOf(o);)
+      o = Math.floor(65535 * Math.random() + 1).toString(16),
+      o = lib.f.zpad(o, 4), t && (o = t + ':' + o);
   var s = this.childFactories_[e](this, o);
-  return s.trace = this.trace, s.resetAll(), this.childLists_[e][o] = s, i.push(o), this.set(e, i), s;
-};, lib.PreferenceManager.prototype.removeChild = function(e, t) {
+  return s.trace = this.trace, s.resetAll(), this.childLists_[e][o] = s,
+         i.push(o), this.set(e, i), s;
+};
+, lib.PreferenceManager.prototype.removeChild = function(e, t) {
   var r = this.getChild(e, t);
   r.resetAll();
-  var o = this.get(e),
-    i = o.indexOf(t); - 1 != i && (o.splice(i, 1), this.set(e, o)), delete this.childLists_[e][t];
-};, lib.PreferenceManager.prototype.getChild = function(e, t, r) {
+  var o = this.get(e), i = o.indexOf(t);
+  -1 != i && (o.splice(i, 1), this.set(e, o)), delete this.childLists_[e][t];
+};
+, lib.PreferenceManager.prototype.getChild = function(e, t, r) {
   if (!(e in this.childLists_)) throw new Error('Unknown child list: ' + e);
   var o = this.childLists_[e];
   if (!(t in o)) {
-    if ('undefined' == typeof r) throw new Error('Unknown "' + e + '" child: ' + t);
+    if ('undefined' == typeof r)
+      throw new Error('Unknown "' + e + '" child: ' + t);
     return r;
   }
   return o[t];
-};, lib.PreferenceManager.diffChildLists = function(e, t) {
-  for (var r = {
-      added: {},
-      removed: {},
-      common: {}
-    }, o = 0; o < e.length; o++) - 1 != t.indexOf(e[o]) ? r.common[e[o]] = !0 : r.added[e[o]] = !0;
-  for (var o = 0; o < t.length; o++) t[o] in r.added || t[o] in r.common || (r.removed[t[o]] = !0);
+};
+, lib.PreferenceManager.diffChildLists = function(e, t) {
+  for (var r = {added: {}, removed: {}, common: {}}, o = 0; o < e.length; o++)
+    -1 != t.indexOf(e[o]) ? r.common[e[o]] = !0 : r.added[e[o]] = !0;
+  for (var o = 0; o < t.length; o++)
+    t[o] in r.added || t[o] in r.common || (r.removed[t[o]] = !0);
   return r;
-};, lib.PreferenceManager.prototype.syncChildList = function(e, t) {
+};
+, lib.PreferenceManager.prototype.syncChildList = function(e, t) {
   function r() {
     0 == --o && t && t();
   }
-  for (var o = 0, i = this.get(e), s = Object.keys(this.childLists_[e]), n = (lib.PreferenceManager.diffChildLists(i, s), 0); n < i.length; n++) {
-    var a = i[n],
-      l = s.indexOf(a);
+  for (var o = 0, i = this.get(e), s = Object.keys(this.childLists_[e]),
+           n = (lib.PreferenceManager.diffChildLists(i, s), 0);
+       n < i.length; n++) {
+    var a = i[n], l = s.indexOf(a);
     if (l >= 0 && s.splice(l, 1), !this.childLists_[e][a]) {
       var h = this.childFactories_[e](this, a);
       if (!h) {
@@ -1028,1072 +1195,1224 @@
   }
   for (var n = 0; n < s.length; n++) delete this.childLists_[e][s[n]];
   !o && t && setTimeout(t);
-};, lib.PreferenceManager.prototype.reset = function(e) {
+};
+, lib.PreferenceManager.prototype.reset = function(e) {
   var t = this.prefRecords_[e];
   if (!t) throw new Error('Unknown preference: ' + e);
-  this.storage.removeItem(this.prefix + e), t.currentValue !== this.DEFAULT_VALUE && (t.currentValue = this.DEFAULT_VALUE, this.notifyChange_(e));
-};, lib.PreferenceManager.prototype.resetAll = function() {
+  this.storage.removeItem(this.prefix + e),
+      t.currentValue !== this.DEFAULT_VALUE &&
+      (t.currentValue = this.DEFAULT_VALUE, this.notifyChange_(e));
+};
+, lib.PreferenceManager.prototype.resetAll = function() {
   var e = [];
   for (var t in this.childLists_) {
     var r = this.childLists_[t];
     for (var o in r) r[o].resetAll();
   }
-  for (var i in this.prefRecords_) this.prefRecords_[i].currentValue !== this.DEFAULT_VALUE && (this.prefRecords_[i].currentValue = this.DEFAULT_VALUE, e.push(i));
+  for (var i in this.prefRecords_)
+    this.prefRecords_[i].currentValue !== this.DEFAULT_VALUE &&
+        (this.prefRecords_[i].currentValue = this.DEFAULT_VALUE, e.push(i));
   var s = Object.keys(this.prefRecords_).map(function(e) {
     return this.prefix + e;
   }.bind(this));
   this.storage.removeItems(s), e.forEach(this.notifyChange_.bind(this));
-};, lib.PreferenceManager.prototype.diff = function(e, t) {
-  return typeof e == typeof t && /^(undefined|boolean|number|string)$/.test(typeof e) ? e !== t : !0;
-};, lib.PreferenceManager.prototype.changeDefault = function(e, t) {
+};
+, lib.PreferenceManager.prototype.diff = function(e, t) {
+  return typeof e == typeof t &&
+          /^(undefined|boolean|number|string)$/.test(typeof e) ?
+      e !== t :
+      !0;
+};
+, lib.PreferenceManager.prototype.changeDefault = function(e, t) {
   var r = this.prefRecords_[e];
   if (!r) throw new Error('Unknown preference: ' + e);
   if (this.diff(r.defaultValue, t)) {
     if (r.currentValue !== this.DEFAULT_VALUE) return void(r.defaultValue = t);
     r.defaultValue = t, this.notifyChange_(e);
   }
-};, lib.PreferenceManager.prototype.changeDefaults = function(e) {
+};
+, lib.PreferenceManager.prototype.changeDefaults = function(e) {
   for (var t in e) this.changeDefault(t, e[t]);
-};, lib.PreferenceManager.prototype.set = function(e, t) {
+};
+, lib.PreferenceManager.prototype.set = function(e, t) {
   var r = this.prefRecords_[e];
   if (!r) throw new Error('Unknown preference: ' + e);
   var o = r.get();
-  this.diff(o, t) && (this.diff(r.defaultValue, t) ? (r.currentValue = t, this.storage.setItem(this.prefix + e, t)) : (r.currentValue = this.DEFAULT_VALUE, this.storage.removeItem(this.prefix + e)), setTimeout(this.notifyChange_.bind(this, e), 0));
-};, lib.PreferenceManager.prototype.get = function(e) {
+  this.diff(o, t) &&
+      (this.diff(r.defaultValue, t) ?
+           (r.currentValue = t, this.storage.setItem(this.prefix + e, t)) :
+           (r.currentValue = this.DEFAULT_VALUE,
+            this.storage.removeItem(this.prefix + e)),
+       setTimeout(this.notifyChange_.bind(this, e), 0));
+};
+, lib.PreferenceManager.prototype.get = function(e) {
   var t = this.prefRecords_[e];
   if (!t) throw new Error('Unknown preference: ' + e);
   return t.get();
-};, lib.PreferenceManager.prototype.exportAsJson = function() {
+};
+, lib.PreferenceManager.prototype.exportAsJson = function() {
   var e = {};
   for (var t in this.prefRecords_)
     if (t in this.childLists_) {
       e[t] = [];
       for (var r = this.get(t), o = 0; o < r.length; o++) {
         var i = r[o];
-        e[t].push({
-          id: i,
-          json: this.getChild(t, i).exportAsJson()
-        });
+        e[t].push({id: i, json: this.getChild(t, i).exportAsJson()});
       }
+    } else {
+      var s = this.prefRecords_[t];
+      s.currentValue != this.DEFAULT_VALUE && (e[t] = s.currentValue);
     }
-  else {
-    var s = this.prefRecords_[t];
-    s.currentValue != this.DEFAULT_VALUE && (e[t] = s.currentValue);
-  }
   return e;
-};, lib.PreferenceManager.prototype.importFromJson = function(e) {
+};
+, lib.PreferenceManager.prototype.importFromJson = function(e) {
   for (var t in e)
     if (t in this.childLists_)
       for (var r = e[t], o = 0; o < r.length; o++) {
-        var i = r[o].id,
-          s = this.childLists_[t][i];
+        var i = r[o].id, s = this.childLists_[t][i];
         s || (s = this.createChild(t, null, i)), s.importFromJson(r[o].json);
       }
-  else this.set(t, e[t]);
-};, lib.PreferenceManager.prototype.onChildListChange_ = function(e) {
+    else
+      this.set(t, e[t]);
+};
+, lib.PreferenceManager.prototype.onChildListChange_ = function(e) {
   this.syncChildList(e);
-};, lib.PreferenceManager.prototype.onStorageChange_ = function(e) {
+};
+, lib.PreferenceManager.prototype.onStorageChange_ = function(e) {
   for (var t in e)
     if (!this.prefix || 0 == t.lastIndexOf(this.prefix, 0)) {
       var r = t.substr(this.prefix.length);
       if (r in this.prefRecords_) {
-        var o = this.prefRecords_[r],
-          i = e[t].newValue,
-          s = o.currentValue;
-        s === o.DEFAULT_VALUE && (s = void 0), this.diff(s, i) && ('undefined' == typeof i ? o.currentValue = o.DEFAULT_VALUE : o.currentValue = i, this.notifyChange_(r));
+        var o = this.prefRecords_[r], i = e[t].newValue, s = o.currentValue;
+        s === o.DEFAULT_VALUE && (s = void 0),
+            this.diff(s, i) &&
+            ('undefined' == typeof i ? o.currentValue = o.DEFAULT_VALUE :
+                                       o.currentValue = i,
+             this.notifyChange_(r));
       }
     }
-};, lib.resource = {
-  resources_: {}
-}, lib.resource.add = function(e, t, r) {
-  lib.resource.resources_[e] = {
-    type: t,
-    name: e,
-    data: r
-  };
-};, lib.resource.get = function(e, t) {
+};
+, lib.resource = {resources_: {}}, lib.resource.add = function(e, t, r) {
+  lib.resource.resources_[e] = {type: t, name: e, data: r};
+};
+, lib.resource.get = function(e, t) {
   if (!(e in lib.resource.resources_)) {
     if ('undefined' == typeof t) throw 'Unknown resource: ' + e;
     return t;
   }
   return lib.resource.resources_[e];
-};, lib.resource.getData = function(e, t) {
+};
+, lib.resource.getData = function(e, t) {
   if (!(e in lib.resource.resources_)) {
     if ('undefined' == typeof t) throw 'Unknown resource: ' + e;
     return t;
   }
   return lib.resource.resources_[e].data;
-};, lib.resource.getDataUrl = function(e, t) {
+};
+, lib.resource.getDataUrl = function(e, t) {
   var r = lib.resource.get(e, t);
   return 'data:' + r.type + ',' + r.data;
-};, lib.Storage = new Object, lib.Storage.Chrome = function(e) {
-  this.storage_ = e, this.observers_ = [], chrome.storage.onChanged.addListener(this.onChanged_.bind(this));
-};, lib.Storage.Chrome.prototype.onChanged_ = function(e, t) {
+};
+, lib.Storage = new Object, lib.Storage.Chrome = function(e) {
+  this.storage_ = e, this.observers_ = [],
+  chrome.storage.onChanged.addListener(this.onChanged_.bind(this));
+};
+, lib.Storage.Chrome.prototype.onChanged_ = function(e, t) {
   if (chrome.storage[t] == this.storage_)
     for (var r = 0; r < this.observers_.length; r++) this.observers_[r](e);
-};, lib.Storage.Chrome.prototype.addObserver = function(e) {
+};
+, lib.Storage.Chrome.prototype.addObserver = function(e) {
   this.observers_.push(e);
-};, lib.Storage.Chrome.prototype.removeObserver = function(e) {
-  var t = this.observers_.indexOf(e); - 1 != t && this.observers_.splice(t, 1);
-};, lib.Storage.Chrome.prototype.clear = function(e) {
+};
+, lib.Storage.Chrome.prototype.removeObserver = function(e) {
+  var t = this.observers_.indexOf(e);
+  -1 != t && this.observers_.splice(t, 1);
+};
+, lib.Storage.Chrome.prototype.clear = function(e) {
   this.storage_.clear(), e && setTimeout(e, 0);
-};, lib.Storage.Chrome.prototype.getItem = function(e, t) {
+};
+, lib.Storage.Chrome.prototype.getItem = function(e, t) {
   this.storage_.get(e, t);
-};, lib.Storage.Chrome.prototype.getItems = function(e, t) {
+};
+, lib.Storage.Chrome.prototype.getItems = function(e, t) {
   this.storage_.get(e, t);
-};, lib.Storage.Chrome.prototype.setItem = function(e, t, r) {
+};
+, lib.Storage.Chrome.prototype.setItem = function(e, t, r) {
   var o = {};
   o[e] = t, this.storage_.set(o, r);
-};, lib.Storage.Chrome.prototype.setItems = function(e, t) {
+};
+, lib.Storage.Chrome.prototype.setItems = function(e, t) {
   this.storage_.set(e, t);
-};, lib.Storage.Chrome.prototype.removeItem = function(e, t) {
+};
+, lib.Storage.Chrome.prototype.removeItem = function(e, t) {
   this.storage_.remove(e, t);
-};, lib.Storage.Chrome.prototype.removeItems = function(e, t) {
+};
+, lib.Storage.Chrome.prototype.removeItems = function(e, t) {
   this.storage_.remove(e, t);
-};, lib.Storage.Local = function() {
-  this.observers_ = [], this.storage_ = window.localStorage, window.addEventListener('storage', this.onStorage_.bind(this));
-};, lib.Storage.Local.prototype.onStorage_ = function(e) {
+};
+, lib.Storage.Local = function() {
+  this.observers_ = [], this.storage_ = window.localStorage,
+  window.addEventListener('storage', this.onStorage_.bind(this));
+};
+, lib.Storage.Local.prototype.onStorage_ = function(e) {
   if (e.storageArea == this.storage_) {
     var t = e.oldValue ? JSON.parse(e.oldValue) : '',
-      r = e.newValue ? JSON.parse(e.newValue) : '',
-      o = {};
-    o[e.key] = {
-      oldValue: t,
-      newValue: r
-    };
+        r = e.newValue ? JSON.parse(e.newValue) : '', o = {};
+    o[e.key] = {oldValue: t, newValue: r};
     for (var i = 0; i < this.observers_.length; i++) this.observers_[i](o);
   }
-};, lib.Storage.Local.prototype.addObserver = function(e) {
+};
+, lib.Storage.Local.prototype.addObserver = function(e) {
   this.observers_.push(e);
-};, lib.Storage.Local.prototype.removeObserver = function(e) {
-  var t = this.observers_.indexOf(e); - 1 != t && this.observers_.splice(t, 1);
-};, lib.Storage.Local.prototype.clear = function(e) {
+};
+, lib.Storage.Local.prototype.removeObserver = function(e) {
+  var t = this.observers_.indexOf(e);
+  -1 != t && this.observers_.splice(t, 1);
+};
+, lib.Storage.Local.prototype.clear = function(e) {
   this.storage_.clear(), e && setTimeout(e, 0);
-};, lib.Storage.Local.prototype.getItem = function(e, t) {
+};
+, lib.Storage.Local.prototype.getItem = function(e, t) {
   var r = this.storage_.getItem(e);
   if ('string' == typeof r) try {
-    r = JSON.parse(r);
-  }
-  catch (o) {}
+      r = JSON.parse(r);
+    } catch (o) {
+    }
   setTimeout(t.bind(null, r), 0);
-};, lib.Storage.Local.prototype.getItems = function(e, t) {
+};
+, lib.Storage.Local.prototype.getItems = function(e, t) {
   for (var r = {}, o = e.length - 1; o >= 0; o--) {
-    var i = e[o],
-      s = this.storage_.getItem(i);
+    var i = e[o], s = this.storage_.getItem(i);
     if ('string' == typeof s) try {
-      r[i] = JSON.parse(s);
-    }
-    catch (n) {
-      r[i] = s;
-    }
-    else e.splice(o, 1);
+        r[i] = JSON.parse(s);
+      } catch (n) {
+        r[i] = s;
+      }
+    else
+      e.splice(o, 1);
   }
   setTimeout(t.bind(null, r), 0);
-};, lib.Storage.Local.prototype.setItem = function(e, t, r) {
+};
+, lib.Storage.Local.prototype.setItem = function(e, t, r) {
   this.storage_.setItem(e, JSON.stringify(t)), r && setTimeout(r, 0);
-};, lib.Storage.Local.prototype.setItems = function(e, t) {
+};
+, lib.Storage.Local.prototype.setItems = function(e, t) {
   for (var r in e) this.storage_.setItem(r, JSON.stringify(e[r]));
   t && setTimeout(t, 0);
-};, lib.Storage.Local.prototype.removeItem = function(e, t) {
+};
+, lib.Storage.Local.prototype.removeItem = function(e, t) {
   this.storage_.removeItem(e), t && setTimeout(t, 0);
-};, lib.Storage.Local.prototype.removeItems = function(e, t) {
+};
+, lib.Storage.Local.prototype.removeItems = function(e, t) {
   for (var r = 0; r < e.length; r++) this.storage_.removeItem(e[r]);
   t && setTimeout(t, 0);
-};, lib.Storage.Memory = function() {
+};
+, lib.Storage.Memory = function() {
   this.observers_ = [], this.storage_ = {};
-};, lib.Storage.Memory.prototype.addObserver = function(e) {
+};
+, lib.Storage.Memory.prototype.addObserver = function(e) {
   this.observers_.push(e);
-};, lib.Storage.Memory.prototype.removeObserver = function(e) {
-  var t = this.observers_.indexOf(e); - 1 != t && this.observers_.splice(t, 1);
-};, lib.Storage.Memory.prototype.clear = function(e) {
+};
+, lib.Storage.Memory.prototype.removeObserver = function(e) {
+  var t = this.observers_.indexOf(e);
+  -1 != t && this.observers_.splice(t, 1);
+};
+, lib.Storage.Memory.prototype.clear = function(e) {
   var t = {};
-  for (var r in this.storage_) t[r] = {
-    oldValue: this.storage_[r],
-    newValue: void 0
-  };
+  for (var r in this.storage_)
+    t[r] = {oldValue: this.storage_[r], newValue: void 0};
   this.storage_ = {}, setTimeout(function() {
     for (var e = 0; e < this.observers_.length; e++) this.observers_[e](t);
   }.bind(this), 0), e && setTimeout(e, 0);
-};, lib.Storage.Memory.prototype.getItem = function(e, t) {
+};
+, lib.Storage.Memory.prototype.getItem = function(e, t) {
   var r = this.storage_[e];
   if ('string' == typeof r) try {
-    r = JSON.parse(r);
-  }
-  catch (o) {}
+      r = JSON.parse(r);
+    } catch (o) {
+    }
   setTimeout(t.bind(null, r), 0);
-};, lib.Storage.Memory.prototype.getItems = function(e, t) {
+};
+, lib.Storage.Memory.prototype.getItems = function(e, t) {
   for (var r = {}, o = e.length - 1; o >= 0; o--) {
-    var i = e[o],
-      s = this.storage_[i];
+    var i = e[o], s = this.storage_[i];
     if ('string' == typeof s) try {
-      r[i] = JSON.parse(s);
-    }
-    catch (n) {
-      r[i] = s;
-    }
-    else e.splice(o, 1);
+        r[i] = JSON.parse(s);
+      } catch (n) {
+        r[i] = s;
+      }
+    else
+      e.splice(o, 1);
   }
   setTimeout(t.bind(null, r), 0);
-};, lib.Storage.Memory.prototype.setItem = function(e, t, r) {
+};
+, lib.Storage.Memory.prototype.setItem = function(e, t, r) {
   var o = this.storage_[e];
   this.storage_[e] = JSON.stringify(t);
   var i = {};
-  i[e] = {
-    oldValue: o,
-    newValue: t
-  }, setTimeout(function() {
+  i[e] = {oldValue: o, newValue: t}, setTimeout(function() {
     for (var e = 0; e < this.observers_.length; e++) this.observers_[e](i);
   }.bind(this), 0), r && setTimeout(r, 0);
-};, lib.Storage.Memory.prototype.setItems = function(e, t) {
+};
+, lib.Storage.Memory.prototype.setItems = function(e, t) {
   var r = {};
-  for (var o in e) r[o] = {
-    oldValue: this.storage_[o],
-    newValue: e[o]
-  }, this.storage_[o] = JSON.stringify(e[o]);
+  for (var o in e)
+    r[o] = {oldValue: this.storage_[o], newValue: e[o]},
+    this.storage_[o] = JSON.stringify(e[o]);
   setTimeout(function() {
     for (var e = 0; e < this.observers_.length; e++) this.observers_[e](r);
-  }.bind(this)), t && setTimeout(t, 0);
-};, lib.Storage.Memory.prototype.removeItem = function(e, t) {
+  }.bind(this)),
+      t && setTimeout(t, 0);
+};
+, lib.Storage.Memory.prototype.removeItem = function(e, t) {
   delete this.storage_[e], t && setTimeout(t, 0);
-};, lib.Storage.Memory.prototype.removeItems = function(e, t) {
+};
+, lib.Storage.Memory.prototype.removeItems = function(e, t) {
   for (var r = 0; r < e.length; r++) delete this.storage_[e[r]];
   t && setTimeout(t, 0);
-};, lib.TestManager = function(e) {
+};
+, lib.TestManager = function(e) {
   this.log = e || new lib.TestManager.Log;
-};, lib.TestManager.prototype.createTestRun = function(e) {
+};
+, lib.TestManager.prototype.createTestRun = function(e) {
   return new lib.TestManager.TestRun(this, e);
-};, lib.TestManager.prototype.onTestRunComplete = function(e) {};, lib.TestManager.prototype.testPreamble = function(e, t) {};, lib.TestManager.prototype.testPostamble = function(e, t) {};, lib.TestManager.Log = function(e) {
+};
+, lib.TestManager.prototype.onTestRunComplete = function(e) {};
+, lib.TestManager.prototype.testPreamble = function(e, t) {};
+, lib.TestManager.prototype.testPostamble = function(e, t) {};
+, lib.TestManager.Log = function(e) {
   this.save = !1, this.data = '', this.logFunction_ = e || function(e) {
     this.save && (this.data += e + '\n'), console.log(e);
-  };, this.pending_ = '', this.prefix_ = '', this.prefixStack_ = [];
-};, lib.TestManager.Log.prototype.pushPrefix = function(e) {
+  };
+  , this.pending_ = '', this.prefix_ = '', this.prefixStack_ = [];
+};
+, lib.TestManager.Log.prototype.pushPrefix = function(e) {
   this.prefixStack_.push(e), this.prefix_ = this.prefixStack_.join('');
-};, lib.TestManager.Log.prototype.popPrefix = function() {
+};
+, lib.TestManager.Log.prototype.popPrefix = function() {
   this.prefixStack_.pop(), this.prefix_ = this.prefixStack_.join('');
-};, lib.TestManager.Log.prototype.print = function(e) {
+};
+, lib.TestManager.Log.prototype.print = function(e) {
   this.pending_ ? this.pending_ += e : this.pending_ = this.prefix_ + e;
-};, lib.TestManager.Log.prototype.println = function(e) {
+};
+, lib.TestManager.Log.prototype.println = function(e) {
   this.pending_ && this.flush(), this.logFunction_(this.prefix_ + e);
-};, lib.TestManager.Log.prototype.flush = function() {
+};
+, lib.TestManager.Log.prototype.flush = function() {
   this.pending_ && (this.logFunction_(this.pending_), this.pending_ = '');
-};, lib.TestManager.Suite = function(e) {
+};
+, lib.TestManager.Suite = function(e) {
   function t(t, r) {
     this.testManager_ = t, this.suiteName = e, this.setup(r);
   }
-  return t.suiteName = e, t.addTest = lib.TestManager.Suite.addTest, t.disableTest = lib.TestManager.Suite.disableTest, t.getTest = lib.TestManager.Suite.getTest, t.getTestList = lib.TestManager.Suite.getTestList, t.testList_ = [], t.testMap_ = {}, t.prototype = {
-    __proto__: lib.TestManager.Suite.prototype
-  }, lib.TestManager.Suite.subclasses.push(t), t;
-};, lib.TestManager.Suite.subclasses = [], lib.TestManager.Suite.addTest = function(e, t) {
-  if (e in this.testMap_) throw 'Duplicate test name: ' + e;
-  var r = new lib.TestManager.Test(this, e, t);
-  this.testMap_[e] = r, this.testList_.push(r);
-};, lib.TestManager.Suite.disableTest = function(e, t) {
+  return t.suiteName = e, t.addTest = lib.TestManager.Suite.addTest,
+         t.disableTest = lib.TestManager.Suite.disableTest,
+         t.getTest = lib.TestManager.Suite.getTest,
+         t.getTestList = lib.TestManager.Suite.getTestList, t.testList_ = [],
+         t.testMap_ = {},
+         t.prototype = {__proto__: lib.TestManager.Suite.prototype},
+         lib.TestManager.Suite.subclasses.push(t), t;
+};
+, lib.TestManager.Suite.subclasses = [],
+  lib.TestManager.Suite.addTest = function(e, t) {
+    if (e in this.testMap_) throw 'Duplicate test name: ' + e;
+    var r = new lib.TestManager.Test(this, e, t);
+    this.testMap_[e] = r, this.testList_.push(r);
+  };
+, lib.TestManager.Suite.disableTest = function(e, t) {
   if (e in this.testMap_) throw 'Duplicate test name: ' + e;
   var r = new lib.TestManager.Test(this, e, t);
   console.log('Disabled test: ' + r.fullName);
-};, lib.TestManager.Suite.getTest = function(e) {
+};
+, lib.TestManager.Suite.getTest = function(e) {
   return this.testMap_[e];
-};, lib.TestManager.Suite.getTestList = function() {
+};
+, lib.TestManager.Suite.getTestList = function() {
   return this.testList_;
-};, lib.TestManager.Suite.prototype.setDefaults = function(e, t) {
+};
+, lib.TestManager.Suite.prototype.setDefaults = function(e, t) {
   for (var r in t) this[r] = r in e ? e[r] : t[r];
-};, lib.TestManager.Suite.prototype.setup = function(e) {};, lib.TestManager.Suite.prototype.preamble = function(e, t) {};, lib.TestManager.Suite.prototype.postamble = function(e, t) {};, lib.TestManager.Test = function(e, t, r) {
-  this.suiteClass = e, this.testName = t, this.fullName = e.suiteName + '[' + t + ']', this.testFunction_ = r;
-};, lib.TestManager.Test.prototype.run = function(e) {
+};
+, lib.TestManager.Suite.prototype.setup = function(e) {};
+, lib.TestManager.Suite.prototype.preamble = function(e, t) {};
+, lib.TestManager.Suite.prototype.postamble = function(e, t) {};
+, lib.TestManager.Test = function(e, t, r) {
+  this.suiteClass = e, this.testName = t,
+  this.fullName = e.suiteName + '[' + t + ']', this.testFunction_ = r;
+};
+, lib.TestManager.Test.prototype.run = function(e) {
   try {
     this.testFunction_.apply(e.suite, [e, e.testRun.cx]);
-  }
-  catch (t) {
+  } catch (t) {
     if (t instanceof lib.TestManager.Result.TestComplete) return;
-    e.println('Test raised an exception: ' + t), t.stack && (t.stack instanceof Array ? e.println(t.stack.join('\n')) : e.println(t.stack)), e.completeTest_(e.FAILED, !1);
+    e.println('Test raised an exception: ' + t),
+        t.stack &&
+        (t.stack instanceof Array ? e.println(t.stack.join('\n')) :
+                                    e.println(t.stack)),
+        e.completeTest_(e.FAILED, !1);
   }
-};, lib.TestManager.TestRun = function(e, t) {
-  this.testManager = e, this.log = e.log, this.cx = t || {}, this.failures = [], this.passes = [], this.startDate = null, this.duration = null, this.currentResult = null, this.maxFailures = 0, this.panic = !1, this.testQueue_ = [];
-};, lib.TestManager.TestRun.prototype.ALL_TESTS = new String('<all-tests>'), lib.TestManager.TestRun.prototype.selectTest = function(e) {
-  this.testQueue_.push(e);
-};, lib.TestManager.TestRun.prototype.selectSuite = function(e, t) {
-  for (var r = t || this.ALL_TESTS, o = 0, i = e.getTestList(), s = 0; s < i.length; s++) {
+};
+, lib.TestManager.TestRun = function(e, t) {
+  this.testManager = e, this.log = e.log, this.cx = t || {}, this.failures = [],
+  this.passes = [], this.startDate = null, this.duration = null,
+  this.currentResult = null, this.maxFailures = 0, this.panic = !1,
+  this.testQueue_ = [];
+};
+, lib.TestManager.TestRun.prototype.ALL_TESTS = new String('<all-tests>'),
+  lib.TestManager.TestRun.prototype.selectTest = function(e) {
+    this.testQueue_.push(e);
+  };
+, lib.TestManager.TestRun.prototype.selectSuite = function(e, t) {
+  for (var r = t || this.ALL_TESTS, o = 0, i = e.getTestList(), s = 0;
+       s < i.length; s++) {
     var n = i[s];
     if (r !== this.ALL_TESTS)
       if (r instanceof RegExp) {
         if (!r.test(n.testName)) continue;
-      }
-    else if (n.testName != r) continue;
+      } else if (n.testName != r)
+        continue;
     this.selectTest(n), o++;
   }
   return o;
-};, lib.TestManager.TestRun.prototype.selectPattern = function(e) {
-  for (var t = 0, r = 0; r < lib.TestManager.Suite.subclasses.length; r++) t += this.selectSuite(lib.TestManager.Suite.subclasses[r], e);
+};
+, lib.TestManager.TestRun.prototype.selectPattern = function(e) {
+  for (var t = 0, r = 0; r < lib.TestManager.Suite.subclasses.length; r++)
+    t += this.selectSuite(lib.TestManager.Suite.subclasses[r], e);
   return t || this.log.println('No tests matched selection criteria: ' + e), t;
-};, lib.TestManager.TestRun.prototype.onUncaughtException_ = function(e, t, r) {
-  if (0 == e.indexOf('Uncaught lib.TestManager.Result.TestComplete') || -1 != e.indexOf('status: passed')) return !0;
-  if (this.currentResult && e != 'Uncaught ' + this.currentResult.expectedErrorMessage_) {
+};
+, lib.TestManager.TestRun.prototype.onUncaughtException_ = function(e, t, r) {
+  if (0 == e.indexOf('Uncaught lib.TestManager.Result.TestComplete') ||
+      -1 != e.indexOf('status: passed'))
+    return !0;
+  if (this.currentResult &&
+      e != 'Uncaught ' + this.currentResult.expectedErrorMessage_) {
     var o = 'during';
-    return this.currentResult.status != this.currentResult.PENDING && (o = 'after'), this.log.println('Uncaught exception ' + o + ' test case: ' + this.currentResult.test.fullName), this.log.println(e + ', ' + t + ':' + r), this.currentResult.completeTest_(this.currentResult.FAILED, !1), !1;
+    return this.currentResult.status != this.currentResult.PENDING &&
+               (o = 'after'),
+           this.log.println(
+               'Uncaught exception ' + o +
+               ' test case: ' + this.currentResult.test.fullName),
+           this.log.println(e + ', ' + t + ':' + r),
+           this.currentResult.completeTest_(this.currentResult.FAILED, !1), !1;
   }
-};, lib.TestManager.TestRun.prototype.onTestRunComplete_ = function(e) {
-  return e ? (this.duration = new Date - this.startDate, this.log.popPrefix(), this.log.println('} ' + this.passes.length + ' passed, ' + this.failures.length + ' failed, ' + this.msToSeconds_(this.duration)), this.log.println(''), this.summarize(), window.onerror = null, void this.testManager.onTestRunComplete(this)) : void setTimeout(this.onTestRunComplete_.bind(this), 0, !0);
-};, lib.TestManager.TestRun.prototype.onResultComplete = function(e) {
+};
+, lib.TestManager.TestRun.prototype.onTestRunComplete_ = function(e) {
+  return e ?
+      (this.duration = new Date - this.startDate, this.log.popPrefix(),
+       this.log.println(
+           '} ' + this.passes.length + ' passed, ' + this.failures.length +
+           ' failed, ' + this.msToSeconds_(this.duration)),
+       this.log.println(''), this.summarize(), window.onerror = null,
+       void this.testManager.onTestRunComplete(this)) :
+      void setTimeout(this.onTestRunComplete_.bind(this), 0, !0);
+};
+, lib.TestManager.TestRun.prototype.onResultComplete = function(e) {
   try {
     this.testManager.testPostamble(e, this.cx), e.suite.postamble(e, this.ctx);
+  } catch (t) {
+    this.log.println(
+        'Unexpected exception in postamble: ' + (t.stack ? t.stack : t)),
+        this.panic = !0;
   }
-  catch (t) {
-    this.log.println('Unexpected exception in postamble: ' + (t.stack ? t.stack : t)), this.panic = !0;
-  }
-  if (this.log.popPrefix(), this.log.print('} ' + e.status + ', ' + this.msToSeconds_(e.duration)), this.log.flush(), e.status == e.FAILED) this.failures.push(e), this.currentSuite = null;
+  if (this.log.popPrefix(),
+      this.log.print('} ' + e.status + ', ' + this.msToSeconds_(e.duration)),
+      this.log.flush(), e.status == e.FAILED)
+    this.failures.push(e), this.currentSuite = null;
   else {
-    if (e.status != e.PASSED) return this.log.println('Unknown result status: ' + e.test.fullName + ': ' + e.status), this.panic = !0;
+    if (e.status != e.PASSED)
+      return this.log.println(
+                 'Unknown result status: ' + e.test.fullName + ': ' + e.status),
+             this.panic = !0;
     this.passes.push(e);
   }
   this.runNextTest_();
-};, lib.TestManager.TestRun.prototype.onResultReComplete = function(e, t) {
+};
+, lib.TestManager.TestRun.prototype.onResultReComplete = function(e, t) {
   this.log.println('Late complete for test: ' + e.test.fullName + ': ' + t);
   var r = this.passes.indexOf(e);
   r >= 0 && (this.passes.splice(r, 1), this.failures.push(e));
-};, lib.TestManager.TestRun.prototype.runNextTest_ = function() {
+};
+, lib.TestManager.TestRun.prototype.runNextTest_ = function() {
   if (this.panic || !this.testQueue_.length) return this.onTestRunComplete_();
-  if (this.maxFailures && this.failures.length >= this.maxFailures) return this.log.println('Maximum failure count reached, aborting test run.'), this.onTestRunComplete_();
+  if (this.maxFailures && this.failures.length >= this.maxFailures)
+    return this.log.println(
+               'Maximum failure count reached, aborting test run.'),
+           this.onTestRunComplete_();
   var e = this.testQueue_[0],
-    t = this.currentResult ? this.currentResult.suite : null;
+      t = this.currentResult ? this.currentResult.suite : null;
   try {
-    t && t instanceof e.suiteClass || (this.log.println('Initializing suite: ' + e.suiteClass.suiteName), t = new e.suiteClass(this.testManager, this.cx));
-  }
-  catch (r) {
-    return this.log.println('Exception during setup: ' + (r.stack ? r.stack : r)), this.panic = !0, void this.onTestRunComplete_();
+    t && t instanceof e.suiteClass ||
+        (this.log.println('Initializing suite: ' + e.suiteClass.suiteName),
+         t = new e.suiteClass(this.testManager, this.cx));
+  } catch (r) {
+    return this.log.println(
+               'Exception during setup: ' + (r.stack ? r.stack : r)),
+           this.panic = !0, void this.onTestRunComplete_();
   }
   try {
-    this.log.print('Test: ' + e.fullName + ' {'), this.log.pushPrefix('  '), this.currentResult = new lib.TestManager.Result(this, t, e), this.testManager.testPreamble(this.currentResult, this.cx), t.preamble(this.currentResult, this.cx), this.testQueue_.shift();
-  }
-  catch (r) {
-    return this.log.println('Unexpected exception during test preamble: ' + (r.stack ? r.stack : r)), this.log.popPrefix(), this.log.println('}'), this.panic = !0, void this.onTestRunComplete_();
+    this.log.print('Test: ' + e.fullName + ' {'), this.log.pushPrefix('  '),
+        this.currentResult = new lib.TestManager.Result(this, t, e),
+        this.testManager.testPreamble(this.currentResult, this.cx),
+        t.preamble(this.currentResult, this.cx), this.testQueue_.shift();
+  } catch (r) {
+    return this.log.println(
+               'Unexpected exception during test preamble: ' +
+               (r.stack ? r.stack : r)),
+           this.log.popPrefix(), this.log.println('}'),
+           this.panic = !0, void this.onTestRunComplete_();
   }
   try {
     this.currentResult.run();
+  } catch (r) {
+    this.log.println(
+        'Unexpected exception during test run: ' + (r.stack ? r.stack : r)),
+        this.panic = !0;
   }
-  catch (r) {
-    this.log.println('Unexpected exception during test run: ' + (r.stack ? r.stack : r)), this.panic = !0;
-  }
-};, lib.TestManager.TestRun.prototype.run = function() {
-  this.log.println('Running ' + this.testQueue_.length + ' test(s) {'), this.log.pushPrefix('  '), window.onerror = this.onUncaughtException_.bind(this), this.startDate = new Date, this.runNextTest_();
-};, lib.TestManager.TestRun.prototype.msToSeconds_ = function(e) {
+};
+, lib.TestManager.TestRun.prototype.run = function() {
+  this.log.println('Running ' + this.testQueue_.length + ' test(s) {'),
+      this.log.pushPrefix('  '),
+      window.onerror = this.onUncaughtException_.bind(this),
+      this.startDate = new Date, this.runNextTest_();
+};
+, lib.TestManager.TestRun.prototype.msToSeconds_ = function(e) {
   var t = (e / 1e3).toFixed(2);
   return t + 's';
-};, lib.TestManager.TestRun.prototype.summarize = function() {
+};
+, lib.TestManager.TestRun.prototype.summarize = function() {
   if (this.failures.length)
-    for (var e = 0; e < this.failures.length; e++) this.log.println('FAILED: ' + this.failures[e].test.fullName);
-  this.testQueue_.length && this.log.println('Test run incomplete: ' + this.testQueue_.length + ' test(s) were not run.');
-};, lib.TestManager.Result = function(e, t, r) {
-  this.testRun = e, this.suite = t, this.test = r, this.startDate = null, this.duration = null, this.status = this.PENDING, this.expectedErrorMessage_ = null;
-};, lib.TestManager.Result.prototype.PENDING = 'pending', lib.TestManager.Result.prototype.FAILED = 'FAILED', lib.TestManager.Result.prototype.PASSED = 'passed', lib.TestManager.Result.TestComplete = function(e) {
-  this.result = e;
-};, lib.TestManager.Result.TestComplete.prototype.toString = function() {
-  return 'lib.TestManager.Result.TestComplete: ' + this.result.test.fullName + ', status: ' + this.result.status;
-};, lib.TestManager.Result.prototype.run = function() {
-  this.startDate = new Date, this.test.run(this), this.status != this.PENDING || this.timeout_ || (this.println('Test did not return a value and did not request more time.'), this.completeTest_(this.FAILED, !1));
-};, lib.TestManager.Result.prototype.expectErrorMessage = function(e) {
+    for (var e = 0; e < this.failures.length; e++)
+      this.log.println('FAILED: ' + this.failures[e].test.fullName);
+  this.testQueue_.length &&
+      this.log.println(
+          'Test run incomplete: ' + this.testQueue_.length +
+          ' test(s) were not run.');
+};
+, lib.TestManager.Result = function(e, t, r) {
+  this.testRun = e, this.suite = t, this.test = r, this.startDate = null,
+  this.duration = null, this.status = this.PENDING,
+  this.expectedErrorMessage_ = null;
+};
+, lib.TestManager.Result.prototype.PENDING = 'pending',
+  lib.TestManager.Result.prototype.FAILED = 'FAILED',
+  lib.TestManager.Result.prototype.PASSED = 'passed',
+  lib.TestManager.Result.TestComplete = function(e) {
+    this.result = e;
+  };
+, lib.TestManager.Result.TestComplete.prototype.toString = function() {
+  return 'lib.TestManager.Result.TestComplete: ' + this.result.test.fullName +
+      ', status: ' + this.result.status;
+};
+, lib.TestManager.Result.prototype.run = function() {
+  this.startDate = new Date, this.test.run(this),
+  this.status != this.PENDING || this.timeout_ ||
+      (this.println(
+           'Test did not return a value and did not request more time.'),
+       this.completeTest_(this.FAILED, !1));
+};
+, lib.TestManager.Result.prototype.expectErrorMessage = function(e) {
   this.expectedErrorMessage_ = e;
-};, lib.TestManager.Result.prototype.onTimeout_ = function() {
-  this.timeout_ = null, this.status == this.PENDING && (this.println('Test timed out.'), this.completeTest_(this.FAILED, !1));
-};, lib.TestManager.Result.prototype.requestTime = function(e) {
-  this.timeout_ && clearTimeout(this.timeout_), this.timeout_ = setTimeout(this.onTimeout_.bind(this), e);
-};, lib.TestManager.Result.prototype.completeTest_ = function(e, t) {
-  if (this.status == this.PENDING ? (this.duration = new Date - this.startDate, this.status = e, this.testRun.onResultComplete(this)) : this.testRun.onResultReComplete(this, e), arguments.length < 2 || t) throw new lib.TestManager.Result.TestComplete(this);
-};, lib.TestManager.Result.prototype.arrayEQ_ = function(e, t) {
+};
+, lib.TestManager.Result.prototype.onTimeout_ = function() {
+  this.timeout_ = null,
+  this.status == this.PENDING &&
+      (this.println('Test timed out.'), this.completeTest_(this.FAILED, !1));
+};
+, lib.TestManager.Result.prototype.requestTime = function(e) {
+  this.timeout_ && clearTimeout(this.timeout_),
+      this.timeout_ = setTimeout(this.onTimeout_.bind(this), e);
+};
+, lib.TestManager.Result.prototype.completeTest_ = function(e, t) {
+  if (this.status == this.PENDING ?
+          (this.duration = new Date - this.startDate, this.status = e,
+           this.testRun.onResultComplete(this)) :
+          this.testRun.onResultReComplete(this, e),
+      arguments.length < 2 || t)
+    throw new lib.TestManager.Result.TestComplete(this);
+};
+, lib.TestManager.Result.prototype.arrayEQ_ = function(e, t) {
   if (!e || !t) return !e && !t;
   if (e.length != t.length) return !1;
   for (var r = 0; r < e.length; ++r)
     if (e[r] != t[r]) return !1;
   return !0;
-};, lib.TestManager.Result.prototype.assertEQ = function(e, t, r) {
+};
+, lib.TestManager.Result.prototype.assertEQ = function(e, t, r) {
   function o(e) {
     if ('number' == typeof e) return e;
-    var t = String(e),
-      r = t.split('\n').map(function(e) {
-        return JSON.stringify(e);
-      });
+    var t = String(e), r = t.split('\n').map(function(e) {
+      return JSON.stringify(e);
+    });
     return r.length > 1 ? '\n' + r.join('\n') : r.join('\n');
   }
   if (e !== t && !(t instanceof Array && this.arrayEQ_(e, t))) {
     var i = r ? '[' + r + ']' : '';
-    this.fail('assertEQ' + i + ': ' + this.getCallerLocation_(1) + ': ' + o(e) + ' !== ' + o(t));
+    this.fail(
+        'assertEQ' + i + ': ' + this.getCallerLocation_(1) + ': ' + o(e) +
+        ' !== ' + o(t));
   }
-};, lib.TestManager.Result.prototype.assert = function(e, t) {
+};
+, lib.TestManager.Result.prototype.assert = function(e, t) {
   if (e !== !0) {
     var r = t ? '[' + t + ']' : '';
-    this.fail('assert' + r + ': ' + this.getCallerLocation_(1) + ': ' + String(e));
+    this.fail(
+        'assert' + r + ': ' + this.getCallerLocation_(1) + ': ' + String(e));
   }
-};, lib.TestManager.Result.prototype.getCallerLocation_ = function(e) {
+};
+, lib.TestManager.Result.prototype.getCallerLocation_ = function(e) {
   try {
     throw new Error;
-  }
-  catch (t) {
-    var r = t.stack.split('\n')[e + 2],
-      o = r.match(/([^\/]+:\d+):\d+\)?$/);
+  } catch (t) {
+    var r = t.stack.split('\n')[e + 2], o = r.match(/([^\/]+:\d+):\d+\)?$/);
     return o ? o[1] : '???';
   }
-};, lib.TestManager.Result.prototype.println = function(e) {
+};
+, lib.TestManager.Result.prototype.println = function(e) {
   this.testRun.log.println(e);
-};, lib.TestManager.Result.prototype.fail = function(e) {
+};
+, lib.TestManager.Result.prototype.fail = function(e) {
   arguments.length && this.println(e), this.completeTest_(this.FAILED, !0);
-};, lib.TestManager.Result.prototype.pass = function() {
+};
+, lib.TestManager.Result.prototype.pass = function() {
   this.completeTest_(this.PASSED, !0);
-};, lib.UTF8Decoder = function() {
+};
+, lib.UTF8Decoder = function() {
   this.bytesLeft = 0, this.codePoint = 0, this.lowerBound = 0;
-};, lib.UTF8Decoder.prototype.decode = function(e) {
+};
+, lib.UTF8Decoder.prototype.decode = function(e) {
   for (var t = '', r = 0; r < e.length; r++) {
     var o = e.charCodeAt(r);
-    if (0 == this.bytesLeft) 127 >= o ? t += e.charAt(r) : o >= 192 && 223 >= o ? (this.codePoint = o - 192, this.bytesLeft = 1, this.lowerBound = 128) : o >= 224 && 239 >= o ? (this.codePoint = o - 224, this.bytesLeft = 2, this.lowerBound = 2048) : o >= 240 && 247 >= o ? (this.codePoint = o - 240, this.bytesLeft = 3, this.lowerBound = 65536) : o >= 248 && 251 >= o ? (this.codePoint = o - 248, this.bytesLeft = 4, this.lowerBound = 2097152) : o >= 252 && 253 >= o ? (this.codePoint = o - 252, this.bytesLeft = 5, this.lowerBound = 67108864) : t += '�';
+    if (0 == this.bytesLeft)
+      127 >= o ?
+          t += e.charAt(r) :
+          o >= 192 && 223 >= o ?
+          (this.codePoint = o - 192, this.bytesLeft = 1,
+           this.lowerBound = 128) :
+          o >= 224 && 239 >= o ?
+          (this.codePoint = o - 224, this.bytesLeft = 2,
+           this.lowerBound = 2048) :
+          o >= 240 && 247 >= o ?
+          (this.codePoint = o - 240, this.bytesLeft = 3,
+           this.lowerBound = 65536) :
+          o >= 248 && 251 >= o ?
+          (this.codePoint = o - 248, this.bytesLeft = 4,
+           this.lowerBound = 2097152) :
+          o >= 252 && 253 >= o ? (this.codePoint = o - 252, this.bytesLeft = 5,
+                                  this.lowerBound = 67108864) :
+                                 t += '�';
     else if (o >= 128 && 191 >= o) {
-      if (this.bytesLeft--, this.codePoint = (this.codePoint << 6) + (o - 128), 0 == this.bytesLeft) {
+      if (this.bytesLeft--, this.codePoint = (this.codePoint << 6) + (o - 128),
+          0 == this.bytesLeft) {
         var i = this.codePoint;
-        i < this.lowerBound || i >= 55296 && 57343 >= i || i > 1114111 ? t += '�' : 65536 > i ? t += String.fromCharCode(i) : (i -= 65536, t += String.fromCharCode(55296 + (i >>> 10 & 1023), 56320 + (1023 & i)))
+        i<this.lowerBound || i >= 55296 && 57343 >= i || i>1114111 ?
+            t += '�' :
+            65536 > i ? t += String.fromCharCode(i) :
+                        (i -= 65536,
+                         t += String.fromCharCode(
+                             55296 + (i >>> 10 & 1023), 56320 + (1023 & i)))
       }
-    }
-    else t += '�', this.bytesLeft = 0, r--;
+    } else
+      t += '�', this.bytesLeft = 0, r--;
   }
   return t;
-};, lib.decodeUTF8 = function(e) {
+};
+, lib.decodeUTF8 = function(e) {
   return (new lib.UTF8Decoder).decode(e);
-};, lib.encodeUTF8 = function(e) {
+};
+, lib.encodeUTF8 = function(e) {
   for (var t = '', r = 0; r < e.length; r++) {
     var o = e.charCodeAt(r);
-    if (o >= 56320 && 57343 >= o) o = 65533;
+    if (o >= 56320 && 57343 >= o)
+      o = 65533;
     else if (o >= 55296 && 56319 >= o)
       if (r + 1 < e.length) {
         var i = e.charCodeAt(r + 1);
-        i >= 56320 && 57343 >= i ? (o = 65536 + ((1023 & o) << 10) + (1023 & i), r++) : o = 65533;
-      }
-    else o = 65533;
+        i >= 56320 && 57343 >= i ?
+            (o = 65536 + ((1023 & o) << 10) + (1023 & i), r++) :
+            o = 65533;
+      } else
+        o = 65533;
     var s;
-    if (127 >= o) t += e.charAt(r);
+    if (127 >= o)
+      t += e.charAt(r);
     else
-      for (2047 >= o ? (t += String.fromCharCode(192 | o >>> 6), s = 1) : 65535 >= o ? (t += String.fromCharCode(224 | o >>> 12), s = 2) : (t += String.fromCharCode(240 | o >>> 18), s = 3); s > 0;) s--, t += String.fromCharCode(128 | o >>> 6 * s & 63);
+      for (2047 >= o ?
+               (t += String.fromCharCode(192 | o >>> 6), s = 1) :
+               65535 >= o ? (t += String.fromCharCode(224 | o >>> 12), s = 2) :
+                            (t += String.fromCharCode(240 | o >>> 18), s = 3);
+           s > 0;)
+        s--, t += String.fromCharCode(128 | o >>> 6 * s & 63);
   }
   return t;
-};, String.prototype.codePointAt || ! function() {
-  var e = function(e) {
-    if (null == this) throw TypeError();
-    var t = String(this),
-      r = t.length,
-      o = e ? Number(e) : 0;
-    if (o != o && (o = 0), 0 > o || o >= r) return void 0;
-    var i, s = t.charCodeAt(o);
-    return s >= 55296 && 56319 >= s && r > o + 1 && (i = t.charCodeAt(o + 1), i >= 56320 && 57343 >= i) ? 1024 * (s - 55296) + i - 56320 + 65536 : s;
-  };
-  Object.defineProperty ? Object.defineProperty(String.prototype, 'codePointAt', {
-    value: e,
-    configurable: !0,
-    writable: !0
-  }) : String.prototype.codePointAt = e;
-}(), lib.wc = {}, lib.wc.nulWidth = 0, lib.wc.controlWidth = 0, lib.wc.regardCjkAmbiguous = !1, lib.wc.cjkAmbiguousWidth = 2, lib.wc.combining = [
-  [768, 879],
-  [1155, 1158],
-  [1160, 1161],
-  [1425, 1469],
-  [1471, 1471],
-  [1473, 1474],
-  [1476, 1477],
-  [1479, 1479],
-  [1536, 1539],
-  [1552, 1557],
-  [1611, 1630],
-  [1648, 1648],
-  [1750, 1764],
-  [1767, 1768],
-  [1770, 1773],
-  [1807, 1807],
-  [1809, 1809],
-  [1840, 1866],
-  [1958, 1968],
-  [2027, 2035],
-  [2305, 2306],
-  [2364, 2364],
-  [2369, 2376],
-  [2381, 2381],
-  [2385, 2388],
-  [2402, 2403],
-  [2433, 2433],
-  [2492, 2492],
-  [2497, 2500],
-  [2509, 2509],
-  [2530, 2531],
-  [2561, 2562],
-  [2620, 2620],
-  [2625, 2626],
-  [2631, 2632],
-  [2635, 2637],
-  [2672, 2673],
-  [2689, 2690],
-  [2748, 2748],
-  [2753, 2757],
-  [2759, 2760],
-  [2765, 2765],
-  [2786, 2787],
-  [2817, 2817],
-  [2876, 2876],
-  [2879, 2879],
-  [2881, 2883],
-  [2893, 2893],
-  [2902, 2902],
-  [2946, 2946],
-  [3008, 3008],
-  [3021, 3021],
-  [3134, 3136],
-  [3142, 3144],
-  [3146, 3149],
-  [3157, 3158],
-  [3260, 3260],
-  [3263, 3263],
-  [3270, 3270],
-  [3276, 3277],
-  [3298, 3299],
-  [3393, 3395],
-  [3405, 3405],
-  [3530, 3530],
-  [3538, 3540],
-  [3542, 3542],
-  [3633, 3633],
-  [3636, 3642],
-  [3655, 3662],
-  [3761, 3761],
-  [3764, 3769],
-  [3771, 3772],
-  [3784, 3789],
-  [3864, 3865],
-  [3893, 3893],
-  [3895, 3895],
-  [3897, 3897],
-  [3953, 3966],
-  [3968, 3972],
-  [3974, 3975],
-  [3984, 3991],
-  [3993, 4028],
-  [4038, 4038],
-  [4141, 4144],
-  [4146, 4146],
-  [4150, 4151],
-  [4153, 4153],
-  [4184, 4185],
-  [4448, 4607],
-  [4959, 4959],
-  [5906, 5908],
-  [5938, 5940],
-  [5970, 5971],
-  [6002, 6003],
-  [6068, 6069],
-  [6071, 6077],
-  [6086, 6086],
-  [6089, 6099],
-  [6109, 6109],
-  [6155, 6157],
-  [6313, 6313],
-  [6432, 6434],
-  [6439, 6440],
-  [6450, 6450],
-  [6457, 6459],
-  [6679, 6680],
-  [6912, 6915],
-  [6964, 6964],
-  [6966, 6970],
-  [6972, 6972],
-  [6978, 6978],
-  [7019, 7027],
-  [7616, 7626],
-  [7678, 7679],
-  [8203, 8207],
-  [8234, 8238],
-  [8288, 8291],
-  [8298, 8303],
-  [8400, 8431],
-  [12330, 12335],
-  [12441, 12442],
-  [43014, 43014],
-  [43019, 43019],
-  [43045, 43046],
-  [64286, 64286],
-  [65024, 65039],
-  [65056, 65059],
-  [65279, 65279],
-  [65529, 65531],
-  [68097, 68099],
-  [68101, 68102],
-  [68108, 68111],
-  [68152, 68154],
-  [68159, 68159],
-  [119143, 119145],
-  [119155, 119170],
-  [119173, 119179],
-  [119210, 119213],
-  [119362, 119364],
-  [917505, 917505],
-  [917536, 917631],
-  [917760, 917999]
-], lib.wc.ambiguous = [
-  [161, 161],
-  [164, 164],
-  [167, 168],
-  [170, 170],
-  [174, 174],
-  [176, 180],
-  [182, 186],
-  [188, 191],
-  [198, 198],
-  [208, 208],
-  [215, 216],
-  [222, 225],
-  [230, 230],
-  [232, 234],
-  [236, 237],
-  [240, 240],
-  [242, 243],
-  [247, 250],
-  [252, 252],
-  [254, 254],
-  [257, 257],
-  [273, 273],
-  [275, 275],
-  [283, 283],
-  [294, 295],
-  [299, 299],
-  [305, 307],
-  [312, 312],
-  [319, 322],
-  [324, 324],
-  [328, 331],
-  [333, 333],
-  [338, 339],
-  [358, 359],
-  [363, 363],
-  [462, 462],
-  [464, 464],
-  [466, 466],
-  [468, 468],
-  [470, 470],
-  [472, 472],
-  [474, 474],
-  [476, 476],
-  [593, 593],
-  [609, 609],
-  [708, 708],
-  [711, 711],
-  [713, 715],
-  [717, 717],
-  [720, 720],
-  [728, 731],
-  [733, 733],
-  [735, 735],
-  [913, 929],
-  [931, 937],
-  [945, 961],
-  [963, 969],
-  [1025, 1025],
-  [1040, 1103],
-  [1105, 1105],
-  [8208, 8208],
-  [8211, 8214],
-  [8216, 8217],
-  [8220, 8221],
-  [8224, 8226],
-  [8228, 8231],
-  [8240, 8240],
-  [8242, 8243],
-  [8245, 8245],
-  [8251, 8251],
-  [8254, 8254],
-  [8308, 8308],
-  [8319, 8319],
-  [8321, 8324],
-  [8364, 8364],
-  [8451, 8451],
-  [8453, 8453],
-  [8457, 8457],
-  [8467, 8467],
-  [8470, 8470],
-  [8481, 8482],
-  [8486, 8486],
-  [8491, 8491],
-  [8531, 8532],
-  [8539, 8542],
-  [8544, 8555],
-  [8560, 8569],
-  [8592, 8601],
-  [8632, 8633],
-  [8658, 8658],
-  [8660, 8660],
-  [8679, 8679],
-  [8704, 8704],
-  [8706, 8707],
-  [8711, 8712],
-  [8715, 8715],
-  [8719, 8719],
-  [8721, 8721],
-  [8725, 8725],
-  [8730, 8730],
-  [8733, 8736],
-  [8739, 8739],
-  [8741, 8741],
-  [8743, 8748],
-  [8750, 8750],
-  [8756, 8759],
-  [8764, 8765],
-  [8776, 8776],
-  [8780, 8780],
-  [8786, 8786],
-  [8800, 8801],
-  [8804, 8807],
-  [8810, 8811],
-  [8814, 8815],
-  [8834, 8835],
-  [8838, 8839],
-  [8853, 8853],
-  [8857, 8857],
-  [8869, 8869],
-  [8895, 8895],
-  [8978, 8978],
-  [9312, 9449],
-  [9451, 9547],
-  [9552, 9587],
-  [9600, 9615],
-  [9618, 9621],
-  [9632, 9633],
-  [9635, 9641],
-  [9650, 9651],
-  [9654, 9655],
-  [9660, 9661],
-  [9664, 9665],
-  [9670, 9672],
-  [9675, 9675],
-  [9678, 9681],
-  [9698, 9701],
-  [9711, 9711],
-  [9733, 9734],
-  [9737, 9737],
-  [9742, 9743],
-  [9748, 9749],
-  [9756, 9756],
-  [9758, 9758],
-  [9792, 9792],
-  [9794, 9794],
-  [9824, 9825],
-  [9827, 9829],
-  [9831, 9834],
-  [9836, 9837],
-  [9839, 9839],
-  [10045, 10045],
-  [10102, 10111],
-  [57344, 63743],
-  [65533, 65533],
-  [983040, 1048573],
-  [1048576, 1114109]
-], lib.wc.isSpace = function(e) {
-  var t, r = 0,
-    o = lib.wc.combining.length - 1;
-  if (e < lib.wc.combining[0][0] || e > lib.wc.combining[o][1]) return !1;
-  for (; o >= r;)
-    if (t = Math.floor((r + o) / 2), e > lib.wc.combining[t][1]) r = t + 1;
-    else {
-      if (!(e < lib.wc.combining[t][0])) return !0;
-      o = t - 1;
-    }
-  return !1;
-};, lib.wc.isCjkAmbiguous = function(e) {
-  var t, r = 0,
-    o = lib.wc.ambiguous.length - 1;
+};
+,
+    String.prototype.codePointAt ||
+    !function() {
+      var e = function(e) {
+        if (null == this) throw TypeError();
+        var t = String(this), r = t.length, o = e ? Number(e) : 0;
+        if (o != o && (o = 0), 0 > o || o >= r) return void 0;
+        var i, s = t.charCodeAt(o);
+        return s >= 55296 && 56319 >= s && r > o + 1 &&
+                (i = t.charCodeAt(o + 1), i >= 56320 && 57343 >= i) ?
+            1024 * (s - 55296) + i - 56320 + 65536 :
+            s;
+      };
+      Object.defineProperty ? Object.defineProperty(
+                                  String.prototype, 'codePointAt',
+                                  {value: e, configurable: !0, writable: !0}) :
+                              String.prototype.codePointAt = e;
+    }(),
+    lib.wc = {}, lib.wc.nulWidth = 0, lib.wc.controlWidth = 0,
+    lib.wc.regardCjkAmbiguous = !1, lib.wc.cjkAmbiguousWidth = 2,
+    lib.wc.combining =
+        [
+          [768, 879],       [1155, 1158],     [1160, 1161],
+          [1425, 1469],     [1471, 1471],     [1473, 1474],
+          [1476, 1477],     [1479, 1479],     [1536, 1539],
+          [1552, 1557],     [1611, 1630],     [1648, 1648],
+          [1750, 1764],     [1767, 1768],     [1770, 1773],
+          [1807, 1807],     [1809, 1809],     [1840, 1866],
+          [1958, 1968],     [2027, 2035],     [2305, 2306],
+          [2364, 2364],     [2369, 2376],     [2381, 2381],
+          [2385, 2388],     [2402, 2403],     [2433, 2433],
+          [2492, 2492],     [2497, 2500],     [2509, 2509],
+          [2530, 2531],     [2561, 2562],     [2620, 2620],
+          [2625, 2626],     [2631, 2632],     [2635, 2637],
+          [2672, 2673],     [2689, 2690],     [2748, 2748],
+          [2753, 2757],     [2759, 2760],     [2765, 2765],
+          [2786, 2787],     [2817, 2817],     [2876, 2876],
+          [2879, 2879],     [2881, 2883],     [2893, 2893],
+          [2902, 2902],     [2946, 2946],     [3008, 3008],
+          [3021, 3021],     [3134, 3136],     [3142, 3144],
+          [3146, 3149],     [3157, 3158],     [3260, 3260],
+          [3263, 3263],     [3270, 3270],     [3276, 3277],
+          [3298, 3299],     [3393, 3395],     [3405, 3405],
+          [3530, 3530],     [3538, 3540],     [3542, 3542],
+          [3633, 3633],     [3636, 3642],     [3655, 3662],
+          [3761, 3761],     [3764, 3769],     [3771, 3772],
+          [3784, 3789],     [3864, 3865],     [3893, 3893],
+          [3895, 3895],     [3897, 3897],     [3953, 3966],
+          [3968, 3972],     [3974, 3975],     [3984, 3991],
+          [3993, 4028],     [4038, 4038],     [4141, 4144],
+          [4146, 4146],     [4150, 4151],     [4153, 4153],
+          [4184, 4185],     [4448, 4607],     [4959, 4959],
+          [5906, 5908],     [5938, 5940],     [5970, 5971],
+          [6002, 6003],     [6068, 6069],     [6071, 6077],
+          [6086, 6086],     [6089, 6099],     [6109, 6109],
+          [6155, 6157],     [6313, 6313],     [6432, 6434],
+          [6439, 6440],     [6450, 6450],     [6457, 6459],
+          [6679, 6680],     [6912, 6915],     [6964, 6964],
+          [6966, 6970],     [6972, 6972],     [6978, 6978],
+          [7019, 7027],     [7616, 7626],     [7678, 7679],
+          [8203, 8207],     [8234, 8238],     [8288, 8291],
+          [8298, 8303],     [8400, 8431],     [12330, 12335],
+          [12441, 12442],   [43014, 43014],   [43019, 43019],
+          [43045, 43046],   [64286, 64286],   [65024, 65039],
+          [65056, 65059],   [65279, 65279],   [65529, 65531],
+          [68097, 68099],   [68101, 68102],   [68108, 68111],
+          [68152, 68154],   [68159, 68159],   [119143, 119145],
+          [119155, 119170], [119173, 119179], [119210, 119213],
+          [119362, 119364], [917505, 917505], [917536, 917631],
+          [917760, 917999]
+        ],
+    lib.wc.ambiguous =
+        [
+          [161, 161],     [164, 164],        [167, 168],
+          [170, 170],     [174, 174],        [176, 180],
+          [182, 186],     [188, 191],        [198, 198],
+          [208, 208],     [215, 216],        [222, 225],
+          [230, 230],     [232, 234],        [236, 237],
+          [240, 240],     [242, 243],        [247, 250],
+          [252, 252],     [254, 254],        [257, 257],
+          [273, 273],     [275, 275],        [283, 283],
+          [294, 295],     [299, 299],        [305, 307],
+          [312, 312],     [319, 322],        [324, 324],
+          [328, 331],     [333, 333],        [338, 339],
+          [358, 359],     [363, 363],        [462, 462],
+          [464, 464],     [466, 466],        [468, 468],
+          [470, 470],     [472, 472],        [474, 474],
+          [476, 476],     [593, 593],        [609, 609],
+          [708, 708],     [711, 711],        [713, 715],
+          [717, 717],     [720, 720],        [728, 731],
+          [733, 733],     [735, 735],        [913, 929],
+          [931, 937],     [945, 961],        [963, 969],
+          [1025, 1025],   [1040, 1103],      [1105, 1105],
+          [8208, 8208],   [8211, 8214],      [8216, 8217],
+          [8220, 8221],   [8224, 8226],      [8228, 8231],
+          [8240, 8240],   [8242, 8243],      [8245, 8245],
+          [8251, 8251],   [8254, 8254],      [8308, 8308],
+          [8319, 8319],   [8321, 8324],      [8364, 8364],
+          [8451, 8451],   [8453, 8453],      [8457, 8457],
+          [8467, 8467],   [8470, 8470],      [8481, 8482],
+          [8486, 8486],   [8491, 8491],      [8531, 8532],
+          [8539, 8542],   [8544, 8555],      [8560, 8569],
+          [8592, 8601],   [8632, 8633],      [8658, 8658],
+          [8660, 8660],   [8679, 8679],      [8704, 8704],
+          [8706, 8707],   [8711, 8712],      [8715, 8715],
+          [8719, 8719],   [8721, 8721],      [8725, 8725],
+          [8730, 8730],   [8733, 8736],      [8739, 8739],
+          [8741, 8741],   [8743, 8748],      [8750, 8750],
+          [8756, 8759],   [8764, 8765],      [8776, 8776],
+          [8780, 8780],   [8786, 8786],      [8800, 8801],
+          [8804, 8807],   [8810, 8811],      [8814, 8815],
+          [8834, 8835],   [8838, 8839],      [8853, 8853],
+          [8857, 8857],   [8869, 8869],      [8895, 8895],
+          [8978, 8978],   [9312, 9449],      [9451, 9547],
+          [9552, 9587],   [9600, 9615],      [9618, 9621],
+          [9632, 9633],   [9635, 9641],      [9650, 9651],
+          [9654, 9655],   [9660, 9661],      [9664, 9665],
+          [9670, 9672],   [9675, 9675],      [9678, 9681],
+          [9698, 9701],   [9711, 9711],      [9733, 9734],
+          [9737, 9737],   [9742, 9743],      [9748, 9749],
+          [9756, 9756],   [9758, 9758],      [9792, 9792],
+          [9794, 9794],   [9824, 9825],      [9827, 9829],
+          [9831, 9834],   [9836, 9837],      [9839, 9839],
+          [10045, 10045], [10102, 10111],    [57344, 63743],
+          [65533, 65533], [983040, 1048573], [1048576, 1114109]
+        ],
+    lib.wc.isSpace = function(e) {
+      var t, r = 0, o = lib.wc.combining.length - 1;
+      if (e < lib.wc.combining[0][0] || e > lib.wc.combining[o][1]) return !1;
+      for (; o >= r;)
+        if (t = Math.floor((r + o) / 2), e > lib.wc.combining[t][1])
+          r = t + 1;
+        else {
+          if (!(e < lib.wc.combining[t][0])) return !0;
+          o = t - 1;
+        }
+      return !1;
+    };
+, lib.wc.isCjkAmbiguous = function(e) {
+  var t, r = 0, o = lib.wc.ambiguous.length - 1;
   if (e < lib.wc.ambiguous[0][0] || e > lib.wc.ambiguous[o][1]) return !1;
   for (; o >= r;)
-    if (t = Math.floor((r + o) / 2), e > lib.wc.ambiguous[t][1]) r = t + 1;
+    if (t = Math.floor((r + o) / 2), e > lib.wc.ambiguous[t][1])
+      r = t + 1;
     else {
       if (!(e < lib.wc.ambiguous[t][0])) return !0;
       o = t - 1;
     }
   return !1;
-};, lib.wc.charWidth = function(e) {
-  return lib.wc.regardCjkAmbiguous ? lib.wc.charWidthRegardAmbiguous(e) : lib.wc.charWidthDisregardAmbiguous(e);
-};, lib.wc.charWidthDisregardAmbiguous = function(e) {
-  return 0 === e ? lib.wc.nulWidth : 32 > e || e >= 127 && 160 > e ? lib.wc.controlWidth : 127 > e ? 1 : lib.wc.isSpace(e) ? 0 : 1 + (e >= 4352 && (4447 >= e || 9001 == e || 9002 == e || e >= 11904 && 42191 >= e && 12351 != e || e >= 44032 && 55203 >= e || e >= 63744 && 64255 >= e || e >= 65040 && 65049 >= e || e >= 65072 && 65135 >= e || e >= 65280 && 65376 >= e || e >= 65504 && 65510 >= e || e >= 131072 && 196605 >= e || e >= 196608 && 262141 >= e))
-};, lib.wc.charWidthRegardAmbiguous = function(e) {
-  return lib.wc.isCjkAmbiguous(e) ? lib.wc.cjkAmbiguousWidth : lib.wc.charWidthDisregardAmbiguous(e);
-};, lib.wc.strWidth = function(e) {
+};
+, lib.wc.charWidth = function(e) {
+  return lib.wc.regardCjkAmbiguous ? lib.wc.charWidthRegardAmbiguous(e) :
+                                     lib.wc.charWidthDisregardAmbiguous(e);
+};
+, lib.wc.charWidthDisregardAmbiguous = function(e) {
+  return 0 === e ?
+      lib.wc.nulWidth :
+      32 > e || e >= 127 && 160 > e ? lib.wc.controlWidth :
+                                      127 > e ? 1 :
+                                                lib.wc.isSpace(e) ? 0 :
+                                                                    1 +
+                      (e >= 4352 &&
+                       (4447 >= e || 9001 == e || 9002 == e ||
+                        e >= 11904 && 42191 >= e && 12351 != e ||
+                        e >= 44032 && 55203 >= e || e >= 63744 && 64255 >= e ||
+                        e >= 65040 && 65049 >= e || e >= 65072 && 65135 >= e ||
+                        e >= 65280 && 65376 >= e || e >= 65504 && 65510 >= e ||
+                        e >= 131072 && 196605 >= e ||
+                        e >= 196608 && 262141 >= e))
+};
+, lib.wc.charWidthRegardAmbiguous = function(e) {
+  return lib.wc.isCjkAmbiguous(e) ? lib.wc.cjkAmbiguousWidth :
+                                    lib.wc.charWidthDisregardAmbiguous(e);
+};
+, lib.wc.strWidth = function(e) {
   for (var t, r = 0, o = 0; o < e.length;) {
     var i = e.codePointAt(o);
     if (t = lib.wc.charWidth(i), 0 > t) return -1;
     r += t, o += 65535 >= i ? 1 : 2;
   }
   return r;
-};, lib.wc.substr = function(e, t, r) {
+};
+, lib.wc.substr = function(e, t, r) {
   var o, i, s;
-  for (o = 0, s = 0; o < e.length && (s += lib.wc.charWidth(e.charCodeAt(o)), !(s > t)); o++);
+  for (o = 0, s = 0;
+       o < e.length && (s += lib.wc.charWidth(e.charCodeAt(o)), !(s > t)); o++)
+    ;
   if (void 0 != r) {
-    for (i = o, s = 0; i < e.length && r > s; s += lib.wc.charWidth(e.charCodeAt(i)), i++);
+    for (i = o, s = 0; i < e.length && r > s;
+         s += lib.wc.charWidth(e.charCodeAt(i)), i++)
+      ;
     return s > r && i--, e.substring(o, i);
   }
   return e.substr(o);
-};, lib.wc.substring = function(e, t, r) {
+};
+, lib.wc.substring = function(e, t, r) {
   return lib.wc.substr(e, t, r - t);
-};, lib.resource.add('libdot/changelog/version', 'text/plain', '1.11'), lib.resource.add('libdot/changelog/date', 'text/plain', '2017-04-17'), lib.rtdep('lib.Storage');
+};
+, lib.resource.add('libdot/changelog/version', 'text/plain', '1.11'),
+    lib.resource.add('libdot/changelog/date', 'text/plain', '2017-04-17'),
+    lib.rtdep('lib.Storage');
 var hterm = {};
-hterm.windowType = null, hterm.zoomWarningMessage = 'ZOOM != 100%', hterm.notifyCopyMessage = '✂', hterm.desktopNotificationTitle = '♪ %(title) ♪', hterm.testDeps = ['hterm.ScrollPort.Tests', 'hterm.Screen.Tests', 'hterm.Terminal.Tests', 'hterm.VT.Tests', 'hterm.VT.CannedTests'], lib.registerInit('hterm', function(e) {
-  function t(t) {
-    hterm.windowType = t.type, setTimeout(e, 0);
-  }
+hterm.windowType = null,
+    hterm.zoomWarningMessage = 'ZOOM != 100%', hterm.notifyCopyMessage = '✂',
+    hterm.desktopNotificationTitle = '♪ %(title) ♪',
+    hterm.testDeps =
+        [
+          'hterm.ScrollPort.Tests', 'hterm.Screen.Tests',
+          'hterm.Terminal.Tests', 'hterm.VT.Tests', 'hterm.VT.CannedTests'
+        ],
+    lib.registerInit('hterm', function(e) {
+      function t(t) {
+        hterm.windowType = t.type, setTimeout(e, 0);
+      }
 
-  function r(r) {
-    r && window.chrome ? chrome.windows.get(r.windowId, null, t) : (hterm.windowType = 'normal', setTimeout(e, 0));
-  }
-  if (!hterm.defaultStorage) {
-    var o = navigator.userAgent.match(/\sChrome\/(\d\d)/),
-      i = o ? parseInt(o[1]) : -1;
-    window.chrome && chrome.storage && chrome.storage.sync && i > 21 ? hterm.defaultStorage = new lib.Storage.Chrome(chrome.storage.sync) : hterm.defaultStorage = new lib.Storage.Local;
-  }
-  var s = !1;
-  if (window.chrome && chrome.runtime && chrome.runtime.getManifest) {
-    var n = chrome.runtime.getManifest();
-    s = n.app && n.app.background;
-  }
-  s ? setTimeout(t.bind(null, {
-    type: 'popup'
-  }), 0) : window.chrome && chrome.tabs ? chrome.tabs.getCurrent(r) : setTimeout(t.bind(null, {
-    type: 'normal'
-  }), 0)
-}), hterm.getClientSize = function(e) {
-  return e.getBoundingClientRect();
-};, hterm.getClientWidth = function(e) {
+      function r(r) {
+        r && window.chrome ? chrome.windows.get(r.windowId, null, t) :
+                             (hterm.windowType = 'normal', setTimeout(e, 0));
+      }
+      if (!hterm.defaultStorage) {
+        var o = navigator.userAgent.match(/\sChrome\/(\d\d)/),
+            i = o ? parseInt(o[1]) : -1;
+        window.chrome &&chrome.storage &&chrome.storage.sync &&i > 21 ?
+            hterm.defaultStorage = new lib.Storage.Chrome(chrome.storage.sync) :
+            hterm.defaultStorage = new lib.Storage.Local;
+      }
+      var s = !1;
+      if (window.chrome && chrome.runtime && chrome.runtime.getManifest) {
+        var n = chrome.runtime.getManifest();
+        s = n.app && n.app.background;
+      }
+      s ? setTimeout(t.bind(null, {type: 'popup'}), 0) :
+          window.chrome && chrome.tabs ?
+          chrome.tabs.getCurrent(r) :
+          setTimeout(t.bind(null, {type: 'normal'}), 0)
+    }), hterm.getClientSize = function(e) {
+      return e.getBoundingClientRect();
+    };
+, hterm.getClientWidth = function(e) {
   return e.getBoundingClientRect().width;
-};, hterm.getClientHeight = function(e) {
+};
+, hterm.getClientHeight = function(e) {
   return e.getBoundingClientRect().height;
-};, hterm.copySelectionToClipboard = function(e) {
+};
+, hterm.copySelectionToClipboard = function(e) {
   try {
     e.execCommand('copy');
+  } catch (t) {
   }
-  catch (t) {}
-};, hterm.pasteFromClipboard = function(e) {
+};
+, hterm.pasteFromClipboard = function(e) {
   try {
     e.execCommand('paste');
+  } catch (t) {
   }
-  catch (t) {}
-};, hterm.Size = function(e, t) {
+};
+, hterm.Size = function(e, t) {
   this.width = e, this.height = t;
-};, hterm.Size.prototype.resize = function(e, t) {
+};
+, hterm.Size.prototype.resize = function(e, t) {
   this.width = e, this.height = t;
-};, hterm.Size.prototype.clone = function() {
+};
+, hterm.Size.prototype.clone = function() {
   return new hterm.Size(this.width, this.height);
-};, hterm.Size.prototype.setTo = function(e) {
+};
+, hterm.Size.prototype.setTo = function(e) {
   this.width = e.width, this.height = e.height;
-};, hterm.Size.prototype.equals = function(e) {
+};
+, hterm.Size.prototype.equals = function(e) {
   return this.width == e.width && this.height == e.height;
-};, hterm.Size.prototype.toString = function() {
+};
+, hterm.Size.prototype.toString = function() {
   return '[hterm.Size: ' + this.width + ', ' + this.height + ']';
-};, hterm.RowCol = function(e, t, r) {
+};
+, hterm.RowCol = function(e, t, r) {
   this.row = e, this.column = t, this.overflow = !!r;
-};, hterm.RowCol.prototype.move = function(e, t, r) {
+};
+, hterm.RowCol.prototype.move = function(e, t, r) {
   this.row = e, this.column = t, this.overflow = !!r;
-};, hterm.RowCol.prototype.clone = function() {
+};
+, hterm.RowCol.prototype.clone = function() {
   return new hterm.RowCol(this.row, this.column, this.overflow);
-};, hterm.RowCol.prototype.setTo = function(e) {
+};
+, hterm.RowCol.prototype.setTo = function(e) {
   this.row = e.row, this.column = e.column, this.overflow = e.overflow;
-};, hterm.RowCol.prototype.equals = function(e) {
-  return this.row == e.row && this.column == e.column && this.overflow == e.overflow;
-};, hterm.RowCol.prototype.toString = function() {
-  return '[hterm.RowCol: ' + this.row + ', ' + this.column + ', ' + this.overflow + ']';
-};, lib.rtdep('lib.f'), hterm.Frame = function(e, t, r) {
-  this.terminal_ = e, this.div_ = e.div_, this.url = t, this.options = r || {}, this.iframe_ = null, this.container_ = null, this.messageChannel_ = null;
-};, hterm.Frame.prototype.onMessage_ = function(e) {
-  return 'ipc-init-ok' != e.data.name ? void console.log('Unknown message from frame:', e.data) : (this.sendTerminalInfo_(), this.messageChannel_.port1.onmessage = this.onMessage.bind(this), void this.onLoad());
-};, hterm.Frame.prototype.onMessage = function() {};, 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]);
-};, hterm.Frame.prototype.onLoad = function() {};, hterm.Frame.prototype.sendTerminalInfo_ = function() {
+};
+, hterm.RowCol.prototype.equals = function(e) {
+  return this.row == e.row && this.column == e.column &&
+      this.overflow == e.overflow;
+};
+, hterm.RowCol.prototype.toString = function() {
+  return '[hterm.RowCol: ' + this.row + ', ' + this.column + ', ' +
+      this.overflow + ']';
+};
+, lib.rtdep('lib.f'), hterm.Frame = function(e, t, r) {
+  this.terminal_ = e, this.div_ = e.div_, this.url = t, this.options = r || {},
+  this.iframe_ = null, this.container_ = null, this.messageChannel_ = null;
+};
+, hterm.Frame.prototype.onMessage_ = function(e) {
+  return 'ipc-init-ok' != e.data.name ?
+      void console.log('Unknown message from frame:', e.data) :
+      (this.sendTerminalInfo_(),
+       this.messageChannel_.port1.onmessage = this.onMessage.bind(this),
+       void this.onLoad());
+};
+, hterm.Frame.prototype.onMessage = function() {};
+, 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]);
+};
+, hterm.Frame.prototype.onLoad = function() {};
+, hterm.Frame.prototype.sendTerminalInfo_ = function() {
   lib.f.getAcceptLanguages(function(e) {
     this.postMessage('terminal-info', [{
-      acceptLanguages: e,
-      foregroundColor: this.terminal_.getForegroundColor(),
-      backgroundColor: this.terminal_.getBackgroundColor(),
-      cursorColor: this.terminal_.getCursorColor(),
-      fontSize: this.terminal_.getFontSize(),
-      fontFamily: this.terminal_.getFontFamily(),
-      baseURL: lib.f.getURL('/')
-    }]);
+                       acceptLanguages: e,
+                       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));
-};, hterm.Frame.prototype.onCloseClicked_ = function() {
+};
+, hterm.Frame.prototype.onCloseClicked_ = function() {
   this.close();
-};, hterm.Frame.prototype.close = function() {
-  this.container_ && this.container_.parentNode && (this.container_.parentNode.removeChild(this.container_), this.onClose());
-};, hterm.Frame.prototype.onClose = function() {};, hterm.Frame.prototype.postMessage = function(e, t) {
+};
+, hterm.Frame.prototype.close = function() {
+  this.container_ && this.container_.parentNode &&
+      (this.container_.parentNode.removeChild(this.container_), this.onClose());
+};
+, hterm.Frame.prototype.onClose = function() {};
+, hterm.Frame.prototype.postMessage = function(e, t) {
   if (!this.messageChannel_) throw new Error('Message channel is not set up.');
-  this.messageChannel_.port1.postMessage({
-    name: e,
-    argv: t
-  });
-};, hterm.Frame.prototype.show = function() {
+  this.messageChannel_.port1.postMessage({name: e, argv: t});
+};
+, hterm.Frame.prototype.show = function() {
   function e(e, r) {
     return e in t.options ? t.options[e] : r;
   }
-  var t = this,
-    t = this;
-  if (this.container_ && this.container_.parentNode) return void console.error('Frame already visible');
-  var r = '16px',
-    o = hterm.getClientSize(this.div_),
-    i = e('width', 640),
-    s = e('height', 480),
-    n = ((o.width - i) / 2, (o.height - s) / 2, this.terminal_.document_),
-    a = this.container_ = n.createElement('div');
-  a.style.cssText = 'position: absolute;display: -webkit-flex;-webkit-flex-direction: column;top: 10%;left: 4%;width: 90%;height: 80%;box-shadow: 0 0 2px ' + this.terminal_.getForegroundColor() + ';border: 2px ' + this.terminal_.getForegroundColor() + ' solid;';
+  var t = this, t = this;
+  if (this.container_ && this.container_.parentNode)
+    return void console.error('Frame already visible');
+  var r = '16px', o = hterm.getClientSize(this.div_), i = e('width', 640),
+      s = e('height', 480),
+      n = ((o.width - i) / 2, (o.height - s) / 2, this.terminal_.document_),
+      a = this.container_ = n.createElement('div');
+  a.style.cssText =
+      'position: absolute;display: -webkit-flex;-webkit-flex-direction: column;top: 10%;left: 4%;width: 90%;height: 80%;box-shadow: 0 0 2px ' +
+      this.terminal_.getForegroundColor() + ';border: 2px ' +
+      this.terminal_.getForegroundColor() + ' solid;';
   var l = n.createElement('div');
-  l.style.cssText = 'display: -webkit-flex;-webkit-justify-content: flex-end;height: ' + r + ';background-color: ' + this.terminal_.getForegroundColor() + ';color: ' + this.terminal_.getBackgroundColor() + ';font-size: 16px;font-family: ' + this.terminal_.getFontFamily(), a.appendChild(l);
+  l.style.cssText =
+      'display: -webkit-flex;-webkit-justify-content: flex-end;height: ' + r +
+      ';background-color: ' + this.terminal_.getForegroundColor() +
+      ';color: ' + this.terminal_.getBackgroundColor() +
+      ';font-size: 16px;font-family: ' + this.terminal_.getFontFamily(),
+  a.appendChild(l);
   var h = this.iframe_ = n.createElement('iframe');
-  h.onload = this.onLoad_.bind(this), h.style.cssText = 'display: -webkit-flex;-webkit-flex: 1;width: 100%', h.setAttribute('src', this.url), h.setAttribute('seamless', !0), a.appendChild(h), this.div_.appendChild(a);
-};, lib.rtdep('hterm.Keyboard.KeyMap'), hterm.Keyboard = function(e) {
-  this.terminal = e, this.keyboardElement_ = null, 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)]
-  ], this.keyMap = new hterm.Keyboard.KeyMap(this), this.bindings = new hterm.Keyboard.Bindings(this), this.altGrMode = 'none', this.shiftInsertPaste = !0, this.homeKeysScroll = !1, this.pageKeysScroll = !1, this.ctrlPlusMinusZeroZoom = !0, this.ctrlCCopy = !1, this.ctrlVPaste = !1, this.applicationKeypad = !1, this.applicationCursor = !1, this.backspaceSendsBackspace = !1, this.characterEncoding = 'utf-8', this.metaSendsEscape = !0, this.passMetaV = !0, this.altSendsWhat = 'escape', this.altIsMeta = !1, this.altBackspaceIsMetaBackspace = !1, this.altKeyPressed = 0, this.mediaKeysAreFKeys = !1, this.previousAltSendsWhat_ = null;
-};, hterm.Keyboard.KeyActions = {
+  h.onload = this.onLoad_.bind(this),
+  h.style.cssText = 'display: -webkit-flex;-webkit-flex: 1;width: 100%',
+  h.setAttribute('src', this.url), h.setAttribute('seamless', !0),
+  a.appendChild(h), this.div_.appendChild(a);
+};
+, lib.rtdep('hterm.Keyboard.KeyMap'), hterm.Keyboard = function(e) {
+  this.terminal = e, this.keyboardElement_ = null,
+  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)]
+      ],
+  this.keyMap = new hterm.Keyboard.KeyMap(this),
+  this.bindings = new hterm.Keyboard.Bindings(this), this.altGrMode = 'none',
+  this.shiftInsertPaste = !0, this.homeKeysScroll = !1,
+  this.pageKeysScroll = !1, this.ctrlPlusMinusZeroZoom = !0,
+  this.ctrlCCopy = !1, this.ctrlVPaste = !1, this.applicationKeypad = !1,
+  this.applicationCursor = !1, this.backspaceSendsBackspace = !1,
+  this.characterEncoding = 'utf-8', this.metaSendsEscape = !0,
+  this.passMetaV = !0, this.altSendsWhat = 'escape', this.altIsMeta = !1,
+  this.altBackspaceIsMetaBackspace = !1, this.altKeyPressed = 0,
+  this.mediaKeysAreFKeys = !1, this.previousAltSendsWhat_ = null;
+};
+, hterm.Keyboard.KeyActions = {
   CANCEL: new String('CANCEL'),
   DEFAULT: new String('DEFAULT'),
   PASS: new String('PASS'),
   STRIP: new String('STRIP')
-}, hterm.Keyboard.prototype.encode = function(e) {
-  return 'utf-8' == this.characterEncoding ? this.terminal.vt.encodeUTF8(e) : e;
-};, hterm.Keyboard.prototype.installKeyboard = function(e) {
+},
+  hterm.Keyboard.prototype.encode = function(e) {
+    return 'utf-8' == this.characterEncoding ? this.terminal.vt.encodeUTF8(e) :
+                                               e;
+  };
+, hterm.Keyboard.prototype.installKeyboard = function(e) {
   if (e != this.keyboardElement_) {
     e && this.keyboardElement_ && this.installKeyboard(null);
     for (var t = 0; t < this.handlers_.length; t++) {
       var r = this.handlers_[t];
-      e ? e.addEventListener(r[0], r[1]) : this.keyboardElement_.removeEventListener(r[0], r[1]);
+      e ? e.addEventListener(r[0], r[1]) :
+          this.keyboardElement_.removeEventListener(r[0], r[1]);
     }
     this.keyboardElement_ = e;
   }
-};, hterm.Keyboard.prototype.uninstallKeyboard = function() {
+};
+, hterm.Keyboard.prototype.uninstallKeyboard = function() {
   this.installKeyboard(null);
-};, hterm.Keyboard.prototype.onTextInput_ = function(e) {
-  e.data && e.data.split('').forEach(this.terminal.onVTKeystroke.bind(this.terminal));
-};, hterm.Keyboard.prototype.onKeyPress_ = function(e) {
-  var t, r = String.fromCharCode(e.which),
-    o = r.toLowerCase();
+};
+, hterm.Keyboard.prototype.onTextInput_ = function(e) {
+  e.data &&
+      e.data.split('').forEach(this.terminal.onVTKeystroke.bind(this.terminal));
+};
+, hterm.Keyboard.prototype.onKeyPress_ = function(e) {
+  var t, r = String.fromCharCode(e.which), o = r.toLowerCase();
   if (!e.ctrlKey && !e.metaKey || 'c' != o && 'v' != o) {
     if (e.altKey && 'browser-key' == this.altSendsWhat && 0 == e.charCode) {
       var i = String.fromCharCode(e.keyCode);
       e.shiftKey || (i = i.toLowerCase()), t = i.charCodeAt(0) + 128;
-    }
-    else e.charCode >= 32 && (i = e.charCode);
-    i && this.terminal.onVTKeystroke(String.fromCharCode(i)), e.preventDefault(), e.stopPropagation();
+    } else
+      e.charCode >= 32 && (i = e.charCode);
+    i && this.terminal.onVTKeystroke(String.fromCharCode(i)),
+        e.preventDefault(), e.stopPropagation();
   }
-};, hterm.Keyboard.prototype.preventChromeAppNonCtrlShiftDefault_ = function(e) {
-  window.chrome && window.chrome.app && window.chrome.app.window && (e.ctrlKey && e.shiftKey || e.preventDefault());
-};, hterm.Keyboard.prototype.onFocusOut_ = function(e) {
+};
+, hterm.Keyboard.prototype.preventChromeAppNonCtrlShiftDefault_ = function(e) {
+  window.chrome && window.chrome.app && window.chrome.app.window &&
+      (e.ctrlKey && e.shiftKey || e.preventDefault());
+};
+, hterm.Keyboard.prototype.onFocusOut_ = function(e) {
   this.altKeyPressed = 0;
-};, hterm.Keyboard.prototype.onKeyUp_ = function(e) {
-  18 == e.keyCode && (this.altKeyPressed = this.altKeyPressed & ~(1 << e.location - 1)), 27 == e.keyCode && this.preventChromeAppNonCtrlShiftDefault_(e);
-};, hterm.Keyboard.prototype.onKeyDown_ = function(e) {
+};
+, hterm.Keyboard.prototype.onKeyUp_ = function(e) {
+  18 == e.keyCode &&
+      (this.altKeyPressed = this.altKeyPressed & ~(1 << e.location - 1)),
+      27 == e.keyCode && this.preventChromeAppNonCtrlShiftDefault_(e);
+};
+, hterm.Keyboard.prototype.onKeyDown_ = function(e) {
   function t(s) {
     o = s;
     var a = r[s];
-    return 'function' == typeof a && (a = a.apply(i.keyMap, [e, r])), a === n && 'normal' != s && (a = t('normal')), a;
+    return 'function' == typeof a && (a = a.apply(i.keyMap, [e, r])),
+           a === n && 'normal' != s && (a = t('normal')), a;
   }
-  18 == e.keyCode && (this.altKeyPressed = this.altKeyPressed | 1 << e.location - 1), 27 == e.keyCode && this.preventChromeAppNonCtrlShiftDefault_(e);
+  18 == e.keyCode &&
+      (this.altKeyPressed = this.altKeyPressed | 1 << e.location - 1),
+      27 == e.keyCode && this.preventChromeAppNonCtrlShiftDefault_(e);
   var r = this.keyMap.keyDefs[e.keyCode];
   if (!r) return void console.warn('No definition for keyCode: ' + e.keyCode);
-  var o = null,
-    i = this,
-    s = hterm.Keyboard.KeyActions.CANCEL,
-    n = hterm.Keyboard.KeyActions.DEFAULT,
-    a = hterm.Keyboard.KeyActions.PASS,
-    l = hterm.Keyboard.KeyActions.STRIP,
-    h = e.ctrlKey,
-    c = this.altIsMeta ? !1 : e.altKey,
-    u = this.altIsMeta ? e.altKey || e.metaKey : e.metaKey,
-    g = !/^\[\w+\]$/.test(r.keyCap);
+  var o = null, i = this, s = hterm.Keyboard.KeyActions.CANCEL,
+      n = hterm.Keyboard.KeyActions.DEFAULT, a = hterm.Keyboard.KeyActions.PASS,
+      l = hterm.Keyboard.KeyActions.STRIP, h = e.ctrlKey,
+      c = this.altIsMeta ? !1 : e.altKey,
+      u = this.altIsMeta ? e.altKey || e.metaKey : e.metaKey,
+      g = !/^\[\w+\]$/.test(r.keyCap);
   switch (this.altGrMode) {
     case 'ctrl-alt':
       g && h && c && (h = !1, c = !1);
       break;
     case 'right-alt':
-      g && 2 & this.terminal.keyboard.altKeyPressed && (h = !1, c = !1);
+      g && 2&this.terminal.keyboard.altKeyPressed && (h = !1, c = !1);
       break;
     case 'left-alt':
-      g && 1 & this.terminal.keyboard.altKeyPressed && (h = !1, c = !1);
+      g && 1&this.terminal.keyboard.altKeyPressed && (h = !1, c = !1);
   }
   var d;
   d = t(h ? 'control' : c ? 'alt' : u ? 'meta' : 'normal');
   var p = !e.maskShiftKey && e.shiftKey,
-    m = {
-      keyCode: e.keyCode,
-      shift: e.shiftKey,
-      ctrl: h,
-      alt: c,
-      meta: u
-    },
-    b = this.bindings.getBinding(m);
-  if (b && (p = h = c = u = !1, o = 'normal', d = b.action, 'function' == typeof d && (d = d.call(this, this.terminal, m))), c && 'browser-key' == this.altSendsWhat && d == n && (d = a), d !== a && (d !== n || h || c || u) && (d === l && (c = h = !1, d = r.normal, 'function' == typeof d && (d = d.apply(this.keyMap, [e, r])), d == n && 2 == r.keyCap.length && (d = r.keyCap.substr(p ? 1 : 0, 1))), e.preventDefault(), e.stopPropagation(), d !== s)) {
-    if (d !== n && 'string' != typeof d) return void console.warn('Invalid action: ' + JSON.stringify(d));
-    if ('control' == o ? h = !1 : 'alt' == o ? c = !1 : 'meta' == o && (u = !1), '[' == d.substr(0, 2) && (c || h || p)) {
+      m = {keyCode: e.keyCode, shift: e.shiftKey, ctrl: h, alt: c, meta: u},
+      b = this.bindings.getBinding(m);
+  if (b &&
+          (p = h = c = u = !1, o = 'normal', d = b.action,
+           'function' == typeof d && (d = d.call(this, this.terminal, m))),
+      c && 'browser-key' == this.altSendsWhat && d == n && (d = a),
+      d !== a && (d !== n || h || c || u) &&
+          (d === l &&
+               (c = h = !1, d = r.normal,
+                'function' == typeof d && (d = d.apply(this.keyMap, [e, r])),
+                d == n && 2 == r.keyCap.length &&
+                    (d = r.keyCap.substr(p ? 1 : 0, 1))),
+           e.preventDefault(), e.stopPropagation(), d !== s)) {
+    if (d !== n && 'string' != typeof d)
+      return void console.warn('Invalid action: ' + JSON.stringify(d));
+    if ('control' == o ? h = !1 : 'alt' == o ? c = !1 : 'meta' == o && (u = !1),
+        '[' == d.substr(0, 2) && (c || h || p)) {
       var f;
-      !p || c || h ? !c || p || h ? p && c && !h ? f = ';4' : !h || p || c ? p && h && !c ? f = ';6' : c && h && !p ? f = ';7' : p && c && h && (f = ';8') : f = ';5' : f = ';3' : f = ';2', d = 3 == d.length ? '[1' + f + d.substr(2, 1) : d.substr(0, d.length - 1) + f + d.substr(d.length - 1);
-    }
-    else {
+      !p || c || h ? !c || p || h ?
+                     p && c && !h ?
+                     f = ';4' :
+                     !h || p || c ?
+                     p && h && !c ?
+                     f = ';6' :
+                     c && h && !p ? f = ';7' : p && c && h && (f = ';8') :
+                     f = ';5' :
+                     f = ';3' :
+                     f = ';2',
+                     d = 3 == d.length ?
+          '[1' + f + d.substr(2, 1) :
+          d.substr(0, d.length - 1) + f + d.substr(d.length - 1);
+    } else {
       if (d === n && (d = r.keyCap.substr(p ? 1 : 0, 1), h)) {
-        var y = r.keyCap.substr(0, 1),
-          _ = y.charCodeAt(0);
+        var y = r.keyCap.substr(0, 1), _ = y.charCodeAt(0);
         _ >= 64 && 95 >= _ && (d = String.fromCharCode(_ - 64));
       }
       if (c && '8-bit' == this.altSendsWhat && 1 == d.length) {
         var _ = d.charCodeAt(0) + 128;
         d = String.fromCharCode(_);
-      }(c && 'escape' == this.altSendsWhat || u && this.metaSendsEscape) && (d = '' + d);
+      }
+      (c && 'escape' == this.altSendsWhat || u && this.metaSendsEscape) &&
+          (d = '' + d);
     }
     this.terminal.onVTKeystroke(d);
   }
-};, hterm.Keyboard.Bindings = function() {
+};
+, hterm.Keyboard.Bindings = function() {
   this.bindings_ = {};
-};, hterm.Keyboard.Bindings.prototype.clear = function() {
+};
+, hterm.Keyboard.Bindings.prototype.clear = function() {
   this.bindings_ = {};
-};, hterm.Keyboard.Bindings.prototype.addBinding_ = function(e, t) {
-  var r = null,
-    o = this.bindings_[e.keyCode];
+};
+, hterm.Keyboard.Bindings.prototype.addBinding_ = function(e, t) {
+  var r = null, o = this.bindings_[e.keyCode];
   if (o)
     for (var i = 0; i < o.length; i++)
       if (o[i].keyPattern.matchKeyPattern(e)) {
         r = o[i];
         break;
       }
-  r ? r.action = t : (r = {
-    keyPattern: e,
-    action: t
-  }, o ? (this.bindings_[e.keyCode].push(r), o.sort(function(e, t) {
-    return hterm.Keyboard.KeyPattern.sortCompare(e.keyPattern, t.keyPattern);
-  })) : this.bindings_[e.keyCode] = [r]);
-};, hterm.Keyboard.Bindings.prototype.addBinding = function(e, t) {
+  r ? r.action = t :
+      (r = {keyPattern: e, action: t},
+       o ? (this.bindings_[e.keyCode].push(r), o.sort(function(e, t) {
+         return hterm.Keyboard.KeyPattern.sortCompare(
+             e.keyPattern, t.keyPattern);
+       })) :
+           this.bindings_[e.keyCode] = [r]);
+};
+, hterm.Keyboard.Bindings.prototype.addBinding = function(e, t) {
   if ('string' != typeof e) return void this.addBinding_(e, t);
   var r = new hterm.Parser;
   r.reset(e);
   var o;
   try {
     o = r.parseKeySequence();
-  }
-  catch (i) {
+  } catch (i) {
     return void console.error(i);
   }
-  if (!r.isComplete()) return void console.error(r.error('Expected end of sequence: ' + o));
+  if (!r.isComplete())
+    return void console.error(r.error('Expected end of sequence: ' + o));
   if ('string' == typeof t) {
     r.reset(t);
     try {
       t = r.parseKeyAction();
-    }
-    catch (i) {
+    } catch (i) {
       return void console.error(i);
     }
   }
-  return r.isComplete() ? void this.addBinding_(new hterm.Keyboard.KeyPattern(o), t) : void console.error(r.error('Expected end of sequence: ' + o));
-};, hterm.Keyboard.Bindings.prototype.addBindings = function(e) {
+  return r.isComplete() ?
+      void this.addBinding_(new hterm.Keyboard.KeyPattern(o), t) :
+      void console.error(r.error('Expected end of sequence: ' + o));
+};
+, hterm.Keyboard.Bindings.prototype.addBindings = function(e) {
   for (var t in e) this.addBinding(t, e[t]);
-};, hterm.Keyboard.Bindings.prototype.getBinding = function(e) {
+};
+, hterm.Keyboard.Bindings.prototype.getBinding = function(e) {
   var t = this.bindings_[e.keyCode];
   if (!t) return null;
   for (var r = 0; r < t.length; r++) {
@@ -2101,26 +2420,35 @@
     if (o.keyPattern.matchKeyDown(e)) return o;
   }
   return null;
-};, lib.rtdep('hterm.Keyboard.KeyActions'), hterm.Keyboard.KeyMap = function(e) {
+};
+, lib.rtdep('hterm.Keyboard.KeyActions'), hterm.Keyboard.KeyMap = function(e) {
   this.keyboard = e, this.keyDefs = {}, this.reset();
-};, hterm.Keyboard.KeyMap.prototype.addKeyDef = function(e, t) {
-  e in this.keyDefs && console.warn('Duplicate keyCode: ' + e), this.keyDefs[e] = t;
-};, hterm.Keyboard.KeyMap.prototype.addKeyDefs = function(e) {
-  for (var t = 0; t < arguments.length; t++) this.addKeyDef(arguments[t][0], {
-    keyCap: arguments[t][1],
-    normal: arguments[t][2],
-    control: arguments[t][3],
-    alt: arguments[t][4],
-    meta: arguments[t][5]
-  });
-};, hterm.Keyboard.KeyMap.prototype.reset = function() {
+};
+, hterm.Keyboard.KeyMap.prototype.addKeyDef = function(e, t) {
+  e in this.keyDefs && console.warn('Duplicate keyCode: ' + e),
+      this.keyDefs[e] = t;
+};
+, hterm.Keyboard.KeyMap.prototype.addKeyDefs = function(e) {
+  for (var t = 0; t < arguments.length; t++)
+    this.addKeyDef(arguments[t][0], {
+      keyCap: arguments[t][1],
+      normal: arguments[t][2],
+      control: arguments[t][3],
+      alt: arguments[t][4],
+      meta: arguments[t][5]
+    });
+};
+, hterm.Keyboard.KeyMap.prototype.reset = function() {
   function e(e, t, r) {
     return 'function' == typeof e ? e.apply(h, [t, r]) : e;
   }
 
   function t(t, r) {
     return function(o, i) {
-      var s = o.shiftKey || o.ctrlKey || o.altKey || o.metaKey || !h.keyboard.applicationCursor ? t : r;
+      var s = o.shiftKey || o.ctrlKey || o.altKey || o.metaKey ||
+              !h.keyboard.applicationCursor ?
+          t :
+          r;
       return e(s, o, i);
     }
   }
@@ -2165,38 +2493,152 @@
 
   function l(t) {
     return function(r, o) {
-      return h.keyboard.mediaKeysAreFKeys ? e(t, r, o) : 166 == r.keyCode || 167 == r.keyCode || 168 == r.keyCode ? hterm.Keyboard.KeyActions.CANCEL : hterm.Keyboard.KeyActions.PASS
+      return h.keyboard.mediaKeysAreFKeys ?
+          e(t, r, o) :
+          166 == r.keyCode || 167 == r.keyCode || 168 == r.keyCode ?
+          hterm.Keyboard.KeyActions.CANCEL :
+          hterm.Keyboard.KeyActions.PASS
     }
   }
   this.keyDefs = {};
-  var h = this,
-    c = '',
-    u = '[',
-    g = 'O',
-    d = hterm.Keyboard.KeyActions.CANCEL,
-    p = hterm.Keyboard.KeyActions.DEFAULT,
-    m = hterm.Keyboard.KeyActions.PASS,
-    b = hterm.Keyboard.KeyActions.STRIP;
-  this.addKeyDefs([0, '[UNKNOWN]', m, m, m, m], [27, '[ESC]', c, p, p, p], [112, '[F1]', s(g + 'P', u + 'P'), p, u + '23~', p], [113, '[F2]', s(g + 'Q', u + 'Q'), p, u + '24~', p], [114, '[F3]', s(g + 'R', u + 'R'), p, u + '25~', p], [115, '[F4]', s(g + 'S', u + 'S'), p, u + '26~', p], [116, '[F5]', u + '15~', p, u + '28~', p], [117, '[F6]', u + '17~', p, u + '29~', p], [118, '[F7]', u + '18~', p, u + '31~', p], [119, '[F8]', u + '19~', p, u + '32~', p], [120, '[F9]', u + '20~', p, u + '33~', p], [121, '[F10]', u + '21~', p, u + '34~', p], [122, '[F11]', u + '23~', p, u + '42~', p], [123, '[F12]', u + '24~', p, u + '43~', p], [192, '`~', p, o(n('@'), n('^')), p, m], [49, '1!', p, a('onCtrlNum_'), a('onAltNum_'), a('onMetaNum_')], [50, '2@', p, a('onCtrlNum_'), a('onAltNum_'), a('onMetaNum_')], [51, '3#', p, a('onCtrlNum_'), a('onAltNum_'), a('onMetaNum_')], [52, '4$', p, a('onCtrlNum_'), a('onAltNum_'), a('onMetaNum_')], [53, '5%', p, a('onCtrlNum_'), a('onAltNum_'), a('onMetaNum_')], [54, '6^', p, a('onCtrlNum_'), a('onAltNum_'), a('onMetaNum_')], [55, '7&', p, a('onCtrlNum_'), a('onAltNum_'), a('onMetaNum_')], [56, '8*', p, a('onCtrlNum_'), a('onAltNum_'), a('onMetaNum_')], [57, '9(', p, a('onCtrlNum_'), a('onAltNum_'), a('onMetaNum_')], [48, '0)', p, a('onPlusMinusZero_'), a('onAltNum_'), a('onPlusMinusZero_')], [189, '-_', p, a('onPlusMinusZero_'), p, a('onPlusMinusZero_')], [187, '=+', p, a('onPlusMinusZero_'), p, a('onPlusMinusZero_')], [173, '-_', p, a('onPlusMinusZero_'), p, a('onPlusMinusZero_')], [61, '=+', p, a('onPlusMinusZero_'), p, a('onPlusMinusZero_')], [171, '+*', p, a('onPlusMinusZero_'), p, a('onPlusMinusZero_')], [8, '[BKSP]', r('', '\b'), r('\b', ''), p, p], [9, '[TAB]', o('	', u + 'Z'), b, m, p], [81, 'qQ', p, n('Q'), p, p], [87, 'wW', p, n('W'), p, p], [69, 'eE', p, n('E'), p, p], [82, 'rR', p, n('R'), p, p], [84, 'tT', p, n('T'), p, p], [89, 'yY', p, n('Y'), p, p], [85, 'uU', p, n('U'), p, p], [73, 'iI', p, n('I'), p, p], [79, 'oO', p, n('O'), p, p], [80, 'pP', p, n('P'), p, p], [219, '[{', p, n('['), p, p], [221, ']}', p, n(']'), p, p], [220, '\\|', p, n('\\'), p, p], [20, '[CAPS]', m, m, m, p], [65, 'aA', p, n('A'), p, p], [83, 'sS', p, n('S'), p, p], [68, 'dD', p, n('D'), p, p], [70, 'fF', p, n('F'), p, p], [71, 'gG', p, n('G'), p, p], [72, 'hH', p, n('H'), p, p], [74, 'jJ', p, o(n('J'), m), p, p], [75, 'kK', p, o(n('K'), a('onClear_')), p, p], [76, 'lL', p, o(n('L'), m), p, p], [186, ';:', p, b, p, p], [222, "'\"", p, b, p, p], [13, '[ENTER]', '\r', d, d, p], [16, '[SHIFT]', m, m, m, p], [90, 'zZ', p, n('Z'), p, p], [88, 'xX', p, n('X'), p, p], [67, 'cC', p, a('onCtrlC_'), p, a('onMetaC_')], [86, 'vV', p, a('onCtrlV_'), p, a('onMetaV_')], [66, 'bB', p, o(n('B'), m), p, o(p, m)], [78, 'nN', p, a('onCtrlN_'), p, a('onMetaN_')], [77, 'mM', p, n('M'), p, p], [188, ',<', p, i(b, m), p, p], [190, '.>', p, i(b, m), p, p], [191, '/?', p, o(n('_'), n('?')), p, p], [17, '[CTRL]', m, m, m, m], [18, '[ALT]', m, m, m, m], [91, '[LAPL]', m, m, m, m], [32, ' ', p, n('@'), p, p], [92, '[RAPL]', m, m, m, m], [93, '[RMENU]', m, m, m, m], [42, '[PRTSCR]', m, m, m, m], [145, '[SCRLK]', m, m, m, m], [19, '[BREAK]', m, m, m, m], [45, '[INSERT]', a('onKeyInsert_'), p, p, p], [36, '[HOME]', a('onKeyHome_'), p, p, p], [33, '[PGUP]', a('onKeyPageUp_'), p, p, p], [46, '[DEL]', a('onKeyDel_'), p, p, p], [35, '[END]', a('onKeyEnd_'), p, p, p], [34, '[PGDOWN]', a('onKeyPageDown_'), p, p, p], [38, '[UP]', t(u + 'A', g + 'A'), p, p, p], [40, '[DOWN]', t(u + 'B', g + 'B'), p, p, p], [39, '[RIGHT]', t(u + 'C', g + 'C'), p, p, p], [37, '[LEFT]', t(u + 'D', g + 'D'), p, p, p], [144, '[NUMLOCK]', m, m, m, m], [96, '[KP0]', p, p, p, p], [97, '[KP1]', p, p, p, p], [98, '[KP2]', p, p, p, p], [99, '[KP3]', p, p, p, p], [100, '[KP4]', p, p, p, p], [101, '[KP5]', p, p, p, p], [102, '[KP6]', p, p, p, p], [103, '[KP7]', p, p, p, p], [104, '[KP8]', p, p, p, p], [105, '[KP9]', p, p, p, p], [107, '[KP+]', p, a('onPlusMinusZero_'), p, a('onPlusMinusZero_')], [109, '[KP-]', p, a('onPlusMinusZero_'), p, a('onPlusMinusZero_')], [106, '[KP*]', p, p, p, p], [111, '[KP/]', p, p, p, p], [110, '[KP.]', p, p, p, p], [166, '[BACK]', l(s(g + 'P', u + 'P')), p, u + '23~', p], [167, '[FWD]', l(s(g + 'Q', u + 'Q')), p, u + '24~', p], [168, '[RELOAD]', l(s(g + 'R', u + 'R')), p, u + '25~', p], [183, '[FSCR]', l(s(g + 'S', u + 'S')), p, u + '26~', p], [182, '[WINS]', l(u + '15~'), p, u + '28~', p], [216, '[BRIT-]', l(u + '17~'), p, u + '29~', p], [217, '[BRIT+]', l(u + '18~'), p, u + '31~', p]);
-};, hterm.Keyboard.KeyMap.prototype.onKeyInsert_ = function(e) {
-  return this.keyboard.shiftInsertPaste && e.shiftKey ? hterm.Keyboard.KeyActions.PASS : '[2~';
-};, hterm.Keyboard.KeyMap.prototype.onKeyHome_ = function(e) {
-  return !this.keyboard.homeKeysScroll ^ e.shiftKey ? e.altey || e.ctrlKey || e.shiftKey || !this.keyboard.applicationCursor ? '' : 'OH' : (this.keyboard.terminal.scrollHome(), hterm.Keyboard.KeyActions.CANCEL);
-};, hterm.Keyboard.KeyMap.prototype.onKeyEnd_ = function(e) {
-  return !this.keyboard.homeKeysScroll ^ e.shiftKey ? e.altKey || e.ctrlKey || e.shiftKey || !this.keyboard.applicationCursor ? '' : 'OF' : (this.keyboard.terminal.scrollEnd(), hterm.Keyboard.KeyActions.CANCEL);
-};, hterm.Keyboard.KeyMap.prototype.onKeyPageUp_ = function(e) {
-  return !this.keyboard.pageKeysScroll ^ e.shiftKey ? '[5~' : (this.keyboard.terminal.scrollPageUp(), hterm.Keyboard.KeyActions.CANCEL);
-};, hterm.Keyboard.KeyMap.prototype.onKeyDel_ = function(e) {
-  return this.keyboard.altBackspaceIsMetaBackspace && this.keyboard.altKeyPressed && !e.altKey ? '' : '[3~';
-};, hterm.Keyboard.KeyMap.prototype.onKeyPageDown_ = function(e) {
-  return !this.keyboard.pageKeysScroll ^ e.shiftKey ? '[6~' : (this.keyboard.terminal.scrollPageDown(), hterm.Keyboard.KeyActions.CANCEL);
-};, hterm.Keyboard.KeyMap.prototype.onClear_ = function(e, t) {
-  return this.keyboard.terminal.wipeContents(), hterm.Keyboard.KeyActions.CANCEL;
-};, hterm.Keyboard.KeyMap.prototype.onCtrlNum_ = function(e, t) {
+  var h = this, c = '', u = '[', g = 'O',
+      d = hterm.Keyboard.KeyActions.CANCEL,
+      p = hterm.Keyboard.KeyActions.DEFAULT, m = hterm.Keyboard.KeyActions.PASS,
+      b = hterm.Keyboard.KeyActions.STRIP;
+  this.addKeyDefs(
+      [0, '[UNKNOWN]', m, m, m, m], [27, '[ESC]', c, p, p, p],
+      [112, '[F1]', s(g + 'P', u + 'P'), p, u + '23~', p],
+      [113, '[F2]', s(g + 'Q', u + 'Q'), p, u + '24~', p],
+      [114, '[F3]', s(g + 'R', u + 'R'), p, u + '25~', p],
+      [115, '[F4]', s(g + 'S', u + 'S'), p, u + '26~', p],
+      [116, '[F5]', u + '15~', p, u + '28~', p],
+      [117, '[F6]', u + '17~', p, u + '29~', p],
+      [118, '[F7]', u + '18~', p, u + '31~', p],
+      [119, '[F8]', u + '19~', p, u + '32~', p],
+      [120, '[F9]', u + '20~', p, u + '33~', p],
+      [121, '[F10]', u + '21~', p, u + '34~', p],
+      [122, '[F11]', u + '23~', p, u + '42~', p],
+      [123, '[F12]', u + '24~', p, u + '43~', p],
+      [192, '`~', p, o(n('@'), n('^')), p, m],
+      [49, '1!', p, a('onCtrlNum_'), a('onAltNum_'), a('onMetaNum_')],
+      [50, '2@', p, a('onCtrlNum_'), a('onAltNum_'), a('onMetaNum_')],
+      [51, '3#', p, a('onCtrlNum_'), a('onAltNum_'), a('onMetaNum_')],
+      [52, '4$', p, a('onCtrlNum_'), a('onAltNum_'), a('onMetaNum_')],
+      [53, '5%', p, a('onCtrlNum_'), a('onAltNum_'), a('onMetaNum_')],
+      [54, '6^', p, a('onCtrlNum_'), a('onAltNum_'), a('onMetaNum_')],
+      [55, '7&', p, a('onCtrlNum_'), a('onAltNum_'), a('onMetaNum_')],
+      [56, '8*', p, a('onCtrlNum_'), a('onAltNum_'), a('onMetaNum_')],
+      [57, '9(', p, a('onCtrlNum_'), a('onAltNum_'), a('onMetaNum_')],
+      [
+        48, '0)', p, a('onPlusMinusZero_'), a('onAltNum_'),
+        a('onPlusMinusZero_')
+      ],
+      [189, '-_', p, a('onPlusMinusZero_'), p, a('onPlusMinusZero_')],
+      [187, '=+', p, a('onPlusMinusZero_'), p, a('onPlusMinusZero_')],
+      [173, '-_', p, a('onPlusMinusZero_'), p, a('onPlusMinusZero_')],
+      [61, '=+', p, a('onPlusMinusZero_'), p, a('onPlusMinusZero_')],
+      [171, '+*', p, a('onPlusMinusZero_'), p, a('onPlusMinusZero_')],
+      [8, '[BKSP]', r('', '\b'), r('\b', ''), p, p],
+      [9, '[TAB]', o('	', u + 'Z'), b, m, p], [81, 'qQ', p, n('Q'), p, p],
+      [87, 'wW', p, n('W'), p, p], [69, 'eE', p, n('E'), p, p],
+      [82, 'rR', p, n('R'), p, p], [84, 'tT', p, n('T'), p, p],
+      [89, 'yY', p, n('Y'), p, p], [85, 'uU', p, n('U'), p, p],
+      [73, 'iI', p, n('I'), p, p], [79, 'oO', p, n('O'), p, p],
+      [80, 'pP', p, n('P'), p, p], [219, '[{', p, n('['), p, p],
+      [221, ']}', p, n(']'), p, p], [220, '\\|', p, n('\\'), p, p],
+      [20, '[CAPS]', m, m, m, p], [65, 'aA', p, n('A'), p, p],
+      [83, 'sS', p, n('S'), p, p], [68, 'dD', p, n('D'), p, p],
+      [70, 'fF', p, n('F'), p, p], [71, 'gG', p, n('G'), p, p],
+      [72, 'hH', p, n('H'), p, p], [74, 'jJ', p, o(n('J'), m), p, p],
+      [75, 'kK', p, o(n('K'), a('onClear_')), p, p],
+      [76, 'lL', p, o(n('L'), m), p, p], [186, ';:', p, b, p, p],
+      [222, '\'"', p, b, p, p], [13, '[ENTER]', '\r', d, d, p],
+      [16, '[SHIFT]', m, m, m, p], [90, 'zZ', p, n('Z'), p, p],
+      [88, 'xX', p, n('X'), p, p],
+      [67, 'cC', p, a('onCtrlC_'), p, a('onMetaC_')],
+      [86, 'vV', p, a('onCtrlV_'), p, a('onMetaV_')],
+      [66, 'bB', p, o(n('B'), m), p, o(p, m)],
+      [78, 'nN', p, a('onCtrlN_'), p, a('onMetaN_')],
+      [77, 'mM', p, n('M'), p, p], [188, ',<', p, i(b, m), p, p],
+      [190, '.>', p, i(b, m), p, p], [191, '/?', p, o(n('_'), n('?')), p, p],
+      [17, '[CTRL]', m, m, m, m], [18, '[ALT]', m, m, m, m],
+      [91, '[LAPL]', m, m, m, m], [32, ' ', p, n('@'), p, p],
+      [92, '[RAPL]', m, m, m, m], [93, '[RMENU]', m, m, m, m],
+      [42, '[PRTSCR]', m, m, m, m], [145, '[SCRLK]', m, m, m, m],
+      [19, '[BREAK]', m, m, m, m], [45, '[INSERT]', a('onKeyInsert_'), p, p, p],
+      [36, '[HOME]', a('onKeyHome_'), p, p, p],
+      [33, '[PGUP]', a('onKeyPageUp_'), p, p, p],
+      [46, '[DEL]', a('onKeyDel_'), p, p, p],
+      [35, '[END]', a('onKeyEnd_'), p, p, p],
+      [34, '[PGDOWN]', a('onKeyPageDown_'), p, p, p],
+      [38, '[UP]', t(u + 'A', g + 'A'), p, p, p],
+      [40, '[DOWN]', t(u + 'B', g + 'B'), p, p, p],
+      [39, '[RIGHT]', t(u + 'C', g + 'C'), p, p, p],
+      [37, '[LEFT]', t(u + 'D', g + 'D'), p, p, p],
+      [144, '[NUMLOCK]', m, m, m, m], [96, '[KP0]', p, p, p, p],
+      [97, '[KP1]', p, p, p, p], [98, '[KP2]', p, p, p, p],
+      [99, '[KP3]', p, p, p, p], [100, '[KP4]', p, p, p, p],
+      [101, '[KP5]', p, p, p, p], [102, '[KP6]', p, p, p, p],
+      [103, '[KP7]', p, p, p, p], [104, '[KP8]', p, p, p, p],
+      [105, '[KP9]', p, p, p, p],
+      [107, '[KP+]', p, a('onPlusMinusZero_'), p, a('onPlusMinusZero_')],
+      [109, '[KP-]', p, a('onPlusMinusZero_'), p, a('onPlusMinusZero_')],
+      [106, '[KP*]', p, p, p, p], [111, '[KP/]', p, p, p, p],
+      [110, '[KP.]', p, p, p, p],
+      [166, '[BACK]', l(s(g + 'P', u + 'P')), p, u + '23~', p],
+      [167, '[FWD]', l(s(g + 'Q', u + 'Q')), p, u + '24~', p],
+      [168, '[RELOAD]', l(s(g + 'R', u + 'R')), p, u + '25~', p],
+      [183, '[FSCR]', l(s(g + 'S', u + 'S')), p, u + '26~', p],
+      [182, '[WINS]', l(u + '15~'), p, u + '28~', p],
+      [216, '[BRIT-]', l(u + '17~'), p, u + '29~', p],
+      [217, '[BRIT+]', l(u + '18~'), p, u + '31~', p]);
+};
+, hterm.Keyboard.KeyMap.prototype.onKeyInsert_ = function(e) {
+  return this.keyboard.shiftInsertPaste && e.shiftKey ?
+      hterm.Keyboard.KeyActions.PASS :
+      '[2~';
+};
+, hterm.Keyboard.KeyMap.prototype.onKeyHome_ = function(e) {
+  return !this.keyboard.homeKeysScroll ^ e.shiftKey ?
+      e.altey || e.ctrlKey || e.shiftKey || !this.keyboard.applicationCursor ?
+      '' :
+      'OH' :
+      (this.keyboard.terminal.scrollHome(), hterm.Keyboard.KeyActions.CANCEL);
+};
+, hterm.Keyboard.KeyMap.prototype.onKeyEnd_ = function(e) {
+  return !this.keyboard.homeKeysScroll ^ e.shiftKey ?
+      e.altKey || e.ctrlKey || e.shiftKey || !this.keyboard.applicationCursor ?
+      '' :
+      'OF' :
+      (this.keyboard.terminal.scrollEnd(), hterm.Keyboard.KeyActions.CANCEL);
+};
+, hterm.Keyboard.KeyMap.prototype.onKeyPageUp_ = function(e) {
+  return !this.keyboard.pageKeysScroll ^ e.shiftKey ?
+      '[5~' :
+      (this.keyboard.terminal.scrollPageUp(), hterm.Keyboard.KeyActions.CANCEL);
+};
+, hterm.Keyboard.KeyMap.prototype.onKeyDel_ = function(e) {
+  return this.keyboard.altBackspaceIsMetaBackspace &&
+          this.keyboard.altKeyPressed && !e.altKey ?
+      '' :
+      '[3~';
+};
+, hterm.Keyboard.KeyMap.prototype.onKeyPageDown_ = function(e) {
+  return !this.keyboard.pageKeysScroll ^ e.shiftKey ?
+      '[6~' :
+      (this.keyboard.terminal.scrollPageDown(),
+       hterm.Keyboard.KeyActions.CANCEL);
+};
+, hterm.Keyboard.KeyMap.prototype.onClear_ = function(e, t) {
+  return this.keyboard.terminal.wipeContents(),
+         hterm.Keyboard.KeyActions.CANCEL;
+};
+, hterm.Keyboard.KeyMap.prototype.onCtrlNum_ = function(e, t) {
   function r(e) {
     return String.fromCharCode(e.charCodeAt(0) - 64);
   }
-  if (this.keyboard.terminal.passCtrlNumber && !e.shiftKey) return hterm.Keyboard.KeyActions.PASS;
+  if (this.keyboard.terminal.passCtrlNumber && !e.shiftKey)
+    return hterm.Keyboard.KeyActions.PASS;
   switch (t.keyCap.substr(0, 1)) {
     case '1':
       return '1';
@@ -2217,88 +2659,158 @@
     case '9':
       return '9';
   }
-};, hterm.Keyboard.KeyMap.prototype.onAltNum_ = function(e, t) {
-  return this.keyboard.terminal.passAltNumber && !e.shiftKey ? hterm.Keyboard.KeyActions.PASS : hterm.Keyboard.KeyActions.DEFAULT;
-};, hterm.Keyboard.KeyMap.prototype.onMetaNum_ = function(e, t) {
-  return this.keyboard.terminal.passMetaNumber && !e.shiftKey ? hterm.Keyboard.KeyActions.PASS : hterm.Keyboard.KeyActions.DEFAULT;
-};, hterm.Keyboard.KeyMap.prototype.onCtrlC_ = function(e, t) {
+};
+, hterm.Keyboard.KeyMap.prototype.onAltNum_ = function(e, t) {
+  return this.keyboard.terminal.passAltNumber && !e.shiftKey ?
+      hterm.Keyboard.KeyActions.PASS :
+      hterm.Keyboard.KeyActions.DEFAULT;
+};
+, hterm.Keyboard.KeyMap.prototype.onMetaNum_ = function(e, t) {
+  return this.keyboard.terminal.passMetaNumber && !e.shiftKey ?
+      hterm.Keyboard.KeyActions.PASS :
+      hterm.Keyboard.KeyActions.DEFAULT;
+};
+, hterm.Keyboard.KeyMap.prototype.onCtrlC_ = function(e, t) {
   var r = this.keyboard.terminal.getDocument().getSelection();
   if (!r.isCollapsed) {
-    if (this.keyboard.ctrlCCopy && !e.shiftKey) return this.keyboard.terminal.clearSelectionAfterCopy && setTimeout(r.collapseToEnd.bind(r), 50), hterm.Keyboard.KeyActions.PASS;
-    if (!this.keyboard.ctrlCCopy && e.shiftKey) return this.keyboard.terminal.clearSelectionAfterCopy && setTimeout(r.collapseToEnd.bind(r), 50), this.keyboard.terminal.copySelectionToClipboard(), hterm.Keyboard.KeyActions.CANCEL;
+    if (this.keyboard.ctrlCCopy && !e.shiftKey)
+      return this.keyboard.terminal.clearSelectionAfterCopy &&
+                 setTimeout(r.collapseToEnd.bind(r), 50),
+             hterm.Keyboard.KeyActions.PASS;
+    if (!this.keyboard.ctrlCCopy && e.shiftKey)
+      return this.keyboard.terminal.clearSelectionAfterCopy &&
+                 setTimeout(r.collapseToEnd.bind(r), 50),
+             this.keyboard.terminal.copySelectionToClipboard(),
+             hterm.Keyboard.KeyActions.CANCEL;
   }
   return '';
-};, hterm.Keyboard.KeyMap.prototype.onCtrlN_ = function(e, t) {
-  return e.shiftKey ? (window.open(document.location.href, '', 'chrome=no,close=yes,resize=yes,scrollbars=yes,minimizable=yes,width=' + window.innerWidth + ',height=' + window.innerHeight), hterm.Keyboard.KeyActions.CANCEL) : '';
-};, hterm.Keyboard.KeyMap.prototype.onCtrlV_ = function(e, t) {
-  return !e.shiftKey && this.keyboard.ctrlVPaste || e.shiftKey && !this.keyboard.ctrlVPaste ? hterm.Keyboard.KeyActions.PASS : '';
-};, hterm.Keyboard.KeyMap.prototype.onMetaN_ = function(e, t) {
-  return e.shiftKey ? (window.open(document.location.href, '', 'chrome=no,close=yes,resize=yes,scrollbars=yes,minimizable=yes,width=' + window.outerWidth + ',height=' + window.outerHeight), hterm.Keyboard.KeyActions.CANCEL) : hterm.Keyboard.KeyActions.DEFAULT;
-};, hterm.Keyboard.KeyMap.prototype.onMetaC_ = function(e, t) {
+};
+, hterm.Keyboard.KeyMap.prototype.onCtrlN_ = function(e, t) {
+  return e.shiftKey ?
+      (window.open(
+           document.location.href, '',
+           'chrome=no,close=yes,resize=yes,scrollbars=yes,minimizable=yes,width=' +
+               window.innerWidth + ',height=' + window.innerHeight),
+       hterm.Keyboard.KeyActions.CANCEL) :
+      '';
+};
+, hterm.Keyboard.KeyMap.prototype.onCtrlV_ = function(e, t) {
+  return !e.shiftKey && this.keyboard.ctrlVPaste ||
+          e.shiftKey && !this.keyboard.ctrlVPaste ?
+      hterm.Keyboard.KeyActions.PASS :
+      '';
+};
+, hterm.Keyboard.KeyMap.prototype.onMetaN_ = function(e, t) {
+  return e.shiftKey ?
+      (window.open(
+           document.location.href, '',
+           'chrome=no,close=yes,resize=yes,scrollbars=yes,minimizable=yes,width=' +
+               window.outerWidth + ',height=' + window.outerHeight),
+       hterm.Keyboard.KeyActions.CANCEL) :
+      hterm.Keyboard.KeyActions.DEFAULT;
+};
+, hterm.Keyboard.KeyMap.prototype.onMetaC_ = function(e, t) {
   var r = this.keyboard.terminal.getDocument();
-  return e.shiftKey || r.getSelection().isCollapsed ? t.keyCap.substr(e.shiftKey ? 1 : 0, 1) : (this.keyboard.terminal.clearSelectionAfterCopy && setTimeout(function() {
-    r.getSelection().collapseToEnd();
-  }, 50), hterm.Keyboard.KeyActions.PASS);
-};, hterm.Keyboard.KeyMap.prototype.onMetaV_ = function(e, t) {
-  return e.shiftKey ? hterm.Keyboard.KeyActions.PASS : this.keyboard.passMetaV ? hterm.Keyboard.KeyActions.PASS : hterm.Keyboard.KeyActions.DEFAULT
-};, hterm.Keyboard.KeyMap.prototype.onPlusMinusZero_ = function(e, t) {
-  if (!(this.keyboard.ctrlPlusMinusZeroZoom ^ e.shiftKey)) return '-_' == t.keyCap ? '' : hterm.Keyboard.KeyActions.CANCEL;
-  if (1 != this.keyboard.terminal.getZoomFactor()) return hterm.Keyboard.KeyActions.PASS;
+  return e.shiftKey || r.getSelection().isCollapsed ?
+      t.keyCap.substr(e.shiftKey ? 1 : 0, 1) :
+      (this.keyboard.terminal.clearSelectionAfterCopy && setTimeout(function() {
+         r.getSelection().collapseToEnd();
+       }, 50), hterm.Keyboard.KeyActions.PASS);
+};
+, hterm.Keyboard.KeyMap.prototype.onMetaV_ = function(e, t) {
+  return e.shiftKey ?
+      hterm.Keyboard.KeyActions.PASS :
+      this.keyboard.passMetaV ? hterm.Keyboard.KeyActions.PASS :
+                                hterm.Keyboard.KeyActions.DEFAULT
+};
+, hterm.Keyboard.KeyMap.prototype.onPlusMinusZero_ = function(e, t) {
+  if (!(this.keyboard.ctrlPlusMinusZeroZoom ^ e.shiftKey))
+    return '-_' == t.keyCap ? '' : hterm.Keyboard.KeyActions.CANCEL;
+  if (1 != this.keyboard.terminal.getZoomFactor())
+    return hterm.Keyboard.KeyActions.PASS;
   var r = t.keyCap.substr(0, 1);
-  if ('0' == r) this.keyboard.terminal.setFontSize(0);
+  if ('0' == r)
+    this.keyboard.terminal.setFontSize(0);
   else {
     var o = this.keyboard.terminal.getFontSize();
-    '-' == r || '[KP-]' == t.keyCap ? o -= 1 : o += 1, this.keyboard.terminal.setFontSize(o);
+    '-' == r || '[KP-]' == t.keyCap ? o -= 1 : o += 1,
+        this.keyboard.terminal.setFontSize(o);
   }
   return hterm.Keyboard.KeyActions.CANCEL;
-};, hterm.Keyboard.KeyPattern = function(e) {
-  this.wildcardCount = 0, this.keyCode = e.keyCode, hterm.Keyboard.KeyPattern.modifiers.forEach(function(t) {
+};
+, hterm.Keyboard.KeyPattern = function(e) {
+  this.wildcardCount = 0, this.keyCode = e.keyCode,
+  hterm.Keyboard.KeyPattern.modifiers.forEach(function(t) {
     this[t] = e[t] || !1, '*' == this[t] && this.wildcardCount++;
   }.bind(this));
-};, hterm.Keyboard.KeyPattern.modifiers = ['shift', 'ctrl', 'alt', 'meta'], hterm.Keyboard.KeyPattern.sortCompare = function(e, t) {
-  return e.wildcardCount < t.wildcardCount ? -1 : e.wildcardCount > t.wildcardCount ? 1 : 0
-};, hterm.Keyboard.KeyPattern.prototype.match_ = function(e, t) {
+};
+, hterm.Keyboard.KeyPattern.modifiers = ['shift', 'ctrl', 'alt', 'meta'],
+  hterm.Keyboard.KeyPattern.sortCompare = function(e, t) {
+    return e.wildcardCount < t.wildcardCount ?
+        -1 :
+        e.wildcardCount > t.wildcardCount ? 1 : 0
+  };
+, hterm.Keyboard.KeyPattern.prototype.match_ = function(e, t) {
   if (this.keyCode != e.keyCode) return !1;
   var r = !0;
   return hterm.Keyboard.KeyPattern.modifiers.forEach(function(o) {
     var i = o in e ? e[o] : !1;
     r && (t || '*' != this[o]) && this[o] != i && (r = !1);
-  }.bind(this)), r;
-};, hterm.Keyboard.KeyPattern.prototype.matchKeyDown = function(e) {
+  }.bind(this)),
+         r;
+};
+, hterm.Keyboard.KeyPattern.prototype.matchKeyDown = function(e) {
   return this.match_(e, !1);
-};, hterm.Keyboard.KeyPattern.prototype.matchKeyPattern = function(e) {
+};
+, hterm.Keyboard.KeyPattern.prototype.matchKeyPattern = function(e) {
   return this.match_(e, !0);
-};, hterm.Options = function(e) {
-  this.wraparound = e ? e.wraparound : !0, this.reverseWraparound = e ? e.reverseWraparound : !1, this.originMode = e ? e.originMode : !1, this.autoCarriageReturn = e ? e.autoCarriageReturn : !1, this.cursorVisible = e ? e.cursorVisible : !1, this.cursorBlink = e ? e.cursorBlink : !1, this.insertMode = e ? e.insertMode : !1, this.reverseVideo = e ? e.reverseVideo : !1, this.bracketedPaste = e ? e.bracketedPaste : !1;
-};, lib.rtdep('hterm.Keyboard.KeyActions'), hterm.Parser = function() {
+};
+, hterm.Options = function(e) {
+  this.wraparound = e ? e.wraparound : !0,
+  this.reverseWraparound = e ? e.reverseWraparound : !1,
+  this.originMode = e ? e.originMode : !1,
+  this.autoCarriageReturn = e ? e.autoCarriageReturn : !1,
+  this.cursorVisible = e ? e.cursorVisible : !1,
+  this.cursorBlink = e ? e.cursorBlink : !1,
+  this.insertMode = e ? e.insertMode : !1,
+  this.reverseVideo = e ? e.reverseVideo : !1,
+  this.bracketedPaste = e ? e.bracketedPaste : !1;
+};
+, lib.rtdep('hterm.Keyboard.KeyActions'), hterm.Parser = function() {
   this.source = '', this.pos = 0, this.ch = null;
-};, hterm.Parser.prototype.error = function(e) {
+};
+, hterm.Parser.prototype.error = function(e) {
   return new Error('Parse error at ' + this.pos + ': ' + e);
-};, hterm.Parser.prototype.isComplete = function() {
+};
+, hterm.Parser.prototype.isComplete = function() {
   return this.pos == this.source.length;
-};, hterm.Parser.prototype.reset = function(e, t) {
+};
+, hterm.Parser.prototype.reset = function(e, t) {
   this.source = e, this.pos = t || 0, this.ch = e.substr(0, 1);
-};, hterm.Parser.prototype.parseKeySequence = function() {
-  var e = {
-    keyCode: null
-  };
-  for (var t in hterm.Parser.identifiers.modifierKeys) e[hterm.Parser.identifiers.modifierKeys[t]] = !1;
+};
+, hterm.Parser.prototype.parseKeySequence = function() {
+  var e = {keyCode: null};
+  for (var t in hterm.Parser.identifiers.modifierKeys)
+    e[hterm.Parser.identifiers.modifierKeys[t]] = !1;
   for (; this.pos < this.source.length;) {
     this.skipSpace();
     var r = this.parseToken();
-    if ('integer' == r.type) e.keyCode = r.value;
+    if ('integer' == r.type)
+      e.keyCode = r.value;
     else if ('identifier' == r.type)
       if (r.value in hterm.Parser.identifiers.modifierKeys) {
         var o = hterm.Parser.identifiers.modifierKeys[r.value];
-        if (e[o] && '*' != e[o]) throw this.error('Duplicate modifier: ' + r.value);
+        if (e[o] && '*' != e[o])
+          throw this.error('Duplicate modifier: ' + r.value);
         e[o] = !0;
+      } else {
+        if (!(r.value in hterm.Parser.identifiers.keyCodes))
+          throw this.error('Unknown key: ' + r.value);
+        e.keyCode = hterm.Parser.identifiers.keyCodes[r.value];
       }
     else {
-      if (!(r.value in hterm.Parser.identifiers.keyCodes)) throw this.error('Unknown key: ' + r.value);
-      e.keyCode = hterm.Parser.identifiers.keyCodes[r.value];
-    }
-    else {
-      if ('symbol' != r.type) throw this.error('Expected integer or identifier');
+      if ('symbol' != r.type)
+        throw this.error('Expected integer or identifier');
       if ('*' != r.value) throw this.error('Unexpected symbol: ' + r.value);
       for (var i in hterm.Parser.identifiers.modifierKeys) {
         var s = hterm.Parser.identifiers.modifierKeys[i];
@@ -2306,71 +2818,77 @@
       }
     }
     if (this.skipSpace(), '-' != this.ch) break;
-    if (null != e.keyCode) throw this.error('Extra definition after target key');
+    if (null != e.keyCode)
+      throw this.error('Extra definition after target key');
     this.advance(1);
   }
   if (null == e.keyCode) throw this.error('Missing target key');
   return e;
-};, hterm.Parser.prototype.parseKeyAction = function() {
+};
+, hterm.Parser.prototype.parseKeyAction = function() {
   this.skipSpace();
   var e = this.parseToken();
   if ('string' == e.type) return e.value;
   if ('identifier' == e.type) {
-    if (e.value in hterm.Parser.identifiers.actions) return hterm.Parser.identifiers.actions[e.value];
+    if (e.value in hterm.Parser.identifiers.actions)
+      return hterm.Parser.identifiers.actions[e.value];
     throw this.error('Unknown key action: ' + e.value);
   }
   throw this.error('Expected string or identifier');
-};, hterm.Parser.prototype.peekString = function() {
-  return "'" == this.ch || '"' == this.ch;
-};, hterm.Parser.prototype.peekIdentifier = function() {
+};
+, 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() {
+};
+, hterm.Parser.prototype.peekInteger = function() {
   return this.ch.match(/[0-9]/);
-};, hterm.Parser.prototype.parseToken = function() {
+};
+, hterm.Parser.prototype.parseToken = function() {
   if ('*' == this.ch) {
-    var e = {
-      type: 'symbol',
-      value: this.ch
-    };
+    var e = {type: 'symbol', value: this.ch};
     return this.advance(1), e;
   }
-  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()
-  };
+  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() {
+};
+, hterm.Parser.prototype.parseIdentifier = function() {
   if (!this.peekIdentifier()) throw this.error('Expected identifier');
   return this.parsePattern(/[a-z0-9_]+/gi);
-};, hterm.Parser.prototype.parseInteger = function() {
-  return '0' == this.ch && this.pos < this.source.length - 1 && 'x' == this.source.substr(this.pos + 1, 1) ? parseInt(this.parsePattern(/0x[0-9a-f]+/gi)) : parseInt(this.parsePattern(/\d+/g));
-};, hterm.Parser.prototype.parseString = function() {
-  var e = '',
-    t = this.ch;
-  if ('"' != t && "'" != t) throw this.error('String expected');
+};
+, hterm.Parser.prototype.parseInteger = function() {
+  return '0' == this.ch && this.pos < this.source.length - 1 &&
+          'x' == this.source.substr(this.pos + 1, 1) ?
+      parseInt(this.parsePattern(/0x[0-9a-f]+/gi)) :
+      parseInt(this.parsePattern(/\d+/g));
+};
+, hterm.Parser.prototype.parseString = function() {
+  var e = '', t = this.ch;
+  if ('"' != t && '\'' != t) throw this.error('String expected');
   this.advance(1);
-  for (var r = new RegExp('[\\\\' + t + ']', 'g'); this.pos < this.source.length;) {
-    if (r.lastIndex = this.pos, !r.exec(this.source)) throw this.error('Unterminated string literal');
-    if (e += this.source.substring(this.pos, r.lastIndex - 1), this.advance(r.lastIndex - this.pos - 1), '"' != t || '\\' != this.ch)
-      if ("'" != t || '\\' != this.ch) {
+  for (var r = new RegExp('[\\\\' + t + ']', 'g');
+       this.pos < this.source.length;) {
+    if (r.lastIndex = this.pos, !r.exec(this.source))
+      throw this.error('Unterminated string literal');
+    if (e += this.source.substring(this.pos, r.lastIndex - 1),
+        this.advance(r.lastIndex - this.pos - 1), '"' != t || '\\' != this.ch)
+      if ('\'' != t || '\\' != this.ch) {
         if (this.ch == t) return this.advance(1), e;
-      }
-    else e += this.ch, this.advance(1);
-    else this.advance(1), e += this.parseEscape();
+      } else
+        e += this.ch, this.advance(1);
+    else
+      this.advance(1), e += this.parseEscape();
   }
   throw this.error('Unterminated string literal');
-};, hterm.Parser.prototype.parseEscape = function() {
+};
+, hterm.Parser.prototype.parseEscape = function() {
   var e = {
     '"': '"',
-    "'": "'",
+    '\'': '\'',
     '\\': '\\',
     a: '',
     b: '\b',
@@ -2392,450 +2910,757 @@
   if (!(this.ch in e)) throw this.error('Unknown escape: ' + this.ch);
   var t = e[this.ch];
   return this.advance(1), 'function' == typeof t && (t = t.call(this)), t;
-};, hterm.Parser.prototype.parsePattern = function(e) {
-  if (!e.global) throw this.error('Internal error: Span patterns must be global');
+};
+, hterm.Parser.prototype.parsePattern = function(e) {
+  if (!e.global)
+    throw this.error('Internal error: Span patterns must be global');
   e.lastIndex = this.pos;
   var t = e.exec(this.source);
-  if (!t || e.lastIndex - t[0].length != this.pos) throw this.error('Expected match for: ' + e);
+  if (!t || e.lastIndex - t[0].length != this.pos)
+    throw this.error('Expected match for: ' + e);
   return this.pos = e.lastIndex - 1, this.advance(1), t[0];
-};, hterm.Parser.prototype.advance = function(e) {
+};
+, hterm.Parser.prototype.advance = function(e) {
   this.pos += e, this.ch = this.source.substr(this.pos, 1);
-};, hterm.Parser.prototype.skipSpace = function(e) {
+};
+, hterm.Parser.prototype.skipSpace = function(e) {
   if (/\s/.test(this.ch)) {
     var t = /\s+/gm;
     t.lastIndex = this.pos;
     var r = this.source;
-    if (t.exec(r) && (this.pos = t.lastIndex), this.ch = this.source.substr(this.pos, 1), e && -1 == this.ch.indexOf(e)) throw this.error('Expected one of ' + e + ', found: ' + this.ch);
+    if (t.exec(r) && (this.pos = t.lastIndex),
+        this.ch = this.source.substr(this.pos, 1),
+        e && -1 == this.ch.indexOf(e))
+      throw this.error('Expected one of ' + e + ', found: ' + this.ch);
   }
-};, hterm.Parser.identifiers = {}, hterm.Parser.identifiers.modifierKeys = {
-  Shift: 'shift',
-  Ctrl: 'ctrl',
-  Alt: 'alt',
-  Meta: 'meta'
-}, hterm.Parser.identifiers.keyCodes = {
-  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,
-  ONE: 49,
-  TWO: 50,
-  THREE: 51,
-  FOUR: 52,
-  FIVE: 53,
-  SIX: 54,
-  SEVEN: 55,
-  EIGHT: 56,
-  NINE: 57,
-  ZERO: 48,
-  BACKSPACE: 8,
-  TAB: 9,
-  Q: 81,
-  W: 87,
-  E: 69,
-  R: 82,
-  T: 84,
-  Y: 89,
-  U: 85,
-  I: 73,
-  O: 79,
-  P: 80,
-  CAPSLOCK: 20,
-  A: 65,
-  S: 83,
-  D: 68,
-  F: 70,
-  G: 71,
-  H: 72,
-  J: 74,
-  K: 75,
-  L: 76,
-  ENTER: 13,
-  Z: 90,
-  X: 88,
-  C: 67,
-  V: 86,
-  B: 66,
-  N: 78,
-  M: 77,
-  SPACE: 32,
-  PRINT_SCREEN: 42,
-  SCROLL_LOCK: 145,
-  BREAK: 19,
-  INSERT: 45,
-  HOME: 36,
-  PGUP: 33,
-  DEL: 46,
-  END: 35,
-  PGDOWN: 34,
-  UP: 38,
-  DOWN: 40,
-  RIGHT: 39,
-  LEFT: 37,
-  NUMLOCK: 144,
-  KP0: 96,
-  KP1: 97,
-  KP2: 98,
-  KP3: 99,
-  KP4: 100,
-  KP5: 101,
-  KP6: 102,
-  KP7: 103,
-  KP8: 104,
-  KP9: 105,
-  KP_PLUS: 107,
-  KP_MINUS: 109,
-  KP_STAR: 106,
-  KP_DIVIDE: 111,
-  KP_DECIMAL: 110,
-  NAVIGATE_BACK: 166,
-  NAVIGATE_FORWARD: 167,
-  RELOAD: 168,
-  FULL_SCREEN: 183,
-  WINDOW_OVERVIEW: 182,
-  BRIGHTNESS_UP: 216,
-  BRIGHTNESS_DOWN: 217
-}, hterm.Parser.identifiers.actions = {
-  CANCEL: hterm.Keyboard.KeyActions.CANCEL,
-  DEFAULT: hterm.Keyboard.KeyActions.DEFAULT,
-  PASS: hterm.Keyboard.KeyActions.PASS,
-  scrollPageUp: function(e) {
-    return e.scrollPageUp(), hterm.Keyboard.KeyActions.CANCEL;
+};
+, hterm.Parser.identifiers = {},
+  hterm.Parser.identifiers
+      .modifierKeys = {Shift: 'shift', Ctrl: 'ctrl', Alt: 'alt', Meta: 'meta'},
+  hterm.Parser.identifiers.keyCodes = {
+    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,
+    ONE: 49,
+    TWO: 50,
+    THREE: 51,
+    FOUR: 52,
+    FIVE: 53,
+    SIX: 54,
+    SEVEN: 55,
+    EIGHT: 56,
+    NINE: 57,
+    ZERO: 48,
+    BACKSPACE: 8,
+    TAB: 9,
+    Q: 81,
+    W: 87,
+    E: 69,
+    R: 82,
+    T: 84,
+    Y: 89,
+    U: 85,
+    I: 73,
+    O: 79,
+    P: 80,
+    CAPSLOCK: 20,
+    A: 65,
+    S: 83,
+    D: 68,
+    F: 70,
+    G: 71,
+    H: 72,
+    J: 74,
+    K: 75,
+    L: 76,
+    ENTER: 13,
+    Z: 90,
+    X: 88,
+    C: 67,
+    V: 86,
+    B: 66,
+    N: 78,
+    M: 77,
+    SPACE: 32,
+    PRINT_SCREEN: 42,
+    SCROLL_LOCK: 145,
+    BREAK: 19,
+    INSERT: 45,
+    HOME: 36,
+    PGUP: 33,
+    DEL: 46,
+    END: 35,
+    PGDOWN: 34,
+    UP: 38,
+    DOWN: 40,
+    RIGHT: 39,
+    LEFT: 37,
+    NUMLOCK: 144,
+    KP0: 96,
+    KP1: 97,
+    KP2: 98,
+    KP3: 99,
+    KP4: 100,
+    KP5: 101,
+    KP6: 102,
+    KP7: 103,
+    KP8: 104,
+    KP9: 105,
+    KP_PLUS: 107,
+    KP_MINUS: 109,
+    KP_STAR: 106,
+    KP_DIVIDE: 111,
+    KP_DECIMAL: 110,
+    NAVIGATE_BACK: 166,
+    NAVIGATE_FORWARD: 167,
+    RELOAD: 168,
+    FULL_SCREEN: 183,
+    WINDOW_OVERVIEW: 182,
+    BRIGHTNESS_UP: 216,
+    BRIGHTNESS_DOWN: 217
   },
-  scrollPageDown: function(e) {
-    return e.scrollPageDown(), hterm.Keyboard.KeyActions.CANCEL;
+  hterm.Parser.identifiers.actions = {
+    CANCEL: hterm.Keyboard.KeyActions.CANCEL,
+    DEFAULT: hterm.Keyboard.KeyActions.DEFAULT,
+    PASS: hterm.Keyboard.KeyActions.PASS,
+    scrollPageUp: function(e) {
+      return e.scrollPageUp(), hterm.Keyboard.KeyActions.CANCEL;
+    },
+    scrollPageDown: function(e) {
+      return e.scrollPageDown(), hterm.Keyboard.KeyActions.CANCEL;
+    },
+    scrollToTop: function(e) {
+      return e.scrollEnd(), hterm.Keyboard.KeyActions.CANCEL;
+    },
+    scrollToBottom: function(e) {
+      return e.scrollEnd(), hterm.Keyboard.KeyActions.CANCEL;
+    },
+    clearScrollback: function(e) {
+      return e.wipeContents(), hterm.Keyboard.KeyActions.CANCEL;
+    }
   },
-  scrollToTop: function(e) {
-    return e.scrollEnd(), hterm.Keyboard.KeyActions.CANCEL;
-  },
-  scrollToBottom: function(e) {
-    return e.scrollEnd(), hterm.Keyboard.KeyActions.CANCEL;
-  },
-  clearScrollback: function(e) {
-    return e.wipeContents(), hterm.Keyboard.KeyActions.CANCEL;
-  }
-}, lib.rtdep('lib.f', 'lib.Storage'), hterm.PreferenceManager = function(e) {
-  lib.PreferenceManager.call(this, hterm.defaultStorage, '/hterm/profiles/' + e);
-  var t = hterm.PreferenceManager.defaultPreferences;
-  Object.keys(t).forEach(function(e) {
-    this.definePreference(e, t[e][1]);
-  }.bind(this));
-};, 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.Miscellaneous = 'Miscellaneous', 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.Miscellaneous,
-  text: 'Misc.'
-}], hterm.PreferenceManager.defaultPreferences = {
-  'alt-gr-mode': [hterm.PreferenceManager.categories.Keyboard, null, [null, 'none', 'ctrl-alt', 'left-alt', 'right-alt'], "Select an AltGr detection hack^Wheuristic.\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.\n"],
-  'alt-backspace-is-meta-backspace': [hterm.PreferenceManager.categories.Keyboard, !1, 'bool', 'If set, undoes the Chrome OS Alt-Backspace->DEL remap, so that alt-backspace indeed is alt-backspace.'],
-  'alt-is-meta': [hterm.PreferenceManager.categories.Keyboard, !1, 'bool', 'Set whether the alt key acts as a meta key or as a distinct alt key.'],
-  'alt-sends-what': [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 unshifted 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 \n                browser performs a default action for some alt sequences.)"],
-  'audible-bell-sound': [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.categories.Sounds, !1, 'bool', 'If true, terminal bells in the background will create a Web Notification. https://www.w3.org/TR/notifications/\n\nDisplaying notifications requires permission from the user. When this option is set to true, hterm will attempt to ask the user for permission if necessary. Note browsers may not show this permission request if it did not originate from a user action.\n\nChrome extensions with the "notifications" permission have permission to display notifications.'],
-  '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.categories.Appearance, '', 'string', 'CSS value of the background image.  Empty string for no image.\n\nFor example:\n  url(https://goo.gl/anedTK)\n  linear-gradient(top bottom, blue, red)'],
-  'background-size': [hterm.PreferenceManager.categories.Appearance, '', 'string', 'CSS value of the background image size.  Defaults to none.'],
-  'background-position': [hterm.PreferenceManager.categories.Appearance, '', 'string', 'CSS value of the background image position.\n\nFor example:\n  10% 10%\n  center'],
-  'backspace-sends-backspace': [hterm.PreferenceManager.categories.Keyboard, !1, 'bool', "If true, the backspace should send BS ('\\x08', aka ^H).  Otherwise the backspace key should send '\\x7f'."],
-  '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\nFor example:\n  {"0":{"+":"\\u2192",",":"\\u2190","-":"\\u2191",".":"\\u2193", "0":"\\u2588"}}'],
-  'close-on-exit': [hterm.PreferenceManager.categories.Miscellaneous, !0, 'bool', 'Whether or not to close the window when the command exits.'],
-  'cursor-blink': [hterm.PreferenceManager.categories.Appearance, !1, 'bool', 'Whether or not to blink the cursor by default.'],
-  'cursor-blink-cycle': [hterm.PreferenceManager.categories.Appearance, [1e3, 500], 'value', 'The cursor blink rate in milliseconds.\n\nA two element array, the first of which is how long the cursor should be on, second is how long it should be off.'],
-  'cursor-color': [hterm.PreferenceManager.categories.Appearance, 'rgba(255, 0, 0, 0.5)', 'color', 'The color of the visible cursor.'],
-  'color-palette-overrides': [hterm.PreferenceManager.categories.Appearance, null, 'value', "Override colors in the default palette.\n\nThis 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\nValues 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 stock X11 rgb.txt file.\n\nYou 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."],
-  'copy-on-select': [hterm.PreferenceManager.categories.CopyPaste, !0, 'bool', 'Automatically copy mouse selection to the clipboard.'],
-  'use-default-window-copy': [hterm.PreferenceManager.categories.CopyPaste, !1, 'bool', 'Whether to use the default window copy behavior'],
-  'clear-selection-after-copy': [hterm.PreferenceManager.categories.CopyPaste, !0, 'bool', 'Whether to clear the selection after copying.'],
-  'ctrl-plus-minus-zero-zoom': [hterm.PreferenceManager.categories.Keyboard, !0, 'bool', 'If true, Ctrl-Plus/Minus/Zero controls zoom.\nIf false, Ctrl-Shift-Plus/Minus/Zero controls zoom, Ctrl-Minus sends ^_, Ctrl-Plus/Zero do nothing.'],
-  'ctrl-c-copy': [hterm.PreferenceManager.categories.Keyboard, !1, 'bool', 'Ctrl+C copies if true, send ^C to host if false.\nCtrl+Shift+C sends ^C to host if true, copies if false.'],
-  'ctrl-v-paste': [hterm.PreferenceManager.categories.Keyboard, !1, 'bool', 'Ctrl+V pastes if true, send ^V to host if false.\nCtrl+Shift+V sends ^V to host if true, pastes if false.'],
-  'east-asian-ambiguous-as-two-column': [hterm.PreferenceManager.categories.Keyboard, !1, 'bool', 'Set whether East Asian Ambiguous characters have two column width.'],
-  'enable-8-bit-control': [hterm.PreferenceManager.categories.Keyboard, !1, 'bool', "True to enable 8-bit control characters, false to ignore them.\n\nWe'll respect the two-byte versions of these control characters regardless of this setting."],
-  'enable-bold': [hterm.PreferenceManager.categories.Appearance, null, 'tristate', 'True if we should 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.categories.Appearance, !0, 'bool', 'True if we should use bright colors (8-15 on a 16 color palette) for any text with the bold attribute.  False otherwise.'],
-  'enable-blink': [hterm.PreferenceManager.categories.Appearance, !0, 'bool', 'True if we should respect the blink attribute.  False to ignore it.  '],
-  'enable-clipboard-notice': [hterm.PreferenceManager.categories.CopyPaste, !0, 'bool', 'Show a message in the terminal when the host writes to the clipboard.'],
-  'enable-clipboard-write': [hterm.PreferenceManager.categories.CopyPaste, !0, 'bool', 'Allow the host to write directly to the system clipboard.'],
-  'enable-dec12': [hterm.PreferenceManager.categories.Miscellaneous, !1, 'bool', "Respect the host's attempt to change the cursor blink status using DEC Private Mode 12."],
-  environment: [hterm.PreferenceManager.categories.Miscellaneous, {
-    TERM: 'xterm-256color'
-  }, 'value', 'The default environment variables, as an object.'],
-  'font-family': [hterm.PreferenceManager.categories.Appearance, '"DejaVu Sans Mono", "Everson Mono", FreeMono, "Menlo", "Terminal", monospace', 'string', 'Default font family for the terminal text.'],
-  'font-size': [hterm.PreferenceManager.categories.Appearance, 15, 'int', 'The default font size in pixels.'],
-  'font-smoothing': [hterm.PreferenceManager.categories.Appearance, 'antialiased', 'string', 'CSS font-smoothing property.'],
-  'foreground-color': [hterm.PreferenceManager.categories.Appearance, 'rgb(240, 240, 240)', 'color', 'The foreground color for text with no other color attributes.'],
-  'home-keys-scroll': [hterm.PreferenceManager.categories.Keyboard, !1, 'bool', '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.'],
-  keybindings: [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 a string to send to the host, or an action identifier.  For a full list of key code and action identifiers, see https://goo.gl/8AoD09.\n\nSample keybindings:\n{ "Ctrl-Alt-K": "clearScrollback",\n  "Ctrl-Shift-L": "PASS",\n  "Ctrl-H": "\'HELLO\\n\'"\n}'],
-  'max-string-sequence': [hterm.PreferenceManager.categories.Encoding, 1e5, 'int', 'Max length of a DCS, OSC, PM, or APS sequence before we give up and ignore the code.'],
-  'media-keys-are-fkeys': [hterm.PreferenceManager.categories.Keyboard, !1, 'bool', 'If true, convert media keys to their Fkey equivalent. If false, let the browser handle the keys.'],
-  'meta-sends-escape': [hterm.PreferenceManager.categories.Keyboard, !0, 'bool', 'Set whether the meta key sends a leading escape or not.'],
-  'mouse-paste-button': [hterm.PreferenceManager.categories.CopyPaste, null, [null, 0, 1, 2, 3, 4, 5, 6], "Mouse paste button, or null to autodetect.\n\nFor autodetect, we'll try to enable middle button paste for non-X11 platforms.  On X11 we move it to button 3."],
-  'page-keys-scroll': [hterm.PreferenceManager.categories.Keyboard, !1, 'bool', 'If true, page up/down will control the terminal scrollbar and shift page up/down will send the VT keycodes.  If false then page up/down sends VT codes and shift page up/down scrolls.'],
-  'pass-alt-number': [hterm.PreferenceManager.categories.Keyboard, null, 'tristate', "Set whether we should pass Alt-1..9 to the browser.\n\nThis 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\nIf 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.categories.Keyboard, null, 'tristate', "Set whether we should pass Ctrl-1..9 to the browser.\n\nThis 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\nIf 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.categories.Keyboard, null, 'tristate', "Set whether we should pass Meta-1..9 to the browser.\n\nThis 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\nIf 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.categories.Keyboard, !0, 'bool', 'Set whether meta-V gets passed to host.'],
-  'receive-encoding': [hterm.PreferenceManager.categories.Encoding, 'utf-8', ['utf-8', 'raw'], "Set the expected encoding for data received from the host.\n\nValid values are 'utf-8' and 'raw'."],
-  'scroll-on-keystroke': [hterm.PreferenceManager.categories.Scrolling, !0, 'bool', 'If true, scroll to the bottom on any keystroke.'],
-  'scroll-on-output': [hterm.PreferenceManager.categories.Scrolling, !1, 'bool', 'If true, scroll to the bottom on terminal output.'],
-  'scrollbar-visible': [hterm.PreferenceManager.categories.Scrolling, !0, 'bool', 'The vertical scrollbar mode.'],
-  'scroll-wheel-move-multiplier': [hterm.PreferenceManager.categories.Scrolling, 1, 'int', 'The multiplier for the pixel delta in mousewheel event caused by the scroll wheel. Alters how fast the page scrolls.'],
-  'send-encoding': [hterm.PreferenceManager.categories.Encoding, 'utf-8', ['utf-8', 'raw'], 'Set the encoding for data sent to host.'],
-  'shift-insert-paste': [hterm.PreferenceManager.categories.Keyboard, !0, 'bool', 'Shift + Insert pastes if true, sent to host if false.'],
-  'user-css': [hterm.PreferenceManager.categories.Appearance, '', 'url', 'URL of user stylesheet to include in the terminal document.']
-}, hterm.PreferenceManager.prototype = {
-  __proto__: lib.PreferenceManager.prototype
-}, hterm.PubSub = function() {
-  this.observers_ = {};
-};, hterm.PubSub.addBehavior = function(e) {
+  lib.rtdep('lib.f', 'lib.Storage'), hterm.PreferenceManager = function(e) {
+    lib.PreferenceManager.call(
+        this, hterm.defaultStorage, '/hterm/profiles/' + e);
+    var t = hterm.PreferenceManager.defaultPreferences;
+    Object.keys(t).forEach(function(e) {
+      this.definePreference(e, t[e][1]);
+    }.bind(this));
+  };
+,
+    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.Miscellaneous = 'Miscellaneous',
+    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.Miscellaneous,
+            text: 'Misc.'
+          }
+        ],
+    hterm.PreferenceManager.defaultPreferences = {
+      'alt-gr-mode': [
+        hterm.PreferenceManager.categories.Keyboard, null,
+        [null, 'none', 'ctrl-alt', 'left-alt', 'right-alt'],
+        'Select an AltGr detection hack^Wheuristic.\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.\n'
+      ],
+      'alt-backspace-is-meta-backspace': [
+        hterm.PreferenceManager.categories.Keyboard, !1, 'bool',
+        'If set, undoes the Chrome OS Alt-Backspace->DEL remap, so that alt-backspace indeed is alt-backspace.'
+      ],
+      'alt-is-meta': [
+        hterm.PreferenceManager.categories.Keyboard, !1, 'bool',
+        'Set whether the alt key acts as a meta key or as a distinct alt key.'
+      ],
+      'alt-sends-what': [
+        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 unshifted 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 \n                browser performs a default action for some alt sequences.)'
+      ],
+      'audible-bell-sound': [
+        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.categories.Sounds, !1, 'bool',
+        'If true, terminal bells in the background will create a Web Notification. https://www.w3.org/TR/notifications/\n\nDisplaying notifications requires permission from the user. When this option is set to true, hterm will attempt to ask the user for permission if necessary. Note browsers may not show this permission request if it did not originate from a user action.\n\nChrome extensions with the "notifications" permission have permission to display notifications.'
+      ],
+      '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.categories.Appearance, '', 'string',
+        'CSS value of the background image.  Empty string for no image.\n\nFor example:\n  url(https://goo.gl/anedTK)\n  linear-gradient(top bottom, blue, red)'
+      ],
+      'background-size': [
+        hterm.PreferenceManager.categories.Appearance, '', 'string',
+        'CSS value of the background image size.  Defaults to none.'
+      ],
+      'background-position': [
+        hterm.PreferenceManager.categories.Appearance, '', 'string',
+        'CSS value of the background image position.\n\nFor example:\n  10% 10%\n  center'
+      ],
+      'backspace-sends-backspace': [
+        hterm.PreferenceManager.categories.Keyboard, !1, 'bool',
+        'If true, the backspace should send BS (\'\\x08\', aka ^H).  Otherwise the backspace key should send \'\\x7f\'.'
+      ],
+      '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\nFor example:\n  {"0":{"+":"\\u2192",",":"\\u2190","-":"\\u2191",".":"\\u2193", "0":"\\u2588"}}'
+      ],
+      'close-on-exit': [
+        hterm.PreferenceManager.categories.Miscellaneous, !0, 'bool',
+        'Whether or not to close the window when the command exits.'
+      ],
+      'cursor-blink': [
+        hterm.PreferenceManager.categories.Appearance, !1, 'bool',
+        'Whether or not to blink the cursor by default.'
+      ],
+      'cursor-blink-cycle': [
+        hterm.PreferenceManager.categories.Appearance, [1e3, 500], 'value',
+        'The cursor blink rate in milliseconds.\n\nA two element array, the first of which is how long the cursor should be on, second is how long it should be off.'
+      ],
+      'cursor-color': [
+        hterm.PreferenceManager.categories.Appearance, 'rgba(255, 0, 0, 0.5)',
+        'color', 'The color of the visible cursor.'
+      ],
+      'color-palette-overrides': [
+        hterm.PreferenceManager.categories.Appearance, null, 'value',
+        'Override colors in the default palette.\n\nThis 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\nValues 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 stock X11 rgb.txt file.\n\nYou 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.'
+      ],
+      'copy-on-select': [
+        hterm.PreferenceManager.categories.CopyPaste, !0, 'bool',
+        'Automatically copy mouse selection to the clipboard.'
+      ],
+      'use-default-window-copy': [
+        hterm.PreferenceManager.categories.CopyPaste, !1, 'bool',
+        'Whether to use the default window copy behavior'
+      ],
+      'clear-selection-after-copy': [
+        hterm.PreferenceManager.categories.CopyPaste, !0, 'bool',
+        'Whether to clear the selection after copying.'
+      ],
+      'ctrl-plus-minus-zero-zoom': [
+        hterm.PreferenceManager.categories.Keyboard, !0, 'bool',
+        'If true, Ctrl-Plus/Minus/Zero controls zoom.\nIf false, Ctrl-Shift-Plus/Minus/Zero controls zoom, Ctrl-Minus sends ^_, Ctrl-Plus/Zero do nothing.'
+      ],
+      'ctrl-c-copy': [
+        hterm.PreferenceManager.categories.Keyboard, !1, 'bool',
+        'Ctrl+C copies if true, send ^C to host if false.\nCtrl+Shift+C sends ^C to host if true, copies if false.'
+      ],
+      'ctrl-v-paste': [
+        hterm.PreferenceManager.categories.Keyboard, !1, 'bool',
+        'Ctrl+V pastes if true, send ^V to host if false.\nCtrl+Shift+V sends ^V to host if true, pastes if false.'
+      ],
+      'east-asian-ambiguous-as-two-column': [
+        hterm.PreferenceManager.categories.Keyboard, !1, 'bool',
+        'Set whether East Asian Ambiguous characters have two column width.'
+      ],
+      'enable-8-bit-control': [
+        hterm.PreferenceManager.categories.Keyboard, !1, 'bool',
+        'True to enable 8-bit control characters, false to ignore them.\n\nWe\'ll respect the two-byte versions of these control characters regardless of this setting.'
+      ],
+      'enable-bold': [
+        hterm.PreferenceManager.categories.Appearance, null, 'tristate',
+        'True if we should 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.categories.Appearance, !0, 'bool',
+        'True if we should use bright colors (8-15 on a 16 color palette) for any text with the bold attribute.  False otherwise.'
+      ],
+      'enable-blink': [
+        hterm.PreferenceManager.categories.Appearance, !0, 'bool',
+        'True if we should respect the blink attribute.  False to ignore it.  '
+      ],
+      'enable-clipboard-notice': [
+        hterm.PreferenceManager.categories.CopyPaste, !0, 'bool',
+        'Show a message in the terminal when the host writes to the clipboard.'
+      ],
+      'enable-clipboard-write': [
+        hterm.PreferenceManager.categories.CopyPaste, !0, 'bool',
+        'Allow the host to write directly to the system clipboard.'
+      ],
+      'enable-dec12': [
+        hterm.PreferenceManager.categories.Miscellaneous, !1, 'bool',
+        'Respect the host\'s attempt to change the cursor blink status using DEC Private Mode 12.'
+      ],
+      environment: [
+        hterm.PreferenceManager.categories.Miscellaneous,
+        {TERM: 'xterm-256color'}, 'value',
+        'The default environment variables, as an object.'
+      ],
+      'font-family': [
+        hterm.PreferenceManager.categories.Appearance,
+        '"DejaVu Sans Mono", "Everson Mono", FreeMono, "Menlo", "Terminal", monospace',
+        'string', 'Default font family for the terminal text.'
+      ],
+      'font-size': [
+        hterm.PreferenceManager.categories.Appearance, 15, 'int',
+        'The default font size in pixels.'
+      ],
+      'font-smoothing': [
+        hterm.PreferenceManager.categories.Appearance, 'antialiased', 'string',
+        'CSS font-smoothing property.'
+      ],
+      'foreground-color': [
+        hterm.PreferenceManager.categories.Appearance, 'rgb(240, 240, 240)',
+        'color', 'The foreground color for text with no other color attributes.'
+      ],
+      'home-keys-scroll': [
+        hterm.PreferenceManager.categories.Keyboard, !1, 'bool',
+        '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.'
+      ],
+      keybindings: [
+        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 a string to send to the host, or an action identifier.  For a full list of key code and action identifiers, see https://goo.gl/8AoD09.\n\nSample keybindings:\n{ "Ctrl-Alt-K": "clearScrollback",\n  "Ctrl-Shift-L": "PASS",\n  "Ctrl-H": "\'HELLO\\n\'"\n}'
+      ],
+      'max-string-sequence': [
+        hterm.PreferenceManager.categories.Encoding, 1e5, 'int',
+        'Max length of a DCS, OSC, PM, or APS sequence before we give up and ignore the code.'
+      ],
+      'media-keys-are-fkeys': [
+        hterm.PreferenceManager.categories.Keyboard, !1, 'bool',
+        'If true, convert media keys to their Fkey equivalent. If false, let the browser handle the keys.'
+      ],
+      'meta-sends-escape': [
+        hterm.PreferenceManager.categories.Keyboard, !0, 'bool',
+        'Set whether the meta key sends a leading escape or not.'
+      ],
+      'mouse-paste-button': [
+        hterm.PreferenceManager.categories.CopyPaste, null,
+        [null, 0, 1, 2, 3, 4, 5, 6],
+        'Mouse paste button, or null to autodetect.\n\nFor autodetect, we\'ll try to enable middle button paste for non-X11 platforms.  On X11 we move it to button 3.'
+      ],
+      'page-keys-scroll': [
+        hterm.PreferenceManager.categories.Keyboard, !1, 'bool',
+        'If true, page up/down will control the terminal scrollbar and shift page up/down will send the VT keycodes.  If false then page up/down sends VT codes and shift page up/down scrolls.'
+      ],
+      'pass-alt-number': [
+        hterm.PreferenceManager.categories.Keyboard, null, 'tristate',
+        'Set whether we should pass Alt-1..9 to the browser.\n\nThis 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\nIf 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.categories.Keyboard, null, 'tristate',
+        'Set whether we should pass Ctrl-1..9 to the browser.\n\nThis 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\nIf 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.categories.Keyboard, null, 'tristate', 'Set whether we should pass Meta-1..9 to the browser.\n\nThis 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\nIf 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.categories.Keyboard, !0, 'bool',
+        'Set whether meta-V gets passed to host.'
+      ],
+      'receive-encoding': [
+        hterm.PreferenceManager.categories.Encoding, 'utf-8', ['utf-8', 'raw'],
+        'Set the expected encoding for data received from the host.\n\nValid values are \'utf-8\' and \'raw\'.'
+      ],
+      'scroll-on-keystroke': [
+        hterm.PreferenceManager.categories.Scrolling, !0, 'bool',
+        'If true, scroll to the bottom on any keystroke.'
+      ],
+      'scroll-on-output': [
+        hterm.PreferenceManager.categories.Scrolling, !1, 'bool',
+        'If true, scroll to the bottom on terminal output.'
+      ],
+      'scrollbar-visible': [
+        hterm.PreferenceManager.categories.Scrolling, !0, 'bool',
+        'The vertical scrollbar mode.'
+      ],
+      'scroll-wheel-move-multiplier': [
+        hterm.PreferenceManager.categories.Scrolling, 1, 'int',
+        'The multiplier for the pixel delta in mousewheel event caused by the scroll wheel. Alters how fast the page scrolls.'
+      ],
+      'send-encoding': [
+        hterm.PreferenceManager.categories.Encoding, 'utf-8', ['utf-8', 'raw'],
+        'Set the encoding for data sent to host.'
+      ],
+      'shift-insert-paste': [
+        hterm.PreferenceManager.categories.Keyboard, !0, 'bool',
+        'Shift + Insert pastes if true, sent to host if false.'
+      ],
+      'user-css': [
+        hterm.PreferenceManager.categories.Appearance, '', 'url',
+        'URL of user stylesheet to include in the terminal document.'
+      ]
+    },
+    hterm.PreferenceManager.prototype = {
+      __proto__: lib.PreferenceManager.prototype
+    },
+    hterm.PubSub = function() {
+      this.observers_ = {};
+    };
+, hterm.PubSub.addBehavior = function(e) {
   var t = new hterm.PubSub;
-  for (var r in hterm.PubSub.prototype) e[r] = hterm.PubSub.prototype[r].bind(t);
-};, hterm.PubSub.prototype.subscribe = function(e, t) {
+  for (var r in hterm.PubSub.prototype)
+    e[r] = hterm.PubSub.prototype[r].bind(t);
+};
+, hterm.PubSub.prototype.subscribe = function(e, t) {
   e in this.observers_ || (this.observers_[e] = []), this.observers_[e].push(t);
-};, hterm.PubSub.prototype.unsubscribe = function(e, t) {
+};
+, hterm.PubSub.prototype.unsubscribe = function(e, t) {
   var r = this.observers_[e];
   if (!r) throw 'Invalid subject: ' + e;
   var o = r.indexOf(t);
   if (0 > o) throw 'Not subscribed: ' + e;
   r.splice(o, 1);
-};, hterm.PubSub.prototype.publish = function(e, t, r) {
+};
+, hterm.PubSub.prototype.publish = function(e, t, r) {
   function o(e) {
     e < i.length - 1 && setTimeout(o, 0, e + 1), i[e](t);
   }
   var i = this.observers_[e];
-  i && (i = [].concat(i)), r && (i ? i.push(r) : i = [r]), i && setTimeout(o, 0, 0);
-};, lib.rtdep('lib.f', 'lib.wc', 'hterm.RowCol', 'hterm.Size', 'hterm.TextAttributes'), hterm.Screen = function(e) {
-  this.rowsArray = [], this.columnCount_ = e || 80, this.textAttributes = new hterm.TextAttributes(window.document), this.cursorPosition = new hterm.RowCol(0, 0), this.cursorRowNode_ = null, this.cursorNode_ = null, this.cursorOffset_ = null;
-};, hterm.Screen.prototype.getSize = function() {
+  i && (i = [].concat(i)), r && (i ? i.push(r) : i = [r]),
+      i && setTimeout(o, 0, 0);
+};
+,
+    lib.rtdep(
+        'lib.f', 'lib.wc', 'hterm.RowCol', 'hterm.Size',
+        'hterm.TextAttributes'),
+    hterm.Screen = function(e) {
+      this.rowsArray = [], this.columnCount_ = e || 80,
+      this.textAttributes = new hterm.TextAttributes(window.document),
+      this.cursorPosition = new hterm.RowCol(0, 0), this.cursorRowNode_ = null,
+      this.cursorNode_ = null, this.cursorOffset_ = null;
+    };
+, hterm.Screen.prototype.getSize = function() {
   return new hterm.Size(this.columnCount_, this.rowsArray.length);
-};, hterm.Screen.prototype.getHeight = function() {
+};
+, hterm.Screen.prototype.getHeight = function() {
   return this.rowsArray.length;
-};, hterm.Screen.prototype.getWidth = function() {
+};
+, hterm.Screen.prototype.getWidth = function() {
   return this.columnCount_;
-};, hterm.Screen.prototype.setColumnCount = function(e) {
-  this.columnCount_ = e, this.cursorPosition.column >= e && this.setCursorPosition(this.cursorPosition.row, e - 1);
-};, hterm.Screen.prototype.shiftRow = function() {
+};
+, hterm.Screen.prototype.setColumnCount = function(e) {
+  this.columnCount_ = e,
+  this.cursorPosition.column >= e &&
+      this.setCursorPosition(this.cursorPosition.row, e - 1);
+};
+, hterm.Screen.prototype.shiftRow = function() {
   return this.shiftRows(1)[0];
-};, hterm.Screen.prototype.shiftRows = function(e) {
+};
+, hterm.Screen.prototype.shiftRows = function(e) {
   return this.rowsArray.splice(0, e);
-};, hterm.Screen.prototype.unshiftRow = function(e) {
+};
+, hterm.Screen.prototype.unshiftRow = function(e) {
   this.rowsArray.splice(0, 0, e);
-};, hterm.Screen.prototype.unshiftRows = function(e) {
+};
+, hterm.Screen.prototype.unshiftRows = function(e) {
   this.rowsArray.unshift.apply(this.rowsArray, e);
-};, hterm.Screen.prototype.popRow = function() {
+};
+, hterm.Screen.prototype.popRow = function() {
   return this.popRows(1)[0];
-};, hterm.Screen.prototype.popRows = function(e) {
+};
+, hterm.Screen.prototype.popRows = function(e) {
   return this.rowsArray.splice(this.rowsArray.length - e, e);
-};, hterm.Screen.prototype.pushRow = function(e) {
+};
+, hterm.Screen.prototype.pushRow = function(e) {
   this.rowsArray.push(e);
-};, hterm.Screen.prototype.pushRows = function(e) {
+};
+, hterm.Screen.prototype.pushRows = function(e) {
   e.push.apply(this.rowsArray, e);
-};, hterm.Screen.prototype.insertRow = function(e, t) {
+};
+, hterm.Screen.prototype.insertRow = function(e, t) {
   this.rowsArray.splice(e, 0, t);
-};, hterm.Screen.prototype.insertRows = function(e, t) {
+};
+, hterm.Screen.prototype.insertRows = function(e, t) {
   for (var r = 0; r < t.length; r++) this.rowsArray.splice(e + r, 0, t[r]);
-};, hterm.Screen.prototype.removeRow = function(e) {
+};
+, hterm.Screen.prototype.removeRow = function(e) {
   return this.rowsArray.splice(e, 1)[0];
-};, hterm.Screen.prototype.removeRows = function(e, t) {
+};
+, hterm.Screen.prototype.removeRows = function(e, t) {
   return this.rowsArray.splice(e, t);
-};, hterm.Screen.prototype.invalidateCursorPosition = function() {
-  this.cursorPosition.move(0, 0), this.cursorRowNode_ = null, this.cursorNode_ = null, this.cursorOffset_ = null;
-};, hterm.Screen.prototype.clearCursorRow = function() {
-  this.cursorRowNode_.innerHTML = '', this.cursorRowNode_.removeAttribute('line-overflow'), this.cursorOffset_ = 0, this.cursorPosition.column = 0, this.cursorPosition.overflow = !1;
+};
+, hterm.Screen.prototype.invalidateCursorPosition = function() {
+  this.cursorPosition.move(0, 0), this.cursorRowNode_ = null,
+                                  this.cursorNode_ = null,
+                                  this.cursorOffset_ = null;
+};
+, hterm.Screen.prototype.clearCursorRow = function() {
+  this.cursorRowNode_.innerHTML = '',
+  this.cursorRowNode_.removeAttribute('line-overflow'), this.cursorOffset_ = 0,
+  this.cursorPosition.column = 0, this.cursorPosition.overflow = !1;
   var e;
-  e = this.textAttributes.isDefault() ? '' : lib.f.getWhitespace(this.columnCount_);
+  e = this.textAttributes.isDefault() ? '' :
+                                        lib.f.getWhitespace(this.columnCount_);
   var t = this.textAttributes.inverse;
   this.textAttributes.inverse = !1, this.textAttributes.syncColors();
   var r = this.textAttributes.createContainer(e);
-  this.cursorRowNode_.appendChild(r), this.cursorNode_ = r, this.textAttributes.inverse = t, this.textAttributes.syncColors();
-};, hterm.Screen.prototype.commitLineOverflow = function() {
+  this.cursorRowNode_.appendChild(r), this.cursorNode_ = r,
+                                      this.textAttributes.inverse = t,
+                                      this.textAttributes.syncColors();
+};
+, hterm.Screen.prototype.commitLineOverflow = function() {
   this.cursorRowNode_.setAttribute('line-overflow', !0);
-};, hterm.Screen.prototype.setCursorPosition = function(e, t) {
-  if (!this.rowsArray.length) return void console.warn('Attempt to set cursor position on empty screen.');
-  e >= this.rowsArray.length ? (console.error('Row out of bounds: ' + e), e = this.rowsArray.length - 1) : 0 > e && (console.error('Row out of bounds: ' + e), e = 0), t >= this.columnCount_ ? (console.error('Column out of bounds: ' + t), t = this.columnCount_ - 1) : 0 > t && (console.error('Column out of bounds: ' + t), t = 0), this.cursorPosition.overflow = !1;
-  var r = this.rowsArray[e],
-    o = r.firstChild;
+};
+, hterm.Screen.prototype.setCursorPosition = function(e, t) {
+  if (!this.rowsArray.length)
+    return void console.warn('Attempt to set cursor position on empty screen.');
+  e >= this.rowsArray.length ?
+      (console.error('Row out of bounds: ' + e),
+       e = this.rowsArray.length - 1) :
+      0 > e && (console.error('Row out of bounds: ' + e), e = 0),
+      t >= this.columnCount_ ?
+      (console.error('Column out of bounds: ' + t), t = this.columnCount_ - 1) :
+      0 > t && (console.error('Column out of bounds: ' + t), t = 0),
+      this.cursorPosition.overflow = !1;
+  var r = this.rowsArray[e], o = r.firstChild;
   o || (o = r.ownerDocument.createTextNode(''), r.appendChild(o));
   var i = 0;
-  for (r == this.cursorRowNode_ ? t >= this.cursorPosition.column - this.cursorOffset_ && (o = this.cursorNode_, i = this.cursorPosition.column - this.cursorOffset_) : this.cursorRowNode_ = r, this.cursorPosition.move(e, t); o;) {
-    var s = t - i,
-      n = hterm.TextAttributes.nodeWidth(o);
-    if (!o.nextSibling || n > s) return this.cursorNode_ = o, void(this.cursorOffset_ = s);
+  for (r == this.cursorRowNode_ ?
+           t >= this.cursorPosition.column - this.cursorOffset_ &&
+               (o = this.cursorNode_,
+               i = this.cursorPosition.column - this.cursorOffset_) :
+           this.cursorRowNode_ = r,
+           this.cursorPosition.move(e, t);
+       o;) {
+    var s = t - i, n = hterm.TextAttributes.nodeWidth(o);
+    if (!o.nextSibling || n > s)
+      return this.cursorNode_ = o, void(this.cursorOffset_ = s);
     i += n, o = o.nextSibling;
   }
-};, hterm.Screen.prototype.syncSelectionCaret = function(e) {
+};
+, hterm.Screen.prototype.syncSelectionCaret = function(e) {
   try {
     e.collapse(this.cursorNode_, this.cursorOffset_);
+  } catch (t) {
   }
-  catch (t) {}
-};, hterm.Screen.prototype.splitNode_ = function(e, t) {
-  var r = e.cloneNode(!1),
-    o = e.textContent;
-  e.textContent = hterm.TextAttributes.nodeSubstr(e, 0, t), r.textContent = lib.wc.substr(o, t), r.textContent && e.parentNode.insertBefore(r, e.nextSibling), e.textContent || e.parentNode.removeChild(e);
-};, hterm.Screen.prototype.maybeClipCurrentRow = function() {
+};
+, hterm.Screen.prototype.splitNode_ = function(e, t) {
+  var r = e.cloneNode(!1), o = e.textContent;
+  e.textContent = hterm.TextAttributes.nodeSubstr(e, 0, t),
+  r.textContent = lib.wc.substr(o, t),
+  r.textContent && e.parentNode.insertBefore(r, e.nextSibling),
+  e.textContent || e.parentNode.removeChild(e);
+};
+, hterm.Screen.prototype.maybeClipCurrentRow = function() {
   var e = hterm.TextAttributes.nodeWidth(this.cursorRowNode_);
-  if (e <= this.columnCount_) return void(this.cursorPosition.column >= this.columnCount_ && (this.setCursorPosition(this.cursorPosition.row, this.columnCount_ - 1), this.cursorPosition.overflow = !0));
+  if (e <= this.columnCount_)
+    return void(
+        this.cursorPosition.column >= this.columnCount_ &&
+        (this.setCursorPosition(this.cursorPosition.row, this.columnCount_ - 1),
+         this.cursorPosition.overflow = !0));
   var t = this.cursorPosition.column;
-  this.setCursorPosition(this.cursorPosition.row, this.columnCount_ - 1), e = hterm.TextAttributes.nodeWidth(this.cursorNode_), this.cursorOffset_ < e - 1 && (this.cursorNode_.textContent = hterm.TextAttributes.nodeSubstr(this.cursorNode_, 0, this.cursorOffset_ + 1));
-  for (var r = this.cursorRowNode_, o = this.cursorNode_.nextSibling; o;) r.removeChild(o), o = this.cursorNode_.nextSibling;
-  t < this.columnCount_ ? this.setCursorPosition(this.cursorPosition.row, t) : this.cursorPosition.overflow = !0;
-};, hterm.Screen.prototype.insertString = function(e) {
-  var t = this.cursorNode_,
-    r = t.textContent;
+  this.setCursorPosition(this.cursorPosition.row, this.columnCount_ - 1),
+      e = hterm.TextAttributes.nodeWidth(this.cursorNode_),
+      this.cursorOffset_ < e - 1 &&
+      (this.cursorNode_.textContent = hterm.TextAttributes.nodeSubstr(
+           this.cursorNode_, 0, this.cursorOffset_ + 1));
+  for (var r = this.cursorRowNode_, o = this.cursorNode_.nextSibling; o;)
+    r.removeChild(o), o = this.cursorNode_.nextSibling;
+  t < this.columnCount_ ? this.setCursorPosition(this.cursorPosition.row, t) :
+                          this.cursorPosition.overflow = !0;
+};
+, hterm.Screen.prototype.insertString = function(e) {
+  var t = this.cursorNode_, r = t.textContent;
   this.cursorRowNode_.removeAttribute('line-overflow');
   var o = lib.wc.strWidth(e);
   this.cursorPosition.column += o;
-  var i = this.cursorOffset_,
-    s = hterm.TextAttributes.nodeWidth(t) - i;
+  var i = this.cursorOffset_, s = hterm.TextAttributes.nodeWidth(t) - i;
   if (0 > s) {
     var n = lib.f.getWhitespace(-s);
-    if (this.textAttributes.underline || this.textAttributes.strikethrough || this.textAttributes.background || this.textAttributes.wcNode || null != this.textAttributes.tileData)
-      if (3 != t.nodeType && (t.wcNode || t.tileNode || t.style.textDecoration || t.style.backgroundColor)) {
+    if (this.textAttributes.underline || this.textAttributes.strikethrough ||
+        this.textAttributes.background || this.textAttributes.wcNode ||
+        null != this.textAttributes.tileData)
+      if (3 != t.nodeType &&
+          (t.wcNode || t.tileNode || t.style.textDecoration ||
+           t.style.backgroundColor)) {
         var a = t.ownerDocument.createTextNode(n);
-        this.cursorRowNode_.insertBefore(a, t.nextSibling), this.cursorNode_ = t = a, this.cursorOffset_ = i = -s, r = n;
-      }
-    else t.textContent = r += n;
-    else e = n + e;
+        this.cursorRowNode_.insertBefore(a, t.nextSibling),
+            this.cursorNode_ = t = a, this.cursorOffset_ = i = -s, r = n;
+      } else
+        t.textContent = r += n;
+    else
+      e = n + e;
     s = 0;
   }
-  if (this.textAttributes.matchesContainer(t)) return 0 == s ? t.textContent = r + e : 0 == i ? t.textContent = e + r : t.textContent = hterm.TextAttributes.nodeSubstr(t, 0, i) + e + hterm.TextAttributes.nodeSubstr(t, i), void(this.cursorOffset_ += o);
+  if (this.textAttributes.matchesContainer(t))
+    return 0 == s ? t.textContent = r + e :
+                    0 == i ?
+                    t.textContent = e + r :
+                    t.textContent = hterm.TextAttributes.nodeSubstr(t, 0, i) +
+                       e + hterm.TextAttributes.nodeSubstr(t, i),
+                    void(this.cursorOffset_ += o);
   if (0 == i) {
     var l = t.previousSibling;
-    if (l && this.textAttributes.matchesContainer(l)) return l.textContent += e, this.cursorNode_ = l, void(this.cursorOffset_ = lib.wc.strWidth(l.textContent));
+    if (l && this.textAttributes.matchesContainer(l))
+      return l.textContent += e,
+             this.cursorNode_ = l,
+             void(this.cursorOffset_ = lib.wc.strWidth(l.textContent));
     var h = this.textAttributes.createContainer(e);
-    return this.cursorRowNode_.insertBefore(h, t), this.cursorNode_ = h, void(this.cursorOffset_ = o);
+    return this.cursorRowNode_.insertBefore(h, t), this.cursorNode_ = h,
+                                                   void(this.cursorOffset_ = o);
   }
   if (0 == s) {
     var c = t.nextSibling;
-    if (c && this.textAttributes.matchesContainer(c)) return c.textContent = e + c.textContent, this.cursorNode_ = c, void(this.cursorOffset_ = lib.wc.strWidth(e));
+    if (c && this.textAttributes.matchesContainer(c))
+      return c.textContent = e + c.textContent, this.cursorNode_ = c,
+             void(this.cursorOffset_ = lib.wc.strWidth(e));
     var h = this.textAttributes.createContainer(e);
-    return this.cursorRowNode_.insertBefore(h, c), this.cursorNode_ = h, void(this.cursorOffset_ = hterm.TextAttributes.nodeWidth(h));
+    return this.cursorRowNode_.insertBefore(h, c),
+           this.cursorNode_ = h,
+           void(this.cursorOffset_ = hterm.TextAttributes.nodeWidth(h));
   }
   this.splitNode_(t, i);
   var h = this.textAttributes.createContainer(e);
-  this.cursorRowNode_.insertBefore(h, t.nextSibling), this.cursorNode_ = h, this.cursorOffset_ = o;
-};, hterm.Screen.prototype.overwriteString = function(e) {
+  this.cursorRowNode_.insertBefore(h, t.nextSibling), this.cursorNode_ = h,
+                                                      this.cursorOffset_ = o;
+};
+, hterm.Screen.prototype.overwriteString = function(e) {
   var t = this.columnCount_ - this.cursorPosition.column;
   if (!t) return [e];
   var r = lib.wc.strWidth(e);
-  return this.textAttributes.matchesContainer(this.cursorNode_) && this.cursorNode_.textContent.substr(this.cursorOffset_) == e ? (this.cursorOffset_ += r, void(this.cursorPosition.column += r)) : (this.deleteChars(Math.min(r, t)), void this.insertString(e));
-};, hterm.Screen.prototype.deleteChars = function(e) {
-  var t = this.cursorNode_,
-    r = this.cursorOffset_,
-    o = this.cursorPosition.column;
+  return this.textAttributes.matchesContainer(this.cursorNode_) &&
+          this.cursorNode_.textContent.substr(this.cursorOffset_) == e ?
+      (this.cursorOffset_ += r, void(this.cursorPosition.column += r)) :
+      (this.deleteChars(Math.min(r, t)), void this.insertString(e));
+};
+, hterm.Screen.prototype.deleteChars = function(e) {
+  var t = this.cursorNode_, r = this.cursorOffset_,
+      o = this.cursorPosition.column;
   if (e = Math.min(e, this.columnCount_ - o), !e) return 0;
   for (var i, s, n = e; t && e;) {
-    if (i = hterm.TextAttributes.nodeWidth(t), t.textContent = hterm.TextAttributes.nodeSubstr(t, 0, r) + hterm.TextAttributes.nodeSubstr(t, r + e), s = hterm.TextAttributes.nodeWidth(t), e -= i - s, i > r && s && i == s) {
+    if (i = hterm.TextAttributes.nodeWidth(t),
+        t.textContent = hterm.TextAttributes.nodeSubstr(t, 0, r) +
+            hterm.TextAttributes.nodeSubstr(t, r + e),
+        s = hterm.TextAttributes.nodeWidth(t), e -= i - s,
+        i > r && s && i == s) {
       var a = this.textAttributes.createContainer(' ');
-      t.parentNode.insertBefore(a, t.nextSibling), t.textContent = '', s = 0, e -= 1;
+      t.parentNode.insertBefore(a, t.nextSibling), t.textContent = '', s = 0,
+                                                   e -= 1;
     }
     var l = t.nextSibling;
-    0 == s && t != this.cursorNode_ && t.parentNode.removeChild(t), t = l, r = 0;
+    0 == s && t != this.cursorNode_ && t.parentNode.removeChild(t), t = l,
+                                                                    r = 0;
   }
   if (3 != this.cursorNode_.nodeType && !this.cursorNode_.textContent) {
     var h = this.cursorNode_;
-    if (h.previousSibling) this.cursorNode_ = h.previousSibling, this.cursorOffset_ = hterm.TextAttributes.nodeWidth(h.previousSibling);
-    else if (h.nextSibling) this.cursorNode_ = h.nextSibling, this.cursorOffset_ = 0;
+    if (h.previousSibling)
+      this.cursorNode_ = h.previousSibling,
+      this.cursorOffset_ = hterm.TextAttributes.nodeWidth(h.previousSibling);
+    else if (h.nextSibling)
+      this.cursorNode_ = h.nextSibling, this.cursorOffset_ = 0;
     else {
       var c = this.cursorRowNode_.ownerDocument.createTextNode('');
-      this.cursorRowNode_.appendChild(c), this.cursorNode_ = c, this.cursorOffset_ = 0;
+      this.cursorRowNode_.appendChild(c), this.cursorNode_ = c,
+                                          this.cursorOffset_ = 0;
     }
     this.cursorRowNode_.removeChild(h);
   }
   return n;
-};, hterm.Screen.prototype.getLineStartRow_ = function(e) {
-  for (; e.previousSibling && e.previousSibling.hasAttribute('line-overflow');) e = e.previousSibling;
+};
+, hterm.Screen.prototype.getLineStartRow_ = function(e) {
+  for (; e.previousSibling && e.previousSibling.hasAttribute('line-overflow');)
+    e = e.previousSibling;
   return e;
-};, hterm.Screen.prototype.getLineText_ = function(e) {
-  for (var t = ''; e && (t += e.textContent, e.hasAttribute('line-overflow'));) e = e.nextSibling;
+};
+, hterm.Screen.prototype.getLineText_ = function(e) {
+  for (var t = ''; e && (t += e.textContent, e.hasAttribute('line-overflow'));)
+    e = e.nextSibling;
   return t;
-};, hterm.Screen.prototype.getXRowAncestor_ = function(e) {
+};
+, hterm.Screen.prototype.getXRowAncestor_ = function(e) {
   for (; e && 'X-ROW' !== e.nodeName;) e = e.parentNode;
   return e;
-};, hterm.Screen.prototype.getPositionWithOverflow_ = function(e, t, r) {
+};
+, hterm.Screen.prototype.getPositionWithOverflow_ = function(e, t, r) {
   if (!t) return -1;
   var o = this.getXRowAncestor_(t);
   if (!o) return -1;
   for (var i = 0; o != e;) {
-    if (i += hterm.TextAttributes.nodeWidth(e), !e.hasAttribute('line-overflow') || !e.nextSibling) return -1;
+    if (i += hterm.TextAttributes.nodeWidth(e),
+        !e.hasAttribute('line-overflow') || !e.nextSibling)
+      return -1;
     e = e.nextSibling;
   }
   return i + this.getPositionWithinRow_(e, t, r);
-};, hterm.Screen.prototype.getPositionWithinRow_ = function(e, t, r) {
-  if (t.parentNode != e) return this.getPositionWithinRow_(t.parentNode, t, r) + this.getPositionWithinRow_(e, t.parentNode, 0);
+};
+, hterm.Screen.prototype.getPositionWithinRow_ = function(e, t, r) {
+  if (t.parentNode != e)
+    return this.getPositionWithinRow_(t.parentNode, t, r) +
+        this.getPositionWithinRow_(e, t.parentNode, 0);
   for (var o = 0, i = 0; i < e.childNodes.length; i++) {
     var s = e.childNodes[i];
     if (s == t) return o + r;
     o += hterm.TextAttributes.nodeWidth(s);
   }
   return -1;
-};, hterm.Screen.prototype.getNodeAndOffsetWithOverflow_ = function(e, t) {
+};
+, hterm.Screen.prototype.getNodeAndOffsetWithOverflow_ = function(e, t) {
   for (; e && t > hterm.TextAttributes.nodeWidth(e);) {
     if (!e.hasAttribute('line-overflow') || !e.nextSibling) return -1;
     t -= hterm.TextAttributes.nodeWidth(e), e = e.nextSibling;
   }
   return this.getNodeAndOffsetWithinRow_(e, t);
-};, hterm.Screen.prototype.getNodeAndOffsetWithinRow_ = function(e, t) {
+};
+, hterm.Screen.prototype.getNodeAndOffsetWithinRow_ = function(e, t) {
   for (var r = 0; r < e.childNodes.length; r++) {
-    var o = e.childNodes[r],
-      i = hterm.TextAttributes.nodeWidth(o);
-    if (i >= t) return 'SPAN' === o.nodeName ? this.getNodeAndOffsetWithinRow_(o, t) : [o, t];
+    var o = e.childNodes[r], i = hterm.TextAttributes.nodeWidth(o);
+    if (i >= t)
+      return 'SPAN' === o.nodeName ? this.getNodeAndOffsetWithinRow_(o, t) :
+                                     [o, t];
     t -= i;
   }
   return null;
-};, hterm.Screen.prototype.setRange_ = function(e, t, r, o) {
+};
+, hterm.Screen.prototype.setRange_ = function(e, t, r, o) {
   var i = this.getNodeAndOffsetWithOverflow_(e, t);
   if (null != i) {
     var s = this.getNodeAndOffsetWithOverflow_(e, r);
     null != s && (o.setStart(i[0], i[1]), o.setEnd(s[0], s[1]));
   }
-};, hterm.Screen.prototype.expandSelection = function(e) {
+};
+, hterm.Screen.prototype.expandSelection = function(e) {
   if (e) {
     var t = e.getRangeAt(0);
     if (t && !t.toString().match(/\s/)) {
       var r = this.getLineStartRow_(this.getXRowAncestor_(t.startContainer));
       if (r) {
-        var o = this.getPositionWithOverflow_(r, t.startContainer, t.startOffset);
+        var o =
+            this.getPositionWithOverflow_(r, t.startContainer, t.startOffset);
         if (-1 != o) {
           var i = this.getPositionWithOverflow_(r, t.endContainer, t.endOffset);
           if (-1 != i) {
-            var s = "[^\\s\\[\\](){}<>\"'\\^!@#$%&*,;:`]",
-              n = "[^\\s\\[\\](){}<>\"'\\^!@#$%&*,;:~.`]",
-              a = "[^\\s\\[\\](){}<>\"'\\^]*",
-              l = this.getLineText_(r),
-              h = lib.wc.substring(l, 0, i),
-              c = new RegExp(s + a + '$'),
-              u = h.search(c);
+            var s = '[^\\s\\[\\](){}<>"\'\\^!@#$%&*,;:`]',
+                n = '[^\\s\\[\\](){}<>"\'\\^!@#$%&*,;:~.`]',
+                a = '[^\\s\\[\\](){}<>"\'\\^]*', l = this.getLineText_(r),
+                h = lib.wc.substring(l, 0, i), c = new RegExp(s + a + '$'),
+                u = h.search(c);
             if (!(-1 == u || u > o)) {
               var g = lib.wc.substring(l, o, lib.wc.strWidth(l)),
-                d = new RegExp('^' + a + n),
-                p = g.match(d);
+                  d = new RegExp('^' + a + n), p = g.match(d);
               if (p) {
-                var m = o + lib.wc.strWidth(p[0]); - 1 == m || i > m || (this.setRange_(r, u, m, t), e.addRange(t));
+                var m = o + lib.wc.strWidth(p[0]);
+                -1 == m || i > m || (this.setRange_(r, u, m, t), e.addRange(t));
               }
             }
           }
@@ -2843,11 +3668,26 @@
       }
     }
   }
-};, lib.rtdep('lib.f', 'hterm.PubSub', 'hterm.Size'), hterm.ScrollPort = function(e) {
-  hterm.PubSub.addBehavior(this), this.rowProvider_ = e, this.characterSize = new hterm.Size(10, 10), this.ruler_ = null, this.selection = new hterm.ScrollPort.Selection(this), this.currentRowNodeCache_ = null, this.previousRowNodeCache_ = {}, this.lastScreenWidth_ = null, this.lastScreenHeight_ = null, this.selectionEnabled_ = !0, this.lastRowCount_ = 0, this.scrollWheelMultiplier_ = 1, this.isScrolledEnd = !0, this.xrowCssRule_ = null, this.currentScrollbarWidthPx = 16, this.ctrlVPaste = !1, this.div_ = null, this.document_ = null, this.timeouts_ = {}, this.observers_ = {}, this.DEBUG_ = !1;
-};, hterm.ScrollPort.Selection = function(e) {
-  this.scrollPort_ = e, this.startRow = null, this.endRow = null, this.isMultiline = null, this.isCollapsed = null;
-};, hterm.ScrollPort.Selection.prototype.findFirstChild = function(e, t) {
+};
+, lib.rtdep('lib.f', 'hterm.PubSub', 'hterm.Size'),
+    hterm.ScrollPort = function(e) {
+      hterm.PubSub.addBehavior(this),
+          this.rowProvider_ = e, this.characterSize = new hterm.Size(10, 10),
+          this.ruler_ = null,
+          this.selection = new hterm.ScrollPort.Selection(this),
+          this.currentRowNodeCache_ = null, this.previousRowNodeCache_ = {},
+          this.lastScreenWidth_ = null, this.lastScreenHeight_ = null,
+          this.selectionEnabled_ = !0, this.lastRowCount_ = 0,
+          this.scrollWheelMultiplier_ = 1, this.isScrolledEnd = !0,
+          this.xrowCssRule_ = null, this.currentScrollbarWidthPx = 16,
+          this.ctrlVPaste = !1, this.div_ = null, this.document_ = null,
+          this.timeouts_ = {}, this.observers_ = {}, this.DEBUG_ = !1;
+    };
+, hterm.ScrollPort.Selection = function(e) {
+  this.scrollPort_ = e, this.startRow = null, this.endRow = null,
+  this.isMultiline = null, this.isCollapsed = null;
+};
+, hterm.ScrollPort.Selection.prototype.findFirstChild = function(e, t) {
   for (var r = e.firstChild; r;) {
     if (-1 != t.indexOf(r)) return r;
     if (r.childNodes.length) {
@@ -2857,24 +3697,36 @@
     r = r.nextSibling;
   }
   return null;
-};, hterm.ScrollPort.Selection.prototype.sync = function() {
+};
+, hterm.ScrollPort.Selection.prototype.sync = function() {
   function e() {
-    r.startRow = i, r.startNode = o.anchorNode, r.startOffset = o.anchorOffset, r.endRow = s, r.endNode = o.focusNode, r.endOffset = o.focusOffset;
+    r.startRow = i, r.startNode = o.anchorNode, r.startOffset = o.anchorOffset,
+    r.endRow = s, r.endNode = o.focusNode, r.endOffset = o.focusOffset;
   }
 
   function t() {
-    r.startRow = s, r.startNode = o.focusNode, r.startOffset = o.focusOffset, r.endRow = i, r.endNode = o.anchorNode, r.endOffset = o.anchorOffset;
+    r.startRow = s, r.startNode = o.focusNode, r.startOffset = o.focusOffset,
+    r.endRow = i, r.endNode = o.anchorNode, r.endOffset = o.anchorOffset;
   }
-  var r = this,
-    o = this.scrollPort_.getDocument().getSelection();
-  if (this.startRow = null, this.endRow = null, this.isMultiline = null, this.isCollapsed = !o || o.isCollapsed, !this.isCollapsed) {
+  var r = this, o = this.scrollPort_.getDocument().getSelection();
+  if (this.startRow = null, this.endRow = null, this.isMultiline = null,
+      this.isCollapsed = !o || o.isCollapsed, !this.isCollapsed) {
     for (var i = o.anchorNode; i && !('rowIndex' in i);) i = i.parentNode;
-    if (!i) return void console.error('Selection anchor is not rooted in a row node: ' + o.anchorNode.nodeName);
+    if (!i)
+      return void console.error(
+          'Selection anchor is not rooted in a row node: ' +
+          o.anchorNode.nodeName);
     for (var s = o.focusNode; s && !('rowIndex' in s);) s = s.parentNode;
-    if (!s) return void console.error('Selection focus is not rooted in a row node: ' + o.focusNode.nodeName);
-    if (i.rowIndex < s.rowIndex) e();
-    else if (i.rowIndex > s.rowIndex) t();
-    else if (o.focusNode == o.anchorNode) o.anchorOffset < o.focusOffset ? e() : t();
+    if (!s)
+      return void console.error(
+          'Selection focus is not rooted in a row node: ' +
+          o.focusNode.nodeName);
+    if (i.rowIndex < s.rowIndex)
+      e();
+    else if (i.rowIndex > s.rowIndex)
+      t();
+    else if (o.focusNode == o.anchorNode)
+      o.anchorOffset < o.focusOffset ? e() : t();
     else {
       var n = this.findFirstChild(i, [o.anchorNode, o.focusNode]);
       if (!n) throw new Error('Unexpected error syncing selection.');
@@ -2882,487 +3734,794 @@
     }
     this.isMultiline = i.rowIndex != s.rowIndex;
   }
-};, hterm.ScrollPort.prototype.decorate = function(e) {
-  this.div_ = e, this.iframe_ = e.ownerDocument.createElement('iframe'), this.iframe_.style.cssText = 'border: 0;height: 100%;position: absolute;width: 100%', 'mozInnerScreenX' in window && (this.iframe_.src = '#'), e.appendChild(this.iframe_), this.iframe_.contentWindow.addEventListener('resize', this.onResize_.bind(this));
+};
+, hterm.ScrollPort.prototype.decorate = function(e) {
+  this.div_ = e, this.iframe_ = e.ownerDocument.createElement('iframe'),
+  this.iframe_.style.cssText =
+      'border: 0;height: 100%;position: absolute;width: 100%',
+  'mozInnerScreenX' in window && (this.iframe_.src = '#'),
+  e.appendChild(this.iframe_),
+  this.iframe_.contentWindow.addEventListener(
+      'resize', this.onResize_.bind(this));
   var t = this.document_ = this.iframe_.contentDocument;
-  t.body.style.cssText = 'margin: 0px;padding: 0px;height: 100%;width: 100%;overflow: hidden;cursor: text;-webkit-user-select: none;-moz-user-select: none;';
+  t.body.style.cssText =
+      'margin: 0px;padding: 0px;height: 100%;width: 100%;overflow: hidden;cursor: text;-webkit-user-select: none;-moz-user-select: none;';
   var r = t.createElement('style');
-  r.textContent = 'x-row {}', t.head.appendChild(r), this.xrowCssRule_ = t.styleSheets[0].cssRules[0], this.xrowCssRule_.style.display = 'block', this.userCssLink_ = t.createElement('link'), this.userCssLink_.setAttribute('rel', 'stylesheet'), this.screen_ = t.createElement('x-screen'), this.screen_.setAttribute('role', 'textbox'), this.screen_.setAttribute('tabindex', '-1'), this.screen_.style.cssText = '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', t.body.appendChild(this.screen_), this.screen_.addEventListener('scroll', this.onScroll_.bind(this)), this.screen_.addEventListener('mousewheel', this.onScrollWheel_.bind(this)), this.screen_.addEventListener('DOMMouseScroll', this.onScrollWheel_.bind(this)), this.screen_.addEventListener('copy', this.onCopy_.bind(this)), this.screen_.addEventListener('paste', this.onPaste_.bind(this)), t.body.addEventListener('keydown', this.onBodyKeyDown_.bind(this)), this.rowNodes_ = t.createElement('div'), this.rowNodes_.style.cssText = 'display: block;position: fixed;overflow: hidden;-webkit-user-select: text;-moz-user-select: text;', this.screen_.appendChild(this.rowNodes_), this.topSelectBag_ = t.createElement('x-select-bag'), this.topSelectBag_.style.cssText = 'display: block;overflow: hidden;white-space: pre;', this.bottomSelectBag_ = this.topSelectBag_.cloneNode(), this.topFold_ = t.createElement('x-fold'), this.topFold_.style.cssText = 'display: block;', this.rowNodes_.appendChild(this.topFold_), this.bottomFold_ = this.topFold_.cloneNode(), this.rowNodes_.appendChild(this.bottomFold_), this.scrollArea_ = t.createElement('div'), this.scrollArea_.style.cssText = 'visibility: hidden', this.screen_.appendChild(this.scrollArea_);
+  r.textContent = 'x-row {}', t.head.appendChild(r),
+  this.xrowCssRule_ = t.styleSheets[0].cssRules[0],
+  this.xrowCssRule_.style.display = 'block',
+  this.userCssLink_ = t.createElement('link'),
+  this.userCssLink_.setAttribute('rel', 'stylesheet'),
+  this.screen_ = t.createElement('x-screen'),
+  this.screen_.setAttribute('role', 'textbox'),
+  this.screen_.setAttribute('tabindex', '-1'),
+  this.screen_.style.cssText =
+      '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',
+  t.body.appendChild(this.screen_),
+  this.screen_.addEventListener('scroll', this.onScroll_.bind(this)),
+  this.screen_.addEventListener('mousewheel', this.onScrollWheel_.bind(this)),
+  this.screen_.addEventListener(
+      'DOMMouseScroll', this.onScrollWheel_.bind(this)),
+  this.screen_.addEventListener('copy', this.onCopy_.bind(this)),
+  this.screen_.addEventListener('paste', this.onPaste_.bind(this)),
+  t.body.addEventListener('keydown', this.onBodyKeyDown_.bind(this)),
+  this.rowNodes_ = t.createElement('div'),
+  this.rowNodes_.style.cssText =
+      'display: block;position: fixed;overflow: hidden;-webkit-user-select: text;-moz-user-select: text;',
+  this.screen_.appendChild(this.rowNodes_),
+  this.topSelectBag_ = t.createElement('x-select-bag'),
+  this.topSelectBag_.style.cssText =
+      'display: block;overflow: hidden;white-space: pre;',
+  this.bottomSelectBag_ = this.topSelectBag_.cloneNode(),
+  this.topFold_ = t.createElement('x-fold'),
+  this.topFold_.style.cssText = 'display: block;',
+  this.rowNodes_.appendChild(this.topFold_),
+  this.bottomFold_ = this.topFold_.cloneNode(),
+  this.rowNodes_.appendChild(this.bottomFold_),
+  this.scrollArea_ = t.createElement('div'),
+  this.scrollArea_.style.cssText = 'visibility: hidden',
+  this.screen_.appendChild(this.scrollArea_);
   var o = 'http://www.w3.org/2000/svg';
-  this.svg_ = this.div_.ownerDocument.createElementNS(o, 'svg'), this.svg_.setAttribute('xmlns', o), this.svg_.setAttribute('version', '1.1'), this.svg_.style.cssText = 'position: absolute;top: 0;left: 0;visibility: hidden', this.pasteTarget_ = t.createElement('textarea'), this.pasteTarget_.setAttribute('tabindex', '-1'), this.pasteTarget_.style.cssText = 'position: absolute;height: 1px;width: 1px;left: 0px; bottom: 0px;opacity: 0', this.pasteTarget_.contentEditable = !0, this.screen_.appendChild(this.pasteTarget_), this.pasteTarget_.addEventListener('textInput', this.handlePasteTargetTextInput_.bind(this)), this.resize();
-};, hterm.ScrollPort.prototype.setFontFamily = function(e, t) {
-  this.screen_.style.fontFamily = e, t ? this.screen_.style.webkitFontSmoothing = t : this.screen_.style.webkitFontSmoothing = '', this.syncCharacterSize();
-};, hterm.ScrollPort.prototype.getFontFamily = function() {
+  this.svg_ = this.div_.ownerDocument.createElementNS(o, 'svg'),
+  this.svg_.setAttribute('xmlns', o), this.svg_.setAttribute('version', '1.1'),
+  this.svg_.style.cssText =
+      'position: absolute;top: 0;left: 0;visibility: hidden',
+  this.pasteTarget_ = t.createElement('textarea'),
+  this.pasteTarget_.setAttribute('tabindex', '-1'),
+  this.pasteTarget_.style.cssText =
+      'position: absolute;height: 1px;width: 1px;left: 0px; bottom: 0px;opacity: 0',
+  this.pasteTarget_.contentEditable = !0,
+  this.screen_.appendChild(this.pasteTarget_),
+  this.pasteTarget_.addEventListener(
+      'textInput', this.handlePasteTargetTextInput_.bind(this)),
+  this.resize();
+};
+, hterm.ScrollPort.prototype.setFontFamily = function(e, t) {
+  this.screen_.style.fontFamily = e,
+  t ? this.screen_.style.webkitFontSmoothing = t :
+      this.screen_.style.webkitFontSmoothing = '',
+  this.syncCharacterSize();
+};
+, hterm.ScrollPort.prototype.getFontFamily = function() {
   return this.screen_.style.fontFamily;
-};, hterm.ScrollPort.prototype.setUserCss = function(e) {
-  e ? (this.userCssLink_.setAttribute('href', e), this.userCssLink_.parentNode || this.document_.head.appendChild(this.userCssLink_)) : this.userCssLink_.parentNode && this.document_.head.removeChild(this.userCssLink_);
-};, hterm.ScrollPort.prototype.focus = function() {
+};
+, hterm.ScrollPort.prototype.setUserCss = function(e) {
+  e ? (this.userCssLink_.setAttribute('href', e),
+       this.userCssLink_.parentNode ||
+           this.document_.head.appendChild(this.userCssLink_)) :
+      this.userCssLink_.parentNode &&
+          this.document_.head.removeChild(this.userCssLink_);
+};
+, hterm.ScrollPort.prototype.focus = function() {
   this.iframe_.focus(), this.screen_.focus();
-};, hterm.ScrollPort.prototype.getForegroundColor = function() {
+};
+, hterm.ScrollPort.prototype.getForegroundColor = function() {
   return this.screen_.style.color;
-};, hterm.ScrollPort.prototype.setForegroundColor = function(e) {
+};
+, hterm.ScrollPort.prototype.setForegroundColor = function(e) {
   this.screen_.style.color = e;
-};, hterm.ScrollPort.prototype.getBackgroundColor = function() {
+};
+, hterm.ScrollPort.prototype.getBackgroundColor = function() {
   return this.screen_.style.backgroundColor;
-};, hterm.ScrollPort.prototype.setBackgroundColor = function(e) {
+};
+, hterm.ScrollPort.prototype.setBackgroundColor = function(e) {
   this.screen_.style.backgroundColor = e;
-};, hterm.ScrollPort.prototype.setBackgroundImage = function(e) {
+};
+, hterm.ScrollPort.prototype.setBackgroundImage = function(e) {
   this.screen_.style.backgroundImage = e;
-};, hterm.ScrollPort.prototype.setBackgroundSize = function(e) {
+};
+, hterm.ScrollPort.prototype.setBackgroundSize = function(e) {
   this.screen_.style.backgroundSize = e;
-};, hterm.ScrollPort.prototype.setBackgroundPosition = function(e) {
+};
+, hterm.ScrollPort.prototype.setBackgroundPosition = function(e) {
   this.screen_.style.backgroundPosition = e;
-};, hterm.ScrollPort.prototype.setCtrlVPaste = function(e) {
+};
+, hterm.ScrollPort.prototype.setCtrlVPaste = function(e) {
   this.ctrlVPaste = e;
-};, hterm.ScrollPort.prototype.getScreenSize = function() {
+};
+, hterm.ScrollPort.prototype.getScreenSize = function() {
   var e = hterm.getClientSize(this.screen_);
-  return {
-    height: e.height,
-    width: e.width - this.currentScrollbarWidthPx
-  };
-};, hterm.ScrollPort.prototype.getScreenWidth = function() {
+  return {height: e.height, width: e.width - this.currentScrollbarWidthPx};
+};
+, hterm.ScrollPort.prototype.getScreenWidth = function() {
   return this.getScreenSize().width;
-};, hterm.ScrollPort.prototype.getScreenHeight = function() {
+};
+, hterm.ScrollPort.prototype.getScreenHeight = function() {
   return this.getScreenSize().height;
-};, hterm.ScrollPort.prototype.getDocument = function() {
+};
+, hterm.ScrollPort.prototype.getDocument = function() {
   return this.document_;
-};, hterm.ScrollPort.prototype.getScreenNode = function() {
+};
+, hterm.ScrollPort.prototype.getScreenNode = function() {
   return this.screen_;
-};, hterm.ScrollPort.prototype.resetCache = function() {
+};
+, hterm.ScrollPort.prototype.resetCache = function() {
   this.currentRowNodeCache_ = null, this.previousRowNodeCache_ = {};
-};, hterm.ScrollPort.prototype.setRowProvider = function(e) {
+};
+, hterm.ScrollPort.prototype.setRowProvider = function(e) {
   this.resetCache(), this.rowProvider_ = e, this.scheduleRedraw();
-};, hterm.ScrollPort.prototype.invalidate = function() {
+};
+, hterm.ScrollPort.prototype.invalidate = function() {
   for (var e = this.topFold_.nextSibling; e != this.bottomFold_;) {
     var t = e.nextSibling;
     e.parentElement.removeChild(e), e = t;
   }
   this.previousRowNodeCache_ = null;
-  var r = this.getTopRowIndex(),
-    o = this.getBottomRowIndex(r);
+  var r = this.getTopRowIndex(), o = this.getBottomRowIndex(r);
   this.drawVisibleRows_(r, o);
-};, hterm.ScrollPort.prototype.scheduleInvalidate = function() {
+};
+, hterm.ScrollPort.prototype.scheduleInvalidate = function() {
   if (!this.timeouts_.invalidate) {
     var e = this;
     this.timeouts_.invalidate = setTimeout(function() {
       delete e.timeouts_.invalidate, e.invalidate();
     }, 0);
   }
-};, hterm.ScrollPort.prototype.setFontSize = function(e) {
+};
+, hterm.ScrollPort.prototype.setFontSize = function(e) {
   this.screen_.style.fontSize = e + 'px', this.syncCharacterSize();
-};, hterm.ScrollPort.prototype.getFontSize = function() {
+};
+, hterm.ScrollPort.prototype.getFontSize = function() {
   return parseInt(this.screen_.style.fontSize);
-};, hterm.ScrollPort.prototype.measureCharacterSize = function(e) {
+};
+, hterm.ScrollPort.prototype.measureCharacterSize = function(e) {
   var t = 100,
-    r = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
+      r = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
   if (!this.ruler_) {
-    this.ruler_ = this.document_.createElement('div'), this.ruler_.style.cssText = 'position: absolute;top: 0;left: 0;visibility: hidden;height: auto !important;width: auto !important;', this.rulerSpan_ = this.document_.createElement('span');
-    for (var o = '' + r, i = 0; t - 1 > i; ++i) o += String.fromCharCode(13) + r;
-    this.rulerSpan_.innerHTML = o, this.ruler_.appendChild(this.rulerSpan_), this.rulerBaseline_ = this.document_.createElement('span'), this.rulerBaseline_.style.fontSize = '0px', this.rulerBaseline_.textContent = 'X';
+    this.ruler_ = this.document_.createElement('div'),
+    this.ruler_.style.cssText =
+        'position: absolute;top: 0;left: 0;visibility: hidden;height: auto !important;width: auto !important;',
+    this.rulerSpan_ = this.document_.createElement('span');
+    for (var o = '' + r, i = 0; t - 1 > i; ++i)
+      o += String.fromCharCode(13) + r;
+    this.rulerSpan_.innerHTML = o, this.ruler_.appendChild(this.rulerSpan_),
+    this.rulerBaseline_ = this.document_.createElement('span'),
+    this.rulerBaseline_.style.fontSize = '0px',
+    this.rulerBaseline_.textContent = 'X';
   }
-  this.rulerSpan_.style.fontWeight = e || '', this.rowNodes_.appendChild(this.ruler_);
+  this.rulerSpan_.style.fontWeight = e || '',
+  this.rowNodes_.appendChild(this.ruler_);
   var s = hterm.getClientSize(this.rulerSpan_),
-    n = new hterm.Size(s.width / r.length, s.height / t);
-  return this.ruler_.appendChild(this.rulerBaseline_), n.baseline = this.rulerBaseline_.offsetTop, this.ruler_.removeChild(this.rulerBaseline_), this.rowNodes_.removeChild(this.ruler_), this.div_.ownerDocument.body.appendChild(this.svg_), n.zoomFactor = this.svg_.currentScale, this.div_.ownerDocument.body.removeChild(this.svg_), n;
-};, hterm.ScrollPort.prototype.syncCharacterSize = function() {
+      n = new hterm.Size(s.width / r.length, s.height / t);
+  return this.ruler_.appendChild(this.rulerBaseline_),
+         n.baseline = this.rulerBaseline_.offsetTop,
+         this.ruler_.removeChild(this.rulerBaseline_),
+         this.rowNodes_.removeChild(this.ruler_),
+         this.div_.ownerDocument.body.appendChild(this.svg_),
+         n.zoomFactor = this.svg_.currentScale,
+         this.div_.ownerDocument.body.removeChild(this.svg_), n;
+};
+, hterm.ScrollPort.prototype.syncCharacterSize = function() {
   this.characterSize = this.measureCharacterSize();
   var e = this.characterSize.height + 'px';
-  this.xrowCssRule_.style.height = e, this.topSelectBag_.style.height = e, this.bottomSelectBag_.style.height = e, this.resize(), this.DEBUG_ && (this.document_.body.style.paddingTop = this.document_.body.style.paddingBottom = 3 * this.characterSize.height + 'px');
-};, hterm.ScrollPort.prototype.resize = function() {
-  this.currentScrollbarWidthPx = hterm.getClientWidth(this.screen_) - this.screen_.clientWidth, this.syncScrollHeight(), this.syncRowNodesDimensions_();
+  this.xrowCssRule_.style.height = e, this.topSelectBag_.style.height = e,
+  this.bottomSelectBag_.style.height = e, this.resize(),
+  this.DEBUG_ &&
+      (this.document_.body.style.paddingTop =
+           this.document_.body.style.paddingBottom =
+               3 * this.characterSize.height + 'px');
+};
+, hterm.ScrollPort.prototype.resize = function() {
+  this.currentScrollbarWidthPx =
+      hterm.getClientWidth(this.screen_) - this.screen_.clientWidth,
+  this.syncScrollHeight(), this.syncRowNodesDimensions_();
   var e = this;
-  this.publish('resize', {
-    scrollPort: this
-  }, function() {
+  this.publish('resize', {scrollPort: this}, function() {
     e.scrollRowToBottom(e.rowProvider_.getRowCount()), e.scheduleRedraw();
   });
-};, hterm.ScrollPort.prototype.syncRowNodesDimensions_ = function() {
+};
+, hterm.ScrollPort.prototype.syncRowNodesDimensions_ = function() {
   var e = this.getScreenSize();
-  this.lastScreenWidth_ = e.width, this.lastScreenHeight_ = e.height, this.visibleRowCount = lib.f.smartFloorDivide(e.height, this.characterSize.height);
+  this.lastScreenWidth_ = e.width, this.lastScreenHeight_ = e.height,
+  this.visibleRowCount =
+      lib.f.smartFloorDivide(e.height, this.characterSize.height);
   var t = this.visibleRowCount * this.characterSize.height;
-  this.visibleRowTopMargin = 0, this.visibleRowBottomMargin = e.height - t, this.topFold_.style.marginBottom = this.visibleRowTopMargin + 'px';
-  for (var r = 0, o = this.topFold_.previousSibling; o;) r += hterm.getClientHeight(o), o = o.previousSibling;
-  this.rowNodes_.style.width = e.width + 'px', this.rowNodes_.style.height = t + r + 'px', this.rowNodes_.style.left = this.screen_.offsetLeft + 'px', this.rowNodes_.style.top = this.screen_.offsetTop - r + 'px';
-};, hterm.ScrollPort.prototype.syncScrollHeight = function() {
-  this.lastRowCount_ = this.rowProvider_.getRowCount(), this.scrollArea_.style.height = this.characterSize.height * this.lastRowCount_ + this.visibleRowTopMargin + this.visibleRowBottomMargin + 'px';
-};, hterm.ScrollPort.prototype.scheduleRedraw = function() {
+  this.visibleRowTopMargin = 0, this.visibleRowBottomMargin = e.height - t,
+  this.topFold_.style.marginBottom = this.visibleRowTopMargin + 'px';
+  for (var r = 0, o = this.topFold_.previousSibling; o;)
+    r += hterm.getClientHeight(o), o = o.previousSibling;
+  this.rowNodes_.style.width = e.width + 'px',
+  this.rowNodes_.style.height = t + r + 'px',
+  this.rowNodes_.style.left = this.screen_.offsetLeft + 'px',
+  this.rowNodes_.style.top = this.screen_.offsetTop - r + 'px';
+};
+, hterm.ScrollPort.prototype.syncScrollHeight = function() {
+  this.lastRowCount_ = this.rowProvider_.getRowCount(),
+  this.scrollArea_.style.height =
+      this.characterSize.height * this.lastRowCount_ +
+      this.visibleRowTopMargin + this.visibleRowBottomMargin + 'px';
+};
+, hterm.ScrollPort.prototype.scheduleRedraw = function() {
   if (!this.timeouts_.redraw) {
     var e = this;
     this.timeouts_.redraw = setTimeout(function() {
       delete e.timeouts_.redraw, e.redraw_();
     }, 0);
   }
-};, hterm.ScrollPort.prototype.redraw_ = function() {
-  this.resetSelectBags_(), this.selection.sync(), this.syncScrollHeight(), this.currentRowNodeCache_ = {};
-  var e = this.getTopRowIndex(),
-    t = this.getBottomRowIndex(e);
-  this.drawTopFold_(e), this.drawBottomFold_(t), this.drawVisibleRows_(e, t), this.syncRowNodesDimensions_(), this.previousRowNodeCache_ = this.currentRowNodeCache_, this.currentRowNodeCache_ = null, this.isScrolledEnd = this.getTopRowIndex() + this.visibleRowCount >= this.lastRowCount_;
-};, hterm.ScrollPort.prototype.drawTopFold_ = function(e) {
-  if (!this.selection.startRow || this.selection.startRow.rowIndex >= e) return void(this.rowNodes_.firstChild != this.topFold_ && this.rowNodes_.insertBefore(this.topFold_, this.rowNodes_.firstChild));
-  if (!this.selection.isMultiline || this.selection.endRow.rowIndex >= e) this.selection.startRow.nextSibling != this.topFold_ && this.rowNodes_.insertBefore(this.topFold_, this.selection.startRow.nextSibling);
+};
+, hterm.ScrollPort.prototype.redraw_ = function() {
+  this.resetSelectBags_(), this.selection.sync(), this.syncScrollHeight(),
+      this.currentRowNodeCache_ = {};
+  var e = this.getTopRowIndex(), t = this.getBottomRowIndex(e);
+  this.drawTopFold_(e), this.drawBottomFold_(t), this.drawVisibleRows_(e, t),
+      this.syncRowNodesDimensions_(),
+      this.previousRowNodeCache_ = this.currentRowNodeCache_,
+      this.currentRowNodeCache_ = null,
+      this.isScrolledEnd =
+          this.getTopRowIndex() + this.visibleRowCount >= this.lastRowCount_;
+};
+, hterm.ScrollPort.prototype.drawTopFold_ = function(e) {
+  if (!this.selection.startRow || this.selection.startRow.rowIndex >= e)
+    return void(
+        this.rowNodes_.firstChild != this.topFold_ &&
+        this.rowNodes_.insertBefore(this.topFold_, this.rowNodes_.firstChild));
+  if (!this.selection.isMultiline || this.selection.endRow.rowIndex >= e)
+    this.selection.startRow.nextSibling != this.topFold_ &&
+        this.rowNodes_.insertBefore(
+            this.topFold_, this.selection.startRow.nextSibling);
   else
-    for (this.selection.endRow.nextSibling != this.topFold_ && this.rowNodes_.insertBefore(this.topFold_, this.selection.endRow.nextSibling); this.selection.startRow.nextSibling != this.selection.endRow;) this.rowNodes_.removeChild(this.selection.startRow.nextSibling);
-  for (; this.rowNodes_.firstChild != this.selection.startRow;) this.rowNodes_.removeChild(this.rowNodes_.firstChild);
-};, hterm.ScrollPort.prototype.drawBottomFold_ = function(e) {
-  if (!this.selection.endRow || this.selection.endRow.rowIndex <= e) return void(this.rowNodes_.lastChild != this.bottomFold_ && this.rowNodes_.appendChild(this.bottomFold_));
-  if (!this.selection.isMultiline || this.selection.startRow.rowIndex <= e) this.bottomFold_.nextSibling != this.selection.endRow && this.rowNodes_.insertBefore(this.bottomFold_, this.selection.endRow);
+    for (this.selection.endRow.nextSibling != this.topFold_ &&
+             this.rowNodes_.insertBefore(
+                 this.topFold_, this.selection.endRow.nextSibling);
+         this.selection.startRow.nextSibling != this.selection.endRow;)
+      this.rowNodes_.removeChild(this.selection.startRow.nextSibling);
+  for (; this.rowNodes_.firstChild != this.selection.startRow;)
+    this.rowNodes_.removeChild(this.rowNodes_.firstChild);
+};
+, hterm.ScrollPort.prototype.drawBottomFold_ = function(e) {
+  if (!this.selection.endRow || this.selection.endRow.rowIndex <= e)
+    return void(
+        this.rowNodes_.lastChild != this.bottomFold_ &&
+        this.rowNodes_.appendChild(this.bottomFold_));
+  if (!this.selection.isMultiline || this.selection.startRow.rowIndex <= e)
+    this.bottomFold_.nextSibling != this.selection.endRow &&
+        this.rowNodes_.insertBefore(this.bottomFold_, this.selection.endRow);
   else
-    for (this.bottomFold_.nextSibling != this.selection.startRow && this.rowNodes_.insertBefore(this.bottomFold_, this.selection.startRow); this.selection.startRow.nextSibling != this.selection.endRow;) this.rowNodes_.removeChild(this.selection.startRow.nextSibling);
-  for (; this.rowNodes_.lastChild != this.selection.endRow;) this.rowNodes_.removeChild(this.rowNodes_.lastChild);
-};, hterm.ScrollPort.prototype.drawVisibleRows_ = function(e, t) {
+    for (this.bottomFold_.nextSibling != this.selection.startRow &&
+             this.rowNodes_.insertBefore(
+                 this.bottomFold_, this.selection.startRow);
+         this.selection.startRow.nextSibling != this.selection.endRow;)
+      this.rowNodes_.removeChild(this.selection.startRow.nextSibling);
+  for (; this.rowNodes_.lastChild != this.selection.endRow;)
+    this.rowNodes_.removeChild(this.rowNodes_.lastChild);
+};
+, hterm.ScrollPort.prototype.drawVisibleRows_ = function(e, t) {
   function r(e, t) {
     for (; e != t;) {
       if (!e) throw 'Did not encounter target node';
-      if (e == o.bottomFold_) throw 'Encountered bottom fold before target node';
+      if (e == o.bottomFold_)
+        throw 'Encountered bottom fold before target node';
       var r = e;
       e = e.nextSibling, r.parentNode.removeChild(r);
     }
   }
-  for (var o = this, i = this.selection.startRow, s = this.selection.endRow, n = this.bottomFold_, a = this.topFold_.nextSibling, l = Math.min(this.visibleRowCount, this.rowProvider_.getRowCount()), h = 0; l > h; h++) {
+  for (var o = this, i = this.selection.startRow, s = this.selection.endRow,
+           n = this.bottomFold_, a = this.topFold_.nextSibling,
+           l = Math.min(this.visibleRowCount, this.rowProvider_.getRowCount()),
+           h = 0;
+       l > h; h++) {
     var c = e + h;
     if (a != n)
       if (a.rowIndex != c)
-        if (i && i.rowIndex == c) r(a, i), a = i.nextSibling;
-        else if (s && s.rowIndex == c) r(a, s), a = s.nextSibling;
-    else if (a != i && a != s) {
-      var u = this.fetchRowNode_(c);
-      if (!u) {
-        console.log("Couldn't fetch row index: " + c);
-        break;
-      }
-      a != u ? (this.rowNodes_.insertBefore(u, a), !u.nextSibling, this.rowNodes_.removeChild(a), a = u.nextSibling) : a = a.nextSibling;
-    }
+        if (i && i.rowIndex == c)
+          r(a, i), a = i.nextSibling;
+        else if (s && s.rowIndex == c)
+          r(a, s), a = s.nextSibling;
+        else if (a != i && a != s) {
+          var u = this.fetchRowNode_(c);
+          if (!u) {
+            console.log('Couldn\'t fetch row index: ' + c);
+            break;
+          }
+          a != u ? (this.rowNodes_.insertBefore(u, a), !u.nextSibling,
+                    this.rowNodes_.removeChild(a), a = u.nextSibling) :
+                   a = a.nextSibling;
+        } else {
+          var u = this.fetchRowNode_(c);
+          if (!u) {
+            console.log('Couldn\'t fetch row index: ' + c);
+            break;
+          }
+          this.rowNodes_.insertBefore(u, a);
+        }
+      else
+        a = a.nextSibling;
     else {
       var u = this.fetchRowNode_(c);
       if (!u) {
-        console.log("Couldn't fetch row index: " + c);
-        break;
-      }
-      this.rowNodes_.insertBefore(u, a);
-    }
-    else a = a.nextSibling;
-    else {
-      var u = this.fetchRowNode_(c);
-      if (!u) {
-        console.log("Couldn't fetch row index: " + c);
+        console.log('Couldn\'t fetch row index: ' + c);
         break;
       }
       this.rowNodes_.insertBefore(u, a);
     }
   }
   a != this.bottomFold_ && r(a, n);
-};, hterm.ScrollPort.prototype.resetSelectBags_ = function() {
-  this.topSelectBag_.parentNode && (this.topSelectBag_.textContent = '', this.topSelectBag_.parentNode.removeChild(this.topSelectBag_)), this.bottomSelectBag_.parentNode && (this.bottomSelectBag_.textContent = '', this.bottomSelectBag_.parentNode.removeChild(this.bottomSelectBag_));
-};, hterm.ScrollPort.prototype.cacheRowNode_ = function(e) {
+};
+, hterm.ScrollPort.prototype.resetSelectBags_ = function() {
+  this.topSelectBag_.parentNode &&
+      (this.topSelectBag_.textContent = '',
+       this.topSelectBag_.parentNode.removeChild(this.topSelectBag_)),
+      this.bottomSelectBag_.parentNode &&
+      (this.bottomSelectBag_.textContent = '',
+       this.bottomSelectBag_.parentNode.removeChild(this.bottomSelectBag_));
+};
+, hterm.ScrollPort.prototype.cacheRowNode_ = function(e) {
   this.currentRowNodeCache_[e.rowIndex] = e;
-};, hterm.ScrollPort.prototype.fetchRowNode_ = function(e) {
+};
+, hterm.ScrollPort.prototype.fetchRowNode_ = function(e) {
   var t;
-  return t = this.previousRowNodeCache_ && e in this.previousRowNodeCache_ ? this.previousRowNodeCache_[e] : this.rowProvider_.getRowNode(e), this.currentRowNodeCache_ && this.cacheRowNode_(t), t;
-};, hterm.ScrollPort.prototype.selectAll = function() {
+  return t = this.previousRowNodeCache_ && e in this.previousRowNodeCache_ ?
+             this.previousRowNodeCache_[e] :
+             this.rowProvider_.getRowNode(e),
+         this.currentRowNodeCache_ && this.cacheRowNode_(t), t;
+};
+, hterm.ScrollPort.prototype.selectAll = function() {
   var e;
   if (0 != this.topFold_.nextSibling.rowIndex) {
-    for (; this.topFold_.previousSibling;) this.rowNodes_.removeChild(this.topFold_.previousSibling);
-    e = this.fetchRowNode_(0), this.rowNodes_.insertBefore(e, this.topFold_), this.syncRowNodesDimensions_();
-  }
-  else e = this.topFold_.nextSibling;
+    for (; this.topFold_.previousSibling;)
+      this.rowNodes_.removeChild(this.topFold_.previousSibling);
+    e = this.fetchRowNode_(0), this.rowNodes_.insertBefore(e, this.topFold_),
+    this.syncRowNodesDimensions_();
+  } else
+    e = this.topFold_.nextSibling;
   var t, r = this.rowProvider_.getRowCount() - 1;
   if (this.bottomFold_.previousSibling.rowIndex != r) {
-    for (; this.bottomFold_.nextSibling;) this.rowNodes_.removeChild(this.bottomFold_.nextSibling);
+    for (; this.bottomFold_.nextSibling;)
+      this.rowNodes_.removeChild(this.bottomFold_.nextSibling);
     t = this.fetchRowNode_(r), this.rowNodes_.appendChild(t);
-  }
-  else t = this.bottomFold_.previousSibling.rowIndex;
+  } else
+    t = this.bottomFold_.previousSibling.rowIndex;
   var o = this.document_.getSelection();
   o.collapse(e, 0), o.extend(t, t.childNodes.length), this.selection.sync();
-};, hterm.ScrollPort.prototype.getScrollMax_ = function(e) {
-  return hterm.getClientHeight(this.scrollArea_) + this.visibleRowTopMargin + this.visibleRowBottomMargin - hterm.getClientHeight(this.screen_);
-};, hterm.ScrollPort.prototype.scrollRowToTop = function(e) {
-  this.syncScrollHeight(), this.isScrolledEnd = e + this.visibleRowCount >= this.lastRowCount_;
+};
+, hterm.ScrollPort.prototype.getScrollMax_ = function(e) {
+  return hterm.getClientHeight(this.scrollArea_) + this.visibleRowTopMargin +
+      this.visibleRowBottomMargin - hterm.getClientHeight(this.screen_);
+};
+, hterm.ScrollPort.prototype.scrollRowToTop = function(e) {
+  this.syncScrollHeight(),
+      this.isScrolledEnd = e + this.visibleRowCount >= this.lastRowCount_;
   var t = e * this.characterSize.height + this.visibleRowTopMargin,
-    r = this.getScrollMax_();
-  t > r && (t = r), this.screen_.scrollTop != t && (this.screen_.scrollTop = t, this.scheduleRedraw());
-};, hterm.ScrollPort.prototype.scrollRowToBottom = function(e) {
-  this.syncScrollHeight(), this.isScrolledEnd = e + this.visibleRowCount >= this.lastRowCount_;
-  var t = e * this.characterSize.height + this.visibleRowTopMargin + this.visibleRowBottomMargin;
-  t -= this.visibleRowCount * this.characterSize.height, 0 > t && (t = 0), this.screen_.scrollTop != t && (this.screen_.scrollTop = t);
-};, hterm.ScrollPort.prototype.getTopRowIndex = function() {
+      r = this.getScrollMax_();
+  t > r && (t = r),
+      this.screen_.scrollTop != t &&
+      (this.screen_.scrollTop = t, this.scheduleRedraw());
+};
+, hterm.ScrollPort.prototype.scrollRowToBottom = function(e) {
+  this.syncScrollHeight(),
+      this.isScrolledEnd = e + this.visibleRowCount >= this.lastRowCount_;
+  var t = e * this.characterSize.height + this.visibleRowTopMargin +
+      this.visibleRowBottomMargin;
+  t -= this.visibleRowCount * this.characterSize.height, 0 > t && (t = 0),
+      this.screen_.scrollTop != t && (this.screen_.scrollTop = t);
+};
+, hterm.ScrollPort.prototype.getTopRowIndex = function() {
   return Math.round(this.screen_.scrollTop / this.characterSize.height);
-};, hterm.ScrollPort.prototype.getBottomRowIndex = function(e) {
+};
+, hterm.ScrollPort.prototype.getBottomRowIndex = function(e) {
   return e + this.visibleRowCount - 1;
-};, hterm.ScrollPort.prototype.onScroll_ = function(e) {
+};
+, hterm.ScrollPort.prototype.onScroll_ = function(e) {
   var t = this.getScreenSize();
-  return t.width != this.lastScreenWidth_ || t.height != this.lastScreenHeight_ ? void this.resize() : (this.redraw_(), void this.publish('scroll', {
-    scrollPort: this
-  }));
-};, hterm.ScrollPort.prototype.onScrollWheel = function(e) {};, hterm.ScrollPort.prototype.onScrollWheel_ = function(e) {
+  return t.width != this.lastScreenWidth_ ||
+          t.height != this.lastScreenHeight_ ?
+      void this.resize() :
+      (this.redraw_(), void this.publish('scroll', {scrollPort: this}));
+};
+, hterm.ScrollPort.prototype.onScrollWheel = function(e) {};
+, hterm.ScrollPort.prototype.onScrollWheel_ = function(e) {
   if (this.onScrollWheel(e), !e.defaultPrevented) {
     var t = 'DOMMouseScroll' == e.type ? -1 * e.detail : e.wheelDeltaY;
     t *= this.scrollWheelMultiplier_;
     var r = this.screen_.scrollTop - t;
     0 > r && (r = 0);
     var o = this.getScrollMax_();
-    r > o && (r = o), r != this.screen_.scrollTop && (this.screen_.scrollTop = r, e.preventDefault());
+    r > o && (r = o),
+        r != this.screen_.scrollTop &&
+        (this.screen_.scrollTop = r, e.preventDefault());
   }
-};, hterm.ScrollPort.prototype.onResize_ = function(e) {
+};
+, hterm.ScrollPort.prototype.onResize_ = function(e) {
   this.syncCharacterSize(), this.resize();
-};, hterm.ScrollPort.prototype.onCopy = function(e) {};, hterm.ScrollPort.prototype.onCopy_ = function(e) {
-  if (this.onCopy(e), !e.defaultPrevented && (this.resetSelectBags_(), this.selection.sync(), this.selection.startRow && !(this.selection.endRow.rowIndex - this.selection.startRow.rowIndex < 2))) {
-    var t = this.getTopRowIndex(),
-      r = this.getBottomRowIndex(t);
+};
+, hterm.ScrollPort.prototype.onCopy = function(e) {};
+, hterm.ScrollPort.prototype.onCopy_ = function(e) {
+  if (this.onCopy(e),
+      !e.defaultPrevented &&
+          (this.resetSelectBags_(), this.selection.sync(),
+           this.selection.startRow &&
+               !(this.selection.endRow.rowIndex -
+                     this.selection.startRow.rowIndex <
+                 2))) {
+    var t = this.getTopRowIndex(), r = this.getBottomRowIndex(t);
     if (this.selection.startRow.rowIndex < t) {
       var o;
-      o = this.selection.endRow.rowIndex < t ? this.selection.endRow.rowIndex : this.topFold_.nextSibling.rowIndex, this.topSelectBag_.textContent = this.rowProvider_.getRowsText(this.selection.startRow.rowIndex + 1, o), this.rowNodes_.insertBefore(this.topSelectBag_, this.selection.startRow.nextSibling), this.syncRowNodesDimensions_();
+      o = this.selection.endRow.rowIndex < t ?
+          this.selection.endRow.rowIndex :
+          this.topFold_.nextSibling.rowIndex,
+      this.topSelectBag_.textContent = this.rowProvider_.getRowsText(
+          this.selection.startRow.rowIndex + 1, o),
+      this.rowNodes_.insertBefore(
+          this.topSelectBag_, this.selection.startRow.nextSibling),
+      this.syncRowNodesDimensions_();
     }
     if (this.selection.endRow.rowIndex > r) {
       var i;
-      i = this.selection.startRow.rowIndex > r ? this.selection.startRow.rowIndex + 1 : this.bottomFold_.previousSibling.rowIndex + 1, this.bottomSelectBag_.textContent = this.rowProvider_.getRowsText(i, this.selection.endRow.rowIndex), this.rowNodes_.insertBefore(this.bottomSelectBag_, this.selection.endRow);
+      i = this.selection.startRow.rowIndex > r ?
+          this.selection.startRow.rowIndex + 1 :
+          this.bottomFold_.previousSibling.rowIndex + 1,
+      this.bottomSelectBag_.textContent =
+          this.rowProvider_.getRowsText(i, this.selection.endRow.rowIndex),
+      this.rowNodes_.insertBefore(this.bottomSelectBag_, this.selection.endRow);
     }
   }
-};, hterm.ScrollPort.prototype.onBodyKeyDown_ = function(e) {
+};
+, hterm.ScrollPort.prototype.onBodyKeyDown_ = function(e) {
   if (this.ctrlVPaste) {
-    var t = String.fromCharCode(e.which),
-      r = t.toLowerCase();
+    var t = String.fromCharCode(e.which), r = t.toLowerCase();
     (e.ctrlKey || e.metaKey) && 'v' == r && this.pasteTarget_.focus();
   }
-};, hterm.ScrollPort.prototype.onPaste_ = function(e) {
+};
+, hterm.ScrollPort.prototype.onPaste_ = function(e) {
   this.pasteTarget_.focus();
   var t = this;
   setTimeout(function() {
-    t.publish('paste', {
-      text: t.pasteTarget_.value
-    }), t.pasteTarget_.value = '', t.screen_.focus();
+    t.publish('paste', {text: t.pasteTarget_.value}), t.pasteTarget_.value = '',
+                                                      t.screen_.focus();
   }, 0);
-};, hterm.ScrollPort.prototype.handlePasteTargetTextInput_ = function(e) {
+};
+, hterm.ScrollPort.prototype.handlePasteTargetTextInput_ = function(e) {
   e.stopPropagation();
-};, hterm.ScrollPort.prototype.setScrollbarVisible = function(e) {
+};
+, hterm.ScrollPort.prototype.setScrollbarVisible = function(e) {
   this.screen_.style.overflowY = e ? 'scroll' : 'hidden';
-};, hterm.ScrollPort.prototype.setScrollWheelMoveMultipler = function(e) {
+};
+, hterm.ScrollPort.prototype.setScrollWheelMoveMultipler = function(e) {
   this.scrollWheelMultiplier_ = e;
-};, lib.rtdep('lib.colors', 'lib.PreferenceManager', 'lib.resource', 'lib.wc', 'lib.f', 'hterm.Keyboard', 'hterm.Options', 'hterm.PreferenceManager', 'hterm.Screen', 'hterm.ScrollPort', 'hterm.Size', 'hterm.TextAttributes', 'hterm.VT'), hterm.Terminal = function(e) {
-  this.profileId_ = null, this.primaryScreen_ = new hterm.Screen, this.alternateScreen_ = new hterm.Screen, this.screen_ = this.primaryScreen_, this.screenSize = new hterm.Size(0, 0), 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_.onCopy = this.onCopy_.bind(this), this.div_ = null, this.document_ = window.document, this.scrollbackRows_ = [], this.tabStops_ = [], this.defaultTabStops = !0, this.vtScrollTop_ = null, this.vtScrollBottom_ = null, this.cursorNode_ = null, this.cursorShape_ = hterm.Terminal.cursorShape.BLOCK, this.cursorColor_ = null, this.cursorBlinkCycle_ = [100, 100], this.myOnCursorBlink_ = this.onCursorBlink_.bind(this), this.backgroundColor_ = null, this.foregroundColor_ = null, this.scrollOnOutput_ = null, this.scrollOnKeystroke_ = null, this.defeatMouseReports_ = !1, this.bellAudio_ = this.document_.createElement('audio'), this.bellAudio_.setAttribute('preload', 'auto'), this.bellNotificationList_ = [], this.desktopNotificationBell_ = !1, this.savedOptions_ = {}, this.options_ = new hterm.Options, this.timeouts_ = {}, this.vt = new hterm.VT(this), this.keyboard = new hterm.Keyboard(this), this.io = new hterm.Terminal.IO(this), this.enableMouseDragScroll = !0, this.copyOnSelect = null, this.mousePasteButton = null, this.useDefaultWindowCopy = !1, this.clearSelectionAfterCopy = !0, this.realizeSize_(80, 24), this.setDefaultTabStops(), this.setProfile(e || 'default', function() {
-    this.onTerminalReady();
-  }.bind(this));
-};, hterm.Terminal.cursorShape = {
+};
+,
+    lib.rtdep(
+        'lib.colors', 'lib.PreferenceManager', 'lib.resource', 'lib.wc',
+        'lib.f', 'hterm.Keyboard', 'hterm.Options', 'hterm.PreferenceManager',
+        'hterm.Screen', 'hterm.ScrollPort', 'hterm.Size',
+        'hterm.TextAttributes', 'hterm.VT'),
+    hterm.Terminal = function(e) {
+      this.profileId_ = null, this.primaryScreen_ = new hterm.Screen,
+      this.alternateScreen_ = new hterm.Screen,
+      this.screen_ = this.primaryScreen_,
+      this.screenSize = new hterm.Size(0, 0),
+      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_.onCopy = this.onCopy_.bind(this), this.div_ = null,
+      this.document_ = window.document, this.scrollbackRows_ = [],
+      this.tabStops_ = [], this.defaultTabStops = !0, this.vtScrollTop_ = null,
+      this.vtScrollBottom_ = null, this.cursorNode_ = null,
+      this.cursorShape_ = hterm.Terminal.cursorShape.BLOCK,
+      this.cursorColor_ = null, this.cursorBlinkCycle_ = [100, 100],
+      this.myOnCursorBlink_ = this.onCursorBlink_.bind(this),
+      this.backgroundColor_ = null, this.foregroundColor_ = null,
+      this.scrollOnOutput_ = null, this.scrollOnKeystroke_ = null,
+      this.defeatMouseReports_ = !1,
+      this.bellAudio_ = this.document_.createElement('audio'),
+      this.bellAudio_.setAttribute('preload', 'auto'),
+      this.bellNotificationList_ = [], this.desktopNotificationBell_ = !1,
+      this.savedOptions_ = {}, this.options_ = new hterm.Options,
+      this.timeouts_ = {}, this.vt = new hterm.VT(this),
+      this.keyboard = new hterm.Keyboard(this),
+      this.io = new hterm.Terminal.IO(this), this.enableMouseDragScroll = !0,
+      this.copyOnSelect = null, this.mousePasteButton = null,
+      this.useDefaultWindowCopy = !1, this.clearSelectionAfterCopy = !0,
+      this.realizeSize_(80, 24), this.setDefaultTabStops(),
+      this.setProfile(e || 'default', function() {
+        this.onTerminalReady();
+      }.bind(this));
+    };
+, hterm.Terminal.cursorShape = {
   BLOCK: 'BLOCK',
   BEAM: 'BEAM',
   UNDERLINE: 'UNDERLINE'
-}, hterm.Terminal.prototype.onTerminalReady = function() {};, hterm.Terminal.prototype.tabWidth = 8, hterm.Terminal.prototype.setProfile = function(e, t) {
-  this.profileId_ = e.replace(/\//g, '');
-  var r = this;
-  this.prefs_ && this.prefs_.deactivate(), this.prefs_ = new hterm.PreferenceManager(this.profileId_), this.prefs_.addObservers(null, {
-    'alt-gr-mode': function(e) {
-      e = null == e ? 'en-us' == navigator.language.toLowerCase() ? 'none' : 'right-alt' : 'string' == typeof e ? e.toLowerCase() : 'none', /^(none|ctrl-alt|left-alt|right-alt)$/.test(e) || (e = 'none'), r.keyboard.altGrMode = e;
-    },
-    'alt-backspace-is-meta-backspace': function(e) {
-      r.keyboard.altBackspaceIsMetaBackspace = e;
-    },
-    'alt-is-meta': function(e) {
-      r.keyboard.altIsMeta = e;
-    },
-    'alt-sends-what': function(e) {
-      /^(escape|8-bit|browser-key)$/.test(e) || (e = 'escape'), r.keyboard.altSendsWhat = e;
-    },
-    'audible-bell-sound': function(e) {
-      var t = e.match(/^lib-resource:(\S+)/);
-      t ? r.bellAudio_.setAttribute('src', lib.resource.getDataUrl(t[1])) : r.bellAudio_.setAttribute('src', e);
-    },
-    'desktop-notification-bell': function(e) {
-      e && Notification ? (r.desktopNotificationBell_ = 'granted' === Notification.permission, r.desktopNotificationBell_ || console.warn('desktop-notification-bell is true but we do not have permission to display notifications.')) : r.desktopNotificationBell_ = !1;
-    },
-    'background-color': function(e) {
-      r.setBackgroundColor(e);
-    },
-    'background-image': function(e) {
-      r.scrollPort_.setBackgroundImage(e);
-    },
-    'background-size': function(e) {
-      r.scrollPort_.setBackgroundSize(e);
-    },
-    'background-position': function(e) {
-      r.scrollPort_.setBackgroundPosition(e);
-    },
-    'backspace-sends-backspace': function(e) {
-      r.keyboard.backspaceSendsBackspace = e;
-    },
-    'character-map-overrides': function(e) {
-      if (!(null == e || e instanceof Object)) return void console.warn('Preference character-map-modifications is not an object: ' + e);
-      for (var t in e) {
-        var r = hterm.VT.CharacterMap.maps[t].glmap;
-        for (var o in e[t]) r[o] = e[t][o];
-        hterm.VT.CharacterMap.maps[t].reset(r);
-      }
-    },
-    'cursor-blink': function(e) {
-      r.setCursorBlink(!!e);
-    },
-    'cursor-blink-cycle': function(e) {
-      e instanceof Array && 'number' == typeof e[0] && 'number' == typeof e[1] ? r.cursorBlinkCycle_ = e : 'number' == typeof e ? r.cursorBlinkCycle_ = [e, e] : r.cursorBlinkCycle_ = [100, 100]
-    },
-    'cursor-color': function(e) {
-      r.setCursorColor(e);
-    },
-    'color-palette-overrides': function(e) {
-      if (!(null == e || e instanceof Object || e instanceof Array)) return void console.warn('Preference color-palette-overrides is not an array or object: ' + e);
-      if (lib.colors.colorPalette = lib.colors.stockColorPalette.concat(), e)
-        for (var t in e) {
-          var o = parseInt(t);
-          if (isNaN(o) || 0 > o || o > 255) console.log('Invalid value in palette: ' + t + ': ' + e[t]);
-          else if (e[o]) {
-            var i = lib.colors.normalizeCSS(e[o]);
-            i && (lib.colors.colorPalette[o] = i);
+},
+  hterm.Terminal.prototype.onTerminalReady = function() {};
+, hterm.Terminal.prototype.tabWidth = 8,
+  hterm.Terminal.prototype.setProfile = function(e, t) {
+    this.profileId_ = e.replace(/\//g, '');
+    var r = this;
+    this.prefs_ && this.prefs_.deactivate(),
+        this.prefs_ = new hterm.PreferenceManager(this.profileId_),
+        this.prefs_.addObservers(null, {
+          'alt-gr-mode': function(e) {
+            e = null == e ? 'en-us' == navigator.language.toLowerCase() ?
+                            'none' :
+                            'right-alt' :
+                            'string' == typeof e ? e.toLowerCase() : 'none',
+            /^(none|ctrl-alt|left-alt|right-alt)$/.test(e) || (e = 'none'),
+            r.keyboard.altGrMode = e;
+          },
+          'alt-backspace-is-meta-backspace': function(e) {
+            r.keyboard.altBackspaceIsMetaBackspace = e;
+          },
+          'alt-is-meta': function(e) {
+            r.keyboard.altIsMeta = e;
+          },
+          'alt-sends-what': function(e) {
+            /^(escape|8-bit|browser-key)$/.test(e) || (e = 'escape'),
+                r.keyboard.altSendsWhat = e;
+          },
+          'audible-bell-sound': function(e) {
+            var t = e.match(/^lib-resource:(\S+)/);
+            t ? r.bellAudio_.setAttribute(
+                    'src', lib.resource.getDataUrl(t[1])) :
+                r.bellAudio_.setAttribute('src', e);
+          },
+          'desktop-notification-bell': function(e) {
+            e && Notification ?
+                (r.desktopNotificationBell_ =
+                     'granted' === Notification.permission,
+                 r.desktopNotificationBell_ ||
+                     console.warn(
+                         'desktop-notification-bell is true but we do not have permission to display notifications.')) :
+                r.desktopNotificationBell_ = !1;
+          },
+          'background-color': function(e) {
+            r.setBackgroundColor(e);
+          },
+          'background-image': function(e) {
+            r.scrollPort_.setBackgroundImage(e);
+          },
+          'background-size': function(e) {
+            r.scrollPort_.setBackgroundSize(e);
+          },
+          'background-position': function(e) {
+            r.scrollPort_.setBackgroundPosition(e);
+          },
+          'backspace-sends-backspace': function(e) {
+            r.keyboard.backspaceSendsBackspace = e;
+          },
+          'character-map-overrides': function(e) {
+            if (!(null == e || e instanceof Object))
+              return void console.warn(
+                  'Preference character-map-modifications is not an object: ' +
+                  e);
+            for (var t in e) {
+              var r = hterm.VT.CharacterMap.maps[t].glmap;
+              for (var o in e[t]) r[o] = e[t][o];
+              hterm.VT.CharacterMap.maps[t].reset(r);
+            }
+          },
+          'cursor-blink': function(e) {
+            r.setCursorBlink(!!e);
+          },
+          'cursor-blink-cycle': function(e) {
+            e instanceof Array && 'number' == typeof e[0] &&
+                    'number' == typeof e[1] ?
+                r.cursorBlinkCycle_ = e :
+                'number' == typeof e ? r.cursorBlinkCycle_ = [e, e] :
+                                       r.cursorBlinkCycle_ = [100, 100]
+          },
+          'cursor-color': function(e) {
+            r.setCursorColor(e);
+          },
+          'color-palette-overrides': function(e) {
+            if (!(null == e || e instanceof Object || e instanceof Array))
+              return void console.warn(
+                  'Preference color-palette-overrides is not an array or object: ' +
+                  e);
+            if (lib.colors.colorPalette = lib.colors.stockColorPalette.concat(),
+                e)
+              for (var t in e) {
+                var o = parseInt(t);
+                if (isNaN(o) || 0 > o || o > 255)
+                  console.log('Invalid value in palette: ' + t + ': ' + e[t]);
+                else if (e[o]) {
+                  var i = lib.colors.normalizeCSS(e[o]);
+                  i && (lib.colors.colorPalette[o] = i);
+                }
+              }
+            r.primaryScreen_.textAttributes.resetColorPalette(),
+                r.alternateScreen_.textAttributes.resetColorPalette();
+          },
+          'copy-on-select': function(e) {
+            r.copyOnSelect = !!e;
+          },
+          'use-default-window-copy': function(e) {
+            r.useDefaultWindowCopy = !!e;
+          },
+          'clear-selection-after-copy': function(e) {
+            r.clearSelectionAfterCopy = !!e;
+          },
+          'ctrl-plus-minus-zero-zoom': function(e) {
+            r.keyboard.ctrlPlusMinusZeroZoom = e;
+          },
+          'ctrl-c-copy': function(e) {
+            r.keyboard.ctrlCCopy = e;
+          },
+          'ctrl-v-paste': function(e) {
+            r.keyboard.ctrlVPaste = e, r.scrollPort_.setCtrlVPaste(e);
+          },
+          'east-asian-ambiguous-as-two-column': function(e) {
+            lib.wc.regardCjkAmbiguous = e;
+          },
+          'enable-8-bit-control': function(e) {
+            r.vt.enable8BitControl = !!e;
+          },
+          'enable-bold': function(e) {
+            r.syncBoldSafeState();
+          },
+          'enable-bold-as-bright': function(e) {
+            r.primaryScreen_.textAttributes.enableBoldAsBright = !!e,
+            r.alternateScreen_.textAttributes.enableBoldAsBright = !!e;
+          },
+          'enable-blink': function(e) {
+            r.syncBlinkState();
+          },
+          'enable-clipboard-write': function(e) {
+            r.vt.enableClipboardWrite = !!e;
+          },
+          'enable-dec12': function(e) {
+            r.vt.enableDec12 = !!e;
+          },
+          'font-family': function(e) {
+            r.syncFontFamily();
+          },
+          'font-size': function(e) {
+            r.setFontSize(e);
+          },
+          'font-smoothing': function(e) {
+            r.syncFontFamily();
+          },
+          'foreground-color': function(e) {
+            r.setForegroundColor(e);
+          },
+          'home-keys-scroll': function(e) {
+            r.keyboard.homeKeysScroll = e;
+          },
+          keybindings: function(e) {
+            if (r.keyboard.bindings.clear(), e) {
+              if (!(e instanceof Object))
+                return void console.error(
+                    'Error in keybindings preference: Expected object');
+              try {
+                r.keyboard.bindings.addBindings(e);
+              } catch (t) {
+                console.error('Error in keybindings preference: ' + t);
+              }
+            }
+          },
+          'max-string-sequence': function(e) {
+            r.vt.maxStringSequence = e;
+          },
+          'media-keys-are-fkeys': function(e) {
+            r.keyboard.mediaKeysAreFKeys = e;
+          },
+          'meta-sends-escape': function(e) {
+            r.keyboard.metaSendsEscape = e;
+          },
+          'mouse-paste-button': function(e) {
+            r.syncMousePasteButton();
+          },
+          'page-keys-scroll': function(e) {
+            r.keyboard.pageKeysScroll = e;
+          },
+          'pass-alt-number': function(e) {
+            if (null == e) {
+              var t = window.navigator.userAgent.match(/Mac OS X/);
+              e = !t && 'popup' != hterm.windowType;
+            }
+            r.passAltNumber = e;
+          },
+          'pass-ctrl-number': function(e) {
+            if (null == e) {
+              var t = window.navigator.userAgent.match(/Mac OS X/);
+              e = !t && 'popup' != hterm.windowType;
+            }
+            r.passCtrlNumber = e;
+          },
+          'pass-meta-number': function(e) {
+            if (null == e) {
+              var t = window.navigator.userAgent.match(/Mac OS X/);
+              e = t && 'popup' != hterm.windowType;
+            }
+            r.passMetaNumber = e;
+          },
+          'pass-meta-v': function(e) {
+            r.keyboard.passMetaV = e;
+          },
+          'receive-encoding': function(e) {
+            /^(utf-8|raw)$/.test(e) ||
+                (console.warn('Invalid value for "receive-encoding": ' + e),
+                 e = 'utf-8'),
+                r.vt.characterEncoding = e;
+          },
+          'scroll-on-keystroke': function(e) {
+            r.scrollOnKeystroke_ = e;
+          },
+          'scroll-on-output': function(e) {
+            r.scrollOnOutput_ = e;
+          },
+          'scrollbar-visible': function(e) {
+            r.setScrollbarVisible(e);
+          },
+          'scroll-wheel-move-multiplier': function(e) {
+            r.setScrollWheelMoveMultipler(e);
+          },
+          'send-encoding': function(e) {
+            /^(utf-8|raw)$/.test(e) ||
+                (console.warn('Invalid value for "send-encoding": ' + e),
+                 e = 'utf-8'),
+                r.keyboard.characterEncoding = e;
+          },
+          'shift-insert-paste': function(e) {
+            r.keyboard.shiftInsertPaste = e;
+          },
+          'user-css': function(e) {
+            r.scrollPort_.setUserCss(e);
           }
-        }
-      r.primaryScreen_.textAttributes.resetColorPalette(), r.alternateScreen_.textAttributes.resetColorPalette();
-    },
-    'copy-on-select': function(e) {
-      r.copyOnSelect = !!e;
-    },
-    'use-default-window-copy': function(e) {
-      r.useDefaultWindowCopy = !!e;
-    },
-    'clear-selection-after-copy': function(e) {
-      r.clearSelectionAfterCopy = !!e;
-    },
-    'ctrl-plus-minus-zero-zoom': function(e) {
-      r.keyboard.ctrlPlusMinusZeroZoom = e;
-    },
-    'ctrl-c-copy': function(e) {
-      r.keyboard.ctrlCCopy = e;
-    },
-    'ctrl-v-paste': function(e) {
-      r.keyboard.ctrlVPaste = e, r.scrollPort_.setCtrlVPaste(e);
-    },
-    'east-asian-ambiguous-as-two-column': function(e) {
-      lib.wc.regardCjkAmbiguous = e;
-    },
-    'enable-8-bit-control': function(e) {
-      r.vt.enable8BitControl = !!e;
-    },
-    'enable-bold': function(e) {
-      r.syncBoldSafeState();
-    },
-    'enable-bold-as-bright': function(e) {
-      r.primaryScreen_.textAttributes.enableBoldAsBright = !!e, r.alternateScreen_.textAttributes.enableBoldAsBright = !!e;
-    },
-    'enable-blink': function(e) {
-      r.syncBlinkState();
-    },
-    'enable-clipboard-write': function(e) {
-      r.vt.enableClipboardWrite = !!e;
-    },
-    'enable-dec12': function(e) {
-      r.vt.enableDec12 = !!e;
-    },
-    'font-family': function(e) {
-      r.syncFontFamily();
-    },
-    'font-size': function(e) {
-      r.setFontSize(e);
-    },
-    'font-smoothing': function(e) {
-      r.syncFontFamily();
-    },
-    'foreground-color': function(e) {
-      r.setForegroundColor(e);
-    },
-    'home-keys-scroll': function(e) {
-      r.keyboard.homeKeysScroll = e;
-    },
-    keybindings: function(e) {
-      if (r.keyboard.bindings.clear(), e) {
-        if (!(e instanceof Object)) return void console.error('Error in keybindings preference: Expected object');
-        try {
-          r.keyboard.bindings.addBindings(e);
-        }
-        catch (t) {
-          console.error('Error in keybindings preference: ' + t);
-        }
-      }
-    },
-    'max-string-sequence': function(e) {
-      r.vt.maxStringSequence = e;
-    },
-    'media-keys-are-fkeys': function(e) {
-      r.keyboard.mediaKeysAreFKeys = e;
-    },
-    'meta-sends-escape': function(e) {
-      r.keyboard.metaSendsEscape = e;
-    },
-    'mouse-paste-button': function(e) {
-      r.syncMousePasteButton();
-    },
-    'page-keys-scroll': function(e) {
-      r.keyboard.pageKeysScroll = e;
-    },
-    'pass-alt-number': function(e) {
-      if (null == e) {
-        var t = window.navigator.userAgent.match(/Mac OS X/);
-        e = !t && 'popup' != hterm.windowType;
-      }
-      r.passAltNumber = e;
-    },
-    'pass-ctrl-number': function(e) {
-      if (null == e) {
-        var t = window.navigator.userAgent.match(/Mac OS X/);
-        e = !t && 'popup' != hterm.windowType;
-      }
-      r.passCtrlNumber = e;
-    },
-    'pass-meta-number': function(e) {
-      if (null == e) {
-        var t = window.navigator.userAgent.match(/Mac OS X/);
-        e = t && 'popup' != hterm.windowType;
-      }
-      r.passMetaNumber = e;
-    },
-    'pass-meta-v': function(e) {
-      r.keyboard.passMetaV = e;
-    },
-    'receive-encoding': function(e) {
-      /^(utf-8|raw)$/.test(e) || (console.warn('Invalid value for "receive-encoding": ' + e), e = 'utf-8'), r.vt.characterEncoding = e;
-    },
-    'scroll-on-keystroke': function(e) {
-      r.scrollOnKeystroke_ = e;
-    },
-    'scroll-on-output': function(e) {
-      r.scrollOnOutput_ = e;
-    },
-    'scrollbar-visible': function(e) {
-      r.setScrollbarVisible(e);
-    },
-    'scroll-wheel-move-multiplier': function(e) {
-      r.setScrollWheelMoveMultipler(e);
-    },
-    'send-encoding': function(e) {
-      /^(utf-8|raw)$/.test(e) || (console.warn('Invalid value for "send-encoding": ' + e), e = 'utf-8'), r.keyboard.characterEncoding = e;
-    },
-    'shift-insert-paste': function(e) {
-      r.keyboard.shiftInsertPaste = e;
-    },
-    'user-css': function(e) {
-      r.scrollPort_.setUserCss(e);
-    }
-  }), this.prefs_.readStorage(function() {
-    this.prefs_.notifyAll(), t && t();
-  }.bind(this));
-};, hterm.Terminal.prototype.getPrefs = function() {
+        }),
+        this.prefs_.readStorage(function() {
+          this.prefs_.notifyAll(), t && t();
+        }.bind(this));
+  };
+, hterm.Terminal.prototype.getPrefs = function() {
   return this.prefs_;
-};, hterm.Terminal.prototype.setBracketedPaste = function(e) {
+};
+, hterm.Terminal.prototype.setBracketedPaste = function(e) {
   this.options_.bracketedPaste = e;
-};, hterm.Terminal.prototype.setCursorColor = function(e) {
-  this.cursorColor_ = e, this.cursorNode_.style.backgroundColor = e, this.cursorNode_.style.borderColor = e;
-};, hterm.Terminal.prototype.getCursorColor = function() {
+};
+, hterm.Terminal.prototype.setCursorColor = function(e) {
+  this.cursorColor_ = e, this.cursorNode_.style.backgroundColor = e,
+  this.cursorNode_.style.borderColor = e;
+};
+, hterm.Terminal.prototype.getCursorColor = function() {
   return this.cursorColor_;
-};, hterm.Terminal.prototype.setSelectionEnabled = function(e) {
+};
+, hterm.Terminal.prototype.setSelectionEnabled = function(e) {
   this.enableMouseDragScroll = e;
-};, hterm.Terminal.prototype.setBackgroundColor = function(e) {
-  this.backgroundColor_ = lib.colors.normalizeCSS(e), this.primaryScreen_.textAttributes.setDefaults(this.foregroundColor_, this.backgroundColor_), this.alternateScreen_.textAttributes.setDefaults(this.foregroundColor_, this.backgroundColor_), this.scrollPort_.setBackgroundColor(e);
-};, hterm.Terminal.prototype.getBackgroundColor = function() {
+};
+, hterm.Terminal.prototype.setBackgroundColor = function(e) {
+  this.backgroundColor_ = lib.colors.normalizeCSS(e),
+  this.primaryScreen_.textAttributes.setDefaults(
+      this.foregroundColor_, this.backgroundColor_),
+  this.alternateScreen_.textAttributes.setDefaults(
+      this.foregroundColor_, this.backgroundColor_),
+  this.scrollPort_.setBackgroundColor(e);
+};
+, hterm.Terminal.prototype.getBackgroundColor = function() {
   return this.backgroundColor_;
-};, hterm.Terminal.prototype.setForegroundColor = function(e) {
-  this.foregroundColor_ = lib.colors.normalizeCSS(e), this.primaryScreen_.textAttributes.setDefaults(this.foregroundColor_, this.backgroundColor_), this.alternateScreen_.textAttributes.setDefaults(this.foregroundColor_, this.backgroundColor_), this.scrollPort_.setForegroundColor(e);
-};, hterm.Terminal.prototype.getForegroundColor = function() {
+};
+, hterm.Terminal.prototype.setForegroundColor = function(e) {
+  this.foregroundColor_ = lib.colors.normalizeCSS(e),
+  this.primaryScreen_.textAttributes.setDefaults(
+      this.foregroundColor_, this.backgroundColor_),
+  this.alternateScreen_.textAttributes.setDefaults(
+      this.foregroundColor_, this.backgroundColor_),
+  this.scrollPort_.setForegroundColor(e);
+};
+, hterm.Terminal.prototype.getForegroundColor = function() {
   return this.foregroundColor_;
-};, hterm.Terminal.prototype.runCommandClass = function(e, t) {
+};
+, hterm.Terminal.prototype.runCommandClass = function(e, t) {
   var r = this.prefs_.get('environment');
   ('object' != typeof r || null == r) && (r = {});
   var o = this;
@@ -3371,71 +4530,129 @@
     io: this.io.push(),
     environment: r,
     onExit: function(e) {
-      o.io.pop(), o.uninstallKeyboard(), o.prefs_.get('close-on-exit') && window.close();
+      o.io.pop(), o.uninstallKeyboard(),
+          o.prefs_.get('close-on-exit') && window.close();
     }
-  }), this.installKeyboard(), this.command.run();
-};, hterm.Terminal.prototype.isPrimaryScreen = function() {
+  }),
+  this.installKeyboard(), this.command.run();
+};
+, hterm.Terminal.prototype.isPrimaryScreen = function() {
   return this.screen_ == this.primaryScreen_;
-};, hterm.Terminal.prototype.installKeyboard = function() {
+};
+, hterm.Terminal.prototype.installKeyboard = function() {
   this.keyboard.installKeyboard(this.scrollPort_.getDocument().body);
-};, hterm.Terminal.prototype.uninstallKeyboard = function() {
+};
+, hterm.Terminal.prototype.uninstallKeyboard = function() {
   this.keyboard.installKeyboard(null);
-};, hterm.Terminal.prototype.setFontSize = function(e) {
-  0 === e && (e = this.prefs_.get('font-size')), this.scrollPort_.setFontSize(e), this.wcCssRule_ && (this.wcCssRule_.style.width = 2 * this.scrollPort_.characterSize.width + 'px');
-};, hterm.Terminal.prototype.getFontSize = function() {
+};
+, hterm.Terminal.prototype.setFontSize = function(e) {
+  0 === e && (e = this.prefs_.get('font-size')),
+      this.scrollPort_.setFontSize(e),
+      this.wcCssRule_ &&
+      (this.wcCssRule_.style.width =
+           2 * this.scrollPort_.characterSize.width + 'px');
+};
+, hterm.Terminal.prototype.getFontSize = function() {
   return this.scrollPort_.getFontSize();
-};, hterm.Terminal.prototype.getFontFamily = function() {
+};
+, hterm.Terminal.prototype.getFontFamily = function() {
   return this.scrollPort_.getFontFamily();
-};, hterm.Terminal.prototype.syncFontFamily = function() {
-  this.scrollPort_.setFontFamily(this.prefs_.get('font-family'), this.prefs_.get('font-smoothing')), this.syncBoldSafeState();
-};, hterm.Terminal.prototype.syncMousePasteButton = function() {
+};
+, hterm.Terminal.prototype.syncFontFamily = function() {
+  this.scrollPort_.setFontFamily(
+      this.prefs_.get('font-family'), this.prefs_.get('font-smoothing')),
+      this.syncBoldSafeState();
+};
+, hterm.Terminal.prototype.syncMousePasteButton = function() {
   var e = this.prefs_.get('mouse-paste-button');
   if ('number' == typeof e) return void(this.mousePasteButton = e);
   var t = navigator.userAgent.match(/\(X11;\s+(\S+)/);
   t && 'CrOS' != t[2] ? this.mousePasteButton = 3 : this.mousePasteButton = 2;
-};, hterm.Terminal.prototype.syncBoldSafeState = function() {
+};
+, hterm.Terminal.prototype.syncBoldSafeState = function() {
   var e = this.prefs_.get('enable-bold');
-  if (null !== e) return this.primaryScreen_.textAttributes.enableBold = e, void(this.alternateScreen_.textAttributes.enableBold = e);
+  if (null !== e)
+    return this.primaryScreen_.textAttributes.enableBold = e,
+           void(this.alternateScreen_.textAttributes.enableBold = e);
   var t = this.scrollPort_.measureCharacterSize(),
-    r = this.scrollPort_.measureCharacterSize('bold'),
-    o = t.equals(r);
-  o || console.warn('Bold characters disabled: Size of bold weight differs from normal.  Font family is: ' + this.scrollPort_.getFontFamily()), this.primaryScreen_.textAttributes.enableBold = o, this.alternateScreen_.textAttributes.enableBold = o;
-};, hterm.Terminal.prototype.syncBlinkState = function() {
-  this.document_.documentElement.style.setProperty('--hterm-blink-node-duration', this.prefs_.get('enable-blink') ? '0.7s' : '0');
-};, hterm.Terminal.prototype.saveCursor = function() {
+      r = this.scrollPort_.measureCharacterSize('bold'), o = t.equals(r);
+  o ||
+      console.warn(
+          'Bold characters disabled: Size of bold weight differs from normal.  Font family is: ' +
+          this.scrollPort_.getFontFamily()),
+      this.primaryScreen_.textAttributes.enableBold = o,
+      this.alternateScreen_.textAttributes.enableBold = o;
+};
+, hterm.Terminal.prototype.syncBlinkState = function() {
+  this.document_.documentElement.style.setProperty(
+      '--hterm-blink-node-duration',
+      this.prefs_.get('enable-blink') ? '0.7s' : '0');
+};
+, hterm.Terminal.prototype.saveCursor = function() {
   return this.screen_.cursorPosition.clone();
-};, hterm.Terminal.prototype.getTextAttributes = function() {
+};
+, hterm.Terminal.prototype.getTextAttributes = function() {
   return this.screen_.textAttributes;
-};, hterm.Terminal.prototype.setTextAttributes = function(e) {
+};
+, hterm.Terminal.prototype.setTextAttributes = function(e) {
   this.screen_.textAttributes = e;
-};, hterm.Terminal.prototype.getZoomFactor = function() {
+};
+, hterm.Terminal.prototype.getZoomFactor = function() {
   return this.scrollPort_.characterSize.zoomFactor;
-};, hterm.Terminal.prototype.setWindowTitle = function(e) {
+};
+, hterm.Terminal.prototype.setWindowTitle = function(e) {
   window.document.title = e;
-};, hterm.Terminal.prototype.restoreCursor = function(e) {
+};
+, hterm.Terminal.prototype.restoreCursor = function(e) {
   var t = lib.f.clamp(e.row, 0, this.screenSize.height - 1),
-    r = lib.f.clamp(e.column, 0, this.screenSize.width - 1);
-  this.screen_.setCursorPosition(t, r), (e.column > r || e.column == r && e.overflow) && (this.screen_.cursorPosition.overflow = !0);
-};, hterm.Terminal.prototype.clearCursorOverflow = function() {
+      r = lib.f.clamp(e.column, 0, this.screenSize.width - 1);
+  this.screen_.setCursorPosition(t, r),
+      (e.column > r || e.column == r && e.overflow) &&
+      (this.screen_.cursorPosition.overflow = !0);
+};
+, hterm.Terminal.prototype.clearCursorOverflow = function() {
   this.screen_.cursorPosition.overflow = !1;
-};, hterm.Terminal.prototype.setCursorShape = function(e) {
+};
+, hterm.Terminal.prototype.setCursorShape = function(e) {
   this.cursorShape_ = e, this.restyleCursor_();
-};, hterm.Terminal.prototype.getCursorShape = function() {
+};
+, hterm.Terminal.prototype.getCursorShape = function() {
   return this.cursorShape_;
-};, hterm.Terminal.prototype.setWidth = function(e) {
-  return null == e ? void(this.div_.style.width = '100%') : (this.div_.style.width = Math.ceil(this.scrollPort_.characterSize.width * e + this.scrollPort_.currentScrollbarWidthPx) + 'px', this.realizeSize_(e, this.screenSize.height), void this.scheduleSyncCursorPosition_());
-};, hterm.Terminal.prototype.setHeight = function(e) {
-  return null == e ? void(this.div_.style.height = '100%') : (this.div_.style.height = this.scrollPort_.characterSize.height * e + 'px', this.realizeSize_(this.screenSize.width, e), void this.scheduleSyncCursorPosition_());
-};, hterm.Terminal.prototype.realizeSize_ = function(e, t) {
-  e != this.screenSize.width && this.realizeWidth_(e), t != this.screenSize.height && this.realizeHeight_(t), this.io.onTerminalResize_(e, t);
-};, hterm.Terminal.prototype.realizeWidth_ = function(e) {
+};
+, hterm.Terminal.prototype.setWidth = function(e) {
+  return null == e ?
+      void(this.div_.style.width = '100%') :
+      (this.div_.style.width = Math.ceil(
+                                   this.scrollPort_.characterSize.width * e +
+                                   this.scrollPort_.currentScrollbarWidthPx) +
+           'px',
+       this.realizeSize_(e, this.screenSize.height),
+       void this.scheduleSyncCursorPosition_());
+};
+, hterm.Terminal.prototype.setHeight = function(e) {
+  return null == e ? void(this.div_.style.height = '100%') :
+                     (this.div_.style.height =
+                          this.scrollPort_.characterSize.height * e + 'px',
+                      this.realizeSize_(this.screenSize.width, e),
+                      void this.scheduleSyncCursorPosition_());
+};
+, hterm.Terminal.prototype.realizeSize_ = function(e, t) {
+  e != this.screenSize.width && this.realizeWidth_(e),
+      t != this.screenSize.height && this.realizeHeight_(t),
+      this.io.onTerminalResize_(e, t);
+};
+, hterm.Terminal.prototype.realizeWidth_ = function(e) {
   if (0 >= e) throw new Error('Attempt to realize bad width: ' + e);
   var t = e - this.screen_.getWidth();
-  if (this.screenSize.width = e, this.screen_.setColumnCount(e), t > 0) this.defaultTabStops && this.setDefaultTabStops(this.screenSize.width - t);
+  if (this.screenSize.width = e, this.screen_.setColumnCount(e), t > 0)
+    this.defaultTabStops && this.setDefaultTabStops(this.screenSize.width - t);
   else
-    for (var r = this.tabStops_.length - 1; r >= 0 && !(this.tabStops_[r] < e); r--) this.tabStops_.pop();
+    for (var r = this.tabStops_.length - 1; r >= 0 && !(this.tabStops_[r] < e);
+         r--)
+      this.tabStops_.pop();
   this.screen_.setColumnCount(this.screenSize.width);
-};, hterm.Terminal.prototype.realizeHeight_ = function(e) {
+};
+, hterm.Terminal.prototype.realizeHeight_ = function(e) {
   if (0 >= e) throw new Error('Attempt to realize bad height: ' + e);
   var t = e - this.screen_.getHeight();
   this.screenSize.height = e;
@@ -3448,601 +4665,1109 @@
       this.screen_.popRow(), t--;
     }
     var i = this.screen_.shiftRows(t);
-    this.scrollbackRows_.push.apply(this.scrollbackRows_, i), r.row = Math.max(r.row - t, 0);
-  }
-  else if (t > 0) {
+    this.scrollbackRows_.push.apply(this.scrollbackRows_, i),
+        r.row = Math.max(r.row - t, 0);
+  } else if (t > 0) {
     if (t <= this.scrollbackRows_.length) {
       var s = Math.min(t, this.scrollbackRows_.length),
-        n = this.scrollbackRows_.splice(this.scrollbackRows_.length - s, s);
+          n = this.scrollbackRows_.splice(this.scrollbackRows_.length - s, s);
       this.screen_.unshiftRows(n), t -= s, r.row += s;
     }
     t && this.appendRows_(t);
   }
   this.setVTScrollRegion(null, null), this.restoreCursor(r);
-};, hterm.Terminal.prototype.scrollHome = function() {
+};
+, hterm.Terminal.prototype.scrollHome = function() {
   this.scrollPort_.scrollRowToTop(0);
-};, hterm.Terminal.prototype.scrollEnd = function() {
+};
+, hterm.Terminal.prototype.scrollEnd = function() {
   this.scrollPort_.scrollRowToBottom(this.getRowCount());
-};, hterm.Terminal.prototype.scrollPageUp = function() {
+};
+, hterm.Terminal.prototype.scrollPageUp = function() {
   var e = this.scrollPort_.getTopRowIndex();
   this.scrollPort_.scrollRowToTop(e - this.screenSize.height + 1);
-};, hterm.Terminal.prototype.scrollPageDown = function() {
+};
+, hterm.Terminal.prototype.scrollPageDown = function() {
   var e = this.scrollPort_.getTopRowIndex();
   this.scrollPort_.scrollRowToTop(e + this.screenSize.height - 1);
-};, hterm.Terminal.prototype.wipeContents = function() {
-  this.scrollbackRows_.length = 0, this.scrollPort_.resetCache(), [this.primaryScreen_, this.alternateScreen_].forEach(function(e) {
+};
+, hterm.Terminal.prototype.wipeContents = function() {
+  this.scrollbackRows_.length = 0, this.scrollPort_.resetCache(),
+  [this.primaryScreen_, this.alternateScreen_].forEach(function(e) {
     var t = e.getHeight();
     t > 0 && (this.renumberRows_(0, t), this.clearHome(e));
-  }.bind(this)), this.syncCursorPosition_(), this.scrollPort_.invalidate();
-};, hterm.Terminal.prototype.reset = function() {
-  this.clearAllTabStops(), this.setDefaultTabStops(), this.clearHome(this.primaryScreen_), this.primaryScreen_.textAttributes.reset(), this.clearHome(this.alternateScreen_), this.alternateScreen_.textAttributes.reset(), this.setCursorBlink(!!this.prefs_.get('cursor-blink')), this.vt.reset(), this.softReset();
-};, hterm.Terminal.prototype.softReset = function() {
-  this.options_ = new hterm.Options, this.options_.cursorBlink = !!this.timeouts_.cursorBlink, this.primaryScreen_.textAttributes.resetColorPalette(), this.alternateScreen_.textAttributes.resetColorPalette(), this.setVTScrollRegion(null, null), this.setCursorVisible(!0);
-};, hterm.Terminal.prototype.forwardTabStop = function() {
-  for (var e = this.screen_.cursorPosition.column, t = 0; t < this.tabStops_.length; t++)
-    if (this.tabStops_[t] > e) return void this.setCursorColumn(this.tabStops_[t]);
+  }.bind(this)),
+  this.syncCursorPosition_(), this.scrollPort_.invalidate();
+};
+, hterm.Terminal.prototype.reset = function() {
+  this.clearAllTabStops(), this.setDefaultTabStops(),
+      this.clearHome(this.primaryScreen_),
+      this.primaryScreen_.textAttributes.reset(),
+      this.clearHome(this.alternateScreen_),
+      this.alternateScreen_.textAttributes.reset(),
+      this.setCursorBlink(!!this.prefs_.get('cursor-blink')), this.vt.reset(),
+      this.softReset();
+};
+, hterm.Terminal.prototype.softReset = function() {
+  this.options_ = new hterm.Options,
+  this.options_.cursorBlink = !!this.timeouts_.cursorBlink,
+  this.primaryScreen_.textAttributes.resetColorPalette(),
+  this.alternateScreen_.textAttributes.resetColorPalette(),
+  this.setVTScrollRegion(null, null), this.setCursorVisible(!0);
+};
+, hterm.Terminal.prototype.forwardTabStop = function() {
+  for (var e = this.screen_.cursorPosition.column, t = 0;
+       t < this.tabStops_.length; t++)
+    if (this.tabStops_[t] > e)
+      return void this.setCursorColumn(this.tabStops_[t]);
   var r = this.screen_.cursorPosition.overflow;
-  this.setCursorColumn(this.screenSize.width - 1), this.screen_.cursorPosition.overflow = r;
-};, hterm.Terminal.prototype.backwardTabStop = function() {
-  for (var e = this.screen_.cursorPosition.column, t = this.tabStops_.length - 1; t >= 0; t--)
-    if (this.tabStops_[t] < e) return void this.setCursorColumn(this.tabStops_[t]);
+  this.setCursorColumn(this.screenSize.width - 1),
+      this.screen_.cursorPosition.overflow = r;
+};
+, hterm.Terminal.prototype.backwardTabStop = function() {
+  for (var e = this.screen_.cursorPosition.column,
+           t = this.tabStops_.length - 1;
+       t >= 0; t--)
+    if (this.tabStops_[t] < e)
+      return void this.setCursorColumn(this.tabStops_[t]);
   this.setCursorColumn(1);
-};, hterm.Terminal.prototype.setTabStop = function(e) {
+};
+, hterm.Terminal.prototype.setTabStop = function(e) {
   for (var t = this.tabStops_.length - 1; t >= 0; t--) {
     if (this.tabStops_[t] == e) return;
     if (this.tabStops_[t] < e) return void this.tabStops_.splice(t + 1, 0, e);
   }
   this.tabStops_.splice(0, 0, e);
-};, hterm.Terminal.prototype.clearTabStopAtCursor = function() {
-  var e = this.screen_.cursorPosition.column,
-    t = this.tabStops_.indexOf(e); - 1 != t && this.tabStops_.splice(t, 1);
-};, hterm.Terminal.prototype.clearAllTabStops = function() {
+};
+, hterm.Terminal.prototype.clearTabStopAtCursor = function() {
+  var e = this.screen_.cursorPosition.column, t = this.tabStops_.indexOf(e);
+  -1 != t && this.tabStops_.splice(t, 1);
+};
+, hterm.Terminal.prototype.clearAllTabStops = function() {
   this.tabStops_.length = 0, this.defaultTabStops = !1;
-};, hterm.Terminal.prototype.setDefaultTabStops = function(e) {
-  var t = e || 0,
-    r = this.tabWidth;
+};
+, hterm.Terminal.prototype.setDefaultTabStops = function(e) {
+  var t = e || 0, r = this.tabWidth;
   t = t - 1 - (t - 1) % r + r;
   for (var o = t; o < this.screenSize.width; o += r) this.setTabStop(o);
   this.defaultTabStops = !0;
-};, hterm.Terminal.prototype.interpret = function(e) {
+};
+, hterm.Terminal.prototype.interpret = function(e) {
   this.vt.interpret(e), this.scheduleSyncCursorPosition_();
-};, hterm.Terminal.prototype.decorate = function(e) {
-  this.div_ = e, this.scrollPort_.decorate(e), 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_.setUserCss(this.prefs_.get('user-css')), 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.document_.body.oncontextmenu = function() {
+};
+, hterm.Terminal.prototype.decorate = function(e) {
+  this.div_ = e, this.scrollPort_.decorate(e),
+  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_.setUserCss(this.prefs_.get('user-css')),
+  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.document_.body.oncontextmenu = function() {
     return !1;
   };
-  var t = this.onMouse_.bind(this),
-    r = this.scrollPort_.getScreenNode();
-  r.addEventListener('mousedown', t), r.addEventListener('mouseup', t), r.addEventListener('mousemove', t), this.scrollPort_.onScrollWheel = t, r.addEventListener('focus', this.onFocusChange_.bind(this, !0)), r.addEventListener('mousedown', function() {
-    setTimeout(this.onFocusChange_.bind(this, !0));
-  }.bind(this)), r.addEventListener('blur', this.onFocusChange_.bind(this, !1));
+  var t = this.onMouse_.bind(this), r = this.scrollPort_.getScreenNode();
+  r.addEventListener('mousedown', t), r.addEventListener('mouseup', t),
+      r.addEventListener('mousemove', t),
+      this.scrollPort_.onScrollWheel = t,
+      r.addEventListener('focus', this.onFocusChange_.bind(this, !0)),
+      r.addEventListener(
+          'mousedown',
+          function() {
+            setTimeout(this.onFocusChange_.bind(this, !0));
+          }.bind(this)),
+      r.addEventListener('blur', this.onFocusChange_.bind(this, !1));
   var o = this.document_.createElement('style');
-  o.textContent = '.cursor-node[focus="false"] {  box-sizing: border-box;  background-color: transparent !important;  border-width: 2px;  border-style: solid;}.wc-node {  display: inline-block;  text-align: center;  width: ' + 2 * this.scrollPort_.characterSize.width + 'px;}:root {  --hterm-blink-node-duration: 0.7s;}@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;}', this.document_.head.appendChild(o);
-  var i = this.document_.styleSheets,
-    s = i[i.length - 1].cssRules;
-  this.wcCssRule_ = s[s.length - 1], this.cursorNode_ = this.document_.createElement('div'), this.cursorNode_.className = 'cursor-node', this.cursorNode_.style.cssText = 'position: absolute;top: -99px;display: block;width: ' + this.scrollPort_.characterSize.width + 'px;height: ' + this.scrollPort_.characterSize.height + 'px;-webkit-transition: opacity, background-color 100ms linear;-moz-transition: opacity, background-color 100ms linear;', this.setCursorColor(this.prefs_.get('cursor-color')), this.setCursorBlink(!!this.prefs_.get('cursor-blink')), this.restyleCursor_(), this.document_.body.appendChild(this.cursorNode_), this.scrollBlockerNode_ = this.document_.createElement('div'), this.scrollBlockerNode_.style.cssText = 'position: absolute;top: -99px;display: block;width: 10px;height: 10px;', this.document_.body.appendChild(this.scrollBlockerNode_), this.scrollPort_.onScrollWheel = t, ['mousedown', 'mouseup', 'mousemove', 'click', 'dblclick'].forEach(function(e) {
-    this.scrollBlockerNode_.addEventListener(e, t), this.cursorNode_.addEventListener(e, t), this.document_.addEventListener(e, t);
-  }.bind(this)), this.cursorNode_.addEventListener('mousedown', function() {
-    setTimeout(this.focus.bind(this));
-  }.bind(this)), this.setReverseVideo(!1), this.scrollPort_.focus(), this.scrollPort_.scheduleRedraw();
-};, hterm.Terminal.prototype.getDocument = function() {
+  o.textContent =
+      '.cursor-node[focus="false"] {  box-sizing: border-box;  background-color: transparent !important;  border-width: 2px;  border-style: solid;}.wc-node {  display: inline-block;  text-align: center;  width: ' +
+      2 * this.scrollPort_.characterSize.width +
+      'px;}:root {  --hterm-blink-node-duration: 0.7s;}@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;}',
+  this.document_.head.appendChild(o);
+  var i = this.document_.styleSheets, s = i[i.length - 1].cssRules;
+  this.wcCssRule_ = s[s.length - 1],
+  this.cursorNode_ = this.document_.createElement('div'),
+  this.cursorNode_.className = 'cursor-node',
+  this.cursorNode_.style.cssText =
+      'position: absolute;top: -99px;display: block;width: ' +
+      this.scrollPort_.characterSize.width +
+      'px;height: ' + this.scrollPort_.characterSize.height +
+      'px;-webkit-transition: opacity, background-color 100ms linear;-moz-transition: opacity, background-color 100ms linear;',
+  this.setCursorColor(this.prefs_.get('cursor-color')),
+  this.setCursorBlink(!!this.prefs_.get('cursor-blink')), this.restyleCursor_(),
+  this.document_.body.appendChild(this.cursorNode_),
+  this.scrollBlockerNode_ = this.document_.createElement('div'),
+  this.scrollBlockerNode_.style.cssText =
+      'position: absolute;top: -99px;display: block;width: 10px;height: 10px;',
+  this.document_.body.appendChild(this.scrollBlockerNode_),
+  this.scrollPort_.onScrollWheel = t,
+  ['mousedown', 'mouseup', 'mousemove', 'click', 'dblclick'].forEach(function(
+                                                                         e) {
+    this.scrollBlockerNode_.addEventListener(e, t),
+        this.cursorNode_.addEventListener(e, t),
+        this.document_.addEventListener(e, t);
+  }.bind(this)),
+  this.cursorNode_.addEventListener(
+      'mousedown',
+      function() {
+        setTimeout(this.focus.bind(this));
+      }.bind(this)),
+  this.setReverseVideo(!1), this.scrollPort_.focus(),
+  this.scrollPort_.scheduleRedraw();
+};
+, hterm.Terminal.prototype.getDocument = function() {
   return this.document_;
-};, hterm.Terminal.prototype.focus = function() {
+};
+, hterm.Terminal.prototype.focus = function() {
   this.scrollPort_.focus();
-};, hterm.Terminal.prototype.getRowNode = function(e) {
+};
+, hterm.Terminal.prototype.getRowNode = function(e) {
   if (e < this.scrollbackRows_.length) return this.scrollbackRows_[e];
   var t = e - this.scrollbackRows_.length;
   return this.screen_.rowsArray[t];
-};, hterm.Terminal.prototype.getRowsText = function(e, t) {
+};
+, hterm.Terminal.prototype.getRowsText = function(e, t) {
   for (var r = [], o = e; t > o; o++) {
     var i = this.getRowNode(o);
-    r.push(i.textContent), t - 1 > o && !i.getAttribute('line-overflow') && r.push('\n');
+    r.push(i.textContent),
+        t - 1 > o && !i.getAttribute('line-overflow') && r.push('\n');
   }
   return r.join('');
-};, hterm.Terminal.prototype.getRowText = function(e) {
+};
+, hterm.Terminal.prototype.getRowText = function(e) {
   var t = this.getRowNode(e);
   return t.textContent;
-};, hterm.Terminal.prototype.getRowCount = function() {
+};
+, hterm.Terminal.prototype.getRowCount = function() {
   return this.scrollbackRows_.length + this.screen_.rowsArray.length;
-};, hterm.Terminal.prototype.appendRows_ = function(e) {
-  for (var t = this.screen_.rowsArray.length, r = this.scrollbackRows_.length + t, o = 0; e > o; o++) {
+};
+, hterm.Terminal.prototype.appendRows_ = function(e) {
+  for (var t = this.screen_.rowsArray.length,
+           r = this.scrollbackRows_.length + t, o = 0;
+       e > o; o++) {
     var i = this.document_.createElement('x-row');
-    i.appendChild(this.document_.createTextNode('')), i.rowIndex = r + o, this.screen_.pushRow(i);
+    i.appendChild(this.document_.createTextNode('')), i.rowIndex = r + o,
+                                                      this.screen_.pushRow(i);
   }
   var s = this.screen_.rowsArray.length - this.screenSize.height;
   if (s > 0) {
     var n = this.screen_.shiftRows(s);
-    Array.prototype.push.apply(this.scrollbackRows_, n), this.scrollPort_.isScrolledEnd && this.scheduleScrollDown_();
+    Array.prototype.push.apply(this.scrollbackRows_, n),
+        this.scrollPort_.isScrolledEnd && this.scheduleScrollDown_();
   }
-  t >= this.screen_.rowsArray.length && (t = this.screen_.rowsArray.length - 1), this.setAbsoluteCursorPosition(t, 0);
-};, hterm.Terminal.prototype.moveRows_ = function(e, t, r) {
+  t >= this.screen_.rowsArray.length && (t = this.screen_.rowsArray.length - 1),
+      this.setAbsoluteCursorPosition(t, 0);
+};
+, hterm.Terminal.prototype.moveRows_ = function(e, t, r) {
   var o = this.screen_.removeRows(e, t);
   this.screen_.insertRows(r, o);
   var i, s;
-  r > e ? (i = e, s = r + t) : (i = r, s = e + t), this.renumberRows_(i, s), this.scrollPort_.scheduleInvalidate();
-};, hterm.Terminal.prototype.renumberRows_ = function(e, t, r) {
-  for (var o = r || this.screen_, i = this.scrollbackRows_.length, s = e; t > s; s++) o.rowsArray[s].rowIndex = i + s;
-};, hterm.Terminal.prototype.print = function(e) {
+  r > e ? (i = e, s = r + t) : (i = r, s = e + t), this.renumberRows_(i, s),
+      this.scrollPort_.scheduleInvalidate();
+};
+, hterm.Terminal.prototype.renumberRows_ = function(e, t, r) {
+  for (var o = r || this.screen_, i = this.scrollbackRows_.length, s = e; t > s;
+       s++)
+    o.rowsArray[s].rowIndex = i + s;
+};
+, hterm.Terminal.prototype.print = function(e) {
   for (var t = 0, r = lib.wc.strWidth(e); r > t;) {
-    this.options_.wraparound && this.screen_.cursorPosition.overflow && (this.screen_.commitLineOverflow(), this.newLine());
-    var o, i = r - t,
-      s = !1;
-    this.screen_.cursorPosition.column + i >= this.screenSize.width && (s = !0, i = this.screenSize.width - this.screen_.cursorPosition.column), s && !this.options_.wraparound ? (o = lib.wc.substr(e, t, i - 1) + lib.wc.substr(e, r - 1), i = r) : o = lib.wc.substr(e, t, i);
-    for (var n = hterm.TextAttributes.splitWidecharString(o), a = 0; a < n.length; a++) n[a].wcNode && (this.screen_.textAttributes.wcNode = !0), this.options_.insertMode ? this.screen_.insertString(n[a].str) : this.screen_.overwriteString(n[a].str), this.screen_.textAttributes.wcNode = !1;
+    this.options_.wraparound && this.screen_.cursorPosition.overflow &&
+        (this.screen_.commitLineOverflow(), this.newLine());
+    var o, i = r - t, s = !1;
+    this.screen_.cursorPosition.column + i >= this.screenSize.width &&
+        (s = !0,
+         i = this.screenSize.width - this.screen_.cursorPosition.column),
+        s && !this.options_.wraparound ?
+        (o = lib.wc.substr(e, t, i - 1) + lib.wc.substr(e, r - 1), i = r) :
+        o = lib.wc.substr(e, t, i);
+    for (var n = hterm.TextAttributes.splitWidecharString(o), a = 0;
+         a < n.length; a++)
+      n[a].wcNode && (this.screen_.textAttributes.wcNode = !0),
+          this.options_.insertMode ? this.screen_.insertString(n[a].str) :
+                                     this.screen_.overwriteString(n[a].str),
+          this.screen_.textAttributes.wcNode = !1;
     this.screen_.maybeClipCurrentRow(), t += i;
   }
-  this.scheduleSyncCursorPosition_(), this.scrollOnOutput_ && this.scrollPort_.scrollRowToBottom(this.getRowCount());
-};, hterm.Terminal.prototype.setVTScrollRegion = function(e, t) {
-  0 == e && t == this.screenSize.height - 1 ? (this.vtScrollTop_ = null, this.vtScrollBottom_ = null) : (this.vtScrollTop_ = e, this.vtScrollBottom_ = t);
-};, hterm.Terminal.prototype.getVTScrollTop = function() {
+  this.scheduleSyncCursorPosition_(),
+      this.scrollOnOutput_ &&
+      this.scrollPort_.scrollRowToBottom(this.getRowCount());
+};
+, hterm.Terminal.prototype.setVTScrollRegion = function(e, t) {
+  0 == e && t == this.screenSize.height - 1 ?
+      (this.vtScrollTop_ = null, this.vtScrollBottom_ = null) :
+      (this.vtScrollTop_ = e, this.vtScrollBottom_ = t);
+};
+, hterm.Terminal.prototype.getVTScrollTop = function() {
   return null != this.vtScrollTop_ ? this.vtScrollTop_ : 0;
-};, hterm.Terminal.prototype.getVTScrollBottom = function() {
-  return null != this.vtScrollBottom_ ? this.vtScrollBottom_ : this.screenSize.height - 1;
-};, hterm.Terminal.prototype.newLine = function() {
+};
+, hterm.Terminal.prototype.getVTScrollBottom = function() {
+  return null != this.vtScrollBottom_ ? this.vtScrollBottom_ :
+                                        this.screenSize.height - 1;
+};
+, hterm.Terminal.prototype.newLine = function() {
   var e = this.screen_.cursorPosition.row == this.screen_.rowsArray.length - 1;
-  null != this.vtScrollBottom_ ? this.screen_.cursorPosition.row == this.vtScrollBottom_ ? (this.vtScrollUp(1), this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row, 0)) : e ? this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row, 0) : this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row + 1, 0) : e ? this.appendRows_(1) : this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row + 1, 0)
-};, hterm.Terminal.prototype.lineFeed = function() {
+  null != this.vtScrollBottom_ ?
+      this.screen_.cursorPosition.row == this.vtScrollBottom_ ?
+      (this.vtScrollUp(1),
+       this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row, 0)) :
+      e ?
+      this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row, 0) :
+      this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row + 1, 0) :
+      e ? this.appendRows_(1) :
+          this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row + 1, 0)
+};
+, hterm.Terminal.prototype.lineFeed = function() {
   var e = this.screen_.cursorPosition.column;
   this.newLine(), this.setCursorColumn(e);
-};, hterm.Terminal.prototype.formFeed = function() {
+};
+, hterm.Terminal.prototype.formFeed = function() {
   this.options_.autoCarriageReturn ? this.newLine() : this.lineFeed();
-};, hterm.Terminal.prototype.reverseLineFeed = function() {
-  var e = this.getVTScrollTop(),
-    t = this.screen_.cursorPosition.row;
+};
+, hterm.Terminal.prototype.reverseLineFeed = function() {
+  var e = this.getVTScrollTop(), t = this.screen_.cursorPosition.row;
   t == e ? this.insertLines(1) : this.setAbsoluteCursorRow(t - 1);
-};, hterm.Terminal.prototype.eraseToLeft = function() {
+};
+, hterm.Terminal.prototype.eraseToLeft = function() {
   var e = this.saveCursor();
-  this.setCursorColumn(0), this.screen_.overwriteString(lib.f.getWhitespace(e.column + 1)), this.restoreCursor(e);
-};, hterm.Terminal.prototype.eraseToRight = function(e) {
+  this.setCursorColumn(0),
+      this.screen_.overwriteString(lib.f.getWhitespace(e.column + 1)),
+      this.restoreCursor(e);
+};
+, hterm.Terminal.prototype.eraseToRight = function(e) {
   if (!this.screen_.cursorPosition.overflow) {
     var t = this.screenSize.width - this.screen_.cursorPosition.column,
-      r = e ? Math.min(e, t) : t;
-    if (this.screen_.textAttributes.background === this.screen_.textAttributes.DEFAULT_COLOR) {
+        r = e ? Math.min(e, t) : t;
+    if (this.screen_.textAttributes.background ===
+        this.screen_.textAttributes.DEFAULT_COLOR) {
       var o = this.screen_.rowsArray[this.screen_.cursorPosition.row];
-      if (hterm.TextAttributes.nodeWidth(o) <= this.screen_.cursorPosition.column + r) return this.screen_.deleteChars(r), void this.clearCursorOverflow();
+      if (hterm.TextAttributes.nodeWidth(o) <=
+          this.screen_.cursorPosition.column + r)
+        return this.screen_.deleteChars(r), void this.clearCursorOverflow();
     }
     var i = this.saveCursor();
-    this.screen_.overwriteString(lib.f.getWhitespace(r)), this.restoreCursor(i), this.clearCursorOverflow();
+    this.screen_.overwriteString(lib.f.getWhitespace(r)), this.restoreCursor(i),
+        this.clearCursorOverflow();
   }
-};, hterm.Terminal.prototype.eraseLine = function() {
+};
+, hterm.Terminal.prototype.eraseLine = function() {
   var e = this.saveCursor();
-  this.screen_.clearCursorRow(), this.restoreCursor(e), this.clearCursorOverflow();
-};, hterm.Terminal.prototype.eraseAbove = function() {
+  this.screen_.clearCursorRow(), this.restoreCursor(e),
+      this.clearCursorOverflow();
+};
+, hterm.Terminal.prototype.eraseAbove = function() {
   var e = this.saveCursor();
   this.eraseToLeft();
-  for (var t = 0; t < e.row; t++) this.setAbsoluteCursorPosition(t, 0), this.screen_.clearCursorRow();
+  for (var t = 0; t < e.row; t++)
+    this.setAbsoluteCursorPosition(t, 0), this.screen_.clearCursorRow();
   this.restoreCursor(e), this.clearCursorOverflow();
-};, hterm.Terminal.prototype.eraseBelow = function() {
+};
+, hterm.Terminal.prototype.eraseBelow = function() {
   var e = this.saveCursor();
   this.eraseToRight();
-  for (var t = this.screenSize.height - 1, r = e.row + 1; t >= r; r++) this.setAbsoluteCursorPosition(r, 0), this.screen_.clearCursorRow();
+  for (var t = this.screenSize.height - 1, r = e.row + 1; t >= r; r++)
+    this.setAbsoluteCursorPosition(r, 0), this.screen_.clearCursorRow();
   this.restoreCursor(e), this.clearCursorOverflow();
-};, hterm.Terminal.prototype.fill = function(e) {
+};
+, hterm.Terminal.prototype.fill = function(e) {
   var t = this.saveCursor();
   this.setAbsoluteCursorPosition(0, 0);
   for (var r = 0; r < this.screenSize.height; r++)
-    for (var o = 0; o < this.screenSize.width; o++) this.setAbsoluteCursorPosition(r, o), this.screen_.overwriteString(e);
+    for (var o = 0; o < this.screenSize.width; o++)
+      this.setAbsoluteCursorPosition(r, o), this.screen_.overwriteString(e);
   this.restoreCursor(t);
-};, hterm.Terminal.prototype.clearHome = function(e) {
-  var t = e || this.screen_,
-    r = t.getHeight();
+};
+, hterm.Terminal.prototype.clearHome = function(e) {
+  var t = e || this.screen_, r = t.getHeight();
   if (0 != r) {
     for (var o = 0; r > o; o++) t.setCursorPosition(o, 0), t.clearCursorRow();
     t.setCursorPosition(0, 0);
   }
-};, hterm.Terminal.prototype.clear = function(e) {
-  var t = e || this.screen_,
-    r = t.cursorPosition.clone();
+};
+, hterm.Terminal.prototype.clear = function(e) {
+  var t = e || this.screen_, r = t.cursorPosition.clone();
   this.clearHome(t), t.setCursorPosition(r.row, r.column);
-};, hterm.Terminal.prototype.insertLines = function(e) {
-  var t = this.screen_.cursorPosition.row,
-    r = this.getVTScrollBottom();
+};
+, hterm.Terminal.prototype.insertLines = function(e) {
+  var t = this.screen_.cursorPosition.row, r = this.getVTScrollBottom();
   e = Math.min(e, r - t);
   var o = r - t - e + 1;
   o && this.moveRows_(t, o, t + e);
-  for (var i = e - 1; i >= 0; i--) this.setAbsoluteCursorPosition(t + i, 0), this.screen_.clearCursorRow();
-};, hterm.Terminal.prototype.deleteLines = function(e) {
-  var t = this.saveCursor(),
-    r = t.row,
-    o = this.getVTScrollBottom(),
-    i = o - r + 1;
+  for (var i = e - 1; i >= 0; i--)
+    this.setAbsoluteCursorPosition(t + i, 0), this.screen_.clearCursorRow();
+};
+, hterm.Terminal.prototype.deleteLines = function(e) {
+  var t = this.saveCursor(), r = t.row, o = this.getVTScrollBottom(),
+      i = o - r + 1;
   e = Math.min(e, i);
   var s = o - e + 1;
   e != i && this.moveRows_(r, e, s);
-  for (var n = 0; e > n; n++) this.setAbsoluteCursorPosition(s + n, 0), this.screen_.clearCursorRow();
+  for (var n = 0; e > n; n++)
+    this.setAbsoluteCursorPosition(s + n, 0), this.screen_.clearCursorRow();
   this.restoreCursor(t), this.clearCursorOverflow();
-};, hterm.Terminal.prototype.insertSpace = function(e) {
-  var t = this.saveCursor(),
-    r = lib.f.getWhitespace(e || 1);
-  this.screen_.insertString(r), this.screen_.maybeClipCurrentRow(), this.restoreCursor(t), this.clearCursorOverflow();
-};, hterm.Terminal.prototype.deleteChars = function(e) {
+};
+, hterm.Terminal.prototype.insertSpace = function(e) {
+  var t = this.saveCursor(), r = lib.f.getWhitespace(e || 1);
+  this.screen_.insertString(r), this.screen_.maybeClipCurrentRow(),
+      this.restoreCursor(t), this.clearCursorOverflow();
+};
+, hterm.Terminal.prototype.deleteChars = function(e) {
   var t = this.screen_.deleteChars(e);
   if (t && !this.screen_.textAttributes.isDefault()) {
     var r = this.saveCursor();
-    this.setCursorColumn(this.screenSize.width - t), this.screen_.insertString(lib.f.getWhitespace(t)), this.restoreCursor(r);
+    this.setCursorColumn(this.screenSize.width - t),
+        this.screen_.insertString(lib.f.getWhitespace(t)),
+        this.restoreCursor(r);
   }
   this.clearCursorOverflow();
-};, hterm.Terminal.prototype.vtScrollUp = function(e) {
+};
+, hterm.Terminal.prototype.vtScrollUp = function(e) {
   var t = this.saveCursor();
-  this.setAbsoluteCursorRow(this.getVTScrollTop()), this.deleteLines(e), this.restoreCursor(t);
-};, hterm.Terminal.prototype.vtScrollDown = function(e) {
+  this.setAbsoluteCursorRow(this.getVTScrollTop()), this.deleteLines(e),
+      this.restoreCursor(t);
+};
+, hterm.Terminal.prototype.vtScrollDown = function(e) {
   var t = this.saveCursor();
-  this.setAbsoluteCursorPosition(this.getVTScrollTop(), 0), this.insertLines(e), this.restoreCursor(t);
-};, hterm.Terminal.prototype.setCursorPosition = function(e, t) {
-  this.options_.originMode ? this.setRelativeCursorPosition(e, t) : this.setAbsoluteCursorPosition(e, t);
-};, hterm.Terminal.prototype.setRelativeCursorPosition = function(e, t) {
+  this.setAbsoluteCursorPosition(this.getVTScrollTop(), 0), this.insertLines(e),
+      this.restoreCursor(t);
+};
+, hterm.Terminal.prototype.setCursorPosition = function(e, t) {
+  this.options_.originMode ? this.setRelativeCursorPosition(e, t) :
+                             this.setAbsoluteCursorPosition(e, t);
+};
+, hterm.Terminal.prototype.setRelativeCursorPosition = function(e, t) {
   var r = this.getVTScrollTop();
-  e = lib.f.clamp(e + r, r, this.getVTScrollBottom()), t = lib.f.clamp(t, 0, this.screenSize.width - 1), this.screen_.setCursorPosition(e, t);
-};, hterm.Terminal.prototype.setAbsoluteCursorPosition = function(e, t) {
-  e = lib.f.clamp(e, 0, this.screenSize.height - 1), t = lib.f.clamp(t, 0, this.screenSize.width - 1), this.screen_.setCursorPosition(e, t);
-};, hterm.Terminal.prototype.setCursorColumn = function(e) {
+  e = lib.f.clamp(e + r, r, this.getVTScrollBottom()),
+  t = lib.f.clamp(t, 0, this.screenSize.width - 1),
+  this.screen_.setCursorPosition(e, t);
+};
+, hterm.Terminal.prototype.setAbsoluteCursorPosition = function(e, t) {
+  e = lib.f.clamp(e, 0, this.screenSize.height - 1),
+  t = lib.f.clamp(t, 0, this.screenSize.width - 1),
+  this.screen_.setCursorPosition(e, t);
+};
+, hterm.Terminal.prototype.setCursorColumn = function(e) {
   this.setAbsoluteCursorPosition(this.screen_.cursorPosition.row, e);
-};, hterm.Terminal.prototype.getCursorColumn = function() {
+};
+, hterm.Terminal.prototype.getCursorColumn = function() {
   return this.screen_.cursorPosition.column;
-};, hterm.Terminal.prototype.setAbsoluteCursorRow = function(e) {
+};
+, hterm.Terminal.prototype.setAbsoluteCursorRow = function(e) {
   this.setAbsoluteCursorPosition(e, this.screen_.cursorPosition.column);
-};, hterm.Terminal.prototype.getCursorRow = function() {
+};
+, hterm.Terminal.prototype.getCursorRow = function() {
   return this.screen_.cursorPosition.row;
-};, hterm.Terminal.prototype.scheduleRedraw_ = function() {
+};
+, hterm.Terminal.prototype.scheduleRedraw_ = function() {
   if (!this.timeouts_.redraw) {
     var e = this;
     this.timeouts_.redraw = setTimeout(function() {
       delete e.timeouts_.redraw, e.scrollPort_.redraw_();
     }, 0);
   }
-};, hterm.Terminal.prototype.scheduleScrollDown_ = function() {
+};
+, hterm.Terminal.prototype.scheduleScrollDown_ = function() {
   if (!this.timeouts_.scrollDown) {
     var e = this;
     this.timeouts_.scrollDown = setTimeout(function() {
-      delete e.timeouts_.scrollDown, e.scrollPort_.scrollRowToBottom(e.getRowCount());
+      delete e.timeouts_.scrollDown,
+          e.scrollPort_.scrollRowToBottom(e.getRowCount());
     }, 10);
   }
-};, hterm.Terminal.prototype.cursorUp = function(e) {
+};
+, hterm.Terminal.prototype.cursorUp = function(e) {
   return this.cursorDown(-(e || 1));
-};, hterm.Terminal.prototype.cursorDown = function(e) {
+};
+, hterm.Terminal.prototype.cursorDown = function(e) {
   e = e || 1;
   var t = this.options_.originMode ? this.getVTScrollTop() : 0,
-    r = this.options_.originMode ? this.getVTScrollBottom() : this.screenSize.height - 1,
-    o = lib.f.clamp(this.screen_.cursorPosition.row + e, t, r);
+      r = this.options_.originMode ? this.getVTScrollBottom() :
+                                     this.screenSize.height - 1,
+      o = lib.f.clamp(this.screen_.cursorPosition.row + e, t, r);
   this.setAbsoluteCursorRow(o);
-};, hterm.Terminal.prototype.cursorLeft = function(e) {
+};
+, hterm.Terminal.prototype.cursorLeft = function(e) {
   if (e = e || 1, !(1 > e)) {
     var t = this.screen_.cursorPosition.column;
     if (this.options_.reverseWraparound) {
-      if (this.screen_.cursorPosition.overflow && (e--, this.clearCursorOverflow(), !e)) return;
-      var r = this.screen_.cursorPosition.row,
-        o = t - e;
-      0 > o && (r = r - Math.floor(e / this.screenSize.width) - 1, 0 > r && (r = this.screenSize.height + r % this.screenSize.height), o = this.screenSize.width + o % this.screenSize.width), this.setCursorPosition(Math.max(r, 0), o);
-    }
-    else {
+      if (this.screen_.cursorPosition.overflow &&
+          (e--, this.clearCursorOverflow(), !e))
+        return;
+      var r = this.screen_.cursorPosition.row, o = t - e;
+      0 > o &&
+          (r = r - Math.floor(e / this.screenSize.width) - 1,
+           0 > r && (r = this.screenSize.height + r % this.screenSize.height),
+           o = this.screenSize.width + o % this.screenSize.width),
+          this.setCursorPosition(Math.max(r, 0), o);
+    } else {
       var o = Math.max(t - e, 0);
       this.setCursorColumn(o);
     }
   }
-};, hterm.Terminal.prototype.cursorRight = function(e) {
+};
+, hterm.Terminal.prototype.cursorRight = function(e) {
   if (e = e || 1, !(1 > e)) {
-    var t = lib.f.clamp(this.screen_.cursorPosition.column + e, 0, this.screenSize.width - 1);
+    var t = lib.f.clamp(
+        this.screen_.cursorPosition.column + e, 0, this.screenSize.width - 1);
     this.setCursorColumn(t);
   }
-};, hterm.Terminal.prototype.setReverseVideo = function(e) {
-  this.options_.reverseVideo = e, e ? (this.scrollPort_.setForegroundColor(this.prefs_.get('background-color')), this.scrollPort_.setBackgroundColor(this.prefs_.get('foreground-color'))) : (this.scrollPort_.setForegroundColor(this.prefs_.get('foreground-color')), this.scrollPort_.setBackgroundColor(this.prefs_.get('background-color')));
-};, hterm.Terminal.prototype.ringBell = function() {
-  this.cursorNode_.style.backgroundColor = this.scrollPort_.getForegroundColor();
+};
+, hterm.Terminal.prototype.setReverseVideo = function(e) {
+  this.options_.reverseVideo = e,
+  e ? (this.scrollPort_.setForegroundColor(this.prefs_.get('background-color')),
+       this.scrollPort_.setBackgroundColor(
+           this.prefs_.get('foreground-color'))) :
+      (this.scrollPort_.setForegroundColor(this.prefs_.get('foreground-color')),
+       this.scrollPort_.setBackgroundColor(
+           this.prefs_.get('background-color')));
+};
+, hterm.Terminal.prototype.ringBell = function() {
+  this.cursorNode_.style.backgroundColor =
+      this.scrollPort_.getForegroundColor();
   var e = this;
-  if (setTimeout(function() {
-      e.cursorNode_.style.backgroundColor = e.prefs_.get('cursor-color');
-    }, 200), !this.bellSquelchTimeout_ && (this.bellAudio_.getAttribute('src') ? (this.bellAudio_.play(), this.bellSequelchTimeout_ = setTimeout(function() {
-      delete this.bellSquelchTimeout_;
-    }.bind(this), 500)) : delete this.bellSquelchTimeout_, this.desktopNotificationBell_ && !this.document_.hasFocus())) {
-    var t = new Notification(lib.f.replaceVars(hterm.desktopNotificationTitle, {
-      title: window.document.title || 'hterm'
-    }));
+  if (setTimeout(
+          function() {
+            e.cursorNode_.style.backgroundColor = e.prefs_.get('cursor-color');
+          },
+          200),
+      !this.bellSquelchTimeout_ &&
+          (this.bellAudio_.getAttribute('src') ?
+               (this.bellAudio_.play(),
+                this.bellSequelchTimeout_ = setTimeout(
+                    function() {
+                      delete this.bellSquelchTimeout_;
+                    }.bind(this),
+                    500)) :
+               delete this.bellSquelchTimeout_,
+           this.desktopNotificationBell_ && !this.document_.hasFocus())) {
+    var t = new Notification(lib.f.replaceVars(
+        hterm.desktopNotificationTitle,
+        {title: window.document.title || 'hterm'}));
     this.bellNotificationList_.push(t), t.onclick = function() {
       e.closeBellNotifications_();
     };
   }
-};, hterm.Terminal.prototype.setOriginMode = function(e) {
+};
+, hterm.Terminal.prototype.setOriginMode = function(e) {
   this.options_.originMode = e, this.setCursorPosition(0, 0);
-};, hterm.Terminal.prototype.setInsertMode = function(e) {
+};
+, hterm.Terminal.prototype.setInsertMode = function(e) {
   this.options_.insertMode = e;
-};, hterm.Terminal.prototype.setAutoCarriageReturn = function(e) {
+};
+, hterm.Terminal.prototype.setAutoCarriageReturn = function(e) {
   this.options_.autoCarriageReturn = e;
-};, hterm.Terminal.prototype.setWraparound = function(e) {
+};
+, hterm.Terminal.prototype.setWraparound = function(e) {
   this.options_.wraparound = e;
-};, hterm.Terminal.prototype.setReverseWraparound = function(e) {
+};
+, hterm.Terminal.prototype.setReverseWraparound = function(e) {
   this.options_.reverseWraparound = e;
-};, hterm.Terminal.prototype.setAlternateMode = function(e) {
+};
+, hterm.Terminal.prototype.setAlternateMode = function(e) {
   var t = this.saveCursor();
-  if (this.screen_ = e ? this.alternateScreen_ : this.primaryScreen_, this.screen_.rowsArray.length && this.screen_.rowsArray[0].rowIndex != this.scrollbackRows_.length)
-    for (var r = this.scrollbackRows_.length, o = this.screen_.rowsArray, i = 0; i < o.length; i++) o[i].rowIndex = r + i;
-  this.realizeWidth_(this.screenSize.width), this.realizeHeight_(this.screenSize.height), this.scrollPort_.syncScrollHeight(), this.scrollPort_.invalidate(), this.restoreCursor(t), this.scrollPort_.resize();
-};, hterm.Terminal.prototype.setCursorBlink = function(e) {
-  this.options_.cursorBlink = e, !e && this.timeouts_.cursorBlink && (clearTimeout(this.timeouts_.cursorBlink), delete this.timeouts_.cursorBlink), this.options_.cursorVisible && this.setCursorVisible(!0);
-};, hterm.Terminal.prototype.setCursorVisible = function(e) {
-  if (this.options_.cursorVisible = e, !e) return this.timeouts_.cursorBlink && (clearTimeout(this.timeouts_.cursorBlink), delete this.timeouts_.cursorBlink), void(this.cursorNode_.style.opacity = '0');
-  if (this.syncCursorPosition_(), this.cursorNode_.style.opacity = '1', this.options_.cursorBlink) {
+  if (this.screen_ = e ? this.alternateScreen_ : this.primaryScreen_,
+      this.screen_.rowsArray.length &&
+          this.screen_.rowsArray[0].rowIndex != this.scrollbackRows_.length)
+    for (var r = this.scrollbackRows_.length, o = this.screen_.rowsArray, i = 0;
+         i < o.length; i++)
+      o[i].rowIndex = r + i;
+  this.realizeWidth_(this.screenSize.width),
+      this.realizeHeight_(this.screenSize.height),
+      this.scrollPort_.syncScrollHeight(), this.scrollPort_.invalidate(),
+      this.restoreCursor(t), this.scrollPort_.resize();
+};
+, hterm.Terminal.prototype.setCursorBlink = function(e) {
+  this.options_.cursorBlink = e,
+  !e && this.timeouts_.cursorBlink &&
+      (clearTimeout(this.timeouts_.cursorBlink),
+       delete this.timeouts_.cursorBlink),
+  this.options_.cursorVisible && this.setCursorVisible(!0);
+};
+, hterm.Terminal.prototype.setCursorVisible = function(e) {
+  if (this.options_.cursorVisible = e, !e)
+    return this.timeouts_.cursorBlink &&
+               (clearTimeout(this.timeouts_.cursorBlink),
+                delete this.timeouts_.cursorBlink),
+           void(this.cursorNode_.style.opacity = '0');
+  if (this.syncCursorPosition_(), this.cursorNode_.style.opacity = '1',
+      this.options_.cursorBlink) {
     if (this.timeouts_.cursorBlink) return;
     this.onCursorBlink_();
-  }
-  else this.timeouts_.cursorBlink && (clearTimeout(this.timeouts_.cursorBlink), delete this.timeouts_.cursorBlink);
-};, hterm.Terminal.prototype.syncCursorPosition_ = function() {
+  } else
+    this.timeouts_.cursorBlink &&
+        (clearTimeout(this.timeouts_.cursorBlink),
+         delete this.timeouts_.cursorBlink);
+};
+, hterm.Terminal.prototype.syncCursorPosition_ = function() {
   var e = this.scrollPort_.getTopRowIndex(),
-    t = this.scrollPort_.getBottomRowIndex(e),
-    r = this.scrollbackRows_.length + this.screen_.cursorPosition.row;
-  if (r > t) return void(this.cursorNode_.style.top = -this.scrollPort_.characterSize.height + 'px');
-  this.options_.cursorVisible && 'none' == this.cursorNode_.style.display && (this.cursorNode_.style.display = ''), this.cursorNode_.style.top = this.scrollPort_.visibleRowTopMargin + this.scrollPort_.characterSize.height * (r - e) + 'px', this.cursorNode_.style.left = this.scrollPort_.characterSize.width * this.screen_.cursorPosition.column + 'px', this.cursorNode_.setAttribute('title', '(' + this.screen_.cursorPosition.row + ', ' + this.screen_.cursorPosition.column + ')');
+      t = this.scrollPort_.getBottomRowIndex(e),
+      r = this.scrollbackRows_.length + this.screen_.cursorPosition.row;
+  if (r > t)
+    return void(
+        this.cursorNode_.style.top =
+            -this.scrollPort_.characterSize.height + 'px');
+  this.options_.cursorVisible && 'none' == this.cursorNode_.style.display &&
+      (this.cursorNode_.style.display = ''),
+      this.cursorNode_.style.top = this.scrollPort_.visibleRowTopMargin +
+      this.scrollPort_.characterSize.height * (r - e) + 'px',
+      this.cursorNode_.style.left = this.scrollPort_.characterSize.width *
+          this.screen_.cursorPosition.column +
+      'px',
+      this.cursorNode_.setAttribute(
+          'title',
+          '(' + this.screen_.cursorPosition.row + ', ' +
+              this.screen_.cursorPosition.column + ')');
   var o = this.document_.getSelection();
   o && o.isCollapsed && this.screen_.syncSelectionCaret(o);
-};, hterm.Terminal.prototype.restyleCursor_ = function() {
+};
+, hterm.Terminal.prototype.restyleCursor_ = function() {
   var e = this.cursorShape_;
-  'false' == this.cursorNode_.getAttribute('focus') && (e = hterm.Terminal.cursorShape.BLOCK);
+  'false' == this.cursorNode_.getAttribute('focus') &&
+      (e = hterm.Terminal.cursorShape.BLOCK);
   var t = this.cursorNode_.style;
   switch (t.width = this.scrollPort_.characterSize.width + 'px', e) {
     case hterm.Terminal.cursorShape.BEAM:
-      t.height = this.scrollPort_.characterSize.height + 'px', t.backgroundColor = 'transparent', t.borderBottomStyle = null, t.borderLeftStyle = 'solid';
+      t.height = this.scrollPort_.characterSize.height + 'px',
+      t.backgroundColor = 'transparent', t.borderBottomStyle = null,
+      t.borderLeftStyle = 'solid';
       break;
     case hterm.Terminal.cursorShape.UNDERLINE:
-      t.height = this.scrollPort_.characterSize.baseline + 'px', t.backgroundColor = 'transparent', t.borderBottomStyle = 'solid', t.borderLeftStyle = null;
+      t.height = this.scrollPort_.characterSize.baseline + 'px',
+      t.backgroundColor = 'transparent', t.borderBottomStyle = 'solid',
+      t.borderLeftStyle = null;
       break;
     default:
-      t.height = this.scrollPort_.characterSize.height + 'px', t.backgroundColor = this.cursorColor_, t.borderBottomStyle = null, t.borderLeftStyle = null;
+      t.height = this.scrollPort_.characterSize.height + 'px',
+      t.backgroundColor = this.cursorColor_, t.borderBottomStyle = null,
+      t.borderLeftStyle = null;
   }
-};, hterm.Terminal.prototype.scheduleSyncCursorPosition_ = function() {
+};
+, hterm.Terminal.prototype.scheduleSyncCursorPosition_ = function() {
   if (!this.timeouts_.syncCursor) {
     var e = this;
     this.timeouts_.syncCursor = setTimeout(function() {
       e.syncCursorPosition_(), delete e.timeouts_.syncCursor;
     }, 0);
   }
-};, hterm.Terminal.prototype.showZoomWarning_ = function(e) {
+};
+, hterm.Terminal.prototype.showZoomWarning_ = function(e) {
   if (!this.zoomWarningNode_) {
     if (!e) return;
-    this.zoomWarningNode_ = this.document_.createElement('div'), 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.zoomWarningNode_ = this.document_.createElement('div'),
+    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.MessageManager.replaceReferences(hterm.zoomWarningMessage, [parseInt(100 * this.scrollPort_.characterSize.zoomFactor)]), this.zoomWarningNode_.style.fontFamily = this.prefs_.get('font-family'), e ? this.zoomWarningNode_.parentNode || this.div_.parentNode.appendChild(this.zoomWarningNode_) : this.zoomWarningNode_.parentNode && this.zoomWarningNode_.parentNode.removeChild(this.zoomWarningNode_);
-};, hterm.Terminal.prototype.showOverlay = function(e, t) {
+  this.zoomWarningNode_.textContent = lib.MessageManager.replaceReferences(
+      hterm.zoomWarningMessage,
+      [parseInt(100 * this.scrollPort_.characterSize.zoomFactor)]),
+  this.zoomWarningNode_.style.fontFamily = this.prefs_.get('font-family'),
+  e ? this.zoomWarningNode_.parentNode ||
+          this.div_.parentNode.appendChild(this.zoomWarningNode_) :
+      this.zoomWarningNode_.parentNode &&
+          this.zoomWarningNode_.parentNode.removeChild(this.zoomWarningNode_);
+};
+, hterm.Terminal.prototype.showOverlay = function(e, t) {
   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) {
+    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();
     }, !0);
   }
-  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 = e, this.overlayNode_.style.opacity = '0.75', this.overlayNode_.parentNode || this.div_.appendChild(this.overlayNode_);
+  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 = e, this.overlayNode_.style.opacity = '0.75',
+  this.overlayNode_.parentNode || this.div_.appendChild(this.overlayNode_);
   var r = hterm.getClientSize(this.div_),
-    o = hterm.getClientSize(this.overlayNode_);
-  this.overlayNode_.style.top = (r.height - o.height) / 2 + 'px', this.overlayNode_.style.left = (r.width - o.width - this.scrollPort_.currentScrollbarWidthPx) / 2 + 'px';
+      o = hterm.getClientSize(this.overlayNode_);
+  this.overlayNode_.style.top = (r.height - o.height) / 2 + 'px',
+  this.overlayNode_.style.left =
+      (r.width - o.width - this.scrollPort_.currentScrollbarWidthPx) / 2 + 'px';
   var i = this;
-  this.overlayTimeout_ && clearTimeout(this.overlayTimeout_), null !== t && (this.overlayTimeout_ = setTimeout(function() {
-    i.overlayNode_.style.opacity = '0', i.overlayTimeout_ = setTimeout(function() {
-      i.overlayNode_.parentNode && i.overlayNode_.parentNode.removeChild(i.overlayNode_), i.overlayTimeout_ = null, i.overlayNode_.style.opacity = '0.75';
-    }, 200);
-  }, t || 1500));
-};, hterm.Terminal.prototype.paste = function() {
+  this.overlayTimeout_ && clearTimeout(this.overlayTimeout_),
+      null !== t &&
+      (this.overlayTimeout_ = setTimeout(function() {
+         i.overlayNode_.style.opacity = '0',
+         i.overlayTimeout_ = setTimeout(function() {
+           i.overlayNode_.parentNode &&
+               i.overlayNode_.parentNode.removeChild(i.overlayNode_),
+               i.overlayTimeout_ = null, i.overlayNode_.style.opacity = '0.75';
+         }, 200);
+       }, t || 1500));
+};
+, hterm.Terminal.prototype.paste = function() {
   hterm.pasteFromClipboard(this.document_);
-};, hterm.Terminal.prototype.copyStringToClipboard = function(e) {
-  this.prefs_.get('enable-clipboard-notice') && setTimeout(this.showOverlay.bind(this, hterm.notifyCopyMessage, 500), 200);
+};
+, hterm.Terminal.prototype.copyStringToClipboard = function(e) {
+  this.prefs_.get('enable-clipboard-notice') &&
+      setTimeout(
+          this.showOverlay.bind(this, hterm.notifyCopyMessage, 500), 200);
   var t = this.document_.createElement('pre');
-  t.textContent = e, t.style.cssText = '-webkit-user-select: text;-moz-user-select: text;position: absolute;top: -99px', this.document_.body.appendChild(t);
-  var r = this.document_.getSelection(),
-    o = r.anchorNode,
-    i = r.anchorOffset,
-    s = r.focusNode,
-    n = r.focusOffset;
-  r.selectAllChildren(t), hterm.copySelectionToClipboard(this.document_), r.extend && (r.collapse(o, i), r.extend(s, n)), t.parentNode.removeChild(t);
-};, hterm.Terminal.prototype.getSelectionText = function() {
+  t.textContent = e,
+  t.style.cssText =
+      '-webkit-user-select: text;-moz-user-select: text;position: absolute;top: -99px',
+  this.document_.body.appendChild(t);
+  var r = this.document_.getSelection(), o = r.anchorNode, i = r.anchorOffset,
+      s = r.focusNode, n = r.focusOffset;
+  r.selectAllChildren(t), hterm.copySelectionToClipboard(this.document_),
+      r.extend && (r.collapse(o, i), r.extend(s, n)),
+      t.parentNode.removeChild(t);
+};
+, hterm.Terminal.prototype.getSelectionText = function() {
   var e = this.scrollPort_.selection;
   if (e.sync(), e.isCollapsed) return null;
-  var t = e.startOffset,
-    r = e.startNode;
+  var t = e.startOffset, r = e.startNode;
   if ('X-ROW' != r.nodeName)
-    for ('#text' == r.nodeName && 'SPAN' == r.parentNode.nodeName && (r = r.parentNode); r.previousSibling;) r = r.previousSibling, t += hterm.TextAttributes.nodeWidth(r);
+    for ('#text' == r.nodeName && 'SPAN' == r.parentNode.nodeName &&
+             (r = r.parentNode);
+         r.previousSibling;)
+      r = r.previousSibling, t += hterm.TextAttributes.nodeWidth(r);
   var o = hterm.TextAttributes.nodeWidth(e.endNode) - e.endOffset;
   if (r = e.endNode, 'X-ROW' != r.nodeName)
-    for ('#text' == r.nodeName && 'SPAN' == r.parentNode.nodeName && (r = r.parentNode); r.nextSibling;) r = r.nextSibling, o += hterm.TextAttributes.nodeWidth(r);
+    for ('#text' == r.nodeName && 'SPAN' == r.parentNode.nodeName &&
+             (r = r.parentNode);
+         r.nextSibling;)
+      r = r.nextSibling, o += hterm.TextAttributes.nodeWidth(r);
   var i = this.getRowsText(e.startRow.rowIndex, e.endRow.rowIndex + 1);
   return lib.wc.substring(i, t, lib.wc.strWidth(i) - o);
-};, hterm.Terminal.prototype.copySelectionToClipboard = function() {
+};
+, hterm.Terminal.prototype.copySelectionToClipboard = function() {
   var e = this.getSelectionText();
   null != e && this.copyStringToClipboard(e);
-};, hterm.Terminal.prototype.overlaySize = function() {
+};
+, hterm.Terminal.prototype.overlaySize = function() {
   this.showOverlay(this.screenSize.width + 'x' + this.screenSize.height);
-};, hterm.Terminal.prototype.onVTKeystroke = function(e) {
-  this.scrollOnKeystroke_ && this.scrollPort_.scrollRowToBottom(this.getRowCount()), this.io.onVTKeystroke(this.keyboard.encode(e));
-};, hterm.Terminal.prototype.openUrl = function(e) {
+};
+, hterm.Terminal.prototype.onVTKeystroke = function(e) {
+  this.scrollOnKeystroke_ &&
+      this.scrollPort_.scrollRowToBottom(this.getRowCount()),
+      this.io.onVTKeystroke(this.keyboard.encode(e));
+};
+, hterm.Terminal.prototype.openUrl = function(e) {
   var t = window.open(e, '_blank');
   t.focus();
-};, hterm.Terminal.prototype.openSelectedUrl_ = function() {
+};
+, hterm.Terminal.prototype.openSelectedUrl_ = function() {
   var e = this.getSelectionText();
-  null == e && (this.screen_.expandSelection(this.document_.getSelection()), e = this.getSelectionText()), e.length > 2048 || e.search(/[\s\[\](){}<>"'\\^`]/) >= 0 || (e.search('^[a-zA-Z][a-zA-Z0-9+.-]*://') < 0 && (e = 'http://' + e), this.openUrl(e));
-};, hterm.Terminal.prototype.onMouse_ = function(e) {
+  null == e &&
+      (this.screen_.expandSelection(this.document_.getSelection()),
+       e = this.getSelectionText()),
+      e.length > 2048 || e.search(/[\s\[\](){}<>"'\\^`]/) >= 0 ||
+      (e.search('^[a-zA-Z][a-zA-Z0-9+.-]*://') < 0 && (e = 'http://' + e),
+       this.openUrl(e));
+};
+, hterm.Terminal.prototype.onMouse_ = function(e) {
   if (!e.processedByTerminalHandler_) {
-    var t = !this.defeatMouseReports_ && this.vt.mouseReport != this.vt.MOUSE_REPORT_DISABLED;
-    if (e.processedByTerminalHandler_ = !0, e.terminalRow = parseInt((e.clientY - this.scrollPort_.visibleRowTopMargin) / this.scrollPort_.characterSize.height) + 1, e.terminalColumn = parseInt(e.clientX / this.scrollPort_.characterSize.width) + 1, !('mousedown' == e.type && e.terminalColumn > this.screenSize.width)) {
-      if (this.options_.cursorVisible && !t && (e.terminalRow - 1 == this.screen_.cursorPosition.row && e.terminalColumn - 1 == this.screen_.cursorPosition.column ? this.cursorNode_.style.display = 'none' : 'none' == this.cursorNode_.style.display && (this.cursorNode_.style.display = '')), 'mousedown' == e.type && (e.altKey || !t ? (this.defeatMouseReports_ = !0, this.setSelectionEnabled(!0)) : (this.defeatMouseReports_ = !1, this.document_.getSelection().collapseToEnd(), this.setSelectionEnabled(!1), e.preventDefault())), t) this.scrollBlockerNode_.engaged || ('mousedown' == e.type ? (this.scrollBlockerNode_.engaged = !0, this.scrollBlockerNode_.style.top = e.clientY - 5 + 'px', this.scrollBlockerNode_.style.left = e.clientX - 5 + 'px') : 'mousemove' == e.type && (this.document_.getSelection().collapseToEnd(), e.preventDefault())), this.onMouse(e);
+    var t = !this.defeatMouseReports_ &&
+        this.vt.mouseReport != this.vt.MOUSE_REPORT_DISABLED;
+    if (e.processedByTerminalHandler_ = !0,
+        e.terminalRow = parseInt(
+                            (e.clientY - this.scrollPort_.visibleRowTopMargin) /
+                            this.scrollPort_.characterSize.height) +
+            1,
+        e.terminalColumn =
+            parseInt(e.clientX / this.scrollPort_.characterSize.width) + 1,
+        !('mousedown' == e.type && e.terminalColumn > this.screenSize.width)) {
+      if (this.options_.cursorVisible && !t &&
+              (e.terminalRow - 1 ==
+                       this.screen_.cursorPosition.row &&e.terminalColumn - 1 ==
+                       this.screen_.cursorPosition.column ?
+                   this.cursorNode_.style.display = 'none' :
+                   'none' == this.cursorNode_.style.display &&
+                       (this.cursorNode_.style.display = '')),
+          'mousedown' == e.type &&
+              (e.altKey || !t ?
+                   (this.defeatMouseReports_ = !0,
+                    this.setSelectionEnabled(!0)) :
+                   (this.defeatMouseReports_ = !1,
+                    this.document_.getSelection().collapseToEnd(),
+                    this.setSelectionEnabled(!1), e.preventDefault())),
+          t)
+        this.scrollBlockerNode_.engaged ||
+            ('mousedown' == e.type ?
+                 (this.scrollBlockerNode_.engaged = !0,
+                  this.scrollBlockerNode_.style.top = e.clientY - 5 + 'px',
+                  this.scrollBlockerNode_.style.left = e.clientX - 5 + 'px') :
+                 'mousemove' == e.type &&
+                     (this.document_.getSelection().collapseToEnd(),
+                      e.preventDefault())),
+            this.onMouse(e);
       else {
-        if ('dblclick' == e.type && this.copyOnSelect && (this.screen_.expandSelection(this.document_.getSelection()), this.copySelectionToClipboard(this.document_)), 'click' == e.type && !e.shiftKey && e.ctrlKey) return clearTimeout(this.timeouts_.openUrl), void(this.timeouts_.openUrl = setTimeout(this.openSelectedUrl_.bind(this), 500));
-        'mousedown' == e.type && e.which == this.mousePasteButton && this.paste(), 'mouseup' == e.type && 1 == e.which && this.copyOnSelect && !this.document_.getSelection().isCollapsed && this.copySelectionToClipboard(this.document_), 'mousemove' != e.type && 'mouseup' != e.type || !this.scrollBlockerNode_.engaged || (this.scrollBlockerNode_.engaged = !1, this.scrollBlockerNode_.style.top = '-99px');
+        if ('dblclick' == e.type && this.copyOnSelect &&
+                (this.screen_.expandSelection(this.document_.getSelection()),
+                 this.copySelectionToClipboard(this.document_)),
+            'click' == e.type && !e.shiftKey && e.ctrlKey)
+          return clearTimeout(this.timeouts_.openUrl),
+                 void(
+                     this.timeouts_.openUrl =
+                         setTimeout(this.openSelectedUrl_.bind(this), 500));
+        'mousedown' == e.type && e.which == this.mousePasteButton &&
+            this.paste(),
+            'mouseup' == e.type && 1 == e.which && this.copyOnSelect &&
+            !this.document_.getSelection().isCollapsed &&
+            this.copySelectionToClipboard(this.document_),
+            'mousemove' != e.type && 'mouseup' != e.type ||
+            !this.scrollBlockerNode_.engaged ||
+            (this.scrollBlockerNode_.engaged = !1,
+             this.scrollBlockerNode_.style.top = '-99px');
       }
-      'mouseup' == e.type && this.document_.getSelection().isCollapsed && (this.defeatMouseReports_ = !1);
+      'mouseup' == e.type && this.document_.getSelection().isCollapsed &&
+          (this.defeatMouseReports_ = !1);
     }
   }
-};, hterm.Terminal.prototype.onMouse = function(e) {};, hterm.Terminal.prototype.onFocusChange_ = function(e) {
-  this.cursorNode_.setAttribute('focus', e), this.restyleCursor_(), e === !0 && this.closeBellNotifications_();
-};, hterm.Terminal.prototype.onScroll_ = function() {
+};
+, hterm.Terminal.prototype.onMouse = function(e) {};
+, hterm.Terminal.prototype.onFocusChange_ = function(e) {
+  this.cursorNode_.setAttribute('focus', e), this.restyleCursor_(),
+      e === !0 && this.closeBellNotifications_();
+};
+, hterm.Terminal.prototype.onScroll_ = function() {
   this.scheduleSyncCursorPosition_();
-};, hterm.Terminal.prototype.onPaste_ = function(e) {
+};
+, hterm.Terminal.prototype.onPaste_ = function(e) {
   var t = e.text.replace(/\n/gm, '\r');
-  t = this.keyboard.encode(t), this.options_.bracketedPaste && (t = '[200~' + t + '[201~'), this.io.sendString(t);
-};, hterm.Terminal.prototype.onCopy_ = function(e) {
-  this.useDefaultWindowCopy || (e.preventDefault(), setTimeout(this.copySelectionToClipboard.bind(this), 0));
-};, hterm.Terminal.prototype.onResize_ = function() {
-  var e = Math.floor(this.scrollPort_.getScreenWidth() / this.scrollPort_.characterSize.width) || 0,
-    t = lib.f.smartFloorDivide(this.scrollPort_.getScreenHeight(), this.scrollPort_.characterSize.height) || 0;
+  t = this.keyboard.encode(t),
+  this.options_.bracketedPaste && (t = '[200~' + t + '[201~'),
+  this.io.sendString(t);
+};
+, hterm.Terminal.prototype.onCopy_ = function(e) {
+  this.useDefaultWindowCopy ||
+      (e.preventDefault(),
+       setTimeout(this.copySelectionToClipboard.bind(this), 0));
+};
+, hterm.Terminal.prototype.onResize_ = function() {
+  var e = Math.floor(
+              this.scrollPort_.getScreenWidth() /
+              this.scrollPort_.characterSize.width) ||
+      0,
+      t = lib.f.smartFloorDivide(
+              this.scrollPort_.getScreenHeight(),
+              this.scrollPort_.characterSize.height) ||
+      0;
   if (!(0 >= e || 0 >= t)) {
     var r = e != this.screenSize.width || t != this.screenSize.height;
-    this.realizeSize_(e, t), this.showZoomWarning_(1 != this.scrollPort_.characterSize.zoomFactor), r && this.overlaySize(), this.restyleCursor_(), this.scheduleSyncCursorPosition_();
+    this.realizeSize_(e, t),
+        this.showZoomWarning_(1 != this.scrollPort_.characterSize.zoomFactor),
+        r && this.overlaySize(), this.restyleCursor_(),
+        this.scheduleSyncCursorPosition_();
   }
-};, hterm.Terminal.prototype.onCursorBlink_ = function() {
-  return this.options_.cursorBlink ? void('false' == this.cursorNode_.getAttribute('focus') || '0' == this.cursorNode_.style.opacity ? (this.cursorNode_.style.opacity = '1', this.timeouts_.cursorBlink = setTimeout(this.myOnCursorBlink_, this.cursorBlinkCycle_[0])) : (this.cursorNode_.style.opacity = '0', this.timeouts_.cursorBlink = setTimeout(this.myOnCursorBlink_, this.cursorBlinkCycle_[1]))) : void delete this.timeouts_.cursorBlink;
-};, hterm.Terminal.prototype.setScrollbarVisible = function(e) {
+};
+, hterm.Terminal.prototype.onCursorBlink_ = function() {
+  return this.options_.cursorBlink ?
+      void(
+          'false' == this.cursorNode_.getAttribute('focus') ||
+                  '0' == this.cursorNode_.style.opacity ?
+              (this.cursorNode_.style.opacity = '1',
+               this.timeouts_.cursorBlink = setTimeout(
+                   this.myOnCursorBlink_, this.cursorBlinkCycle_[0])) :
+              (this.cursorNode_.style.opacity = '0',
+               this.timeouts_.cursorBlink = setTimeout(
+                   this.myOnCursorBlink_, this.cursorBlinkCycle_[1]))) :
+      void delete this.timeouts_.cursorBlink;
+};
+, hterm.Terminal.prototype.setScrollbarVisible = function(e) {
   this.scrollPort_.setScrollbarVisible(e);
-};, hterm.Terminal.prototype.setScrollWheelMoveMultipler = function(e) {
+};
+, hterm.Terminal.prototype.setScrollWheelMoveMultipler = function(e) {
   this.scrollPort_.setScrollWheelMoveMultipler(e);
-};, hterm.Terminal.prototype.closeBellNotifications_ = function() {
+};
+, hterm.Terminal.prototype.closeBellNotifications_ = function() {
   this.bellNotificationList_.forEach(function(e) {
     e.close();
-  }), this.bellNotificationList_.length = 0;
-};, lib.rtdep('lib.encodeUTF8'), hterm.Terminal.IO = function(e) {
+  }),
+      this.bellNotificationList_.length = 0;
+};
+, lib.rtdep('lib.encodeUTF8'), hterm.Terminal.IO = function(e) {
   this.terminal_ = e, this.previousIO_ = null;
-};, hterm.Terminal.IO.prototype.showOverlay = function(e, t) {
+};
+, hterm.Terminal.IO.prototype.showOverlay = function(e, t) {
   this.terminal_.showOverlay(e, t);
-};, hterm.Terminal.IO.prototype.createFrame = function(e, t) {
+};
+, hterm.Terminal.IO.prototype.createFrame = function(e, t) {
   return new hterm.Frame(this.terminal_, e, t);
-};, hterm.Terminal.IO.prototype.setTerminalProfile = function(e) {
+};
+, hterm.Terminal.IO.prototype.setTerminalProfile = function(e) {
   this.terminal_.setProfile(e);
-};, hterm.Terminal.IO.prototype.push = function() {
+};
+, hterm.Terminal.IO.prototype.push = function() {
   var e = new hterm.Terminal.IO(this.terminal_);
-  return e.keyboardCaptured_ = this.keyboardCaptured_, e.columnCount = this.columnCount, e.rowCount = this.rowCount, e.previousIO_ = this.terminal_.io, this.terminal_.io = e, e;
-};, hterm.Terminal.IO.prototype.pop = function() {
+  return e.keyboardCaptured_ = this.keyboardCaptured_,
+         e.columnCount = this.columnCount, e.rowCount = this.rowCount,
+         e.previousIO_ = this.terminal_.io, this.terminal_.io = e, e;
+};
+, hterm.Terminal.IO.prototype.pop = function() {
   this.terminal_.io = this.previousIO_;
-};, hterm.Terminal.IO.prototype.sendString = function(e) {
+};
+, hterm.Terminal.IO.prototype.sendString = function(e) {
   console.log('Unhandled sendString: ' + e);
-};, hterm.Terminal.IO.prototype.onVTKeystroke = function(e) {
+};
+, hterm.Terminal.IO.prototype.onVTKeystroke = function(e) {
   console.log('Unobserverd VT keystroke: ' + JSON.stringify(e));
-};, hterm.Terminal.IO.prototype.onTerminalResize_ = function(e, t) {
+};
+, hterm.Terminal.IO.prototype.onTerminalResize_ = function(e, t) {
   for (var r = this; r;) r.columnCount = e, r.rowCount = t, r = r.previousIO_;
   this.onTerminalResize(e, t);
-};, hterm.Terminal.IO.prototype.onTerminalResize = function(e, t) {};, hterm.Terminal.IO.prototype.writeUTF8 = function(e) {
-  if (this.terminal_.io != this) throw 'Attempt to print from inactive IO object.';
+};
+, hterm.Terminal.IO.prototype.onTerminalResize = function(e, t) {};
+, hterm.Terminal.IO.prototype.writeUTF8 = function(e) {
+  if (this.terminal_.io != this)
+    throw 'Attempt to print from inactive IO object.';
   this.terminal_.interpret(e);
-};, hterm.Terminal.IO.prototype.writelnUTF8 = function(e) {
-  if (this.terminal_.io != this) throw 'Attempt to print from inactive IO object.';
+};
+, hterm.Terminal.IO.prototype.writelnUTF8 = function(e) {
+  if (this.terminal_.io != this)
+    throw 'Attempt to print from inactive IO object.';
   this.terminal_.interpret(e + '\r\n');
-};, hterm.Terminal.IO.prototype.print = hterm.Terminal.IO.prototype.writeUTF16 = function(e) {
-  this.writeUTF8(lib.encodeUTF8(e));
-};, hterm.Terminal.IO.prototype.println = hterm.Terminal.IO.prototype.writelnUTF16 = function(e) {
-  this.writelnUTF8(lib.encodeUTF8(e));
-};, lib.rtdep('lib.colors'), hterm.TextAttributes = function(e) {
-  this.document_ = e, this.foregroundSource = this.SRC_DEFAULT, this.backgroundSource = this.SRC_DEFAULT, this.foreground = this.DEFAULT_COLOR, this.background = this.DEFAULT_COLOR, this.defaultForeground = 'rgb(255, 255, 255)', this.defaultBackground = 'rgb(0, 0, 0)', this.bold = !1, this.faint = !1, this.italic = !1, this.blink = !1, this.underline = !1, this.strikethrough = !1, this.inverse = !1, this.invisible = !1, this.wcNode = !1, this.tileData = null, this.colorPalette = null, this.resetColorPalette();
-};, hterm.TextAttributes.prototype.enableBold = !0, hterm.TextAttributes.prototype.enableBoldAsBright = !0, hterm.TextAttributes.prototype.DEFAULT_COLOR = new String(''), hterm.TextAttributes.prototype.SRC_DEFAULT = 'default', hterm.TextAttributes.prototype.SRC_RGB = 'rgb', hterm.TextAttributes.prototype.setDocument = function(e) {
-  this.document_ = e;
-};, hterm.TextAttributes.prototype.clone = function() {
+};
+,
+    hterm.Terminal.IO.prototype.print =
+        hterm.Terminal.IO.prototype.writeUTF16 = function(e) {
+          this.writeUTF8(lib.encodeUTF8(e));
+        };
+,
+    hterm.Terminal.IO.prototype.println =
+        hterm.Terminal.IO.prototype.writelnUTF16 = function(e) {
+          this.writelnUTF8(lib.encodeUTF8(e));
+        };
+, lib.rtdep('lib.colors'), hterm.TextAttributes = function(e) {
+  this.document_ = e, this.foregroundSource = this.SRC_DEFAULT,
+  this.backgroundSource = this.SRC_DEFAULT,
+  this.foreground = this.DEFAULT_COLOR, this.background = this.DEFAULT_COLOR,
+  this.defaultForeground = 'rgb(255, 255, 255)',
+  this.defaultBackground = 'rgb(0, 0, 0)', this.bold = !1, this.faint = !1,
+  this.italic = !1, this.blink = !1, this.underline = !1,
+  this.strikethrough = !1, this.inverse = !1, this.invisible = !1,
+  this.wcNode = !1, this.tileData = null, this.colorPalette = null,
+  this.resetColorPalette();
+};
+, hterm.TextAttributes.prototype.enableBold = !0,
+  hterm.TextAttributes.prototype.enableBoldAsBright = !0,
+  hterm.TextAttributes.prototype.DEFAULT_COLOR = new String(''),
+  hterm.TextAttributes.prototype.SRC_DEFAULT = 'default',
+  hterm.TextAttributes.prototype.SRC_RGB = 'rgb',
+  hterm.TextAttributes.prototype.setDocument = function(e) {
+    this.document_ = e;
+  };
+, hterm.TextAttributes.prototype.clone = function() {
   var e = new hterm.TextAttributes(null);
   for (var t in this) e[t] = this[t];
   return e.colorPalette = this.colorPalette.concat(), e;
-};, hterm.TextAttributes.prototype.reset = function() {
-  this.foregroundSource = this.SRC_DEFAULT, this.backgroundSource = this.SRC_DEFAULT, this.foreground = this.DEFAULT_COLOR, this.background = this.DEFAULT_COLOR, this.bold = !1, this.faint = !1, this.italic = !1, this.blink = !1, this.underline = !1, this.strikethrough = !1, this.inverse = !1, this.invisible = !1, this.wcNode = !1;
-};, hterm.TextAttributes.prototype.resetColorPalette = function() {
+};
+, hterm.TextAttributes.prototype.reset = function() {
+  this.foregroundSource = this.SRC_DEFAULT,
+  this.backgroundSource = this.SRC_DEFAULT,
+  this.foreground = this.DEFAULT_COLOR, this.background = this.DEFAULT_COLOR,
+  this.bold = !1, this.faint = !1, this.italic = !1, this.blink = !1,
+  this.underline = !1, this.strikethrough = !1, this.inverse = !1,
+  this.invisible = !1, this.wcNode = !1;
+};
+, hterm.TextAttributes.prototype.resetColorPalette = function() {
   this.colorPalette = lib.colors.colorPalette.concat(), this.syncColors();
-};, 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 || null != this.tileData);
-};, hterm.TextAttributes.prototype.createContainer = function(e) {
+};
+, 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 || null != this.tileData);
+};
+, hterm.TextAttributes.prototype.createContainer = function(e) {
   if (this.isDefault()) return this.document_.createTextNode(e);
-  var t = this.document_.createElement('span'),
-    r = t.style,
-    o = [];
-  this.foreground != this.DEFAULT_COLOR && (r.color = this.foreground), this.background != this.DEFAULT_COLOR && (r.backgroundColor = this.background), this.enableBold && this.bold && (r.fontWeight = 'bold'), this.faint && (t.faint = !0), this.italic && (r.fontStyle = 'italic'), this.blink && (o.push('blink-node'), t.blinkNode = !0);
+  var t = this.document_.createElement('span'), r = t.style, o = [];
+  this.foreground != this.DEFAULT_COLOR && (r.color = this.foreground),
+      this.background != this.DEFAULT_COLOR &&
+      (r.backgroundColor = this.background),
+      this.enableBold && this.bold && (r.fontWeight = 'bold'),
+      this.faint && (t.faint = !0), this.italic && (r.fontStyle = 'italic'),
+      this.blink && (o.push('blink-node'), t.blinkNode = !0);
   var i = '';
-  return this.underline && (i += ' underline', t.underline = !0), this.strikethrough && (i += ' line-through', t.strikethrough = !0), i && (r.textDecoration = i), this.wcNode && (o.push('wc-node'), t.wcNode = !0), null != this.tileData && (o.push('tile'), o.push('tile_' + this.tileData), t.tileNode = !0), e && (t.textContent = e), o.length && (t.className = o.join(' ')), t;
-};, hterm.TextAttributes.prototype.matchesContainer = function(e) {
+  return this.underline && (i += ' underline', t.underline = !0),
+         this.strikethrough && (i += ' line-through', t.strikethrough = !0),
+         i && (r.textDecoration = i),
+         this.wcNode && (o.push('wc-node'), t.wcNode = !0),
+         null != this.tileData &&
+             (o.push('tile'), o.push('tile_' + this.tileData), t.tileNode = !0),
+         e && (t.textContent = e), o.length && (t.className = o.join(' ')), t;
+};
+, hterm.TextAttributes.prototype.matchesContainer = function(e) {
   if ('string' == typeof e || 3 == e.nodeType) return this.isDefault();
   var t = e.style;
-  return !(this.wcNode || e.wcNode || null != this.tileData || e.tileNode || this.foreground != t.color || this.background != t.backgroundColor || (this.enableBold && this.bold) != !!t.fontWeight || this.blink != e.blinkNode || this.italic != !!t.fontStyle || !!this.underline != !!e.underline || !!this.strikethrough != !!e.strikethrough);
-};, hterm.TextAttributes.prototype.setDefaults = function(e, t) {
+  return !(
+      this.wcNode || e.wcNode || null != this.tileData || e.tileNode ||
+      this.foreground != t.color || this.background != t.backgroundColor ||
+      (this.enableBold && this.bold) != !!t.fontWeight ||
+      this.blink != e.blinkNode || this.italic != !!t.fontStyle ||
+      !!this.underline != !!e.underline ||
+      !!this.strikethrough != !!e.strikethrough);
+};
+, hterm.TextAttributes.prototype.setDefaults = function(e, t) {
   this.defaultForeground = e, this.defaultBackground = t, this.syncColors();
-};, hterm.TextAttributes.prototype.syncColors = function() {
+};
+, hterm.TextAttributes.prototype.syncColors = function() {
   function e(e) {
     return 8 > e ? e + 8 : e;
   }
-  var t = this.foregroundSource,
-    r = this.backgroundSource,
-    o = this.DEFAULT_COLOR,
-    i = this.DEFAULT_COLOR;
-  if (this.inverse && (t = this.backgroundSource, r = this.foregroundSource, o = this.defaultBackground, i = this.defaultForeground), this.enableBoldAsBright && this.bold && t != this.SRC_DEFAULT && t != this.SRC_RGB && (t = e(t)), this.invisible && (t = r, o = this.defaultBackground), t != this.SRC_RGB && (this.foreground = t == this.SRC_DEFAULT ? o : this.colorPalette[t]), this.faint && !this.invisible) {
-    var s = this.foreground == this.DEFAULT_COLOR ? this.defaultForeground : this.foreground;
+  var t = this.foregroundSource, r = this.backgroundSource,
+      o = this.DEFAULT_COLOR, i = this.DEFAULT_COLOR;
+  if (this.inverse &&
+          (t = this.backgroundSource, r = this.foregroundSource,
+           o = this.defaultBackground, i = this.defaultForeground),
+      this.enableBoldAsBright && this.bold && t != this.SRC_DEFAULT &&
+          t != this.SRC_RGB && (t = e(t)),
+      this.invisible && (t = r, o = this.defaultBackground),
+      t != this.SRC_RGB &&
+          (this.foreground = t == this.SRC_DEFAULT ? o : this.colorPalette[t]),
+      this.faint && !this.invisible) {
+    var s = this.foreground == this.DEFAULT_COLOR ? this.defaultForeground :
+                                                    this.foreground;
     this.foreground = lib.colors.mix(s, 'rgb(0, 0, 0)', .3333);
   }
-  r != this.SRC_RGB && (this.background = r == this.SRC_DEFAULT ? i : this.colorPalette[r]);
-};, hterm.TextAttributes.containersMatch = function(e, t) {
+  r != this.SRC_RGB &&
+      (this.background = r == this.SRC_DEFAULT ? i : this.colorPalette[r]);
+};
+, hterm.TextAttributes.containersMatch = function(e, t) {
   if ('string' == typeof e) return hterm.TextAttributes.containerIsDefault(t);
   if (e.nodeType != t.nodeType) return !1;
   if (3 == e.nodeType) return !0;
-  var r = e.style,
-    o = t.style;
-  return r.color == o.color && r.backgroundColor == o.backgroundColor && r.fontWeight == o.fontWeight && r.fontStyle == o.fontStyle && r.textDecoration == o.textDecoration;
-};, hterm.TextAttributes.containerIsDefault = function(e) {
+  var r = e.style, o = t.style;
+  return r.color == o.color && r.backgroundColor == o.backgroundColor &&
+      r.fontWeight == o.fontWeight && r.fontStyle == o.fontStyle &&
+      r.textDecoration == o.textDecoration;
+};
+, hterm.TextAttributes.containerIsDefault = function(e) {
   return 'string' == typeof e || 3 == e.nodeType;
-};, hterm.TextAttributes.nodeWidth = function(e) {
+};
+, hterm.TextAttributes.nodeWidth = function(e) {
   return e.wcNode ? lib.wc.strWidth(e.textContent) : e.textContent.length;
-};, hterm.TextAttributes.nodeSubstr = function(e, t, r) {
-  return e.wcNode ? lib.wc.substr(e.textContent, t, r) : e.textContent.substr(t, r);
-};, hterm.TextAttributes.nodeSubstring = function(e, t, r) {
-  return e.wcNode ? lib.wc.substring(e.textContent, t, r) : e.textContent.substring(t, r);
-};, hterm.TextAttributes.splitWidecharString = function(e) {
+};
+, hterm.TextAttributes.nodeSubstr = function(e, t, r) {
+  return e.wcNode ? lib.wc.substr(e.textContent, t, r) :
+                    e.textContent.substr(t, r);
+};
+, hterm.TextAttributes.nodeSubstring = function(e, t, r) {
+  return e.wcNode ? lib.wc.substring(e.textContent, t, r) :
+                    e.textContent.substring(t, r);
+};
+, hterm.TextAttributes.splitWidecharString = function(e) {
   for (var t = [], r = 0, o = 0, i = 0; i < e.length;) {
-    var s = e.codePointAt(i),
-      n = 65535 >= s ? 1 : 2;
-    128 > s || 1 == lib.wc.charWidth(s) ? o += n : (o && t.push({
-      str: e.substr(r, o)
-    }), t.push({
-      str: e.substr(i, n),
-      wcNode: !0
-    }), r = i + n, o = 0), i += n;
+    var s = e.codePointAt(i), n = 65535 >= s ? 1 : 2;
+    128 > s || 1 == lib.wc.charWidth(s) ?
+        o += n :
+        (o && t.push({str: e.substr(r, o)}),
+         t.push({str: e.substr(i, n), wcNode: !0}), r = i + n, o = 0),
+        i += n;
   }
-  return o && t.push({
-    str: e.substr(r, o)
-  }), t;
-};, lib.rtdep('lib.colors', 'lib.f', 'lib.UTF8Decoder', 'hterm.VT.CharacterMap'), hterm.VT = function(e) {
-  this.terminal = e, e.onMouse = this.onTerminalMouse_.bind(this), this.mouseReport = this.MOUSE_REPORT_DISABLED, this.parseState_ = new hterm.VT.ParseState(this.parseUnknown_), this.leadingModifier_ = '', this.trailingModifier_ = '', this.allowColumnWidthChanges_ = !1, this.oscTimeLimit_ = 2e4;
-  var t = Object.keys(hterm.VT.CC1).map(function(e) {
-    return '\\x' + lib.f.zpad(e.charCodeAt().toString(16), 2);
-  }).join('');
-  this.cc1Pattern_ = new RegExp('[' + t + ']'), this.utf8Decoder_ = new lib.UTF8Decoder, this.enable8BitControl = !1, this.enableClipboardWrite = !0, this.enableDec12 = !1, this.characterEncoding = 'utf-8', this.maxStringSequence = 1024, this.warnUnimplemented = !0, this.G0 = hterm.VT.CharacterMap.maps.B, this.G1 = hterm.VT.CharacterMap.maps[0], this.G2 = hterm.VT.CharacterMap.maps.B, this.G3 = hterm.VT.CharacterMap.maps.B, this.GL = 'G0', this.GR = 'G0', this.savedState_ = new hterm.VT.CursorState(this);
-};, hterm.VT.prototype.MOUSE_REPORT_DISABLED = 0, hterm.VT.prototype.MOUSE_REPORT_CLICK = 1, hterm.VT.prototype.MOUSE_REPORT_DRAG = 3, hterm.VT.ParseState = function(e, t) {
-  this.defaultFunction = e, this.buf = t || null, this.pos = 0, this.func = e, this.args = [];
-};, hterm.VT.ParseState.prototype.reset = function(e) {
+  return o && t.push({str: e.substr(r, o)}), t;
+};
+, lib.rtdep('lib.colors', 'lib.f', 'lib.UTF8Decoder', 'hterm.VT.CharacterMap'),
+    hterm.VT = function(e) {
+      this.terminal = e, e.onMouse = this.onTerminalMouse_.bind(this),
+      this.mouseReport = this.MOUSE_REPORT_DISABLED,
+      this.parseState_ = new hterm.VT.ParseState(this.parseUnknown_),
+      this.leadingModifier_ = '', this.trailingModifier_ = '',
+      this.allowColumnWidthChanges_ = !1, this.oscTimeLimit_ = 2e4;
+      var t = Object.keys(hterm.VT.CC1)
+                  .map(function(e) {
+                    return '\\x' + lib.f.zpad(e.charCodeAt().toString(16), 2);
+                  })
+                  .join('');
+      this.cc1Pattern_ = new RegExp('[' + t + ']'),
+      this.utf8Decoder_ = new lib.UTF8Decoder, this.enable8BitControl = !1,
+      this.enableClipboardWrite = !0, this.enableDec12 = !1,
+      this.characterEncoding = 'utf-8', this.maxStringSequence = 1024,
+      this.warnUnimplemented = !0, this.G0 = hterm.VT.CharacterMap.maps.B,
+      this.G1 = hterm.VT.CharacterMap.maps[0],
+      this.G2 = hterm.VT.CharacterMap.maps.B,
+      this.G3 = hterm.VT.CharacterMap.maps.B, this.GL = 'G0', this.GR = 'G0',
+      this.savedState_ = new hterm.VT.CursorState(this);
+    };
+, hterm.VT.prototype.MOUSE_REPORT_DISABLED = 0,
+  hterm.VT.prototype.MOUSE_REPORT_CLICK = 1,
+  hterm.VT.prototype.MOUSE_REPORT_DRAG = 3,
+  hterm.VT.ParseState = function(e, t) {
+    this.defaultFunction = e, this.buf = t || null, this.pos = 0, this.func = e,
+    this.args = [];
+  };
+, hterm.VT.ParseState.prototype.reset = function(e) {
   this.resetParseFunction(), this.resetBuf(e || ''), this.resetArguments();
-};, hterm.VT.ParseState.prototype.resetParseFunction = function() {
+};
+, hterm.VT.ParseState.prototype.resetParseFunction = function() {
   this.func = this.defaultFunction;
-};, hterm.VT.ParseState.prototype.resetBuf = function(e) {
+};
+, hterm.VT.ParseState.prototype.resetBuf = function(e) {
   this.buf = 'string' == typeof e ? e : null, this.pos = 0;
-};, hterm.VT.ParseState.prototype.resetArguments = function(e) {
+};
+, hterm.VT.ParseState.prototype.resetArguments = function(e) {
   this.args.length = 0, 'undefined' != typeof e && (this.args[0] = e);
-};, hterm.VT.ParseState.prototype.iarg = function(e, t) {
+};
+, hterm.VT.ParseState.prototype.iarg = function(e, t) {
   var r = this.args[e];
   if (r) {
     var o = parseInt(r, 10);
     return 0 == o && (o = t), o;
   }
   return t;
-};, hterm.VT.ParseState.prototype.advance = function(e) {
+};
+, hterm.VT.ParseState.prototype.advance = function(e) {
   this.pos += e;
-};, hterm.VT.ParseState.prototype.peekRemainingBuf = function() {
+};
+, hterm.VT.ParseState.prototype.peekRemainingBuf = function() {
   return this.buf.substr(this.pos);
-};, hterm.VT.ParseState.prototype.peekChar = function() {
+};
+, hterm.VT.ParseState.prototype.peekChar = function() {
   return this.buf.substr(this.pos, 1);
-};, hterm.VT.ParseState.prototype.consumeChar = function() {
+};
+, hterm.VT.ParseState.prototype.consumeChar = function() {
   return this.buf.substr(this.pos++, 1);
-};, hterm.VT.ParseState.prototype.isComplete = function() {
+};
+, hterm.VT.ParseState.prototype.isComplete = function() {
   return null == this.buf || this.buf.length <= this.pos;
-};, hterm.VT.CursorState = function(e) {
+};
+, hterm.VT.CursorState = function(e) {
   this.vt_ = e, this.save();
-};, hterm.VT.CursorState.prototype.save = function() {
-  this.cursor = this.vt_.terminal.saveCursor(), this.textAttributes = this.vt_.terminal.getTextAttributes().clone(), this.GL = this.vt_.GL, this.GR = this.vt_.GR, this.G0 = this.vt_.G0, this.G1 = this.vt_.G1, this.G2 = this.vt_.G2, this.G3 = this.vt_.G3;
-};, hterm.VT.CursorState.prototype.restore = function() {
-  this.vt_.terminal.restoreCursor(this.cursor), this.vt_.terminal.setTextAttributes(this.textAttributes.clone()), this.vt_.GL = this.GL, this.vt_.GR = this.GR, this.vt_.G0 = this.G0, this.vt_.G1 = this.G1, this.vt_.G2 = this.G2, this.vt_.G3 = this.G3;
-};, hterm.VT.prototype.reset = function() {
-  this.G0 = hterm.VT.CharacterMap.maps.B, this.G1 = hterm.VT.CharacterMap.maps[0], this.G2 = hterm.VT.CharacterMap.maps.B, this.G3 = hterm.VT.CharacterMap.maps.B, this.GL = 'G0', this.GR = 'G0', this.savedState_ = new hterm.VT.CursorState(this), this.mouseReport = this.MOUSE_REPORT_DISABLED;
-};, hterm.VT.prototype.onTerminalMouse_ = function(e) {
+};
+, hterm.VT.CursorState.prototype.save = function() {
+  this.cursor = this.vt_.terminal.saveCursor(),
+  this.textAttributes = this.vt_.terminal.getTextAttributes().clone(),
+  this.GL = this.vt_.GL, this.GR = this.vt_.GR, this.G0 = this.vt_.G0,
+  this.G1 = this.vt_.G1, this.G2 = this.vt_.G2, this.G3 = this.vt_.G3;
+};
+, hterm.VT.CursorState.prototype.restore = function() {
+  this.vt_.terminal.restoreCursor(this.cursor),
+      this.vt_.terminal.setTextAttributes(this.textAttributes.clone()),
+      this.vt_.GL = this.GL, this.vt_.GR = this.GR, this.vt_.G0 = this.G0,
+      this.vt_.G1 = this.G1, this.vt_.G2 = this.G2, this.vt_.G3 = this.G3;
+};
+, hterm.VT.prototype.reset = function() {
+  this.G0 = hterm.VT.CharacterMap.maps.B,
+  this.G1 = hterm.VT.CharacterMap.maps[0],
+  this.G2 = hterm.VT.CharacterMap.maps.B,
+  this.G3 = hterm.VT.CharacterMap.maps.B, this.GL = 'G0', this.GR = 'G0',
+  this.savedState_ = new hterm.VT.CursorState(this),
+  this.mouseReport = this.MOUSE_REPORT_DISABLED;
+};
+, hterm.VT.prototype.onTerminalMouse_ = function(e) {
   if (this.mouseReport != this.MOUSE_REPORT_DISABLED) {
     var t, r = 0;
-    e.shiftKey && (r |= 4), (e.metaKey || this.terminal.keyboard.altIsMeta && e.altKey) && (r |= 8), e.ctrlKey && (r |= 16);
+    e.shiftKey && (r |= 4),
+        (e.metaKey || this.terminal.keyboard.altIsMeta && e.altKey) && (r |= 8),
+        e.ctrlKey && (r |= 16);
     var o = String.fromCharCode(lib.f.clamp(e.terminalColumn + 32, 32, 255)),
-      i = String.fromCharCode(lib.f.clamp(e.terminalRow + 32, 32, 255));
+        i = String.fromCharCode(lib.f.clamp(e.terminalRow + 32, 32, 255));
     switch (e.type) {
       case 'mousewheel':
-        s = (e.wheelDeltaY > 0 ? 0 : 1) + 96, s |= r, t = '' + String.fromCharCode(s) + o + i, e.preventDefault();
+        s = (e.wheelDeltaY > 0 ? 0 : 1) + 96, s |= r,
+        t = '' + String.fromCharCode(s) + o + i, e.preventDefault();
         break;
       case 'mousedown':
         var s = Math.min(e.which - 1, 2) + 32;
@@ -4052,7 +5777,9 @@
         t = '#' + o + i;
         break;
       case 'mousemove':
-        this.mouseReport == this.MOUSE_REPORT_DRAG && e.which && (s = 32 + Math.min(e.which - 1, 2), s += 32, s |= r, t = '' + String.fromCharCode(s) + o + i);
+        this.mouseReport == this.MOUSE_REPORT_DRAG && e.which &&
+            (s = 32 + Math.min(e.which - 1, 2), s += 32, s |= r,
+             t = '' + String.fromCharCode(s) + o + i);
         break;
       case 'click':
       case 'dblclick':
@@ -4062,53 +5789,108 @@
     }
     t && this.terminal.io.sendString(t);
   }
-};, hterm.VT.prototype.interpret = function(e) {
-  for (this.parseState_.resetBuf(this.decode(e)); !this.parseState_.isComplete();) {
-    var t = this.parseState_.func,
-      r = this.parseState_.pos,
-      e = this.parseState_.buf;
-    if (this.parseState_.func.call(this, this.parseState_), this.parseState_.func == t && this.parseState_.pos == r && this.parseState_.buf == e) throw 'Parser did not alter the state!';
+};
+, hterm.VT.prototype.interpret = function(e) {
+  for (this.parseState_.resetBuf(this.decode(e));
+       !this.parseState_.isComplete();) {
+    var t = this.parseState_.func, r = this.parseState_.pos,
+        e = this.parseState_.buf;
+    if (this.parseState_.func.call(this, this.parseState_),
+        this.parseState_.func == t && this.parseState_.pos == r &&
+            this.parseState_.buf == e)
+      throw 'Parser did not alter the state!';
   }
-};, hterm.VT.prototype.decode = function(e) {
+};
+, hterm.VT.prototype.decode = function(e) {
   return 'utf-8' == this.characterEncoding ? this.decodeUTF8(e) : e;
-};, hterm.VT.prototype.encodeUTF8 = function(e) {
+};
+, hterm.VT.prototype.encodeUTF8 = function(e) {
   return lib.encodeUTF8(e);
-};, hterm.VT.prototype.decodeUTF8 = function(e) {
+};
+, hterm.VT.prototype.decodeUTF8 = function(e) {
   return this.utf8Decoder_.decode(e);
-};, hterm.VT.prototype.parseUnknown_ = function(e) {
+};
+, hterm.VT.prototype.parseUnknown_ = function(e) {
   function t(e) {
-    r[r.GL].GL && (e = r[r.GL].GL(e)), r[r.GR].GR && (e = r[r.GR].GR(e)), r.terminal.print(e);
+    r[r.GL].GL && (e = r[r.GL].GL(e)), r[r.GR].GR && (e = r[r.GR].GR(e)),
+        r.terminal.print(e);
   }
-  var r = this,
-    o = e.peekRemainingBuf(),
-    i = o.search(this.cc1Pattern_);
-  return 0 == i ? (this.dispatch('CC1', o.substr(0, 1), e), void e.advance(1)) : -1 == i ? (t(o), void e.reset()) : (t(o.substr(0, i)), this.dispatch('CC1', o.substr(i, 1), e), void e.advance(i + 1))
-};, hterm.VT.prototype.parseCSI_ = function(e) {
-  var t = e.peekChar(),
-    r = e.args;
-  t >= '@' && '~' >= t ? (this.dispatch('CSI', this.leadingModifier_ + this.trailingModifier_ + t, e), e.resetParseFunction()) : ';' == t ? this.trailingModifier_ ? e.resetParseFunction() : (r.length || r.push(''), r.push('')) : t >= '0' && '9' >= t ? this.trailingModifier_ ? e.resetParseFunction() : r.length ? r[r.length - 1] += t : r[0] = t : t >= ' ' && '?' >= t && ':' != t ? r.length ? this.trailingModifier_ += t : this.leadingModifier_ += t : this.cc1Pattern_.test(t) ? this.dispatch('CC1', t, e) : e.resetParseFunction(), e.advance(1);
-};, hterm.VT.prototype.parseUntilStringTerminator_ = function(e) {
-  var t = e.peekRemainingBuf(),
-    r = t.search(/(\x1b\\|\x07)/),
-    o = e.args;
+  var r = this, o = e.peekRemainingBuf(), i = o.search(this.cc1Pattern_);
+  return 0 == i ?
+      (this.dispatch('CC1', o.substr(0, 1), e), void e.advance(1)) :
+      -1 == i ? (t(o), void e.reset()) :
+                (t(o.substr(0, i)), this.dispatch('CC1', o.substr(i, 1), e),
+                 void e.advance(i + 1))
+};
+, hterm.VT.prototype.parseCSI_ = function(e) {
+  var t = e.peekChar(), r = e.args;
+  t >= '@' && '~' >= t ?
+      (this.dispatch(
+           'CSI', this.leadingModifier_ + this.trailingModifier_ + t, e),
+       e.resetParseFunction()) :
+      ';' == t ?
+      this.trailingModifier_ ? e.resetParseFunction() :
+                               (r.length || r.push(''), r.push('')) :
+      t >= '0' && '9' >= t ?
+      this.trailingModifier_ ? e.resetParseFunction() :
+                               r.length ? r[r.length - 1] += t : r[0] = t :
+      t >= ' ' && '?' >= t && ':' != t ?
+      r.length ? this.trailingModifier_ += t : this.leadingModifier_ += t :
+      this.cc1Pattern_.test(t) ? this.dispatch('CC1', t, e) :
+                                 e.resetParseFunction(),
+                                                                 e.advance(1);
+};
+, hterm.VT.prototype.parseUntilStringTerminator_ = function(e) {
+  var t = e.peekRemainingBuf(), r = t.search(/(\x1b\\|\x07)/), o = e.args;
   if (o.length || (o[0] = '', o[1] = new Date), -1 == r) {
     o[0] += t;
     var i;
-    return o[0].length > this.maxStringSequence && (i = 'too long: ' + o[0].length), -1 != o[0].indexOf('') && (i = 'embedded escape: ' + o[0].indexOf('')), new Date - o[1] > this.oscTimeLimit_ && (i = 'timeout expired: ' + new Date - o[1]), i ? (console.log('parseUntilStringTerminator_: aborting: ' + i, o[0]), e.reset(o[0]), !1) : (e.advance(t.length), !0);
+    return o[0].length > this.maxStringSequence &&
+               (i = 'too long: ' + o[0].length),
+           -1 != o[0].indexOf('') &&
+               (i = 'embedded escape: ' + o[0].indexOf('')),
+           new Date - o[1] > this.oscTimeLimit_ &&
+               (i = 'timeout expired: ' + new Date - o[1]),
+           i ? (console.log(
+                    'parseUntilStringTerminator_: aborting: ' + i, o[0]),
+                e.reset(o[0]), !1) :
+               (e.advance(t.length), !0);
   }
-  return o[0].length + r > this.maxStringSequence ? (e.reset(o[0] + t), !1) : (o[0] += t.substr(0, r), e.resetParseFunction(), e.advance(r + ('' == t.substr(r, 1) ? 2 : 1)), !0);
-};, hterm.VT.prototype.dispatch = function(e, t, r) {
+  return o[0].length + r > this.maxStringSequence ?
+      (e.reset(o[0] + t), !1) :
+      (o[0] += t.substr(0, r), e.resetParseFunction(),
+       e.advance(r + ('' == t.substr(r, 1) ? 2 : 1)), !0);
+};
+, hterm.VT.prototype.dispatch = function(e, t, r) {
   var o = hterm.VT[e][t];
-  return o ? o == hterm.VT.ignore ? void(this.warnUnimplemented && console.warn('Ignored ' + e + ' code: ' + JSON.stringify(t))) : 'CC1' == e && t > '' && !this.enable8BitControl ? void console.warn('Ignoring 8-bit control code: 0x' + t.charCodeAt(0).toString(16)) : void o.apply(this, [r, t]) : void(this.warnUnimplemented && console.warn('Unknown ' + e + ' code: ' + JSON.stringify(t)))
-};, hterm.VT.prototype.setANSIMode = function(e, t) {
-  '4' == e ? this.terminal.setInsertMode(t) : '20' == e ? this.terminal.setAutoCarriageReturn(t) : this.warnUnimplemented && console.warn('Unimplemented ANSI Mode: ' + e)
-};, hterm.VT.prototype.setDECMode = function(e, t) {
+  return o ?
+      o == hterm.VT.ignore ?
+      void(
+          this.warnUnimplemented &&
+          console.warn('Ignored ' + e + ' code: ' + JSON.stringify(t))) :
+      'CC1' == e && t > '' && !this.enable8BitControl ?
+      void console.warn(
+          'Ignoring 8-bit control code: 0x' + t.charCodeAt(0).toString(16)) :
+      void o.apply(this, [r, t]) :
+      void(
+          this.warnUnimplemented &&
+          console.warn('Unknown ' + e + ' code: ' + JSON.stringify(t)))
+};
+, hterm.VT.prototype.setANSIMode = function(e, t) {
+  '4' == e ? this.terminal.setInsertMode(t) :
+             '20' == e ? this.terminal.setAutoCarriageReturn(t) :
+                         this.warnUnimplemented &&
+              console.warn('Unimplemented ANSI Mode: ' + e)
+};
+, hterm.VT.prototype.setDECMode = function(e, t) {
   switch (e) {
     case '1':
       this.terminal.keyboard.applicationCursor = t;
       break;
     case '3':
-      this.allowColumnWidthChanges_ && (this.terminal.setWidth(t ? 132 : 80), this.terminal.clearHome(), this.terminal.setVTScrollRegion(null, null));
+      this.allowColumnWidthChanges_ &&
+          (this.terminal.setWidth(t ? 132 : 80), this.terminal.clearHome(),
+           this.terminal.setVTScrollRegion(null, null));
       break;
     case '5':
       this.terminal.setReverseVideo(t);
@@ -4135,10 +5917,12 @@
       this.terminal.keyboard.backspaceSendsBackspace = t;
       break;
     case '1000':
-      this.mouseReport = t ? this.MOUSE_REPORT_CLICK : this.MOUSE_REPORT_DISABLED;
+      this.mouseReport =
+          t ? this.MOUSE_REPORT_CLICK : this.MOUSE_REPORT_DISABLED;
       break;
     case '1002':
-      this.mouseReport = t ? this.MOUSE_REPORT_DRAG : this.MOUSE_REPORT_DISABLED;
+      this.mouseReport =
+          t ? this.MOUSE_REPORT_DRAG : this.MOUSE_REPORT_DISABLED;
       break;
     case '1010':
       this.terminal.scrollOnOutput = t;
@@ -4150,7 +5934,14 @@
       this.terminal.keyboard.metaSendsEscape = t;
       break;
     case '1039':
-      t ? this.terminal.keyboard.previousAltSendsWhat_ || (this.terminal.keyboard.previousAltSendsWhat_ = this.terminal.keyboard.altSendsWhat, this.terminal.keyboard.altSendsWhat = 'escape') : this.terminal.keyboard.previousAltSendsWhat_ && (this.terminal.keyboard.altSendsWhat = this.terminal.keyboard.previousAltSendsWhat_, this.terminal.keyboard.previousAltSendsWhat_ = null);
+      t ? this.terminal.keyboard.previousAltSendsWhat_ ||
+              (this.terminal.keyboard.previousAltSendsWhat_ =
+                   this.terminal.keyboard.altSendsWhat,
+               this.terminal.keyboard.altSendsWhat = 'escape') :
+          this.terminal.keyboard.previousAltSendsWhat_ &&
+              (this.terminal.keyboard.altSendsWhat =
+                   this.terminal.keyboard.previousAltSendsWhat_,
+               this.terminal.keyboard.previousAltSendsWhat_ = null);
       break;
     case '47':
     case '1047':
@@ -4159,115 +5950,194 @@
     case '1048':
       this.savedState_.save();
     case '1049':
-      t ? (this.savedState_.save(), this.terminal.setAlternateMode(t), this.terminal.clear()) : (this.terminal.setAlternateMode(t), this.savedState_.restore());
+      t ? (this.savedState_.save(), this.terminal.setAlternateMode(t),
+           this.terminal.clear()) :
+          (this.terminal.setAlternateMode(t), this.savedState_.restore());
       break;
     case '2004':
       this.terminal.setBracketedPaste(t);
       break;
     default:
-      this.warnUnimplemented && console.warn('Unimplemented DEC Private Mode: ' + e);
+      this.warnUnimplemented &&
+          console.warn('Unimplemented DEC Private Mode: ' + e);
   }
-};, hterm.VT.ignore = function() {};, hterm.VT.CC1 = {}, hterm.VT.ESC = {}, hterm.VT.CSI = {}, hterm.VT.OSC = {}, hterm.VT.VT52 = {}, hterm.VT.CC1['\x00'] = function() {};, hterm.VT.CC1[''] = hterm.VT.ignore, hterm.VT.CC1[''] = function() {
+};
+, hterm.VT.ignore = function() {};
+, hterm.VT.CC1 = {}, hterm.VT.ESC = {}, hterm.VT.CSI = {}, hterm.VT.OSC = {},
+  hterm.VT.VT52 = {}, hterm.VT.CC1['\x00'] = function() {};
+, hterm.VT.CC1[''] = hterm.VT.ignore, hterm.VT.CC1[''] = function() {
   this.terminal.ringBell();
-};, hterm.VT.CC1['\b'] = function() {
+};
+, hterm.VT.CC1['\b'] = function() {
   this.terminal.cursorLeft(1);
-};, hterm.VT.CC1['	'] = function() {
+};
+, hterm.VT.CC1['	'] = function() {
   this.terminal.forwardTabStop();
-};, hterm.VT.CC1['\n'] = function() {
+};
+, hterm.VT.CC1['\n'] = function() {
   this.terminal.formFeed();
-};, hterm.VT.CC1[''] = hterm.VT.CC1['\n'], hterm.VT.CC1['\f'] = function() {
+};
+, hterm.VT.CC1[''] = hterm.VT.CC1['\n'], hterm.VT.CC1['\f'] = function() {
   this.terminal.formFeed();
-};, hterm.VT.CC1['\r'] = function() {
+};
+, hterm.VT.CC1['\r'] = function() {
   this.terminal.setCursorColumn(0);
-};, hterm.VT.CC1[''] = function() {
+};
+, hterm.VT.CC1[''] = function() {
   this.GL = 'G1';
-};, hterm.VT.CC1[''] = function() {
+};
+, hterm.VT.CC1[''] = function() {
   this.GL = 'G0';
-};, hterm.VT.CC1[''] = hterm.VT.ignore, hterm.VT.CC1[''] = hterm.VT.ignore, hterm.VT.CC1[''] = function(e) {
-  'G1' == this.GL && (this.GL = 'G0'), e.resetParseFunction(), this.terminal.print('?');
-};, hterm.VT.CC1[''] = hterm.VT.CC1[''], hterm.VT.CC1[''] = function(e) {
+};
+, hterm.VT.CC1[''] = hterm.VT.ignore, hterm.VT.CC1[''] = hterm.VT.ignore,
+  hterm.VT.CC1[''] = function(e) {
+    'G1' == this.GL && (this.GL = 'G0'), e.resetParseFunction(),
+        this.terminal.print('?');
+  };
+, hterm.VT.CC1[''] = hterm.VT.CC1[''], hterm.VT.CC1[''] = function(e) {
   function t(e) {
     var r = e.consumeChar();
-    '' != r && (this.dispatch('ESC', r, e), e.func == t && e.resetParseFunction());
+    '' != r &&
+        (this.dispatch('ESC', r, e), e.func == t && e.resetParseFunction());
   }
   e.func = t;
-};, hterm.VT.CC1[''] = hterm.VT.ignore, hterm.VT.CC1['„'] = hterm.VT.ESC.D = function() {
-  this.terminal.lineFeed();
-};, hterm.VT.CC1['…'] = hterm.VT.ESC.E = function() {
+};
+, hterm.VT.CC1[''] = hterm.VT.ignore,
+  hterm.VT.CC1['„'] = hterm.VT.ESC.D = function() {
+    this.terminal.lineFeed();
+  };
+, hterm.VT.CC1['…'] = hterm.VT.ESC.E = function() {
   this.terminal.setCursorColumn(0), this.terminal.cursorDown(1);
-};, hterm.VT.CC1['ˆ'] = hterm.VT.ESC.H = function() {
+};
+, hterm.VT.CC1['ˆ'] = hterm.VT.ESC.H = function() {
   this.terminal.setTabStop(this.terminal.getCursorColumn());
-};, hterm.VT.CC1[''] = hterm.VT.ESC.M = function() {
+};
+, hterm.VT.CC1[''] = hterm.VT.ESC.M = function() {
   this.terminal.reverseLineFeed();
-};, hterm.VT.CC1['Ž'] = hterm.VT.ESC.N = hterm.VT.ignore, hterm.VT.CC1[''] = hterm.VT.ESC.O = hterm.VT.ignore, hterm.VT.CC1[''] = hterm.VT.ESC.P = function(e) {
-  e.resetArguments(), e.func = this.parseUntilStringTerminator_;
-};, hterm.VT.CC1['–'] = hterm.VT.ESC.V = hterm.VT.ignore, hterm.VT.CC1['—'] = hterm.VT.ESC.W = hterm.VT.ignore, hterm.VT.CC1['˜'] = hterm.VT.ESC.X = hterm.VT.ignore, hterm.VT.CC1['š'] = hterm.VT.ESC.Z = function() {
-  this.terminal.io.sendString('[?1;2c');
-};, hterm.VT.CC1['›'] = hterm.VT.ESC['['] = function(e) {
-  e.resetArguments(), this.leadingModifier_ = '',
-    this.trailingModifier_ = '', e.func = this.parseCSI_;
-};, hterm.VT.CC1['œ'] = hterm.VT.ESC['\\'] = hterm.VT.ignore, hterm.VT.CC1[''] = hterm.VT.ESC[']'] = function(e) {
-  function t(e) {
-    if (this.parseUntilStringTerminator_(e) && e.func != t) {
-      var r = e.args[0].match(/^(\d+);(.*)$/);
-      r ? (e.args[0] = r[2], this.dispatch('OSC', r[1], e)) : console.warn('Invalid OSC: ' + JSON.stringify(e.args[0]));
+};
+, hterm.VT.CC1['Ž'] = hterm.VT.ESC.N = hterm.VT.ignore,
+  hterm.VT.CC1[''] = hterm.VT.ESC.O = hterm.VT.ignore,
+  hterm.VT.CC1[''] = hterm.VT.ESC.P = function(e) {
+    e.resetArguments(), e.func = this.parseUntilStringTerminator_;
+  };
+, hterm.VT.CC1['–'] = hterm.VT.ESC.V = hterm.VT.ignore,
+  hterm.VT.CC1['—'] = hterm.VT.ESC.W = hterm.VT.ignore,
+  hterm.VT.CC1['˜'] = hterm.VT.ESC.X = hterm.VT.ignore,
+  hterm.VT.CC1['š'] = hterm.VT.ESC.Z = function() {
+    this.terminal.io.sendString('[?1;2c');
+  };
+, hterm.VT.CC1['›'] = hterm.VT.ESC['['] = function(e) {
+  e.resetArguments(), this.leadingModifier_ = '', this.trailingModifier_ = '',
+                      e.func = this.parseCSI_;
+};
+, hterm.VT.CC1['œ'] = hterm.VT.ESC['\\'] = hterm.VT.ignore,
+  hterm.VT.CC1[''] = hterm.VT.ESC[']'] = function(e) {
+    function t(e) {
+      if (this.parseUntilStringTerminator_(e) && e.func != t) {
+        var r = e.args[0].match(/^(\d+);(.*)$/);
+        r ? (e.args[0] = r[2], this.dispatch('OSC', r[1], e)) :
+            console.warn('Invalid OSC: ' + JSON.stringify(e.args[0]));
+      }
     }
-  }
-  e.resetArguments(), e.func = t;
-};, hterm.VT.CC1['ž'] = hterm.VT.ESC['^'] = function(e) {
+    e.resetArguments(), e.func = t;
+  };
+, hterm.VT.CC1['ž'] = hterm.VT.ESC['^'] = function(e) {
   e.resetArguments(), e.func = this.parseUntilStringTerminator_;
-};, hterm.VT.CC1['Ÿ'] = hterm.VT.ESC._ = function(e) {
+};
+, hterm.VT.CC1['Ÿ'] = hterm.VT.ESC._ = function(e) {
   e.resetArguments(), e.func = this.parseUntilStringTerminator_;
-};, hterm.VT.ESC[' '] = function(e) {
+};
+, hterm.VT.ESC[' '] = function(e) {
   e.func = function(e) {
     var t = e.consumeChar();
-    this.warnUnimplemented && console.warn('Unimplemented sequence: ESC 0x20 ' + t), e.resetParseFunction();
+    this.warnUnimplemented &&
+        console.warn('Unimplemented sequence: ESC 0x20 ' + t),
+        e.resetParseFunction();
   };
-};, hterm.VT.ESC['#'] = function(e) {
+};
+, hterm.VT.ESC['#'] = function(e) {
   e.func = function(e) {
     var t = e.consumeChar();
     '8' == t && this.terminal.fill('E'), e.resetParseFunction();
   };
-};, hterm.VT.ESC['%'] = function(e) {
+};
+, hterm.VT.ESC['%'] = function(e) {
   e.func = function(e) {
     var t = e.consumeChar();
-    '@' != t && 'G' != t && this.warnUnimplemented && console.warn('Unknown ESC % argument: ' + JSON.stringify(t)), e.resetParseFunction();
+    '@' != t && 'G' != t && this.warnUnimplemented &&
+        console.warn('Unknown ESC % argument: ' + JSON.stringify(t)),
+        e.resetParseFunction();
   };
-};, hterm.VT.ESC['('] = hterm.VT.ESC[')'] = hterm.VT.ESC['*'] = hterm.VT.ESC['+'] = hterm.VT.ESC['-'] = hterm.VT.ESC['.'] = hterm.VT.ESC['/'] = function(e, t) {
-  e.func = function(e) {
-    var r = e.consumeChar();
-    return '' == r ? (e.resetParseFunction(), void e.func()) : (r in hterm.VT.CharacterMap.maps ? '(' == t ? this.G0 = hterm.VT.CharacterMap.maps[r] : ')' == t || '-' == t ? this.G1 = hterm.VT.CharacterMap.maps[r] : '*' == t || '.' == t ? this.G2 = hterm.VT.CharacterMap.maps[r] : ('+' == t || '/' == t) && (this.G3 = hterm.VT.CharacterMap.maps[r]) : this.warnUnimplemented && console.log('Invalid character set for "' + t + '": ' + r), void e.resetParseFunction());
-  };
-};, hterm.VT.ESC[6] = hterm.VT.ignore, hterm.VT.ESC[7] = function() {
+};
+,
+    hterm.VT.ESC['('] = hterm.VT.ESC[')'] = hterm.VT.ESC['*'] =
+        hterm.VT.ESC['+'] = hterm.VT.ESC['-'] = hterm.VT.ESC['.'] =
+            hterm.VT.ESC['/'] = function(e, t) {
+              e.func = function(e) {
+                var r = e.consumeChar();
+                return '' == r ?
+                    (e.resetParseFunction(), void e.func()) :
+                    (r in hterm.VT.CharacterMap.maps ?
+                         '(' == t ? this.G0 = hterm.VT.CharacterMap.maps[r] :
+                                    ')' == t || '-' == t ?
+                                    this.G1 = hterm.VT.CharacterMap.maps[r] :
+                                    '*' == t || '.' == t ?
+                                    this.G2 = hterm.VT.CharacterMap.maps[r] :
+                                    ('+' == t || '/' == t) &&
+                                         (this.G3 =
+                                              hterm.VT.CharacterMap.maps[r]) :
+                         this.warnUnimplemented &&
+                             console.log(
+                                 'Invalid character set for "' + t + '": ' + r),
+                     void e.resetParseFunction());
+              };
+            };
+, hterm.VT.ESC[6] = hterm.VT.ignore, hterm.VT.ESC[7] = function() {
   this.savedState_.save();
-};, hterm.VT.ESC[8] = function() {
+};
+, hterm.VT.ESC[8] = function() {
   this.savedState_.restore();
-};, hterm.VT.ESC[9] = hterm.VT.ignore, hterm.VT.ESC['='] = function() {
+};
+, hterm.VT.ESC[9] = hterm.VT.ignore, hterm.VT.ESC['='] = function() {
   this.terminal.keyboard.applicationKeypad = !0;
-};, hterm.VT.ESC['>'] = function() {
+};
+, hterm.VT.ESC['>'] = function() {
   this.terminal.keyboard.applicationKeypad = !1;
-};, hterm.VT.ESC.F = hterm.VT.ignore, hterm.VT.ESC.c = function() {
+};
+, hterm.VT.ESC.F = hterm.VT.ignore, hterm.VT.ESC.c = function() {
   this.reset(), this.terminal.reset();
-};, hterm.VT.ESC.l = hterm.VT.ESC.m = hterm.VT.ignore, hterm.VT.ESC.n = function() {
-  this.GL = 'G2';
-};, hterm.VT.ESC.o = function() {
+};
+, hterm.VT.ESC.l = hterm.VT.ESC.m = hterm.VT.ignore,
+  hterm.VT.ESC.n = function() {
+    this.GL = 'G2';
+  };
+, hterm.VT.ESC.o = function() {
   this.GL = 'G3';
-};, hterm.VT.ESC['|'] = function() {
+};
+, hterm.VT.ESC['|'] = function() {
   this.GR = 'G3';
-};, hterm.VT.ESC['}'] = function() {
+};
+, hterm.VT.ESC['}'] = function() {
   this.GR = 'G2';
-};, hterm.VT.ESC['~'] = function() {
+};
+, hterm.VT.ESC['~'] = function() {
   this.GR = 'G1';
-};, hterm.VT.OSC[0] = function(e) {
+};
+, hterm.VT.OSC[0] = function(e) {
   this.terminal.setWindowTitle(e.args[0]);
-};, hterm.VT.OSC[2] = hterm.VT.OSC[0], hterm.VT.OSC[4] = function(e) {
-  for (var t = e.args[0].split(';'), r = parseInt(t.length / 2), o = this.terminal.getTextAttributes().colorPalette, i = [], s = 0; r > s; ++s) {
-    var n = parseInt(t[2 * s]),
-      a = t[2 * s + 1];
-    n >= o.length || ('?' != a ? (a = lib.colors.x11ToCSS(a), a && (o[n] = a)) : (a = lib.colors.rgbToX11(o[n]), a && i.push(n + ';' + a)));
+};
+, hterm.VT.OSC[2] = hterm.VT.OSC[0], hterm.VT.OSC[4] = function(e) {
+  for (var t = e.args[0].split(';'), r = parseInt(t.length / 2),
+           o = this.terminal.getTextAttributes().colorPalette, i = [], s = 0;
+       r > s; ++s) {
+    var n = parseInt(t[2 * s]), a = t[2 * s + 1];
+    n >= o.length ||
+        ('?' != a ? (a = lib.colors.x11ToCSS(a), a && (o[n] = a)) :
+                    (a = lib.colors.rgbToX11(o[n]), a && i.push(n + ';' + a)));
   }
   i.length && this.terminal.io.sendString(']4;' + i.join(';') + '');
-};, hterm.VT.OSC[50] = function(e) {
+};
+, hterm.VT.OSC[50] = function(e) {
   var t = e.args[0].match(/CursorShape=(.)/i);
   if (!t) return void console.warn('Could not parse OSC 50 args: ' + e.args[0]);
   switch (t[1]) {
@@ -4280,164 +6150,276 @@
     default:
       this.terminal.setCursorShape(hterm.Terminal.cursorShape.BLOCK);
   }
-};, hterm.VT.OSC[52] = function(e) {
+};
+, hterm.VT.OSC[52] = function(e) {
   var t = e.args[0].match(/^[cps01234567]*;(.*)/);
   if (t) {
     var r = window.atob(t[1]);
     r && this.terminal.copyStringToClipboard(this.decode(r));
   }
-};, hterm.VT.CSI['@'] = function(e) {
+};
+, hterm.VT.CSI['@'] = function(e) {
   this.terminal.insertSpace(e.iarg(0, 1));
-};, hterm.VT.CSI.A = function(e) {
+};
+, hterm.VT.CSI.A = function(e) {
   this.terminal.cursorUp(e.iarg(0, 1));
-};, hterm.VT.CSI.B = function(e) {
+};
+, hterm.VT.CSI.B = function(e) {
   this.terminal.cursorDown(e.iarg(0, 1));
-};, hterm.VT.CSI.C = function(e) {
+};
+, hterm.VT.CSI.C = function(e) {
   this.terminal.cursorRight(e.iarg(0, 1));
-};, hterm.VT.CSI.D = function(e) {
+};
+, hterm.VT.CSI.D = function(e) {
   this.terminal.cursorLeft(e.iarg(0, 1));
-};, hterm.VT.CSI.E = function(e) {
+};
+, hterm.VT.CSI.E = function(e) {
   this.terminal.cursorDown(e.iarg(0, 1)), this.terminal.setCursorColumn(0);
-};, hterm.VT.CSI.F = function(e) {
+};
+, hterm.VT.CSI.F = function(e) {
   this.terminal.cursorUp(e.iarg(0, 1)), this.terminal.setCursorColumn(0);
-};, hterm.VT.CSI.G = function(e) {
+};
+, hterm.VT.CSI.G = function(e) {
   this.terminal.setCursorColumn(e.iarg(0, 1) - 1);
-};, hterm.VT.CSI.H = function(e) {
+};
+, hterm.VT.CSI.H = function(e) {
   this.terminal.setCursorPosition(e.iarg(0, 1) - 1, e.iarg(1, 1) - 1);
-};, hterm.VT.CSI.I = function(e) {
+};
+, hterm.VT.CSI.I = function(e) {
   var t = e.iarg(0, 1);
   t = lib.f.clamp(t, 1, this.terminal.screenSize.width);
   for (var r = 0; t > r; r++) this.terminal.forwardTabStop();
-};, hterm.VT.CSI.J = hterm.VT.CSI['?J'] = function(e, t) {
+};
+, hterm.VT.CSI.J = hterm.VT.CSI['?J'] = function(e, t) {
   var r = e.args[0];
-  r && '0' != r ? '1' == r ? this.terminal.eraseAbove() : '2' == r ? this.terminal.clear() : '3' == r && this.terminal.clear() : this.terminal.eraseBelow()
-};, hterm.VT.CSI.K = hterm.VT.CSI['?K'] = function(e, t) {
+  r && '0' != r ? '1' == r ? this.terminal.eraseAbove() :
+                             '2' == r ? this.terminal.clear() :
+                                        '3' == r && this.terminal.clear() :
+                  this.terminal.eraseBelow()
+};
+, hterm.VT.CSI.K = hterm.VT.CSI['?K'] = function(e, t) {
   var r = e.args[0];
-  r && '0' != r ? '1' == r ? this.terminal.eraseToLeft() : '2' == r && this.terminal.eraseLine() : this.terminal.eraseToRight();
-};, hterm.VT.CSI.L = function(e) {
+  r && '0' != r ? '1' == r ? this.terminal.eraseToLeft() :
+                             '2' == r && this.terminal.eraseLine() :
+                  this.terminal.eraseToRight();
+};
+, hterm.VT.CSI.L = function(e) {
   this.terminal.insertLines(e.iarg(0, 1));
-};, hterm.VT.CSI.M = function(e) {
+};
+, hterm.VT.CSI.M = function(e) {
   this.terminal.deleteLines(e.iarg(0, 1));
-};, hterm.VT.CSI.P = function(e) {
+};
+, hterm.VT.CSI.P = function(e) {
   this.terminal.deleteChars(e.iarg(0, 1));
-};, hterm.VT.CSI.S = function(e) {
+};
+, hterm.VT.CSI.S = function(e) {
   this.terminal.vtScrollUp(e.iarg(0, 1));
-};, hterm.VT.CSI.T = function(e) {
+};
+, hterm.VT.CSI.T = function(e) {
   e.args.length <= 1 && this.terminal.vtScrollDown(e.iarg(0, 1));
-};, hterm.VT.CSI['>T'] = hterm.VT.ignore, hterm.VT.CSI.X = function(e) {
+};
+, hterm.VT.CSI['>T'] = hterm.VT.ignore, hterm.VT.CSI.X = function(e) {
   this.terminal.eraseToRight(e.iarg(0, 1));
-};, hterm.VT.CSI.Z = function(e) {
+};
+, hterm.VT.CSI.Z = function(e) {
   var t = e.iarg(0, 1);
   t = lib.f.clamp(t, 1, this.terminal.screenSize.width);
   for (var r = 0; t > r; r++) this.terminal.backwardTabStop();
-};, hterm.VT.CSI['`'] = function(e) {
+};
+, hterm.VT.CSI['`'] = function(e) {
   this.terminal.setCursorColumn(e.iarg(0, 1) - 1);
-};, hterm.VT.CSI.b = hterm.VT.ignore, hterm.VT.CSI.c = function(e) {
+};
+, hterm.VT.CSI.b = hterm.VT.ignore, hterm.VT.CSI.c = function(e) {
   e.args[0] && '0' != e.args[0] || this.terminal.io.sendString('[?1;2c');
-};, hterm.VT.CSI['>c'] = function(e) {
+};
+, hterm.VT.CSI['>c'] = function(e) {
   this.terminal.io.sendString('[>0;256;0c');
-};, hterm.VT.CSI.d = function(e) {
+};
+, hterm.VT.CSI.d = function(e) {
   this.terminal.setAbsoluteCursorRow(e.iarg(0, 1) - 1);
-};, hterm.VT.CSI.f = hterm.VT.CSI.H, hterm.VT.CSI.g = function(e) {
-  e.args[0] && '0' != e.args[0] ? '3' == e.args[0] && this.terminal.clearAllTabStops() : this.terminal.clearTabStopAtCursor(!1);
-};, hterm.VT.CSI.h = function(e) {
+};
+, hterm.VT.CSI.f = hterm.VT.CSI.H, hterm.VT.CSI.g = function(e) {
+  e.args[0] && '0' != e.args[0] ?
+      '3' == e.args[0] && this.terminal.clearAllTabStops() :
+      this.terminal.clearTabStopAtCursor(!1);
+};
+, hterm.VT.CSI.h = function(e) {
   for (var t = 0; t < e.args.length; t++) this.setANSIMode(e.args[t], !0);
-};, hterm.VT.CSI['?h'] = function(e) {
+};
+, hterm.VT.CSI['?h'] = function(e) {
   for (var t = 0; t < e.args.length; t++) this.setDECMode(e.args[t], !0);
-};, hterm.VT.CSI.i = hterm.VT.CSI['?i'] = hterm.VT.ignore, hterm.VT.CSI.l = function(e) {
-  for (var t = 0; t < e.args.length; t++) this.setANSIMode(e.args[t], !1);
-};, hterm.VT.CSI['?l'] = function(e) {
+};
+, hterm.VT.CSI.i = hterm.VT.CSI['?i'] = hterm.VT.ignore,
+  hterm.VT.CSI.l = function(e) {
+    for (var t = 0; t < e.args.length; t++) this.setANSIMode(e.args[t], !1);
+  };
+, hterm.VT.CSI['?l'] = function(e) {
   for (var t = 0; t < e.args.length; t++) this.setDECMode(e.args[t], !1);
-};, hterm.VT.CSI.m = function(e) {
+};
+, hterm.VT.CSI.m = function(e) {
   function t(t) {
-    return e.args.length < t + 2 || '5' != e.args[t + 1] ? null : e.iarg(t + 2, 0);
+    return e.args.length < t + 2 || '5' != e.args[t + 1] ? null :
+                                                           e.iarg(t + 2, 0);
   }
 
   function r(t) {
     if (e.args.length < t + 5 || '2' != e.args[t + 1]) return null;
-    var r = e.iarg(t + 2, 0),
-      o = e.iarg(t + 3, 0),
-      i = e.iarg(t + 4, 0);
+    var r = e.iarg(t + 2, 0), o = e.iarg(t + 3, 0), i = e.iarg(t + 4, 0);
     return 'rgb(' + r + ' ,' + o + ' ,' + i + ')';
   }
   var o = this.terminal.getTextAttributes();
   if (!e.args.length) return void o.reset();
   for (var i = 0; i < e.args.length; i++) {
     var s = e.iarg(i, 0);
-    if (30 > s) 0 == s ? o.reset() : 1 == s ? o.bold = !0 : 2 == s ? o.faint = !0 : 3 == s ? o.italic = !0 : 4 == s ? o.underline = !0 : 5 == s ? o.blink = !0 : 7 == s ? o.inverse = !0 : 8 == s ? o.invisible = !0 : 9 == s ? o.strikethrough = !0 : 22 == s ? (o.bold = !1, o.faint = !1) : 23 == s ? o.italic = !1 : 24 == s ? o.underline = !1 : 25 == s ? o.blink = !1 : 27 == s ? o.inverse = !1 : 28 == s ? o.invisible = !1 : 29 == s && (o.strikethrough = !1);
+    if (30 > s)
+      0 == s ? o.reset() :
+               1 == s ?
+               o.bold = !0 :
+               2 == s ?
+               o.faint = !0 :
+               3 == s ?
+               o.italic = !0 :
+               4 == s ?
+               o.underline = !0 :
+               5 == s ?
+               o.blink = !0 :
+               7 == s ?
+               o.inverse = !0 :
+               8 == s ?
+               o.invisible = !0 :
+               9 == s ?
+               o.strikethrough = !0 :
+               22 == s ?
+               (o.bold = !1, o.faint = !1) :
+               23 == s ?
+               o.italic = !1 :
+               24 == s ?
+               o.underline = !1 :
+               25 == s ? o.blink = !1 :
+                         27 == s ? o.inverse = !1 :
+                                   28 == s ? o.invisible = !1 :
+                                             29 == s && (o.strikethrough = !1);
     else if (50 > s)
-      if (38 > s) o.foregroundSource = s - 30;
+      if (38 > s)
+        o.foregroundSource = s - 30;
       else if (38 == s) {
-      var n = r(i);
-      if (null != n) o.foregroundSource = o.SRC_RGB, o.foreground = n, i += 5;
-      else {
-        var a = t(i);
-        if (null == a) break;
-        if (i += 2, a >= o.colorPalette.length) continue;
-        o.foregroundSource = a;
-      }
-    }
-    else if (39 == s) o.foregroundSource = o.SRC_DEFAULT;
-    else if (48 > s) o.backgroundSource = s - 40;
-    else if (48 == s) {
-      var n = r(i);
-      if (null != n) o.backgroundSource = o.SRC_RGB, o.background = n, i += 5;
-      else {
-        var a = t(i);
-        if (null == a) break;
-        if (i += 2, a >= o.colorPalette.length) continue;
-        o.backgroundSource = a;
-      }
-    }
-    else o.backgroundSource = o.SRC_DEFAULT;
-    else s >= 90 && 97 >= s ? o.foregroundSource = s - 90 + 8 : s >= 100 && 107 >= s && (o.backgroundSource = s - 100 + 8);
+        var n = r(i);
+        if (null != n)
+          o.foregroundSource = o.SRC_RGB, o.foreground = n, i += 5;
+        else {
+          var a = t(i);
+          if (null == a) break;
+          if (i += 2, a >= o.colorPalette.length) continue;
+          o.foregroundSource = a;
+        }
+      } else if (39 == s)
+        o.foregroundSource = o.SRC_DEFAULT;
+      else if (48 > s)
+        o.backgroundSource = s - 40;
+      else if (48 == s) {
+        var n = r(i);
+        if (null != n)
+          o.backgroundSource = o.SRC_RGB, o.background = n, i += 5;
+        else {
+          var a = t(i);
+          if (null == a) break;
+          if (i += 2, a >= o.colorPalette.length) continue;
+          o.backgroundSource = a;
+        }
+      } else
+        o.backgroundSource = o.SRC_DEFAULT;
+    else
+      s >= 90 && 97 >= s ?
+          o.foregroundSource = s - 90 + 8 :
+          s >= 100 && 107 >= s && (o.backgroundSource = s - 100 + 8);
   }
-  o.setDefaults(this.terminal.getForegroundColor(), this.terminal.getBackgroundColor());
-};, hterm.VT.CSI['>m'] = hterm.VT.ignore, hterm.VT.CSI.n = function(e) {
-  if ('5' == e.args[0]) this.terminal.io.sendString('0n');
+  o.setDefaults(
+      this.terminal.getForegroundColor(), this.terminal.getBackgroundColor());
+};
+, hterm.VT.CSI['>m'] = hterm.VT.ignore, hterm.VT.CSI.n = function(e) {
+  if ('5' == e.args[0])
+    this.terminal.io.sendString('0n');
   else if ('6' == e.args[0]) {
     var t = this.terminal.getCursorRow() + 1,
-      r = this.terminal.getCursorColumn() + 1;
+        r = this.terminal.getCursorColumn() + 1;
     this.terminal.io.sendString('[' + t + ';' + r + 'R');
   }
-};, hterm.VT.CSI['>n'] = hterm.VT.ignore, hterm.VT.CSI['?n'] = function(e) {
+};
+, hterm.VT.CSI['>n'] = hterm.VT.ignore, hterm.VT.CSI['?n'] = function(e) {
   if ('6' == e.args[0]) {
     var t = this.terminal.getCursorRow() + 1,
-      r = this.terminal.getCursorColumn() + 1;
+        r = this.terminal.getCursorColumn() + 1;
     this.terminal.io.sendString('[' + t + ';' + r + 'R');
-  }
-  else '15' == e.args[0] ? this.terminal.io.sendString('[?11n') : '25' == e.args[0] ? this.terminal.io.sendString('[?21n') : '26' == e.args[0] ? this.terminal.io.sendString('[?12;1;0;0n') : '53' == e.args[0] && this.terminal.io.sendString('[?50n')
-};, hterm.VT.CSI['>p'] = hterm.VT.ignore, hterm.VT.CSI['!p'] = function() {
+  } else
+    '15' == e.args[0] ?
+        this.terminal.io.sendString('[?11n') :
+        '25' == e.args[0] ?
+        this.terminal.io.sendString('[?21n') :
+        '26' == e.args[0] ?
+        this.terminal.io.sendString('[?12;1;0;0n') :
+        '53' == e.args[0] && this.terminal.io.sendString('[?50n')
+};
+, hterm.VT.CSI['>p'] = hterm.VT.ignore, hterm.VT.CSI['!p'] = function() {
   this.reset(), this.terminal.softReset();
-};, hterm.VT.CSI.$p = hterm.VT.ignore, hterm.VT.CSI['?$p'] = hterm.VT.ignore, hterm.VT.CSI['"p'] = hterm.VT.ignore, hterm.VT.CSI.q = hterm.VT.ignore, hterm.VT.CSI[' q'] = function(e) {
-  var t = e.args[0];
-  '0' == t || '1' == t ? (this.terminal.setCursorShape(hterm.Terminal.cursorShape.BLOCK), this.terminal.setCursorBlink(!0)) : '2' == t ? (this.terminal.setCursorShape(hterm.Terminal.cursorShape.BLOCK), this.terminal.setCursorBlink(!1)) : '3' == t ? (this.terminal.setCursorShape(hterm.Terminal.cursorShape.UNDERLINE), this.terminal.setCursorBlink(!0)) : '4' == t ? (this.terminal.setCursorShape(hterm.Terminal.cursorShape.UNDERLINE), this.terminal.setCursorBlink(!1)) : console.warn('Unknown cursor style: ' + t)
-};, hterm.VT.CSI['"q'] = hterm.VT.ignore, hterm.VT.CSI.r = function(e) {
-  var t = e.args,
-    r = t[0] ? parseInt(t[0], 10) - 1 : null,
-    o = t[1] ? parseInt(t[1], 10) - 1 : null;
-  this.terminal.setVTScrollRegion(r, o), this.terminal.setCursorPosition(0, 0);
-};, hterm.VT.CSI['?r'] = hterm.VT.ignore, hterm.VT.CSI.$r = hterm.VT.ignore, hterm.VT.CSI.s = function() {
-  this.savedState_.save();
-};, hterm.VT.CSI['?s'] = hterm.VT.ignore, hterm.VT.CSI.t = hterm.VT.ignore, hterm.VT.CSI.$t = hterm.VT.ignore, hterm.VT.CSI['>t'] = hterm.VT.ignore, hterm.VT.CSI[' t'] = hterm.VT.ignore, hterm.VT.CSI.u = function() {
-  this.savedState_.restore();
-};, hterm.VT.CSI[' u'] = hterm.VT.ignore, hterm.VT.CSI.$v = hterm.VT.ignore, hterm.VT.CSI["'w"] = hterm.VT.ignore, hterm.VT.CSI.x = hterm.VT.ignore, hterm.VT.CSI['*x'] = hterm.VT.ignore, hterm.VT.CSI.$x = hterm.VT.ignore, hterm.VT.CSI.z = function(e) {
-  if (!(e.args.length < 1)) {
+};
+, hterm.VT.CSI.$p = hterm.VT.ignore, hterm.VT.CSI['?$p'] = hterm.VT.ignore,
+  hterm.VT.CSI['"p'] = hterm.VT.ignore, hterm.VT.CSI.q = hterm.VT.ignore,
+  hterm.VT.CSI[' q'] = function(e) {
     var t = e.args[0];
-    if ('0' == t) {
-      if (e.args.length < 2) return;
-      this.terminal.getTextAttributes().tileData = e.args[1];
+    '0' == t || '1' == t ?
+        (this.terminal.setCursorShape(hterm.Terminal.cursorShape.BLOCK),
+         this.terminal.setCursorBlink(!0)) :
+        '2' == t ?
+        (this.terminal.setCursorShape(hterm.Terminal.cursorShape.BLOCK),
+         this.terminal.setCursorBlink(!1)) :
+        '3' == t ?
+        (this.terminal.setCursorShape(hterm.Terminal.cursorShape.UNDERLINE),
+         this.terminal.setCursorBlink(!0)) :
+        '4' == t ?
+        (this.terminal.setCursorShape(hterm.Terminal.cursorShape.UNDERLINE),
+         this.terminal.setCursorBlink(!1)) :
+        console.warn('Unknown cursor style: ' + t)
+  };
+, hterm.VT.CSI['"q'] = hterm.VT.ignore, hterm.VT.CSI.r = function(e) {
+  var t = e.args, r = t[0] ? parseInt(t[0], 10) - 1 : null,
+      o = t[1] ? parseInt(t[1], 10) - 1 : null;
+  this.terminal.setVTScrollRegion(r, o), this.terminal.setCursorPosition(0, 0);
+};
+, hterm.VT.CSI['?r'] = hterm.VT.ignore, hterm.VT.CSI.$r = hterm.VT.ignore,
+  hterm.VT.CSI.s = function() {
+    this.savedState_.save();
+  };
+, hterm.VT.CSI['?s'] = hterm.VT.ignore, hterm.VT.CSI.t = hterm.VT.ignore,
+  hterm.VT.CSI.$t = hterm.VT.ignore, hterm.VT.CSI['>t'] = hterm.VT.ignore,
+  hterm.VT.CSI[' t'] = hterm.VT.ignore, hterm.VT.CSI.u = function() {
+    this.savedState_.restore();
+  };
+, hterm.VT.CSI[' u'] = hterm.VT.ignore, hterm.VT.CSI.$v = hterm.VT.ignore,
+  hterm.VT.CSI['\'w'] = hterm.VT.ignore, hterm.VT.CSI.x = hterm.VT.ignore,
+  hterm.VT.CSI['*x'] = hterm.VT.ignore, hterm.VT.CSI.$x = hterm.VT.ignore,
+  hterm.VT.CSI.z = function(e) {
+    if (!(e.args.length < 1)) {
+      var t = e.args[0];
+      if ('0' == t) {
+        if (e.args.length < 2) return;
+        this.terminal.getTextAttributes().tileData = e.args[1];
+      } else
+        '1' == t && (this.terminal.getTextAttributes().tileData = null);
     }
-    else '1' == t && (this.terminal.getTextAttributes().tileData = null);
-  }
-};, hterm.VT.CSI["'z"] = hterm.VT.ignore, hterm.VT.CSI.$z = hterm.VT.ignore, hterm.VT.CSI["'{"] = hterm.VT.ignore, hterm.VT.CSI["'|"] = hterm.VT.ignore, hterm.VT.CSI[' }'] = hterm.VT.ignore, hterm.VT.CSI[' ~'] = hterm.VT.ignore, lib.rtdep('lib.f'), hterm.VT.CharacterMap = function(e, t) {
-  this.name = e, this.GL = null, this.GR = null, t && this.reset(t);
-};, hterm.VT.CharacterMap.prototype.reset = function(e) {
+  };
+, hterm.VT.CSI['\'z'] = hterm.VT.ignore, hterm.VT.CSI.$z = hterm.VT.ignore,
+  hterm.VT.CSI['\'{'] = hterm.VT.ignore, hterm.VT.CSI['\'|'] = hterm.VT.ignore,
+  hterm.VT.CSI[' }'] = hterm.VT.ignore, hterm.VT.CSI[' ~'] = hterm.VT.ignore,
+  lib.rtdep('lib.f'), hterm.VT.CharacterMap = function(e, t) {
+    this.name = e, this.GL = null, this.GR = null, t && this.reset(t);
+  };
+, hterm.VT.CharacterMap.prototype.reset = function(e) {
   this.glmap = e;
   var t = Object.keys(this.glmap).map(function(e) {
     return '\\x' + lib.f.zpad(e.charCodeAt(0).toString(16));
   });
-  this.glre = new RegExp('[' + t.join('') + ']', 'g'), this.grmap = {}, t.forEach(function(e) {
+  this.glre = new RegExp('[' + t.join('') + ']', 'g'), this.grmap = {},
+  t.forEach(function(e) {
     var t = String.fromCharCode(128 & e.charCodeAt(0));
     this.grmap[t] = this.glmap[e];
   }.bind(this));
@@ -4453,143 +6435,167 @@
       return this.grmap[e];
     }.bind(this));
   }.bind(this);
-};, hterm.VT.CharacterMap.maps = {}, hterm.VT.CharacterMap.maps[0] = new hterm.VT.CharacterMap('graphic', {
-  '`': '◆',
-  a: '▒',
-  b: '␉',
-  c: '␌',
-  d: '␍',
-  e: '␊',
-  f: '°',
-  g: '±',
-  h: '␤',
-  i: '␋',
-  j: '┘',
-  k: '┐',
-  l: '┌',
-  m: '└',
-  n: '┼',
-  o: '⎺',
-  p: '⎻',
-  q: '─',
-  r: '⎼',
-  s: '⎽',
-  t: '├',
-  u: '┤',
-  v: '┴',
-  w: '┬',
-  x: '│',
-  y: '≤',
-  z: '≥',
-  '{': 'π',
-  '|': '≠',
-  '}': '£',
-  '~': '·'
-}), hterm.VT.CharacterMap.maps.A = new hterm.VT.CharacterMap('british', {
-  '#': '£'
-}), hterm.VT.CharacterMap.maps.B = new hterm.VT.CharacterMap('us', null), hterm.VT.CharacterMap.maps[4] = new hterm.VT.CharacterMap('dutch', {
-  '#': '£',
-  '@': '¾',
-  '[': 'IJ',
-  '\\': '½',
-  ']': '|',
-  '{': '¨',
-  '|': 'f',
-  '}': '¼',
-  '~': '´'
-}), hterm.VT.CharacterMap.maps.C = hterm.VT.CharacterMap.maps[5] = new hterm.VT.CharacterMap('finnish', {
-  '[': 'Ä',
-  '\\': 'Ö',
-  ']': 'Å',
-  '^': 'Ü',
-  '`': 'é',
-  '{': 'ä',
-  '|': 'ö',
-  '}': 'å',
-  '~': 'ü'
-}), hterm.VT.CharacterMap.maps.R = new hterm.VT.CharacterMap('french', {
-  '#': '£',
-  '@': 'à',
-  '[': '°',
-  '\\': 'ç',
-  ']': '§',
-  '{': 'é',
-  '|': 'ù',
-  '}': 'è',
-  '~': '¨'
-}), hterm.VT.CharacterMap.maps.Q = new hterm.VT.CharacterMap('french canadian', {
-  '@': 'à',
-  '[': 'â',
-  '\\': 'ç',
-  ']': 'ê',
-  '^': 'î',
-  '`': 'ô',
-  '{': 'é',
-  '|': 'ù',
-  '}': 'è',
-  '~': 'û'
-}), hterm.VT.CharacterMap.maps.K = new hterm.VT.CharacterMap('german', {
-  '@': '§',
-  '[': 'Ä',
-  '\\': 'Ö',
-  ']': 'Ü',
-  '{': 'ä',
-  '|': 'ö',
-  '}': 'ü',
-  '~': 'ß'
-}), hterm.VT.CharacterMap.maps.Y = new hterm.VT.CharacterMap('italian', {
-  '#': '£',
-  '@': '§',
-  '[': '°',
-  '\\': 'ç',
-  ']': 'é',
-  '`': 'ù',
-  '{': 'à',
-  '|': 'ò',
-  '}': 'è',
-  '~': 'ì'
-}), hterm.VT.CharacterMap.maps.E = hterm.VT.CharacterMap.maps[6] = new hterm.VT.CharacterMap('norwegian/danish', {
-  '@': 'Ä',
-  '[': 'Æ',
-  '\\': 'Ø',
-  ']': 'Å',
-  '^': 'Ü',
-  '`': 'ä',
-  '{': 'æ',
-  '|': 'ø',
-  '}': 'å',
-  '~': 'ü'
-}), hterm.VT.CharacterMap.maps.Z = new hterm.VT.CharacterMap('spanish', {
-  '#': '£',
-  '@': '§',
-  '[': '¡',
-  '\\': 'Ñ',
-  ']': '¿',
-  '{': '°',
-  '|': 'ñ',
-  '}': 'ç'
-}), hterm.VT.CharacterMap.maps[7] = hterm.VT.CharacterMap.maps.H = new hterm.VT.CharacterMap('swedish', {
-  '@': 'É',
-  '[': 'Ä',
-  '\\': 'Ö',
-  ']': 'Å',
-  '^': 'Ü',
-  '`': 'é',
-  '{': 'ä',
-  '|': 'ö',
-  '}': 'å',
-  '~': 'ü'
-}), hterm.VT.CharacterMap.maps['='] = new hterm.VT.CharacterMap('swiss', {
-  '#': 'ù',
-  '@': 'à',
-  '[': 'é',
-  '\\': 'ç',
-  ']': 'ê',
-  '^': 'î',
-  _: 'è',
-  '`': 'ô',
-  '{': 'ä',
-  '|': 'ö',
-  '}': 'ü',
-  '~': 'û'
-}), lib.resource.add('hterm/audio/bell', 'audio/ogg;base64', 'T2dnUwACAAAAAAAAAADhqW5KAAAAAMFvEjYBHgF2b3JiaXMAAAAAAYC7AAAAAAAAAHcBAAAAAAC4AU9nZ1MAAAAAAAAAAAAA4aluSgEAAAAAesI3EC3//////////////////8kDdm9yYmlzHQAAAFhpcGguT3JnIGxpYlZvcmJpcyBJIDIwMDkwNzA5AAAAAAEFdm9yYmlzKUJDVgEACAAAADFMIMWA0JBVAAAQAABgJCkOk2ZJKaWUoSh5mJRISSmllMUwiZiUicUYY4wxxhhjjDHGGGOMIDRkFQAABACAKAmOo+ZJas45ZxgnjnKgOWlOOKcgB4pR4DkJwvUmY26mtKZrbs4pJQgNWQUAAAIAQEghhRRSSCGFFGKIIYYYYoghhxxyyCGnnHIKKqigggoyyCCDTDLppJNOOumoo4466ii00EILLbTSSkwx1VZjrr0GXXxzzjnnnHPOOeecc84JQkNWAQAgAAAEQgYZZBBCCCGFFFKIKaaYcgoyyIDQkFUAACAAgAAAAABHkRRJsRTLsRzN0SRP8ixREzXRM0VTVE1VVVVVdV1XdmXXdnXXdn1ZmIVbuH1ZuIVb2IVd94VhGIZhGIZhGIZh+H3f933f930gNGQVACABAKAjOZbjKaIiGqLiOaIDhIasAgBkAAAEACAJkiIpkqNJpmZqrmmbtmirtm3LsizLsgyEhqwCAAABAAQAAAAAAKBpmqZpmqZpmqZpmqZpmqZpmqZpmmZZlmVZlmVZlmVZlmVZlmVZlmVZlmVZlmVZlmVZlmVZlmVZlmVZQGjIKgBAAgBAx3Ecx3EkRVIkx3IsBwgNWQUAyAAACABAUizFcjRHczTHczzHczxHdETJlEzN9EwPCA1ZBQAAAgAIAAAAAABAMRzFcRzJ0SRPUi3TcjVXcz3Xc03XdV1XVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVYHQkFUAAAQAACGdZpZqgAgzkGEgNGQVAIAAAAAYoQhDDAgNWQUAAAQAAIih5CCa0JrzzTkOmuWgqRSb08GJVJsnuamYm3POOeecbM4Z45xzzinKmcWgmdCac85JDJqloJnQmnPOeRKbB62p0ppzzhnnnA7GGWGcc85p0poHqdlYm3POWdCa5qi5FJtzzomUmye1uVSbc84555xzzjnnnHPOqV6czsE54Zxzzonam2u5CV2cc875ZJzuzQnhnHPOOeecc84555xzzglCQ1YBAEAAAARh2BjGnYIgfY4GYhQhpiGTHnSPDpOgMcgppB6NjkZKqYNQUhknpXSC0JBVAAAgAACEEFJIIYUUUkghhRRSSCGGGGKIIaeccgoqqKSSiirKKLPMMssss8wyy6zDzjrrsMMQQwwxtNJKLDXVVmONteaec645SGultdZaK6WUUkoppSA0ZBUAAAIAQCBkkEEGGYUUUkghhphyyimnoIIKCA1ZBQAAAgAIAAAA8CTPER3RER3RER3RER3RER3P8RxREiVREiXRMi1TMz1VVFVXdm1Zl3Xbt4Vd2HXf133f141fF4ZlWZZlWZZlWZZlWZZlWZZlCUJDVgEAIAAAAEIIIYQUUkghhZRijDHHnINOQgmB0JBVAAAgAIAAAAAAR3EUx5EcyZEkS7IkTdIszfI0T/M00RNFUTRNUxVd0RV10xZlUzZd0zVl01Vl1XZl2bZlW7d9WbZ93/d93/d93/d93/d939d1IDRkFQAgAQCgIzmSIimSIjmO40iSBISGrAIAZAAABACgKI7iOI4jSZIkWZImeZZniZqpmZ7pqaIKhIasAgAAAQAEAAAAAACgaIqnmIqniIrniI4oiZZpiZqquaJsyq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7rukBoyCoAQAIAQEdyJEdyJEVSJEVyJAcIDVkFAMgAAAgAwDEcQ1Ikx7IsTfM0T/M00RM90TM9VXRFFwgNWQUAAAIACAAAAAAAwJAMS7EczdEkUVIt1VI11VItVVQ9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV1TRN0zSB0JCVAAAZAAAjQQYZhBCKcpBCbj1YCDHmJAWhOQahxBiEpxAzDDkNInSQQSc9uJI5wwzz4FIoFURMg40lN44gDcKmXEnlOAhCQ1YEAFEAAIAxyDHEGHLOScmgRM4xCZ2UyDknpZPSSSktlhgzKSWmEmPjnKPSScmklBhLip2kEmOJrQAAgAAHAIAAC6HQkBUBQBQAAGIMUgophZRSzinmkFLKMeUcUko5p5xTzjkIHYTKMQadgxAppRxTzinHHITMQeWcg9BBKAAAIMABACDAQig0ZEUAECcA4HAkz5M0SxQlSxNFzxRl1xNN15U0zTQ1UVRVyxNV1VRV2xZNVbYlTRNNTfRUVRNFVRVV05ZNVbVtzzRl2VRV3RZV1bZl2xZ+V5Z13zNNWRZV1dZNVbV115Z9X9ZtXZg0zTQ1UVRVTRRV1VRV2zZV17Y1UXRVUVVlWVRVWXZlWfdVV9Z9SxRV1VNN2RVVVbZV2fVtVZZ94XRVXVdl2fdVWRZ+W9eF4fZ94RhV1dZN19V1VZZ9YdZlYbd13yhpmmlqoqiqmiiqqqmqtm2qrq1bouiqoqrKsmeqrqzKsq+rrmzrmiiqrqiqsiyqqiyrsqz7qizrtqiquq3KsrCbrqvrtu8LwyzrunCqrq6rsuz7qizruq3rxnHrujB8pinLpqvquqm6um7runHMtm0co6rqvirLwrDKsu/rui+0dSFRVXXdlF3jV2VZ921fd55b94WybTu/rfvKceu60vg5z28cubZtHLNuG7+t+8bzKz9hOI6lZ5q2baqqrZuqq+uybivDrOtCUVV9XZVl3zddWRdu3zeOW9eNoqrquirLvrDKsjHcxm8cuzAcXds2jlvXnbKtC31jyPcJz2vbxnH7OuP2daOvDAnHjwAAgAEHAIAAE8pAoSErAoA4AQAGIecUUxAqxSB0EFLqIKRUMQYhc05KxRyUUEpqIZTUKsYgVI5JyJyTEkpoKZTSUgehpVBKa6GU1lJrsabUYu0gpBZKaS2U0lpqqcbUWowRYxAy56RkzkkJpbQWSmktc05K56CkDkJKpaQUS0otVsxJyaCj0kFIqaQSU0mptVBKa6WkFktKMbYUW24x1hxKaS2kEltJKcYUU20txpojxiBkzknJnJMSSmktlNJa5ZiUDkJKmYOSSkqtlZJSzJyT0kFIqYOOSkkptpJKTKGU1kpKsYVSWmwx1pxSbDWU0lpJKcaSSmwtxlpbTLV1EFoLpbQWSmmttVZraq3GUEprJaUYS0qxtRZrbjHmGkppraQSW0mpxRZbji3GmlNrNabWam4x5hpbbT3WmnNKrdbUUo0txppjbb3VmnvvIKQWSmktlNJiai3G1mKtoZTWSiqxlZJabDHm2lqMOZTSYkmpxZJSjC3GmltsuaaWamwx5ppSi7Xm2nNsNfbUWqwtxppTS7XWWnOPufVWAADAgAMAQIAJZaDQkJUAQBQAAEGIUs5JaRByzDkqCULMOSepckxCKSlVzEEIJbXOOSkpxdY5CCWlFksqLcVWaykptRZrLQAAoMABACDABk2JxQEKDVkJAEQBACDGIMQYhAYZpRiD0BikFGMQIqUYc05KpRRjzknJGHMOQioZY85BKCmEUEoqKYUQSkklpQIAAAocAAACbNCUWByg0JAVAUAUAABgDGIMMYYgdFQyKhGETEonqYEQWgutddZSa6XFzFpqrbTYQAithdYySyXG1FpmrcSYWisAAOzAAQDswEIoNGQlAJAHAEAYoxRjzjlnEGLMOegcNAgx5hyEDirGnIMOQggVY85BCCGEzDkIIYQQQuYchBBCCKGDEEIIpZTSQQghhFJK6SCEEEIppXQQQgihlFIKAAAqcAAACLBRZHOCkaBCQ1YCAHkAAIAxSjkHoZRGKcYglJJSoxRjEEpJqXIMQikpxVY5B6GUlFrsIJTSWmw1dhBKaS3GWkNKrcVYa64hpdZirDXX1FqMteaaa0otxlprzbkAANwFBwCwAxtFNicYCSo0ZCUAkAcAgCCkFGOMMYYUYoox55xDCCnFmHPOKaYYc84555RijDnnnHOMMeecc845xphzzjnnHHPOOeecc44555xzzjnnnHPOOeecc84555xzzgkAACpwAAAIsFFkc4KRoEJDVgIAqQAAABFWYowxxhgbCDHGGGOMMUYSYowxxhhjbDHGGGOMMcaYYowxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGFtrrbXWWmuttdZaa6211lprrQBAvwoHAP8HG1ZHOCkaCyw0ZCUAEA4AABjDmHOOOQYdhIYp6KSEDkIIoUNKOSglhFBKKSlzTkpKpaSUWkqZc1JSKiWlllLqIKTUWkottdZaByWl1lJqrbXWOgiltNRaa6212EFIKaXWWostxlBKSq212GKMNYZSUmqtxdhirDGk0lJsLcYYY6yhlNZaazHGGGstKbXWYoy1xlprSam11mKLNdZaCwDgbnAAgEiwcYaVpLPC0eBCQ1YCACEBAARCjDnnnHMQQgghUoox56CDEEIIIURKMeYcdBBCCCGEjDHnoIMQQgghhJAx5hx0EEIIIYQQOucchBBCCKGEUkrnHHQQQgghlFBC6SCEEEIIoYRSSikdhBBCKKGEUkopJYQQQgmllFJKKaWEEEIIoYQSSimllBBCCKWUUkoppZQSQgghlFJKKaWUUkIIoZRQSimllFJKCCGEUkoppZRSSgkhhFBKKaWUUkopIYQSSimllFJKKaUAAIADBwCAACPoJKPKImw04cIDUGjISgCADAAAcdhq6ynWyCDFnISWS4SQchBiLhFSijlHsWVIGcUY1ZQxpRRTUmvonGKMUU+dY0oxw6yUVkookYLScqy1dswBAAAgCAAwECEzgUABFBjIAIADhAQpAKCwwNAxXAQE5BIyCgwKx4Rz0mkDABCEyAyRiFgMEhOqgaJiOgBYXGDIB4AMjY20iwvoMsAFXdx1IIQgBCGIxQEUkICDE2544g1PuMEJOkWlDgIAAAAA4AAAHgAAkg0gIiKaOY4Ojw+QEJERkhKTE5QAAAAAALABgA8AgCQFiIiIZo6jw+MDJERkhKTE5AQlAAAAAAAAAAAACAgIAAAAAAAEAAAACAhPZ2dTAAQYOwAAAAAAAOGpbkoCAAAAmc74DRgyNjM69TAzOTk74dnLubewsbagmZiNp4d0KbsExSY/I3XUTwJgkeZdn1HY4zoj33/q9DFtv3Ui1/jmx7lCUtPt18/sYf9MkgAsAGRBd3gMGP4sU+qCPYBy9VrA3YqJosW3W2/ef1iO/u3cg8ZG/57jU+pPmbGEJUgkfnaI39DbPqxddZphbMRmCc5rKlkUMkyx8iIoug5dJv1OYH9a59c+3Gevqc7Z2XFdDjL/qHztRfjWEWxJ/aiGezjohu9HsCZdQBKbiH0VtU/3m85lDG2T/+xkZcYnX+E+aqzv/xTgOoTFG+x7SNqQ4N+oAABSxuVXw77Jd5bmmTmuJakX7509HH0kGYKvARPpwfOSAPySPAc2EkneDwB2HwAAJlQDYK5586N79GJCjx4+p6aDUd27XSvRyXLJkIC5YZ1jLv5lpOhZTz0s+DmnF1diptrnM6UDgIW11Xh8cHTd0/SmbgOAdxcyWwMAAGIrZ3fNSfZbzKiYrK4+tPqtnMVLOeWOG2kVvUY+p2PJ/hkCl5aFRO4TLGYPZcIU3vYM1hohS4jHFlnyW/2T5J7kGsShXWT8N05V+3C/GPqJ1QdWisGPxEzHqXISBPIinWDUt7IeJv/f5OtzBxpTzZZQ+CYEhHXfqG4aABQli72GJhN4oJv+hXcApAJSErAW8G2raAX4NUcABnVt77CzZAB+LsHcVe+Q4h+QB1wh/ZrJTPxSBdI8mgTeAdTsQOoFUEng9BHcVPhxSRRYkKWZJXOFYP6V4AEripJoEjXgA2wJRZHSExmJDm8F0A6gEXsg5a4ZsALItrMB7+fh7UKLvYWSdtsDwFf1mzYzS1F82N1h2Oyt2e76B1QdS0SAsQigLPMOgJS9JRC7hFXA6kUsLFNKD5cA5cTRvgSqPc3Fl99xW3QTi/MHR8DEm6WnvaVQATwRqRKjywQ9BrrhugR2AKTsPQeQckrAOgDOhbTESyrXQ50CkNpXdtWjW7W2/3UjeX3U95gIdalfRAoAmqUEiwp53hCdcCwlg47fcbfzlmQMAgaBkh7c+fcDgF+ifwDXfzegLPcLYJsAAJQArTXjnh/uXGy3v1Hk3pV6/3t5ruW81f6prfbM2Q3WNVy98BwUtbCwhFhAWuPev6Oe/4ZaFQUcgKrVs4defzh1TADA1DEh5b3VlDaECw5b+bPfkKos3tIAue3vJZOih3ga3l6O3PSfIkrLv0PAS86PPdL7g8oc2KteNFKKzKRehOv2gJoFLBPXmaXvPBQILgJon0bbWBszrYZYYwE7jl2j+vTdU7Vpk21LiU0QajPkywAAHqbUC0/YsYOdb4e6BOp7E0cCi04Ao/TgD8ZVAMid6h/A8IeBNkp6/xsAACZELEYIk+yvI6Qz1NN6lIftB/6IMWjWJNOqPTMedAmyaj6Es0QBklJpiSWWHnQ2CoYbGWAmt+0gLQBFKCBnp2QUUQZ/1thtZDBJUpFWY82z34ocorB62oX7qB5y0oPAv/foxH25wVmgIHf2xFOr8leZcBq1Kx3ZvCq9Bga639AxuHuPNL/71YCF4EywJpqHFAX6XF0sjVbuANnvvdLcrufYwOM/iDa6iA468AYAAB6mNBMXcgTD8HSRqJ4vw8CjAlCEPACASlX/APwPOJKl9xQAAAPmnev2eWp33Xgyw3Dvfz6myGk3oyP8YTKsCOvzAgALQi0o1c6Nzs2O2Pg2h4ACIJAgAGP0aNn5x0BDgVfH7u2TtyfDcRIuYAyQhBF/lvSRAttgA6TPbWZA9gaUrZWAUEAA+Dx47Q3/r87HxUUqZmB0BmUuMlojFjHt1gDunnvuX8MImsjSq5WkzSzGS62OEIlOufWWezxWpv6FBgDgJVltfXFYtNAAnqU0xQoD0YLiXo5cF5QV4CnY1tBLAkZCOABAhbk/AM+/AwSCCdlWAAAMcFjS7owb8GVDzveDiZvznbt2tF4bL5odN1YKl88TAEABCZvufq9YCTBtMwVAQUEAwGtNltzSaHvADYC3TxLVjqiRA+OZAMhzcqEgRcAOwoCgvdTxsTHLQEF6+oOb2+PAI8ciPQcXg7pOY+LjxQSv2fjmFuj34gGwz310/bGK6z3xgT887eomWULEaDd04wHetYxdjcgV2SxvSwn0VoZXJRqkRC5ASQ/muVoAUsX7AgAQMBNaVwAAlABRxT/1PmfqLqSRNDbhXb07berpB3b94jpuWEZjBCD2OcdXFpCKEgCDfcFPMw8AAADUwT4lnUm50lmwrpMMhPQIKj6u0E8fr2vGBngMNdIlrZsigjahljud6AFVg+tzXwUnXL3TJLpajaWKA4VAAAAMiFfqJgKAZ08XrtS3dxtQNYcpPvYEG8ClvrQRJgBephwnNWJjtGqmp6VEPSvBe7EBiU3qgJbQAwD4Le8LAMDMhHbNAAAlgK+tFs5O+YyJc9yCnJa3rxLPulGnxwsXV9Fsk2k4PisCAHC8FkwbGE9gJQAAoMnyksj0CdFMZLLgoz8M+FxziwYBgIx+zHiCBAKAlBKNpF1sO9JpVcyEi9ar15YlHgrut5fPJnkdJ6vEwZPyAHQBIEDUrlMcBAAd2KAS0Qq+JwRsE4AJZtMnAD6GnOYwYlOIZvtzUNdjreB7fiMkWI0CmBB6AIAKc38A9osEFlTSGECB+cbeRDC0aRpLHqNPplcK/76Lxn2rpmqyXsYJWRi/FQAAAKBQk9MCAOibrQBQADCDsqpooPutd+05Ce9g6iEdiYXgVmQAI4+4wskEBEiBloNQ6Ki0/KTQ0QjWfjxzi+AeuXKoMjEVfQOZzr0y941qLgM2AExvbZOqcxZ6J6krlrj4y2j9AdgKDx6GnJsVLhbc42uq584+ouSdNBpoCiCVHrz+WzUA/DDtD8ATgA3h0lMCAAzcFv+S+fSSNkeYWlTpb34mf2RfmqqJeMeklhHAfu7VoAEACgAApKRktL+KkQDWMwYCUAAAAHCKsp80xhp91UjqQBw3x45cetqkjQEyu3G9B6N+R650Uq8OVig7wOm6Wun0ea4lKDPoabJs6aLqgbhPzpv4KR4iODilw88ZpY7q1IOMcbASAOAVtmcCnobcrkG4KGS7/ZnskVWRNF9J0RUHKOnByy9WA8Dv6L4AAARMCQUA4GritfVM2lcZfH3Q3T/vZ47J2YHhcmBazjfdyuV25gLAzrc0cwAAAAAYCh6PdwAAAGyWjFW4yScjaWa2mGcofHxWxewKALglWBpLUvwwk+UOh5eNGyUOs1/EF+pZr+ud5OzoGwYdAABg2p52LiSgAY/ZVlOmilEgHn6G3OcwYjzI7vOj1t6xsx4S3lBY96EUQBF6AIBAmPYH4PoGYCoJAADWe+OZJZi7/x76/yH7Lzf9M5XzRKnFPmveMsilQHwVAAAAAKB3LQD8PCIAAADga0QujBLywzeJ4a6Z/ERVBAUlAEDqvoM7BQBAuAguzFqILtmjH3Kd4wfKobnOhA3z85qWoRPm9hwoOHoDAAlCbwDAA56FHAuXflHo3fe2ttG9XUDeA9YmYCBQ0oPr/1QC8IvuCwAAApbUAQCK22MmE3O78VAbHQT9PIPNoT9zNc3l2Oe7TAVLANBufT8MAQAAAGzT4PS8AQAAoELGHb2uaCwwEv1EWhFriUkbAaAZ27/fVZnTZXbWz3BwWpjUaMZKRj7dZ0J//gUeTdpVEwAAZOFsNxKAjQSgA+ABPoY8Jj5y2wje81jsXc/1TOQWTDYZBmAkNDiqVwuA2NJ9AQAAEBKAt9Vrsfs/2N19MO91S9rd8EHTZHnzC5MYmfQEACy/FBcAAADA5c4gi4z8RANs/m6FNXVo9DV46JG1BBDukqlw/Va5G7QbuGVSI+2aZaoLXJrdVj2zlC9Z5QEAEFz/5QzgVZwAAAAA/oXcxyC6WfTu+09Ve/c766J4VTAGUFmA51+VANKi/QPoPwYgYAkA715OH4S0s5KDHvj99MMq8TPFc3roKZnGOoT1bmIhVgc7XAMBAAAAAMAW1VbQw3gapzOpJd+Kd2fc4iSO62fJv9+movui1wUNPAj059N3OVxzk4gV73PmE8FIA2F5mRq37Evc76vLXfF4rD5UJJAw46hW6LZCb5sNLdx+kzMCAAB+hfy95+965ZCLP7B3/VlTHCvDEKtQhTm4KiCgAEAbrfbWTPssAAAAXpee1tVrozYYn41wD1aeYtkKfswN5/SXPO0JDnhO/4laUortv/s412fybe/nONdncoCHnBVliu0CQGBWlPY/5Kwom2L/kruPM6Q7oz4tvDQy+bZ3HzOi+gNHA4DZEgA='), lib.resource.add('hterm/concat/date', 'text/plain', 'Tue, 25 Apr 2017 15:12:45 +0000'), lib.resource.add('hterm/changelog/version', 'text/plain', '1.62'), lib.resource.add('hterm/changelog/date', 'text/plain', '2017-04-17'), lib.resource.add('hterm/git/HEAD', 'text/plain', 'git rev-parse HEAD');
+};
+, hterm.VT.CharacterMap.maps = {},
+  hterm.VT.CharacterMap.maps[0] = new hterm.VT.CharacterMap('graphic', {
+    '`': '◆',
+    a: '▒',
+    b: '␉',
+    c: '␌',
+    d: '␍',
+    e: '␊',
+    f: '°',
+    g: '±',
+    h: '␤',
+    i: '␋',
+    j: '┘',
+    k: '┐',
+    l: '┌',
+    m: '└',
+    n: '┼',
+    o: '⎺',
+    p: '⎻',
+    q: '─',
+    r: '⎼',
+    s: '⎽',
+    t: '├',
+    u: '┤',
+    v: '┴',
+    w: '┬',
+    x: '│',
+    y: '≤',
+    z: '≥',
+    '{': 'π',
+    '|': '≠',
+    '}': '£',
+    '~': '·'
+  }),
+  hterm.VT.CharacterMap.maps.A =
+      new hterm.VT.CharacterMap('british', {'#': '£'}),
+  hterm.VT.CharacterMap.maps.B = new hterm.VT.CharacterMap('us', null),
+  hterm.VT.CharacterMap.maps[4] = new hterm.VT.CharacterMap('dutch', {
+    '#': '£',
+    '@': '¾',
+    '[': 'IJ',
+    '\\': '½',
+    ']': '|',
+    '{': '¨',
+    '|': 'f',
+    '}': '¼',
+    '~': '´'
+  }),
+  hterm.VT.CharacterMap.maps.C = hterm.VT.CharacterMap.maps[5] =
+      new hterm.VT.CharacterMap('finnish', {
+        '[': 'Ä',
+        '\\': 'Ö',
+        ']': 'Å',
+        '^': 'Ü',
+        '`': 'é',
+        '{': 'ä',
+        '|': 'ö',
+        '}': 'å',
+        '~': 'ü'
+      }),
+  hterm.VT.CharacterMap.maps.R = new hterm.VT.CharacterMap('french', {
+    '#': '£',
+    '@': 'à',
+    '[': '°',
+    '\\': 'ç',
+    ']': '§',
+    '{': 'é',
+    '|': 'ù',
+    '}': 'è',
+    '~': '¨'
+  }),
+  hterm.VT.CharacterMap.maps.Q = new hterm.VT.CharacterMap('french canadian', {
+    '@': 'à',
+    '[': 'â',
+    '\\': 'ç',
+    ']': 'ê',
+    '^': 'î',
+    '`': 'ô',
+    '{': 'é',
+    '|': 'ù',
+    '}': 'è',
+    '~': 'û'
+  }),
+  hterm.VT.CharacterMap.maps.K = new hterm.VT.CharacterMap('german', {
+    '@': '§',
+    '[': 'Ä',
+    '\\': 'Ö',
+    ']': 'Ü',
+    '{': 'ä',
+    '|': 'ö',
+    '}': 'ü',
+    '~': 'ß'
+  }),
+  hterm.VT.CharacterMap.maps.Y = new hterm.VT.CharacterMap('italian', {
+    '#': '£',
+    '@': '§',
+    '[': '°',
+    '\\': 'ç',
+    ']': 'é',
+    '`': 'ù',
+    '{': 'à',
+    '|': 'ò',
+    '}': 'è',
+    '~': 'ì'
+  }),
+  hterm.VT.CharacterMap.maps.E = hterm.VT.CharacterMap.maps[6] =
+      new hterm.VT.CharacterMap('norwegian/danish', {
+        '@': 'Ä',
+        '[': 'Æ',
+        '\\': 'Ø',
+        ']': 'Å',
+        '^': 'Ü',
+        '`': 'ä',
+        '{': 'æ',
+        '|': 'ø',
+        '}': 'å',
+        '~': 'ü'
+      }),
+  hterm.VT.CharacterMap.maps.Z = new hterm.VT.CharacterMap('spanish', {
+    '#': '£',
+    '@': '§',
+    '[': '¡',
+    '\\': 'Ñ',
+    ']': '¿',
+    '{': '°',
+    '|': 'ñ',
+    '}': 'ç'
+  }),
+  hterm.VT.CharacterMap.maps[7] = hterm.VT.CharacterMap.maps.H =
+      new hterm.VT.CharacterMap('swedish', {
+        '@': 'É',
+        '[': 'Ä',
+        '\\': 'Ö',
+        ']': 'Å',
+        '^': 'Ü',
+        '`': 'é',
+        '{': 'ä',
+        '|': 'ö',
+        '}': 'å',
+        '~': 'ü'
+      }),
+  hterm.VT.CharacterMap.maps['='] = new hterm.VT.CharacterMap('swiss', {
+    '#': 'ù',
+    '@': 'à',
+    '[': 'é',
+    '\\': 'ç',
+    ']': 'ê',
+    '^': 'î',
+    _: 'è',
+    '`': 'ô',
+    '{': 'ä',
+    '|': 'ö',
+    '}': 'ü',
+    '~': 'û'
+  }),
+  lib.resource.add(
+      'hterm/audio/bell', 'audio/ogg;base64',
+      'T2dnUwACAAAAAAAAAADhqW5KAAAAAMFvEjYBHgF2b3JiaXMAAAAAAYC7AAAAAAAAAHcBAAAAAAC4AU9nZ1MAAAAAAAAAAAAA4aluSgEAAAAAesI3EC3//////////////////8kDdm9yYmlzHQAAAFhpcGguT3JnIGxpYlZvcmJpcyBJIDIwMDkwNzA5AAAAAAEFdm9yYmlzKUJDVgEACAAAADFMIMWA0JBVAAAQAABgJCkOk2ZJKaWUoSh5mJRISSmllMUwiZiUicUYY4wxxhhjjDHGGGOMIDRkFQAABACAKAmOo+ZJas45ZxgnjnKgOWlOOKcgB4pR4DkJwvUmY26mtKZrbs4pJQgNWQUAAAIAQEghhRRSSCGFFGKIIYYYYoghhxxyyCGnnHIKKqigggoyyCCDTDLppJNOOumoo4466ii00EILLbTSSkwx1VZjrr0GXXxzzjnnnHPOOeecc84JQkNWAQAgAAAEQgYZZBBCCCGFFFKIKaaYcgoyyIDQkFUAACAAgAAAAABHkRRJsRTLsRzN0SRP8ixREzXRM0VTVE1VVVVVdV1XdmXXdnXXdn1ZmIVbuH1ZuIVb2IVd94VhGIZhGIZhGIZh+H3f933f930gNGQVACABAKAjOZbjKaIiGqLiOaIDhIasAgBkAAAEACAJkiIpkqNJpmZqrmmbtmirtm3LsizLsgyEhqwCAAABAAQAAAAAAKBpmqZpmqZpmqZpmqZpmqZpmqZpmmZZlmVZlmVZlmVZlmVZlmVZlmVZlmVZlmVZlmVZlmVZlmVZlmVZQGjIKgBAAgBAx3Ecx3EkRVIkx3IsBwgNWQUAyAAACABAUizFcjRHczTHczzHczxHdETJlEzN9EwPCA1ZBQAAAgAIAAAAAABAMRzFcRzJ0SRPUi3TcjVXcz3Xc03XdV1XVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVYHQkFUAAAQAACGdZpZqgAgzkGEgNGQVAIAAAAAYoQhDDAgNWQUAAAQAAIih5CCa0JrzzTkOmuWgqRSb08GJVJsnuamYm3POOeecbM4Z45xzzinKmcWgmdCac85JDJqloJnQmnPOeRKbB62p0ppzzhnnnA7GGWGcc85p0poHqdlYm3POWdCa5qi5FJtzzomUmye1uVSbc84555xzzjnnnHPOqV6czsE54Zxzzonam2u5CV2cc875ZJzuzQnhnHPOOeecc84555xzzglCQ1YBAEAAAARh2BjGnYIgfY4GYhQhpiGTHnSPDpOgMcgppB6NjkZKqYNQUhknpXSC0JBVAAAgAACEEFJIIYUUUkghhRRSSCGGGGKIIaeccgoqqKSSiirKKLPMMssss8wyy6zDzjrrsMMQQwwxtNJKLDXVVmONteaec645SGultdZaK6WUUkoppSA0ZBUAAAIAQCBkkEEGGYUUUkghhphyyimnoIIKCA1ZBQAAAgAIAAAA8CTPER3RER3RER3RER3RER3P8RxREiVREiXRMi1TMz1VVFVXdm1Zl3Xbt4Vd2HXf133f141fF4ZlWZZlWZZlWZZlWZZlWZZlCUJDVgEAIAAAAEIIIYQUUkghhZRijDHHnINOQgmB0JBVAAAgAIAAAAAAR3EUx5EcyZEkS7IkTdIszfI0T/M00RNFUTRNUxVd0RV10xZlUzZd0zVl01Vl1XZl2bZlW7d9WbZ93/d93/d93/d93/d939d1IDRkFQAgAQCgIzmSIimSIjmO40iSBISGrAIAZAAABACgKI7iOI4jSZIkWZImeZZniZqpmZ7pqaIKhIasAgAAAQAEAAAAAACgaIqnmIqniIrniI4oiZZpiZqquaJsyq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7ruq7rukBoyCoAQAIAQEdyJEdyJEVSJEVyJAcIDVkFAMgAAAgAwDEcQ1Ikx7IsTfM0T/M00RM90TM9VXRFFwgNWQUAAAIACAAAAAAAwJAMS7EczdEkUVIt1VI11VItVVQ9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV1TRN0zSB0JCVAAAZAAAjQQYZhBCKcpBCbj1YCDHmJAWhOQahxBiEpxAzDDkNInSQQSc9uJI5wwzz4FIoFURMg40lN44gDcKmXEnlOAhCQ1YEAFEAAIAxyDHEGHLOScmgRM4xCZ2UyDknpZPSSSktlhgzKSWmEmPjnKPSScmklBhLip2kEmOJrQAAgAAHAIAAC6HQkBUBQBQAAGIMUgophZRSzinmkFLKMeUcUko5p5xTzjkIHYTKMQadgxAppRxTzinHHITMQeWcg9BBKAAAIMABACDAQig0ZEUAECcA4HAkz5M0SxQlSxNFzxRl1xNN15U0zTQ1UVRVyxNV1VRV2xZNVbYlTRNNTfRUVRNFVRVV05ZNVbVtzzRl2VRV3RZV1bZl2xZ+V5Z13zNNWRZV1dZNVbV115Z9X9ZtXZg0zTQ1UVRVTRRV1VRV2zZV17Y1UXRVUVVlWVRVWXZlWfdVV9Z9SxRV1VNN2RVVVbZV2fVtVZZ94XRVXVdl2fdVWRZ+W9eF4fZ94RhV1dZN19V1VZZ9YdZlYbd13yhpmmlqoqiqmiiqqqmqtm2qrq1bouiqoqrKsmeqrqzKsq+rrmzrmiiqrqiqsiyqqiyrsqz7qizrtqiquq3KsrCbrqvrtu8LwyzrunCqrq6rsuz7qizruq3rxnHrujB8pinLpqvquqm6um7runHMtm0co6rqvirLwrDKsu/rui+0dSFRVXXdlF3jV2VZ921fd55b94WybTu/rfvKceu60vg5z28cubZtHLNuG7+t+8bzKz9hOI6lZ5q2baqqrZuqq+uybivDrOtCUVV9XZVl3zddWRdu3zeOW9eNoqrquirLvrDKsjHcxm8cuzAcXds2jlvXnbKtC31jyPcJz2vbxnH7OuP2daOvDAnHjwAAgAEHAIAAE8pAoSErAoA4AQAGIecUUxAqxSB0EFLqIKRUMQYhc05KxRyUUEpqIZTUKsYgVI5JyJyTEkpoKZTSUgehpVBKa6GU1lJrsabUYu0gpBZKaS2U0lpqqcbUWowRYxAy56RkzkkJpbQWSmktc05K56CkDkJKpaQUS0otVsxJyaCj0kFIqaQSU0mptVBKa6WkFktKMbYUW24x1hxKaS2kEltJKcYUU20txpojxiBkzknJnJMSSmktlNJa5ZiUDkJKmYOSSkqtlZJSzJyT0kFIqYOOSkkptpJKTKGU1kpKsYVSWmwx1pxSbDWU0lpJKcaSSmwtxlpbTLV1EFoLpbQWSmmttVZraq3GUEprJaUYS0qxtRZrbjHmGkppraQSW0mpxRZbji3GmlNrNabWam4x5hpbbT3WmnNKrdbUUo0txppjbb3VmnvvIKQWSmktlNJiai3G1mKtoZTWSiqxlZJabDHm2lqMOZTSYkmpxZJSjC3GmltsuaaWamwx5ppSi7Xm2nNsNfbUWqwtxppTS7XWWnOPufVWAADAgAMAQIAJZaDQkJUAQBQAAEGIUs5JaRByzDkqCULMOSepckxCKSlVzEEIJbXOOSkpxdY5CCWlFksqLcVWaykptRZrLQAAoMABACDABk2JxQEKDVkJAEQBACDGIMQYhAYZpRiD0BikFGMQIqUYc05KpRRjzknJGHMOQioZY85BKCmEUEoqKYUQSkklpQIAAAocAAACbNCUWByg0JAVAUAUAABgDGIMMYYgdFQyKhGETEonqYEQWgutddZSa6XFzFpqrbTYQAithdYySyXG1FpmrcSYWisAAOzAAQDswEIoNGQlAJAHAEAYoxRjzjlnEGLMOegcNAgx5hyEDirGnIMOQggVY85BCCGEzDkIIYQQQuYchBBCCKGDEEIIpZTSQQghhFJK6SCEEEIppXQQQgihlFIKAAAqcAAACLBRZHOCkaBCQ1YCAHkAAIAxSjkHoZRGKcYglJJSoxRjEEpJqXIMQikpxVY5B6GUlFrsIJTSWmw1dhBKaS3GWkNKrcVYa64hpdZirDXX1FqMteaaa0otxlprzbkAANwFBwCwAxtFNicYCSo0ZCUAkAcAgCCkFGOMMYYUYoox55xDCCnFmHPOKaYYc84555RijDnnnHOMMeecc845xphzzjnnHHPOOeecc44555xzzjnnnHPOOeecc84555xzzgkAACpwAAAIsFFkc4KRoEJDVgIAqQAAABFWYowxxhgbCDHGGGOMMUYSYowxxhhjbDHGGGOMMcaYYowxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY4wxxhhjjDHGGFtrrbXWWmuttdZaa6211lprrQBAvwoHAP8HG1ZHOCkaCyw0ZCUAEA4AABjDmHOOOQYdhIYp6KSEDkIIoUNKOSglhFBKKSlzTkpKpaSUWkqZc1JSKiWlllLqIKTUWkottdZaByWl1lJqrbXWOgiltNRaa6212EFIKaXWWostxlBKSq212GKMNYZSUmqtxdhirDGk0lJsLcYYY6yhlNZaazHGGGstKbXWYoy1xlprSam11mKLNdZaCwDgbnAAgEiwcYaVpLPC0eBCQ1YCACEBAARCjDnnnHMQQgghUoox56CDEEIIIURKMeYcdBBCCCGEjDHnoIMQQgghhJAx5hx0EEIIIYQQOucchBBCCKGEUkrnHHQQQgghlFBC6SCEEEIIoYRSSikdhBBCKKGEUkopJYQQQgmllFJKKaWEEEIIoYQSSimllBBCCKWUUkoppZQSQgghlFJKKaWUUkIIoZRQSimllFJKCCGEUkoppZRSSgkhhFBKKaWUUkopIYQSSimllFJKKaUAAIADBwCAACPoJKPKImw04cIDUGjISgCADAAAcdhq6ynWyCDFnISWS4SQchBiLhFSijlHsWVIGcUY1ZQxpRRTUmvonGKMUU+dY0oxw6yUVkookYLScqy1dswBAAAgCAAwECEzgUABFBjIAIADhAQpAKCwwNAxXAQE5BIyCgwKx4Rz0mkDABCEyAyRiFgMEhOqgaJiOgBYXGDIB4AMjY20iwvoMsAFXdx1IIQgBCGIxQEUkICDE2544g1PuMEJOkWlDgIAAAAA4AAAHgAAkg0gIiKaOY4Ojw+QEJERkhKTE5QAAAAAALABgA8AgCQFiIiIZo6jw+MDJERkhKTE5AQlAAAAAAAAAAAACAgIAAAAAAAEAAAACAhPZ2dTAAQYOwAAAAAAAOGpbkoCAAAAmc74DRgyNjM69TAzOTk74dnLubewsbagmZiNp4d0KbsExSY/I3XUTwJgkeZdn1HY4zoj33/q9DFtv3Ui1/jmx7lCUtPt18/sYf9MkgAsAGRBd3gMGP4sU+qCPYBy9VrA3YqJosW3W2/ef1iO/u3cg8ZG/57jU+pPmbGEJUgkfnaI39DbPqxddZphbMRmCc5rKlkUMkyx8iIoug5dJv1OYH9a59c+3Gevqc7Z2XFdDjL/qHztRfjWEWxJ/aiGezjohu9HsCZdQBKbiH0VtU/3m85lDG2T/+xkZcYnX+E+aqzv/xTgOoTFG+x7SNqQ4N+oAABSxuVXw77Jd5bmmTmuJakX7509HH0kGYKvARPpwfOSAPySPAc2EkneDwB2HwAAJlQDYK5586N79GJCjx4+p6aDUd27XSvRyXLJkIC5YZ1jLv5lpOhZTz0s+DmnF1diptrnM6UDgIW11Xh8cHTd0/SmbgOAdxcyWwMAAGIrZ3fNSfZbzKiYrK4+tPqtnMVLOeWOG2kVvUY+p2PJ/hkCl5aFRO4TLGYPZcIU3vYM1hohS4jHFlnyW/2T5J7kGsShXWT8N05V+3C/GPqJ1QdWisGPxEzHqXISBPIinWDUt7IeJv/f5OtzBxpTzZZQ+CYEhHXfqG4aABQli72GJhN4oJv+hXcApAJSErAW8G2raAX4NUcABnVt77CzZAB+LsHcVe+Q4h+QB1wh/ZrJTPxSBdI8mgTeAdTsQOoFUEng9BHcVPhxSRRYkKWZJXOFYP6V4AEripJoEjXgA2wJRZHSExmJDm8F0A6gEXsg5a4ZsALItrMB7+fh7UKLvYWSdtsDwFf1mzYzS1F82N1h2Oyt2e76B1QdS0SAsQigLPMOgJS9JRC7hFXA6kUsLFNKD5cA5cTRvgSqPc3Fl99xW3QTi/MHR8DEm6WnvaVQATwRqRKjywQ9BrrhugR2AKTsPQeQckrAOgDOhbTESyrXQ50CkNpXdtWjW7W2/3UjeX3U95gIdalfRAoAmqUEiwp53hCdcCwlg47fcbfzlmQMAgaBkh7c+fcDgF+ifwDXfzegLPcLYJsAAJQArTXjnh/uXGy3v1Hk3pV6/3t5ruW81f6prfbM2Q3WNVy98BwUtbCwhFhAWuPev6Oe/4ZaFQUcgKrVs4defzh1TADA1DEh5b3VlDaECw5b+bPfkKos3tIAue3vJZOih3ga3l6O3PSfIkrLv0PAS86PPdL7g8oc2KteNFKKzKRehOv2gJoFLBPXmaXvPBQILgJon0bbWBszrYZYYwE7jl2j+vTdU7Vpk21LiU0QajPkywAAHqbUC0/YsYOdb4e6BOp7E0cCi04Ao/TgD8ZVAMid6h/A8IeBNkp6/xsAACZELEYIk+yvI6Qz1NN6lIftB/6IMWjWJNOqPTMedAmyaj6Es0QBklJpiSWWHnQ2CoYbGWAmt+0gLQBFKCBnp2QUUQZ/1thtZDBJUpFWY82z34ocorB62oX7qB5y0oPAv/foxH25wVmgIHf2xFOr8leZcBq1Kx3ZvCq9Bga639AxuHuPNL/71YCF4EywJpqHFAX6XF0sjVbuANnvvdLcrufYwOM/iDa6iA468AYAAB6mNBMXcgTD8HSRqJ4vw8CjAlCEPACASlX/APwPOJKl9xQAAAPmnev2eWp33Xgyw3Dvfz6myGk3oyP8YTKsCOvzAgALQi0o1c6Nzs2O2Pg2h4ACIJAgAGP0aNn5x0BDgVfH7u2TtyfDcRIuYAyQhBF/lvSRAttgA6TPbWZA9gaUrZWAUEAA+Dx47Q3/r87HxUUqZmB0BmUuMlojFjHt1gDunnvuX8MImsjSq5WkzSzGS62OEIlOufWWezxWpv6FBgDgJVltfXFYtNAAnqU0xQoD0YLiXo5cF5QV4CnY1tBLAkZCOABAhbk/AM+/AwSCCdlWAAAMcFjS7owb8GVDzveDiZvznbt2tF4bL5odN1YKl88TAEABCZvufq9YCTBtMwVAQUEAwGtNltzSaHvADYC3TxLVjqiRA+OZAMhzcqEgRcAOwoCgvdTxsTHLQEF6+oOb2+PAI8ciPQcXg7pOY+LjxQSv2fjmFuj34gGwz310/bGK6z3xgT887eomWULEaDd04wHetYxdjcgV2SxvSwn0VoZXJRqkRC5ASQ/muVoAUsX7AgAQMBNaVwAAlABRxT/1PmfqLqSRNDbhXb07berpB3b94jpuWEZjBCD2OcdXFpCKEgCDfcFPMw8AAADUwT4lnUm50lmwrpMMhPQIKj6u0E8fr2vGBngMNdIlrZsigjahljud6AFVg+tzXwUnXL3TJLpajaWKA4VAAAAMiFfqJgKAZ08XrtS3dxtQNYcpPvYEG8ClvrQRJgBephwnNWJjtGqmp6VEPSvBe7EBiU3qgJbQAwD4Le8LAMDMhHbNAAAlgK+tFs5O+YyJc9yCnJa3rxLPulGnxwsXV9Fsk2k4PisCAHC8FkwbGE9gJQAAoMnyksj0CdFMZLLgoz8M+FxziwYBgIx+zHiCBAKAlBKNpF1sO9JpVcyEi9ar15YlHgrut5fPJnkdJ6vEwZPyAHQBIEDUrlMcBAAd2KAS0Qq+JwRsE4AJZtMnAD6GnOYwYlOIZvtzUNdjreB7fiMkWI0CmBB6AIAKc38A9osEFlTSGECB+cbeRDC0aRpLHqNPplcK/76Lxn2rpmqyXsYJWRi/FQAAAKBQk9MCAOibrQBQADCDsqpooPutd+05Ce9g6iEdiYXgVmQAI4+4wskEBEiBloNQ6Ki0/KTQ0QjWfjxzi+AeuXKoMjEVfQOZzr0y941qLgM2AExvbZOqcxZ6J6krlrj4y2j9AdgKDx6GnJsVLhbc42uq584+ouSdNBpoCiCVHrz+WzUA/DDtD8ATgA3h0lMCAAzcFv+S+fSSNkeYWlTpb34mf2RfmqqJeMeklhHAfu7VoAEACgAApKRktL+KkQDWMwYCUAAAAHCKsp80xhp91UjqQBw3x45cetqkjQEyu3G9B6N+R650Uq8OVig7wOm6Wun0ea4lKDPoabJs6aLqgbhPzpv4KR4iODilw88ZpY7q1IOMcbASAOAVtmcCnobcrkG4KGS7/ZnskVWRNF9J0RUHKOnByy9WA8Dv6L4AAARMCQUA4GritfVM2lcZfH3Q3T/vZ47J2YHhcmBazjfdyuV25gLAzrc0cwAAAAAYCh6PdwAAAGyWjFW4yScjaWa2mGcofHxWxewKALglWBpLUvwwk+UOh5eNGyUOs1/EF+pZr+ud5OzoGwYdAABg2p52LiSgAY/ZVlOmilEgHn6G3OcwYjzI7vOj1t6xsx4S3lBY96EUQBF6AIBAmPYH4PoGYCoJAADWe+OZJZi7/x76/yH7Lzf9M5XzRKnFPmveMsilQHwVAAAAAKB3LQD8PCIAAADga0QujBLywzeJ4a6Z/ERVBAUlAEDqvoM7BQBAuAguzFqILtmjH3Kd4wfKobnOhA3z85qWoRPm9hwoOHoDAAlCbwDAA56FHAuXflHo3fe2ttG9XUDeA9YmYCBQ0oPr/1QC8IvuCwAAApbUAQCK22MmE3O78VAbHQT9PIPNoT9zNc3l2Oe7TAVLANBufT8MAQAAAGzT4PS8AQAAoELGHb2uaCwwEv1EWhFriUkbAaAZ27/fVZnTZXbWz3BwWpjUaMZKRj7dZ0J//gUeTdpVEwAAZOFsNxKAjQSgA+ABPoY8Jj5y2wje81jsXc/1TOQWTDYZBmAkNDiqVwuA2NJ9AQAAEBKAt9Vrsfs/2N19MO91S9rd8EHTZHnzC5MYmfQEACy/FBcAAADA5c4gi4z8RANs/m6FNXVo9DV46JG1BBDukqlw/Va5G7QbuGVSI+2aZaoLXJrdVj2zlC9Z5QEAEFz/5QzgVZwAAAAA/oXcxyC6WfTu+09Ve/c766J4VTAGUFmA51+VANKi/QPoPwYgYAkA715OH4S0s5KDHvj99MMq8TPFc3roKZnGOoT1bmIhVgc7XAMBAAAAAMAW1VbQw3gapzOpJd+Kd2fc4iSO62fJv9+movui1wUNPAj059N3OVxzk4gV73PmE8FIA2F5mRq37Evc76vLXfF4rD5UJJAw46hW6LZCb5sNLdx+kzMCAAB+hfy95+965ZCLP7B3/VlTHCvDEKtQhTm4KiCgAEAbrfbWTPssAAAAXpee1tVrozYYn41wD1aeYtkKfswN5/SXPO0JDnhO/4laUortv/s412fybe/nONdncoCHnBVliu0CQGBWlPY/5Kwom2L/kruPM6Q7oz4tvDQy+bZ3HzOi+gNHA4DZEgA='),
+  lib.resource.add(
+      'hterm/concat/date', 'text/plain', 'Tue, 25 Apr 2017 15:12:45 +0000'),
+  lib.resource.add('hterm/changelog/version', 'text/plain', '1.62'),
+  lib.resource.add('hterm/changelog/date', 'text/plain', '2017-04-17'),
+  lib.resource.add('hterm/git/HEAD', 'text/plain', 'git rev-parse HEAD');
diff --git a/karma.conf.js b/karma.conf.js
index 3707578..0b56d6f 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -37,22 +37,12 @@
     singleRun: true,
 
     // Configure code coverage reporter
-    coverageReporter: {
-      dir: 'coverage/',
-      reporters: [{
-          type: 'text-summary'
-        },
-        {
-          type: 'html'
-        }
-      ]
-    },
+    coverageReporter:
+        {dir: 'coverage/', reporters: [{type: 'text-summary'}, {type: 'html'}]},
 
     webpack: require('./webpack.config'),
 
     // Hide webpack build information from output
-    webpackMiddleware: {
-      noInfo: 'errors-only'
-    }
+    webpackMiddleware: {noInfo: 'errors-only'}
   });
 };
diff --git a/postcss.config.js b/postcss.config.js
index 3691590..c3d6ea6 100644
--- a/postcss.config.js
+++ b/postcss.config.js
@@ -1,7 +1,5 @@
 module.exports = {
   plugins: {
-    autoprefixer: {
-      browsers: ['last 2 versions']
-    },
+    autoprefixer: {browsers: ['last 2 versions']},
   },
 };
diff --git a/webpack.config.js b/webpack.config.js
index 63ddda2..b82bbb9 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -20,208 +20,190 @@
 var isTest = ENV === 'test' || ENV === 'test-watch';
 var isProd = ENV === 'build';
 
-module.exports = [
-  function makeWebpackConfig() {
-    /**
-     * Config
-     * Reference: http://webpack.github.io/docs/configuration.html
-     * This is the object where all configuration gets set
-     */
-    var config = {};
+module.exports = [function makeWebpackConfig() {
+  /**
+   * Config
+   * Reference: http://webpack.github.io/docs/configuration.html
+   * This is the object where all configuration gets set
+   */
+  var config = {};
 
-    /**
-     * Entry
-     * Reference: http://webpack.github.io/docs/configuration.html#entry
-     * Should be an empty object if it's generating a test build
-     * Karma will set this when it's a test build
-     */
-    config.entry = isTest ? void 0 : {
-      app: './app/index.js'
+  /**
+   * Entry
+   * Reference: http://webpack.github.io/docs/configuration.html#entry
+   * Should be an empty object if it's generating a test build
+   * Karma will set this when it's a test build
+   */
+  config.entry = isTest ? void 0 : {
+    app: './app/index.js'
 
-    };
+  };
 
-    /**
-     * Output
-     * Reference: http://webpack.github.io/docs/configuration.html#output
-     * Should be an empty object if it's generating a test build
-     * Karma will handle setting it up for you when it's a test build
-     */
-    config.output = isTest ? {} : {
-      // Absolute output directory
-      path: __dirname + '/dist',
+  /**
+   * Output
+   * Reference: http://webpack.github.io/docs/configuration.html#output
+   * Should be an empty object if it's generating a test build
+   * Karma will handle setting it up for you when it's a test build
+   */
+  config.output = isTest ? {} : {
+    // Absolute output directory
+    path: __dirname + '/dist',
 
-      // Output path from the view of the page
-      // Uses webpack-dev-server in development
-      publicPath: '/',
+    // Output path from the view of the page
+    // Uses webpack-dev-server in development
+    publicPath: '/',
 
-      // Filename for entry points
-      // Only adds hash in build mode
-      filename: isProd ? '[name].[hash].js' : '[name].bundle.js',
+    // Filename for entry points
+    // Only adds hash in build mode
+    filename: isProd ? '[name].[hash].js' : '[name].bundle.js',
 
-      // Filename for non-entry points
-      // Only adds hash in build mode
-      chunkFilename: isProd ? '[name].[hash].js' : '[name].bundle.js'
-    };
+    // Filename for non-entry points
+    // Only adds hash in build mode
+    chunkFilename: isProd ? '[name].[hash].js' : '[name].bundle.js'
+  };
 
-    /**
-     * Devtool
-     * Reference: http://webpack.github.io/docs/configuration.html#devtool
-     * Type of sourcemap to use per build type
-     */
-    if (isTest) {
-      https:
+  /**
+   * Devtool
+   * Reference: http://webpack.github.io/docs/configuration.html#devtool
+   * Type of sourcemap to use per build type
+   */
+  if (isTest) {
+    https:
         // unix.stackexchange.com/questions/144208/find-files-without-extension
         config.devtool = 'inline-source-map';
-    }
-    else if (isProd) {
-      config.devtool = 'source-map';
-    }
-    else {
-      config.devtool = 'eval-source-map';
-    }
+  } else if (isProd) {
+    config.devtool = 'source-map';
+  } else {
+    config.devtool = 'eval-source-map';
+  }
 
-    /**
-     * Loaders
-     * Reference:
-     * http://webpack.github.io/docs/configuration.html#module-loaders
-     * List: http://webpack.github.io/docs/list-of-loaders.html
-     * This handles most of the magic responsible for converting modules
-     */
+  /**
+   * Loaders
+   * Reference:
+   * http://webpack.github.io/docs/configuration.html#module-loaders
+   * List: http://webpack.github.io/docs/list-of-loaders.html
+   * This handles most of the magic responsible for converting modules
+   */
 
-    // Initialize module
-    config.module = {
-      rules: [{
-          // JS LOADER
-          // Reference: https://github.com/babel/babel-loader
-          // Transpile .js files using babel-loader
-          // Compiles ES6 and ES7 into ES5 code
-          test: /\.js$/,
-          use: 'babel-loader',
-          exclude: /node_modules/
-        },
-        {
-          // CSS LOADER
-          // Reference: https://github.com/webpack/css-loader
-          // Allow loading css through js
-          //
-          // Reference: https://github.com/postcss/postcss-loader
-          // Postprocess your css with PostCSS plugins
-          test: /\.css$/,
-          // Reference: https://github.com/webpack/extract-text-webpack-plugin
-          // Extract css files in production builds
-          //
-          // Reference: https://github.com/webpack/style-loader
-          // Use style-loader in development.
-
-          loader: isTest ? 'null-loader' : ExtractTextPlugin.extract({
-            fallback: 'style-loader',
-            use: [{
-                loader: 'css-loader',
-                query: {
-                  sourceMap: true
-                }
-              },
-              {
-                loader: 'postcss-loader'
-              }
-            ],
-          })
-        },
-        {
-          // ASSET LOADER
-          // Reference: https://github.com/webpack/file-loader
-          // Copy png, jpg, jpeg, gif, svg, woff, woff2, ttf, eot files to
-          // output
-          // Rename the file using the asset hash
-          // Pass along the updated reference to your code
-          // You can add here any file extension you want to get copied to your
-          // output
-          test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot|ico)$/,
-          loader: 'file-loader',
-          options: {
-            name(file) {
-              if (!isProd) {
-                return '[path][name].[ext]';
-              }
-
-              return '[hash].[ext]';
-            }
-          }
-        },
-        {
-          // HTML LOADER
-          // Reference: https://github.com/webpack/raw-loader
-          // Allow loading html through js
-          test: /\.html$/,
-          use: {
-            loader: 'html-loader'
-          }
-        },
-        // JSON LOADER
-        {
-          test: /\.json$/,
-          loader: 'json-loader'
-        }, {
-          test: /\.scss$/,
-          use: [{
-              loader: 'style-loader' // creates style nodes from JS strings
-            },
-            {
-              loader: 'css-loader' // translates CSS into CommonJS
-            },
-            {
-              loader: 'sass-loader' // compiles Sass to CSS
-            }
-          ]
-        }
-      ]
-    };
-
-    // ISTANBUL LOADER
-    // https://github.com/deepsweet/istanbul-instrumenter-loader
-    // Instrument JS files with istanbul-lib-instrument for subsequent code
-    // coverage reporting
-    // Skips node_modules and files that end with .spec.js
-    if (isTest) {
-      config.module.rules.push({
-        enforce: 'pre',
+  // Initialize module
+  config.module = {
+    rules: [
+      {
+        // JS LOADER
+        // Reference: https://github.com/babel/babel-loader
+        // Transpile .js files using babel-loader
+        // Compiles ES6 and ES7 into ES5 code
         test: /\.js$/,
-        exclude: [/node_modules/, /\.spec\.js$/],
-        loader: 'istanbul-instrumenter-loader',
-        query: {
-          esModules: true
-        }
-      });
-    }
+        use: 'babel-loader',
+        exclude: /node_modules/
+      },
+      {
+        // CSS LOADER
+        // Reference: https://github.com/webpack/css-loader
+        // Allow loading css through js
+        //
+        // Reference: https://github.com/postcss/postcss-loader
+        // Postprocess your css with PostCSS plugins
+        test: /\.css$/,
+        // Reference: https://github.com/webpack/extract-text-webpack-plugin
+        // Extract css files in production builds
+        //
+        // Reference: https://github.com/webpack/style-loader
+        // Use style-loader in development.
 
-    /**
-     * PostCSS
-     * Reference: https://github.com/postcss/autoprefixer-core
-     * Add vendor prefixes to your css
-     */
-    // NOTE: This is now handled in the `postcss.config.js`
-    //       webpack2 has some issues, making the config file necessary
+        loader: isTest ? 'null-loader' : ExtractTextPlugin.extract({
+          fallback: 'style-loader',
+          use: [
+            {loader: 'css-loader', query: {sourceMap: true}},
+            {loader: 'postcss-loader'}
+          ],
+        })
+      },
+      {
+        // ASSET LOADER
+        // Reference: https://github.com/webpack/file-loader
+        // Copy png, jpg, jpeg, gif, svg, woff, woff2, ttf, eot files to
+        // output
+        // Rename the file using the asset hash
+        // Pass along the updated reference to your code
+        // You can add here any file extension you want to get copied to your
+        // output
+        test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot|ico)$/,
+        loader: 'file-loader',
+        options: {
+          name(file) {
+            if (!isProd) {
+              return '[path][name].[ext]';
+            }
 
-    /**
-     * Plugins
-     * Reference: http://webpack.github.io/docs/configuration.html#plugins
-     * List: http://webpack.github.io/docs/list-of-plugins.html
-     */
-    config.plugins = [new webpack.LoaderOptionsPlugin({
-      test: /\.scss$/i,
-      options: {
-        postcss: {
-          plugins: [autoprefixer]
+            return '[hash].[ext]';
+          }
         }
       },
-      debug: !isProd
-    })];
+      {
+        // HTML LOADER
+        // Reference: https://github.com/webpack/raw-loader
+        // Allow loading html through js
+        test: /\.html$/,
+        use: {loader: 'html-loader'}
+      },
+      // JSON LOADER
+      {test: /\.json$/, loader: 'json-loader'}, {
+        test: /\.scss$/,
+        use: [
+          {
+            loader: 'style-loader'  // creates style nodes from JS strings
+          },
+          {
+            loader: 'css-loader'  // translates CSS into CommonJS
+          },
+          {
+            loader: 'sass-loader'  // compiles Sass to CSS
+          }
+        ]
+      }
+    ]
+  };
 
-    // Skip rendering index.html in test mode
-    if (!isTest) {
-      // Reference: https://github.com/ampedandwired/html-webpack-plugin
-      // Render index.html
-      config.plugins.push(
+  // ISTANBUL LOADER
+  // https://github.com/deepsweet/istanbul-instrumenter-loader
+  // Instrument JS files with istanbul-lib-instrument for subsequent code
+  // coverage reporting
+  // Skips node_modules and files that end with .spec.js
+  if (isTest) {
+    config.module.rules.push({
+      enforce: 'pre',
+      test: /\.js$/,
+      exclude: [/node_modules/, /\.spec\.js$/],
+      loader: 'istanbul-instrumenter-loader',
+      query: {esModules: true}
+    });
+  }
+
+  /**
+   * PostCSS
+   * Reference: https://github.com/postcss/autoprefixer-core
+   * Add vendor prefixes to your css
+   */
+  // NOTE: This is now handled in the `postcss.config.js`
+  //       webpack2 has some issues, making the config file necessary
+
+  /**
+   * Plugins
+   * Reference: http://webpack.github.io/docs/configuration.html#plugins
+   * List: http://webpack.github.io/docs/list-of-plugins.html
+   */
+  config.plugins = [new webpack.LoaderOptionsPlugin({
+    test: /\.scss$/i,
+    options: {postcss: {plugins: [autoprefixer]}},
+    debug: !isProd
+  })];
+
+  // Skip rendering index.html in test mode
+  if (!isTest) {
+    // Reference: https://github.com/ampedandwired/html-webpack-plugin
+    // Render index.html
+    config.plugins.push(
         new HtmlWebpackPlugin({
           template: './app/index.html',
           inject: 'body',
@@ -231,46 +213,31 @@
         // Reference: https://github.com/webpack/extract-text-webpack-plugin
         // Extract css files
         // Disabled when in test mode or not in build mode
-        new ExtractTextPlugin({
-          filename: 'css/[name].css',
-          disable: !isProd,
-          allChunks: true
-        }));
-    }
+        new ExtractTextPlugin(
+            {filename: 'css/[name].css', disable: !isProd, allChunks: true}));
+  }
 
-    // Add build specific plugins
-    if (isProd) {
-      config.plugins.push(
+  // Add build specific plugins
+  if (isProd) {
+    config.plugins.push(
         // Reference:
         // http://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin
         // Minify all javascript, switch loaders to minimizing mode
         // TODO: openbmc/openbmc#2871  Mangling currently breaks the GUI.
-        new UglifyJsPlugin({
-          uglifyOptions: {
-            mangle: false
-          }
-        }),
+        new UglifyJsPlugin({uglifyOptions: {mangle: false}}),
 
         // Copy assets from the public folder
         // Reference: https://github.com/kevlened/copy-webpack-plugin
-        new CopyWebpackPlugin([{
-          from: __dirname + '/app/assets'
-        }]),
-        new CompressionPlugin({
-          deleteOriginalAssets: true
-        }));
-    }
+        new CopyWebpackPlugin([{from: __dirname + '/app/assets'}]),
+        new CompressionPlugin({deleteOriginalAssets: true}));
+  }
 
-    /**
-     * Dev server configuration
-     * Reference: http://webpack.github.io/docs/configuration.html#devserver
-     * Reference: http://webpack.github.io/docs/webpack-dev-server.html
-     */
-    config.devServer = {
-      contentBase: './src/public',
-      stats: 'minimal'
-    };
+  /**
+   * Dev server configuration
+   * Reference: http://webpack.github.io/docs/configuration.html#devserver
+   * Reference: http://webpack.github.io/docs/webpack-dev-server.html
+   */
+  config.devServer = {contentBase: './src/public', stats: 'minimal'};
 
-    return config;
-  }()
-];
+  return config;
+}()];