diff --git a/docs/awesome_table_in_html.Rmd b/docs/awesome_table_in_html.Rmd
index 7ae49b6..9b1eea9 100644
--- a/docs/awesome_table_in_html.Rmd
+++ b/docs/awesome_table_in_html.Rmd
@@ -536,14 +536,15 @@
 ```
 
 ## Use it with sparkline
-Well, this is not a feature but rather a documentation of how to use the `sparkline` package together with this package. The easiest way is sort of a hack. You can call `sparkline::sparkline(0)` somewhere on your document where no one would mind so its dependencies could be loaded without any hurdles. Then you use `sparkline::spk_chr()` to generate the text. Here is another example: [Chinese names in US babynames](https://cranky-chandrasekhar-cfefcd.netlify.app/)
+Well, this is not a feature but rather a documentation of how to use the `sparkline` package together with this package. The easiest way is sort of a hack. You can call `sparkline::sparkline(0)` somewhere on your document where no one would mind so its dependencies could be loaded without any hurdles. Then you use `sparkline::spk_chr()` to generate the text. For a working example, see: [Chinese names in US babynames](https://cranky-chandrasekhar-cfefcd.netlify.app/)
 
-```{r}
+```{r, eval=FALSE}
+# Not evaluated
 library(sparkline)
 sparkline(0)
 ```
 
-```{r}
+```{r,eval=FALSE}
 spk_dt <- data.frame(
   var = c("mpg", "wt"),
   sparkline = c(spk_chr(mtcars$mpg), spk_chr(mtcars$wt))
diff --git a/docs/awesome_table_in_html.html b/docs/awesome_table_in_html.html
index 5f28af0..40f4a07 100644
--- a/docs/awesome_table_in_html.html
+++ b/docs/awesome_table_in_html.html
@@ -1489,4578 +1489,6 @@
 border: 0;
 }
 </style>
