diff --git a/skyquake/framework/js/gauge-modified.js b/skyquake/framework/js/gauge-modified.js
deleted file mode 100644
index ad881c3..0000000
--- a/skyquake/framework/js/gauge-modified.js
+++ /dev/null
@@ -1,1258 +0,0 @@
-
-/*
- * 
- *   Copyright 2016 RIFT.IO Inc
- *
- *   Licensed under the Apache License, Version 2.0 (the "License");
- *   you may not use this file except in compliance with the License.
- *   You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *   Unless required by applicable law or agreed to in writing, software
- *   distributed under the License is distributed on an "AS IS" BASIS,
- *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *   See the License for the specific language governing permissions and
- *   limitations under the License.
- *
- */
-// (function(window){
-  /**!
-   * @license
-   * HTML5 Canvas Gauge implementation
-   *
-   * This code is subject to MIT license.
-   *
-   * Copyright (c) 2012 Mykhailo Stadnyk <mikhus@gmail.com>
-   *
-   * Permission is hereby granted, free of charge, to any person obtaining a copy of
-   * this software and associated documentation files (the "Software"), to deal in
-   * the Software without restriction, including without limitation the rights to use,
-   * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
-   * Software, and to permit persons to whom the Software is furnished to do so,
-   * subject to the following conditions:
-   *
-   * The above copyright notice and this permission notice shall be included in all
-   * copies or substantial portions of the Software.
-   *
-   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-   * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-   * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-   * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-   * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-   *
-   * @authors: Mykhailo Stadnyk <mikhus@gmail.com>
-   *           Chris Poile <poile@edwards.usask.ca>
-   *           Luca Invernizzi <http://www.lucainvernizzi.net>
-   *           Robert Blackburn <http://www.rwblackburn.com>
-   */
-
-  /**
-   * @param {Object} config
-   * @constructor
-   */
-  var Gauge = function (config) {
-    Gauge.Collection.push(this);
-
-    /**
-     *  Default gauge configuration
-     *  @struct
-     */
-    this.config = {
-      isAggregate: false,
-      renderTo: null,
-      width: 200,
-      height: 200,
-      title: false,
-      maxValue: 100,
-      minValue: 0,
-      majorTicks: [],
-      minorTicks: 10,
-      strokeTicks: true,
-      units: false,
-      valueFormat: { "int": 3, "dec": 2 },
-      majorTicksFormat: { "int": 1, "dec": 0 },
-      glow: true,
-      animation: {
-        delay: 10,
-        duration: 250,
-        fn: 'cycle'
-      },
-      colors: {
-        plate: '#fff',
-        majorTicks: '#444',
-        minorTicks: '#666',
-        title: '#888',
-        units: '#888',
-        numbers: '#444',
-        needle: { start: 'rgba(240, 128, 128, 1)', end: 'rgba(255, 160, 122, .9)' }
-      },
-      highlights: [
-        {
-          from: 20,
-          to: 60,
-          color: '#eee'
-        },
-        {
-          from: 60,
-          to: 80,
-          color: '#ccc'
-        },
-        {
-          from: 80,
-          to: 100,
-          color: '#999'
-        }
-      ]
-    };
-
-    var
-      value = 0,
-      self = this,
-      fromValue = 0,
-      toValue = 0,
-      imready = false
-      ;
-
-    /**
-     * Sets a new value to gauge and updates the gauge view
-     *
-     * @param {number} val  - the new value to set to the gauge
-     * @return {Gauge} this - returns self
-     */
-    this.setValue = function (val) {
-
-      fromValue = config.animation ? value : val;
-
-      var dv = (config.maxValue - config.minValue) / 100;
-
-      toValue = val > config.maxValue ?
-      config.maxValue + dv :
-        val < config.minValue ?
-        config.minValue - dv :
-          val
-      ;
-
-      value = val;
-
-      if (toValue >= fromValue) {
-        config.arrow = 'up';
-      } else {
-        config.arrow = 'down';
-      }
-
-      config.animation ? animate() : this.draw();
-
-      return this;
-    };
-
-    /**
-     * Sets a new value to gauge and updates the gauge view without
-     * any animation (even if configured)
-     *
-     * @param {number} val  - the new value to set to the gauge
-     * @return {Gauge} this - returns self
-     */
-    this.setRawValue = function (val) {
-      fromValue = value = val;
-      this.draw();
-      return this;
-    };
-
-    /**
-     * Clears the value of the gauge
-     * @return {Gauge}
-     */
-    this.clear = function () {
-      value = fromValue = toValue = this.config.minValue;
-      this.draw();
-      return this;
-    };
-
-
-    /**
-     * Returns the current value been set to the gauge
-     *
-     * @return {number} value - current gauge's value
-     */
-    this.getValue = function () {
-      return value;
-    };
-
-    /**
-     * Ready event for the gauge. Use it whenever you
-     * initialize the gauge to be assured it was fully drawn
-     * before you start the update on it
-     *
-     * @event {Function} onready
-     */
-    this.onready = function () {
-    };
-
-    function applyRecursive(dst, src) {
-      for (var i in src) {
-        // modification by Chris Poile, Oct 08, 2012. More correct check of an Array instance
-        if (typeof src[i] == "object" && !(Object.prototype.toString.call(src[i]) === '[object Array]') && i != 'renderTo') {
-          if (typeof dst[i] != "object") {
-            dst[i] = {};
-          }
-
-          applyRecursive(dst[i], src[i]);
-        } else {
-          dst[i] = src[i];
-        }
-      }
-    };
-
-    applyRecursive(this.config, config);
-
-    this.config.minValue = parseFloat(this.config.minValue);
-    this.config.maxValue = parseFloat(this.config.maxValue);
-
-    config = this.config;
-    fromValue = value = config.minValue;
-
-    if (!config.renderTo) {
-      throw Error("Canvas element was not specified when creating the Gauge object!");
-    }
-
-    var
-      canvas = config.renderTo.tagName ? config.renderTo : document.getElementById(config.renderTo),
-      ctx = canvas.getContext('2d'),
-      cache, CW, CH, CX, CY, max, cctx
-      ;
-
-    function baseInit() {
-      canvas.width = config.width;
-      canvas.height = config.height;
-
-      cache = canvas.cloneNode(true);
-      cctx = cache.getContext('2d');
-      CW = canvas.width;
-      CH = canvas.height;
-      CX = CW / 2;
-      CY = CH / 2;
-      max = CX < CY ? CX : CY;
-
-      cache.i8d = false;
-
-      // translate cache to have 0, 0 in center
-      cctx.translate(CX, CY);
-      cctx.save();
-
-      // translate canvas to have 0,0 in center
-      ctx.translate(CX, CY);
-      ctx.save();
-    };
-
-    // do basic initialization
-    baseInit();
-
-    /**
-     * Updates the gauge config
-     *
-     * @param  {Object} config
-     * @return {Gauge}
-     */
-    this.updateConfig = function (config) {
-      applyRecursive(this.config, config);
-      baseInit();
-      this.draw();
-      return this;
-    };
-
-    var animateFx = {
-      linear: function (p) {
-        return p;
-      },
-      quad: function (p) {
-        return Math.pow(p, 2);
-      },
-      quint: function (p) {
-        return Math.pow(p, 5);
-      },
-      cycle: function (p) {
-        return 1 - Math.sin(Math.acos(p));
-      },
-      bounce: function (p) {
-        return 1 - (function (p) {
-            for (var a = 0, b = 1; 1; a += b, b /= 2) {
-              if (p >= (7 - 4 * a) / 11) {
-                return -Math.pow((11 - 6 * a - 11 * p) / 4, 2) + Math.pow(b, 2);
-              }
-            }
-          })(1 - p);
-      },
-      elastic: function (p) {
-        return 1 - (function (p) {
-            var x = 1.5;
-            return Math.pow(2, 10 * (p - 1)) * Math.cos(20 * Math.PI * x / 3 * p);
-          })(1 - p);
-      }
-    };
-
-    var animateInterval = null;
-
-    function _animate(opts) {
-      var start = new Date;
-
-      animateInterval = setInterval(function () {
-        var
-          timePassed = new Date - start,
-          progress = timePassed / opts.duration
-          ;
-
-        if (progress > 1) {
-          progress = 1;
-        }
-
-        var animateFn = typeof opts.delta == "function" ?
-            opts.delta :
-            animateFx[opts.delta]
-          ;
-
-        var delta = animateFn(progress);
-        opts.step(delta);
-
-        if (progress == 1) {
-          clearInterval(animateInterval);
-        }
-      }, opts.delay || 10);
-    };
-
-    function animate() {
-      animateInterval && clearInterval(animateInterval); // stop previous animation
-      var
-        path = (toValue - fromValue),
-        from = fromValue,
-        cfg = config.animation
-        ;
-
-      _animate({
-        delay: cfg.delay,
-        duration: cfg.duration,
-        delta: cfg.fn,
-        step: function (delta) {
-          fromValue = parseFloat(from) + path * delta;
-          self.draw();
-        }
-      });
-    };
-
-    // defaults
-    ctx.lineCap = "round";
-
-    /**
-     * Drows the gauge. Normally this function should be used to
-     * initally draw the gauge
-     *
-     * @return {Gauge} this - returns the self Gauge object
-     */
-    this.draw = function () {
-      if (!cache.i8d) {
-        // clear the cache
-        cctx.clearRect(-CX, -CY, CW, CH);
-        cctx.save();
-
-        var tmp = {ctx: ctx};
-        ctx = cctx;
-
-        drawPlate();
-        drawHighlights();
-        drawMinorTicks();
-        drawMajorTicks();
-        drawNumbers();
-        drawTitle();
-        drawUnits();
-
-        cache.i8d = true;
-        ctx = tmp.ctx;
-        delete tmp.ctx;
-      }
-
-      // clear the canvas
-      ctx.clearRect(-CX, -CY, CW, CH);
-      ctx.save();
-
-      ctx.drawImage(cache, -CX, -CY, CW, CH);
-
-      if (!Gauge.initialized) {
-        var iv = setInterval(function () {
-          if (!Gauge.initialized) {
-            return;
-          }
-
-          clearInterval(iv);
-
-          drawValueBox();
-          drawNeedle();
-          // drawArrow();
-
-          if (!imready) {
-            self.onready && self.onready();
-            imready = true;
-          }
-        }, 10);
-      } else {
-        drawValueBox();
-        drawNeedle();
-        // drawArrow();
-
-        if (!imready) {
-          self.onready && self.onready();
-          imready = true;
-        }
-      }
-
-      return this;
-    };
-
-    /**
-     * Transforms degrees to radians
-     */
-    function radians(degrees) {
-      return degrees * Math.PI / 180;
-    };
-
-    /**
-     * Linear gradient
-     */
-    function lgrad(clrFrom, clrTo, len) {
-      var grad = ctx.createLinearGradient(0, 0, 0, len);
-      grad.addColorStop(0, clrFrom);
-      grad.addColorStop(1, clrTo);
-
-      return grad;
-    };
-
-    function drawPlate() {
-      var
-        r0 = max / 100 * 93,
-        d0 = max - r0,
-        r1 = max / 100 * 91,
-        d1 = max - r1,
-        r2 = max / 100 * 88,
-        d2 = max - r2,
-        r3 = max / 100 * 85;
-
-      ctx.save();
-
-      if (config.glow) {
-        ctx.shadowBlur = d0;
-        ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
-      }
-
-      ctx.beginPath();
-      ctx.arc(0, 0, r0, 0, Math.PI * 2, true);
-      // ctx.fillStyle = lgrad( '#ddd', '#aaa', r0);
-      ctx.fillStyle = lgrad('hsla(0, 0%, 17%, 1)', 'hsla(0, 0%, 0%, 1)', r0);
-      //ctx.fill();
-
-      //ctx.restore();
-
-      ctx.beginPath();
-      ctx.arc(0, 0, r1, 0, Math.PI * 2, true);
-      // ctx.fillStyle = lgrad( '#fafafa', '#ccc', r1);
-      ctx.fillStyle = lgrad('hsla(0, 0%, 47%, 1)', 'hsla(0, 0%, 33%, 1)', r1);
-      //ctx.fill();
-
-      ctx.beginPath();
-      ctx.arc(0, 0, r2, 0, Math.PI * 2, true);
-      // ctx.fillStyle = lgrad( '#eee', '#f0f0f0', r2);
-      ctx.fillStyle = lgrad('hsla(0, 0%, 33%, 1)', 'hsla(0, 0%, 43%, 1)', r2);
-      //ctx.fill();
-
-      ctx.beginPath();
-      ctx.arc(0, 0, r3, 0, Math.PI * 2, true);
-      ctx.fillStyle = config.colors.plate;
-      //ctx.fill();
-
-      ctx.save();
-    };
-
-    /**
-     * Formats a number for display on the dial's plate using the majorTicksFormat config option.
-     *
-     * @param {number} num The number to format
-     * @returns {string} The formatted number
-     */
-    function formatMajorTickNumber(num) {
-      var r, isDec = false;
-
-      // First, force the correct number of digits right of the decimal.
-      if (config.majorTicksFormat.dec === 0) {
-        r = Math.round(num).toString();
-      } else {
-        r = num.toFixed(config.majorTicksFormat.dec);
-      }
-
-      // Second, force the correct number of digits left of the decimal.
-      if (config.majorTicksFormat["int"] > 1) {
-        // Does this number have a decimal?
-        isDec = (r.indexOf('.') > -1);
-
-        // Is this number a negative number?
-        if (r.indexOf('-') > -1) {
-          return '-' + [
-              config.majorTicksFormat["int"] + config.majorTicksFormat.dec + 2 + (isDec ? 1 : 0) - r.length
-            ].join('0') + r.replace('-', '');
-        } else {
-          return [
-              config.majorTicksFormat["int"] + config.majorTicksFormat.dec + 1 + (isDec ? 1 : 0) - r.length
-            ].join('0') + r;
-        }
-      } else {
-        return r;
-      }
-    }
-
-    // major ticks draw
-    function drawMajorTicks() {
-      var r = max / 100 * 81;
-
-      ctx.lineWidth = 1;
-      ctx.strokeStyle = config.colors.majorTicks;
-      ctx.save();
-
-      if (config.majorTicks.length === 0) {
-        var numberOfDefaultTicks = 5;
-        var tickSize = (config.maxValue - config.minValue) / numberOfDefaultTicks;
-
-        for (var i = 0; i < numberOfDefaultTicks; i++) {
-          config.majorTicks.push(formatMajorTickNumber(config.minValue + (tickSize * i)));
-        }
-        config.majorTicks.push(formatMajorTickNumber(config.maxValue));
-      }
-
-      for (var i = 0; i < config.majorTicks.length; ++i) {
-        var a = 45 + i * (270 / (config.majorTicks.length - 1));
-        ctx.rotate(radians(a));
-
-        ctx.beginPath();
-        ctx.moveTo(0, r);
-        ctx.lineTo(0, r - max / 100 * 15);
-        ctx.stroke();
-
-        ctx.restore();
-        ctx.save();
-      }
-
-      if (config.strokeTicks) {
-        ctx.rotate(radians(90));
-
-        ctx.beginPath();
-        ctx.arc(0, 0, r, radians(45), radians(315), false);
-        ctx.stroke();
-        ctx.restore();
-
-        ctx.save();
-      }
-    };
-
-    // minor ticks draw
-    function drawMinorTicks() {
-      var r = max / 100 * 81;
-
-      ctx.lineWidth = 1;
-      ctx.strokeStyle = config.colors.minorTicks;
-
-      ctx.save();
-
-      var len = config.minorTicks * (config.majorTicks.length - 1);
-
-      for (var i = 0; i < len; ++i) {
-        var a = 45 + i * (270 / len);
-        ctx.rotate(radians(a));
-
-        ctx.beginPath();
-        ctx.moveTo(0, r);
-        ctx.lineTo(0, r - max / 100 * 7.5);
-        ctx.stroke();
-
-        ctx.restore();
-        ctx.save();
-      }
-    };
-
-    // tick numbers draw
-    function drawNumbers() {
-      //var r = max / 100 * 55;
-      //
-      //for (var i = 0; i < config.majorTicks.length; ++i) {
-      //  var
-      //    a = 45 + i * (270 / (config.majorTicks.length - 1)),
-      //    p = rpoint(r, radians(a))
-      //    ;
-      //
-      //  ctx.font = 20 * (max / 200) + "px Arial";
-      //  ctx.fillStyle = config.colors.numbers;
-      //  ctx.lineWidth = 0;
-      //  ctx.textAlign = "center";
-      //  ctx.fillText(config.majorTicks[i], p.x, p.y + 3);
-      //}
-    };
-
-    // title draw
-    function drawTitle() {
-      if (!config.title) {
-        return;
-      }
-
-      ctx.save();
-      ctx.font = 24 * (max / 200) + "px Arial";
-      ctx.fillStyle = config.colors.title;
-      ctx.textAlign = "center";
-      ctx.fillText(config.title, 0, -max / 4.25);
-      ctx.restore();
-    };
-
-    // units draw
-    function drawUnits() {
-      if (!config.units) {
-        return;
-      }
-
-      ctx.save();
-      ctx.font = 22 * (max / 200) + "px Arial";
-      ctx.fillStyle = config.colors.units;
-      ctx.textAlign = "center";
-      ctx.fillText(config.units, 0, max / 3.25);
-      ctx.restore();
-    };
-
-
-    function drawArrow() {
-
-      if (config.arrow != "false") {
-
-        if (config.arrow == "up") {
-          var r = max / 100 * 2.0;
-          y0 = max / 100 * 64;
-          y1 = max / 100 * 55;
-          y2 = max / 100 * 53;
-          y3 = max / 100 * 50;
-          y4 = max / 100 * 45;
-          arrow_color = "rgba(107, 184, 20, 1)";
-
-          var x0 = max / 100 * -8
-          var x1 = max / 100 * -6
-          var x2 = max / 100 * -1.5
-          var x3 = max / 100 * 0
-          var x4 = max / 100 * 1.5
-          var x5 = max / 100 * 6
-          var x6 = max / 100 * 8
-
-          ctx.beginPath();
-          ctx.moveTo(x0, y2);
-          ctx.lineTo(x3 - r, y4 + r);
-          ctx.arcTo(x3, y4 - r, x3 + r, y4 + r, r * 1.09);
-          ctx.lineTo(x6, y2);
-          ctx.arcTo(x6 + r/2.0, y2 + r/1.0, x5, y1, r*.9)
-          ctx.lineTo(x4, y3);
-          ctx.lineTo(x4, y0);
-          ctx.arcTo(x3, y0 + r, x2, y0, r*.9);
-          ctx.lineTo(x2, y3);
-          ctx.lineTo(x1, y1);
-          ctx.arcTo(x1 - r, y1 - r/2.0, x0, y2, r*1.09)
-
-
-          ctx.closePath();
-          ctx.fillStyle = arrow_color;
-          ctx.fill();
-        } else {
-          var r = max / 100 * 2.0;
-          var y0 = max / 100 * 45;
-          var y1 = max / 100 * 54;
-          var y2 = max / 100 * 56;
-          var y3 = max / 100 * 59;
-          var y4 = max / 100 * 64;
-          var arrow_color = "rgba(252, 38, 50, 1)";
-
-          var x0 = max / 100 * -8
-          var x1 = max / 100 * -6
-          var x2 = max / 100 * -1.5
-          var x3 = max / 100 * 0
-          var x4 = max / 100 * 1.5
-          var x5 = max / 100 * 6
-          var x6 = max / 100 * 8
-
-          ctx.beginPath();
-          ctx.moveTo(x0, y2);
-          ctx.lineTo(x3 - r, y4 - r);
-          ctx.arcTo(x3, y4 + r, x3 + r, y4 - r, r * 1.09);
-          ctx.lineTo(x6, y2);
-          ctx.arcTo(x6 + r/2.0, y2 - r/1.0, x5, y1, r*.9)
-          ctx.lineTo(x4, y3);
-          ctx.lineTo(x4, y0);
-          ctx.arcTo(x3, y0 - r, x2, y0, r*.9);
-          ctx.lineTo(x2, y3);
-          ctx.lineTo(x1, y1);
-          ctx.arcTo(x1 - r, y1 + r/2.0, x0, y2, r*1.09)
-
-
-          ctx.closePath();
-          ctx.fillStyle = arrow_color;
-          ctx.fill();
-        }
-        ctx.save();
-        ctx.restore();
-      }
-    }
-
-    function padValue(val) {
-        var cdec = config.valueFormat['dec']
-        var cint = config.valueFormat['int']
-
-      val = parseFloat(val);
-      var n = (val < 0);
-
-      val = Math.abs(val);
-
-      if (cdec > 0) {
-        val = val.toFixed(cdec).toString().split('.');
-
-        for (var i = 0, s = cint - val[0].length; i < s; ++i) {
-          val[0] = '0' + val[0];
-        }
-
-        val = (n ? '-' : '') + val[0] + '.' + val[1];
-      } else {
-        val = Math.round(val).toString();
-
-        for (var i = 0, s = cint - val.length; i < s; ++i) {
-          val = '0' + val;
-        }
-
-        val = (n ? '-' : '') + val
-      }
-
-      return val;
-    };
-
-    function rpoint(r, a) {
-      var
-        x = 0, y = r,
-
-        sin = Math.sin(a),
-        cos = Math.cos(a),
-
-        X = x * cos - y * sin,
-        Y = x * sin + y * cos
-        ;
-
-      return { x: X, y: Y };
-    };
-    function clearCircle(x, y, radius)
-    {
-      ctx.beginPath();
-      ctx.arc(x, y, radius, 0, 2 * Math.PI, false);
-      ctx.clip();
-      ctx.clearRect(x - radius - 1, y - radius - 1,
-        radius * 2 + 2, radius * 2 + 2);
-
-    };
-    // draws the highlight colors
-    function drawHighlights() {
-      ctx.save();
-
-      var r1 = max / 100 * 81;
-      var r2 = r1 - max / 100 * 15;
-
-      for (var i = 0, s = config.highlights.length; i < s; i++) {
-        var
-          hlt = config.highlights[i],
-          vd = (config.maxValue - config.minValue) / 270,
-          sa = radians(45 + (hlt.from - config.minValue) / vd),
-          ea = radians(45 + (hlt.to - config.minValue) / vd)
-          ;
-
-        ctx.beginPath();
-
-        ctx.rotate(radians(90));
-        ctx.arc(0, 0, r1, sa, ea, false);
-        ctx.restore();
-        ctx.save();
-
-        var
-          ps = rpoint(r2, sa),
-          pe = rpoint(r1, sa)
-          ;
-        ctx.moveTo(ps.x, ps.y);
-        ctx.lineTo(pe.x, pe.y);
-
-        var
-          ps1 = rpoint(r1, ea),
-          pe1 = rpoint(r2, ea)
-          ;
-
-        ctx.lineTo(ps1.x, ps1.y);
-        ctx.lineTo(pe1.x, pe1.y);
-        ctx.lineTo(ps.x, ps.y);
-
-        ctx.closePath();
-
-        ctx.fillStyle = hlt.color;
-        ctx.fill();
-
-        ctx.beginPath();
-        ctx.rotate(radians(90));
-        ctx.arc(0, 0, r2, sa - 0.2, ea + 0.2, false);
-        ctx.restore();
-
-        ctx.closePath();
-
-        ctx.fillStyle = config.colors.plate;
-        ctx.fill();
-        ctx.save();
-        ctx.imageSmoothingEnabled = true
-        //clearCircle(0, 0, 100)
-
-      }
-    };
-
-    // drows the gauge needle
-    function drawNeedle() {
-      var
-        r1 = 0 ,
-        r2 = 0 ,
-        rIn = max / 100 * 85,
-        rOut = max / 100 * 63,
-        rP = max / 100 * 59,
-        pad1 = max / 100 * 3,
-        pad2 = max / 100 * 2.5,
-
-        shad = function () {
-          ctx.shadowOffsetX = 2;
-          ctx.shadowOffsetY = 2;
-          ctx.shadowBlur = 10;
-          // ctx.shadowColor   = 'rgba(188, 143, 143, 0.45)';
-          ctx.shadowColor = 'rgba(50, 50, 50, .3)';
-        }
-        ;
-
-      shad();
-
-      ctx.save();
-
-      if (fromValue < 0) {
-        fromValue = Math.abs(config.minValue - fromValue);
-      } else if (config.minValue > 0) {
-        fromValue -= config.minValue
-      } else {
-        fromValue = Math.abs(config.minValue) + fromValue;
-      }
-
-      ctx.rotate(radians(45 + fromValue / ((config.maxValue - config.minValue) / 270)));
-
-      ctx.beginPath();
-      ctx.lineTo(-pad2, rOut);
-      ctx.lineTo(-pad2, rIn);
-      ctx.lineTo(pad2, rIn);
-      ctx.lineTo(pad2, rOut);
-      ctx.lineTo(0, rP);
-      ctx.closePath();
-      ctx.strokeStyle = "#999"
-      ctx.stroke();
-
-      ctx.fillStyle = lgrad(
-        config.colors.needle.start,
-        config.colors.needle.end,
-        rIn - rOut
-      );
-      ctx.fill();
-
-      // ctx.beginPath();
-      // ctx.lineTo(-_pad2, _rOut);
-      // ctx.lineTo(-_pad2, _rIn);
-      // ctx.lineTo(_pad2, _rIn);
-      // ctx.lineTo(_pad2, _rOut);
-      // ctx.lineTo(0, _rOut - 5);
-      // ctx.closePath();
-
-      // ctx.fillStyle = "#ccc"
-      // ctx.fill();
-
-      ctx.beginPath();
-      ctx.lineTo(-pad2, rIn);
-      ctx.lineTo(-pad2, rIn);
-      ctx.lineTo(-pad1, 0);
-      ctx.lineTo(-pad2, rOut);
-      ctx.lineTo(pad2 / 2 - 2, rOut);
-      ctx.closePath();
-      ctx.fillStyle = 'rgba(255, 255, 255, 0.2)';
-
-      //ctx.fill();
-
-      ctx.restore();
-
-      //shad();
-
-      ctx.beginPath();
-      ctx.arc(0, 0, r2 +.5, 0, Math.PI * 2, true);
-      // ctx.fillStyle = lgrad( '#f0f0f0', '#ccc', r1);
-      ctx.fillStyle = lgrad('#3b3b3b', '#121212', r1);
-      //ctx.fill();
-
-      ctx.restore();
-
-      ctx.beginPath();
-      ctx.arc(0, 0, r2, 0, Math.PI * 2, true);
-      // ctx.fillStyle = lgrad( "#e8e8e8", "#f5f5f5", r2);
-      ctx.fillStyle = 'rgba(255,255,255,1)';
-      //ctx.fill();
-    };
-
-    function roundRect(x, y, w, h, r) {
-      ctx.beginPath();
-
-      ctx.moveTo(x + r, y);
-      ctx.lineTo(x + w - r, y);
-
-      ctx.quadraticCurveTo(x + w, y, x + w, y + r);
-      ctx.lineTo(x + w, y + h - r);
-
-      ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
-      ctx.lineTo(x + r, y + h);
-
-      ctx.quadraticCurveTo(x, y + h, x, y + h - r);
-      ctx.lineTo(x, y + r);
-
-      ctx.quadraticCurveTo(x, y, x + r, y);
-
-      ctx.closePath();
-    };
-
-    // value box draw
-    function drawValueBox() {
-      ctx.save();
-
-      ctx.font = 100 +  " " + 73 * (max / 200) + "px 'roboto-light";
-      var
-        text = padValue(value),
-        tw = ctx.measureText('-' + padValue(0)).width,
-        y = max - max / 100 * 96,
-        x = 0,
-        th = 0.12 * max
-        ;
-
-      ctx.save();
-
-      roundRect(
-        -tw / 2 - 0.025 * max,
-        y - th - 0.04 * max,
-        tw + 0.05 * max,
-        th + 0.07 * max,
-        0.025 * max
-      );
-
-      var grd = ctx.createRadialGradient(
-        x,
-        y - 0.12 * max - 0.025 * max + (0.12 * max + 0.045 * max) / 2,
-        max / 10,
-        x,
-        y - 0.12 * max - 0.025 * max + (0.12 * max + 0.045 * max) / 2,
-        max / 5
-      );
-
-      // grd.addColorStop( 0, "#888");
-      //    grd.addColorStop( 1, "#666");
-
-      // ctx.strokeStyle = grd;
-      // ctx.lineWidth = 0.05 * max;
-      // ctx.stroke();
-
-      // ctx.shadowBlur  = 0.012 * max;
-      // ctx.shadowColor = 'rgba(0, 0, 0, 1)';
-
-      // ctx.fillStyle = "#babab2";
-      // ctx.fill();
-
-      // ctx.restore();
-
-      // ctx.shadowOffsetX = 0.004 * max;
-      // ctx.shadowOffsetY = 0.004 * max;
-      // ctx.shadowBlur    = 0.012 * max;
-      // ctx.shadowColor   = 'rgba(0, 0, 0, 0.3)';
-
-      // ctx.fillStyle = "#444";
-      ctx.fillStyle = "rgba(50,50,50,1)";
-      //      ctx.fillStyle = "rgba(50,50,50,1)";
-      ctx.textAlign = "center";
-
-      ctx.fillText(text, -x, y);
-
-
-      ctx.save();
-      ctx.font = 100 +  " " + 20 * (max / 200) + "px 'roboto-light";
-      //ctx.fillText(config.unit, -x, y + 30);
-      ctx.restore();
-
-    };
-  };
-
-// initialize
-  Gauge.initialized = false;
-  (function () {
-    var
-      d = document,
-      h = d.getElementsByTagName('head')[0],
-      ie = navigator.userAgent.toLocaleLowerCase().indexOf('msie') != -1,
-      url = 'fonts/digital-7-mono.' + (ie ? 'eot' : 'ttf'),
-
-    // RW: don't use mono font, this was causing err in js console
-      text = '',
-//        text = "@font-face {" +
-//            "font-family: 'Led';" +
-//            "src: url('" + url + "');" +
-//            "}",
-      ss,
-      r = d.createElement('style')
-      ;
-
-    r.type = 'text/css';
-
-    if (ie) {
-      h.appendChild(r);
-      ss = r.styleSheet;
-      ss.cssText = text;
-    } else {
-      try {
-        r.appendChild(d.createTextNode(text));
-      } catch (e) {
-        r.cssText = text;
-      }
-
-      h.appendChild(r);
-
-      ss = r.styleSheet ? r.styleSheet :
-        (r.sheet || d.styleSheets[d.styleSheets.length - 1])
-      ;
-    }
-
-    var iv = setInterval(function () {
-      if (!d.body) {
-        return;
-      }
-
-      clearInterval(iv);
-
-      var dd = d.createElement('div');
-
-      dd.style.fontFamily = 'Led';
-      dd.style.position = 'absolute';
-      dd.style.height = dd.style.width = 0;
-      dd.style.overflow = 'hidden';
-
-      dd.innerHTML = '.';
-
-      d.body.appendChild(dd);
-
-      setTimeout(function () { // no other way to handle font is rendered by a browser
-        // just give the browser around 250ms to do that :(
-        Gauge.initialized = true;
-        dd.parentNode.removeChild(dd);
-      }, 250);
-    }, 1);
-  })();
-
-  Gauge.Collection = [];
-  Gauge.Collection.get = function (id) {
-    var self = this;
-
-    if (typeof(id) == 'string') {
-      for (var i = 0, s = self.length; i < s; i++) {
-        var canvas = self[i].config.renderTo.tagName ? self[i].config.renderTo : document.getElementById(self[i].config.renderTo);
-        if (canvas.getAttribute('id') == id) {
-          return self[i];
-        }
-      }
-    } else if (typeof(id) == 'number') {
-      return self[id];
-    } else {
-      return null;
-    }
-  };
-
-  function domReady(handler) {
-    if (window.addEventListener) {
-      window.addEventListener('DOMContentLoaded', handler, false);
-    } else {
-      window.attachEvent('onload', handler);
-    }
-  }
-
-  domReady(function () {
-    function toCamelCase(arr) {
-      var str = arr[0];
-      for (var i = 1, s = arr.length; i < s; i++) {
-        str += arr[i].substr(0, 1).toUpperCase() + arr[i].substr(1, arr[i].length - 1);
-      }
-      return str;
-    };
-
-    function trim(str) {
-      return str.replace(/^\s+|\s+$/g, '');
-    };
-
-    var c = document.getElementsByTagName('canvas');
-
-    for (var i = 0, s = c.length; i < s; i++) {
-
-      if (c[i].getAttribute('data-type') == 'canv-gauge') {
-        var
-          gauge = c[i],
-          config = {},
-          prop,
-          w = parseInt(gauge.getAttribute('width'), 10),
-          h = parseInt(gauge.getAttribute('height'), 10)
-          ;
-
-        config.renderTo = gauge;
-
-        if (w) {
-          config.width = w;
-        }
-
-        if (h) {
-          config.height = h;
-        }
-
-        for (var ii = 0, ss = gauge.attributes.length; ii < ss; ii++) {
-          prop = gauge.attributes.item(ii).nodeName;
-
-          if (prop != 'data-type' && prop.substr(0, 5) == 'data-') {
-            var
-              cfgProp = prop.substr(5, prop.length - 5).toLowerCase().split('-'),
-              attrValue = gauge.getAttribute(prop)
-              ;
-
-            if (!attrValue) {
-              continue;
-            }
-
-            switch (cfgProp[0]) {
-              case 'colors' :
-              {
-                if (cfgProp[1]) {
-                  if (!config.colors) {
-                    config.colors = {};
-                  }
-
-                  if (cfgProp[1] == 'needle') {
-                    var parts = attrValue.split(/\s+/);
-
-                    if (parts[0] && parts[1]) {
-                      config.colors.needle = { start: parts[0], end: parts[1] };
-                    }
-                    else {
-                      config.colors.needle = attrValue;
-                    }
-                  }
-                  else {
-                    cfgProp.shift();
-                    config.colors[toCamelCase(cfgProp)] = attrValue;
-                  }
-                }
-                break;
-              }
-              case 'highlights' :
-              {
-                if (!config.highlights) {
-                  config.highlights = [];
-                }
-
-                var hls = attrValue.match(/(?:(?:-?\d*\.)?(-?\d+){1,2} ){2}(?:(?:#|0x)?(?:[0-9A-F|a-f]){3,8}|rgba?\(.*?\))/g);
-
-                for (var j = 0, l = hls.length; j < l; j++) {
-                  var
-                    cfg = trim(hls[j]).split(/\s+/),
-                    hlCfg = {}
-                    ;
-
-                  if (cfg[0] && cfg[0] != '') {
-                    hlCfg.from = cfg[0];
-                  }
-
-                  if (cfg[1] && cfg[1] != '') {
-                    hlCfg.to = cfg[1];
-                  }
-
-                  if (cfg[2] && cfg[2] != '') {
-                    hlCfg.color = cfg[2];
-                  }
-
-                  config.highlights.push(hlCfg);
-                }
-                break;
-              }
-              case 'animation' :
-              {
-                if (cfgProp[1]) {
-                  if (!config.animation) {
-                    config.animation = {};
-                  }
-
-                  if (cfgProp[1] == 'fn' && /^\s*function\s*\(/.test(attrValue)) {
-                    attrValue = eval('(' + attrValue + ')');
-                  }
-
-                  config.animation[cfgProp[1]] = attrValue;
-                }
-                break;
-              }
-              default :
-              {
-                var cfgName = toCamelCase(cfgProp);
-
-                if (cfgName == 'onready') {
-                  continue;
-                }
-
-                if (cfgName == 'majorTicks') {
-                  attrValue = attrValue.split(/\s+/);
-                }
-                else if (cfgName == 'strokeTicks' || cfgName == 'glow') {
-                  attrValue = attrValue == 'true' ? true : false;
-                }
-                else if (cfgName == 'valueFormat') {
-                  var val = attrValue.split('.');
-
-                  if (val.length == 2) {
-                    attrValue = {
-                      'int': parseInt(val[0], 10),
-                      'dec': parseInt(val[1], 10)
-                    }
-                  }
-                  else {
-                    continue;
-                  }
-                }
-
-                config[cfgName] = attrValue;
-                break;
-              }
-            }
-          }
-        }
-
-        var g = new Gauge(config);
-
-        if (gauge.getAttribute('data-value')) {
-          g.setRawValue(parseFloat(gauge.getAttribute('data-value')));
-        }
-
-        if (gauge.getAttribute('data-onready')) {
-          g.onready = function () {
-            eval(this.config.renderTo.getAttribute('data-onready'));
-          };
-        }
-
-        g.draw();
-      }
-    }
-  });
-module.exports = Gauge;
-  // window['Gauge'] = Gauge;
-
-// })(window);
diff --git a/skyquake/framework/style/core.css b/skyquake/framework/style/core.css
index 2a64a8c..8183eab 100644
--- a/skyquake/framework/style/core.css
+++ b/skyquake/framework/style/core.css
@@ -15,7 +15,9 @@
  *   limitations under the License.
  *
  */
-@import "./vendor/css-reset-2.0/css-reset.css";
+/*@import "./vendor/css-reset-2.0/css-reset.css";*/
+@import "../../node_modules/reset-css/reset.css";
+
 .has-drop-shadow {
     box-shadow: 2px 2px rgba(0, 0, 0, .15)
 }
diff --git a/skyquake/framework/widgets/components.js b/skyquake/framework/widgets/components.js
index 1fe49bc..f38719a 100644
--- a/skyquake/framework/widgets/components.js
+++ b/skyquake/framework/widgets/components.js
@@ -26,7 +26,7 @@
 //  Histogram: Histogram,
   Multicomponent: require('./multicomponent/multicomponent.js'),
   Mixins: require('./mixins/ButtonEventListener.js'),
-  Gauge: require('./gauge/gauge.js'),
+  // Gauge: require('./gauge/gauge.js'),
   Bullet: require('./bullet/bullet.js')
 };
 
diff --git a/skyquake/framework/widgets/gauge/gauge.js b/skyquake/framework/widgets/gauge/gauge.js
deleted file mode 100644
index dc1a083..0000000
--- a/skyquake/framework/widgets/gauge/gauge.js
+++ /dev/null
@@ -1,275 +0,0 @@
-
-/*
- * 
- *   Copyright 2016 RIFT.IO Inc
- *
- *   Licensed under the Apache License, Version 2.0 (the "License");
- *   you may not use this file except in compliance with the License.
- *   You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *   Unless required by applicable law or agreed to in writing, software
- *   distributed under the License is distributed on an "AS IS" BASIS,
- *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *   See the License for the specific language governing permissions and
- *   limitations under the License.
- *
- */
-var React = require("react");
-var ReactDOM = require('react-dom');
-var MIXINS = require("../mixins/ButtonEventListener.js");
-var Gauge = require("../../js/gauge-modified.js");
-var GUID = require("utils/guid");
-import _ from 'underscore'
-
-
-
-
-/**
- *  Gauge Component
- *  It's props values and a brief description below
- *
- *  min:         minimum value expected
- *  max:         maximum value expected
- *  width:       width of gauge in px
- *  height:      height of gauge in px
- *  value:       the number displayed on the gauge
- *  resize:      should the gauge resize with container
- *  unit:        the units displayed on the gauge
- *  valueFormat: An object with an 'int' and 'dec' property. The 'int' is the min number of integer digits displayed
- *                 and the 'dec' object is the min number of fractional digits displayed.
- *
- *
- **/
-module.exports = React.createClass({
-  displayName: 'Gauge',
-  mixins:MIXINS,
-  propTypes: {
-    min:           React.PropTypes.number,
-    max:           React.PropTypes.number,
-    width:         React.PropTypes.number,
-    height:        React.PropTypes.string,
-    value:         React.PropTypes.number,
-    resize:        React.PropTypes.bool,
-    isAggregate:   React.PropTypes.bool,
-    units:         React.PropTypes.string,
-    valueFormat:   React.PropTypes.shape({
-      'int':         React.PropTypes.number,
-      'dec':         React.PropTypes.number
-    })
-  },
-  clone: function(obj) {
-      if (null == obj || "object" != typeof obj) return obj;
-      var copy = obj.constructor();
-      for (var attr in obj) {
-          if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
-      }
-      return copy;
-  },
-
-  /**
-   * Defines default state.
-   *
-   *  min:         minimum value expected
-   *  max:         maximum value expected
-   *  nSteps:      fixed number for now. The number of ticks in the gauge.
-   *  width:       width of gauge in px
-   *  height:      height of gauge in px
-   *  value:       the number displayed on the gauge
-   *  resize:      should the gauge resize with container
-   *  unit:        the units displayed on the gauge
-   *  valueFormat: An object with an 'int' and 'dec' property. The 'int' is the min number of integer digits displayed
-   *                 and the 'dec' object is the min number of fractional digits displayed.
-   */
-  getInitialState: function() {
-    var valueFormatState = null
-    this.gauge = null;
-    this.gaugeID = GUID();
-    if (!this.props.valueFormat) {
-        if ((this.props.max && this.props.max > 1000) || this.props.value) {
-            valueFormatState = {
-                "int": 1,
-                "dec": 0
-            };
-        } else {
-            valueFormatState = {
-                "int": 1,
-                "dec": 2
-            };
-        }
-    } else {
-      valueFormatState = this.props.valueFormat;
-    }
-    return {
-      //sizeOfButton:   this.props.size || '',  //There is no Medium value in CSS, default size is the absence of a value
-      min: this.props.min || 0,
-      max: this.props.max || 0,
-      nSteps: 14,
-      height: this.props.height || 200,
-      width: this.props.width || 200,
-      color: this.props.color || 'hsla(212, 57%, 50%, 1)',
-      value: this.props.value || 0,
-      valueFormat: valueFormatState,
-      isAggregate: this.props.isAggregate || false,
-      units: this.props.units || '',
-      resize:this.props.resize || false
-
-    }
-  },
-
-
-  /**
-   *  Called when props are changed.  Syncs props with state.
-   */
-  componentWillReceiveProps: function(nextProps) {
-    this.setState({
-      max:nextProps.max || this.state.max,
-      value:nextProps.value || 0,
-      valueFormat:nextProps.valueFormat || this.state.valueFormat
-    });
-  },
-
-  /**
-   * Calls the render on the gauge object once the component first mounts
-   */
-  componentDidMount: function() {
-    this.canvasRender(this.state);
-  },
-
-  /**
-   * If any of the state variables have changed, the component should update.
-   * Note, this is where the render step occures for the gauge object.
-   */
-  shouldComponentUpdate: function(nextProps, nextState) {
-    var currentStateString = String(this.state.max) + String(this.state.valueFormat.int) + String(this.state.valueFormat.dec) + String(this.state.value);
-    var nextStateString = String(nextState.max) + String(nextState.valueFormat.int) + String(nextState.valueFormat.dec) + String(nextState.value);
-    if (currentStateString == nextStateString) {
-      return false;
-    }
-    this.state.valueFormat = this.determineValueFormat(nextState.value);
-    this.canvasRender(nextState);
-    return true;
-  },
-
-  /**
-   * Default value format based on units.
-   */
-  determineValueFormat: function(value) {
-          if (value > 999 || this.state.units == "%") {
-              return {
-                  "int": 1,
-                  "dec": 0
-              }
-          }
-
-          return {
-              "int": 1,
-              "dec": 2
-          }
-      },
-
-
-  /**
-   * Render step for the gauge object. Sets some defaults, passes some of the component's state down.
-   */
-  canvasRender: function(state) {
-    if (state.max == state.min) {
-        state.max = 14;
-    }
-    var range = state.max - state.min;
-    var step = Math.round(range / state.nSteps);
-    var majorTicks = [];
-    for (var i = 0; i <= state.nSteps; i++) {
-        majorTicks.push(state.min + (i * step));
-    }
-    var redLine = state.min + (range * 0.9);
-    var config = {
-        isAggregate: state.isAggregate,
-        renderTo: ReactDOM.findDOMNode(document.getElementById(this.gaugeID)),
-        width: state.width,
-        height: state.height,
-        glow: false,
-        units: state.units,
-        title: false,
-        minValue: state.min,
-        maxValue: state.max,
-        majorTicks: majorTicks,
-        valueFormat: this.determineValueFormat(self.value),
-        minorTicks: 0,
-        strokeTicks: false,
-        highlights: [],
-        colors: {
-            plate: 'rgba(0,0,0,0)',
-            majorTicks: 'rgba(15, 123, 182, .84)',
-            minorTicks: '#ccc',
-            title: 'rgba(50,50,50,100)',
-            units: 'rgba(50,50,50,100)',
-            numbers: '#fff',
-            needle: {
-                start: 'rgba(255, 255, 255, 1)',
-                end: 'rgba(255, 255, 255, 1)'
-            }
-        }
-    };
-
-    var min = config.minValue;
-    var max = config.maxValue;
-    var N = 1000;
-    var increment = (max - min) / N;
-    for (i = 0; i < N; i++) {
-        var temp_color = 'rgb(0, 172, 238)';
-        if (i > 0.5714 * N && i <= 0.6428 * N) {
-            temp_color = 'rgb(0,157,217)';
-        } else if (i >= 0.6428 * N && i < 0.7142 * N) {
-            temp_color = 'rgb(0,142,196)';
-        } else if (i >= 0.7142 * N && i < 0.7857 * N) {
-            temp_color = 'rgb(0,126,175)';
-        } else if (i >= 0.7857 * N && i < 0.8571 * N) {
-            temp_color = 'rgb(0,122,154)';
-        } else if (i >= 0.8571 * N && i < 0.9285 * N) {
-            temp_color = 'rgb(0,96,133)';
-        } else if (i >= 0.9285 * N) {
-            temp_color = 'rgb(0,80,112)';
-        }
-        config.highlights.push({
-            from: i * increment,
-            to: increment * (i + 2),
-            color: temp_color
-        })
-    }
-    var updateSize = _.debounce(function() {
-        config.maxValue = state.max;
-    }, 500);
-    if (state.resize) $(window).resize(updateSize)
-
-    if (this.gauge) {
-        this.gauge.setValue(Math.ceil(state.value* 100) / 100)
-        this.gauge.updateConfig(config);
-    } else {
-        this.gauge = new Gauge(config);
-        this.gauge.setValue(Math.ceil(state.value* 100) / 100)
-        this.gauge.draw();
-    }
-  },
-
-  /**
-   * Renders the Gauge Component
-   * Returns the canvas element the gauge will be housed in.
-   * @returns {*}
-   */
-  render: function() {
-    var gaugeDOM = React.createElement("div", null,
-      React.createElement("canvas",
-        {className: "rwgauge", style:
-          {width:'100%','maxWidth':this.state.width + 'px','maxHeight':this.state.width},
-          id:this.gaugeID
-        }
-      )
-    )
-
-
-
-    return gaugeDOM;
-  }
-});
diff --git a/skyquake/framework/widgets/input-range-slider/react-rangeslider.jsx b/skyquake/framework/widgets/input-range-slider/react-rangeslider.jsx
deleted file mode 100644
index feff1eb..0000000
--- a/skyquake/framework/widgets/input-range-slider/react-rangeslider.jsx
+++ /dev/null
@@ -1,251 +0,0 @@
-
-/*
- * 
- *   Copyright 2016 RIFT.IO Inc
- *
- *   Licensed under the Apache License, Version 2.0 (the "License");
- *   you may not use this file except in compliance with the License.
- *   You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *   Unless required by applicable law or agreed to in writing, software
- *   distributed under the License is distributed on an "AS IS" BASIS,
- *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *   See the License for the specific language governing permissions and
- *   limitations under the License.
- *
- */
-/**
- * https://github.com/larsmaultsby/react-rangeslider
- *
- *
- * Forked from: https://github.com/whoisandie/react-rangeslider
- *
- *
-    The MIT License (MIT)
-
-    Copyright (c) 2015 Bhargav Anand
-
-    Permission is hereby granted, free of charge, to any person obtaining a copy
-    of this software and associated documentation files (the "Software"), to deal
-    in the Software without restriction, including without limitation the rights
-    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-    copies of the Software, and to permit persons to whom the Software is
-    furnished to do so, subject to the following conditions:
-
-    The above copyright notice and this permission notice shall be included in all
-    copies or substantial portions of the Software.
-
-    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-    SOFTWARE.
- *
- */
-
-import React, { PropTypes, Component, findDOMNode } from 'react';
-import joinClasses from 'react/lib/joinClasses';
-
-function capitalize(str) {
-  return str.charAt(0).toUpperCase() + str.substr(1);
-}
-
-function maxmin(pos, min, max) {
-  if (pos < min) { return min; }
-  if (pos > max) { return max; }
-  return pos;
-}
-
-const constants = {
-  orientation: {
-    horizontal: {
-      dimension: 'width',
-      direction: 'left',
-      coordinate: 'x',
-    },
-    vertical: {
-      dimension: 'height',
-      direction: 'top',
-      coordinate: 'y',
-    }
-  }
-};
-
-class Slider extends Component {
-  static propTypes = {
-    min: PropTypes.number,
-    max: PropTypes.number,
-    step: PropTypes.number,
-    value: PropTypes.number,
-    orientation: PropTypes.string,
-    onChange: PropTypes.func,
-    className: PropTypes.string,
-  }
-
-  static defaultProps = {
-    min: 0,
-    max: 100,
-    step: 1,
-    value: 0,
-    orientation: 'horizontal',
-  }
-
-  state = {
-    limit: 0,
-    grab: 0
-  }
-
-  // Add window resize event listener here
-  componentDidMount() {
-    this.calculateDimensions();
-    window.addEventListener('resize', this.calculateDimensions);
-  }
-
-  componentWillUnmount() {
-    window.removeEventListener('resize', this.calculateDimensions);
-  }
-
-  handleSliderMouseDown = (e) => {
-    let value, { onChange } = this.props;
-    if (!onChange) return;
-    value = this.position(e);
-    onChange && onChange(value);
-  }
-
-  handleKnobMouseDown = () => {
-    document.addEventListener('mousemove', this.handleDrag);
-    document.addEventListener('mouseup', this.handleDragEnd);
-  }
-
-  handleDrag = (e) => {
-    let value, { onChange } = this.props;
-    if (!onChange) return;
-    value = this.position(e);
-    onChange && onChange(value);
-  }
-
-  handleDragEnd = () => {
-    document.removeEventListener('mousemove', this.handleDrag);
-    document.removeEventListener('mouseup', this.handleDragEnd);
-  }
-
-  handleNoop = (e) => {
-    e.stopPropagation();
-    e.preventDefault();
-  }
-
-  calculateDimensions = () => {
-    let { orientation } = this.props;
-    let dimension = capitalize(constants.orientation[orientation].dimension);
-    const sliderPos = findDOMNode(this.refs.slider)['offset' + dimension];
-    const handlePos = findDOMNode(this.refs.handle)['offset' + dimension]
-    this.setState({
-      limit: sliderPos - handlePos,
-      grab: handlePos / 2,
-    });
-  }
-  getPositionFromValue = (value) => {
-    let percentage, pos;
-    let { limit } = this.state;
-    let { min, max } = this.props;
-    percentage = (value - min) / (max - min);
-    pos = Math.round(percentage * limit);
-
-    return pos;
-  }
-
-  getValueFromPosition = (pos) => {
-    let percentage, value;
-    let { limit } = this.state;
-    let { orientation, min, max, step } = this.props;
-    percentage = (maxmin(pos, 0, limit) / (limit || 1));
-
-    if (orientation === 'horizontal') {
-      value = step * Math.round(percentage * (max - min) / step) + min;
-    } else {
-      value = max - (step * Math.round(percentage * (max - min) / step) + min);
-    }
-
-    return value;
-  }
-
-  position = (e) => {
-    let pos, value, { grab } = this.state;
-    let { orientation } = this.props;
-    const node = findDOMNode(this.refs.slider);
-    const coordinateStyle = constants.orientation[orientation].coordinate;
-    const directionStyle = constants.orientation[orientation].direction;
-    const coordinate = e['client' + capitalize(coordinateStyle)];
-    const direction = node.getBoundingClientRect()[directionStyle];
-
-    pos = coordinate - direction - grab;
-    value = this.getValueFromPosition(pos);
-
-    return value;
-  }
-
-  coordinates = (pos) => {
-    let value, fillPos, handlePos;
-    let { limit, grab } = this.state;
-    let { orientation } = this.props;
-    value = this.getValueFromPosition(pos);
-    handlePos = this.getPositionFromValue(value);
-
-    if (orientation === 'horizontal') {
-      fillPos = handlePos + grab;
-    } else {
-      fillPos = limit - handlePos + grab;
-    }
-
-    return {
-      fill: fillPos,
-      handle: handlePos,
-    };
-  }
-
-  render() {
-    let dimension, direction, position, coords, fillStyle, handleStyle, displayValue;
-    let { value, orientation, className } = this.props;
-
-    dimension = constants.orientation[orientation].dimension;
-    direction = constants.orientation[orientation].direction;
-
-    position = this.getPositionFromValue(value);
-    coords = this.coordinates(position);
-
-    fillStyle = {[dimension]: `${coords.fill}px`};
-    handleStyle = {[direction]: `${coords.handle}px`};
-
-    if(this.props.displayValue) {
-      displayValue = <div>{this.props.value}</div>;
-    }
-
-    return (
-      <div
-        ref="slider"
-        className={joinClasses('rangeslider ', 'rangeslider-' + orientation, className)}
-        onMouseDown={this.handleSliderMouseDown}
-        onClick={this.handleNoop}
-        style={{display:'flex'}}>
-        <div
-          ref="fill"
-          className="rangeslider__fill"
-          style={fillStyle} />
-        <div
-          ref="handle"
-          className="rangeslider__handle"
-          onMouseDown={this.handleKnobMouseDown}
-          onClick={this.handleNoop}
-          style={handleStyle}>
-            {displayValue}
-          </div>
-      </div>
-    );
-  }
-}
-
-export default Slider;
