diff --git a/static/js/bmcApp.js b/static/js/bmcApp.js
index 7392c47..1c91e8f 100644
--- a/static/js/bmcApp.js
+++ b/static/js/bmcApp.js
@@ -1,17 +1,46 @@
 'use strict';
 angular.module('Authentication', []);
 var app = angular.module('bmcApp', [
-  'Authentication', 'ngCookies', 'ui.bootstrap', 'ui.router', 'restangular',
-  'ngSanitize', 'ngWebSocket'
+  'Authentication', 'ngCookies', 'ui.bootstrap', 'ui.router',
+  'ngSanitize', 'ngWebSocket', 'ngResource'
 ]);
 
 
-app.controller('MainCtrl', function($scope, Restangular) {
+app.controller('MainCtrl', function($scope) {
 
 });
 
-app.run(['$rootScope', '$cookieStore', '$state', 'Restangular', 'AuthenticationService',
-  function($rootScope, $cookieStore, $state, Restangular, AuthenticationService) {
+app.service('loginInterceptor', function($q, $state) {
+    var service = this;
+
+    service.responseError = function(response) {
+        if (response.status == 401){
+          console.log("Login required... ");
+
+          var invalidate_reason = "Your user was logged out.";
+          var continue_promise_chain = false;
+
+          // if we're attempting to log in, we need to
+          // continue the promise chain to make sure the user is informed
+          if ($state.current.name === "login") {
+            invalidate_reason = "Your username and password was incorrect";
+            continue_promise_chain = true
+          } else {
+            $state.after_login_state = $state.current.name;
+            $state.go('login');
+          }
+          AuthenticationService.ClearCredentials(invalidate_reason);
+        }
+        //return $q.reject(response);
+    };
+})
+
+app.config(['$httpProvider', function ($httpProvider) {
+    $httpProvider.interceptors.push('loginInterceptor');
+}]);
+
+app.run(['$rootScope', '$cookieStore', '$state', '$resource', 'AuthenticationService',
+  function($rootScope, $cookieStore, $state, $resource, AuthenticationService) {
     if ($rootScope.globals == undefined){
         $rootScope.globals = {};
     }
@@ -29,49 +58,9 @@
             $state.go('login');
           }
         });
-
-    // RestangularProvider.setDefaultHttpFields({cache: true});
-    Restangular.setErrorInterceptor(function(response) {
-      if (response.status == 401) {
-        console.log("Login required... ");
-
-        var invalidate_reason = "Your user was logged out.";
-        var continue_promise_chain = false;
-
-        // if we're attempting to log in, we need to
-        // continue the promise chain to make sure the user is informed
-        if ($state.current.name === "login") {
-          invalidate_reason = "Your username and password was incorrect";
-          continue_promise_chain = true
-        } else {
-          $state.after_login_state = $state.current.name;
-          $state.go('login');
-        }
-        AuthenticationService.ClearCredentials(invalidate_reason);
-
-        return continue_promise_chain;  // stop the promise chain
-      } else if (response.status == 404) {
-        console.log("Resource not available...");
-      } else {
-        console.log(
-            "Response received with HTTP error code: " + response.status);
-      }
-
-    });
-
   }
 ]);
 
-app.config(function(RestangularProvider) {
-  // set the base url for api calls on our RESTful services
-  var newBaseUrl = "";
-
-  var deployedAt = window.location.href.substring(0, window.location.href);
-  newBaseUrl = deployedAt + "/restui";
-
-  RestangularProvider.setBaseUrl(newBaseUrl);
-});
-
 app.config(function($stateProvider, $urlRouterProvider) {
 
   $urlRouterProvider.otherwise('/systeminfo');
@@ -80,30 +69,30 @@
       // nested list with just some random string data
       .state('login', {
         url: '/login',
-        templateUrl: 'login.html',
+        templateUrl: 'static/login.html',
         controller: 'LoginController',
       })
       // systeminfo view ========================================
       .state(
           'systeminfo',
-          {url: '/systeminfo', templateUrl: 'partial-systeminfo.html'})
+          {url: '/systeminfo', templateUrl: 'static/partial-systeminfo.html'})
 
 
       // HOME STATES AND NESTED VIEWS ========================================
       .state(
-          'eventlog', {url: '/eventlog', templateUrl: 'partial-eventlog.html'})
+          'eventlog', {url: '/eventlog', templateUrl: 'static/partial-eventlog.html'})
 
 
       .state(
-          'kvm', {url: '/kvm', templateUrl: 'partial-kvm.html'})
+          'kvm', {url: '/kvm', templateUrl: 'static/partial-kvm.html'})
 
       // ABOUT PAGE AND MULTIPLE NAMED VIEWS =================================
-      .state('about', {url: '/about', templateUrl: 'partial-fruinfo.html'})
+      .state('about', {url: '/about', templateUrl: 'static/partial-fruinfo.html'})
 
       // nested list with custom controller
       .state('about.list', {
         url: '/list',
-        templateUrl: 'partial-home-list.html',
+        templateUrl: 'static/partial-home-list.html',
         controller: function($scope) {
           $scope.dogs = ['Bernese', 'Husky', 'Goldendoodle'];
         }
@@ -127,22 +116,22 @@
   $scope.bigCurrentPage = 1;
 });
 
-angular
-    .module('Authentication')
+angular.module('Authentication')
 
     .factory(
         'AuthenticationService',
-        [
-          'Restangular', '$cookieStore', '$rootScope', '$timeout',
-          function(Restangular, $cookieStore, $rootScope, $timeout) {
+        ['$cookieStore', '$rootScope', '$timeout', '$resource', '$log',
+          function($cookieStore, $rootScope, $timeout, $resource, $log) {
             var service = {};
 
-            service.Login = function(
-                username, password, success_callback, fail_callback) {
+            service.Login = function(username, password, success_callback, fail_callback) {
 
               var user = {"username": username, "password": password};
-              Restangular.all("login").post(user).then(
-                  success_callback, fail_callback);
+              var UserLogin = $resource("/login");
+              var this_login = new UserLogin();
+              this_login.data = {"username": username, "password": password};
+              UserLogin.save(user, success_callback, fail_callback);
+              
             };
 
             service.SetCredentials = function(username, token) {
diff --git a/static/js/logincontroller.js b/static/js/logincontroller.js
index d0b7a7f..e83d8bc 100644
--- a/static/js/logincontroller.js
+++ b/static/js/logincontroller.js
@@ -29,4 +29,4 @@
             });
     };
     }
-]);
\ No newline at end of file
+]);
diff --git a/static/js/restangular.js b/static/js/restangular.js
deleted file mode 100644
index b59b25f..0000000
--- a/static/js/restangular.js
+++ /dev/null
@@ -1,1452 +0,0 @@
-/**
- * Restful Resources service for AngularJS apps
- * @version v1.6.1 - 2017-01-06 * @link https://github.com/mgonto/restangular
- * @author Martin Gontovnikas <martin@gon.to>
- * @license MIT License, http://www.opensource.org/licenses/MIT
- */(function(root, factory) {
-  /* global define, require */
-  // https://github.com/umdjs/umd/blob/master/templates/returnExports.js
-  if (typeof define === 'function' && define.amd) {
-    define(['lodash', 'angular'], factory);
-  } else if (typeof module === 'object' && module.exports) {
-    module.exports = factory(require('lodash'), require('angular'));
-  } else {
-    // No global export, Restangular will register itself as Angular.js module
-    factory(root._, root.angular);
-  }
-}(this, function(_, angular) {
-
-  var restangular = angular.module('restangular', []);
-
-  restangular.provider('Restangular', function() {
-    // Configuration
-    var Configurer = {};
-    Configurer.init = function(object, config) {
-      object.configuration = config;
-
-      /**
-       * Those are HTTP safe methods for which there is no need to pass any data with the request.
-       */
-      var safeMethods = ['get', 'head', 'options', 'trace', 'getlist'];
-      config.isSafe = function(operation) {
-        return _.includes(safeMethods, operation.toLowerCase());
-      };
-
-      var absolutePattern = /^https?:\/\//i;
-      config.isAbsoluteUrl = function(string) {
-        return _.isUndefined(config.absoluteUrl) || _.isNull(config.absoluteUrl) ?
-          string && absolutePattern.test(string) :
-          config.absoluteUrl;
-      };
-
-      config.absoluteUrl = _.isUndefined(config.absoluteUrl) ? true : config.absoluteUrl;
-      object.setSelfLinkAbsoluteUrl = function(value) {
-        config.absoluteUrl = value;
-      };
-      /**
-       * This is the BaseURL to be used with Restangular
-       */
-      config.baseUrl = _.isUndefined(config.baseUrl) ? '' : config.baseUrl;
-      object.setBaseUrl = function(newBaseUrl) {
-        config.baseUrl = /\/$/.test(newBaseUrl) ?
-          newBaseUrl.substring(0, newBaseUrl.length - 1) :
-          newBaseUrl;
-        return this;
-      };
-
-      /**
-       * Sets the extra fields to keep from the parents
-       */
-      config.extraFields = config.extraFields || [];
-      object.setExtraFields = function(newExtraFields) {
-        config.extraFields = newExtraFields;
-        return this;
-      };
-
-      /**
-       * Some default $http parameter to be used in EVERY call
-       **/
-      config.defaultHttpFields = config.defaultHttpFields || {};
-      object.setDefaultHttpFields = function(values) {
-        config.defaultHttpFields = values;
-        return this;
-      };
-
-      /**
-       * Always return plain data, no restangularized object
-       **/
-      config.plainByDefault = config.plainByDefault || false;
-      object.setPlainByDefault = function(value) {
-        config.plainByDefault = value === true ? true : false;
-        return this;
-      };
-
-      config.withHttpValues = function(httpLocalConfig, obj) {
-        return _.defaults(obj, httpLocalConfig, config.defaultHttpFields);
-      };
-
-      config.encodeIds = _.isUndefined(config.encodeIds) ? true : config.encodeIds;
-      object.setEncodeIds = function(encode) {
-        config.encodeIds = encode;
-      };
-
-      config.defaultRequestParams = config.defaultRequestParams || {
-        get: {},
-        post: {},
-        put: {},
-        remove: {},
-        common: {}
-      };
-
-      object.setDefaultRequestParams = function(param1, param2) {
-        var methods = [],
-          params = param2 || param1;
-        if (!_.isUndefined(param2)) {
-          if (_.isArray(param1)) {
-            methods = param1;
-          } else {
-            methods.push(param1);
-          }
-        } else {
-          methods.push('common');
-        }
-
-        _.each(methods, function(method) {
-          config.defaultRequestParams[method] = params;
-        });
-        return this;
-      };
-
-      object.requestParams = config.defaultRequestParams;
-
-      config.defaultHeaders = config.defaultHeaders || {};
-      object.setDefaultHeaders = function(headers) {
-        config.defaultHeaders = headers;
-        object.defaultHeaders = config.defaultHeaders;
-        return this;
-      };
-
-      object.defaultHeaders = config.defaultHeaders;
-
-      /**
-       * Method overriders will set which methods are sent via POST with an X-HTTP-Method-Override
-       **/
-      config.methodOverriders = config.methodOverriders || [];
-      object.setMethodOverriders = function(values) {
-        var overriders = _.extend([], values);
-        if (config.isOverridenMethod('delete', overriders)) {
-          overriders.push('remove');
-        }
-        config.methodOverriders = overriders;
-        return this;
-      };
-
-      config.jsonp = _.isUndefined(config.jsonp) ? false : config.jsonp;
-      object.setJsonp = function(active) {
-        config.jsonp = active;
-      };
-
-      config.isOverridenMethod = function(method, values) {
-        var search = values || config.methodOverriders;
-        return !_.isUndefined(_.find(search, function(one) {
-          return one.toLowerCase() === method.toLowerCase();
-        }));
-      };
-
-      /**
-       * Sets the URL creator type. For now, only Path is created. In the future we'll have queryParams
-       **/
-      config.urlCreator = config.urlCreator || 'path';
-      object.setUrlCreator = function(name) {
-        if (!_.has(config.urlCreatorFactory, name)) {
-          throw new Error('URL Path selected isn\'t valid');
-        }
-
-        config.urlCreator = name;
-        return this;
-      };
-
-      /**
-       * You can set the restangular fields here. The 3 required fields for Restangular are:
-       *
-       * id: Id of the element
-       * route: name of the route of this element
-       * parentResource: the reference to the parent resource
-       *
-       *  All of this fields except for id, are handled (and created) by Restangular. By default,
-       *  the field values will be id, route and parentResource respectively
-       */
-      config.restangularFields = config.restangularFields || {
-        id: 'id',
-        route: 'route',
-        parentResource: 'parentResource',
-        restangularCollection: 'restangularCollection',
-        cannonicalId: '__cannonicalId',
-        etag: 'restangularEtag',
-        selfLink: 'href',
-        get: 'get',
-        getList: 'getList',
-        put: 'put',
-        post: 'post',
-        remove: 'remove',
-        head: 'head',
-        trace: 'trace',
-        options: 'options',
-        patch: 'patch',
-        getRestangularUrl: 'getRestangularUrl',
-        getRequestedUrl: 'getRequestedUrl',
-        putElement: 'putElement',
-        addRestangularMethod: 'addRestangularMethod',
-        getParentList: 'getParentList',
-        clone: 'clone',
-        ids: 'ids',
-        httpConfig: '_$httpConfig',
-        reqParams: 'reqParams',
-        one: 'one',
-        all: 'all',
-        several: 'several',
-        oneUrl: 'oneUrl',
-        allUrl: 'allUrl',
-        customPUT: 'customPUT',
-        customPATCH: 'customPATCH',
-        customPOST: 'customPOST',
-        customDELETE: 'customDELETE',
-        customGET: 'customGET',
-        customGETLIST: 'customGETLIST',
-        customOperation: 'customOperation',
-        doPUT: 'doPUT',
-        doPATCH: 'doPATCH',
-        doPOST: 'doPOST',
-        doDELETE: 'doDELETE',
-        doGET: 'doGET',
-        doGETLIST: 'doGETLIST',
-        fromServer: 'fromServer',
-        withConfig: 'withConfig',
-        withHttpConfig: 'withHttpConfig',
-        singleOne: 'singleOne',
-        plain: 'plain',
-        save: 'save',
-        restangularized: 'restangularized'
-      };
-      object.setRestangularFields = function(resFields) {
-        config.restangularFields =
-          _.extend(config.restangularFields, resFields);
-        return this;
-      };
-
-      config.isRestangularized = function(obj) {
-        return !!obj[config.restangularFields.restangularized];
-      };
-
-      config.setFieldToElem = function(field, elem, value) {
-        var properties = field.split('.');
-        var idValue = elem;
-        _.each(_.initial(properties), function(prop) {
-          idValue[prop] = {};
-          idValue = idValue[prop];
-        });
-        idValue[_.last(properties)] = value;
-        return this;
-      };
-
-      config.getFieldFromElem = function(field, elem) {
-        var properties = field.split('.');
-        var idValue = elem;
-        _.each(properties, function(prop) {
-          if (idValue) {
-            idValue = idValue[prop];
-          }
-        });
-        return angular.copy(idValue);
-      };
-
-      config.setIdToElem = function(elem, id /*, route */ ) {
-        config.setFieldToElem(config.restangularFields.id, elem, id);
-        return this;
-      };
-
-      config.getIdFromElem = function(elem) {
-        return config.getFieldFromElem(config.restangularFields.id, elem);
-      };
-
-      config.isValidId = function(elemId) {
-        return '' !== elemId && !_.isUndefined(elemId) && !_.isNull(elemId);
-      };
-
-      config.setUrlToElem = function(elem, url /*, route */ ) {
-        config.setFieldToElem(config.restangularFields.selfLink, elem, url);
-        return this;
-      };
-
-      config.getUrlFromElem = function(elem) {
-        return config.getFieldFromElem(config.restangularFields.selfLink, elem);
-      };
-
-      config.useCannonicalId = _.isUndefined(config.useCannonicalId) ? false : config.useCannonicalId;
-      object.setUseCannonicalId = function(value) {
-        config.useCannonicalId = value;
-        return this;
-      };
-
-      config.getCannonicalIdFromElem = function(elem) {
-        var cannonicalId = elem[config.restangularFields.cannonicalId];
-        var actualId = config.isValidId(cannonicalId) ? cannonicalId : config.getIdFromElem(elem);
-        return actualId;
-      };
-
-      /**
-       * Sets the Response parser. This is used in case your response isn't directly the data.
-       * For example if you have a response like {meta: {'meta'}, data: {name: 'Gonto'}}
-       * you can extract this data which is the one that needs wrapping
-       *
-       * The ResponseExtractor is a function that receives the response and the method executed.
-       */
-
-      config.responseInterceptors = config.responseInterceptors || [];
-
-      config.defaultResponseInterceptor = function(data /*, operation, what, url, response, deferred */ ) {
-        return data;
-      };
-
-      config.responseExtractor = function(data, operation, what, url, response, deferred) {
-        var interceptors = angular.copy(config.responseInterceptors);
-        interceptors.push(config.defaultResponseInterceptor);
-        var theData = data;
-        _.each(interceptors, function(interceptor) {
-          theData = interceptor(theData, operation,
-            what, url, response, deferred);
-        });
-        return theData;
-      };
-
-      object.addResponseInterceptor = function(extractor) {
-        config.responseInterceptors.push(extractor);
-        return this;
-      };
-
-      config.errorInterceptors = config.errorInterceptors || [];
-      object.addErrorInterceptor = function(interceptor) {
-        config.errorInterceptors.push(interceptor);
-        return this;
-      };
-
-      object.setResponseInterceptor = object.addResponseInterceptor;
-      object.setResponseExtractor = object.addResponseInterceptor;
-      object.setErrorInterceptor = object.addErrorInterceptor;
-
-      /**
-       * Response interceptor is called just before resolving promises.
-       */
-
-
-      /**
-       * Request interceptor is called before sending an object to the server.
-       */
-      config.requestInterceptors = config.requestInterceptors || [];
-
-      config.defaultInterceptor = function(element, operation, path, url, headers, params, httpConfig) {
-        return {
-          element: element,
-          headers: headers,
-          params: params,
-          httpConfig: httpConfig
-        };
-      };
-
-      config.fullRequestInterceptor = function(element, operation, path, url, headers, params, httpConfig) {
-        var interceptors = angular.copy(config.requestInterceptors);
-        var defaultRequest = config.defaultInterceptor(element, operation, path, url, headers, params, httpConfig);
-        return _.reduce(interceptors, function(request, interceptor) {
-          return _.extend(request, interceptor(request.element, operation,
-            path, url, request.headers, request.params, request.httpConfig));
-        }, defaultRequest);
-      };
-
-      object.addRequestInterceptor = function(interceptor) {
-        config.requestInterceptors.push(function(elem, operation, path, url, headers, params, httpConfig) {
-          return {
-            headers: headers,
-            params: params,
-            element: interceptor(elem, operation, path, url),
-            httpConfig: httpConfig
-          };
-        });
-        return this;
-      };
-
-      object.setRequestInterceptor = object.addRequestInterceptor;
-
-      object.addFullRequestInterceptor = function(interceptor) {
-        config.requestInterceptors.push(interceptor);
-        return this;
-      };
-
-      object.setFullRequestInterceptor = object.addFullRequestInterceptor;
-
-      config.onBeforeElemRestangularized = config.onBeforeElemRestangularized || function(elem) {
-        return elem;
-      };
-      object.setOnBeforeElemRestangularized = function(post) {
-        config.onBeforeElemRestangularized = post;
-        return this;
-      };
-
-      object.setRestangularizePromiseInterceptor = function(interceptor) {
-        config.restangularizePromiseInterceptor = interceptor;
-        return this;
-      };
-
-      /**
-       * This method is called after an element has been "Restangularized".
-       *
-       * It receives the element, a boolean indicating if it's an element or a collection
-       * and the name of the model
-       *
-       */
-      config.onElemRestangularized = config.onElemRestangularized || function(elem) {
-        return elem;
-      };
-      object.setOnElemRestangularized = function(post) {
-        config.onElemRestangularized = post;
-        return this;
-      };
-
-      config.shouldSaveParent = config.shouldSaveParent || function() {
-        return true;
-      };
-      object.setParentless = function(values) {
-        if (_.isArray(values)) {
-          config.shouldSaveParent = function(route) {
-            return !_.includes(values, route);
-          };
-        } else if (_.isBoolean(values)) {
-          config.shouldSaveParent = function() {
-            return !values;
-          };
-        }
-        return this;
-      };
-
-      /**
-       * This lets you set a suffix to every request.
-       *
-       * For example, if your api requires that for JSon requests you do /users/123.json, you can set that
-       * in here.
-       *
-       *
-       * By default, the suffix is null
-       */
-      config.suffix = _.isUndefined(config.suffix) ? null : config.suffix;
-      object.setRequestSuffix = function(newSuffix) {
-        config.suffix = newSuffix;
-        return this;
-      };
-
-      /**
-       * Add element transformers for certain routes.
-       */
-      config.transformers = config.transformers || {};
-      config.matchTransformers = config.matchTransformers || [];
-      object.addElementTransformer = function(type, secondArg, thirdArg) {
-        var isCollection = null;
-        var transformer = null;
-        if (arguments.length === 2) {
-          transformer = secondArg;
-        } else {
-          transformer = thirdArg;
-          isCollection = secondArg;
-        }
-
-        var transformerFn = function(coll, elem) {
-          if (_.isNull(isCollection) || (coll === isCollection)) {
-            return transformer(elem);
-          }
-          return elem;
-        };
-
-        if (_.isRegExp(type)) {
-          config.matchTransformers.push({
-            regexp: type,
-            transformer: transformerFn
-          });
-        } else {
-          if (!config.transformers[type]) {
-            config.transformers[type] = [];
-          }
-          config.transformers[type].push(transformerFn);
-        }
-
-        return object;
-      };
-
-      object.extendCollection = function(route, fn) {
-        return object.addElementTransformer(route, true, fn);
-      };
-
-      object.extendModel = function(route, fn) {
-        return object.addElementTransformer(route, false, fn);
-      };
-
-      config.transformElem = function(elem, isCollection, route, Restangular, force) {
-        if (!force && !config.transformLocalElements && !elem[config.restangularFields.fromServer]) {
-          return elem;
-        }
-
-        var changedElem = elem;
-
-        var matchTransformers = config.matchTransformers;
-        if (matchTransformers) {
-          _.each(matchTransformers, function(transformer) {
-            if (transformer.regexp.test(route)) {
-              changedElem = transformer.transformer(isCollection, changedElem);
-            }
-          });
-        }
-
-        var typeTransformers = config.transformers[route];
-        if (typeTransformers) {
-          _.each(typeTransformers, function(transformer) {
-            changedElem = transformer(isCollection, changedElem);
-          });
-        }
-        return config.onElemRestangularized(changedElem, isCollection, route, Restangular);
-      };
-
-      config.transformLocalElements = _.isUndefined(config.transformLocalElements) ?
-        false :
-        config.transformLocalElements;
-
-      object.setTransformOnlyServerElements = function(active) {
-        config.transformLocalElements = !active;
-      };
-
-      config.fullResponse = _.isUndefined(config.fullResponse) ? false : config.fullResponse;
-      object.setFullResponse = function(full) {
-        config.fullResponse = full;
-        return this;
-      };
-
-
-      //Internal values and functions
-      config.urlCreatorFactory = {};
-
-      /**
-       * Base URL Creator. Base prototype for everything related to it
-       **/
-
-      var BaseCreator = function() {};
-
-      BaseCreator.prototype.setConfig = function(config) {
-        this.config = config;
-        return this;
-      };
-
-      BaseCreator.prototype.parentsArray = function(current) {
-        var parents = [];
-        while (current) {
-          parents.push(current);
-          current = current[this.config.restangularFields.parentResource];
-        }
-        return parents.reverse();
-      };
-
-      function RestangularResource(config, $http, url, configurer) {
-        var resource = {};
-        _.each(_.keys(configurer), function(key) {
-          var value = configurer[key];
-
-          // Add default parameters
-          value.params = _.extend({}, value.params, config.defaultRequestParams[value.method.toLowerCase()]);
-          // We don't want the ? if no params are there
-          if (_.isEmpty(value.params)) {
-            delete value.params;
-          }
-
-          if (config.isSafe(value.method)) {
-
-            resource[key] = function() {
-              return $http(_.extend(value, {
-                url: url
-              }));
-            };
-
-          } else {
-
-            resource[key] = function(data) {
-              return $http(_.extend(value, {
-                url: url,
-                data: data
-              }));
-            };
-
-          }
-        });
-
-        return resource;
-      }
-
-      BaseCreator.prototype.resource = function(current, $http, localHttpConfig, callHeaders, callParams, what, etag, operation) {
-
-        var params = _.defaults(callParams || {}, this.config.defaultRequestParams.common);
-        var headers = _.defaults(callHeaders || {}, this.config.defaultHeaders);
-
-        if (etag) {
-          if (!config.isSafe(operation)) {
-            headers['If-Match'] = etag;
-          } else {
-            headers['If-None-Match'] = etag;
-          }
-        }
-
-        var url = this.base(current);
-
-        if (what || what === 0) {
-          var add = '';
-          if (!/\/$/.test(url)) {
-            add += '/';
-          }
-          add += what;
-          url += add;
-        }
-
-        if (this.config.suffix &&
-          url.indexOf(this.config.suffix, url.length - this.config.suffix.length) === -1 &&
-          !this.config.getUrlFromElem(current)) {
-          url += this.config.suffix;
-        }
-
-        current[this.config.restangularFields.httpConfig] = undefined;
-
-        return RestangularResource(this.config, $http, url, {
-          getList: this.config.withHttpValues(localHttpConfig, {
-            method: 'GET',
-            params: params,
-            headers: headers
-          }),
-
-          get: this.config.withHttpValues(localHttpConfig, {
-            method: 'GET',
-            params: params,
-            headers: headers
-          }),
-
-          jsonp: this.config.withHttpValues(localHttpConfig, {
-            method: 'jsonp',
-            params: params,
-            headers: headers
-          }),
-
-          put: this.config.withHttpValues(localHttpConfig, {
-            method: 'PUT',
-            params: params,
-            headers: headers
-          }),
-
-          post: this.config.withHttpValues(localHttpConfig, {
-            method: 'POST',
-            params: params,
-            headers: headers
-          }),
-
-          remove: this.config.withHttpValues(localHttpConfig, {
-            method: 'DELETE',
-            params: params,
-            headers: headers
-          }),
-
-          head: this.config.withHttpValues(localHttpConfig, {
-            method: 'HEAD',
-            params: params,
-            headers: headers
-          }),
-
-          trace: this.config.withHttpValues(localHttpConfig, {
-            method: 'TRACE',
-            params: params,
-            headers: headers
-          }),
-
-          options: this.config.withHttpValues(localHttpConfig, {
-            method: 'OPTIONS',
-            params: params,
-            headers: headers
-          }),
-
-          patch: this.config.withHttpValues(localHttpConfig, {
-            method: 'PATCH',
-            params: params,
-            headers: headers
-          })
-        });
-      };
-
-      /**
-       * This is the Path URL creator. It uses Path to show Hierarchy in the Rest API.
-       * This means that if you have an Account that then has a set of Buildings, a URL to a building
-       * would be /accounts/123/buildings/456
-       **/
-      var Path = function() {};
-
-      Path.prototype = new BaseCreator();
-
-      Path.prototype.normalizeUrl = function(url) {
-        var parts = /((?:http[s]?:)?\/\/)?(.*)?/.exec(url);
-        parts[2] = parts[2].replace(/[\\\/]+/g, '/');
-        return (typeof parts[1] !== 'undefined') ? parts[1] + parts[2] : parts[2];
-      };
-
-      Path.prototype.base = function(current) {
-        var __this = this;
-        return _.reduce(this.parentsArray(current), function(acum, elem) {
-          var elemUrl;
-          var elemSelfLink = __this.config.getUrlFromElem(elem);
-          if (elemSelfLink) {
-            if (__this.config.isAbsoluteUrl(elemSelfLink)) {
-              return elemSelfLink;
-            } else {
-              elemUrl = elemSelfLink;
-            }
-          } else {
-            elemUrl = elem[__this.config.restangularFields.route];
-
-            if (elem[__this.config.restangularFields.restangularCollection]) {
-              var ids = elem[__this.config.restangularFields.ids];
-              if (ids) {
-                elemUrl += '/' + ids.join(',');
-              }
-            } else {
-              var elemId;
-              if (__this.config.useCannonicalId) {
-                elemId = __this.config.getCannonicalIdFromElem(elem);
-              } else {
-                elemId = __this.config.getIdFromElem(elem);
-              }
-
-              if (config.isValidId(elemId) && !elem.singleOne) {
-                elemUrl += '/' + (__this.config.encodeIds ? encodeURIComponent(elemId) : elemId);
-              }
-            }
-          }
-          acum = acum.replace(/\/$/, '') + '/' + elemUrl;
-          return __this.normalizeUrl(acum);
-
-        }, this.config.baseUrl);
-      };
-
-
-
-      Path.prototype.fetchUrl = function(current, what) {
-        var baseUrl = this.base(current);
-        if (what) {
-          baseUrl += '/' + what;
-        }
-        return baseUrl;
-      };
-
-      Path.prototype.fetchRequestedUrl = function(current, what) {
-        var url = this.fetchUrl(current, what);
-        var params = current[config.restangularFields.reqParams];
-
-        // From here on and until the end of fetchRequestedUrl,
-        // the code has been kindly borrowed from angular.js
-        // The reason for such code bloating is coherence:
-        //   If the user were to use this for cache management, the
-        //   serialization of parameters would need to be identical
-        //   to the one done by angular for cache keys to match.
-        function sortedKeys(obj) {
-          var keys = [];
-          for (var key in obj) {
-            if (obj.hasOwnProperty(key)) {
-              keys.push(key);
-            }
-          }
-          return keys.sort();
-        }
-
-        function forEachSorted(obj, iterator, context) {
-          var keys = sortedKeys(obj);
-          for (var i = 0; i < keys.length; i++) {
-            iterator.call(context, obj[keys[i]], keys[i]);
-          }
-          return keys;
-        }
-
-        function encodeUriQuery(val, pctEncodeSpaces) {
-          return encodeURIComponent(val).
-          replace(/%40/gi, '@').
-          replace(/%3A/gi, ':').
-          replace(/%24/g, '$').
-          replace(/%2C/gi, ',').
-          replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
-        }
-
-        if (!params) {
-          return url + (this.config.suffix || '');
-        }
-
-        var parts = [];
-        forEachSorted(params, function(value, key) {
-          if (value === null || value === undefined) {
-            return;
-          }
-          if (!angular.isArray(value)) {
-            value = [value];
-          }
-
-          angular.forEach(value, function(v) {
-            if (angular.isObject(v)) {
-              v = angular.toJson(v);
-            }
-            parts.push(encodeUriQuery(key) + '=' + encodeUriQuery(v));
-          });
-        });
-
-        return url + (this.config.suffix || '') + ((url.indexOf('?') === -1) ? '?' : '&') + parts.join('&');
-      };
-
-      config.urlCreatorFactory.path = Path;
-    };
-
-    var globalConfiguration = {};
-
-    Configurer.init(this, globalConfiguration);
-
-
-
-    this.$get = ['$http', '$q', function($http, $q) {
-
-      function createServiceForConfiguration(config) {
-        var service = {};
-
-        var urlHandler = new config.urlCreatorFactory[config.urlCreator]();
-        urlHandler.setConfig(config);
-
-        function restangularizeBase(parent, elem, route, reqParams, fromServer) {
-          elem[config.restangularFields.route] = route;
-          elem[config.restangularFields.getRestangularUrl] = _.bind(urlHandler.fetchUrl, urlHandler, elem);
-          elem[config.restangularFields.getRequestedUrl] = _.bind(urlHandler.fetchRequestedUrl, urlHandler, elem);
-          elem[config.restangularFields.addRestangularMethod] = _.bind(addRestangularMethodFunction, elem);
-          elem[config.restangularFields.clone] = _.bind(copyRestangularizedElement, elem, elem);
-          elem[config.restangularFields.reqParams] = _.isEmpty(reqParams) ? null : reqParams;
-          elem[config.restangularFields.withHttpConfig] = _.bind(withHttpConfig, elem);
-          elem[config.restangularFields.plain] = _.bind(stripRestangular, elem, elem);
-
-          // Tag element as restangularized
-          elem[config.restangularFields.restangularized] = true;
-
-          // RequestLess connection
-          elem[config.restangularFields.one] = _.bind(one, elem, elem);
-          elem[config.restangularFields.all] = _.bind(all, elem, elem);
-          elem[config.restangularFields.several] = _.bind(several, elem, elem);
-          elem[config.restangularFields.oneUrl] = _.bind(oneUrl, elem, elem);
-          elem[config.restangularFields.allUrl] = _.bind(allUrl, elem, elem);
-
-          elem[config.restangularFields.fromServer] = !!fromServer;
-
-          if (parent && config.shouldSaveParent(route)) {
-            var parentId = config.getIdFromElem(parent);
-            var parentUrl = config.getUrlFromElem(parent);
-
-            var restangularFieldsForParent = _.union(
-              _.values(_.pick(config.restangularFields, ['route', 'singleOne', 'parentResource'])),
-              config.extraFields
-            );
-            var parentResource = _.pick(parent, restangularFieldsForParent);
-
-            if (config.isValidId(parentId)) {
-              config.setIdToElem(parentResource, parentId, route);
-            }
-            if (config.isValidId(parentUrl)) {
-              config.setUrlToElem(parentResource, parentUrl, route);
-            }
-
-            elem[config.restangularFields.parentResource] = parentResource;
-          } else {
-            elem[config.restangularFields.parentResource] = null;
-          }
-          return elem;
-        }
-
-        function one(parent, route, id, singleOne) {
-          var error;
-          if (_.isNumber(route) || _.isNumber(parent)) {
-            error = 'You\'re creating a Restangular entity with the number ';
-            error += 'instead of the route or the parent. For example, you can\'t call .one(12).';
-            throw new Error(error);
-          }
-          if (_.isUndefined(route)) {
-            error = 'You\'re creating a Restangular entity either without the path. ';
-            error += 'For example you can\'t call .one(). Please check if your arguments are valid.';
-            throw new Error(error);
-          }
-          var elem = {};
-          config.setIdToElem(elem, id, route);
-          config.setFieldToElem(config.restangularFields.singleOne, elem, singleOne);
-          return restangularizeElem(parent, elem, route, false);
-        }
-
-
-        function all(parent, route) {
-          return restangularizeCollection(parent, [], route, false);
-        }
-
-        function several(parent, route /*, ids */ ) {
-          var collection = [];
-          collection[config.restangularFields.ids] = Array.prototype.splice.call(arguments, 2);
-          return restangularizeCollection(parent, collection, route, false);
-        }
-
-        function oneUrl(parent, route, url) {
-          if (!route) {
-            throw new Error('Route is mandatory when creating new Restangular objects.');
-          }
-          var elem = {};
-          config.setUrlToElem(elem, url, route);
-          return restangularizeElem(parent, elem, route, false);
-        }
-
-
-        function allUrl(parent, route, url) {
-          if (!route) {
-            throw new Error('Route is mandatory when creating new Restangular objects.');
-          }
-          var elem = {};
-          config.setUrlToElem(elem, url, route);
-          return restangularizeCollection(parent, elem, route, false);
-        }
-        // Promises
-        function restangularizePromise(promise, isCollection, valueToFill) {
-          promise.call = _.bind(promiseCall, promise);
-          promise.get = _.bind(promiseGet, promise);
-          promise[config.restangularFields.restangularCollection] = isCollection;
-          if (isCollection) {
-            promise.push = _.bind(promiseCall, promise, 'push');
-          }
-          promise.$object = valueToFill;
-          if (config.restangularizePromiseInterceptor) {
-            config.restangularizePromiseInterceptor(promise);
-          }
-          return promise;
-        }
-
-        function promiseCall(method) {
-          var deferred = $q.defer();
-          var callArgs = arguments;
-          var filledValue = {};
-          this.then(function(val) {
-            var params = Array.prototype.slice.call(callArgs, 1);
-            var func = val[method];
-            func.apply(val, params);
-            filledValue = val;
-            deferred.resolve(val);
-          });
-          return restangularizePromise(deferred.promise, this[config.restangularFields.restangularCollection], filledValue);
-        }
-
-        function promiseGet(what) {
-          var deferred = $q.defer();
-          var filledValue = {};
-          this.then(function(val) {
-            filledValue = val[what];
-            deferred.resolve(filledValue);
-          });
-          return restangularizePromise(deferred.promise, this[config.restangularFields.restangularCollection], filledValue);
-        }
-
-        function resolvePromise(deferred, response, data, filledValue) {
-          _.extend(filledValue, data);
-
-          // Trigger the full response interceptor.
-          if (config.fullResponse) {
-            return deferred.resolve(_.extend(response, {
-              data: data
-            }));
-          } else {
-            deferred.resolve(data);
-          }
-        }
-
-
-        // Elements
-        function stripRestangular(elem) {
-          if (_.isArray(elem)) {
-            var array = [];
-            _.each(elem, function(value) {
-              array.push(config.isRestangularized(value) ? stripRestangular(value) : value);
-            });
-            return array;
-          } else {
-            return _.omit(elem, _.values(_.omit(config.restangularFields, 'id')));
-          }
-        }
-
-        function addCustomOperation(elem) {
-          elem[config.restangularFields.customOperation] = _.bind(customFunction, elem);
-          var requestMethods = {
-            get: customFunction,
-            delete: customFunction
-          };
-          _.each(['put', 'patch', 'post'], function(name) {
-            requestMethods[name] = function(operation, elem, path, params, headers) {
-              return _.bind(customFunction, this)(operation, path, params, headers, elem);
-            };
-          });
-          _.each(requestMethods, function(requestFunc, name) {
-            var callOperation = name === 'delete' ? 'remove' : name;
-            _.each(['do', 'custom'], function(alias) {
-              elem[alias + name.toUpperCase()] = _.bind(requestFunc, elem, callOperation);
-            });
-          });
-          elem[config.restangularFields.customGETLIST] = _.bind(fetchFunction, elem);
-          elem[config.restangularFields.doGETLIST] = elem[config.restangularFields.customGETLIST];
-        }
-
-        function copyRestangularizedElement(element) {
-          var copiedElement = angular.copy(element);
-
-          // check if we're dealing with a collection (i.e. an array)
-          // and restangularize the element using the proper restangularizer,
-          // element / collection
-          if (_.isArray(element)) {
-            return restangularizeCollection(
-              element[config.restangularFields.parentResource],
-              copiedElement,
-              element[config.restangularFields.route],
-              element[config.restangularFields.fromServer],
-              element[config.restangularFields.reqParams]
-            );
-          }
-
-          // not a collection, restangularize it as an element
-          return restangularizeElem(
-            element[config.restangularFields.parentResource],
-            copiedElement,
-            element[config.restangularFields.route],
-            element[config.restangularFields.fromServer],
-            element[config.restangularFields.restangularCollection],
-            element[config.restangularFields.reqParams]
-          );
-        }
-
-        function restangularizeElem(parent, element, route, fromServer, collection, reqParams) {
-          var elem = config.onBeforeElemRestangularized(element, false, route);
-
-          var localElem = restangularizeBase(parent, elem, route, reqParams, fromServer);
-
-          if (config.useCannonicalId) {
-            localElem[config.restangularFields.cannonicalId] = config.getIdFromElem(localElem);
-          }
-
-          if (collection) {
-            localElem[config.restangularFields.getParentList] = function() {
-              return collection;
-            };
-          }
-
-          localElem[config.restangularFields.restangularCollection] = false;
-          localElem[config.restangularFields.get] = _.bind(getFunction, localElem);
-          localElem[config.restangularFields.getList] = _.bind(fetchFunction, localElem);
-          localElem[config.restangularFields.put] = _.bind(putFunction, localElem);
-          localElem[config.restangularFields.post] = _.bind(postFunction, localElem);
-          localElem[config.restangularFields.remove] = _.bind(deleteFunction, localElem);
-          localElem[config.restangularFields.head] = _.bind(headFunction, localElem);
-          localElem[config.restangularFields.trace] = _.bind(traceFunction, localElem);
-          localElem[config.restangularFields.options] = _.bind(optionsFunction, localElem);
-          localElem[config.restangularFields.patch] = _.bind(patchFunction, localElem);
-          localElem[config.restangularFields.save] = _.bind(save, localElem);
-
-          addCustomOperation(localElem);
-          return config.transformElem(localElem, false, route, service, true);
-        }
-
-        function restangularizeCollection(parent, element, route, fromServer, reqParams) {
-          var elem = config.onBeforeElemRestangularized(element, true, route);
-
-          var localElem = restangularizeBase(parent, elem, route, reqParams, fromServer);
-          localElem[config.restangularFields.restangularCollection] = true;
-          localElem[config.restangularFields.post] = _.bind(postFunction, localElem, null);
-          localElem[config.restangularFields.remove] = _.bind(deleteFunction, localElem);
-          localElem[config.restangularFields.head] = _.bind(headFunction, localElem);
-          localElem[config.restangularFields.trace] = _.bind(traceFunction, localElem);
-          localElem[config.restangularFields.putElement] = _.bind(putElementFunction, localElem);
-          localElem[config.restangularFields.options] = _.bind(optionsFunction, localElem);
-          localElem[config.restangularFields.patch] = _.bind(patchFunction, localElem);
-          localElem[config.restangularFields.get] = _.bind(getById, localElem);
-          localElem[config.restangularFields.getList] = _.bind(fetchFunction, localElem, null);
-
-          addCustomOperation(localElem);
-          return config.transformElem(localElem, true, route, service, true);
-        }
-
-        function restangularizeCollectionAndElements(parent, element, route, fromServer) {
-          var collection = restangularizeCollection(parent, element, route, fromServer);
-          _.each(collection, function(elem) {
-            if (elem) {
-              restangularizeElem(parent, elem, route, fromServer);
-            }
-          });
-          return collection;
-        }
-
-        function getById(id, reqParams, headers) {
-          return this.customGET(id.toString(), reqParams, headers);
-        }
-
-        function putElementFunction(idx, params, headers) {
-          var __this = this;
-          var elemToPut = this[idx];
-          var deferred = $q.defer();
-          var filledArray = [];
-          filledArray = config.transformElem(filledArray, true, elemToPut[config.restangularFields.route], service);
-          elemToPut.put(params, headers).then(function(serverElem) {
-            var newArray = copyRestangularizedElement(__this);
-            newArray[idx] = serverElem;
-            filledArray = newArray;
-            deferred.resolve(newArray);
-          }, function(response) {
-            deferred.reject(response);
-          });
-
-          return restangularizePromise(deferred.promise, true, filledArray);
-        }
-
-        function parseResponse(resData, operation, route, fetchUrl, response, deferred) {
-          var data = config.responseExtractor(resData, operation, route, fetchUrl, response, deferred);
-          var etag = response.headers('ETag');
-          if (data && etag) {
-            data[config.restangularFields.etag] = etag;
-          }
-          return data;
-        }
-
-
-        function fetchFunction(what, reqParams, headers) {
-          var __this = this;
-          var deferred = $q.defer();
-          var operation = 'getList';
-          var url = urlHandler.fetchUrl(this, what);
-          var whatFetched = what || __this[config.restangularFields.route];
-
-          var request = config.fullRequestInterceptor(null, operation,
-            whatFetched, url, headers || {}, reqParams || {}, this[config.restangularFields.httpConfig] || {});
-
-          var filledArray = [];
-          filledArray = config.transformElem(filledArray, true, whatFetched, service);
-
-          var method = 'getList';
-
-          if (config.jsonp) {
-            method = 'jsonp';
-          }
-
-          var okCallback = function(response) {
-            var resData = response.data;
-            var fullParams = response.config.params;
-            var data = parseResponse(resData, operation, whatFetched, url, response, deferred);
-
-            // support empty response for getList() calls (some APIs respond with 204 and empty body)
-            if (_.isUndefined(data) || '' === data) {
-              data = [];
-            }
-            if (!_.isArray(data)) {
-              throw new Error('Response for getList SHOULD be an array and not an object or something else');
-            }
-
-            if (true === config.plainByDefault) {
-              return resolvePromise(deferred, response, data, filledArray);
-            }
-
-            var processedData = _.map(data, function(elem) {
-              if (!__this[config.restangularFields.restangularCollection]) {
-                return restangularizeElem(__this, elem, what, true, data);
-              } else {
-                return restangularizeElem(__this[config.restangularFields.parentResource],
-                  elem, __this[config.restangularFields.route], true, data);
-              }
-            });
-
-            processedData = _.extend(data, processedData);
-
-            if (!__this[config.restangularFields.restangularCollection]) {
-              resolvePromise(
-                deferred,
-                response,
-                restangularizeCollection(
-                  __this,
-                  processedData,
-                  what,
-                  true,
-                  fullParams
-                ),
-                filledArray
-              );
-            } else {
-              resolvePromise(
-                deferred,
-                response,
-                restangularizeCollection(
-                  __this[config.restangularFields.parentResource],
-                  processedData,
-                  __this[config.restangularFields.route],
-                  true,
-                  fullParams
-                ),
-                filledArray
-              );
-            }
-          };
-
-          urlHandler.resource(this, $http, request.httpConfig, request.headers, request.params, what,
-            this[config.restangularFields.etag], operation)[method]().then(okCallback, function error(response) {
-            if (response.status === 304 && __this[config.restangularFields.restangularCollection]) {
-              resolvePromise(deferred, response, __this, filledArray);
-            } else if (_.every(config.errorInterceptors, function(cb) {
-                return cb(response, deferred, okCallback) !== false;
-              })) {
-              // triggered if no callback returns false
-              deferred.reject(response);
-            }
-          });
-
-          return restangularizePromise(deferred.promise, true, filledArray);
-        }
-
-        function withHttpConfig(httpConfig) {
-          this[config.restangularFields.httpConfig] = httpConfig;
-          return this;
-        }
-
-        function save(params, headers) {
-          if (this[config.restangularFields.fromServer]) {
-            return this[config.restangularFields.put](params, headers);
-          } else {
-            return _.bind(elemFunction, this)('post', undefined, params, undefined, headers);
-          }
-        }
-
-        function elemFunction(operation, what, params, obj, headers) {
-          var __this = this;
-          var deferred = $q.defer();
-          var resParams = params || {};
-          var route = what || this[config.restangularFields.route];
-          var fetchUrl = urlHandler.fetchUrl(this, what);
-
-          var callObj = obj || this;
-          // fallback to etag on restangular object (since for custom methods we probably don't explicitly specify the etag field)
-          var etag = callObj[config.restangularFields.etag] || (operation !== 'post' ? this[config.restangularFields.etag] : null);
-
-          if (_.isObject(callObj) && config.isRestangularized(callObj)) {
-            callObj = stripRestangular(callObj);
-          }
-          var request = config.fullRequestInterceptor(callObj, operation, route, fetchUrl,
-            headers || {}, resParams || {}, this[config.restangularFields.httpConfig] || {});
-
-          var filledObject = {};
-          filledObject = config.transformElem(filledObject, false, route, service);
-
-          var okCallback = function(response) {
-            var resData = response.data;
-            var fullParams = response.config.params;
-            var elem = parseResponse(resData, operation, route, fetchUrl, response, deferred);
-
-            // accept 0 as response
-            if (elem !== null && elem !== undefined && elem !== '') {
-              var data;
-
-              if (true === config.plainByDefault) {
-                return resolvePromise(deferred, response, elem, filledObject);
-              }
-
-              if (operation === 'post' && !__this[config.restangularFields.restangularCollection]) {
-                data = restangularizeElem(
-                  __this[config.restangularFields.parentResource],
-                  elem,
-                  route,
-                  true,
-                  null,
-                  fullParams
-                );
-                resolvePromise(deferred, response, data, filledObject);
-              } else {
-                data = restangularizeElem(
-                  __this[config.restangularFields.parentResource],
-                  elem,
-                  __this[config.restangularFields.route],
-                  true,
-                  null,
-                  fullParams
-                );
-
-                data[config.restangularFields.singleOne] = __this[config.restangularFields.singleOne];
-                resolvePromise(deferred, response, data, filledObject);
-              }
-
-            } else {
-              resolvePromise(deferred, response, undefined, filledObject);
-            }
-          };
-
-          var errorCallback = function(response) {
-            if (response.status === 304 && config.isSafe(operation)) {
-              resolvePromise(deferred, response, __this, filledObject);
-            } else if (_.every(config.errorInterceptors, function(cb) {
-                return cb(response, deferred, okCallback) !== false;
-              })) {
-              // triggered if no callback returns false
-              deferred.reject(response);
-            }
-          };
-          // Overriding HTTP Method
-          var callOperation = operation;
-          var callHeaders = _.extend({}, request.headers);
-          var isOverrideOperation = config.isOverridenMethod(operation);
-          if (isOverrideOperation) {
-            callOperation = 'post';
-            callHeaders = _.extend(callHeaders, {
-              'X-HTTP-Method-Override': operation === 'remove' ? 'DELETE' : operation.toUpperCase()
-            });
-          } else if (config.jsonp && callOperation === 'get') {
-            callOperation = 'jsonp';
-          }
-
-          if (config.isSafe(operation)) {
-            if (isOverrideOperation) {
-              urlHandler.resource(this, $http, request.httpConfig, callHeaders, request.params,
-                what, etag, callOperation)[callOperation]({}).then(okCallback, errorCallback);
-            } else {
-              urlHandler.resource(this, $http, request.httpConfig, callHeaders, request.params,
-                what, etag, callOperation)[callOperation]().then(okCallback, errorCallback);
-            }
-          } else {
-            urlHandler.resource(this, $http, request.httpConfig, callHeaders, request.params,
-              what, etag, callOperation)[callOperation](request.element).then(okCallback, errorCallback);
-          }
-
-          return restangularizePromise(deferred.promise, false, filledObject);
-        }
-
-        function getFunction(params, headers) {
-          return _.bind(elemFunction, this)('get', undefined, params, undefined, headers);
-        }
-
-        function deleteFunction(params, headers) {
-          return _.bind(elemFunction, this)('remove', undefined, params, undefined, headers);
-        }
-
-        function putFunction(params, headers) {
-          return _.bind(elemFunction, this)('put', undefined, params, undefined, headers);
-        }
-
-        function postFunction(what, elem, params, headers) {
-          return _.bind(elemFunction, this)('post', what, params, elem, headers);
-        }
-
-        function headFunction(params, headers) {
-          return _.bind(elemFunction, this)('head', undefined, params, undefined, headers);
-        }
-
-        function traceFunction(params, headers) {
-          return _.bind(elemFunction, this)('trace', undefined, params, undefined, headers);
-        }
-
-        function optionsFunction(params, headers) {
-          return _.bind(elemFunction, this)('options', undefined, params, undefined, headers);
-        }
-
-        function patchFunction(elem, params, headers) {
-          return _.bind(elemFunction, this)('patch', undefined, params, elem, headers);
-        }
-
-        function customFunction(operation, path, params, headers, elem) {
-          return _.bind(elemFunction, this)(operation, path, params, elem, headers);
-        }
-
-        function addRestangularMethodFunction(name, operation, path, defaultParams, defaultHeaders, defaultElem) {
-          var bindedFunction;
-          if (operation === 'getList') {
-            bindedFunction = _.bind(fetchFunction, this, path);
-          } else {
-            bindedFunction = _.bind(customFunction, this, operation, path);
-          }
-
-          var createdFunction = function(params, headers, elem) {
-            var callParams = _.defaults({
-              params: params,
-              headers: headers,
-              elem: elem
-            }, {
-              params: defaultParams,
-              headers: defaultHeaders,
-              elem: defaultElem
-            });
-            return bindedFunction(callParams.params, callParams.headers, callParams.elem);
-          };
-
-          if (config.isSafe(operation)) {
-            this[name] = createdFunction;
-          } else {
-            this[name] = function(elem, params, headers) {
-              return createdFunction(params, headers, elem);
-            };
-          }
-        }
-
-        function withConfigurationFunction(configurer) {
-          var newConfig = angular.copy(_.omit(config, 'configuration'));
-          Configurer.init(newConfig, newConfig);
-          configurer(newConfig);
-          return createServiceForConfiguration(newConfig);
-        }
-
-        function toService(route, parent) {
-          var knownCollectionMethods = _.values(config.restangularFields);
-          var serv = {};
-          var collection = (parent || service).all(route);
-          serv.one = _.bind(one, (parent || service), parent, route);
-          serv.post = _.bind(collection.post, collection);
-          serv.getList = _.bind(collection.getList, collection);
-          serv.withHttpConfig = _.bind(collection.withHttpConfig, collection);
-          serv.get = _.bind(collection.get, collection);
-
-          for (var prop in collection) {
-            if (collection.hasOwnProperty(prop) && _.isFunction(collection[prop]) && !_.includes(knownCollectionMethods, prop)) {
-              serv[prop] = _.bind(collection[prop], collection);
-            }
-          }
-
-          return serv;
-        }
-
-
-        Configurer.init(service, config);
-
-        service.copy = _.bind(copyRestangularizedElement, service);
-
-        service.service = _.bind(toService, service);
-
-        service.withConfig = _.bind(withConfigurationFunction, service);
-
-        service.one = _.bind(one, service, null);
-
-        service.all = _.bind(all, service, null);
-
-        service.several = _.bind(several, service, null);
-
-        service.oneUrl = _.bind(oneUrl, service, null);
-
-        service.allUrl = _.bind(allUrl, service, null);
-
-        service.stripRestangular = _.bind(stripRestangular, service);
-
-        service.restangularizeElement = _.bind(restangularizeElem, service);
-
-        service.restangularizeCollection = _.bind(restangularizeCollectionAndElements, service);
-
-        return service;
-      }
-
-      return createServiceForConfiguration(globalConfiguration);
-    }];
-  });
-  return restangular.name;
-}));
diff --git a/static/js/run_prettify.js b/static/js/run_prettify.js
index 8204930..427074a 100644
--- a/static/js/run_prettify.js
+++ b/static/js/run_prettify.js
@@ -1,63 +1,1998 @@
-!function(){/*
+/**
+ * @license
+ * Copyright (C) 2013 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
- Copyright (C) 2013 Google Inc.
+/**
+ * @fileoverview
+ * <div style="white-space: pre">
+ * Looks at query parameters to decide which language handlers and style-sheets
+ * to load.
+ *
+ * Query Parameter     Format           Effect                        Default
+ * +------------------+---------------+------------------------------+--------+
+ * | autorun=         | true | false  | If true then prettyPrint()   | "true" |
+ * |                  |               | is called on page load.      |        |
+ * +------------------+---------------+------------------------------+--------+
+ * | lang=            | language name | Loads the language handler   | Can    |
+ * |                  |               | named "lang-<NAME>.js".      | appear |
+ * |                  |               | See available handlers at    | many   |
+ * |                  |               | https://github.com/google/   | times. |
+ * |                  |               | code-prettify/tree/master/   |        |
+ * |                  |               | src                          |        |
+ * +------------------+---------------+------------------------------+--------+
+ * | skin=            | skin name     | Loads the skin stylesheet    | none.  |
+ * |                  |               | named "<NAME>.css".          |        |
+ * |                  |               | https://cdn.rawgit.com/      |        |
+ * |                  |               | google/code-prettify/master/ |        |
+ * |                  |               | styles/index.html            |        |
+ * +------------------+---------------+------------------------------+--------+
+ * | callback=        | JS identifier | When "prettyPrint" finishes  | none   |
+ * |                  |               | window.exports[js_ident] is  |        |
+ * |                  |               | called.                      |        |
+ * |                  |               | The callback must be under   |        |
+ * |                  |               | exports to reduce the risk   |        |
+ * |                  |               | of XSS via query parameter   |        |
+ * |                  |               | injection.                   |        |
+ * +------------------+---------------+------------------------------+--------+
+ *
+ * Exmaples
+ * .../run_prettify.js?lang=css&skin=sunburst
+ *   1. Loads the CSS language handler which can be used to prettify CSS
+ *      stylesheets, HTML <style> element bodies and style="..." attributes
+ *      values.
+ *   2. Loads the sunburst.css stylesheet instead of the default prettify.css
+ *      stylesheet.
+ *      A gallery of stylesheets is available at
+ *      https://cdn.rawgit.com/google/code-prettify/master/styles/index.html
+ *   3. Since autorun=false is not specified, calls prettyPrint() on page load.
+ * </div>
+ */
 
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- Copyright (C) 2006 Google Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
+/**
+* @typedef {!Array.<number|string>}
+* Alternating indices and the decorations that should be inserted there.
+* The indices are monotonically increasing.
 */
-(function(){function ba(g){function k(){try{M.doScroll("left")}catch(g){t.setTimeout(k,50);return}z("poll")}function z(k){if("readystatechange"!=k.type||"complete"==A.readyState)("load"==k.type?t:A)[B](p+k.type,z,!1),!q&&(q=!0)&&g.call(t,k.type||k)}var Y=A.addEventListener,q=!1,C=!0,x=Y?"addEventListener":"attachEvent",B=Y?"removeEventListener":"detachEvent",p=Y?"":"on";if("complete"==A.readyState)g.call(t,"lazy");else{if(A.createEventObject&&M.doScroll){try{C=!t.frameElement}catch(da){}C&&k()}A[x](p+
-"DOMContentLoaded",z,!1);A[x](p+"readystatechange",z,!1);t[x](p+"load",z,!1)}}function U(){V&&ba(function(){var g=N.length;ca(g?function(){for(var k=0;k<g;++k)(function(g){t.setTimeout(function(){t.exports[N[g]].apply(t,arguments)},0)})(k)}:void 0)})}for(var t=window,A=document,M=A.documentElement,O=A.head||A.getElementsByTagName("head")[0]||M,B="",F=A.getElementsByTagName("script"),q=F.length;0<=--q;){var P=F[q],Z=P.src.match(/^[^?#]*\/run_prettify\.js(\?[^#]*)?(?:#.*)?$/);if(Z){B=Z[1]||"";P.parentNode.removeChild(P);
-break}}var V=!0,H=[],Q=[],N=[];B.replace(/[?&]([^&=]+)=([^&]+)/g,function(g,k,z){z=decodeURIComponent(z);k=decodeURIComponent(k);"autorun"==k?V=!/^[0fn]/i.test(z):"lang"==k?H.push(z):"skin"==k?Q.push(z):"callback"==k&&N.push(z)});q=0;for(B=H.length;q<B;++q)(function(){var g=A.createElement("script");g.onload=g.onerror=g.onreadystatechange=function(){!g||g.readyState&&!/loaded|complete/.test(g.readyState)||(g.onerror=g.onload=g.onreadystatechange=null,--T,T||t.setTimeout(U,0),g.parentNode&&g.parentNode.removeChild(g),
-g=null)};g.type="text/javascript";g.src="../css/loader/lang-"+encodeURIComponent(H[q])+".js";O.insertBefore(g,O.firstChild)})(H[q]);for(var T=H.length,F=[],q=0,B=Q.length;q<B;++q)F.push("https://cdn.rawgit.com/google/code-prettify/master/loader/skins/"+encodeURIComponent(Q[q])+".css");F.push("../css/prettify.css");(function(g){function k(q){if(q!==z){var t=A.createElement("link");t.rel="stylesheet";t.type=
-"text/css";q+1<z&&(t.error=t.onerror=function(){k(q+1)});t.href=g[q];O.appendChild(t)}}var z=g.length;k(0)})(F);var ca=function(){window.PR_SHOULD_USE_CONTINUATION=!0;var g;(function(){function k(a){function d(e){var b=e.charCodeAt(0);if(92!==b)return b;var a=e.charAt(1);return(b=W[a])?b:"0"<=a&&"7">=a?parseInt(e.substring(1),8):"u"===a||"x"===a?parseInt(e.substring(2),16):e.charCodeAt(1)}function f(e){if(32>e)return(16>e?"\\x0":"\\x")+e.toString(16);e=String.fromCharCode(e);return"\\"===e||"-"===
-e||"]"===e||"^"===e?"\\"+e:e}function b(e){var b=e.substring(1,e.length-1).match(/\\u[0-9A-Fa-f]{4}|\\x[0-9A-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\s\S]|-|[^-\\]/g);e=[];var a="^"===b[0],c=["["];a&&c.push("^");for(var a=a?1:0,h=b.length;a<h;++a){var l=b[a];if(/\\[bdsw]/i.test(l))c.push(l);else{var l=d(l),n;a+2<h&&"-"===b[a+1]?(n=d(b[a+2]),a+=2):n=l;e.push([l,n]);65>n||122<l||(65>n||90<l||e.push([Math.max(65,l)|32,Math.min(n,90)|32]),97>n||122<l||e.push([Math.max(97,l)&-33,Math.min(n,122)&-33]))}}e.sort(function(e,
-a){return e[0]-a[0]||a[1]-e[1]});b=[];h=[];for(a=0;a<e.length;++a)l=e[a],l[0]<=h[1]+1?h[1]=Math.max(h[1],l[1]):b.push(h=l);for(a=0;a<b.length;++a)l=b[a],c.push(f(l[0])),l[1]>l[0]&&(l[1]+1>l[0]&&c.push("-"),c.push(f(l[1])));c.push("]");return c.join("")}function g(e){for(var a=e.source.match(/(?:\[(?:[^\x5C\x5D]|\\[\s\S])*\]|\\u[A-Fa-f0-9]{4}|\\x[A-Fa-f0-9]{2}|\\[0-9]+|\\[^ux0-9]|\(\?[:!=]|[\(\)\^]|[^\x5B\x5C\(\)\^]+)/g),c=a.length,d=[],h=0,l=0;h<c;++h){var n=a[h];"("===n?++l:"\\"===n.charAt(0)&&(n=
-+n.substring(1))&&(n<=l?d[n]=-1:a[h]=f(n))}for(h=1;h<d.length;++h)-1===d[h]&&(d[h]=++k);for(l=h=0;h<c;++h)n=a[h],"("===n?(++l,d[l]||(a[h]="(?:")):"\\"===n.charAt(0)&&(n=+n.substring(1))&&n<=l&&(a[h]="\\"+d[n]);for(h=0;h<c;++h)"^"===a[h]&&"^"!==a[h+1]&&(a[h]="");if(e.ignoreCase&&I)for(h=0;h<c;++h)n=a[h],e=n.charAt(0),2<=n.length&&"["===e?a[h]=b(n):"\\"!==e&&(a[h]=n.replace(/[a-zA-Z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return a.join("")}for(var k=0,I=!1,
-m=!1,J=0,c=a.length;J<c;++J){var r=a[J];if(r.ignoreCase)m=!0;else if(/[a-z]/i.test(r.source.replace(/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi,""))){I=!0;m=!1;break}}for(var W={b:8,t:9,n:10,v:11,f:12,r:13},u=[],J=0,c=a.length;J<c;++J){r=a[J];if(r.global||r.multiline)throw Error(""+r);u.push("(?:"+g(r)+")")}return new RegExp(u.join("|"),m?"gi":"g")}function q(a,d){function f(a){var c=a.nodeType;if(1==c){if(!b.test(a.className)){for(c=a.firstChild;c;c=c.nextSibling)f(c);c=a.nodeName.toLowerCase();if("br"===
-c||"li"===c)g[m]="\n",I[m<<1]=k++,I[m++<<1|1]=a}}else if(3==c||4==c)c=a.nodeValue,c.length&&(c=d?c.replace(/\r\n?/g,"\n"):c.replace(/[ \t\r\n]+/g," "),g[m]=c,I[m<<1]=k,k+=c.length,I[m++<<1|1]=a)}var b=/(?:^|\s)nocode(?:\s|$)/,g=[],k=0,I=[],m=0;f(a);return{a:g.join("").replace(/\n$/,""),c:I}}function t(a,d,f,b,g){f&&(a={h:a,l:1,j:null,m:null,a:f,c:null,i:d,g:null},b(a),g.push.apply(g,a.g))}function A(a){for(var d=void 0,f=a.firstChild;f;f=f.nextSibling)var b=f.nodeType,d=1===b?d?a:f:3===b?T.test(f.nodeValue)?
-a:d:d;return d===a?void 0:d}function C(a,d){function f(a){for(var m=a.i,k=a.h,c=[m,"pln"],r=0,W=a.a.match(g)||[],u={},e=0,q=W.length;e<q;++e){var D=W[e],w=u[D],h=void 0,l;if("string"===typeof w)l=!1;else{var n=b[D.charAt(0)];if(n)h=D.match(n[1]),w=n[0];else{for(l=0;l<p;++l)if(n=d[l],h=D.match(n[1])){w=n[0];break}h||(w="pln")}!(l=5<=w.length&&"lang-"===w.substring(0,5))||h&&"string"===typeof h[1]||(l=!1,w="src");l||(u[D]=w)}n=r;r+=D.length;if(l){l=h[1];var E=D.indexOf(l),G=E+l.length;h[2]&&(G=D.length-
-h[2].length,E=G-l.length);w=w.substring(5);t(k,m+n,D.substring(0,E),f,c);t(k,m+n+E,l,F(w,l),c);t(k,m+n+G,D.substring(G),f,c)}else c.push(m+n,w)}a.g=c}var b={},g;(function(){for(var f=a.concat(d),m=[],p={},c=0,r=f.length;c<r;++c){var q=f[c],u=q[3];if(u)for(var e=u.length;0<=--e;)b[u.charAt(e)]=q;q=q[1];u=""+q;p.hasOwnProperty(u)||(m.push(q),p[u]=null)}m.push(/[\0-\uffff]/);g=k(m)})();var p=d.length;return f}function x(a){var d=[],f=[];a.tripleQuotedStrings?d.push(["str",/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
-null,"'\""]):a.multiLineStrings?d.push(["str",/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"]):d.push(["str",/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"]);a.verbatimStrings&&f.push(["str",/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null]);var b=a.hashComments;b&&(a.cStyleComments?(1<b?d.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"]):d.push(["com",/^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\r\n]*)/,
-null,"#"]),f.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,null])):d.push(["com",/^#[^\r\n]*/,null,"#"]));a.cStyleComments&&(f.push(["com",/^\/\/[^\r\n]*/,null]),f.push(["com",/^\/\*[\s\S]*?(?:\*\/|$)/,null]));if(b=a.regexLiterals){var g=(b=1<b?"":"\n\r")?".":"[\\S\\s]";f.push(["lang-regex",RegExp("^(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*("+
-("/(?=[^/*"+b+"])(?:[^/\\x5B\\x5C"+b+"]|\\x5C"+g+"|\\x5B(?:[^\\x5C\\x5D"+b+"]|\\x5C"+g+")*(?:\\x5D|$))+/")+")")])}(b=a.types)&&f.push(["typ",b]);b=(""+a.keywords).replace(/^ | $/g,"");b.length&&f.push(["kwd",new RegExp("^(?:"+b.replace(/[\s,]+/g,"|")+")\\b"),null]);d.push(["pln",/^\s+/,null," \r\n\t\u00a0"]);b="^.[^\\s\\w.$@'\"`/\\\\]*";a.regexLiterals&&(b+="(?!s*/)");f.push(["lit",/^@[a-z_$][a-z_$@0-9]*/i,null],["typ",/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],["pln",/^[a-z_$][a-z_$@0-9]*/i,
-null],["lit",/^(?:0x[a-f0-9]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+\-]?\d+)?)[a-z]*/i,null,"0123456789"],["pln",/^\\[\s\S]?/,null],["pun",new RegExp(b),null]);return C(d,f)}function B(a,d,f){function b(a){var c=a.nodeType;if(1==c&&!k.test(a.className))if("br"===a.nodeName)g(a),a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)b(a);else if((3==c||4==c)&&f){var d=a.nodeValue,p=d.match(q);p&&(c=d.substring(0,p.index),a.nodeValue=c,(d=d.substring(p.index+p[0].length))&&
-a.parentNode.insertBefore(m.createTextNode(d),a.nextSibling),g(a),c||a.parentNode.removeChild(a))}}function g(a){function b(a,c){var d=c?a.cloneNode(!1):a,n=a.parentNode;if(n){var n=b(n,1),e=a.nextSibling;n.appendChild(d);for(var f=e;f;f=e)e=f.nextSibling,n.appendChild(f)}return d}for(;!a.nextSibling;)if(a=a.parentNode,!a)return;a=b(a.nextSibling,0);for(var d;(d=a.parentNode)&&1===d.nodeType;)a=d;c.push(a)}for(var k=/(?:^|\s)nocode(?:\s|$)/,q=/\r\n?|\n/,m=a.ownerDocument,p=m.createElement("li");a.firstChild;)p.appendChild(a.firstChild);
-for(var c=[p],r=0;r<c.length;++r)b(c[r]);d===(d|0)&&c[0].setAttribute("value",d);var t=m.createElement("ol");t.className="linenums";d=Math.max(0,d-1|0)||0;for(var r=0,u=c.length;r<u;++r)p=c[r],p.className="L"+(r+d)%10,p.firstChild||p.appendChild(m.createTextNode("\u00a0")),t.appendChild(p);a.appendChild(t)}function p(a,d){for(var f=d.length;0<=--f;){var b=d[f];X.hasOwnProperty(b)?R.console&&console.warn("cannot override language handler %s",b):X[b]=a}}function F(a,d){a&&X.hasOwnProperty(a)||(a=/^\s*</.test(d)?
-"default-markup":"default-code");return X[a]}function H(a){var d=a.j;try{var f=q(a.h,a.l),b=f.a;a.a=b;a.c=f.c;a.i=0;F(d,b)(a);var g=/\bMSIE\s(\d+)/.exec(navigator.userAgent),g=g&&8>=+g[1],d=/\n/g,p=a.a,k=p.length,f=0,m=a.c,t=m.length,b=0,c=a.g,r=c.length,x=0;c[r]=k;var u,e;for(e=u=0;e<r;)c[e]!==c[e+2]?(c[u++]=c[e++],c[u++]=c[e++]):e+=2;r=u;for(e=u=0;e<r;){for(var A=c[e],D=c[e+1],w=e+2;w+2<=r&&c[w+1]===D;)w+=2;c[u++]=A;c[u++]=D;e=w}c.length=u;var h=a.h;a="";h&&(a=h.style.display,h.style.display="none");
-try{for(;b<t;){var l=m[b+2]||k,n=c[x+2]||k,w=Math.min(l,n),E=m[b+1],G;if(1!==E.nodeType&&(G=p.substring(f,w))){g&&(G=G.replace(d,"\r"));E.nodeValue=G;var aa=E.ownerDocument,v=aa.createElement("span");v.className=c[x+1];var B=E.parentNode;B.replaceChild(v,E);v.appendChild(E);f<l&&(m[b+1]=E=aa.createTextNode(p.substring(w,l)),B.insertBefore(E,v.nextSibling))}f=w;f>=l&&(b+=2);f>=n&&(x+=2)}}finally{h&&(h.style.display=a)}}catch(y){R.console&&console.log(y&&y.stack||y)}}var R=window,K=["break,continue,do,else,for,if,return,while"],
-L=[[K,"auto,case,char,const,default,double,enum,extern,float,goto,inline,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],S=[L,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,delegate,dynamic_cast,explicit,export,friend,generic,late_check,mutable,namespace,nullptr,property,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],
-M=[L,"abstract,assert,boolean,byte,extends,finally,final,implements,import,instanceof,interface,null,native,package,strictfp,super,synchronized,throws,transient"],N=[L,"abstract,as,base,bool,by,byte,checked,decimal,delegate,descending,dynamic,event,finally,fixed,foreach,from,group,implicit,in,interface,internal,into,is,let,lock,null,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var,virtual,where"],L=[L,"debugger,eval,export,function,get,instanceof,null,set,undefined,var,with,Infinity,NaN"],
-O=[K,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],P=[K,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],K=[K,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],Q=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)\b/,
-T=/\S/,U=x({keywords:[S,N,M,L,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",O,P,K],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),X={};p(U,["default-code"]);p(C([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",
-/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),"default-markup htm html mxml xhtml xml xsl".split(" "));p(C([["pln",/^[\s]+/,null," \t\r\n"],["atv",/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
-["pun",/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);p(C([],[["atv",/^[\s\S]+/]]),["uq.val"]);p(x({keywords:S,hashComments:!0,cStyleComments:!0,types:Q}),"c cc cpp cxx cyc m".split(" "));p(x({keywords:"null,true,false"}),["json"]);p(x({keywords:N,hashComments:!0,cStyleComments:!0,
-verbatimStrings:!0,types:Q}),["cs"]);p(x({keywords:M,cStyleComments:!0}),["java"]);p(x({keywords:K,hashComments:!0,multiLineStrings:!0}),["bash","bsh","csh","sh"]);p(x({keywords:O,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),["cv","py","python"]);p(x({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:2}),
-["perl","pl","pm"]);p(x({keywords:P,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb","ruby"]);p(x({keywords:L,cStyleComments:!0,regexLiterals:!0}),["javascript","js"]);p(x({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,throw,true,try,unless,until,when,while,yes",hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);p(C([],[["str",/^[\s\S]+/]]),["regex"]);
-var V=R.PR={createSimpleLexer:C,registerLangHandler:p,sourceDecorator:x,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ",prettyPrintOne:function(a,d,f){f=f||!1;d=d||null;var b=document.createElement("div");b.innerHTML="<pre>"+a+"</pre>";b=b.firstChild;f&&B(b,f,!0);H({j:d,m:f,h:b,l:1,a:null,i:null,c:null,g:null});return b.innerHTML},
-prettyPrint:g=g=function(a,d){function f(){for(var b=R.PR_SHOULD_USE_CONTINUATION?c.now()+250:Infinity;r<p.length&&c.now()<b;r++){for(var d=p[r],k=h,q=d;q=q.previousSibling;){var m=q.nodeType,v=(7===m||8===m)&&q.nodeValue;if(v?!/^\??prettify\b/.test(v):3!==m||/\S/.test(q.nodeValue))break;if(v){k={};v.replace(/\b(\w+)=([\w:.%+-]+)/g,function(a,b,c){k[b]=c});break}}q=d.className;if((k!==h||u.test(q))&&!e.test(q)){m=!1;for(v=d.parentNode;v;v=v.parentNode)if(w.test(v.tagName)&&v.className&&u.test(v.className)){m=
-!0;break}if(!m){d.className+=" prettyprinted";m=k.lang;if(!m){var m=q.match(t),C;!m&&(C=A(d))&&z.test(C.tagName)&&(m=C.className.match(t));m&&(m=m[1])}if(x.test(d.tagName))v=1;else var v=d.currentStyle,y=g.defaultView,v=(v=v?v.whiteSpace:y&&y.getComputedStyle?y.getComputedStyle(d,null).getPropertyValue("white-space"):0)&&"pre"===v.substring(0,3);y=k.linenums;(y="true"===y||+y)||(y=(y=q.match(/\blinenums\b(?::(\d+))?/))?y[1]&&y[1].length?+y[1]:!0:!1);y&&B(d,y,v);H({j:m,h:d,m:y,l:v,a:null,i:null,c:null,
-g:null})}}}r<p.length?R.setTimeout(f,250):"function"===typeof a&&a()}for(var b=d||document.body,g=b.ownerDocument||document,b=[b.getElementsByTagName("pre"),b.getElementsByTagName("code"),b.getElementsByTagName("xmp")],p=[],k=0;k<b.length;++k)for(var m=0,q=b[k].length;m<q;++m)p.push(b[k][m]);var b=null,c=Date;c.now||(c={now:function(){return+new Date}});var r=0,t=/\blang(?:uage)?-([\w.]+)(?!\S)/,u=/\bprettyprint\b/,e=/\bprettyprinted\b/,x=/pre|xmp/i,z=/^code$/i,w=/^(?:pre|code|xmp)$/i,h={};f()}},
-S=R.define;"function"===typeof S&&S.amd&&S("google-code-prettify",[],function(){return V})})();return g}();T||t.setTimeout(U,0)})();}()
+var DecorationsT;
+
+/**
+* @typedef {!{
+*   sourceNode: !Element,
+*   pre: !(number|boolean),
+*   langExtension: ?string,
+*   numberLines: ?(number|boolean),
+*   sourceCode: ?string,
+*   spans: ?(Array.<number|Node>),
+*   basePos: ?number,
+*   decorations: ?DecorationsT
+* }}
+* <dl>
+*  <dt>sourceNode<dd>the element containing the source
+*  <dt>sourceCode<dd>source as plain text
+*  <dt>pre<dd>truthy if white-space in text nodes
+*     should be considered significant.
+*  <dt>spans<dd> alternating span start indices into source
+*     and the text node or element (e.g. {@code <BR>}) corresponding to that
+*     span.
+*  <dt>decorations<dd>an array of style classes preceded
+*     by the position at which they start in job.sourceCode in order
+*  <dt>basePos<dd>integer position of this.sourceCode in the larger chunk of
+*     source.
+* </dl>
+*/
+var JobT;
+
+/**
+* @typedef {!{
+*   sourceCode: string,
+*   spans: !(Array.<number|Node>)
+* }}
+* <dl>
+*  <dt>sourceCode<dd>source as plain text
+*  <dt>spans<dd> alternating span start indices into source
+*     and the text node or element (e.g. {@code <BR>}) corresponding to that
+*     span.
+* </dl>
+*/
+var SourceSpansT;
+
+/** @define {boolean} */
+var IN_GLOBAL_SCOPE = false;
+
+(function () {
+  "use strict";
+
+  var win = window;
+  var doc = document;
+  var root = doc.documentElement;
+  var head = doc['head'] || doc.getElementsByTagName("head")[0] || root;
+
+  // From http://javascript.nwbox.com/ContentLoaded/contentloaded.js
+  // Author: Diego Perini (diego.perini at gmail.com)
+  // Summary: cross-browser wrapper for DOMContentLoaded
+  // Updated: 20101020
+  // License: MIT
+  // Version: 1.2
+  function contentLoaded(callback) {
+    var addEventListener = doc['addEventListener'];
+    var done = false, top = true,
+        add = addEventListener ? 'addEventListener' : 'attachEvent',
+        rem = addEventListener ? 'removeEventListener' : 'detachEvent',
+        pre = addEventListener ? '' : 'on',
+
+        init = function(e) {
+          if (e.type == 'readystatechange' && doc.readyState != 'complete') {
+            return;
+          }
+          (e.type == 'load' ? win : doc)[rem](pre + e.type, init, false);
+          if (!done && (done = true)) { callback.call(win, e.type || e); }
+        },
+
+        poll = function() {
+          try {
+            root.doScroll('left');
+          } catch(e) {
+            win.setTimeout(poll, 50);
+            return;
+          }
+          init('poll');
+        };
+
+    if (doc.readyState == 'complete') {
+      callback.call(win, 'lazy');
+    } else {
+      if (doc.createEventObject && root.doScroll) {
+        try { top = !win.frameElement; } catch(e) { }
+        if (top) { poll(); }
+      }
+      doc[add](pre + 'DOMContentLoaded', init, false);
+      doc[add](pre + 'readystatechange', init, false);
+      win[add](pre + 'load', init, false);
+    }
+  }
+
+  // Given a list of URLs to stylesheets, loads the first that loads without
+  // triggering an error event.
+  function loadStylesheetsFallingBack(stylesheets) {
+    var n = stylesheets.length;
+    function load(i) {
+      if (i === n) { return; }
+      var link = doc.createElement('link');
+      link.rel = 'stylesheet';
+      link.type = 'text/css';
+      if (i + 1 < n) {
+        // http://pieisgood.org/test/script-link-events/ indicates that many
+        // versions of IE do not support onerror on <link>s, though
+        // http://msdn.microsoft.com/en-us/library/ie/ms535848(v=vs.85).aspx
+        // indicates that recent IEs do support error.
+        link.error = link.onerror = function () { load(i + 1); };
+      }
+      link.href = stylesheets[i];
+      head.appendChild(link);
+    }
+    load(0);
+  }
+
+  var scriptQuery = '';
+  // Look for the <script> node that loads this script to get its parameters.
+  // This starts looking at the end instead of just considering the last
+  // because deferred and async scripts run out of order.
+  // If the script is loaded twice, then this will run in reverse order.
+  var scripts = doc.getElementsByTagName('script');
+  for (var i = scripts.length; --i >= 0;) {
+    var script = scripts[i];
+    var match = script.src.match(
+        /^[^?#]*\/run_prettify\.js(\?[^#]*)?(?:#.*)?$/);
+    if (match) {
+      scriptQuery = match[1] || '';
+      // Remove the script from the DOM so that multiple runs at least run
+      // multiple times even if parameter sets are interpreted in reverse
+      // order.
+      script.parentNode.removeChild(script);
+      break;
+    }
+  }
+
+  // Pull parameters into local variables.
+  var autorun = true;
+  var langs = [];
+  var skins = [];
+  var callbacks = [];
+  scriptQuery.replace(
+      /[?&]([^&=]+)=([^&]+)/g,
+      function (_, name, value) {
+        value = decodeURIComponent(value);
+        name = decodeURIComponent(name);
+        if (name == 'autorun')   { autorun = !/^[0fn]/i.test(value); } else
+        if (name == 'lang')      { langs.push(value);                } else
+        if (name == 'skin')      { skins.push(value);                } else
+        if (name == 'callback')  { callbacks.push(value);            }
+      });
+
+  // Use https to avoid mixed content warnings in client pages and to
+  // prevent a MITM from rewrite prettify mid-flight.
+  // This only works if this script is loaded via https : something
+  // over which we exercise no control.
+  var LOADER_BASE_URL =
+     'https://cdn.rawgit.com/google/code-prettify/master/loader';
+
+  for (var i = 0, n = langs.length; i < n; ++i) (function (lang) {
+    var script = doc.createElement("script");
+
+    // Excerpted from jQuery.ajaxTransport("script") to fire events when
+    // a script is finished loading.
+    // Attach handlers for each script
+    script.onload = script.onerror = script.onreadystatechange = function () {
+      if (script && (
+            !script.readyState || /loaded|complete/.test(script.readyState))) {
+        // Handle memory leak in IE
+        script.onerror = script.onload = script.onreadystatechange = null;
+
+        --pendingLanguages;
+        checkPendingLanguages();
+
+        // Remove the script
+        if (script.parentNode) {
+          script.parentNode.removeChild(script);
+        }
+
+        script = null;
+      }
+    };
+
+    script.type = 'text/javascript';
+    script.src = LOADER_BASE_URL
+      + '/lang-' + encodeURIComponent(langs[i]) + '.js';
+
+    // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
+    head.insertBefore(script, head.firstChild);
+  })(langs[i]);
+
+  var pendingLanguages = langs.length;
+  function checkPendingLanguages() {
+    if (!pendingLanguages) {
+      win.setTimeout(onLangsLoaded, 0);
+    }
+  }
+
+  var skinUrls = [];
+  for (var i = 0, n = skins.length; i < n; ++i) {
+    skinUrls.push(LOADER_BASE_URL
+        + '/skins/' + encodeURIComponent(skins[i]) + '.css');
+  }
+  skinUrls.push(LOADER_BASE_URL + '/prettify.css');
+  loadStylesheetsFallingBack(skinUrls);
+
+  var prettyPrint = (function () {
+    /**
+     * @license
+     * Copyright (C) 2006 Google Inc.
+     *
+     * Licensed under the Apache License, Version 2.0 (the "License");
+     * you may not use this file except in compliance with the License.
+     * You may obtain a copy of the License at
+     *
+     *      http://www.apache.org/licenses/LICENSE-2.0
+     *
+     * Unless required by applicable law or agreed to in writing, software
+     * distributed under the License is distributed on an "AS IS" BASIS,
+     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     * See the License for the specific language governing permissions and
+     * limitations under the License.
+     */
+    
+    /**
+     * @fileoverview
+     * some functions for browser-side pretty printing of code contained in html.
+     *
+     * <p>
+     * For a fairly comprehensive set of languages see the
+     * <a href="https://github.com/google/code-prettify#for-which-languages-does-it-work">README</a>
+     * file that came with this source.  At a minimum, the lexer should work on a
+     * number of languages including C and friends, Java, Python, Bash, SQL, HTML,
+     * XML, CSS, Javascript, and Makefiles.  It works passably on Ruby, PHP and Awk
+     * and a subset of Perl, but, because of commenting conventions, doesn't work on
+     * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class.
+     * <p>
+     * Usage: <ol>
+     * <li> include this source file in an html page via
+     *   {@code <script type="text/javascript" src="/path/to/prettify.js"></script>}
+     * <li> define style rules.  See the example page for examples.
+     * <li> mark the {@code <pre>} and {@code <code>} tags in your source with
+     *    {@code class=prettyprint.}
+     *    You can also use the (html deprecated) {@code <xmp>} tag, but the pretty
+     *    printer needs to do more substantial DOM manipulations to support that, so
+     *    some css styles may not be preserved.
+     * </ol>
+     * That's it.  I wanted to keep the API as simple as possible, so there's no
+     * need to specify which language the code is in, but if you wish, you can add
+     * another class to the {@code <pre>} or {@code <code>} element to specify the
+     * language, as in {@code <pre class="prettyprint lang-java">}.  Any class that
+     * starts with "lang-" followed by a file extension, specifies the file type.
+     * See the "lang-*.js" files in this directory for code that implements
+     * per-language file handlers.
+     * <p>
+     * Change log:<br>
+     * cbeust, 2006/08/22
+     * <blockquote>
+     *   Java annotations (start with "@") are now captured as literals ("lit")
+     * </blockquote>
+     * @requires console
+     */
+    
+    // JSLint declarations
+    /*global console, document, navigator, setTimeout, window, define */
+    
+    
+    var HACK_TO_FIX_JS_INCLUDE_PL;
+    
+    /**
+     * {@type !{
+     *   'createSimpleLexer': function (Array, Array): (function (JobT)),
+     *   'registerLangHandler': function (function (JobT), Array.<string>),
+     *   'PR_ATTRIB_NAME': string,
+     *   'PR_ATTRIB_NAME': string,
+     *   'PR_ATTRIB_VALUE': string,
+     *   'PR_COMMENT': string,
+     *   'PR_DECLARATION': string,
+     *   'PR_KEYWORD': string,
+     *   'PR_LITERAL': string,
+     *   'PR_NOCODE': string,
+     *   'PR_PLAIN': string,
+     *   'PR_PUNCTUATION': string,
+     *   'PR_SOURCE': string,
+     *   'PR_STRING': string,
+     *   'PR_TAG': string,
+     *   'PR_TYPE': string,
+     *   'prettyPrintOne': function (string, string, number|boolean),
+     *   'prettyPrint': function (?function, ?(HTMLElement|HTMLDocument))
+     * }}
+     * @const
+     */
+    var PR;
+    
+    /**
+     * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
+     * UI events.
+     * If set to {@code false}, {@code prettyPrint()} is synchronous.
+     */
+    window['PR_SHOULD_USE_CONTINUATION'] = true;
+    
+    /**
+     * Pretty print a chunk of code.
+     * @param {string} sourceCodeHtml The HTML to pretty print.
+     * @param {string} opt_langExtension The language name to use.
+     *     Typically, a filename extension like 'cpp' or 'java'.
+     * @param {number|boolean} opt_numberLines True to number lines,
+     *     or the 1-indexed number of the first line in sourceCodeHtml.
+     * @return {string} code as html, but prettier
+     */
+    var prettyPrintOne;
+    /**
+     * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
+     * {@code class=prettyprint} and prettify them.
+     *
+     * @param {Function} opt_whenDone called when prettifying is done.
+     * @param {HTMLElement|HTMLDocument} opt_root an element or document
+     *   containing all the elements to pretty print.
+     *   Defaults to {@code document.body}.
+     */
+    var prettyPrint;
+    
+    
+    (function () {
+      var win = window;
+      // Keyword lists for various languages.
+      // We use things that coerce to strings to make them compact when minified
+      // and to defeat aggressive optimizers that fold large string constants.
+      var FLOW_CONTROL_KEYWORDS = ["break,continue,do,else,for,if,return,while"];
+      var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," +
+          "double,enum,extern,float,goto,inline,int,long,register,restrict,short,signed," +
+          "sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];
+      var COMMON_KEYWORDS = [C_KEYWORDS,"catch,class,delete,false,import," +
+          "new,operator,private,protected,public,this,throw,true,try,typeof"];
+      var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignas,alignof,align_union,asm,axiom,bool," +
+          "concept,concept_map,const_cast,constexpr,decltype,delegate," +
+          "dynamic_cast,explicit,export,friend,generic,late_check," +
+          "mutable,namespace,noexcept,noreturn,nullptr,property,reinterpret_cast,static_assert," +
+          "static_cast,template,typeid,typename,using,virtual,where"];
+      var JAVA_KEYWORDS = [COMMON_KEYWORDS,
+          "abstract,assert,boolean,byte,extends,finally,final,implements,import," +
+          "instanceof,interface,null,native,package,strictfp,super,synchronized," +
+          "throws,transient"];
+      var CSHARP_KEYWORDS = [COMMON_KEYWORDS,
+          "abstract,add,alias,as,ascending,async,await,base,bool,by,byte,checked,decimal,delegate,descending," +
+          "dynamic,event,finally,fixed,foreach,from,get,global,group,implicit,in,interface," +
+          "internal,into,is,join,let,lock,null,object,out,override,orderby,params," +
+          "partial,readonly,ref,remove,sbyte,sealed,select,set,stackalloc,string,select,uint,ulong," +
+          "unchecked,unsafe,ushort,value,var,virtual,where,yield"];
+      var COFFEE_KEYWORDS = "all,and,by,catch,class,else,extends,false,finally," +
+          "for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then," +
+          "throw,true,try,unless,until,when,while,yes";
+      var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS,
+          "abstract,async,await,constructor,debugger,enum,eval,export,function," +
+          "get,implements,instanceof,interface,let,null,set,undefined,var,with," +
+          "yield,Infinity,NaN"];
+      var PERL_KEYWORDS = "caller,delete,die,do,dump,elsif,eval,exit,foreach,for," +
+          "goto,if,import,last,local,my,next,no,our,print,package,redo,require," +
+          "sub,undef,unless,until,use,wantarray,while,BEGIN,END";
+      var PYTHON_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "and,as,assert,class,def,del," +
+          "elif,except,exec,finally,from,global,import,in,is,lambda," +
+          "nonlocal,not,or,pass,print,raise,try,with,yield," +
+          "False,True,None"];
+      var RUBY_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "alias,and,begin,case,class," +
+          "def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo," +
+          "rescue,retry,self,super,then,true,undef,unless,until,when,yield," +
+          "BEGIN,END"];
+      var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "case,done,elif,esac,eval,fi," +
+          "function,in,local,set,then,until"];
+      var ALL_KEYWORDS = [
+          CPP_KEYWORDS, CSHARP_KEYWORDS, JAVA_KEYWORDS, JSCRIPT_KEYWORDS,
+          PERL_KEYWORDS, PYTHON_KEYWORDS, RUBY_KEYWORDS, SH_KEYWORDS];
+      var C_TYPES = /^(DIR|FILE|array|vector|(de|priority_)?queue|(forward_)?list|stack|(const_)?(reverse_)?iterator|(unordered_)?(multi)?(set|map)|bitset|u?(int|float)\d*)\b/;
+    
+      // token style names.  correspond to css classes
+      /**
+       * token style for a string literal
+       * @const
+       */
+      var PR_STRING = 'str';
+      /**
+       * token style for a keyword
+       * @const
+       */
+      var PR_KEYWORD = 'kwd';
+      /**
+       * token style for a comment
+       * @const
+       */
+      var PR_COMMENT = 'com';
+      /**
+       * token style for a type
+       * @const
+       */
+      var PR_TYPE = 'typ';
+      /**
+       * token style for a literal value.  e.g. 1, null, true.
+       * @const
+       */
+      var PR_LITERAL = 'lit';
+      /**
+       * token style for a punctuation string.
+       * @const
+       */
+      var PR_PUNCTUATION = 'pun';
+      /**
+       * token style for plain text.
+       * @const
+       */
+      var PR_PLAIN = 'pln';
+    
+      /**
+       * token style for an sgml tag.
+       * @const
+       */
+      var PR_TAG = 'tag';
+      /**
+       * token style for a markup declaration such as a DOCTYPE.
+       * @const
+       */
+      var PR_DECLARATION = 'dec';
+      /**
+       * token style for embedded source.
+       * @const
+       */
+      var PR_SOURCE = 'src';
+      /**
+       * token style for an sgml attribute name.
+       * @const
+       */
+      var PR_ATTRIB_NAME = 'atn';
+      /**
+       * token style for an sgml attribute value.
+       * @const
+       */
+      var PR_ATTRIB_VALUE = 'atv';
+    
+      /**
+       * A class that indicates a section of markup that is not code, e.g. to allow
+       * embedding of line numbers within code listings.
+       * @const
+       */
+      var PR_NOCODE = 'nocode';
+    
+      
+      
+      /**
+       * A set of tokens that can precede a regular expression literal in
+       * javascript
+       * http://web.archive.org/web/20070717142515/http://www.mozilla.org/js/language/js20/rationale/syntax.html
+       * has the full list, but I've removed ones that might be problematic when
+       * seen in languages that don't support regular expression literals.
+       *
+       * <p>Specifically, I've removed any keywords that can't precede a regexp
+       * literal in a syntactically legal javascript program, and I've removed the
+       * "in" keyword since it's not a keyword in many languages, and might be used
+       * as a count of inches.
+       *
+       * <p>The link above does not accurately describe EcmaScript rules since
+       * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
+       * very well in practice.
+       *
+       * @private
+       * @const
+       */
+      var REGEXP_PRECEDER_PATTERN = '(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*';
+      
+      // CAVEAT: this does not properly handle the case where a regular
+      // expression immediately follows another since a regular expression may
+      // have flags for case-sensitivity and the like.  Having regexp tokens
+      // adjacent is not valid in any language I'm aware of, so I'm punting.
+      // TODO: maybe style special characters inside a regexp as punctuation.
+    
+      /**
+       * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
+       * matches the union of the sets of strings matched by the input RegExp.
+       * Since it matches globally, if the input strings have a start-of-input
+       * anchor (/^.../), it is ignored for the purposes of unioning.
+       * @param {Array.<RegExp>} regexs non multiline, non-global regexs.
+       * @return {RegExp} a global regex.
+       */
+      function combinePrefixPatterns(regexs) {
+        var capturedGroupIndex = 0;
+      
+        var needToFoldCase = false;
+        var ignoreCase = false;
+        for (var i = 0, n = regexs.length; i < n; ++i) {
+          var regex = regexs[i];
+          if (regex.ignoreCase) {
+            ignoreCase = true;
+          } else if (/[a-z]/i.test(regex.source.replace(
+                         /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
+            needToFoldCase = true;
+            ignoreCase = false;
+            break;
+          }
+        }
+      
+        var escapeCharToCodeUnit = {
+          'b': 8,
+          't': 9,
+          'n': 0xa,
+          'v': 0xb,
+          'f': 0xc,
+          'r': 0xd
+        };
+      
+        function decodeEscape(charsetPart) {
+          var cc0 = charsetPart.charCodeAt(0);
+          if (cc0 !== 92 /* \\ */) {
+            return cc0;
+          }
+          var c1 = charsetPart.charAt(1);
+          cc0 = escapeCharToCodeUnit[c1];
+          if (cc0) {
+            return cc0;
+          } else if ('0' <= c1 && c1 <= '7') {
+            return parseInt(charsetPart.substring(1), 8);
+          } else if (c1 === 'u' || c1 === 'x') {
+            return parseInt(charsetPart.substring(2), 16);
+          } else {
+            return charsetPart.charCodeAt(1);
+          }
+        }
+      
+        function encodeEscape(charCode) {
+          if (charCode < 0x20) {
+            return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
+          }
+          var ch = String.fromCharCode(charCode);
+          return (ch === '\\' || ch === '-' || ch === ']' || ch === '^')
+              ? "\\" + ch : ch;
+        }
+      
+        function caseFoldCharset(charSet) {
+          var charsetParts = charSet.substring(1, charSet.length - 1).match(
+              new RegExp(
+                  '\\\\u[0-9A-Fa-f]{4}'
+                  + '|\\\\x[0-9A-Fa-f]{2}'
+                  + '|\\\\[0-3][0-7]{0,2}'
+                  + '|\\\\[0-7]{1,2}'
+                  + '|\\\\[\\s\\S]'
+                  + '|-'
+                  + '|[^-\\\\]',
+                  'g'));
+          var ranges = [];
+          var inverse = charsetParts[0] === '^';
+      
+          var out = ['['];
+          if (inverse) { out.push('^'); }
+      
+          for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
+            var p = charsetParts[i];
+            if (/\\[bdsw]/i.test(p)) {  // Don't muck with named groups.
+              out.push(p);
+            } else {
+              var start = decodeEscape(p);
+              var end;
+              if (i + 2 < n && '-' === charsetParts[i + 1]) {
+                end = decodeEscape(charsetParts[i + 2]);
+                i += 2;
+              } else {
+                end = start;
+              }
+              ranges.push([start, end]);
+              // If the range might intersect letters, then expand it.
+              // This case handling is too simplistic.
+              // It does not deal with non-latin case folding.
+              // It works for latin source code identifiers though.
+              if (!(end < 65 || start > 122)) {
+                if (!(end < 65 || start > 90)) {
+                  ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
+                }
+                if (!(end < 97 || start > 122)) {
+                  ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
+                }
+              }
+            }
+          }
+      
+          // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
+          // -> [[1, 12], [14, 14], [16, 17]]
+          ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1]  - a[1]); });
+          var consolidatedRanges = [];
+          var lastRange = [];
+          for (var i = 0; i < ranges.length; ++i) {
+            var range = ranges[i];
+            if (range[0] <= lastRange[1] + 1) {
+              lastRange[1] = Math.max(lastRange[1], range[1]);
+            } else {
+              consolidatedRanges.push(lastRange = range);
+            }
+          }
+      
+          for (var i = 0; i < consolidatedRanges.length; ++i) {
+            var range = consolidatedRanges[i];
+            out.push(encodeEscape(range[0]));
+            if (range[1] > range[0]) {
+              if (range[1] + 1 > range[0]) { out.push('-'); }
+              out.push(encodeEscape(range[1]));
+            }
+          }
+          out.push(']');
+          return out.join('');
+        }
+      
+        function allowAnywhereFoldCaseAndRenumberGroups(regex) {
+          // Split into character sets, escape sequences, punctuation strings
+          // like ('(', '(?:', ')', '^'), and runs of characters that do not
+          // include any of the above.
+          var parts = regex.source.match(
+              new RegExp(
+                  '(?:'
+                  + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]'  // a character set
+                  + '|\\\\u[A-Fa-f0-9]{4}'  // a unicode escape
+                  + '|\\\\x[A-Fa-f0-9]{2}'  // a hex escape
+                  + '|\\\\[0-9]+'  // a back-reference or octal escape
+                  + '|\\\\[^ux0-9]'  // other escape sequence
+                  + '|\\(\\?[:!=]'  // start of a non-capturing group
+                  + '|[\\(\\)\\^]'  // start/end of a group, or line start
+                  + '|[^\\x5B\\x5C\\(\\)\\^]+'  // run of other characters
+                  + ')',
+                  'g'));
+          var n = parts.length;
+      
+          // Maps captured group numbers to the number they will occupy in
+          // the output or to -1 if that has not been determined, or to
+          // undefined if they need not be capturing in the output.
+          var capturedGroups = [];
+      
+          // Walk over and identify back references to build the capturedGroups
+          // mapping.
+          for (var i = 0, groupIndex = 0; i < n; ++i) {
+            var p = parts[i];
+            if (p === '(') {
+              // groups are 1-indexed, so max group index is count of '('
+              ++groupIndex;
+            } else if ('\\' === p.charAt(0)) {
+              var decimalValue = +p.substring(1);
+              if (decimalValue) {
+                if (decimalValue <= groupIndex) {
+                  capturedGroups[decimalValue] = -1;
+                } else {
+                  // Replace with an unambiguous escape sequence so that
+                  // an octal escape sequence does not turn into a backreference
+                  // to a capturing group from an earlier regex.
+                  parts[i] = encodeEscape(decimalValue);
+                }
+              }
+            }
+          }
+      
+          // Renumber groups and reduce capturing groups to non-capturing groups
+          // where possible.
+          for (var i = 1; i < capturedGroups.length; ++i) {
+            if (-1 === capturedGroups[i]) {
+              capturedGroups[i] = ++capturedGroupIndex;
+            }
+          }
+          for (var i = 0, groupIndex = 0; i < n; ++i) {
+            var p = parts[i];
+            if (p === '(') {
+              ++groupIndex;
+              if (!capturedGroups[groupIndex]) {
+                parts[i] = '(?:';
+              }
+            } else if ('\\' === p.charAt(0)) {
+              var decimalValue = +p.substring(1);
+              if (decimalValue && decimalValue <= groupIndex) {
+                parts[i] = '\\' + capturedGroups[decimalValue];
+              }
+            }
+          }
+      
+          // Remove any prefix anchors so that the output will match anywhere.
+          // ^^ really does mean an anchored match though.
+          for (var i = 0; i < n; ++i) {
+            if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
+          }
+      
+          // Expand letters to groups to handle mixing of case-sensitive and
+          // case-insensitive patterns if necessary.
+          if (regex.ignoreCase && needToFoldCase) {
+            for (var i = 0; i < n; ++i) {
+              var p = parts[i];
+              var ch0 = p.charAt(0);
+              if (p.length >= 2 && ch0 === '[') {
+                parts[i] = caseFoldCharset(p);
+              } else if (ch0 !== '\\') {
+                // TODO: handle letters in numeric escapes.
+                parts[i] = p.replace(
+                    /[a-zA-Z]/g,
+                    function (ch) {
+                      var cc = ch.charCodeAt(0);
+                      return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
+                    });
+              }
+            }
+          }
+      
+          return parts.join('');
+        }
+      
+        var rewritten = [];
+        for (var i = 0, n = regexs.length; i < n; ++i) {
+          var regex = regexs[i];
+          if (regex.global || regex.multiline) { throw new Error('' + regex); }
+          rewritten.push(
+              '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
+        }
+      
+        return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
+      }
+    
+      /**
+       * Split markup into a string of source code and an array mapping ranges in
+       * that string to the text nodes in which they appear.
+       *
+       * <p>
+       * The HTML DOM structure:</p>
+       * <pre>
+       * (Element   "p"
+       *   (Element "b"
+       *     (Text  "print "))       ; #1
+       *   (Text    "'Hello '")      ; #2
+       *   (Element "br")            ; #3
+       *   (Text    "  + 'World';")) ; #4
+       * </pre>
+       * <p>
+       * corresponds to the HTML
+       * {@code <p><b>print </b>'Hello '<br>  + 'World';</p>}.</p>
+       *
+       * <p>
+       * It will produce the output:</p>
+       * <pre>
+       * {
+       *   sourceCode: "print 'Hello '\n  + 'World';",
+       *   //                     1          2
+       *   //           012345678901234 5678901234567
+       *   spans: [0, #1, 6, #2, 14, #3, 15, #4]
+       * }
+       * </pre>
+       * <p>
+       * where #1 is a reference to the {@code "print "} text node above, and so
+       * on for the other text nodes.
+       * </p>
+       *
+       * <p>
+       * The {@code} spans array is an array of pairs.  Even elements are the start
+       * indices of substrings, and odd elements are the text nodes (or BR elements)
+       * that contain the text for those substrings.
+       * Substrings continue until the next index or the end of the source.
+       * </p>
+       *
+       * @param {Node} node an HTML DOM subtree containing source-code.
+       * @param {boolean|number} isPreformatted truthy if white-space in
+       *    text nodes should be considered significant.
+       * @return {SourceSpansT} source code and the nodes in which they occur.
+       */
+      function extractSourceSpans(node, isPreformatted) {
+        var nocode = /(?:^|\s)nocode(?:\s|$)/;
+      
+        var chunks = [];
+        var length = 0;
+        var spans = [];
+        var k = 0;
+      
+        function walk(node) {
+          var type = node.nodeType;
+          if (type == 1) {  // Element
+            if (nocode.test(node.className)) { return; }
+            for (var child = node.firstChild; child; child = child.nextSibling) {
+              walk(child);
+            }
+            var nodeName = node.nodeName.toLowerCase();
+            if ('br' === nodeName || 'li' === nodeName) {
+              chunks[k] = '\n';
+              spans[k << 1] = length++;
+              spans[(k++ << 1) | 1] = node;
+            }
+          } else if (type == 3 || type == 4) {  // Text
+            var text = node.nodeValue;
+            if (text.length) {
+              if (!isPreformatted) {
+                text = text.replace(/[ \t\r\n]+/g, ' ');
+              } else {
+                text = text.replace(/\r\n?/g, '\n');  // Normalize newlines.
+              }
+              // TODO: handle tabs here?
+              chunks[k] = text;
+              spans[k << 1] = length;
+              length += text.length;
+              spans[(k++ << 1) | 1] = node;
+            }
+          }
+        }
+      
+        walk(node);
+      
+        return {
+          sourceCode: chunks.join('').replace(/\n$/, ''),
+          spans: spans
+        };
+      }
+    
+      /**
+       * Apply the given language handler to sourceCode and add the resulting
+       * decorations to out.
+       * @param {!Element} sourceNode
+       * @param {number} basePos the index of sourceCode within the chunk of source
+       *    whose decorations are already present on out.
+       * @param {string} sourceCode
+       * @param {function(JobT)} langHandler
+       * @param {DecorationsT} out
+       */
+      function appendDecorations(
+          sourceNode, basePos, sourceCode, langHandler, out) {
+        if (!sourceCode) { return; }
+        /** @type {JobT} */
+        var job = {
+          sourceNode: sourceNode,
+          pre: 1,
+          langExtension: null,
+          numberLines: null,
+          sourceCode: sourceCode,
+          spans: null,
+          basePos: basePos,
+          decorations: null
+        };
+        langHandler(job);
+        out.push.apply(out, job.decorations);
+      }
+    
+      var notWs = /\S/;
+    
+      /**
+       * Given an element, if it contains only one child element and any text nodes
+       * it contains contain only space characters, return the sole child element.
+       * Otherwise returns undefined.
+       * <p>
+       * This is meant to return the CODE element in {@code <pre><code ...>} when
+       * there is a single child element that contains all the non-space textual
+       * content, but not to return anything where there are multiple child elements
+       * as in {@code <pre><code>...</code><code>...</code></pre>} or when there
+       * is textual content.
+       */
+      function childContentWrapper(element) {
+        var wrapper = undefined;
+        for (var c = element.firstChild; c; c = c.nextSibling) {
+          var type = c.nodeType;
+          wrapper = (type === 1)  // Element Node
+              ? (wrapper ? element : c)
+              : (type === 3)  // Text Node
+              ? (notWs.test(c.nodeValue) ? element : wrapper)
+              : wrapper;
+        }
+        return wrapper === element ? undefined : wrapper;
+      }
+    
+      /** Given triples of [style, pattern, context] returns a lexing function,
+        * The lexing function interprets the patterns to find token boundaries and
+        * returns a decoration list of the form
+        * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
+        * where index_n is an index into the sourceCode, and style_n is a style
+        * constant like PR_PLAIN.  index_n-1 <= index_n, and style_n-1 applies to
+        * all characters in sourceCode[index_n-1:index_n].
+        *
+        * The stylePatterns is a list whose elements have the form
+        * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
+        *
+        * Style is a style constant like PR_PLAIN, or can be a string of the
+        * form 'lang-FOO', where FOO is a language extension describing the
+        * language of the portion of the token in $1 after pattern executes.
+        * E.g., if style is 'lang-lisp', and group 1 contains the text
+        * '(hello (world))', then that portion of the token will be passed to the
+        * registered lisp handler for formatting.
+        * The text before and after group 1 will be restyled using this decorator
+        * so decorators should take care that this doesn't result in infinite
+        * recursion.  For example, the HTML lexer rule for SCRIPT elements looks
+        * something like ['lang-js', /<[s]cript>(.+?)<\/script>/].  This may match
+        * '<script>foo()<\/script>', which would cause the current decorator to
+        * be called with '<script>' which would not match the same rule since
+        * group 1 must not be empty, so it would be instead styled as PR_TAG by
+        * the generic tag rule.  The handler registered for the 'js' extension would
+        * then be called with 'foo()', and finally, the current decorator would
+        * be called with '<\/script>' which would not match the original rule and
+        * so the generic tag rule would identify it as a tag.
+        *
+        * Pattern must only match prefixes, and if it matches a prefix, then that
+        * match is considered a token with the same style.
+        *
+        * Context is applied to the last non-whitespace, non-comment token
+        * recognized.
+        *
+        * Shortcut is an optional string of characters, any of which, if the first
+        * character, gurantee that this pattern and only this pattern matches.
+        *
+        * @param {Array} shortcutStylePatterns patterns that always start with
+        *   a known character.  Must have a shortcut string.
+        * @param {Array} fallthroughStylePatterns patterns that will be tried in
+        *   order if the shortcut ones fail.  May have shortcuts.
+        *
+        * @return {function (JobT)} a function that takes an undecorated job and
+        *   attaches a list of decorations.
+        */
+      function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {
+        var shortcuts = {};
+        var tokenizer;
+        (function () {
+          var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);
+          var allRegexs = [];
+          var regexKeys = {};
+          for (var i = 0, n = allPatterns.length; i < n; ++i) {
+            var patternParts = allPatterns[i];
+            var shortcutChars = patternParts[3];
+            if (shortcutChars) {
+              for (var c = shortcutChars.length; --c >= 0;) {
+                shortcuts[shortcutChars.charAt(c)] = patternParts;
+              }
+            }
+            var regex = patternParts[1];
+            var k = '' + regex;
+            if (!regexKeys.hasOwnProperty(k)) {
+              allRegexs.push(regex);
+              regexKeys[k] = null;
+            }
+          }
+          allRegexs.push(/[\0-\uffff]/);
+          tokenizer = combinePrefixPatterns(allRegexs);
+        })();
+    
+        var nPatterns = fallthroughStylePatterns.length;
+    
+        /**
+         * Lexes job.sourceCode and attaches an output array job.decorations of
+         * style classes preceded by the position at which they start in
+         * job.sourceCode in order.
+         *
+         * @type{function (JobT)}
+         */
+        var decorate = function (job) {
+          var sourceCode = job.sourceCode, basePos = job.basePos;
+          var sourceNode = job.sourceNode;
+          /** Even entries are positions in source in ascending order.  Odd enties
+            * are style markers (e.g., PR_COMMENT) that run from that position until
+            * the end.
+            * @type {DecorationsT}
+            */
+          var decorations = [basePos, PR_PLAIN];
+          var pos = 0;  // index into sourceCode
+          var tokens = sourceCode.match(tokenizer) || [];
+          var styleCache = {};
+    
+          for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
+            var token = tokens[ti];
+            var style = styleCache[token];
+            var match = void 0;
+    
+            var isEmbedded;
+            if (typeof style === 'string') {
+              isEmbedded = false;
+            } else {
+              var patternParts = shortcuts[token.charAt(0)];
+              if (patternParts) {
+                match = token.match(patternParts[1]);
+                style = patternParts[0];
+              } else {
+                for (var i = 0; i < nPatterns; ++i) {
+                  patternParts = fallthroughStylePatterns[i];
+                  match = token.match(patternParts[1]);
+                  if (match) {
+                    style = patternParts[0];
+                    break;
+                  }
+                }
+    
+                if (!match) {  // make sure that we make progress
+                  style = PR_PLAIN;
+                }
+              }
+    
+              isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);
+              if (isEmbedded && !(match && typeof match[1] === 'string')) {
+                isEmbedded = false;
+                style = PR_SOURCE;
+              }
+    
+              if (!isEmbedded) { styleCache[token] = style; }
+            }
+    
+            var tokenStart = pos;
+            pos += token.length;
+    
+            if (!isEmbedded) {
+              decorations.push(basePos + tokenStart, style);
+            } else {  // Treat group 1 as an embedded block of source code.
+              var embeddedSource = match[1];
+              var embeddedSourceStart = token.indexOf(embeddedSource);
+              var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;
+              if (match[2]) {
+                // If embeddedSource can be blank, then it would match at the
+                // beginning which would cause us to infinitely recurse on the
+                // entire token, so we catch the right context in match[2].
+                embeddedSourceEnd = token.length - match[2].length;
+                embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;
+              }
+              var lang = style.substring(5);
+              // Decorate the left of the embedded source
+              appendDecorations(
+                  sourceNode,
+                  basePos + tokenStart,
+                  token.substring(0, embeddedSourceStart),
+                  decorate, decorations);
+              // Decorate the embedded source
+              appendDecorations(
+                  sourceNode,
+                  basePos + tokenStart + embeddedSourceStart,
+                  embeddedSource,
+                  langHandlerForExtension(lang, embeddedSource),
+                  decorations);
+              // Decorate the right of the embedded section
+              appendDecorations(
+                  sourceNode,
+                  basePos + tokenStart + embeddedSourceEnd,
+                  token.substring(embeddedSourceEnd),
+                  decorate, decorations);
+            }
+          }
+          job.decorations = decorations;
+        };
+        return decorate;
+      }
+    
+      /** returns a function that produces a list of decorations from source text.
+        *
+        * This code treats ", ', and ` as string delimiters, and \ as a string
+        * escape.  It does not recognize perl's qq() style strings.
+        * It has no special handling for double delimiter escapes as in basic, or
+        * the tripled delimiters used in python, but should work on those regardless
+        * although in those cases a single string literal may be broken up into
+        * multiple adjacent string literals.
+        *
+        * It recognizes C, C++, and shell style comments.
+        *
+        * @param {Object} options a set of optional parameters.
+        * @return {function (JobT)} a function that examines the source code
+        *     in the input job and builds a decoration list which it attaches to
+        *     the job.
+        */
+      function sourceDecorator(options) {
+        var shortcutStylePatterns = [], fallthroughStylePatterns = [];
+        if (options['tripleQuotedStrings']) {
+          // '''multi-line-string''', 'single-line-string', and double-quoted
+          shortcutStylePatterns.push(
+              [PR_STRING,  /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
+               null, '\'"']);
+        } else if (options['multiLineStrings']) {
+          // 'multi-line-string', "multi-line-string"
+          shortcutStylePatterns.push(
+              [PR_STRING,  /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,
+               null, '\'"`']);
+        } else {
+          // 'single-line-string', "single-line-string"
+          shortcutStylePatterns.push(
+              [PR_STRING,
+               /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
+               null, '"\'']);
+        }
+        if (options['verbatimStrings']) {
+          // verbatim-string-literal production from the C# grammar.  See issue 93.
+          fallthroughStylePatterns.push(
+              [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]);
+        }
+        var hc = options['hashComments'];
+        if (hc) {
+          if (options['cStyleComments']) {
+            if (hc > 1) {  // multiline hash comments
+              shortcutStylePatterns.push(
+                  [PR_COMMENT, /^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/, null, '#']);
+            } else {
+              // Stop C preprocessor declarations at an unclosed open comment
+              shortcutStylePatterns.push(
+                  [PR_COMMENT, /^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\r\n]*)/,
+                   null, '#']);
+            }
+            // #include <stdio.h>
+            fallthroughStylePatterns.push(
+                [PR_STRING,
+                 /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,
+                 null]);
+          } else {
+            shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']);
+          }
+        }
+        if (options['cStyleComments']) {
+          fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]);
+          fallthroughStylePatterns.push(
+              [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]);
+        }
+        var regexLiterals = options['regexLiterals'];
+        if (regexLiterals) {
+          /**
+           * @const
+           */
+          var regexExcls = regexLiterals > 1
+            ? ''  // Multiline regex literals
+            : '\n\r';
+          /**
+           * @const
+           */
+          var regexAny = regexExcls ? '.' : '[\\S\\s]';
+          /**
+           * @const
+           */
+          var REGEX_LITERAL = (
+              // A regular expression literal starts with a slash that is
+              // not followed by * or / so that it is not confused with
+              // comments.
+              '/(?=[^/*' + regexExcls + '])'
+              // and then contains any number of raw characters,
+              + '(?:[^/\\x5B\\x5C' + regexExcls + ']'
+              // escape sequences (\x5C),
+              +    '|\\x5C' + regexAny
+              // or non-nesting character sets (\x5B\x5D);
+              +    '|\\x5B(?:[^\\x5C\\x5D' + regexExcls + ']'
+              +             '|\\x5C' + regexAny + ')*(?:\\x5D|$))+'
+              // finally closed by a /.
+              + '/');
+          fallthroughStylePatterns.push(
+              ['lang-regex',
+               RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')
+               ]);
+        }
+    
+        var types = options['types'];
+        if (types) {
+          fallthroughStylePatterns.push([PR_TYPE, types]);
+        }
+    
+        var keywords = ("" + options['keywords']).replace(/^ | $/g, '');
+        if (keywords.length) {
+          fallthroughStylePatterns.push(
+              [PR_KEYWORD,
+               new RegExp('^(?:' + keywords.replace(/[\s,]+/g, '|') + ')\\b'),
+               null]);
+        }
+    
+        shortcutStylePatterns.push([PR_PLAIN,       /^\s+/, null, ' \r\n\t\xA0']);
+    
+        var punctuation =
+          // The Bash man page says
+    
+          // A word is a sequence of characters considered as a single
+          // unit by GRUB. Words are separated by metacharacters,
+          // which are the following plus space, tab, and newline: { }
+          // | & $ ; < >
+          // ...
+    
+          // A word beginning with # causes that word and all remaining
+          // characters on that line to be ignored.
+    
+          // which means that only a '#' after /(?:^|[{}|&$;<>\s])/ starts a
+          // comment but empirically
+          // $ echo {#}
+          // {#}
+          // $ echo \$#
+          // $#
+          // $ echo }#
+          // }#
+    
+          // so /(?:^|[|&;<>\s])/ is more appropriate.
+    
+          // http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC3
+          // suggests that this definition is compatible with a
+          // default mode that tries to use a single token definition
+          // to recognize both bash/python style comments and C
+          // preprocessor directives.
+    
+          // This definition of punctuation does not include # in the list of
+          // follow-on exclusions, so # will not be broken before if preceeded
+          // by a punctuation character.  We could try to exclude # after
+          // [|&;<>] but that doesn't seem to cause many major problems.
+          // If that does turn out to be a problem, we should change the below
+          // when hc is truthy to include # in the run of punctuation characters
+          // only when not followint [|&;<>].
+          '^.[^\\s\\w.$@\'"`/\\\\]*';
+        if (options['regexLiterals']) {
+          punctuation += '(?!\s*\/)';
+        }
+    
+        fallthroughStylePatterns.push(
+            // TODO(mikesamuel): recognize non-latin letters and numerals in idents
+            [PR_LITERAL,     /^@[a-z_$][a-z_$@0-9]*/i, null],
+            [PR_TYPE,        /^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/, null],
+            [PR_PLAIN,       /^[a-z_$][a-z_$@0-9]*/i, null],
+            [PR_LITERAL,
+             new RegExp(
+                 '^(?:'
+                 // A hex number
+                 + '0x[a-f0-9]+'
+                 // or an octal or decimal number,
+                 + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
+                 // possibly in scientific notation
+                 + '(?:e[+\\-]?\\d+)?'
+                 + ')'
+                 // with an optional modifier like UL for unsigned long
+                 + '[a-z]*', 'i'),
+             null, '0123456789'],
+            // Don't treat escaped quotes in bash as starting strings.
+            // See issue 144.
+            [PR_PLAIN,       /^\\[\s\S]?/, null],
+            [PR_PUNCTUATION, new RegExp(punctuation), null]);
+    
+        return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
+      }
+    
+      var decorateSource = sourceDecorator({
+            'keywords': ALL_KEYWORDS,
+            'hashComments': true,
+            'cStyleComments': true,
+            'multiLineStrings': true,
+            'regexLiterals': true
+          });
+    
+      /**
+       * Given a DOM subtree, wraps it in a list, and puts each line into its own
+       * list item.
+       *
+       * @param {Node} node modified in place.  Its content is pulled into an
+       *     HTMLOListElement, and each line is moved into a separate list item.
+       *     This requires cloning elements, so the input might not have unique
+       *     IDs after numbering.
+       * @param {number|null|boolean} startLineNum
+       *     If truthy, coerced to an integer which is the 1-indexed line number
+       *     of the first line of code.  The number of the first line will be
+       *     attached to the list.
+       * @param {boolean} isPreformatted true iff white-space in text nodes should
+       *     be treated as significant.
+       */
+      function numberLines(node, startLineNum, isPreformatted) {
+        var nocode = /(?:^|\s)nocode(?:\s|$)/;
+        var lineBreak = /\r\n?|\n/;
+      
+        var document = node.ownerDocument;
+      
+        var li = document.createElement('li');
+        while (node.firstChild) {
+          li.appendChild(node.firstChild);
+        }
+        // An array of lines.  We split below, so this is initialized to one
+        // un-split line.
+        var listItems = [li];
+      
+        function walk(node) {
+          var type = node.nodeType;
+          if (type == 1 && !nocode.test(node.className)) {  // Element
+            if ('br' === node.nodeName) {
+              breakAfter(node);
+              // Discard the <BR> since it is now flush against a </LI>.
+              if (node.parentNode) {
+                node.parentNode.removeChild(node);
+              }
+            } else {
+              for (var child = node.firstChild; child; child = child.nextSibling) {
+                walk(child);
+              }
+            }
+          } else if ((type == 3 || type == 4) && isPreformatted) {  // Text
+            var text = node.nodeValue;
+            var match = text.match(lineBreak);
+            if (match) {
+              var firstLine = text.substring(0, match.index);
+              node.nodeValue = firstLine;
+              var tail = text.substring(match.index + match[0].length);
+              if (tail) {
+                var parent = node.parentNode;
+                parent.insertBefore(
+                  document.createTextNode(tail), node.nextSibling);
+              }
+              breakAfter(node);
+              if (!firstLine) {
+                // Don't leave blank text nodes in the DOM.
+                node.parentNode.removeChild(node);
+              }
+            }
+          }
+        }
+      
+        // Split a line after the given node.
+        function breakAfter(lineEndNode) {
+          // If there's nothing to the right, then we can skip ending the line
+          // here, and move root-wards since splitting just before an end-tag
+          // would require us to create a bunch of empty copies.
+          while (!lineEndNode.nextSibling) {
+            lineEndNode = lineEndNode.parentNode;
+            if (!lineEndNode) { return; }
+          }
+      
+          function breakLeftOf(limit, copy) {
+            // Clone shallowly if this node needs to be on both sides of the break.
+            var rightSide = copy ? limit.cloneNode(false) : limit;
+            var parent = limit.parentNode;
+            if (parent) {
+              // We clone the parent chain.
+              // This helps us resurrect important styling elements that cross lines.
+              // E.g. in <i>Foo<br>Bar</i>
+              // should be rewritten to <li><i>Foo</i></li><li><i>Bar</i></li>.
+              var parentClone = breakLeftOf(parent, 1);
+              // Move the clone and everything to the right of the original
+              // onto the cloned parent.
+              var next = limit.nextSibling;
+              parentClone.appendChild(rightSide);
+              for (var sibling = next; sibling; sibling = next) {
+                next = sibling.nextSibling;
+                parentClone.appendChild(sibling);
+              }
+            }
+            return rightSide;
+          }
+      
+          var copiedListItem = breakLeftOf(lineEndNode.nextSibling, 0);
+      
+          // Walk the parent chain until we reach an unattached LI.
+          for (var parent;
+               // Check nodeType since IE invents document fragments.
+               (parent = copiedListItem.parentNode) && parent.nodeType === 1;) {
+            copiedListItem = parent;
+          }
+          // Put it on the list of lines for later processing.
+          listItems.push(copiedListItem);
+        }
+      
+        // Split lines while there are lines left to split.
+        for (var i = 0;  // Number of lines that have been split so far.
+             i < listItems.length;  // length updated by breakAfter calls.
+             ++i) {
+          walk(listItems[i]);
+        }
+      
+        // Make sure numeric indices show correctly.
+        if (startLineNum === (startLineNum|0)) {
+          listItems[0].setAttribute('value', startLineNum);
+        }
+      
+        var ol = document.createElement('ol');
+        ol.className = 'linenums';
+        var offset = Math.max(0, ((startLineNum - 1 /* zero index */)) | 0) || 0;
+        for (var i = 0, n = listItems.length; i < n; ++i) {
+          li = listItems[i];
+          // Stick a class on the LIs so that stylesheets can
+          // color odd/even rows, or any other row pattern that
+          // is co-prime with 10.
+          li.className = 'L' + ((i + offset) % 10);
+          if (!li.firstChild) {
+            li.appendChild(document.createTextNode('\xA0'));
+          }
+          ol.appendChild(li);
+        }
+      
+        node.appendChild(ol);
+      }
+    
+      /**
+       * Breaks {@code job.sourceCode} around style boundaries in
+       * {@code job.decorations} and modifies {@code job.sourceNode} in place.
+       * @param {JobT} job
+       * @private
+       */
+      function recombineTagsAndDecorations(job) {
+        var isIE8OrEarlier = /\bMSIE\s(\d+)/.exec(navigator.userAgent);
+        isIE8OrEarlier = isIE8OrEarlier && +isIE8OrEarlier[1] <= 8;
+        var newlineRe = /\n/g;
+      
+        var source = job.sourceCode;
+        var sourceLength = source.length;
+        // Index into source after the last code-unit recombined.
+        var sourceIndex = 0;
+      
+        var spans = job.spans;
+        var nSpans = spans.length;
+        // Index into spans after the last span which ends at or before sourceIndex.
+        var spanIndex = 0;
+      
+        var decorations = job.decorations;
+        var nDecorations = decorations.length;
+        // Index into decorations after the last decoration which ends at or before
+        // sourceIndex.
+        var decorationIndex = 0;
+      
+        // Remove all zero-length decorations.
+        decorations[nDecorations] = sourceLength;
+        var decPos, i;
+        for (i = decPos = 0; i < nDecorations;) {
+          if (decorations[i] !== decorations[i + 2]) {
+            decorations[decPos++] = decorations[i++];
+            decorations[decPos++] = decorations[i++];
+          } else {
+            i += 2;
+          }
+        }
+        nDecorations = decPos;
+      
+        // Simplify decorations.
+        for (i = decPos = 0; i < nDecorations;) {
+          var startPos = decorations[i];
+          // Conflate all adjacent decorations that use the same style.
+          var startDec = decorations[i + 1];
+          var end = i + 2;
+          while (end + 2 <= nDecorations && decorations[end + 1] === startDec) {
+            end += 2;
+          }
+          decorations[decPos++] = startPos;
+          decorations[decPos++] = startDec;
+          i = end;
+        }
+      
+        nDecorations = decorations.length = decPos;
+      
+        var sourceNode = job.sourceNode;
+        var oldDisplay = "";
+        if (sourceNode) {
+          oldDisplay = sourceNode.style.display;
+          sourceNode.style.display = 'none';
+        }
+        try {
+          var decoration = null;
+          while (spanIndex < nSpans) {
+            var spanStart = spans[spanIndex];
+            var spanEnd = /** @type{number} */ (spans[spanIndex + 2])
+                || sourceLength;
+      
+            var decEnd = decorations[decorationIndex + 2] || sourceLength;
+      
+            var end = Math.min(spanEnd, decEnd);
+      
+            var textNode = /** @type{Node} */ (spans[spanIndex + 1]);
+            var styledText;
+            if (textNode.nodeType !== 1  // Don't muck with <BR>s or <LI>s
+                // Don't introduce spans around empty text nodes.
+                && (styledText = source.substring(sourceIndex, end))) {
+              // This may seem bizarre, and it is.  Emitting LF on IE causes the
+              // code to display with spaces instead of line breaks.
+              // Emitting Windows standard issue linebreaks (CRLF) causes a blank
+              // space to appear at the beginning of every line but the first.
+              // Emitting an old Mac OS 9 line separator makes everything spiffy.
+              if (isIE8OrEarlier) {
+                styledText = styledText.replace(newlineRe, '\r');
+              }
+              textNode.nodeValue = styledText;
+              var document = textNode.ownerDocument;
+              var span = document.createElement('span');
+              span.className = decorations[decorationIndex + 1];
+              var parentNode = textNode.parentNode;
+              parentNode.replaceChild(span, textNode);
+              span.appendChild(textNode);
+              if (sourceIndex < spanEnd) {  // Split off a text node.
+                spans[spanIndex + 1] = textNode
+                    // TODO: Possibly optimize by using '' if there's no flicker.
+                    = document.createTextNode(source.substring(end, spanEnd));
+                parentNode.insertBefore(textNode, span.nextSibling);
+              }
+            }
+      
+            sourceIndex = end;
+      
+            if (sourceIndex >= spanEnd) {
+              spanIndex += 2;
+            }
+            if (sourceIndex >= decEnd) {
+              decorationIndex += 2;
+            }
+          }
+        } finally {
+          if (sourceNode) {
+            sourceNode.style.display = oldDisplay;
+          }
+        }
+      }
+    
+      /** Maps language-specific file extensions to handlers. */
+      var langHandlerRegistry = {};
+      /** Register a language handler for the given file extensions.
+        * @param {function (JobT)} handler a function from source code to a list
+        *      of decorations.  Takes a single argument job which describes the
+        *      state of the computation and attaches the decorations to it.
+        * @param {Array.<string>} fileExtensions
+        */
+      function registerLangHandler(handler, fileExtensions) {
+        for (var i = fileExtensions.length; --i >= 0;) {
+          var ext = fileExtensions[i];
+          if (!langHandlerRegistry.hasOwnProperty(ext)) {
+            langHandlerRegistry[ext] = handler;
+          } else if (win['console']) {
+            console['warn']('cannot override language handler %s', ext);
+          }
+        }
+      }
+      function langHandlerForExtension(extension, source) {
+        if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {
+          // Treat it as markup if the first non whitespace character is a < and
+          // the last non-whitespace character is a >.
+          extension = /^\s*</.test(source)
+              ? 'default-markup'
+              : 'default-code';
+        }
+        return langHandlerRegistry[extension];
+      }
+      registerLangHandler(decorateSource, ['default-code']);
+      registerLangHandler(
+          createSimpleLexer(
+              [],
+              [
+               [PR_PLAIN,       /^[^<?]+/],
+               [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/],
+               [PR_COMMENT,     /^<\!--[\s\S]*?(?:-\->|$)/],
+               // Unescaped content in an unknown language
+               ['lang-',        /^<\?([\s\S]+?)(?:\?>|$)/],
+               ['lang-',        /^<%([\s\S]+?)(?:%>|$)/],
+               [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],
+               ['lang-',        /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],
+               // Unescaped content in javascript.  (Or possibly vbscript).
+               ['lang-js',      /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],
+               // Contains unescaped stylesheet content
+               ['lang-css',     /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],
+               ['lang-in.tag',  /^(<\/?[a-z][^<>]*>)/i]
+              ]),
+          ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);
+      registerLangHandler(
+          createSimpleLexer(
+              [
+               [PR_PLAIN,        /^[\s]+/, null, ' \t\r\n'],
+               [PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\'']
+               ],
+              [
+               [PR_TAG,          /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
+               [PR_ATTRIB_NAME,  /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],
+               ['lang-uq.val',   /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
+               [PR_PUNCTUATION,  /^[=<>\/]+/],
+               ['lang-js',       /^on\w+\s*=\s*\"([^\"]+)\"/i],
+               ['lang-js',       /^on\w+\s*=\s*\'([^\']+)\'/i],
+               ['lang-js',       /^on\w+\s*=\s*([^\"\'>\s]+)/i],
+               ['lang-css',      /^style\s*=\s*\"([^\"]+)\"/i],
+               ['lang-css',      /^style\s*=\s*\'([^\']+)\'/i],
+               ['lang-css',      /^style\s*=\s*([^\"\'>\s]+)/i]
+               ]),
+          ['in.tag']);
+      registerLangHandler(
+          createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']);
+      registerLangHandler(sourceDecorator({
+              'keywords': CPP_KEYWORDS,
+              'hashComments': true,
+              'cStyleComments': true,
+              'types': C_TYPES
+            }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);
+      registerLangHandler(sourceDecorator({
+              'keywords': 'null,true,false'
+            }), ['json']);
+      registerLangHandler(sourceDecorator({
+              'keywords': CSHARP_KEYWORDS,
+              'hashComments': true,
+              'cStyleComments': true,
+              'verbatimStrings': true,
+              'types': C_TYPES
+            }), ['cs']);
+      registerLangHandler(sourceDecorator({
+              'keywords': JAVA_KEYWORDS,
+              'cStyleComments': true
+            }), ['java']);
+      registerLangHandler(sourceDecorator({
+              'keywords': SH_KEYWORDS,
+              'hashComments': true,
+              'multiLineStrings': true
+            }), ['bash', 'bsh', 'csh', 'sh']);
+      registerLangHandler(sourceDecorator({
+              'keywords': PYTHON_KEYWORDS,
+              'hashComments': true,
+              'multiLineStrings': true,
+              'tripleQuotedStrings': true
+            }), ['cv', 'py', 'python']);
+      registerLangHandler(sourceDecorator({
+              'keywords': PERL_KEYWORDS,
+              'hashComments': true,
+              'multiLineStrings': true,
+              'regexLiterals': 2  // multiline regex literals
+            }), ['perl', 'pl', 'pm']);
+      registerLangHandler(sourceDecorator({
+              'keywords': RUBY_KEYWORDS,
+              'hashComments': true,
+              'multiLineStrings': true,
+              'regexLiterals': true
+            }), ['rb', 'ruby']);
+      registerLangHandler(sourceDecorator({
+              'keywords': JSCRIPT_KEYWORDS,
+              'cStyleComments': true,
+              'regexLiterals': true
+            }), ['javascript', 'js', 'ts', 'typescript']);
+      registerLangHandler(sourceDecorator({
+              'keywords': COFFEE_KEYWORDS,
+              'hashComments': 3,  // ### style block comments
+              'cStyleComments': true,
+              'multilineStrings': true,
+              'tripleQuotedStrings': true,
+              'regexLiterals': true
+            }), ['coffee']);
+      registerLangHandler(
+          createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']);
+    
+      /** @param {JobT} job */
+      function applyDecorator(job) {
+        var opt_langExtension = job.langExtension;
+    
+        try {
+          // Extract tags, and convert the source code to plain text.
+          var sourceAndSpans = extractSourceSpans(job.sourceNode, job.pre);
+          /** Plain text. @type {string} */
+          var source = sourceAndSpans.sourceCode;
+          job.sourceCode = source;
+          job.spans = sourceAndSpans.spans;
+          job.basePos = 0;
+    
+          // Apply the appropriate language handler
+          langHandlerForExtension(opt_langExtension, source)(job);
+    
+          // Integrate the decorations and tags back into the source code,
+          // modifying the sourceNode in place.
+          recombineTagsAndDecorations(job);
+        } catch (e) {
+          if (win['console']) {
+            console['log'](e && e['stack'] || e);
+          }
+        }
+      }
+    
+      /**
+       * Pretty print a chunk of code.
+       * @param sourceCodeHtml {string} The HTML to pretty print.
+       * @param opt_langExtension {string} The language name to use.
+       *     Typically, a filename extension like 'cpp' or 'java'.
+       * @param opt_numberLines {number|boolean} True to number lines,
+       *     or the 1-indexed number of the first line in sourceCodeHtml.
+       */
+      function $prettyPrintOne(sourceCodeHtml, opt_langExtension, opt_numberLines) {
+        /** @type{number|boolean} */
+        var nl = opt_numberLines || false;
+        /** @type{string|null} */
+        var langExtension = opt_langExtension || null;
+        /** @type{!Element} */
+        var container = document.createElement('div');
+        // This could cause images to load and onload listeners to fire.
+        // E.g. <img onerror="alert(1337)" src="nosuchimage.png">.
+        // We assume that the inner HTML is from a trusted source.
+        // The pre-tag is required for IE8 which strips newlines from innerHTML
+        // when it is injected into a <pre> tag.
+        // http://stackoverflow.com/questions/451486/pre-tag-loses-line-breaks-when-setting-innerhtml-in-ie
+        // http://stackoverflow.com/questions/195363/inserting-a-newline-into-a-pre-tag-ie-javascript
+        container.innerHTML = '<pre>' + sourceCodeHtml + '</pre>';
+        container = /** @type{!Element} */(container.firstChild);
+        if (nl) {
+          numberLines(container, nl, true);
+        }
+    
+        /** @type{JobT} */
+        var job = {
+          langExtension: langExtension,
+          numberLines: nl,
+          sourceNode: container,
+          pre: 1,
+          sourceCode: null,
+          basePos: null,
+          spans: null,
+          decorations: null
+        };
+        applyDecorator(job);
+        return container.innerHTML;
+      }
+    
+       /**
+        * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
+        * {@code class=prettyprint} and prettify them.
+        *
+        * @param {Function} opt_whenDone called when prettifying is done.
+        * @param {HTMLElement|HTMLDocument} opt_root an element or document
+        *   containing all the elements to pretty print.
+        *   Defaults to {@code document.body}.
+        */
+      function $prettyPrint(opt_whenDone, opt_root) {
+        var root = opt_root || document.body;
+        var doc = root.ownerDocument || document;
+        function byTagName(tn) { return root.getElementsByTagName(tn); }
+        // fetch a list of nodes to rewrite
+        var codeSegments = [byTagName('pre'), byTagName('code'), byTagName('xmp')];
+        var elements = [];
+        for (var i = 0; i < codeSegments.length; ++i) {
+          for (var j = 0, n = codeSegments[i].length; j < n; ++j) {
+            elements.push(codeSegments[i][j]);
+          }
+        }
+        codeSegments = null;
+    
+        var clock = Date;
+        if (!clock['now']) {
+          clock = { 'now': function () { return +(new Date); } };
+        }
+    
+        // The loop is broken into a series of continuations to make sure that we
+        // don't make the browser unresponsive when rewriting a large page.
+        var k = 0;
+    
+        var langExtensionRe = /\blang(?:uage)?-([\w.]+)(?!\S)/;
+        var prettyPrintRe = /\bprettyprint\b/;
+        var prettyPrintedRe = /\bprettyprinted\b/;
+        var preformattedTagNameRe = /pre|xmp/i;
+        var codeRe = /^code$/i;
+        var preCodeXmpRe = /^(?:pre|code|xmp)$/i;
+        var EMPTY = {};
+    
+        function doWork() {
+          var endTime = (win['PR_SHOULD_USE_CONTINUATION'] ?
+                         clock['now']() + 250 /* ms */ :
+                         Infinity);
+          for (; k < elements.length && clock['now']() < endTime; k++) {
+            var cs = elements[k];
+    
+            // Look for a preceding comment like
+            // <?prettify lang="..." linenums="..."?>
+            var attrs = EMPTY;
+            {
+              for (var preceder = cs; (preceder = preceder.previousSibling);) {
+                var nt = preceder.nodeType;
+                // <?foo?> is parsed by HTML 5 to a comment node (8)
+                // like <!--?foo?-->, but in XML is a processing instruction
+                var value = (nt === 7 || nt === 8) && preceder.nodeValue;
+                if (value
+                    ? !/^\??prettify\b/.test(value)
+                    : (nt !== 3 || /\S/.test(preceder.nodeValue))) {
+                  // Skip over white-space text nodes but not others.
+                  break;
+                }
+                if (value) {
+                  attrs = {};
+                  value.replace(
+                      /\b(\w+)=([\w:.%+-]+)/g,
+                    function (_, name, value) { attrs[name] = value; });
+                  break;
+                }
+              }
+            }
+    
+            var className = cs.className;
+            if ((attrs !== EMPTY || prettyPrintRe.test(className))
+                // Don't redo this if we've already done it.
+                // This allows recalling pretty print to just prettyprint elements
+                // that have been added to the page since last call.
+                && !prettyPrintedRe.test(className)) {
+    
+              // make sure this is not nested in an already prettified element
+              var nested = false;
+              for (var p = cs.parentNode; p; p = p.parentNode) {
+                var tn = p.tagName;
+                if (preCodeXmpRe.test(tn)
+                    && p.className && prettyPrintRe.test(p.className)) {
+                  nested = true;
+                  break;
+                }
+              }
+              if (!nested) {
+                // Mark done.  If we fail to prettyprint for whatever reason,
+                // we shouldn't try again.
+                cs.className += ' prettyprinted';
+    
+                // If the classes includes a language extensions, use it.
+                // Language extensions can be specified like
+                //     <pre class="prettyprint lang-cpp">
+                // the language extension "cpp" is used to find a language handler
+                // as passed to PR.registerLangHandler.
+                // HTML5 recommends that a language be specified using "language-"
+                // as the prefix instead.  Google Code Prettify supports both.
+                // http://dev.w3.org/html5/spec-author-view/the-code-element.html
+                var langExtension = attrs['lang'];
+                if (!langExtension) {
+                  langExtension = className.match(langExtensionRe);
+                  // Support <pre class="prettyprint"><code class="language-c">
+                  var wrapper;
+                  if (!langExtension && (wrapper = childContentWrapper(cs))
+                      && codeRe.test(wrapper.tagName)) {
+                    langExtension = wrapper.className.match(langExtensionRe);
+                  }
+    
+                  if (langExtension) { langExtension = langExtension[1]; }
+                }
+    
+                var preformatted;
+                if (preformattedTagNameRe.test(cs.tagName)) {
+                  preformatted = 1;
+                } else {
+                  var currentStyle = cs['currentStyle'];
+                  var defaultView = doc.defaultView;
+                  var whitespace = (
+                      currentStyle
+                      ? currentStyle['whiteSpace']
+                      : (defaultView
+                         && defaultView.getComputedStyle)
+                      ? defaultView.getComputedStyle(cs, null)
+                      .getPropertyValue('white-space')
+                      : 0);
+                  preformatted = whitespace
+                      && 'pre' === whitespace.substring(0, 3);
+                }
+    
+                // Look for a class like linenums or linenums:<n> where <n> is the
+                // 1-indexed number of the first line.
+                var lineNums = attrs['linenums'];
+                if (!(lineNums = lineNums === 'true' || +lineNums)) {
+                  lineNums = className.match(/\blinenums\b(?::(\d+))?/);
+                  lineNums =
+                    lineNums
+                    ? lineNums[1] && lineNums[1].length
+                      ? +lineNums[1] : true
+                    : false;
+                }
+                if (lineNums) { numberLines(cs, lineNums, preformatted); }
+    
+                // do the pretty printing
+                var prettyPrintingJob = {
+                  langExtension: langExtension,
+                  sourceNode: cs,
+                  numberLines: lineNums,
+                  pre: preformatted,
+                  sourceCode: null,
+                  basePos: null,
+                  spans: null,
+                  decorations: null
+                };
+                applyDecorator(prettyPrintingJob);
+              }
+            }
+          }
+          if (k < elements.length) {
+            // finish up in a continuation
+            win.setTimeout(doWork, 250);
+          } else if ('function' === typeof opt_whenDone) {
+            opt_whenDone();
+          }
+        }
+    
+        doWork();
+      }
+    
+      /**
+       * Contains functions for creating and registering new language handlers.
+       * @type {Object}
+       */
+      var PR = win['PR'] = {
+            'createSimpleLexer': createSimpleLexer,
+            'registerLangHandler': registerLangHandler,
+            'sourceDecorator': sourceDecorator,
+            'PR_ATTRIB_NAME': PR_ATTRIB_NAME,
+            'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,
+            'PR_COMMENT': PR_COMMENT,
+            'PR_DECLARATION': PR_DECLARATION,
+            'PR_KEYWORD': PR_KEYWORD,
+            'PR_LITERAL': PR_LITERAL,
+            'PR_NOCODE': PR_NOCODE,
+            'PR_PLAIN': PR_PLAIN,
+            'PR_PUNCTUATION': PR_PUNCTUATION,
+            'PR_SOURCE': PR_SOURCE,
+            'PR_STRING': PR_STRING,
+            'PR_TAG': PR_TAG,
+            'PR_TYPE': PR_TYPE,
+            'prettyPrintOne':
+               IN_GLOBAL_SCOPE
+                 ? (win['prettyPrintOne'] = $prettyPrintOne)
+                 : (prettyPrintOne = $prettyPrintOne),
+            'prettyPrint': prettyPrint =
+               IN_GLOBAL_SCOPE
+                 ? (win['prettyPrint'] = $prettyPrint)
+                 : (prettyPrint = $prettyPrint)
+          };
+    
+      // Make PR available via the Asynchronous Module Definition (AMD) API.
+      // Per https://github.com/amdjs/amdjs-api/wiki/AMD:
+      // The Asynchronous Module Definition (AMD) API specifies a
+      // mechanism for defining modules such that the module and its
+      // dependencies can be asynchronously loaded.
+      // ...
+      // To allow a clear indicator that a global define function (as
+      // needed for script src browser loading) conforms to the AMD API,
+      // any global define function SHOULD have a property called "amd"
+      // whose value is an object. This helps avoid conflict with any
+      // other existing JavaScript code that could have defined a define()
+      // function that does not conform to the AMD API.
+      var define = win['define'];
+      if (typeof define === "function" && define['amd']) {
+        define("google-code-prettify", [], function () {
+          return PR;
+        });
+      }
+    })();
+    return prettyPrint;
+  })();
+
+  // If this script is deferred or async and the document is already
+  // loaded we need to wait for language handlers to load before performing
+  // any autorun.
+  function onLangsLoaded() {
+    if (autorun) {
+      contentLoaded(
+        function () {
+          var n = callbacks.length;
+          var callback = n ? function () {
+            for (var i = 0; i < n; ++i) {
+              (function (i) {
+                win.setTimeout(
+                   function () {
+                     win['exports'][callbacks[i]].apply(win, arguments);
+                   }, 0);
+               })(i);
+            }
+          } : void 0;
+          prettyPrint(callback);
+        });
+    }
+  }
+  checkPendingLanguages();
+
+}());
\ No newline at end of file
diff --git a/static/js/selController.js b/static/js/selController.js
index 7f678a8..06c1abb 100644
--- a/static/js/selController.js
+++ b/static/js/selController.js
@@ -765,7 +765,7 @@
 }
 
 
-angular.module('bmcApp').controller('selController', function($scope, Restangular) {
+angular.module('bmcApp').controller('selController', function($scope) {
 
     var sdr_promise = Restangular.all('sdrentries').getList();
     var sel_promise = Restangular.all('selentries').getList();
diff --git a/static/js/versionController.js b/static/js/versionController.js
index 082ccf8..b77f9b4 100644
--- a/static/js/versionController.js
+++ b/static/js/versionController.js
@@ -1,4 +1,4 @@
-angular.module('bmcApp').controller('versionController', function($scope, Restangular) {
+angular.module('bmcApp').controller('versionController', function($scope) {
 
     var system_status = Restangular.one('systeminfo').get().then(function(system_status) {
         $scope.system_status = system_status;