-<script>(function() {
-  // If window.HTMLWidgets is already defined, then use it; otherwise create a
-  // new object. This allows preceding code to set options that affect the
-  // initialization process (though none currently exist).
-  window.HTMLWidgets = window.HTMLWidgets || {};
-
-  // See if we're running in a viewer pane. If not, we're in a web browser.
-  var viewerMode = window.HTMLWidgets.viewerMode =
-      /\bviewer_pane=1\b/.test(window.location);
-
-  // See if we're running in Shiny mode. If not, it's a static document.
-  // Note that static widgets can appear in both Shiny and static modes, but
-  // obviously, Shiny widgets can only appear in Shiny apps/documents.
-  var shinyMode = window.HTMLWidgets.shinyMode =
-      typeof(window.Shiny) !== "undefined" && !!window.Shiny.outputBindings;
-
-  // We can't count on jQuery being available, so we implement our own
-  // version if necessary.
-  function querySelectorAll(scope, selector) {
-    if (typeof(jQuery) !== "undefined" && scope instanceof jQuery) {
-      return scope.find(selector);
-    }
-    if (scope.querySelectorAll) {
-      return scope.querySelectorAll(selector);
-    }
-  }
-
-  function asArray(value) {
-    if (value === null)
-      return [];
-    if ($.isArray(value))
-      return value;
-    return [value];
-  }
-
-  // Implement jQuery's extend
-  function extend(target /*, ... */) {
-    if (arguments.length == 1) {
-      return target;
-    }
-    for (var i = 1; i < arguments.length; i++) {
-      var source = arguments[i];
-      for (var prop in source) {
-        if (source.hasOwnProperty(prop)) {
-          target[prop] = source[prop];
-        }
-      }
-    }
-    return target;
-  }
-
-  // IE8 doesn't support Array.forEach.
-  function forEach(values, callback, thisArg) {
-    if (values.forEach) {
-      values.forEach(callback, thisArg);
-    } else {
-      for (var i = 0; i < values.length; i++) {
-        callback.call(thisArg, values[i], i, values);
-      }
-    }
-  }
-
-  // Replaces the specified method with the return value of funcSource.
-  //
-  // Note that funcSource should not BE the new method, it should be a function
-  // that RETURNS the new method. funcSource receives a single argument that is
-  // the overridden method, it can be called from the new method. The overridden
-  // method can be called like a regular function, it has the target permanently
-  // bound to it so "this" will work correctly.
-  function overrideMethod(target, methodName, funcSource) {
-    var superFunc = target[methodName] || function() {};
-    var superFuncBound = function() {
-      return superFunc.apply(target, arguments);
-    };
-    target[methodName] = funcSource(superFuncBound);
-  }
-
-  // Add a method to delegator that, when invoked, calls
-  // delegatee.methodName. If there is no such method on
-  // the delegatee, but there was one on delegator before
-  // delegateMethod was called, then the original version
-  // is invoked instead.
-  // For example:
-  //
-  // var a = {
-  //   method1: function() { console.log('a1'); }
-  //   method2: function() { console.log('a2'); }
-  // };
-  // var b = {
-  //   method1: function() { console.log('b1'); }
-  // };
-  // delegateMethod(a, b, "method1");
-  // delegateMethod(a, b, "method2");
-  // a.method1();
-  // a.method2();
-  //
-  // The output would be "b1", "a2".
-  function delegateMethod(delegator, delegatee, methodName) {
-    var inherited = delegator[methodName];
-    delegator[methodName] = function() {
-      var target = delegatee;
-      var method = delegatee[methodName];
-
-      // The method doesn't exist on the delegatee. Instead,
-      // call the method on the delegator, if it exists.
-      if (!method) {
-        target = delegator;
-        method = inherited;
-      }
-
-      if (method) {
-        return method.apply(target, arguments);
-      }
-    };
-  }
-
-  // Implement a vague facsimilie of jQuery's data method
-  function elementData(el, name, value) {
-    if (arguments.length == 2) {
-      return el["htmlwidget_data_" + name];
-    } else if (arguments.length == 3) {
-      el["htmlwidget_data_" + name] = value;
-      return el;
-    } else {
-      throw new Error("Wrong number of arguments for elementData: " +
-        arguments.length);
-    }
-  }
-
-  // http://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex
-  function escapeRegExp(str) {
-    return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
-  }
-
-  function hasClass(el, className) {
-    var re = new RegExp("\\b" + escapeRegExp(className) + "\\b");
-    return re.test(el.className);
-  }
-
-  // elements - array (or array-like object) of HTML elements
-  // className - class name to test for
-  // include - if true, only return elements with given className;
-  //   if false, only return elements *without* given className
-  function filterByClass(elements, className, include) {
-    var results = [];
-    for (var i = 0; i < elements.length; i++) {
-      if (hasClass(elements[i], className) == include)
-        results.push(elements[i]);
-    }
-    return results;
-  }
-
-  function on(obj, eventName, func) {
-    if (obj.addEventListener) {
-      obj.addEventListener(eventName, func, false);
-    } else if (obj.attachEvent) {
-      obj.attachEvent(eventName, func);
-    }
-  }
-
-  function off(obj, eventName, func) {
-    if (obj.removeEventListener)
-      obj.removeEventListener(eventName, func, false);
-    else if (obj.detachEvent) {
-      obj.detachEvent(eventName, func);
-    }
-  }
-
-  // Translate array of values to top/right/bottom/left, as usual with
-  // the "padding" CSS property
-  // https://developer.mozilla.org/en-US/docs/Web/CSS/padding
-  function unpackPadding(value) {
-    if (typeof(value) === "number")
-      value = [value];
-    if (value.length === 1) {
-      return {top: value[0], right: value[0], bottom: value[0], left: value[0]};
-    }
-    if (value.length === 2) {
-      return {top: value[0], right: value[1], bottom: value[0], left: value[1]};
-    }
-    if (value.length === 3) {
-      return {top: value[0], right: value[1], bottom: value[2], left: value[1]};
-    }
-    if (value.length === 4) {
-      return {top: value[0], right: value[1], bottom: value[2], left: value[3]};
-    }
-  }
-
-  // Convert an unpacked padding object to a CSS value
-  function paddingToCss(paddingObj) {
-    return paddingObj.top + "px " + paddingObj.right + "px " + paddingObj.bottom + "px " + paddingObj.left + "px";
-  }
-
-  // Makes a number suitable for CSS
-  function px(x) {
-    if (typeof(x) === "number")
-      return x + "px";
-    else
-      return x;
-  }
-
-  // Retrieves runtime widget sizing information for an element.
-  // The return value is either null, or an object with fill, padding,
-  // defaultWidth, defaultHeight fields.
-  function sizingPolicy(el) {
-    var sizingEl = document.querySelector("script[data-for='" + el.id + "'][type='application/htmlwidget-sizing']");
-    if (!sizingEl)
-      return null;
-    var sp = JSON.parse(sizingEl.textContent || sizingEl.text || "{}");
-    if (viewerMode) {
-      return sp.viewer;
-    } else {
-      return sp.browser;
-    }
-  }
-
-  // @param tasks Array of strings (or falsy value, in which case no-op).
-  //   Each element must be a valid JavaScript expression that yields a
-  //   function. Or, can be an array of objects with "code" and "data"
-  //   properties; in this case, the "code" property should be a string
-  //   of JS that's an expr that yields a function, and "data" should be
-  //   an object that will be added as an additional argument when that
-  //   function is called.
-  // @param target The object that will be "this" for each function
-  //   execution.
-  // @param args Array of arguments to be passed to the functions. (The
-  //   same arguments will be passed to all functions.)
-  function evalAndRun(tasks, target, args) {
-    if (tasks) {
-      forEach(tasks, function(task) {
-        var theseArgs = args;
-        if (typeof(task) === "object") {
-          theseArgs = theseArgs.concat([task.data]);
-          task = task.code;
-        }
-        var taskFunc = tryEval(task);
-        if (typeof(taskFunc) !== "function") {
-          throw new Error("Task must be a function! Source:\n" + task);
-        }
-        taskFunc.apply(target, theseArgs);
-      });
-    }
-  }
-
-  // Attempt eval() both with and without enclosing in parentheses.
-  // Note that enclosing coerces a function declaration into
-  // an expression that eval() can parse
-  // (otherwise, a SyntaxError is thrown)
-  function tryEval(code) {
-    var result = null;
-    try {
-      result = eval(code);
-    } catch(error) {
-      if (!error instanceof SyntaxError) {
-        throw error;
-      }
-      try {
-        result = eval("(" + code + ")");
-      } catch(e) {
-        if (e instanceof SyntaxError) {
-          throw error;
-        } else {
-          throw e;
-        }
-      }
-    }
-    return result;
-  }
-
-  function initSizing(el) {
-    var sizing = sizingPolicy(el);
-    if (!sizing)
-      return;
-
-    var cel = document.getElementById("htmlwidget_container");
-    if (!cel)
-      return;
-
-    if (typeof(sizing.padding) !== "undefined") {
-      document.body.style.margin = "0";
-      document.body.style.padding = paddingToCss(unpackPadding(sizing.padding));
-    }
-
-    if (sizing.fill) {
-      document.body.style.overflow = "hidden";
-      document.body.style.width = "100%";
-      document.body.style.height = "100%";
-      document.documentElement.style.width = "100%";
-      document.documentElement.style.height = "100%";
-      if (cel) {
-        cel.style.position = "absolute";
-        var pad = unpackPadding(sizing.padding);
-        cel.style.top = pad.top + "px";
-        cel.style.right = pad.right + "px";
-        cel.style.bottom = pad.bottom + "px";
-        cel.style.left = pad.left + "px";
-        el.style.width = "100%";
-        el.style.height = "100%";
-      }
-
-      return {
-        getWidth: function() { return cel.offsetWidth; },
-        getHeight: function() { return cel.offsetHeight; }
-      };
-
-    } else {
-      el.style.width = px(sizing.width);
-      el.style.height = px(sizing.height);
-
-      return {
-        getWidth: function() { return el.offsetWidth; },
-        getHeight: function() { return el.offsetHeight; }
-      };
-    }
-  }
-
-  // Default implementations for methods
-  var defaults = {
-    find: function(scope) {
-      return querySelectorAll(scope, "." + this.name);
-    },
-    renderError: function(el, err) {
-      var $el = $(el);
-
-      this.clearError(el);
-
-      // Add all these error classes, as Shiny does
-      var errClass = "shiny-output-error";
-      if (err.type !== null) {
-        // use the classes of the error condition as CSS class names
-        errClass = errClass + " " + $.map(asArray(err.type), function(type) {
-          return errClass + "-" + type;
-        }).join(" ");
-      }
-      errClass = errClass + " htmlwidgets-error";
-
-      // Is el inline or block? If inline or inline-block, just display:none it
-      // and add an inline error.
-      var display = $el.css("display");
-      $el.data("restore-display-mode", display);
-
-      if (display === "inline" || display === "inline-block") {
-        $el.hide();
-        if (err.message !== "") {
-          var errorSpan = $("<span>").addClass(errClass);
-          errorSpan.text(err.message);
-          $el.after(errorSpan);
-        }
-      } else if (display === "block") {
-        // If block, add an error just after the el, set visibility:none on the
-        // el, and position the error to be on top of the el.
-        // Mark it with a unique ID and CSS class so we can remove it later.
-        $el.css("visibility", "hidden");
-        if (err.message !== "") {
-          var errorDiv = $("<div>").addClass(errClass).css("position", "absolute")
-            .css("top", el.offsetTop)
-            .css("left", el.offsetLeft)
-            // setting width can push out the page size, forcing otherwise
-            // unnecessary scrollbars to appear and making it impossible for
-            // the element to shrink; so use max-width instead
-            .css("maxWidth", el.offsetWidth)
-            .css("height", el.offsetHeight);
-          errorDiv.text(err.message);
-          $el.after(errorDiv);
-
-          // Really dumb way to keep the size/position of the error in sync with
-          // the parent element as the window is resized or whatever.
-          var intId = setInterval(function() {
-            if (!errorDiv[0].parentElement) {
-              clearInterval(intId);
-              return;
-            }
-            errorDiv
-              .css("top", el.offsetTop)
-              .css("left", el.offsetLeft)
-              .css("maxWidth", el.offsetWidth)
-              .css("height", el.offsetHeight);
-          }, 500);
-        }
-      }
-    },
-    clearError: function(el) {
-      var $el = $(el);
-      var display = $el.data("restore-display-mode");
-      $el.data("restore-display-mode", null);
-
-      if (display === "inline" || display === "inline-block") {
-        if (display)
-          $el.css("display", display);
-        $(el.nextSibling).filter(".htmlwidgets-error").remove();
-      } else if (display === "block"){
-        $el.css("visibility", "inherit");
-        $(el.nextSibling).filter(".htmlwidgets-error").remove();
-      }
-    },
-    sizing: {}
-  };
-
-  // Called by widget bindings to register a new type of widget. The definition
-  // object can contain the following properties:
-  // - name (required) - A string indicating the binding name, which will be
-  //   used by default as the CSS classname to look for.
-  // - initialize (optional) - A function(el) that will be called once per
-  //   widget element; if a value is returned, it will be passed as the third
-  //   value to renderValue.
-  // - renderValue (required) - A function(el, data, initValue) that will be
-  //   called with data. Static contexts will cause this to be called once per
-  //   element; Shiny apps will cause this to be called multiple times per
-  //   element, as the data changes.
-  window.HTMLWidgets.widget = function(definition) {
-    if (!definition.name) {
-      throw new Error("Widget must have a name");
-    }
-    if (!definition.type) {
-      throw new Error("Widget must have a type");
-    }
-    // Currently we only support output widgets
-    if (definition.type !== "output") {
-      throw new Error("Unrecognized widget type '" + definition.type + "'");
-    }
-    // TODO: Verify that .name is a valid CSS classname
-
-    // Support new-style instance-bound definitions. Old-style class-bound
-    // definitions have one widget "object" per widget per type/class of
-    // widget; the renderValue and resize methods on such widget objects
-    // take el and instance arguments, because the widget object can't
-    // store them. New-style instance-bound definitions have one widget
-    // object per widget instance; the definition that's passed in doesn't
-    // provide renderValue or resize methods at all, just the single method
-    //   factory(el, width, height)
-    // which returns an object that has renderValue(x) and resize(w, h).
-    // This enables a far more natural programming style for the widget
-    // author, who can store per-instance state using either OO-style
-    // instance fields or functional-style closure variables (I guess this
-    // is in contrast to what can only be called C-style pseudo-OO which is
-    // what we required before).
-    if (definition.factory) {
-      definition = createLegacyDefinitionAdapter(definition);
-    }
-
-    if (!definition.renderValue) {
-      throw new Error("Widget must have a renderValue function");
-    }
-
-    // For static rendering (non-Shiny), use a simple widget registration
-    // scheme. We also use this scheme for Shiny apps/documents that also
-    // contain static widgets.
-    window.HTMLWidgets.widgets = window.HTMLWidgets.widgets || [];
-    // Merge defaults into the definition; don't mutate the original definition.
-    var staticBinding = extend({}, defaults, definition);
-    overrideMethod(staticBinding, "find", function(superfunc) {
-      return function(scope) {
-        var results = superfunc(scope);
-        // Filter out Shiny outputs, we only want the static kind
-        return filterByClass(results, "html-widget-output", false);
-      };
-    });
-    window.HTMLWidgets.widgets.push(staticBinding);
-
-    if (shinyMode) {
-      // Shiny is running. Register the definition with an output binding.
-      // The definition itself will not be the output binding, instead
-      // we will make an output binding object that delegates to the
-      // definition. This is because we foolishly used the same method
-      // name (renderValue) for htmlwidgets definition and Shiny bindings
-      // but they actually have quite different semantics (the Shiny
-      // bindings receive data that includes lots of metadata that it
-      // strips off before calling htmlwidgets renderValue). We can't
-      // just ignore the difference because in some widgets it's helpful
-      // to call this.renderValue() from inside of resize(), and if
-      // we're not delegating, then that call will go to the Shiny
-      // version instead of the htmlwidgets version.
-
-      // Merge defaults with definition, without mutating either.
-      var bindingDef = extend({}, defaults, definition);
-
-      // This object will be our actual Shiny binding.
-      var shinyBinding = new Shiny.OutputBinding();
-
-      // With a few exceptions, we'll want to simply use the bindingDef's
-      // version of methods if they are available, otherwise fall back to
-      // Shiny's defaults. NOTE: If Shiny's output bindings gain additional
-      // methods in the future, and we want them to be overrideable by
-      // HTMLWidget binding definitions, then we'll need to add them to this
-      // list.
-      delegateMethod(shinyBinding, bindingDef, "getId");
-      delegateMethod(shinyBinding, bindingDef, "onValueChange");
-      delegateMethod(shinyBinding, bindingDef, "onValueError");
-      delegateMethod(shinyBinding, bindingDef, "renderError");
-      delegateMethod(shinyBinding, bindingDef, "clearError");
-      delegateMethod(shinyBinding, bindingDef, "showProgress");
-
-      // The find, renderValue, and resize are handled differently, because we
-      // want to actually decorate the behavior of the bindingDef methods.
-
-      shinyBinding.find = function(scope) {
-        var results = bindingDef.find(scope);
-
-        // Only return elements that are Shiny outputs, not static ones
-        var dynamicResults = results.filter(".html-widget-output");
-
-        // It's possible that whatever caused Shiny to think there might be
-        // new dynamic outputs, also caused there to be new static outputs.
-        // Since there might be lots of different htmlwidgets bindings, we
-        // schedule execution for later--no need to staticRender multiple
-        // times.
-        if (results.length !== dynamicResults.length)
-          scheduleStaticRender();
-
-        return dynamicResults;
-      };
-
-      // Wrap renderValue to handle initialization, which unfortunately isn't
-      // supported natively by Shiny at the time of this writing.
-
-      shinyBinding.renderValue = function(el, data) {
-        Shiny.renderDependencies(data.deps);
-        // Resolve strings marked as javascript literals to objects
-        if (!(data.evals instanceof Array)) data.evals = [data.evals];
-        for (var i = 0; data.evals && i < data.evals.length; i++) {
-          window.HTMLWidgets.evaluateStringMember(data.x, data.evals[i]);
-        }
-        if (!bindingDef.renderOnNullValue) {
-          if (data.x === null) {
-            el.style.visibility = "hidden";
-            return;
-          } else {
-            el.style.visibility = "inherit";
-          }
-        }
-        if (!elementData(el, "initialized")) {
-          initSizing(el);
-
-          elementData(el, "initialized", true);
-          if (bindingDef.initialize) {
-            var result = bindingDef.initialize(el, el.offsetWidth,
-              el.offsetHeight);
-            elementData(el, "init_result", result);
-          }
-        }
-        bindingDef.renderValue(el, data.x, elementData(el, "init_result"));
-        evalAndRun(data.jsHooks.render, elementData(el, "init_result"), [el, data.x]);
-      };
-
-      // Only override resize if bindingDef implements it
-      if (bindingDef.resize) {
-        shinyBinding.resize = function(el, width, height) {
-          // Shiny can call resize before initialize/renderValue have been
-          // called, which doesn't make sense for widgets.
-          if (elementData(el, "initialized")) {
-            bindingDef.resize(el, width, height, elementData(el, "init_result"));
-          }
-        };
-      }
-
-      Shiny.outputBindings.register(shinyBinding, bindingDef.name);
-    }
-  };
-
-  var scheduleStaticRenderTimerId = null;
-  function scheduleStaticRender() {
-    if (!scheduleStaticRenderTimerId) {
-      scheduleStaticRenderTimerId = setTimeout(function() {
-        scheduleStaticRenderTimerId = null;
-        window.HTMLWidgets.staticRender();
-      }, 1);
-    }
-  }
-
-  // Render static widgets after the document finishes loading
-  // Statically render all elements that are of this widget's class
-  window.HTMLWidgets.staticRender = function() {
-    var bindings = window.HTMLWidgets.widgets || [];
-    forEach(bindings, function(binding) {
-      var matches = binding.find(document.documentElement);
-      forEach(matches, function(el) {
-        var sizeObj = initSizing(el, binding);
-
-        if (hasClass(el, "html-widget-static-bound"))
-          return;
-        el.className = el.className + " html-widget-static-bound";
-
-        var initResult;
-        if (binding.initialize) {
-          initResult = binding.initialize(el,
-            sizeObj ? sizeObj.getWidth() : el.offsetWidth,
-            sizeObj ? sizeObj.getHeight() : el.offsetHeight
-          );
-          elementData(el, "init_result", initResult);
-        }
-
-        if (binding.resize) {
-          var lastSize = {
-            w: sizeObj ? sizeObj.getWidth() : el.offsetWidth,
-            h: sizeObj ? sizeObj.getHeight() : el.offsetHeight
-          };
-          var resizeHandler = function(e) {
-            var size = {
-              w: sizeObj ? sizeObj.getWidth() : el.offsetWidth,
-              h: sizeObj ? sizeObj.getHeight() : el.offsetHeight
-            };
-            if (size.w === 0 && size.h === 0)
-              return;
-            if (size.w === lastSize.w && size.h === lastSize.h)
-              return;
-            lastSize = size;
-            binding.resize(el, size.w, size.h, initResult);
-          };
-
-          on(window, "resize", resizeHandler);
-
-          // This is needed for cases where we're running in a Shiny
-          // app, but the widget itself is not a Shiny output, but
-          // rather a simple static widget. One example of this is
-          // an rmarkdown document that has runtime:shiny and widget
-          // that isn't in a render function. Shiny only knows to
-          // call resize handlers for Shiny outputs, not for static
-          // widgets, so we do it ourselves.
-          if (window.jQuery) {
-            window.jQuery(document).on(
-              "shown.htmlwidgets shown.bs.tab.htmlwidgets shown.bs.collapse.htmlwidgets",
-              resizeHandler
-            );
-            window.jQuery(document).on(
-              "hidden.htmlwidgets hidden.bs.tab.htmlwidgets hidden.bs.collapse.htmlwidgets",
-              resizeHandler
-            );
-          }
-
-          // This is needed for the specific case of ioslides, which
-          // flips slides between display:none and display:block.
-          // Ideally we would not have to have ioslide-specific code
-          // here, but rather have ioslides raise a generic event,
-          // but the rmarkdown package just went to CRAN so the
-          // window to getting that fixed may be long.
-          if (window.addEventListener) {
-            // It's OK to limit this to window.addEventListener
-            // browsers because ioslides itself only supports
-            // such browsers.
-            on(document, "slideenter", resizeHandler);
-            on(document, "slideleave", resizeHandler);
-          }
-        }
-
-        var scriptData = document.querySelector("script[data-for='" + el.id + "'][type='application/json']");
-        if (scriptData) {
-          var data = JSON.parse(scriptData.textContent || scriptData.text);
-          // Resolve strings marked as javascript literals to objects
-          if (!(data.evals instanceof Array)) data.evals = [data.evals];
-          for (var k = 0; data.evals && k < data.evals.length; k++) {
-            window.HTMLWidgets.evaluateStringMember(data.x, data.evals[k]);
-          }
-          binding.renderValue(el, data.x, initResult);
-          evalAndRun(data.jsHooks.render, initResult, [el, data.x]);
-        }
-      });
-    });
-
-    invokePostRenderHandlers();
-  }
-
-
-  function has_jQuery3() {
-    if (!window.jQuery) {
-      return false;
-    }
-    var $version = window.jQuery.fn.jquery;
-    var $major_version = parseInt($version.split(".")[0]);
-    return $major_version >= 3;
-  }
-
-  /*
-  / Shiny 1.4 bumped jQuery from 1.x to 3.x which means jQuery's
-  / on-ready handler (i.e., $(fn)) is now asyncronous (i.e., it now
-  / really means $(setTimeout(fn)).
-  / https://jquery.com/upgrade-guide/3.0/#breaking-change-document-ready-handlers-are-now-asynchronous
-  /
-  / Since Shiny uses $() to schedule initShiny, shiny>=1.4 calls initShiny
-  / one tick later than it did before, which means staticRender() is
-  / called renderValue() earlier than (advanced) widget authors might be expecting.
-  / https://github.com/rstudio/shiny/issues/2630
-  /
-  / For a concrete example, leaflet has some methods (e.g., updateBounds)
-  / which reference Shiny methods registered in initShiny (e.g., setInputValue).
-  / Since leaflet is privy to this life-cycle, it knows to use setTimeout() to
-  / delay execution of those methods (until Shiny methods are ready)
-  / https://github.com/rstudio/leaflet/blob/18ec981/javascript/src/index.js#L266-L268
-  /
-  / Ideally widget authors wouldn't need to use this setTimeout() hack that
-  / leaflet uses to call Shiny methods on a staticRender(). In the long run,
-  / the logic initShiny should be broken up so that method registration happens
-  / right away, but binding happens later.
-  */
-  function maybeStaticRenderLater() {
-    if (shinyMode && has_jQuery3()) {
-      window.jQuery(window.HTMLWidgets.staticRender);
-    } else {
-      window.HTMLWidgets.staticRender();
-    }
-  }
-
-  if (document.addEventListener) {
-    document.addEventListener("DOMContentLoaded", function() {
-      document.removeEventListener("DOMContentLoaded", arguments.callee, false);
-      maybeStaticRenderLater();
-    }, false);
-  } else if (document.attachEvent) {
-    document.attachEvent("onreadystatechange", function() {
-      if (document.readyState === "complete") {
-        document.detachEvent("onreadystatechange", arguments.callee);
-        maybeStaticRenderLater();
-      }
-    });
-  }
-
-
-  window.HTMLWidgets.getAttachmentUrl = function(depname, key) {
-    // If no key, default to the first item
-    if (typeof(key) === "undefined")
-      key = 1;
-
-    var link = document.getElementById(depname + "-" + key + "-attachment");
-    if (!link) {
-      throw new Error("Attachment " + depname + "/" + key + " not found in document");
-    }
-    return link.getAttribute("href");
-  };
-
-  window.HTMLWidgets.dataframeToD3 = function(df) {
-    var names = [];
-    var length;
-    for (var name in df) {
-        if (df.hasOwnProperty(name))
-            names.push(name);
-        if (typeof(df[name]) !== "object" || typeof(df[name].length) === "undefined") {
-            throw new Error("All fields must be arrays");
-        } else if (typeof(length) !== "undefined" && length !== df[name].length) {
-            throw new Error("All fields must be arrays of the same length");
-        }
-        length = df[name].length;
-    }
-    var results = [];
-    var item;
-    for (var row = 0; row < length; row++) {
-        item = {};
-        for (var col = 0; col < names.length; col++) {
-            item[names[col]] = df[names[col]][row];
-        }
-        results.push(item);
-    }
-    return results;
-  };
-
-  window.HTMLWidgets.transposeArray2D = function(array) {
-      if (array.length === 0) return array;
-      var newArray = array[0].map(function(col, i) {
-          return array.map(function(row) {
-              return row[i]
-          })
-      });
-      return newArray;
-  };
-  // Split value at splitChar, but allow splitChar to be escaped
-  // using escapeChar. Any other characters escaped by escapeChar
-  // will be included as usual (including escapeChar itself).
-  function splitWithEscape(value, splitChar, escapeChar) {
-    var results = [];
-    var escapeMode = false;
-    var currentResult = "";
-    for (var pos = 0; pos < value.length; pos++) {
-      if (!escapeMode) {
-        if (value[pos] === splitChar) {
-          results.push(currentResult);
-          currentResult = "";
-        } else if (value[pos] === escapeChar) {
-          escapeMode = true;
-        } else {
-          currentResult += value[pos];
-        }
-      } else {
-        currentResult += value[pos];
-        escapeMode = false;
-      }
-    }
-    if (currentResult !== "") {
-      results.push(currentResult);
-    }
-    return results;
-  }
-  // Function authored by Yihui/JJ Allaire
-  window.HTMLWidgets.evaluateStringMember = function(o, member) {
-    var parts = splitWithEscape(member, '.', '\\');
-    for (var i = 0, l = parts.length; i < l; i++) {
-      var part = parts[i];
-      // part may be a character or 'numeric' member name
-      if (o !== null && typeof o === "object" && part in o) {
-        if (i == (l - 1)) { // if we are at the end of the line then evalulate
-          if (typeof o[part] === "string")
-            o[part] = tryEval(o[part]);
-        } else { // otherwise continue to next embedded object
-          o = o[part];
-        }
-      }
-    }
-  };
-
-  // Retrieve the HTMLWidget instance (i.e. the return value of an
-  // HTMLWidget binding's initialize() or factory() function)
-  // associated with an element, or null if none.
-  window.HTMLWidgets.getInstance = function(el) {
-    return elementData(el, "init_result");
-  };
-
-  // Finds the first element in the scope that matches the selector,
-  // and returns the HTMLWidget instance (i.e. the return value of
-  // an HTMLWidget binding's initialize() or factory() function)
-  // associated with that element, if any. If no element matches the
-  // selector, or the first matching element has no HTMLWidget
-  // instance associated with it, then null is returned.
-  //
-  // The scope argument is optional, and defaults to window.document.
-  window.HTMLWidgets.find = function(scope, selector) {
-    if (arguments.length == 1) {
-      selector = scope;
-      scope = document;
-    }
-
-    var el = scope.querySelector(selector);
-    if (el === null) {
-      return null;
-    } else {
-      return window.HTMLWidgets.getInstance(el);
-    }
-  };
-
-  // Finds all elements in the scope that match the selector, and
-  // returns the HTMLWidget instances (i.e. the return values of
-  // an HTMLWidget binding's initialize() or factory() function)
-  // associated with the elements, in an array. If elements that
-  // match the selector don't have an associated HTMLWidget
-  // instance, the returned array will contain nulls.
-  //
-  // The scope argument is optional, and defaults to window.document.
-  window.HTMLWidgets.findAll = function(scope, selector) {
-    if (arguments.length == 1) {
-      selector = scope;
-      scope = document;
-    }
-
-    var nodes = scope.querySelectorAll(selector);
-    var results = [];
-    for (var i = 0; i < nodes.length; i++) {
-      results.push(window.HTMLWidgets.getInstance(nodes[i]));
-    }
-    return results;
-  };
-
-  var postRenderHandlers = [];
-  function invokePostRenderHandlers() {
-    while (postRenderHandlers.length) {
-      var handler = postRenderHandlers.shift();
-      if (handler) {
-        handler();
-      }
-    }
-  }
-
-  // Register the given callback function to be invoked after the
-  // next time static widgets are rendered.
-  window.HTMLWidgets.addPostRenderHandler = function(callback) {
-    postRenderHandlers.push(callback);
-  };
-
-  // Takes a new-style instance-bound definition, and returns an
-  // old-style class-bound definition. This saves us from having
-  // to rewrite all the logic in this file to accomodate both
-  // types of definitions.
-  function createLegacyDefinitionAdapter(defn) {
-    var result = {
-      name: defn.name,
-      type: defn.type,
-      initialize: function(el, width, height) {
-        return defn.factory(el, width, height);
-      },
-      renderValue: function(el, x, instance) {
-        return instance.renderValue(x);
-      },
-      resize: function(el, width, height, instance) {
-        return instance.resize(width, height);
-      }
-    };
-
-    if (defn.find)
-      result.find = defn.find;
-    if (defn.renderError)
-      result.renderError = defn.renderError;
-    if (defn.clearError)
-      result.clearError = defn.clearError;
-
-    return result;
-  }
-})();
-
-</script>
-<style type="text/css">.jqstooltip {-webkit-box-sizing: content-box;-moz-box-sizing: content-box;box-sizing: content-box;}</style>
-<script>/**
-*
-* jquery.sparkline.js
-*
-* v@VERSION@
-* (c) Splunk, Inc
-* Contact: Gareth Watts (gareth@splunk.com)
-* http://omnipotent.net/jquery.sparkline/
-*
-* Generates inline sparkline charts from data supplied either to the method
-* or inline in HTML
-*
-* Compatible with Internet Explorer 6.0+ and modern browsers equipped with the canvas tag
-* (Firefox 2.0+, Safari, Opera, etc)
-*
-* License: New BSD License
-*
-* Copyright (c) 2012, Splunk Inc.
-* All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification,
-* are permitted provided that the following conditions are met:
-*
-*     * Redistributions of source code must retain the above copyright notice,
-*       this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above copyright notice,
-*       this list of conditions and the following disclaimer in the documentation
-*       and/or other materials provided with the distribution.
-*     * Neither the name of Splunk Inc nor the names of its contributors may
-*       be used to endorse or promote products derived from this software without
-*       specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
-* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-* SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-*
-* Usage:
-*  $(selector).sparkline(values, options)
-*
-* If values is undefined or set to 'html' then the data values are read from the specified tag:
-*   <p>Sparkline: <span class="sparkline">1,4,6,6,8,5,3,5</span></p>
-*   $('.sparkline').sparkline();
-* There must be no spaces in the enclosed data set
-*
-* Otherwise values must be an array of numbers or null values
-*    <p>Sparkline: <span id="sparkline1">This text replaced if the browser is compatible</span></p>
-*    $('#sparkline1').sparkline([1,4,6,6,8,5,3,5])
-*    $('#sparkline2').sparkline([1,4,6,null,null,5,3,5])
-*
-* Values can also be specified in an HTML comment, or as a values attribute:
-*    <p>Sparkline: <span class="sparkline"><!--1,4,6,6,8,5,3,5 --></span></p>
-*    <p>Sparkline: <span class="sparkline" values="1,4,6,6,8,5,3,5"></span></p>
-*    $('.sparkline').sparkline();
-*
-* For line charts, x values can also be specified:
-*   <p>Sparkline: <span class="sparkline">1:1,2.7:4,3.4:6,5:6,6:8,8.7:5,9:3,10:5</span></p>
-*    $('#sparkline1').sparkline([ [1,1], [2.7,4], [3.4,6], [5,6], [6,8], [8.7,5], [9,3], [10,5] ])
-*
-* By default, options should be passed in as the second argument to the sparkline function:
-*   $('.sparkline').sparkline([1,2,3,4], {type: 'bar'})
-*
-* Options can also be set by passing them on the tag itself.  This feature is disabled by default though
-* as there's a slight performance overhead:
-*   $('.sparkline').sparkline([1,2,3,4], {enableTagOptions: true})
-*   <p>Sparkline: <span class="sparkline" sparkType="bar" sparkBarColor="red">loading</span></p>
-* Prefix all options supplied as tag attribute with "spark" (configurable by setting tagOptionsPrefix)
-*
-* Supported options:
-*   lineColor - Color of the line used for the chart
-*   fillColor - Color used to fill in the chart - Set to '' or false for a transparent chart
-*   width - Width of the chart - Defaults to 3 times the number of values in pixels
-*   height - Height of the chart - Defaults to the height of the containing element
-*   chartRangeMin - Specify the minimum value to use for the Y range of the chart - Defaults to the minimum value supplied
-*   chartRangeMax - Specify the maximum value to use for the Y range of the chart - Defaults to the maximum value supplied
-*   chartRangeClip - Clip out of range values to the max/min specified by chartRangeMin and chartRangeMax
-*   chartRangeMinX - Specify the minimum value to use for the X range of the chart - Defaults to the minimum value supplied
-*   chartRangeMaxX - Specify the maximum value to use for the X range of the chart - Defaults to the maximum value supplied
-*   composite - If true then don't erase any existing chart attached to the tag, but draw
-*           another chart over the top - Note that width and height are ignored if an
-*           existing chart is detected.
-*   tagValuesAttribute - Name of tag attribute to check for data values - Defaults to 'values'
-*   enableTagOptions - Whether to check tags for sparkline options
-*   tagOptionsPrefix - Prefix used for options supplied as tag attributes - Defaults to 'spark'
-*   disableHiddenCheck - If set to true, then the plugin will assume that charts will never be drawn into a
-*           hidden dom element, avoiding a browser reflow
-*   disableInteraction - If set to true then all mouseover/click interaction behaviour will be disabled,
-*       making the plugin perform much like it did in 1.x
-*   disableTooltips - If set to true then tooltips will be disabled - Defaults to false (tooltips enabled)
-*   disableHighlight - If set to true then highlighting of selected chart elements on mouseover will be disabled
-*           defaults to false (highlights enabled)
-*   highlightLighten - Factor to lighten/darken highlighted chart values by - Defaults to 1.4 for a 40% increase
-*   tooltipContainer - Specify which DOM element the tooltip should be rendered into - defaults to document.body
-*   tooltipClassname - Optional CSS classname to apply to tooltips - If not specified then a default style will be applied
-*   tooltipOffsetX - How many pixels away from the mouse pointer to render the tooltip on the X axis
-*   tooltipOffsetY - How many pixels away from the mouse pointer to render the tooltip on the r axis
-*   tooltipFormatter  - Optional callback that allows you to override the HTML displayed in the tooltip
-*           callback is given arguments of (sparkline, options, fields)
-*   tooltipChartTitle - If specified then the tooltip uses the string specified by this setting as a title
-*   tooltipFormat - A format string or SPFormat object  (or an array thereof for multiple entries)
-*           to control the format of the tooltip
-*   tooltipPrefix - A string to prepend to each field displayed in a tooltip
-*   tooltipSuffix - A string to append to each field displayed in a tooltip
-*   tooltipPrefixBinLabels - An array of Bin Labels for each offset value to add as the start
-*                            of the tooltip prefix.  Example:
-*        var giants_game_results = [1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,1,1,1,1,1,1],
-*            giants_game_dates  = ["9/30", "10/1", "10/2", "10/3", "10/6", "10/7", "10/9", "10/10", "10/11", "10/14", "10/15",
-*                                  "10/17", "10/18", "10/19", "10/21", "10/22", "10/24", "10/25", "10/27", "10/28"];
-*        $('#giants').sparkline(giants_results, {type: 'tristate', tooltipPrefixBinLabels: giants_dates, tooltipPrefix: ' - '};
-*   tooltipSuffixBinLabels - An array of Bin Labels for each offset value to add as the end
-*                            of the tooltip suffix.
-*   tooltipSkipNull - If true then null values will not have a tooltip displayed (defaults to true)
-*   tooltipValueLookups - An object or range map to map field values to tooltip strings
-*                         (eg. to map -1 to "Lost", 0 to "Draw", and 1 to "Win")
-*   toolTipPosition - Display tooltip to the 'left' or 'right' of the mouse - Defaults to "right"
-*   numberFormatter - Optional callback for formatting numbers in tooltips
-*   numberDigitGroupSep - Character to use for group separator in numbers "1,234" - Defaults to ","
-*   numberDecimalMark - Character to use for the decimal point when formatting numbers - Defaults to "."
-*   numberDigitGroupCount - Number of digits between group separator - Defaults to 3
-*
-* There are 8 types of sparkline, selected by supplying a "type" option of 'line' (default),
-* 'bar', 'tristate', 'bullet', 'discrete', 'pie', 'box' or 'stack'
-*    line - Line chart.  Options:
-*       spotColor - Set to '' to not end each line in a circular spot
-*       minSpotColor - If set, color of spot at minimum value
-*       maxSpotColor - If set, color of spot at maximum value
-*       spotRadius - Radius in pixels
-*       lineWidth - Width of line in pixels
-*       normalRangeMin
-*       normalRangeMax - If set draws a filled horizontal bar between these two values marking the "normal"
-*                        or expected range of values
-*       normalRangeColor - Color to use for the above bar
-*       drawNormalOnTop - Draw the normal range above the chart fill color if true
-*       defaultPixelsPerValue - Defaults to 3 pixels of width for each value in the chart
-*       highlightSpotColor - The color to use for drawing a highlight spot on mouseover - Set to null to disable
-*       highlightLineColor - The color to use for drawing a highlight line on mouseover - Set to null to disable
-*       valueSpots - Specify which points to draw spots on, and in which color.  Accepts a range map
-*
-*   bar - Bar chart.  Options:
-*       barColor - Color of bars for positive values
-*       negBarColor - Color of bars for negative values
-*       zeroColor - Color of bars with zero values
-*       nullColor - Color of bars with null values - Defaults to omitting the bar entirely
-*       barWidth - Width of bars in pixels
-*       colorMap - Optional mapping of values to colors to override the *BarColor values above
-*                  can be an Array of values to control the color of individual bars or a range map
-*                  to specify colors for individual ranges of values
-*       barSpacing - Gap between bars in pixels
-*       zeroAxis - Centers the y-axis around zero if true
-*
-*   tristate - Charts values of win (>0), lose (<0) or draw (=0)
-*       posBarColor - Color of win values
-*       negBarColor - Color of lose values
-*       zeroBarColor - Color of draw values
-*       barWidth - Width of bars in pixels
-*       barSpacing - Gap between bars in pixels
-*       colorMap - Optional mapping of values to colors to override the *BarColor values above
-*                  can be an Array of values to control the color of individual bars or a range map
-*                  to specify colors for individual ranges of values
-*
-*   discrete - Options:
-*       lineHeight - Height of each line in pixels - Defaults to 30% of the graph height
-*       thesholdValue - Values less than this value will be drawn using thresholdColor instead of lineColor
-*       thresholdColor
-*
-*   bullet - Values for bullet graphs msut be in the order: target, performance, range1, range2, range3, ...
-*       options:
-*       targetColor - The color of the vertical target marker
-*       targetWidth - The width of the target marker in pixels
-*       performanceColor - The color of the performance measure horizontal bar
-*       rangeColors - Colors to use for each qualitative range background color
-*
-*   pie - Pie chart. Options:
-*       sliceColors - An array of colors to use for pie slices
-*       offset - Angle in degrees to offset the first slice - Try -90 or +90
-*       borderWidth - Width of border to draw around the pie chart, in pixels - Defaults to 0 (no border)
-*       borderColor - Color to use for the pie chart border - Defaults to #000
-*   stack - Horizontal stack chart. Options:
-*       sliceColors - An array of colors to use for pie slices
-*
-*   box - Box plot. Options:
-*       raw - Set to true to supply pre-computed plot points as values
-*             values should be: low_outlier, low_whisker, q1, median, q3, high_whisker, high_outlier
-*             When set to false you can supply any number of values and the box plot will
-*             be computed for you.  Default is false.
-*       showOutliers - Set to true (default) to display outliers as circles
-*       outlierIQR - Interquartile range used to determine outliers.  Default 1.5
-*       boxLineColor - Outline color of the box
-*       boxFillColor - Fill color for the box
-*       whiskerColor - Line color used for whiskers
-*       outlierLineColor - Outline color of outlier circles
-*       outlierFillColor - Fill color of the outlier circles
-*       spotRadius - Radius of outlier circles
-*       medianColor - Line color of the median line
-*       target - Draw a target cross hair at the supplied value (default undefined)
-*
-*
-*
-*   Examples:
-*   $('#sparkline1').sparkline(myvalues, { lineColor: '#f00', fillColor: false });
-*   $('.barsparks').sparkline('html', { type:'bar', height:'40px', barWidth:5 });
-*   $('#tristate').sparkline([1,1,-1,1,0,0,-1], { type:'tristate' }):
-*   $('#discrete').sparkline([1,3,4,5,5,3,4,5], { type:'discrete' });
-*   $('#bullet').sparkline([10,12,12,9,7], { type:'bullet' });
-*   $('#pie').sparkline([1,1,2], { type:'pie' });
-*/
-
-/*jslint regexp: true, browser: true, jquery: true, white: true, nomen: false, plusplus: false, maxerr: 500, indent: 4 */
-
-(function(document, Math, undefined) { // performance/minified-size optimization
-(function(factory) {
-    if(typeof define === 'function' && define.amd) {
-        define('jquery.sparkline', ['jquery'], factory);
-    } else if (jQuery && !jQuery.fn.sparkline) {
-        factory(jQuery);
-    }
-}
-(function($) {
-    'use strict';
-
-    // CUSTOM MOD: median var added
-    var UNSET_OPTION = {},
-        getDefaults, createClass, SPFormat, clipval, median, quartile, normalizeValue, normalizeValues,
-        remove, isNumber, all, sum, addCSS, ensureArray, formatNumber, RangeMap,
-        MouseHandler, Tooltip, barHighlightMixin,
-        line, bar, tristate, discrete, bullet, pie, stack, box, timeline, defaultStyles, initStyles,
-        VShape, VCanvas_base, VCanvas_canvas, VCanvas_vml, pending, shapeCount = 0;
-
-
-    /**
-     * Default configuration settings
-     */
-    getDefaults = function () {
-        return {
-            // Settings common to most/all chart types
-            common: {
-                type: 'line',
-                lineColor: '#00f',
-                fillColor: '#cdf',
-                defaultPixelsPerValue: 3,
-                width: 'auto',
-                height: 'auto',
-                composite: false,
-                tagValuesAttribute: 'values',
-                tagOptionsPrefix: 'spark',
-                enableTagOptions: false,
-                enableHighlight: true,
-                highlightLighten: 1.4,
-                tooltipSkipNull: true,
-                tooltipPrefix: '',
-                tooltipSuffix: '',
-                disableHiddenCheck: false,
-                numberFormatter: false,
-                numberDigitGroupCount: 3,
-                numberDigitGroupSep: ',',
-                numberDecimalMark: '.',
-                disableTooltips: false,
-                disableInteraction: false
-            },
-            // Defaults for line charts
-            line: {
-                spotColor: '#f80',
-                highlightSpotColor: '#5f5',
-                highlightLineColor: '#f22',
-                refLineColor: '#f22',
-                // refLineX: null,
-                // refLineY: null,
-                spotRadius: 1.5,
-                minSpotColor: '#f80',
-                maxSpotColor: '#f80',
-                lineWidth: 1,
-                normalRangeMin: undefined,
-                normalRangeMax: undefined,
-                normalRangeColor: '#ccc',
-                drawNormalOnTop: false,
-                chartRangeMin: undefined,
-                chartRangeMax: undefined,
-                chartRangeMinX: undefined,
-                chartRangeMaxX: undefined,
-                tooltipFormat: new SPFormat('<span style="color: {{color}}">&#9679;</span> {{prefix}}{{y}}{{suffix}}')
-            },
-            // Defaults for bar charts
-            bar: {
-                barColor: '#3366cc',
-                negBarColor: '#f44',
-                stackedBarColor: ['#3366cc', '#dc3912', '#ff9900', '#109618', '#66aa00',
-                    '#dd4477', '#0099c6', '#990099'],
-                zeroColor: undefined,
-                nullColor: undefined,
-                zeroAxis: true,
-                barWidth: 4,
-                barSpacing: 1,
-                chartRangeMax: undefined,
-                chartRangeMin: undefined,
-                chartRangeClip: false,
-                colorMap: undefined,
-                tooltipFormat: new SPFormat('<span style="color: {{color}}">&#9679;</span> {{prefix}}{{value}}{{suffix}}')
-            },
-            // Defaults for timeline charts
-            timeline: {
-                width: 120,
-                height: 3,
-                lineColor: '#6792c6',
-                fillColor: '#bad7fb',
-                orientation: 'horizontal', // or 'vertical'
-                // number of minutes to modulate time markers from begin option
-                timeMarkInterval: 0,
-                // minimum date/time to show in timeline
-                begin: new Date(2000, 1, 1, 0, 0),
-                // maximum date/time to show in timeline
-                finish: new Date(2000, 1, 1, 23, 59),
-                // allow user to provide their own date parsing abilities
-                // data must provide begin, finish, title and color hash object
-                init: function (data) { return {begin: new Date(data.begin), finish: new Date(data.finish), title: data.title, color: data.color}; },
-                tooltipFormat: new SPFormat('<span style="color: {{color}}">&#9679;</span> {{title}}: {{begin}} / {{finish}}')
-            },
-            // Defaults for tristate charts
-            tristate: {
-                barWidth: 4,
-                barSpacing: 1,
-                posBarColor: '#6f6',
-                negBarColor: '#f44',
-                zeroBarColor: '#999',
-                colorMap: {},
-                tooltipFormat: new SPFormat('<span style="color: {{color}}">&#9679;</span> {{prefix}}{{value:map}}{{suffix}}'),
-                tooltipValueLookups: { map: { '-1': 'Loss', '0': 'Draw', '1': 'Win' } }
-            },
-            // Defaults for discrete charts
-            discrete: {
-                lineHeight: 'auto',
-                thresholdColor: undefined,
-                thresholdValue: 0,
-                chartRangeMax: undefined,
-                chartRangeMin: undefined,
-                chartRangeClip: false,
-                tooltipFormat: new SPFormat('{{prefix}}{{value}}{{suffix}}')
-            },
-            // Defaults for bullet charts
-            bullet: {
-                targetColor: '#f33',
-                targetWidth: 3, // width of the target bar in pixels
-                performanceColor: '#33f',
-                rangeColors: ['#d3dafe', '#a8b6ff', '#7f94ff'],
-                base: undefined, // set this to a number to change the base start number
-                tooltipFormat: new SPFormat('{{fieldkey:fields}} - {{value}}'),
-                tooltipValueLookups: { fields: {r: 'Range', p: 'Performance', t: 'Target'} }
-            },
-            // Defaults for pie charts
-            pie: {
-                offset: 0,
-                sliceColors: ['#3366cc', '#dc3912', '#ff9900', '#109618', '#66aa00',
-                    '#dd4477', '#0099c6', '#990099'],
-                borderWidth: 0,
-                borderColor: '#000',
-                tooltipFormat: new SPFormat('<span style="color: {{color}}">&#9679;</span> {{prefix}}{{value}} ({{percent.1}}%){{suffix}}')
-            },
-            // Defaults for stack charts
-            stack: {
-                offset: 0,
-                sliceColors: ['#3366cc', '#dc3912', '#ff9900', '#109618', '#66aa00',
-                    '#dd4477', '#0099c6', '#990099'],
-                borderWidth: 0,
-                borderColor: '#000',
-                tooltipFormat: new SPFormat('<span style="color: {{color}}">&#9679;</span> {{value}} ({{percent.1}}%)')
-            },
-            // Defaults for box plots
-            box: {
-                raw: false,
-                boxLineColor: '#000',
-                boxFillColor: '#cdf',
-                whiskerColor: '#000',
-                outlierLineColor: '#333',
-                outlierFillColor: '#fff',
-                medianColor: '#f00',
-                showOutliers: true,
-                outlierIQR: 1.5,
-                spotRadius: 1.5,
-                target: undefined,
-                targetColor: '#4a2',
-                chartRangeMax: undefined,
-                chartRangeMin: undefined,
-                tooltipFormat: new SPFormat('{{field:fields}}: {{value}}'),
-                tooltipFormatFieldlistKey: 'field',
-                tooltipValueLookups: { fields: { lq: 'Lower Quartile', med: 'Median',
-                    uq: 'Upper Quartile', lo: 'Left Outlier', ro: 'Right Outlier',
-                    lw: 'Left Whisker', rw: 'Right Whisker'} }
-            }
-        };
-    };
-
-    // Bootstrap adds box-sizing that messes with alignment in the tooltip.
-    var box_sizing = '-webkit-box-sizing: content-box !important;' +
-          '-moz-box-sizing: content-box !important;' +
-          'box-sizing: content-box !important;';
-
-    // You can have tooltips use a css class other than jqstooltip by specifying tooltipClassname
-    defaultStyles = '.jqstooltip { ' +
-            'position: absolute;' +
-            'left: 0px;' +
-            'top: 0px;' +
-            'visibility: hidden;' +
-            'background: rgb(0, 0, 0) transparent;' +
-            'background-color: rgba(0,0,0,0.6);' +
-            'filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000);' +
-            '-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000)";' +
-            'color: white;' +
-            'font: 10px arial, san serif;' +
-            'text-align: left;' +
-            'white-space: nowrap;' +
-            'padding: 5px;' +
-            'border: 1px solid white;' +
-            'z-index: 10000;' +
-            box_sizing +
-            '}' +
-            '.jqsfield { ' +
-            'color: white;' +
-            'font: 10px arial, san serif;' +
-            'text-align: left;' +
-            '}' +
-            '.jqstooltip:before, .jqstooltip:after { ' +
-            box_sizing +
-            '}';
-
-    /**
-     * Utilities
-     */
-
-    createClass = function (/* [baseclass, [mixin, ...]], definition */) {
-        var Class, args;
-        Class = function () {
-            this.init.apply(this, arguments);
-        };
-        if (arguments.length > 1) {
-            if (arguments[0]) {
-                Class.prototype = $.extend(new arguments[0](), arguments[arguments.length - 1]);
-                Class._super = arguments[0].prototype;
-            } else {
-                Class.prototype = arguments[arguments.length - 1];
-            }
-            if (arguments.length > 2) {
-                args = Array.prototype.slice.call(arguments, 1, -1);
-                args.unshift(Class.prototype);
-                $.extend.apply($, args);
-            }
-        } else {
-            Class.prototype = arguments[0];
-        }
-        Class.prototype.cls = Class;
-        return Class;
-    };
-
-    /**
-     * Wraps a format string for tooltips
-     * {{x}}
-     * {{x.2}
-     * {{x:months}}
-     */
-    $.SPFormatClass = SPFormat = createClass({
-        fre: /\{\{([\w.]+?)(:(.+?))?\}\}/g,
-        precre: /(\w+)\.(\d+)/,
-
-        init: function (format, fclass) {
-            this.format = format;
-            this.fclass = fclass;
-        },
-
-        render: function (fieldset, lookups, options) {
-            var self = this,
-                fields = fieldset,
-                match, token, lookupkey, fieldvalue, prec;
-
-            return this.format.replace(this.fre, function () {
-                var lookup;
-                token = arguments[1];
-                lookupkey = arguments[3];
-                match = self.precre.exec(token);
-                if (match) {
-                    prec = match[2];
-                    token = match[1];
-                } else {
-                    prec = false;
-                }
-                fieldvalue = fields[token];
-                if (fieldvalue === undefined) {
-                    return '';
-                }
-                if (lookupkey && lookups && lookups[lookupkey]) {
-                    lookup = lookups[lookupkey];
-                    if (lookup.get) { // RangeMap
-                        return lookups[lookupkey].get(fieldvalue) || fieldvalue;
-                    } else {
-                        return lookups[lookupkey][fieldvalue] || fieldvalue;
-                    }
-                }
-                if (isNumber(fieldvalue)) {
-                    if (options.get('numberFormatter')) {
-                        fieldvalue = options.get('numberFormatter')(fieldvalue);
-                    } else {
-                        fieldvalue = formatNumber(fieldvalue, prec,
-                            options.get('numberDigitGroupCount'),
-                            options.get('numberDigitGroupSep'),
-                            options.get('numberDecimalMark'));
-                    }
-                }
-                return fieldvalue;
-            });
-        }
-    });
-
-    // convenience method to avoid needing the new operator
-    $.spformat = function (format, fclass) {
-        return new SPFormat(format, fclass);
-    };
-
-    clipval = function (val, min, max) {
-        if (val < min) {
-            return min;
-        }
-        if (val > max) {
-            return max;
-        }
-        return val;
-    };
-
-    // CUSTOM MOD: completely new median function
-    median = function (values) {
-        var ret, idx;
-        if (0 === values.length % 2) {
-            var v1, v2;
-            idx = values.length / 2;
-            v1 = values[idx - 1];
-            v2 = values[idx];
-            ret = (v1 + v2) / 2;
-        }
-        else {
-            idx = parseInt(values.length / 2);
-            ret = values[idx];
-        }
-
-        return { 
-            m: ret, 
-            idx: idx 
-        };
-    };
-
-    // CUSTOM MOD: completely rewritten quartile function
-    quartile = function (values, q) {
-        var ret, m, med;
-        m = median(values);
-
-        if (q === 2) {
-            ret = m.m;
-        }
-        else {
-            var arr = [];
-            med = m.m;
-
-            if (med != null) {                                                              // jshint ignore:line
-                var i = 0;
-                if (q === 1) {
-                    while (i < m.idx) {
-                      arr[i] = values[i];
-                      i++;
-                    }
-                    if (!arr.length)
-                      arr = [ values[0] ];
-                }
-                else if (q === 3) {
-                    var j = values.length - 1;
-                    while (j > m.idx) {
-                        arr[i] = values[j];
-                        i++;
-                        j--;
-                    }
-                    if (!arr.length)
-                      arr = [ values[values.length - 1] ];
-                }
-            }
-            m = median(arr);
-            ret = m.m;
-        }
-        return ret;
-    };
-
-    normalizeValue = function (val) {
-        var nf;
-        switch (val) {
-        case 'undefined':
-            val = undefined;
-            break;
-        case 'null':
-            val = null;
-            break;
-        case 'true':
-            val = true;
-            break;
-        case 'false':
-            val = false;
-            break;
-        default:
-            nf = parseFloat(val);
-            if (val == nf) {
-                val = nf;
-            }
-        }
-        return val;
-    };
-
-    normalizeValues = function (vals) {
-        var i, result = [];
-        for (i = vals.length; i--;) {
-            result[i] = normalizeValue(vals[i]);
-        }
-        return result;
-    };
-
-    remove = function (vals, filter) {
-        var i, vl, result = [];
-        for (i = 0, vl = vals.length; i < vl; i++) {
-            if (vals[i] !== filter) {
-                result.push(vals[i]);
-            }
-        }
-        return result;
-    };
-
-    isNumber = function (num) {
-        return !isNaN(parseFloat(num)) && isFinite(num);
-    };
-
-    formatNumber = function (num, prec, groupsize, groupsep, decsep) {
-        var p, i;
-        num = (prec === false ? parseFloat(num).toString() : num.toFixed(prec)).split('');
-        p = (p = $.inArray('.', num)) < 0 ? num.length : p;
-        if (p < num.length) {
-            num[p] = decsep;
-        }
-        for (i = p - groupsize; i > 0; i -= groupsize) {
-            num.splice(i, 0, groupsep);
-        }
-        return num.join('');
-    };
-
-    // determine if all values of an array match a value
-    // returns true if the array is empty
-    all = function (val, arr, ignoreNull) {
-        var i;
-        for (i = arr.length; i--; ) {
-            if (ignoreNull && arr[i] === null) continue;
-            if (arr[i] !== val) {
-                return false;
-            }
-        }
-        return true;
-    };
-
-    // sums the numeric values in an array, ignoring other values
-    sum = function (vals) {
-        var total = 0, i;
-        for (i = vals.length; i--;) {
-            total += typeof vals[i] === 'number' ? vals[i] : 0;
-        }
-        return total;
-    };
-
-    ensureArray = function (val) {
-        return $.isArray(val) ? val : [val];
-    };
-
-    // http://paulirish.com/2008/bookmarklet-inject-new-css-rules/
-    addCSS = function (css) {
-        var tag, iefail;
-        if (document.createStyleSheet) {
-            try {
-                document.createStyleSheet().cssText = css;
-                return;
-            } catch (e) {
-                // IE <= 9 maxes out at 31 stylesheets; inject into page instead.
-                iefail = true;
-            }
-        }
-        tag = document.createElement('style');
-        tag.type = 'text/css';
-        document.getElementsByTagName('head')[0].appendChild(tag);
-        if (iefail) {
-            document.styleSheets[document.styleSheets.length - 1].cssText = css;
-        } else {
-            tag[(typeof document.body.style.WebkitAppearance == 'string') /* webkit only */ ? 'innerText' : 'innerHTML'] = css;
-        }
-    };
-
-
-    // Provide a cross-browser interface to a few simple drawing primitives
-    $.fn.simpledraw = function (width, height, useExisting, interact) {
-        var target, mhandler;
-        if (useExisting && (target = this.data('_jqs_vcanvas'))) {
-            return target;
-        }
-
-        if ($.fn.sparkline.canvas === false) {
-            // We've already determined that neither Canvas nor VML are available
-            return false;
-        } else if ($.fn.sparkline.canvas === undefined) {
-            // No function defined yet -- need to see if we support Canvas or VML
-            var el = document.createElement('canvas');
-            if (!!(el.getContext && el.getContext('2d'))) {
-                // Canvas is available
-                $.fn.sparkline.canvas = function(width, height, target, interact) {
-                    return new VCanvas_canvas(width, height, target, interact);
-                };
-            } else if (document.namespaces && !document.namespaces.v) {
-                // VML is available
-                document.namespaces.add('v', 'urn:schemas-microsoft-com:vml', '#default#VML');
-                $.fn.sparkline.canvas = function(width, height, target, interact) {
-                    return new VCanvas_vml(width, height, target);
-                };
-            } else {
-                // Neither Canvas nor VML are available
-                $.fn.sparkline.canvas = false;
-                return false;
-            }
-        }
-
-        if (width === undefined) {
-            width = $(this).innerWidth();
-        }
-        if (height === undefined) {
-            height = $(this).innerHeight();
-        }
-
-        target = $.fn.sparkline.canvas(width, height, this, interact);
-
-        mhandler = $(this).data('_jqs_mhandler');
-        if (mhandler) {
-            mhandler.registerCanvas(target);
-        }
-        return target;
-    };
-
-    $.fn.cleardraw = function () {
-        var target = this.data('_jqs_vcanvas');
-        if (target) {
-            target.reset();
-        }
-    };
-
-
-    $.RangeMapClass = RangeMap = createClass({
-        init: function (map) {
-            var key, range, rangelist = [];
-            for (key in map) {
-                if (map.hasOwnProperty(key) && typeof key === 'string' && key.indexOf(':') > -1) {
-                    range = key.split(':');
-                    range[0] = range[0].length === 0 ? -Infinity : parseFloat(range[0]);
-                    range[1] = range[1].length === 0 ? Infinity : parseFloat(range[1]);
-                    range[2] = map[key];
-                    rangelist.push(range);
-                }
-            }
-            this.map = map;
-            this.rangelist = rangelist || false;
-        },
-
-        get: function (value) {
-            var rangelist = this.rangelist,
-                i, range, result;
-            if ((result = this.map[value]) !== undefined) {
-                return result;
-            }
-            if (rangelist) {
-                for (i = rangelist.length; i--;) {
-                    range = rangelist[i];
-                    if (range[0] <= value && range[1] >= value) {
-                        return range[2];
-                    }
-                }
-            }
-            return undefined;
-        }
-    });
-
-    // Convenience function
-    $.range_map = function(map) {
-        return new RangeMap(map);
-    };
-
-
-    MouseHandler = createClass({
-        init: function (el, options) {
-            var $el = $(el);
-            this.$el = $el;
-            this.options = options;
-            this.currentPageX = 0;
-            this.currentPageY = 0;
-            this.el = el;
-            this.splist = [];
-            this.tooltip = null;
-            this.over = false;
-            this.displayTooltips = !options.get('disableTooltips');
-            this.highlightEnabled = !options.get('disableHighlight');
-        },
-
-        registerSparkline: function (sp) {
-            this.splist.push(sp);
-            if (this.over) {
-                this.updateDisplay();
-            }
-        },
-
-        registerCanvas: function (canvas) {
-            var $canvas = $(canvas.canvas);
-            this.canvas = canvas;
-            this.$canvas = $canvas;
-            $canvas.mouseenter($.proxy(this.mouseenter, this));
-            $canvas.mouseleave($.proxy(this.mouseleave, this));
-            $canvas.click($.proxy(this.mouseclick, this));
-        },
-
-        reset: function (removeTooltip) {
-            this.splist = [];
-            if (this.tooltip && removeTooltip) {
-                this.tooltip.remove();
-                this.tooltip = undefined;
-            }
-        },
-
-        mouseclick: function (e) {
-            var clickEvent = $.Event('sparklineClick');
-            clickEvent.originalEvent = e;
-            clickEvent.sparklines = this.splist;
-            this.$el.trigger(clickEvent);
-        },
-
-        mouseenter: function (e) {
-            $(document.body).unbind('mousemove.jqs');
-            $(document.body).bind('mousemove.jqs', $.proxy(this.mousemove, this));
-            this.over = true;
-            this.currentPageX = e.pageX;
-            this.currentPageY = e.pageY;
-            this.currentEl = e.target;
-            if (!this.tooltip && this.displayTooltips) {
-                this.tooltip = new Tooltip(this.options);
-                this.tooltip.updatePosition(e.pageX, e.pageY);
-            }
-            this.updateDisplay();
-        },
-
-        mouseleave: function () {
-            $(document.body).unbind('mousemove.jqs');
-            var splist = this.splist,
-                 spcount = splist.length,
-                 needsRefresh = false,
-                 sp, i;
-            this.over = false;
-            this.currentEl = null;
-
-            if (this.tooltip) {
-                this.tooltip.remove();
-                this.tooltip = null;
-            }
-
-            for (i = 0; i < spcount; i++) {
-                sp = splist[i];
-                if (sp.clearRegionHighlight()) {
-                    needsRefresh = true;
-                }
-            }
-
-            if (needsRefresh) {
-                this.canvas.render();
-            }
-        },
-
-        mousemove: function (e) {
-            this.currentPageX = e.pageX;
-            this.currentPageY = e.pageY;
-            this.currentEl = e.target;
-            if (this.tooltip) {
-                this.tooltip.updatePosition(e.pageX, e.pageY);
-            }
-            this.updateDisplay();
-        },
-
-        updateDisplay: function () {
-            var splist = this.splist,
-                 spcount = splist.length,
-                 needsRefresh = false,
-                 offset = this.$canvas.offset(),
-                 localX = Math.round(this.currentPageX - offset.left),
-                 localY = Math.round(this.currentPageY - offset.top),
-                 tooltiphtml, sp, i, result, changeEvent;
-            // localX/localY fix issue #50 with Google Chrome
-            // and subpixel rendering
-
-            if (!this.over) {
-                return;
-            }
-            for (i = 0; i < spcount; i++) {
-                sp = splist[i];
-                result = sp.setRegionHighlight(this.currentEl, localX, localY);
-                if (result) {
-                    needsRefresh = true;
-                }
-            }
-            if (needsRefresh) {
-                changeEvent = $.Event('sparklineRegionChange');
-                changeEvent.sparklines = this.splist;
-                this.$el.trigger(changeEvent);
-                if (this.tooltip) {
-                    tooltiphtml = '';
-                    for (i = 0; i < spcount; i++) {
-                        sp = splist[i];
-                        tooltiphtml += sp.getCurrentRegionTooltip();
-                    }
-                    this.tooltip.setContent(tooltiphtml);
-                }
-                if (!this.disableHighlight) {
-                    this.canvas.render();
-                }
-            }
-            if (result === null) {
-                this.mouseleave();
-            }
-        }
-    });
-
-
-    Tooltip = createClass({
-        sizeStyle: 'position: static !important;' +
-            'display: block !important;' +
-            'visibility: hidden !important;' +
-            'float: left !important;',
-
-        init: function (options) {
-            var tooltipClassname = options.get('tooltipClassname', 'jqstooltip'),
-                sizetipStyle = this.sizeStyle,
-                offset;
-            this.container = options.get('tooltipContainer') || document.body;
-            this.tooltipOffsetX = options.get('tooltipOffsetX', 10);
-            this.tooltipOffsetY = options.get('tooltipOffsetY', 12);
-            this.displayOnLeft  = options.get('toolTipPosition') === 'left';
-            // remove any previous lingering tooltip
-            $('#jqssizetip').remove();
-            $('#jqstooltip').remove();
-            this.sizetip = $('<div/>', {
-                id: 'jqssizetip',
-                style: sizetipStyle,
-                'class': tooltipClassname
-            });
-            this.tooltip = $('<div/>', {
-                id: 'jqstooltip',
-                'class': tooltipClassname
-            }).appendTo(this.container);
-            // account for the container's location
-            offset = this.tooltip.offset();
-            this.offsetLeft = offset.left;
-            this.offsetTop = offset.top;
-            this.hidden = true;
-            $(window).unbind('resize.jqs scroll.jqs');
-            $(window).bind('resize.jqs scroll.jqs', $.proxy(this.updateWindowDims, this));
-            this.updateWindowDims();
-        },
-
-        updateWindowDims: function () {
-            this.scrollTop = $(window).scrollTop();
-            this.scrollLeft = $(window).scrollLeft();
-            this.scrollRight = this.scrollLeft + $(window).width();
-            this.updatePosition();
-        },
-
-        getSize: function (content) {
-            this.sizetip.html(content).appendTo(this.container);
-            var lpadding = parseInt(this.sizetip.css('padding-left'), 10);
-            var rpadding = parseInt(this.sizetip.css('padding-right'), 10);
-            this.padding = lpadding + rpadding + 1;
-            this.width = this.sizetip.width() + 1;
-            this.height = this.sizetip.height();
-            this.sizetip.remove();
-        },
-
-        setContent: function (content) {
-            if (!content) {
-                this.tooltip.css('visibility', 'hidden');
-                this.hidden = true;
-                return;
-            }
-            this.getSize(content);
-            this.tooltip.html(content)
-                .css({
-                    'width': this.width,
-                    'height': this.height,
-                    'visibility': 'visible'
-                });
-            if (this.hidden) {
-                this.hidden = false;
-                this.updatePosition();
-            }
-        },
-
-        updatePosition: function (x, y) {
-            if (x === undefined) {
-                if (this.mousex === undefined) {
-                    return;
-                }
-                x = this.mousex - this.offsetLeft;
-                y = this.mousey - this.offsetTop;
-
-            } else {
-                this.mousex = x = x - this.offsetLeft;
-                this.mousey = y = y - this.offsetTop;
-            }
-            if (!this.height || !this.width || this.hidden) {
-                return;
-            }
-
-            y -= this.height + this.tooltipOffsetY;
-            if (y < this.scrollTop) {
-                y = this.scrollTop;
-            }
-
-            if (this.displayOnLeft) {
-                x -= this.tooltipOffsetX + this.width + this.padding;
-            } else {
-                x += this.tooltipOffsetX;
-            }
-            if (x < this.scrollLeft) {
-                x = this.scrollLeft;
-            } else if (x + this.width > this.scrollRight) {
-                x = this.scrollRight - this.width;
-            }
-
-            this.tooltip.css({
-                'left': x,
-                'top': y
-            });
-        },
-
-        remove: function () {
-            this.tooltip.remove();
-            this.sizetip.remove();
-            this.sizetip = this.tooltip = undefined;
-            $(window).unbind('resize.jqs scroll.jqs');
-        }
-    });
-
-
-    initStyles = function() {
-        addCSS(defaultStyles);
-    };
-
-    $(initStyles);
-
-    pending = [];
-    $.fn.sparkline = function (userValues, userOptions) {
-        return this.each(function () {
-            var options = new $.fn.sparkline.options(this, userOptions),
-                 $this = $(this),
-                 render, i;
-            render = function () {
-                var values, width, height, tmp, mhandler, sp, vals;
-                if (userValues === 'html' || userValues === undefined) {
-                    vals = this.getAttribute(options.get('tagValuesAttribute'));
-                    if (vals === undefined || vals === null) {
-                        vals = $this.html();
-                    }
-                    values = vals.replace(/(^\s*<!--)|(-->\s*$)|\s+/g, '').split(',');
-                } else {
-                    values = userValues;
-                }
-
-                width = options.get('width') === 'auto' ? values.length * options.get('defaultPixelsPerValue') : options.get('width');
-                if (options.get('height') === 'auto') {
-                    if (!options.get('composite') || !$.data(this, '_jqs_vcanvas')) {
-                        // must be a better way to get the line height
-                        tmp = document.createElement('span');
-                        tmp.innerHTML = 'a';
-                        $this.html(tmp);
-                        height = $(tmp).innerHeight() || $(tmp).height();
-                        $(tmp).remove();
-                        tmp = null;
-                    }
-                } else {
-                    height = options.get('height');
-                }
-
-                if (!options.get('disableInteraction')) {
-                    mhandler = $.data(this, '_jqs_mhandler');
-                    if (!mhandler) {
-                        mhandler = new MouseHandler(this, options);
-                        $.data(this, '_jqs_mhandler', mhandler);
-                    } else if (!options.get('composite')) {
-                        mhandler.reset();
-                    }
-                } else {
-                    mhandler = false;
-                }
-
-                if (options.get('composite') && !$.data(this, '_jqs_vcanvas')) {
-                    if (!$.data(this, '_jqs_errnotify')) {
-                        alert('Attempted to attach a composite sparkline to an element with no existing sparkline');
-                        $.data(this, '_jqs_errnotify', true);
-                    }
-                    return;
-                }
-
-                sp = new $.fn.sparkline[options.get('type')](this, values, options, width, height);
-
-                sp.render();
-
-                if (mhandler) {
-                    mhandler.registerSparkline(sp);
-                }
-            };
-            if (($(this).html() && !options.get('disableHiddenCheck') && $(this).is(':hidden')) || !$(this).parents('body').length) {
-                if (!options.get('composite') && $.data(this, '_jqs_pending')) {
-                    // remove any existing references to the element
-                    for (i = pending.length; i; i--) {
-                        if (pending[i - 1][0] == this) {
-                            pending.splice(i - 1, 1);
-                        }
-                    }
-                }
-                pending.push([this, render]);
-                $.data(this, '_jqs_pending', true);
-            } else {
-                render.call(this);
-            }
-        });
-    };
-
-    $.fn.sparkline.defaults = getDefaults();
-
-
-    $.sparkline_display_visible = function () {
-        var el, i, pl;
-        var done = [];
-        for (i = 0, pl = pending.length; i < pl; i++) {
-            el = pending[i][0];
-            if ($(el).is(':visible') && !$(el).parents().is(':hidden')) {
-                pending[i][1].call(el);
-                $.data(pending[i][0], '_jqs_pending', false);
-                done.push(i);
-            } else if (!$(el).closest('html').length && !$.data(el, '_jqs_pending')) {
-                // element has been inserted and removed from the DOM
-                // If it was not yet inserted into the dom then the .data request
-                // will return true.
-                // removing from the dom causes the data to be removed.
-                $.data(pending[i][0], '_jqs_pending', false);
-                done.push(i);
-            }
-        }
-        for (i = done.length; i; i--) {
-            pending.splice(done[i - 1], 1);
-        }
-    };
-
-
-    /**
-     * User option handler
-     */
-    $.fn.sparkline.options = createClass({
-        init: function (tag, userOptions) {
-            var extendedOptions, defaults, base, tagOptionType;
-            this.userOptions = userOptions = userOptions || {};
-            this.tag = tag;
-            this.tagValCache = {};
-            defaults = $.fn.sparkline.defaults;
-            base = defaults.common;
-            this.tagOptionsPrefix = userOptions.enableTagOptions && (userOptions.tagOptionsPrefix || base.tagOptionsPrefix);
-
-            tagOptionType = this.getTagSetting('type');
-            if (tagOptionType === UNSET_OPTION) {
-                extendedOptions = defaults[userOptions.type || base.type];
-            } else {
-                extendedOptions = defaults[tagOptionType];
-            }
-            this.mergedOptions = $.extend({}, base, extendedOptions, userOptions);
-        },
-
-
-        getTagSetting: function (key) {
-            var prefix = this.tagOptionsPrefix,
-                val, i, pairs, keyval;
-            if (prefix === false || prefix === undefined) {
-                return UNSET_OPTION;
-            }
-            if (this.tagValCache.hasOwnProperty(key)) {
-                val = this.tagValCache.key;
-            } else {
-                val = this.tag.getAttribute(prefix + key);
-                if (val === undefined || val === null) {
-                    val = UNSET_OPTION;
-                } else if (val.substr(0, 1) === '[') {
-                    val = val.substr(1, val.length - 2).split(',');
-                    for (i = val.length; i--;) {
-                        val[i] = normalizeValue(val[i].replace(/(^\s*)|(\s*$)/g, ''));
-                    }
-                } else if (val.substr(0, 1) === '{') {
-                    pairs = val.substr(1, val.length - 2).split(',');
-                    val = {};
-                    for (i = pairs.length; i--;) {
-                        keyval = pairs[i].split(':', 2);
-                        val[keyval[0].replace(/(^\s*)|(\s*$)/g, '')] = normalizeValue(keyval[1].replace(/(^\s*)|(\s*$)/g, ''));
-                    }
-                } else {
-                    val = normalizeValue(val);
-                }
-                this.tagValCache.key = val;
-            }
-            return val;
-        },
-
-        get: function (key, defaultval) {
-            var tagOption = this.getTagSetting(key),
-                result;
-            if (tagOption !== UNSET_OPTION) {
-                return tagOption;
-            }
-            return (result = this.mergedOptions[key]) === undefined ? defaultval : result;
-        }
-    });
-
-
-    $.fn.sparkline._base = createClass({
-        disabled: false,
-
-        init: function (el, values, options, width, height) {
-            this.el = el;
-            this.$el = $(el);
-            this.values = values;
-            this.options = options;
-            this.width = width;
-            this.height = height;
-            this.currentRegion = undefined;
-        },
-
-        /**
-         * Setup the canvas
-         */
-        initTarget: function () {
-            var interactive = !this.options.get('disableInteraction');
-            if (!(this.target = this.$el.simpledraw(this.width, this.height, this.options.get('composite'), interactive))) {
-                this.disabled = true;
-            } else {
-                this.canvasWidth = this.target.pixelWidth;
-                this.canvasHeight = this.target.pixelHeight;
-            }
-        },
-
-        /**
-         * Setup colorMap from options
-         */
-        initColorMap: function() {
-            var colorMap = this.options.get('colorMap');
-            if ($.isFunction(colorMap)) {
-                this.colorMapFunction = colorMap;
-            } else if ($.isArray(colorMap)) {
-                this.colorMapFunction = function(sparkline, options, index, value) {
-                    if (index < colorMap.length) {
-                        return colorMap[index];
-                    }
-                    // else undefined
-                };
-            } else if (colorMap) {
-                if (colorMap.get === undefined) {
-                    colorMap = new RangeMap(colorMap); 
-                }
-                this.colorMapFunction = function(sparkline, options, index, value) {
-                    return colorMap.get(value);
-                };
-            }
-        },
-
-        /**
-         * Actually render the chart to the canvas
-         */
-        render: function () {
-            if (this.disabled) {
-                this.el.innerHTML = '';
-                return false;
-            }
-            return true;
-        },
-
-        /**
-         * Return a region id for a given x/y co-ordinate
-         */
-        getRegion: function (x, y) {
-        },
-
-        /**
-         * Highlight an item based on the moused-over x,y co-ordinate
-         */
-        setRegionHighlight: function (el, x, y) {
-            var currentRegion = this.currentRegion,
-                highlightEnabled = !this.options.get('disableHighlight'),
-                newRegion;
-            // CUSTOM MOD: proper hover detection considering padding as well
-            var cW = $('canvas',this.el).width() + parseInt($('canvas',this.el).css('padding-left')) + parseInt($('canvas',this.el).css('padding-right'))
-            // if (x > this.canvasWidth || y > this.canvasHeight || x < 0 || y < 0) {
-            if (x > cW || y > this.canvasHeight || x < 0 || y < 0) {
-                return null;
-            }
-            newRegion = this.getRegion(el, x, y);
-            if (currentRegion !== newRegion) {
-                if (currentRegion !== undefined && highlightEnabled) {
-                    this.removeHighlight();
-                }
-                this.currentRegion = newRegion;
-                if (newRegion !== undefined && highlightEnabled) {
-                    this.renderHighlight();
-                }
-                return true;
-            }
-            return false;
-        },
-
-        /**
-         * Reset any currently highlighted item
-         */
-        clearRegionHighlight: function () {
-            if (this.currentRegion !== undefined) {
-                this.removeHighlight();
-                this.currentRegion = undefined;
-                return true;
-            }
-            return false;
-        },
-
-        renderHighlight: function () {
-            this.changeHighlight(true);
-        },
-
-        removeHighlight: function () {
-            this.changeHighlight(false);
-        },
-
-        changeHighlight: function (highlight)  {},
-
-        /**
-         * Fetch the HTML to display as a tooltip
-         */
-        getCurrentRegionTooltip: function () {
-            var options = this.options,
-                header = '',
-                entries = [],
-                fields, formats, formatlen, fclass, text, i,
-                showFields, showFieldsKey, newFields, fv,
-                formatter, format, fieldlen, j,
-                label_prefix, label_suffix;
-            if (this.currentRegion === undefined) {
-                return '';
-            }
-            fields = this.getCurrentRegionFields();
-            formatter = options.get('tooltipFormatter');
-            if (formatter) {
-                return formatter(this, options, fields);
-            }
-            if (options.get('tooltipChartTitle')) {
-                header += '<div class="jqs jqstitle">' + options.get('tooltipChartTitle') + '</div>\n';
-            }
-            formats = this.options.get('tooltipFormat');
-            if (!formats) {
-                return '';
-            }
-            if (!$.isArray(formats)) {
-                formats = [formats];
-            }
-            if (!$.isArray(fields)) {
-                fields = [fields];
-            }
-            showFields = this.options.get('tooltipFormatFieldlist');
-            showFieldsKey = this.options.get('tooltipFormatFieldlistKey');
-            if (showFields && showFieldsKey) {
-                // user-selected ordering of fields
-                newFields = [];
-                for (i = fields.length; i--;) {
-                    fv = fields[i][showFieldsKey];
-                    if ((j = $.inArray(fv, showFields)) != -1) {
-                        newFields[j] = fields[i];
-                    }
-                }
-                fields = newFields;
-            }
-            formatlen = formats.length;
-            fieldlen = fields.length;
-            for (i = 0; i < formatlen; i++) {
-                format = formats[i];
-                if (typeof format === 'string') {
-                    format = new SPFormat(format);
-                }
-                fclass = format.fclass || 'jqsfield';
-
-                for (j = 0; j < fieldlen; j++) {
-                    if (!fields[j].isNull || !options.get('tooltipSkipNull')) {
-                        label_prefix = '';
-                        label_suffix = '';
-                        if (options.get('tooltipPrefixBinLabels')
-                            && (options.get('tooltipPrefixBinLabels').length > fields[j].offset)) {
-                            label_prefix = options.get('tooltipPrefixBinLabels')[fields[j].offset];
-                        }
-                        if (options.get('tooltipSuffixBinLabels')
-                            && (options.get('tooltipSuffixBinLabels').length > fields[j].offset)) {
-                            label_suffix = options.get('tooltipSuffixBinLabels')[fields[j].offset];
-                        }
-                        $.extend(fields[j], {
-                            prefix: label_prefix + options.get('tooltipPrefix'),
-                            suffix: options.get('tooltipSuffix') + label_suffix
-                        });
-
-                        text = format.render(fields[j], options.get('tooltipValueLookups'), options);
-                        entries.push('<div class="' + fclass + '">' + text + '</div>');
-                    }
-                }
-            }
-            if (entries.length) {
-                return header + entries.join('\n');
-            }
-            return '';
-        },
-
-        getCurrentRegionFields: function () {},
-
-        calcHighlightColor: function (color, options) {
-            var highlightColor = options.get('highlightColor'),
-                lighten = options.get('highlightLighten'),
-                parse, mult, rgbnew, i;
-            if (highlightColor) {
-                return highlightColor;
-            }
-            if (lighten) {
-                // extract RGB values
-                parse = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(color) || /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(color);
-                if (parse) {
-                    rgbnew = [];
-                    mult = color.length === 4 ? 16 : 1;
-                    for (i = 0; i < 3; i++) {
-                        rgbnew[i] = clipval(Math.round(parseInt(parse[i + 1], 16) * mult * lighten), 0, 255);
-                    }
-                    return 'rgb(' + rgbnew.join(',') + ')';
-                }
-
-            }
-            return color;
-        }
-
-    });
-
-    barHighlightMixin = {
-        changeHighlight: function (highlight) {
-            var currentRegion = this.currentRegion,
-                target = this.target,
-                shapeids = this.regionShapes[currentRegion],
-                newShapes;
-            // will be null if the region value was null
-            if (shapeids >= 0) {
-                newShapes = this.renderRegion(currentRegion, highlight);
-                if ($.isArray(newShapes) || $.isArray(shapeids)) {
-                    target.replaceWithShapes(shapeids, newShapes);
-                    this.regionShapes[currentRegion] = $.map(newShapes, function (newShape) {
-                        return newShape.id;
-                    });
-                } else {
-                    target.replaceWithShape(shapeids, newShapes);
-                    this.regionShapes[currentRegion] = newShapes.id;
-                }
-            }
-        },
-
-        render: function () {
-            var values = this.values,
-                target = this.target,
-                regionShapes = this.regionShapes,
-                shapes, ids, i, j;
-
-            if (!this.cls._super.render.call(this)) {
-                return;
-            }
-            for (i = values.length; i--;) {
-                shapes = this.renderRegion(i);
-                if (shapes) {
-                    if ($.isArray(shapes)) {
-                        ids = [];
-                        for (j = shapes.length; j--;) {
-                            shapes[j].append();
-                            ids.push(shapes[j].id);
-                        }
-                        regionShapes[i] = ids;
-                    } else {
-                        shapes.append();
-                        regionShapes[i] = shapes.id; // store just the shapeid
-                    }
-                } else {
-                    // null value
-                    regionShapes[i] = null;
-                }
-            }
-            target.render();
-        }
-    };
-
-
-    /**
-     * Line charts
-     */
-    $.fn.sparkline.line = line = createClass($.fn.sparkline._base, {
-        type: 'line',
-
-        init: function (el, values, options, width, height) {
-            line._super.init.call(this, el, values, options, width, height);
-            this.vertices = [];
-            this.regionMap = [];
-            this.xvalues = [];
-            this.yvalues = [];
-            this.yminmax = [];
-            this.hightlightSpotId = null;
-            this.lastShapeId = null;
-            this.initTarget();
-        },
-
-        getRegion: function (el, x, y) {
-            var i,
-                regionMap = this.regionMap; // maps regions to value positions
-            for (i = regionMap.length; i--;) {
-                if (regionMap[i] !== null && x * this.target.ratio >= regionMap[i][0] && x * this.target.ratio <= regionMap[i][1]) {
-                    return regionMap[i][2];
-                }
-            }
-            return undefined;
-        },
-
-        getCurrentRegionFields: function () {
-            var currentRegion = this.currentRegion;
-            return {
-                isNull: this.yvalues[currentRegion] === null,
-                x: this.xvalues[currentRegion],
-                y: this.yvalues[currentRegion],
-                color: this.options.get('lineColor'),
-                fillColor: this.options.get('fillColor'),
-                offset: currentRegion
-            };
-        },
-
-        renderHighlight: function () {
-            var currentRegion = this.currentRegion,
-                target = this.target,
-                vertex = this.vertices[currentRegion],
-                options = this.options,
-                spotRadius = options.get('spotRadius'),
-                highlightSpotColor = options.get('highlightSpotColor'),
-                highlightLineColor = options.get('highlightLineColor'),
-                highlightSpot, highlightLine;
-
-            if (!vertex) {
-                return;
-            }
-            if (spotRadius && highlightSpotColor) {
-                highlightSpot = target.drawCircle(vertex[0], vertex[1],
-                    spotRadius, undefined, highlightSpotColor);
-                this.highlightSpotId = highlightSpot.id;
-                target.insertAfterShape(this.lastShapeId, highlightSpot);
-            }
-            if (highlightLineColor) {
-                highlightLine = target.drawLine(vertex[0], this.canvasTop, vertex[0],
-                    this.canvasTop + this.canvasHeight, highlightLineColor);
-                this.highlightLineId = highlightLine.id;
-                target.insertAfterShape(this.lastShapeId, highlightLine);
-            }
-        },
-
-        removeHighlight: function () {
-            var target = this.target;
-            if (this.highlightSpotId) {
-                target.removeShapeId(this.highlightSpotId);
-                this.highlightSpotId = null;
-            }
-            if (this.highlightLineId) {
-                target.removeShapeId(this.highlightLineId);
-                this.highlightLineId = null;
-            }
-        },
-
-        scanValues: function () {
-            var values = this.values,
-                valcount = values.length,
-                xvalues = this.xvalues,
-                yvalues = this.yvalues,
-                yminmax = this.yminmax,
-                i, val, isStr, isArray, sp;
-            for (i = 0; i < valcount; i++) {
-                val = values[i];
-                isStr = typeof(values[i]) === 'string';
-                isArray = typeof(values[i]) === 'object' && values[i] instanceof Array;
-                sp = isStr && values[i].split(':');
-                if (isStr && sp.length === 2) { // x:y
-                    xvalues.push(Number(sp[0]));
-                    yvalues.push(Number(sp[1]));
-                    yminmax.push(Number(sp[1]));
-                } else if (isArray) {
-                    xvalues.push(val[0]);
-                    yvalues.push(val[1]);
-                    yminmax.push(val[1]);
-                } else {
-                    xvalues.push(i);
-                    if (values[i] === null || values[i] === 'null') {
-                        yvalues.push(null);
-                    } else {
-                        yvalues.push(Number(val));
-                        yminmax.push(Number(val));
-                    }
-                }
-            }
-            if (this.options.get('xvalues')) {
-                xvalues = this.options.get('xvalues');
-            }
-
-            this.maxy = this.maxyorg = Math.max.apply(Math, yminmax);
-            this.miny = this.minyorg = Math.min.apply(Math, yminmax);
-
-            this.maxx = Math.max.apply(Math, xvalues);
-            this.minx = Math.min.apply(Math, xvalues);
-
-            this.xvalues = xvalues;
-            this.yvalues = yvalues;
-            this.yminmax = yminmax;
-        },
-
-        processRangeOptions: function () {
-            var options = this.options,
-                normalRangeMin = options.get('normalRangeMin'),
-                normalRangeMax = options.get('normalRangeMax');
-
-            if (normalRangeMin !== undefined) {
-                if (normalRangeMin < this.miny) {
-                    this.miny = normalRangeMin;
-                }
-                if (normalRangeMax > this.maxy) {
-                    this.maxy = normalRangeMax;
-                }
-            }
-            if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < this.miny)) {
-                this.miny = options.get('chartRangeMin');
-            }
-            if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > this.maxy)) {
-                this.maxy = options.get('chartRangeMax');
-            }
-            if (options.get('chartRangeMinX') !== undefined && (options.get('chartRangeClipX') || options.get('chartRangeMinX') < this.minx)) {
-                this.minx = options.get('chartRangeMinX');
-            }
-            if (options.get('chartRangeMaxX') !== undefined && (options.get('chartRangeClipX') || options.get('chartRangeMaxX') > this.maxx)) {
-                this.maxx = options.get('chartRangeMaxX');
-            }
-
-        },
-
-        drawNormalRange: function (canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey) {
-            var normalRangeMin = this.options.get('normalRangeMin'),
-                normalRangeMax = this.options.get('normalRangeMax'),
-                ytop = canvasTop + Math.round(canvasHeight - (canvasHeight * ((normalRangeMax - this.miny) / rangey))),
-                height = Math.round((canvasHeight * (normalRangeMax - normalRangeMin)) / rangey);
-            this.target.drawRect(canvasLeft, ytop, canvasWidth, height, undefined, this.options.get('normalRangeColor')).append();
-        },
-
-        render: function () {
-            var options = this.options,
-                target = this.target,
-                canvasWidth = this.canvasWidth,
-                canvasHeight = this.canvasHeight,
-                vertices = this.vertices,
-                spotRadius = options.get('spotRadius'),
-                regionMap = this.regionMap,
-                rangex, rangey, yvallast,
-                canvasTop, canvasLeft,
-                vertex, path, paths, x, y, xnext, xpos, xposnext,
-                last, next, yvalcount, lineShapes, fillShapes, plen,
-                valueSpots, hlSpotsEnabled, color, xvalues, yvalues, i;
-
-            if (!line._super.render.call(this)) {
-                return;
-            }
-
-            this.scanValues();
-            this.processRangeOptions();
-
-            xvalues = this.xvalues;
-            yvalues = this.yvalues;
-
-            if (!this.yminmax.length || this.yvalues.length < 2) {
-                // empty or all null valuess
-                return;
-            }
-
-            canvasTop = canvasLeft = 0;
-
-            rangex = this.maxx - this.minx === 0 ? 1 : this.maxx - this.minx;
-            rangey = this.maxy - this.miny === 0 ? 1 : this.maxy - this.miny;
-            yvallast = this.yvalues.length - 1;
-
-            if (spotRadius && (canvasWidth < (spotRadius * 4) || canvasHeight < (spotRadius * 4))) {
-                spotRadius = 0;
-            }
-            if (spotRadius) {
-                // adjust the canvas size as required so that spots will fit
-                hlSpotsEnabled = options.get('highlightSpotColor') &&  !options.get('disableInteraction');
-                if (hlSpotsEnabled || options.get('minSpotColor') || (options.get('spotColor') && yvalues[yvallast] === this.miny)) {
-                    canvasHeight -= Math.ceil(spotRadius);
-                }
-                if (hlSpotsEnabled || options.get('maxSpotColor') || (options.get('spotColor') && yvalues[yvallast] === this.maxy)) {
-                    canvasHeight -= Math.ceil(spotRadius);
-                    canvasTop += Math.ceil(spotRadius);
-                }
-                if (hlSpotsEnabled ||
-                     ((options.get('minSpotColor') || options.get('maxSpotColor')) && (yvalues[0] === this.miny || yvalues[0] === this.maxy))) {
-                    canvasLeft += Math.ceil(spotRadius);
-                    canvasWidth -= Math.ceil(spotRadius);
-                }
-                if (hlSpotsEnabled || options.get('spotColor') ||
-                    (options.get('minSpotColor') || options.get('maxSpotColor') &&
-                        (yvalues[yvallast] === this.miny || yvalues[yvallast] === this.maxy))) {
-                    canvasWidth -= Math.ceil(spotRadius);
-                }
-            }
-
-
-            canvasHeight--;
-
-            if (options.get('normalRangeMin') !== undefined && !options.get('drawNormalOnTop')) {
-                this.drawNormalRange(canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey);
-            }
-
-            path = [];
-            paths = [path];
-            last = next = null;
-            yvalcount = yvalues.length;
-            for (i = 0; i < yvalcount; i++) {
-                x = xvalues[i];
-                xnext = xvalues[i + 1];
-                y = yvalues[i];
-                xpos = canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex));
-                xposnext = i < yvalcount - 1 ? canvasLeft + Math.round((xnext - this.minx) * (canvasWidth / rangex)) : canvasWidth;
-                next = xpos + ((xposnext - xpos) / 2);
-                regionMap[i] = [last || 0, next, i];
-                last = next;
-                if (y === null) {
-                    if (i) {
-                        if (yvalues[i - 1] !== null) {
-                            path = [];
-                            paths.push(path);
-                        }
-                        vertices.push(null);
-                    }
-                } else {
-                    if (y < this.miny) {
-                        y = this.miny;
-                    }
-                    if (y > this.maxy) {
-                        y = this.maxy;
-                    }
-                    if (!path.length) {
-                        // previous value was null
-                        path.push([xpos, canvasTop + canvasHeight]);
-                    }
-                    vertex = [xpos, canvasTop + Math.round(canvasHeight - (canvasHeight * ((y - this.miny) / rangey)))];
-                    path.push(vertex);
-                    vertices.push(vertex);
-                }
-            }
-
-            lineShapes = [];
-            fillShapes = [];
-            plen = paths.length;
-            for (i = 0; i < plen; i++) {
-                path = paths[i];
-                if (path.length) {
-                    if (options.get('fillColor')) {
-                        path.push([path[path.length - 1][0], (canvasTop + canvasHeight)]);
-                        fillShapes.push(path.slice(0));
-                        path.pop();
-                    }
-                    // if there's only a single point in this path, then we want to display it
-                    // as a vertical line which means we keep path[0]  as is
-                    if (path.length > 2) {
-                        // else we want the first value
-                        path[0] = [path[0][0], path[1][1]];
-                    }
-                    lineShapes.push(path);
-                }
-            }
-
-            // draw the fill first, then optionally the normal range, then the line on top of that
-            plen = fillShapes.length;
-            for (i = 0; i < plen; i++) {
-                target.drawShape(fillShapes[i],
-                    options.get('fillColor'), options.get('fillColor')).append();
-            }
-
-            if (options.get('normalRangeMin') !== undefined && options.get('drawNormalOnTop')) {
-                this.drawNormalRange(canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey);
-            }
-
-            plen = lineShapes.length;
-            for (i = 0; i < plen; i++) {
-                target.drawShape(lineShapes[i], options.get('lineColor'), undefined,
-                    options.get('lineWidth')).append();
-            }
-
-            if (spotRadius && options.get('valueSpots')) {
-                valueSpots = options.get('valueSpots');
-                if (valueSpots.get === undefined) {
-                    valueSpots = new RangeMap(valueSpots);
-                }
-                for (i = 0; i < yvalcount; i++) {
-                    color = valueSpots.get(yvalues[i]);
-                    if (color) {
-                        target.drawCircle(canvasLeft + Math.round((xvalues[i] - this.minx) * (canvasWidth / rangex)),
-                            canvasTop + Math.round(canvasHeight - (canvasHeight * ((yvalues[i] - this.miny) / rangey))),
-                            spotRadius, undefined,
-                            color).append();
-                    }
-                }
-
-            }
-            if (spotRadius && options.get('spotColor') && yvalues[yvallast] !== null) {
-                target.drawCircle(canvasLeft + Math.round((xvalues[xvalues.length - 1] - this.minx) * (canvasWidth / rangex)),
-                    canvasTop + Math.round(canvasHeight - (canvasHeight * ((yvalues[yvallast] - this.miny) / rangey))),
-                    spotRadius, undefined,
-                    options.get('spotColor')).append();
-            }
-            if (this.maxy !== this.minyorg) {
-                if (spotRadius && options.get('minSpotColor')) {
-                    x = xvalues[$.inArray(this.minyorg, yvalues)];
-                    target.drawCircle(canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex)),
-                        canvasTop + Math.round(canvasHeight - (canvasHeight * ((this.minyorg - this.miny) / rangey))),
-                        spotRadius, undefined,
-                        options.get('minSpotColor')).append();
-                }
-                if (spotRadius && options.get('maxSpotColor')) {
-                    x = xvalues[$.inArray(this.maxyorg, yvalues)];
-                    target.drawCircle(canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex)),
-                        canvasTop + Math.round(canvasHeight - (canvasHeight * ((this.maxyorg - this.miny) / rangey))),
-                        spotRadius, undefined,
-                        options.get('maxSpotColor')).append();
-                }
-            }
-
-            // explicitly compare the refLineX/Y option values with 'null' as numeric zero(0) should plot a ref-line at zero!
-            if (options.get('refLineX') != null) {                                          // jshint ignore:line
-                y = Math.round(this.canvasHeight - (options.get('refLineX') - this.miny) * (this.canvasHeight/rangey));
-                target.drawLine(0, y, this.canvasWidth, y, options.get('refLineColor')).append();
-            }
-
-            if (options.get('refLineY') != null) {                                          // jshint ignore:line
-                x = Math.round((options.get('refLineY') - this.minx) * (this.canvasWidth/rangex));
-                target.drawLine(x, this.canvasHeight, x, 0, options.get('refLineColor')).append();
-            }
-
-            this.lastShapeId = target.getLastShapeId();
-            this.canvasTop = canvasTop;
-            target.render();
-        }
-    });
-
-
-    /**
-     * Bar charts
-     */
-    $.fn.sparkline.bar = bar = createClass($.fn.sparkline._base, barHighlightMixin, {
-        type: 'bar',
-
-        init: function (el, values, options, width, height) {
-            var barWidth = parseInt(options.get('barWidth'), 10),
-                barSpacing = parseInt(options.get('barSpacing'), 10),
-                chartRangeMin = options.get('chartRangeMin'),
-                chartRangeMax = options.get('chartRangeMax'),
-                chartRangeClip = options.get('chartRangeClip'),
-                stackMin = Infinity,
-                stackMax = -Infinity,
-                isStackString, groupMin, groupMax, stackRanges, stackRangesNeg, stackTotals, actualMin, actualMax,
-                numValues, i, vlen, range, zeroAxis, xaxisOffset, min, max, clipMin, clipMax,
-                stacked, vlist, j, slen, svals, val, yoffset, yMaxCalc, canvasHeightEf;
-            bar._super.init.call(this, el, values, options, width, height);
-
-            // scan values to determine whether to stack bars
-            for (i = 0, vlen = values.length; i < vlen; i++) {
-                val = values[i];
-                isStackString = typeof(val) === 'string' && val.indexOf(':') > -1;
-                if (isStackString || $.isArray(val)) {
-                    stacked = true;
-                    if (isStackString) {
-                        val = values[i] = normalizeValues(val.split(':'));
-                    }
-                    val = remove(val, null); // min/max will treat null as zero
-                    groupMin = Math.min.apply(Math, val);
-                    groupMax = Math.max.apply(Math, val);
-                    if (groupMin < stackMin) {
-                        stackMin = groupMin;
-                    }
-                    if (groupMax > stackMax) {
-                        stackMax = groupMax;
-                    }
-                }
-            }
-
-            this.initTarget();
-
-            this.stacked = stacked;
-            this.regionShapes = {};
-            this.barWidth = barWidth * this.target.devicePixelRatio;
-            this.barSpacing = barSpacing * this.target.devicePixelRatio;
-            this.totalBarWidth = (barWidth + barSpacing) * this.target.devicePixelRatio;
-            var rawWidth = (values.length * barWidth * this.target.devicePixelRatio) + ((values.length - 1) * barSpacing * this.target.devicePixelRatio);
-            this.xScale = Math.min(1, rawWidth ? width * this.target.devicePixelRatio / rawWidth : 1);
-            this.width = rawWidth * this.xScale;
-
-            if (chartRangeClip) {
-                clipMin = chartRangeMin === undefined ? -Infinity : chartRangeMin;
-                clipMax = chartRangeMax === undefined ? Infinity : chartRangeMax;
-            }
-			if (stacked) {
-				actualMin = chartRangeMin === undefined ? stackMin : Math.min(stackMin, chartRangeMin);
-				actualMax = chartRangeMax === undefined ? stackMax : Math.max(stackMax, chartRangeMax);
-			}
-
-            numValues = [];
-            stackRanges = stacked ? [] : numValues;
-            stackTotals = [];
-            stackRangesNeg = [];
-            for (i = 0, vlen = values.length; i < vlen; i++) {
-                if (stacked) {
-                    vlist = values[i];
-                    values[i] = svals = [];
-                    stackTotals[i] = 0;
-                    stackRanges[i] = stackRangesNeg[i] = 0;
-                    for (j = 0, slen = vlist.length; j < slen; j++) {
-                        val = svals[j] = chartRangeClip ? clipval(vlist[j], clipMin, clipMax) : vlist[j];
-                        if (val !== null) {
-                            if (val > 0) {
-                                stackTotals[i] += val;
-                            }
-                            if (stackMin < 0 && stackMax > 0) {
-                                if (val < 0) {
-                                    stackRangesNeg[i] += Math.abs(val);
-                                } else {
-                                    stackRanges[i] += val;
-                                }
-                            } else {
-                                stackRanges[i] += Math.abs(val - (val < 0 ? actualMax : actualMin));
-                            }
-                            numValues.push(val);
-                        }
-                    }
-                } else {
-                    val = chartRangeClip ? clipval(values[i], clipMin, clipMax) : values[i];
-                    val = values[i] = normalizeValue(val);
-                    if (val !== null) {
-                        numValues.push(val);
-                    }
-                }
-            }
-            this.max = max = Math.max.apply(Math, numValues);
-            this.min = min = Math.min.apply(Math, numValues);
-            this.stackMax = stackMax = stacked ? Math.max.apply(Math, stackTotals) : max;
-            this.stackMin = stackMin = stacked ? Math.min.apply(Math, numValues) : min;
-
-            if (chartRangeMin !== undefined && (chartRangeClip || chartRangeMin < min)) {
-                min = chartRangeMin;
-            }
-            if (chartRangeMax !== undefined && (chartRangeClip || chartRangeMax > max)) {
-                max = chartRangeMax;
-            }
-
-            this.zeroAxis = zeroAxis = options.get('zeroAxis', true);
-            if (min <= 0 && max >= 0 && zeroAxis) {
-                xaxisOffset = 0;
-            } else if (zeroAxis === false) {
-                xaxisOffset = min;
-            } else if (min > 0) {
-                xaxisOffset = min;
-            } else {
-                xaxisOffset = max;
-            }
-            this.xaxisOffset = xaxisOffset;
-
-            range = stacked ? (Math.max.apply(Math, stackRanges) + Math.max.apply(Math, stackRangesNeg)) : max - min;
-
-            // as we plot zero/min values a single pixel line, we add a pixel to all other
-            // values - Reduce the effective canvas size to suit
-            this.canvasHeightEf = (zeroAxis && min < 0) ? this.canvasHeight - 2 : this.canvasHeight - 1;
-
-            if (min < xaxisOffset) {
-                yMaxCalc = (stacked && max >= 0) ? stackMax : max;
-                yoffset = (yMaxCalc - xaxisOffset) / range * this.canvasHeight;
-                if (yoffset !== Math.ceil(yoffset)) {
-                    this.canvasHeightEf -= 2;
-                    yoffset = Math.ceil(yoffset);
-                }
-            } else {
-                yoffset = this.canvasHeight;
-            }
-            this.yoffset = yoffset;
-
-            this.initColorMap();
-            this.range = range;
-        },
-
-        getRegion: function (el, x, y) {
-            x /= this.xScale;
-            var result = Math.floor(x * this.target.ratio / this.totalBarWidth);
-            return (result < 0 || result >= this.values.length) ? undefined : result;
-        },
-
-        getCurrentRegionFields: function () {
-            var currentRegion = this.currentRegion,
-                values = ensureArray(this.values[currentRegion]),
-                result = [],
-                value, i;
-            for (i = values.length; i--;) {
-                value = values[i];
-                result.push({
-                    isNull: value === null,
-                    value: value,
-                    color: this.calcColor(i, value, currentRegion),
-                    offset: currentRegion
-                });
-            }
-            return result;
-        },
-
-        calcColor: function (stacknum, value, valuenum) {
-            var colorMapFunction = this.colorMapFunction,
-                options = this.options,
-                color, newColor;
-
-            if (colorMapFunction && (newColor = colorMapFunction(this, options, valuenum, value))) {
-                color = newColor;
-            }
-            else {
-                if (this.stacked) {
-                    color = options.get('stackedBarColor');
-                } else {
-                    color = (value < 0) ? options.get('negBarColor') : options.get('barColor');
-                }
-                if (value === 0 && options.get('zeroColor') !== undefined) {
-                    color = options.get('zeroColor');
-                }
-            }
-            return $.isArray(color) ? color[stacknum % color.length] : color;
-        },
-
-        /**
-         * Render bar(s) for a region
-         */
-        renderRegion: function (valuenum, highlight) {
-            var vals = this.values[valuenum],
-                options = this.options,
-                xaxisOffset = this.xaxisOffset,
-                result = [],
-                range = this.range,
-                stacked = this.stacked,
-                target = this.target,
-                x = valuenum * this.totalBarWidth,
-                canvasHeightEf = this.canvasHeightEf,
-                yoffset = this.yoffset,
-                y, height, color, isNull, yoffsetNeg, i, valcount, val, minPlotted, allMin;
-
-            vals = $.isArray(vals) ? vals : [vals];
-            valcount = vals.length;
-            val = vals[0];
-            isNull = all(null, vals);
-            allMin = all(xaxisOffset, vals, true);
-
-            if (isNull) {
-                if (options.get('nullColor')) {
-                    color = highlight ? options.get('nullColor') : this.calcHighlightColor(options.get('nullColor'), options);
-                    y = (yoffset > 0) ? yoffset - 1 : yoffset;
-                    return target.drawRect(x, y, this.barWidth - 1, 0, color, color);
-                } else {
-                    return undefined;
-                }
-            }
-            yoffsetNeg = yoffset;
-            for (i = 0; i < valcount; i++) {
-                val = vals[i];
-
-                if (stacked && val === xaxisOffset) {
-                    if (!allMin || minPlotted) {
-                        continue;
-                    }
-                    minPlotted = true;
-                }
-
-                if (range > 0) {
-                    height = Math.floor(canvasHeightEf * ((Math.abs(val - xaxisOffset) / range))) + 1;
-                } else {
-                    height = 1;
-                }
-                if (val < xaxisOffset || (val === xaxisOffset && yoffset === 0)) {
-                    y = yoffsetNeg;
-                    yoffsetNeg += height;
-                } else {
-                    y = yoffset - height;
-                    yoffset -= height;
-                }
-                color = this.calcColor(i, val, valuenum);
-                if (highlight) {
-                    color = this.calcHighlightColor(color, options);
-                }
-                result.push(target.drawRect(x * this.xScale, y, (this.barWidth - 1) * this.xScale, height - 1, color, color));
-            }
-            if (result.length === 1) {
-                return result[0];
-            }
-            return result;
-        }
-    });
-
-
-    /**
-     * Stack charts
-     */
-    $.fn.sparkline.stack = stack = createClass($.fn.sparkline._base, {
-        type: 'stack',
-
-        init: function (el, values, options, width, height) {
-            var total = 0, i;
-
-            stack._super.init.call(this, el, values, options, width, height);
-
-            this.shapes = {}; // map shape ids to value offsets
-            this.valueShapes = {}; // maps value offsets to shape ids
-            this.values = values = $.map(values, Number);
-
-            this.initTarget();
-
-            if (options.get('width') === 'auto') {
-                this.width = this.height;
-            }
-
-            if (values.length > 0) {
-                for (i = values.length; i--;) {
-                    total += values[i];
-                }
-            }
-            this.total = total;
-
-            this.height = this.canvasHeight * this.target.devicePixelRatio;
-            this.width = this.canvasWidth * this.target.devicePixelRatio;
-        },
-
-        getRegion: function (el, x, y) {
-            var shapeid = this.target.getShapeAt(el, x * this.target.ratio, y * this.target.ratio);
-            return (shapeid !== undefined && this.shapes[shapeid] !== undefined) ? this.shapes[shapeid] : undefined;
-        },
-
-        getCurrentRegionFields: function () {
-            var currentRegion = this.currentRegion;
-            return {
-                isNull: this.values[currentRegion] === undefined,
-                value: this.values[currentRegion],
-                percent: this.values[currentRegion] / this.total * 100,
-                color: this.options.get('sliceColors')[currentRegion % this.options.get('sliceColors').length],
-                offset: currentRegion
-            };
-        },
-
-        changeHighlight: function (highlight) {
-            var currentRegion = this.currentRegion,
-                 newslice = this.renderSlice(currentRegion, highlight),
-                 shapeid = this.valueShapes[currentRegion];
-            delete this.shapes[shapeid];
-            this.target.replaceWithShape(shapeid, newslice);
-            this.valueShapes[currentRegion] = newslice.id;
-            this.shapes[newslice.id] = currentRegion;
-        },
-
-        renderSlice: function (valuenum, highlight) {
-            var target = this.target,
-                options = this.options,
-                height = this.height,
-                width = this.width,
-                values = this.values,
-                total = this.total,
-                start = 0,
-                end = 0,
-                i, vlen, color;
-
-            vlen = values.length;
-            for (i = 0; i < vlen; i++) {
-                start = end;
-                var sliceWidth = Math.round(values[i] * width / total);
-                if (valuenum === i) {
-                    color = options.get('sliceColors')[i % options.get('sliceColors').length];
-                    if (highlight) {
-                        color = this.calcHighlightColor(color, options);
-                    }
-                    return target.drawRect(start, 0, sliceWidth, height, undefined, color);
-                }
-                end += sliceWidth;
-            }
-        },
-
-        render: function () {
-            var target = this.target,
-                values = this.values,
-                options = this.options,
-                borderWidth = options.get('borderWidth'),
-                shape, i;
-
-            if (!stack._super.render.call(this)) {
-                return;
-            }
-            for (i = 0; i < values.length; i++) {
-                if (values[i]) { // don't render zero values
-                    shape = this.renderSlice(i).append();
-                    this.valueShapes[i] = shape.id; // store just the shapeid
-                    this.shapes[shape.id] = i;
-                }
-            }
-            target.render();
-        }
-    });
-
-    /**
-     * Tristate charts
-     */
-    $.fn.sparkline.tristate = tristate = createClass($.fn.sparkline._base, barHighlightMixin, {
-        type: 'tristate',
-
-        init: function (el, values, options, width, height) {
-            var barWidth = parseInt(options.get('barWidth'), 10),
-                barSpacing = parseInt(options.get('barSpacing'), 10);
-            tristate._super.init.call(this, el, values, options, width, height);
-
-            this.initTarget();
-
-            this.regionShapes = {};
-            this.barWidth = barWidth * this.target.devicePixelRatio;
-            this.barSpacing = barSpacing * this.target.devicePixelRatio;
-            this.totalBarWidth = (barWidth + barSpacing) * this.target.devicePixelRatio;
-            this.values = $.map(values, Number);
-            var rawWidth = (values.length * barWidth * this.target.devicePixelRatio) + ((values.length - 1) * barSpacing * this.target.devicePixelRatio);
-            this.xScale = Math.min(1, rawWidth ? width * this.target.devicePixelRatio / rawWidth : 1);
-            this.width = rawWidth * this.xScale; 
-
-            this.initColorMap();
-        },
-
-        getRegion: function (el, x, y) {
-            x /= this.xScale;
-            var result = Math.floor(x * this.target.ratio / this.totalBarWidth);
-            return (result < 0 || result >= this.values.length) ? undefined : result;
-        },
-
-        getCurrentRegionFields: function () {
-            var currentRegion = this.currentRegion;
-            return {
-                isNull: this.values[currentRegion] === undefined,
-                value: this.values[currentRegion],
-                color: this.calcColor(this.values[currentRegion], currentRegion),
-                offset: currentRegion
-            };
-        },
-
-        calcColor: function (value, valuenum) {
-            var options = this.options,
-                colorMapFunction = this.colorMapFunction,
-                color, newColor;
-
-            if (colorMapFunction && (newColor = colorMapFunction(this, options, valuenum, value))) {
-                color = newColor;
-            } else if (value < 0) {
-                color = options.get('negBarColor');
-            } else if (value > 0) {
-                color = options.get('posBarColor');
-            } else {
-                color = options.get('zeroBarColor');
-            }
-            return color;
-        },
-
-        renderRegion: function (valuenum, highlight) {
-            var values = this.values,
-                options = this.options,
-                target = this.target,
-                canvasHeight, height, halfHeight,
-                x, y, color;
-
-            canvasHeight = target.pixelHeight;
-            halfHeight = Math.round(canvasHeight / 2);
-
-            x = valuenum * this.totalBarWidth;
-            if (values[valuenum] < 0) {
-                y = halfHeight;
-                height = halfHeight - 1;
-            } else if (values[valuenum] > 0) {
-                y = 0;
-                height = halfHeight - 1;
-            } else {
-                y = halfHeight - 1;
-                height = 2;
-            }
-            color = this.calcColor(values[valuenum], valuenum);
-            if (color === null) {
-                return;
-            }
-            if (highlight) {
-                color = this.calcHighlightColor(color, options);
-            }
-            return target.drawRect(x * this.xScale, y, (this.barWidth - 1) * this.xScale, height - 1, color, color);
-        }
-    });
-
-
-    /**
-     * Discrete charts
-     */
-    $.fn.sparkline.discrete = discrete = createClass($.fn.sparkline._base, barHighlightMixin, {
-        type: 'discrete',
-
-        init: function (el, values, options, width, height) {
-            discrete._super.init.call(this, el, values, options, width, height);
-
-            this.initTarget();
-
-            this.regionShapes = {};
-            this.values = values = $.map(values, Number);
-            this.min = Math.min.apply(Math, values);
-            this.max = Math.max.apply(Math, values);
-            this.range = this.max - this.min;
-            width = options.get('width') === 'auto' ? values.length * 2 * this.target.devicePixelRatio : this.width;
-            //adjust width for pixel ratio
-            width = width * this.target.devicePixelRatio;
-            this.width = width;
-            this.interval = Math.floor(width / values.length);
-            this.itemWidth = width / values.length;
-            if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < this.min)) {
-                this.min = options.get('chartRangeMin');
-            }
-            if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > this.max)) {
-                this.max = options.get('chartRangeMax');
-            }
-
-            if (this.target) {
-                this.lineHeight = options.get('lineHeight') === 'auto' ? Math.round(this.canvasHeight * 0.3) : options.get('lineHeight');
-            }
-        },
-
-        getRegion: function (el, x, y) {
-            return Math.floor(x * this.target.ratio / this.itemWidth);
-        },
-
-        getCurrentRegionFields: function () {
-            var currentRegion = this.currentRegion;
-            return {
-                isNull: this.values[currentRegion] === undefined,
-                value: this.values[currentRegion],
-                offset: currentRegion
-            };
-        },
-
-        renderRegion: function (valuenum, highlight) {
-            var values = this.values,
-                options = this.options,
-                min = this.min,
-                max = this.max,
-                range = this.range,
-                interval = this.interval,
-                target = this.target,
-                canvasHeight = this.canvasHeight,
-                lineHeight = this.lineHeight,
-                pheight = canvasHeight - lineHeight,
-                ytop, val, color, x;
-
-            val = clipval(values[valuenum], min, max);
-            x = valuenum * interval;
-            ytop = Math.round(pheight - pheight * ((val - min) / range));
-            color = (options.get('thresholdColor') && val < options.get('thresholdValue')) ? options.get('thresholdColor') : options.get('lineColor');
-            if (highlight) {
-                color = this.calcHighlightColor(color, options);
-            }
-            return target.drawLine(x, ytop, x, ytop + lineHeight, color);
-        }
-    });
-
-
-    /**
-     * Bullet charts
-     */
-    $.fn.sparkline.bullet = bullet = createClass($.fn.sparkline._base, {
-        type: 'bullet',
-
-        init: function (el, values, options, width, height) {
-            var min, max, vals;
-            bullet._super.init.call(this, el, values, options, width, height);
-
-            // values: target, performance, range1, range2, range3
-            this.values = values = normalizeValues(values);
-            // target or performance could be null
-            vals = values.slice();
-            vals[0] = vals[0] === null ? vals[2] : vals[0];
-            vals[1] = values[1] === null ? vals[2] : vals[1];
-            min = Math.min.apply(Math, values);
-            max = Math.max.apply(Math, values);
-            if (options.get('base') === undefined) {
-                min = min < 0 ? min : 0;
-            } else {
-                min = options.get('base');
-            }
-            this.min = min;
-            this.max = max;
-            this.range = max - min;
-			
-			// GRADIENT
-			var colors = options.get('rangeColors');
-			if (options.get('gradient') && colors.length > 1) {
-				var rainbow = new Rainbow();
-				rainbow.setSpectrumByArray(colors);
-				rainbow.setNumberRange(0, this.values.length);
-				
-				for (var i = 0; i < this.values.length; i++) {
-					colors[i] = rainbow.colorAt(i);
-				}
-			}
-			
-			this.rangeColors = colors;
-            this.shapes = {};
-            this.valueShapes = {};
-            this.regiondata = {};
-            this.width = width = options.get('width') === 'auto' ? '4.0em' : width;
-            this.target = this.$el.simpledraw(width, height, options.get('composite'));
-            if (!values.length) {
-                this.disabled = true;
-            }
-            this.initTarget();
-        },
-
-        getRegion: function (el, x, y) {
-            var shapeid = this.target.getShapeAt(el, x * this.target.ratio, y * this.target.ratio);
-            return (shapeid !== undefined && this.shapes[shapeid] !== undefined) ? this.shapes[shapeid] : undefined;
-        },
-
-        getCurrentRegionFields: function () {
-            var currentRegion = this.currentRegion;
-            return {
-                fieldkey: currentRegion.substr(0, 1),
-                value: this.values[currentRegion.substr(1)],
-                region: currentRegion
-            };
-        },
-
-        changeHighlight: function (highlight) {
-            var currentRegion = this.currentRegion,
-                shapeid = this.valueShapes[currentRegion],
-                shape;
-            delete this.shapes[shapeid];
-            switch (currentRegion.substr(0, 1)) {
-                case 'r':
-                    shape = this.renderRange(currentRegion.substr(1), highlight);
-                    break;
-                case 'p':
-                    shape = this.renderPerformance(highlight);
-                    break;
-                case 't':
-                    shape = this.renderTarget(highlight);
-                    break;
-            }
-            this.valueShapes[currentRegion] = shape.id;
-            this.shapes[shape.id] = currentRegion;
-            this.target.replaceWithShape(shapeid, shape);
-        },
-
-        renderRange: function (rn, highlight) {
-            var rangeval = this.values[rn],
-                rangewidth = Math.round(this.canvasWidth * ((rangeval - this.min) / this.range)),
-                color = this.rangeColors[rn - 2];
-            if (highlight) {
-                color = this.calcHighlightColor(color, this.options);
-            }
-            return this.target.drawRect(0, 0, rangewidth - 1, this.canvasHeight - 1, color, color);
-        },
-
-        renderPerformance: function (highlight) {
-            var perfval = this.values[1],
-                perfwidth = Math.round(this.canvasWidth * ((perfval - this.min) / this.range)),
-                color = this.options.get('performanceColor');
-            if (highlight) {
-                color = this.calcHighlightColor(color, this.options);
-            }
-            return this.target.drawRect(0, Math.round(this.canvasHeight * 0.3), perfwidth - 1,
-                Math.round(this.canvasHeight * 0.4) - 1, color, color);
-        },
-
-        renderTarget: function (highlight) {
-            var targetval = this.values[0],
-                x = Math.round(this.canvasWidth * ((targetval - this.min) / this.range) - (this.options.get('targetWidth') / 2)),
-                targettop = Math.round(this.canvasHeight * 0.10),
-                targetheight = this.canvasHeight - (targettop * 2),
-                color = this.options.get('targetColor');
-            if (highlight) {
-                color = this.calcHighlightColor(color, this.options);
-            }
-            return this.target.drawRect(x, targettop, this.options.get('targetWidth') - 1, targetheight - 1, color, color);
-        },
-
-        render: function () {
-            var vlen = this.values.length,
-                target = this.target,
-                i, shape;
-            if (!bullet._super.render.call(this)) {
-                return;
-            }
-            for (i = 2; i < vlen; i++) {
-                shape = this.renderRange(i).append();
-                this.shapes[shape.id] = 'r' + i;
-                this.valueShapes['r' + i] = shape.id;
-            }
-            if (this.values[1] !== null) {
-                shape = this.renderPerformance().append();
-                this.shapes[shape.id] = 'p1';
-                this.valueShapes.p1 = shape.id;
-            }
-            if (this.values[0] !== null) {
-                shape = this.renderTarget().append();
-                this.shapes[shape.id] = 't0';
-                this.valueShapes.t0 = shape.id;
-            }
-            target.render();
-        }
-    });
-
-
-    /**
-     * Pie charts
-     */
-    $.fn.sparkline.pie = pie = createClass($.fn.sparkline._base, {
-        type: 'pie',
-
-        init: function (el, values, options, width, height) {
-            var total = 0, i;
-
-            pie._super.init.call(this, el, values, options, width, height);
-
-            this.shapes = {}; // map shape ids to value offsets
-            this.valueShapes = {}; // maps value offsets to shape ids
-            this.values = values = $.map(values, Number);
-
-            if (options.get('width') === 'auto') {
-                this.width = this.height;
-            }
-
-            if (values.length > 0) {
-                for (i = values.length; i--;) {
-                    total += values[i];
-                }
-            }
-            this.total = total;
-            this.initTarget();
-            this.radius = Math.floor(Math.min(this.canvasWidth, this.canvasHeight) / 2);
-        },
-
-        getRegion: function (el, x, y) {
-            var shapeid = this.target.getShapeAt(el, x * this.target.ratio, y * this.target.ratio);
-            return (shapeid !== undefined && this.shapes[shapeid] !== undefined) ? this.shapes[shapeid] : undefined;
-        },
-
-        getCurrentRegionFields: function () {
-            var currentRegion = this.currentRegion;
-            return {
-                isNull: this.values[currentRegion] === undefined,
-                value: this.values[currentRegion],
-                percent: this.values[currentRegion] / this.total * 100,
-                color: this.options.get('sliceColors')[currentRegion % this.options.get('sliceColors').length],
-                offset: currentRegion
-            };
-        },
-
-        changeHighlight: function (highlight) {
-            var currentRegion = this.currentRegion,
-                 newslice = this.renderSlice(currentRegion, highlight),
-                 shapeid = this.valueShapes[currentRegion];
-            delete this.shapes[shapeid];
-            this.target.replaceWithShape(shapeid, newslice);
-            this.valueShapes[currentRegion] = newslice.id;
-            this.shapes[newslice.id] = currentRegion;
-        },
-
-        renderSlice: function (valuenum, highlight) {
-            var target = this.target,
-                options = this.options,
-                radius = this.radius,
-                borderWidth = options.get('borderWidth'),
-                offset = options.get('offset'),
-                circle = 2 * Math.PI,
-                values = this.values,
-                total = this.total,
-                next = offset ? (2*Math.PI)*(offset/360) : 0,
-                start, end, i, vlen, color;
-
-            vlen = values.length;
-            for (i = 0; i < vlen; i++) {
-                start = next;
-                end = next;
-                if (total > 0) {  // avoid divide by zero
-                    end = next + (circle * (values[i] / total));
-                }
-                if (valuenum === i) {
-                    color = options.get('sliceColors')[i % options.get('sliceColors').length];
-                    if (highlight) {
-                        color = this.calcHighlightColor(color, options);
-                    }
-
-                    return target.drawPieSlice(radius, radius, radius - borderWidth, start, end, undefined, color);
-                }
-                next = end;
-            }
-        },
-
-        render: function () {
-            var target = this.target,
-                values = this.values,
-                options = this.options,
-                radius = this.radius,
-                borderWidth = options.get('borderWidth'),
-                shape, i;
-
-            if (!pie._super.render.call(this)) {
-                return;
-            }
-            if (borderWidth) {
-                target.drawCircle(radius, radius, Math.floor(radius - (borderWidth / 2)),
-                    options.get('borderColor'), undefined, borderWidth).append();
-            }
-            for (i = values.length; i--;) {
-                if (values[i]) { // don't render zero values
-                    shape = this.renderSlice(i).append();
-                    this.valueShapes[i] = shape.id; // store just the shapeid
-                    this.shapes[shape.id] = i;
-                }
-            }
-            target.render();
-        }
-    });
-
-
-    /**
-     * Box plots
-     */
-    $.fn.sparkline.box = box = createClass($.fn.sparkline._base, {
-        type: 'box',
-
-        init: function (el, values, options, width, height) {
-            box._super.init.call(this, el, values, options, width, height);
-            this.values = $.map(values, Number);
-            this.width = options.get('width') === 'auto' ? '4.0em' : width;
-            this.initTarget();
-            if (!this.values.length) {
-                this.disabled = 1;
-            }
-        },
-
-        /**
-         * Simulate a single region
-         */
-        getRegion: function () {
-            return 1;
-        },
-
-        getCurrentRegionFields: function () {
-            var result = [
-                { field: 'lq', value: this.quartiles[0] },
-                { field: 'med', value: this.quartiles[1] },
-                { field: 'uq', value: this.quartiles[2] }
-            ];
-            if (this.loutlier !== undefined) {
-                result.push({ field: 'lo', value: this.loutlier});
-            }
-            if (this.routlier !== undefined) {
-                result.push({ field: 'ro', value: this.routlier});
-            }
-            if (this.lwhisker !== undefined) {
-                result.push({ field: 'lw', value: this.lwhisker});
-            }
-            if (this.rwhisker !== undefined) {
-                result.push({ field: 'rw', value: this.rwhisker});
-            }
-            return result;
-        },
-
-        render: function () {
-            var target = this.target,
-                values = this.values,
-                vlen = values.length,
-                options = this.options,
-                canvasWidth = this.canvasWidth,
-                canvasHeight = this.canvasHeight,
-                minValue = options.get('chartRangeMin') === undefined ? Math.min.apply(Math, values) : options.get('chartRangeMin'),
-                maxValue = options.get('chartRangeMax') === undefined ? Math.max.apply(Math, values) : options.get('chartRangeMax'),
-                canvasLeft = 0,
-                lwhisker, loutlier, iqr, q1, q2, q3, rwhisker, routlier, i,
-                size, unitSize, unitOffset;
-
-            if (!box._super.render.call(this)) {
-                return;
-            }
-
-            if (options.get('raw')) {
-                if (options.get('showOutliers') && values.length > 5) {
-                    loutlier = values[0];
-                    lwhisker = values[1];
-                    q1 = values[2];
-                    q2 = values[3];
-                    q3 = values[4];
-                    rwhisker = values[5];
-                    routlier = values[6];
-                } else {
-                    lwhisker = values[0];
-                    q1 = values[1];
-                    q2 = values[2];
-                    q3 = values[3];
-                    rwhisker = values[4];
-                }
-            } else {
-                values.sort(function (a, b) { return a - b; });
-                q1 = quartile(values, 1);
-                q2 = quartile(values, 2);
-                q3 = quartile(values, 3);
-                iqr = q3 - q1;
-                if (options.get('showOutliers')) {
-                    lwhisker = rwhisker = undefined;
-                    for (i = 0; i < vlen; i++) {
-                        if (lwhisker === undefined && values[i] > q1 - (iqr * options.get('outlierIQR'))) {
-                            lwhisker = values[i];
-                        }
-                        if (values[i] < q3 + (iqr * options.get('outlierIQR'))) {
-                            rwhisker = values[i];
-                        }
-                    }
-                    loutlier = values[0];
-                    routlier = values[vlen - 1];
-                } else {
-                    lwhisker = values[0];
-                    rwhisker = values[vlen - 1];
-                }
-            }
-            this.quartiles = [q1, q2, q3];
-            this.lwhisker = lwhisker;
-            this.rwhisker = rwhisker;
-            this.loutlier = loutlier;
-            this.routlier = routlier;
-
-            // Non-zero unit offset can throw off the plotting if it is not
-            // required to avoid a division by zero.
-            unitOffset = 0.0;
-            if ( ( maxValue - minValue ) == 0.0 ) { unitOffset = 1.0; }
-
-            unitSize = canvasWidth / (maxValue - minValue + unitOffset );
-            if (options.get('showOutliers')) {
-                canvasLeft = Math.ceil(options.get('spotRadius'));
-                canvasWidth -= 2 * Math.ceil(options.get('spotRadius'));
-                unitSize = canvasWidth / (maxValue - minValue + unitOffset);
-                if (loutlier < lwhisker) {
-                    target.drawCircle((loutlier - minValue) * unitSize + canvasLeft,
-                        canvasHeight / 2,
-                        options.get('spotRadius'),
-                        options.get('outlierLineColor'),
-                        options.get('outlierFillColor')).append();
-                }
-                if (routlier > rwhisker) {
-                    target.drawCircle((routlier - minValue) * unitSize + canvasLeft,
-                        canvasHeight / 2,
-                        options.get('spotRadius'),
-                        options.get('outlierLineColor'),
-                        options.get('outlierFillColor')).append();
-                }
-            }
-
-            // box
-            target.drawRect(
-                Math.round((q1 - minValue) * unitSize + canvasLeft),
-                Math.round(canvasHeight * 0.1),
-                Math.round((q3 - q1) * unitSize),
-                Math.round(canvasHeight * 0.8),
-                options.get('boxLineColor'),
-                options.get('boxFillColor'),
-                // CUSTOM MOD: line width & corner radius
-                options.get('lineWidth'),
-                options.get('cornerRadius')).append();
-            // left whisker
-            // CUSTOM MOD: strikethrough option
-            var rightEnd = q1 - minValue;
-            if (options.get('strikeThrough'))
-              rightEnd = rwhisker - minValue;
-
-            target.drawLine(
-                Math.round((lwhisker - minValue) * unitSize + canvasLeft),
-                Math.round(canvasHeight / 2),
-                Math.round(rightEnd * unitSize + canvasLeft),
-                Math.round(canvasHeight / 2),
-                // CUSTOM MOD: line width added
-                options.get('lineColor'),
-                options.get('lineWidth')).append();
-            target.drawLine(
-                Math.round((lwhisker - minValue) * unitSize + canvasLeft),
-                Math.round(canvasHeight / 4),
-                Math.round((lwhisker - minValue) * unitSize + canvasLeft),
-                Math.round(canvasHeight - canvasHeight / 4),
-                options.get('whiskerColor'),
-                // CUSTOM MOD: line width added
-                options.get('lineWidth')).append();
-            // right whisker
-            // CUSTOM MOD: strikethrough option
-            if (!options.get('strikeThrough'))
-            {
-              target.drawLine(Math.round((rwhisker - minValue) * unitSize + canvasLeft),
-                  Math.round(canvasHeight / 2),
-                  Math.round((q3 - minValue) * unitSize + canvasLeft),
-                  Math.round(canvasHeight / 2),
-                  options.get('lineColor'),
-                  // CUSTOM MOD: line width added
-                  options.get('lineWidth')).append();
-            }
-            target.drawLine(
-                Math.round((rwhisker - minValue) * unitSize + canvasLeft),
-                Math.round(canvasHeight / 4),
-                Math.round((rwhisker - minValue) * unitSize + canvasLeft),
-                Math.round(canvasHeight - canvasHeight / 4),
-                options.get('whiskerColor'),
-                // CUSTOM MOD: line width added
-                options.get('lineWidth')).append();
-
-            // median line
-            target.drawLine(
-                Math.round((q2 - minValue) * unitSize + canvasLeft),
-                Math.round(canvasHeight * 0.1),
-                Math.round((q2 - minValue) * unitSize + canvasLeft),
-                Math.round(canvasHeight * 0.9),
-                // CUSTOM MOD: medianwidth option
-                options.get('medianColor'),
-                options.get('medianWidth')).append();
-            if (typeof options.get('target') == 'number') {
-                size = Math.ceil(options.get('spotRadius'));
-                // CUSTOM MOD: circle representation of median
-                var targetVal = options.get('target');
-                var targetObj = options.get('targetObj')
-                if (!targetObj || targetObj == 'crosshair') {
-                    target.drawLine(
-                        Math.round((targetVal - minValue) * unitSize + canvasLeft),
-                        Math.round((canvasHeight / 2) - size),
-                        Math.round((targetVal - minValue) * unitSize + canvasLeft),
-                        Math.round((canvasHeight / 2) + size),
-                        options.get('targetColor')).append();
-                    target.drawLine(
-                        Math.round((targetVal - minValue) * unitSize + canvasLeft - size),
-                        Math.round(canvasHeight / 2),
-                        Math.round((targetVal - minValue) * unitSize + canvasLeft + size),
-                        Math.round(canvasHeight / 2),
-                        options.get('targetColor')).append();
-                }
-                else if (targetObj == 'circle')
-                {
-                    target.drawCircle(
-                        (targetVal - minValue) * unitSize + canvasLeft,
-                        canvasHeight / 2,
-                        options.get('spotRadius'),
-                        options.get('targetColor'),
-                        options.get('targetColor')).append();
-                }
-            }
-            target.render();
-        }
-    });
-
-
-  /*jslint nomen: true, plusplus: true, todo: true, white: true, browser: true *//**
-     * Timeline sparkline chart
-     * Given a list of events with begin/finish times, graph them vertically or horizontally by event type.
-     * let events = [
-     *  {begin:date(11a), finish:date(12a), color:'red'},
-     *  {begin:date(12a), finish:date(1p), color:'green'},
-     *  {begin:date(1p), finish:date(6p), color:'blue'}
-     * ]
-     * let 1 pixel = 1 minute
-     * let 8 am be the sparkline begin
-     * let 8 pm be the sparkline finish 
-     * let 720 pixels be the total visible duration
-     * then graph 
-     *  |white for 300 pixels||red for 60 pixels||green for 60 pixels||blue for 300 pixels||white for 120 pixels|
-     */
-;(function ($) {
-
-    "use strict";
-
-    $.fn.sparkline.timeline = timeline = createClass($.fn.sparkline._base, barHighlightMixin, {
-
-        type: 'timeline',
-
-        init: function (el, values, options, width, height) {
-            // expect a Date or the Number of milliseconds since the epoc
-            function minutes(date) {
-                return date / (60 * 1000);
-            }
-            // force positive number otherwise 0
-            function forcePositiveNumber(val) {
-                val = Math.abs(val);
-                return isNaN(val) ? 0 : val;
-            }
-            var i, data, segment, beginMinutes, finishMinutes, durationMinutes, 
-                pixelsPerMinute, userInitHandler, timeMarkPixels, isVerticalOrientation, 
-                timeMarkInterval, timeMarkOffset, timeMark, tick, tickSize;
-            timeline._super.init.call(this, el, values, options, width, height);
-            // required by barHighlightMixin
-            this.regionShapes = {};
-            // sets canvas height/width
-            this.initTarget();
-            // holds each timeline entry with x,y,w,h,lc,fc,rd values
-            this.segments = [];
-            // holds time markers entry with x1,y1,x2,y2,lc,w values
-            this.timemarks = [];
-            // paints a 1px line showing full length of timeline
-            timeMarkInterval = forcePositiveNumber(options.mergedOptions.timeMarkInterval);
-            // orient the sparkline direction, the default is horizontal
-            isVerticalOrientation = 'vertical' === options.mergedOptions.orientation;
-            // allow user to manipulate the data before segment is built
-            userInitHandler = $.isFunction(options.mergedOptions.init) ? options.mergedOptions.init : function (d) { return d; };
-            function offset(date, baseline) {
-                return Math.ceil(pixelsPerMinute * (minutes(date) - baseline));
-            }
-            // segments that fall outside of begin/finish will be clipped
-            beginMinutes = minutes(options.mergedOptions.begin);
-            finishMinutes = minutes(options.mergedOptions.finish);
-            durationMinutes = (finishMinutes - beginMinutes);
-            if (isVerticalOrientation) {
-                pixelsPerMinute = (this.canvasHeight - 1) / durationMinutes;
-            } else {
-                pixelsPerMinute = (this.canvasWidth - 1) / durationMinutes;
-            }
-            if (timeMarkInterval > 0) {
-                timeMarkPixels = timeMarkInterval * pixelsPerMinute;
-                // add tick marks based on timeMarkInterval
-                for (i = 0; i < ((durationMinutes * pixelsPerMinute) / timeMarkPixels) + 1; i++) {
-                    tick = {x1: 0, y1: 0, x2: 0, y2: 0, lc:'#ff0011', w: 1};
-                    timeMark = Math.round(i * timeMarkPixels);
-                    tickSize = Math.ceil(timeMark / pixelsPerMinute) % 60 === 0 ? 3 : 1;
-                    if (isVerticalOrientation) {
-                        tick.x2 = tickSize;
-                        tick.y1 = tick.y2 = timeMark;
-                    } else {
-                        tick.y2 = tickSize;
-                        tick.x1 = tick.x2 = timeMark;
-                    }
-                    this.timemarks.push(tick);
-                }
-                // add last tick mark and timeline
-                if (isVerticalOrientation) {
-                    this.timemarks.push({x1:0, y1:0, x2:0, y2:this.canvasHeight, lc:'#eee', w:1});
-                } else {
-                    this.timemarks.push({x1:0, y1:0, x2:this.canvasWidth, y2:0, lc:'#eee', w:1});
-                }
-            }
-            // build each segment for rendering
-            timeMarkOffset = (timeMarkInterval > 0) ? 1 : 0;
-            for (i = 0; i < values.length; i++) {
-                // TODO: determine why values has bogus length value in IE8
-                if (values[i]) {
-                    data = userInitHandler(values[i], i);
-                    if (data) {
-                        // the minus 2 is to prevent clipping the segment
-                        segment = {
-                            x: timeMarkOffset, 
-                            y: timeMarkOffset, 
-                            w: width - (timeMarkOffset + 1), 
-                            h: height - (timeMarkOffset + 1), 
-                            data: data
-                        };
-                        // TODO: adjust shape size for overlapping regions
-                        if (isVerticalOrientation) {
-                            segment.y = offset(data.begin, beginMinutes);
-                            segment.h = offset(data.finish, minutes(data.begin));
-                        } else {
-                            segment.x = offset(data.begin, beginMinutes);
-                            segment.w = offset(data.finish, minutes(data.begin));
-                        }
-                        segment.fc = data.color || options.mergedOptions.fillColor;
-                        segment.lc = data.lineColor || options.mergedOptions.lineColor;
-                        this.segments.push(segment);
-                    }
-                }
-            }
-
-            // sort the segments so all segments are visible in timeline
-            this.segments = this.segments.sort(function compare(a,b) {
-                var ab, af, bb, bf;
-                ab = Number(a.data.begin);
-                bb = Number(b.data.begin);
-                af = Number(a.data.finish);
-                bf = Number(b.data.finish);
-                // reverse order sort
-                return (bb-ab) + (bf-af);
-            });
-        },
-
-        /** return mouse coordinates on timeline */
-        getRegion: function (el, x, y) {
-            return {el: el, x: x, y: y};
-        },
-
-        /** return data used to display tooltip for the current region(s) */
-        getCurrentRegionFields: function () {
-            var i, el, x, y, segment, regions = [], left, right, top, bottom;
-            el = this.currentRegion.el;
-            x = this.currentRegion.x;
-            y = this.currentRegion.y;
-            for (i = 0; i < this.segments.length; i++) {
-                segment = this.segments[i];
-                if (segment) {
-                    left = segment.x;
-                    right = left + segment.w;
-                    top = segment.y;
-                    bottom = top + segment.h;
-                    if (x > left && x < right && y > top && y < bottom) {
-                        regions.push(segment.data);
-                    }
-                }
-            }
-            return regions;
-        },
-
-        /** render timeline segment and tickmarks */
-        renderRegion: function (valuenum, highlight) {
-            var i, tick, segment, result = [], target = this.target;
-            if (valuenum === 0) {
-                for (i = 0; i < this.timemarks.length; i++) {
-                    tick = this.timemarks[i];
-                    result.push(target.drawLine(tick.x1, tick.y1, tick.x2, tick.y2, tick.lc, tick.w));
-                }
-            }
-            segment = this.segments[valuenum];
-            if (segment) {
-                result.push(target.drawRect(segment.x, segment.y, segment.w, segment.h, segment.lc, segment.fc));
-            }
-            return result;
-        }
-    });
-}(jQuery));
-
-
-    // Setup a very simple "virtual canvas" to make drawing the few shapes we need easier
-    // This is accessible as $(foo).simpledraw()
-
-    VShape = createClass({
-        init: function (target, id, type, args) {
-            this.target = target;
-            this.id = id;
-            this.type = type;
-            this.args = args;
-        },
-        append: function () {
-            this.target.appendShape(this);
-            return this;
-        }
-    });
-
-    VCanvas_base = createClass({
-        _pxregex: /(\d+)(px)?\s*$/i,
-
-        init: function (width, height, target) {
-            if (!width) {
-                return;
-            }
-            this.width = width;
-            this.height = height;
-            this.target = target;
-            this.lastShapeId = null;
-            if (target[0]) {
-                target = target[0];
-            }
-            $.data(target, '_jqs_vcanvas', this);
-        },
-
-        drawLine: function (x1, y1, x2, y2, lineColor, lineWidth) {
-            // CUSTOM MOD: line width added
-            return this.drawShape([[x1, y1], [x2, y2]], lineColor, null, lineWidth);
-        },
-
-        drawShape: function (path, lineColor, fillColor, lineWidth) {
-            return this._genShape('Shape', [path, lineColor, fillColor, lineWidth]);
-        },
-
-        drawCircle: function (x, y, radius, lineColor, fillColor, lineWidth) {
-            return this._genShape('Circle', [x, y, radius, lineColor, fillColor, lineWidth]);
-        },
-
-        drawPieSlice: function (x, y, radius, startAngle, endAngle, lineColor, fillColor) {
-            return this._genShape('PieSlice', [x, y, radius, startAngle, endAngle, lineColor, fillColor]);
-        },
-
-        // CUSTOM MOD: line width / radius added
-        drawRect: function (x, y, width, height, lineColor, fillColor, lineWidth, radius) {
-            return this._genShape('Rect', [x, y, width, height, lineColor, fillColor, lineWidth, radius]);
-        },
-
-        getElement: function () {
-            return this.canvas;
-        },
-
-        /**
-         * Return the most recently inserted shape id
-         */
-        getLastShapeId: function () {
-            return this.lastShapeId;
-        },
-
-        /**
-         * Clear and reset the canvas
-         */
-        reset: function () {
-            alert('reset not implemented');
-        },
-
-        _insert: function (el, target) {
-            $(target).html(el);
-        },
-
-        /**
-         * Calculate the pixel dimensions of the canvas
-         */
-        _calculatePixelDims: function (width, height, canvas) {
-            // XXX This should probably be a configurable option
-            var match;
-            match = this._pxregex.exec(height);
-            if (match) {
-                this.pixelHeight = match[1];
-            } else {
-                this.pixelHeight = $(canvas).height();
-            }
-            match = this._pxregex.exec(width);
-            if (match) {
-                this.pixelWidth = match[1];
-            } else {
-                this.pixelWidth = $(canvas).width();
-            }
-            var ratio = window.hasOwnProperty('devicePixelRatio') ? window.devicePixelRatio : 1;
-            this.pixelWidth *= ratio;
-            this.pixelHeight *= ratio;
-        },
-
-        /**
-         * Generate a shape object and id for later rendering
-         */
-        _genShape: function (shapetype, shapeargs) {
-            var id = shapeCount++;
-            shapeargs.unshift(id);
-            return new VShape(this, id, shapetype, shapeargs);
-        },
-
-        /**
-         * Add a shape to the end of the render queue
-         */
-        appendShape: function (shape) {
-            alert('appendShape not implemented');
-        },
-
-        /**
-         * Replace one shape with another
-         */
-        replaceWithShape: function (shapeid, shape) {
-            alert('replaceWithShape not implemented');
-        },
-
-        /**
-         * Insert one shape after another in the render queue
-         */
-        insertAfterShape: function (shapeid, shape) {
-            alert('insertAfterShape not implemented');
-        },
-
-        /**
-         * Remove a shape from the queue
-         */
-        removeShapeId: function (shapeid) {
-            alert('removeShapeId not implemented');
-        },
-
-        /**
-         * Find a shape at the specified x/y co-ordinates
-         */
-        getShapeAt: function (el, x, y) {
-            alert('getShapeAt not implemented');
-        },
-
-        /**
-         * Render all queued shapes onto the canvas
-         */
-        render: function () {
-            alert('render not implemented');
-        }
-    });
-
-
-    VCanvas_canvas = createClass(VCanvas_base, {
-        init: function (width, height, target, interact) {
-            VCanvas_canvas._super.init.call(this, width, height, target);
-            this.canvas = document.createElement('canvas');
-            if (target[0]) {
-                target = target[0];
-            }
-            this.context = this.canvas.getContext('2d');
-
-            var devicePixelRatio = window.devicePixelRatio || 1,
-                backingStoreRatio = this.context.webkitBackingStorePixelRatio || this.context.mozBackingStorePixelRatio || this.context.msBackingStorePixelRatio || this.context.oBackingStorePixelRatio || this.context.backingStorePixelRatio || 1,
-                ratio = devicePixelRatio / backingStoreRatio;
-
-            $.data(target, '_jqs_vcanvas', this);
-            $(this.canvas).css({ display: 'inline-block', width: width, height: height, verticalAlign: 'top' });
-            this._insert(this.canvas, target);
-            this._calculatePixelDims(width, height, this.canvas);
-            this.canvas.width = this.pixelWidth * ratio;
-            this.canvas.height = this.pixelHeight * ratio;
-            this.context.scale(ratio, ratio);
-            this.interact = interact;
-            this.shapes = {};
-            this.shapeseq = [];
-            this.currentTargetShapeId = undefined;
-            //$(this.canvas).css({width: this.pixelWidth, height: this.pixelHeight});
-            //if transform applied to parent then need to adjust for that
-            this.devicePixelRatio = ratio;
-            this.ratio = this.pixelWidth / this.canvas.getBoundingClientRect().width;
-        },
-
-        _getContext: function (lineColor, fillColor, lineWidth) {
-            var context = this.canvas.getContext('2d');
-            if (lineColor !== undefined) {
-                context.strokeStyle = lineColor;
-            }
-            context.lineWidth = lineWidth === undefined ? 1 : lineWidth;
-            if (fillColor !== undefined) {
-                context.fillStyle = fillColor;
-            }
-            return context;
-        },
-
-        reset: function () {
-            var context = this._getContext();
-            context.clearRect(0, 0, this.pixelWidth, this.pixelHeight);
-            this.shapes = {};
-            this.shapeseq = [];
-            this.currentTargetShapeId = undefined;
-        },
-
-        // CUSTOM MOD: radius added
-        _drawShape: function (shapeid, path, lineColor, fillColor, lineWidth, radius) {
-            var context = this._getContext(lineColor, fillColor, lineWidth),
-                i, plen, done = false;
-            if (!radius)
-              radius = 0;
-            context.beginPath();
-            // CUSTOM MOD: corner radius drawing added for rectangles
-            if (path.length === 5) {
-                if ((path[1][0] - path[0][0]) < radius)
-                    radius = 0;
-                // this is a rectangle
-                if (radius > 0) {
-                    context.moveTo(path[0][0] + radius + 0.5, path[0][1] + 0.5);
-
-                    context.lineTo(path[1][0] - radius + 0.5, path[1][1] + 0.5);
-                    context.quadraticCurveTo(path[1][0] - radius + 0.5, path[1][1] + 0.5, path[1][0] + 0.5, path[1][1] + radius + 0.5);
-
-                    context.lineTo(path[2][0] + 0.5, path[2][1] - radius + 0.5);
-                    context.quadraticCurveTo(path[2][0] + 0.5, path[2][1] - radius + 0.5, path[2][0] - radius + 0.5, path[2][1] + 0.5);
-
-                    context.lineTo(path[3][0] + radius + 0.5, path[3][1] + 0.5);
-                    context.quadraticCurveTo(path[3][0] + radius + 0.5, path[3][1] + 0.5, path[3][0] + 0.5, path[3][1] - radius + 0.5);
-
-                    context.lineTo(path[4][0] + 0.5, path[4][1] + radius + 0.5);
-                    context.quadraticCurveTo(path[4][0] + 0.5, path[4][1] + radius + 0.5, path[4][0] + radius + 0.5, path[4][1] + 0.5);
-
-                    done = true;
-                }
-            } 
-            if (!done) {
-              context.moveTo(path[0][0] + 0.5, path[0][1] + 0.5);
-              for (i = 1, plen = path.length; i < plen; i++) {
-                  context.lineTo(path[i][0] + 0.5, path[i][1] + 0.5); // the 0.5 offset gives us crisp pixel-width lines
-              }
-            }
-
-            if (lineColor !== undefined) {
-                context.stroke();
-            }
-            if (fillColor !== undefined) {
-                context.fill();
-            }
-            if (this.targetX !== undefined && this.targetY !== undefined &&
-                context.isPointInPath(this.targetX, this.targetY)) {
-                this.currentTargetShapeId = shapeid;
-            }
-        },
-
-        _drawCircle: function (shapeid, x, y, radius, lineColor, fillColor, lineWidth) {
-            var context = this._getContext(lineColor, fillColor, lineWidth);
-            context.beginPath();
-            context.arc(x, y, radius, 0, 2 * Math.PI, false);
-            if (this.targetX !== undefined && this.targetY !== undefined &&
-                context.isPointInPath(this.targetX, this.targetY)) {
-                this.currentTargetShapeId = shapeid;
-            }
-            if (lineColor !== undefined) {
-                context.stroke();
-            }
-            if (fillColor !== undefined) {
-                context.fill();
-            }
-        },
-
-        _drawPieSlice: function (shapeid, x, y, radius, startAngle, endAngle, lineColor, fillColor) {
-            var context = this._getContext(lineColor, fillColor);
-            context.beginPath();
-            context.moveTo(x, y);
-            context.arc(x, y, radius, startAngle, endAngle, false);
-            context.lineTo(x, y);
-            context.closePath();
-            if (lineColor !== undefined) {
-                context.stroke();
-            }
-            if (fillColor) {
-                context.fill();
-            }
-            if (this.targetX !== undefined && this.targetY !== undefined &&
-                context.isPointInPath(this.targetX, this.targetY)) {
-                this.currentTargetShapeId = shapeid;
-            }
-        },
-
-        // CUSTOM MOD: radius added
-        _drawRect: function (shapeid, x, y, width, height, lineColor, fillColor, lineWidth, radius) {
-            return this._drawShape(shapeid, [[x, y], [x + width, y], [x + width, y + height], [x, y + height], [x, y]], lineColor, fillColor, null, radius);
-        },
-
-        appendShape: function (shape) {
-            this.shapes[shape.id] = shape;
-            this.shapeseq.push(shape.id);
-            this.lastShapeId = shape.id;
-            return shape.id;
-        },
-
-        replaceWithShape: function (shapeid, shape) {
-            var shapeseq = this.shapeseq,
-                i;
-            this.shapes[shape.id] = shape;
-            for (i = shapeseq.length; i--;) {
-                if (shapeseq[i] == shapeid) {
-                    shapeseq[i] = shape.id;
-                }
-            }
-            delete this.shapes[shapeid];
-        },
-
-        replaceWithShapes: function (shapeids, shapes) {
-            var shapeseq = this.shapeseq,
-                shapemap = {},
-                sid, i, first;
-
-            for (i = shapeids.length; i--;) {
-                shapemap[shapeids[i]] = true;
-            }
-            for (i = shapeseq.length; i--;) {
-                sid = shapeseq[i];
-                if (shapemap[sid]) {
-                    shapeseq.splice(i, 1);
-                    delete this.shapes[sid];
-                    first = i;
-                }
-            }
-            for (i = shapes.length; i--;) {
-                shapeseq.splice(first, 0, shapes[i].id);
-                this.shapes[shapes[i].id] = shapes[i];
-            }
-
-        },
-
-        insertAfterShape: function (shapeid, shape) {
-            var shapeseq = this.shapeseq,
-                i;
-            for (i = shapeseq.length; i--;) {
-                if (shapeseq[i] === shapeid) {
-                    shapeseq.splice(i + 1, 0, shape.id);
-                    this.shapes[shape.id] = shape;
-                    return;
-                }
-            }
-        },
-
-        removeShapeId: function (shapeid) {
-            var shapeseq = this.shapeseq,
-                i;
-            for (i = shapeseq.length; i--;) {
-                if (shapeseq[i] === shapeid) {
-                    shapeseq.splice(i, 1);
-                    break;
-                }
-            }
-            delete this.shapes[shapeid];
-        },
-
-        getShapeAt: function (el, x, y) {
-            this.targetX = x * window.devicePixelRatio;
-            this.targetY = y * window.devicePixelRatio;
-            this.render();
-            return this.currentTargetShapeId;
-        },
-
-        render: function () {
-            var shapeseq = this.shapeseq,
-                shapes = this.shapes,
-                shapeCount = shapeseq.length,
-                context = this._getContext(),
-                shapeid, shape, i;
-            context.clearRect(0, 0, this.pixelWidth, this.pixelHeight);
-            for (i = 0; i < shapeCount; i++) {
-                shapeid = shapeseq[i];
-                shape = shapes[shapeid];
-                this['_draw' + shape.type].apply(this, shape.args);
-            }
-            if (!this.interact) {
-                // not interactive so no need to keep the shapes array
-                this.shapes = {};
-                this.shapeseq = [];
-            }
-        }
-    });
-
-
-    VCanvas_vml = createClass(VCanvas_base, {
-        init: function (width, height, target) {
-            var groupel;
-            VCanvas_vml._super.init.call(this, width, height, target);
-            if (target[0]) {
-                target = target[0];
-            }
-            $.data(target, '_jqs_vcanvas', this);
-            this.canvas = document.createElement('span');
-            $(this.canvas).css({ display: 'inline-block', position: 'relative', overflow: 'hidden', width: width, height: height, margin: '0px', padding: '0px', verticalAlign: 'top'});
-            this._insert(this.canvas, target);
-            this._calculatePixelDims(width, height, this.canvas);
-            this.canvas.width = this.pixelWidth;
-            this.canvas.height = this.pixelHeight;
-            groupel = '<v:group coordorigin="0 0" coordsize="' + this.pixelWidth + ' ' + this.pixelHeight + '"' +
-                    ' style="position:absolute;top:0;left:0;width:' + this.pixelWidth + 'px;height=' + this.pixelHeight + 'px;"></v:group>';
-            this.canvas.insertAdjacentHTML('beforeEnd', groupel);
-            this.group = $(this.canvas).children()[0];
-            this.rendered = false;
-            this.prerender = '';
-        },
-
-        _drawShape: function (shapeid, path, lineColor, fillColor, lineWidth, radius) {
-            var vpath = [],
-                initial, stroke, fill, closed, vel, plen, i;
-            for (i = 0, plen = path.length; i < plen; i++) {
-                vpath[i] = '' + (path[i][0]) + ',' + (path[i][1]);
-            }
-            initial = vpath.splice(0, 1);
-            lineWidth = lineWidth === undefined ? 1 : lineWidth;
-            stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="' + lineWidth + 'px" strokeColor="' + lineColor + '" ';
-            fill = fillColor === undefined ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" ';
-            closed = vpath[0] === vpath[vpath.length - 1] ? 'x ' : '';
-            vel = '<v:shape coordorigin="0 0" coordsize="' + this.pixelWidth + ' ' + this.pixelHeight + '" ' +
-                 ' id="jqsshape' + shapeid + '" ' +
-                 stroke +
-                 fill +
-                ' style="position:absolute;left:0px;top:0px;height:' + this.pixelHeight + 'px;width:' + this.pixelWidth + 'px;padding:0px;margin:0px;" ' +
-                ' path="m ' + initial + ' l ' + vpath.join(', ') + ' ' + closed + 'e">' +
-                ' </v:shape>';
-            return vel;
-        },
-
-        _drawCircle: function (shapeid, x, y, radius, lineColor, fillColor, lineWidth) {
-            var stroke, fill, vel;
-            x -= radius;
-            y -= radius;
-            stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="' + lineWidth + 'px" strokeColor="' + lineColor + '" ';
-            fill = fillColor === undefined ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" ';
-            vel = '<v:oval ' +
-                 ' id="jqsshape' + shapeid + '" ' +
-                stroke +
-                fill +
-                ' style="position:absolute;top:' + y + 'px; left:' + x + 'px; width:' + (radius * 2) + 'px; height:' + (radius * 2) + 'px"></v:oval>';
-            return vel;
-
-        },
-
-        _drawPieSlice: function (shapeid, x, y, radius, startAngle, endAngle, lineColor, fillColor) {
-            var vpath, startx, starty, endx, endy, stroke, fill, vel;
-            if (startAngle === endAngle) {
-                return '';  // VML seems to have problem when start angle equals end angle.
-            }
-            if ((endAngle - startAngle) === (2 * Math.PI)) {
-                startAngle = 0.0;  // VML seems to have a problem when drawing a full circle that doesn't start 0
-                endAngle = (2 * Math.PI);
-            }
-
-            startx = x + Math.round(Math.cos(startAngle) * radius);
-            starty = y + Math.round(Math.sin(startAngle) * radius);
-            endx = x + Math.round(Math.cos(endAngle) * radius);
-            endy = y + Math.round(Math.sin(endAngle) * radius);
-
-            if (startx === endx && starty === endy) {
-                if ((endAngle - startAngle) < Math.PI) {
-                    // Prevent very small slices from being mistaken as a whole pie
-                    return '';
-                }
-                // essentially going to be the entire circle, so ignore startAngle
-                startx = endx = x + radius;
-                starty = endy = y;
-            }
-
-            if (startx === endx && starty === endy && (endAngle - startAngle) < Math.PI) {
-                return '';
-            }
-
-            vpath = [x - radius, y - radius, x + radius, y + radius, startx, starty, endx, endy];
-            stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="1px" strokeColor="' + lineColor + '" ';
-            fill = fillColor === undefined ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" ';
-            vel = '<v:shape coordorigin="0 0" coordsize="' + this.pixelWidth + ' ' + this.pixelHeight + '" ' +
-                 ' id="jqsshape' + shapeid + '" ' +
-                 stroke +
-                 fill +
-                ' style="position:absolute;left:0px;top:0px;height:' + this.pixelHeight + 'px;width:' + this.pixelWidth + 'px;padding:0px;margin:0px;" ' +
-                ' path="m ' + x + ',' + y + ' wa ' + vpath.join(', ') + ' x e">' +
-                ' </v:shape>';
-            return vel;
-        },
-
-        _drawRect: function (shapeid, x, y, width, height, lineColor, fillColor, lineWidth, radius) {
-            return this._drawShape(shapeid, [[x, y], [x, y + height], [x + width, y + height], [x + width, y], [x, y]], lineColor, fillColor, lineWidth, radius);
-        },
-
-        reset: function () {
-            this.group.innerHTML = '';
-        },
-
-        appendShape: function (shape) {
-            var vel = this['_draw' + shape.type].apply(this, shape.args);
-            if (this.rendered) {
-                this.group.insertAdjacentHTML('beforeEnd', vel);
-            } else {
-                this.prerender += vel;
-            }
-            this.lastShapeId = shape.id;
-            return shape.id;
-        },
-
-        replaceWithShape: function (shapeid, shape) {
-            var existing = $('#jqsshape' + shapeid),
-                vel = this['_draw' + shape.type].apply(this, shape.args);
-            existing[0].outerHTML = vel;
-        },
-
-        replaceWithShapes: function (shapeids, shapes) {
-            // replace the first shapeid with all the new shapes then toast the remaining old shapes
-            var existing = $('#jqsshape' + shapeids[0]),
-                replace = '',
-                slen = shapes.length,
-                i;
-            for (i = 0; i < slen; i++) {
-                replace += this['_draw' + shapes[i].type].apply(this, shapes[i].args);
-            }
-            existing[0].outerHTML = replace;
-            for (i = 1; i < shapeids.length; i++) {
-                $('#jqsshape' + shapeids[i]).remove();
-            }
-        },
-
-        insertAfterShape: function (shapeid, shape) {
-            var existing = $('#jqsshape' + shapeid),
-                 vel = this['_draw' + shape.type].apply(this, shape.args);
-            existing[0].insertAdjacentHTML('afterEnd', vel);
-        },
-
-        removeShapeId: function (shapeid) {
-            var existing = $('#jqsshape' + shapeid);
-            this.group.removeChild(existing[0]);
-        },
-
-        getShapeAt: function (el, x, y) {
-            var shapeid = el.id.substr(8);
-            return shapeid;
-        },
-
-        render: function () {
-            if (!this.rendered) {
-                // batch the intial render into a single repaint
-                this.group.innerHTML = this.prerender;
-                this.rendered = true;
-            }
-        }
-    });
-
-
-}));
-
-}(document, Math));
-</script>
-<script>HTMLWidgets.widget({
-  name: "sparkline",
-  type: "output",
-  factory: function(el, width, height) {
-    
-    var instance = {};
-    
-    return {
-
-      renderValue: function(data) {
-        
-        $(el).empty();
-
-        // if renderTag provided then we will do three things
-        //   1.  set height and width to 0 and display none
-        //   2.  set our el to the render tag if available
-        //   3.  set height and width options to null
-        if(data.renderSelector && $(data.renderSelector).length){
-          $(el).css({
-            'height': '0',
-            'width': '0',
-            'display': 'none'
-          });
-          el = data.renderSelector;
-          // set height and width to null
-          //   this might be confusing and need to be reverted
-          data.options.height = null;
-          data.options.width = null;
-        }
-        $(el).sparkline(data.values, data.options);
-        
-        // experimental addComposite function in R
-        //   will add composites to data.composites
-        if(data.composites) {
-          if(!Array.isArray(data.composites)) {
-            data.composites = [data.composites];
-          }
-          data.composites.map( function(spk) {
-            $(el).sparkline(spk.values,spk.options);
-          });
-        }
-        
-        instance.data = data;
-      },
-
-      resize: function(width, height) {
-
-        // not sure what to do in the event of resize
-        //  I think nothing for now
-        //  but will need to get a feel for use cases
-        //  where this is important such as slides, flexdashboard, tabset
-        this.renderValue(instance.data);
-
-      }
-
-    };
-  }  
-});
-</script>
 
 <style type="text/css">code{white-space: pre;}</style>
 <style type="text/css">
@@ -11032,7 +6460,7 @@
 2
 </td>
 <td style="text-align:center;">
-1
+0
 </td>
 </tr>
 <tr>
@@ -11072,7 +6500,7 @@
 7
 </td>
 <td style="text-align:center;">
-0
+1
 </td>
 </tr>
 <tr>
@@ -11091,7 +6519,7 @@
 9
 </td>
 <td style="text-align:center;">
-0
+1
 </td>
 </tr>
 <tr>
@@ -11113,7 +6541,7 @@
 11
 </td>
 <td style="text-align:center;">
-0
+1
 </td>
 </tr>
 <tr>
@@ -16438,11 +11866,10 @@
 </div>
 <div id="use-it-with-sparkline" class="section level2">
 <h2>Use it with sparkline</h2>
-<p>Well, this is not a feature but rather a documentation of how to use the <code>sparkline</code> package together with this package. The easiest way is sort of a hack. You can call <code>sparkline::sparkline(0)</code> somewhere on your document where no one would mind so its dependencies could be loaded without any hurdles. Then you use <code>sparkline::spk_chr()</code> to generate the text. Here is another example: <a href="https://cranky-chandrasekhar-cfefcd.netlify.app/">Chinese names in US babynames</a></p>
-<pre class="r"><code>library(sparkline)
+<p>Well, this is not a feature but rather a documentation of how to use the <code>sparkline</code> package together with this package. The easiest way is sort of a hack. You can call <code>sparkline::sparkline(0)</code> somewhere on your document where no one would mind so its dependencies could be loaded without any hurdles. Then you use <code>sparkline::spk_chr()</code> to generate the text. For a working example, see: <a href="https://cranky-chandrasekhar-cfefcd.netlify.app/">Chinese names in US babynames</a></p>
+<pre class="r"><code># Not evaluated
+library(sparkline)
 sparkline(0)</code></pre>
-<span id="htmlwidget-fe2aeadaaa92a48c86ee" class="sparkline html-widget"></span>
-<script type="application/json" data-for="htmlwidget-fe2aeadaaa92a48c86ee">{"x":{"values":0,"options":{"height":20,"width":60},"width":60,"height":20},"evals":[],"jsHooks":[]}</script>
 <pre class="r"><code>spk_dt &lt;- data.frame(
   var = c(&quot;mpg&quot;, &quot;wt&quot;),
   sparkline = c(spk_chr(mtcars$mpg), spk_chr(mtcars$wt))
@@ -16450,38 +11877,6 @@
 
 kbl(spk_dt, escape = F) %&gt;%
   kable_paper(full_width = F)</code></pre>
-<table class=" lightable-paper" style="font-family: &quot;Arial Narrow&quot;, arial, helvetica, sans-serif; width: auto !important; margin-left: auto; margin-right: auto;">
-<thead>
-<tr>
-<th style="text-align:left;">
-var
-</th>
-<th style="text-align:left;">
-sparkline
-</th>
-</tr>
-</thead>
-<tbody>
-<tr>
-<td style="text-align:left;">
-mpg
-</td>
-<td style="text-align:left;">
-<span id="htmlwidget-fdddfe62cb83547210eb" class="sparkline html-widget"></span>
-<script type="application/json" data-for="htmlwidget-fdddfe62cb83547210eb">{"x":{"values":[21,21,22.8,21.4,18.7,18.1,14.3,24.4,22.8,19.2,17.8,16.4,17.3,15.2,10.4,10.4,14.7,32.4,30.4,33.9,21.5,15.5,15.2,13.3,19.2,27.3,26,30.4,15.8,19.7,15,21.4],"options":{"height":20,"width":60},"width":60,"height":20},"evals":[],"jsHooks":[]}</script>
-</td>
-</tr>
-<tr>
-<td style="text-align:left;">
-wt
-</td>
-<td style="text-align:left;">
-<span id="htmlwidget-da7e098e9f570e71333f" class="sparkline html-widget"></span>
-<script type="application/json" data-for="htmlwidget-da7e098e9f570e71333f">{"x":{"values":[2.62,2.875,2.32,3.215,3.44,3.46,3.57,3.19,3.15,3.44,3.44,4.07,3.73,3.78,5.25,5.424,5.345,2.2,1.615,1.835,2.465,3.52,3.435,3.84,3.845,1.935,2.14,1.513,3.17,2.77,3.57,2.78],"options":{"height":20,"width":60},"width":60,"height":20},"evals":[],"jsHooks":[]}</script>
-</td>
-</tr>
-</tbody>
-</table>
 </div>
 </div>
 <div id="from-other-packages" class="section level1">
