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;
diff --git a/skyquake/package.json b/skyquake/package.json
index 1ea4db2..8578562 100644
--- a/skyquake/package.json
+++ b/skyquake/package.json
@@ -39,6 +39,7 @@
     "request-promise": "^3.0.0",
     "require-json": "0.0.1",
     "require-reload": "^0.2.2",
+    "reset-css": "^2.0.20160720",
     "sockjs": "^0.3.17",
     "sockjs-client": "^1.1.1",
     "underscore": "^1.8.3",
diff --git a/skyquake/plugins/composer/src/schemas/yang/confd2model.js b/skyquake/plugins/composer/src/schemas/yang/confd2model.js
index ecaddf4..0362a38 100644
--- a/skyquake/plugins/composer/src/schemas/yang/confd2model.js
+++ b/skyquake/plugins/composer/src/schemas/yang/confd2model.js
@@ -1,245 +1,245 @@
-/*
- * 
- *   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.
- *
- */
+// /*
+//  * 
+//  *   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.
+//  *
+//  */
 
-'use strict';
+// 'use strict';
 
-// the models to be transformed into the output DSL JSON meta file
-var yang = [require('./json-nsd.json'), require('./json-vnfd.json')];
+// // the models to be transformed into the output DSL JSON meta file
+// var yang = [require('./json-nsd.json'), require('./json-vnfd.json')];
 
-var _ = require('lodash');
-var inet = require('./ietf-inet-types.yang.json');
+// var _ = require('lodash');
+// var inet = require('./ietf-inet-types.yang.json');
 
-var utils = {
-	resolvePath(obj, path) {
-		// supports a.b, a[1] and foo[bar], etc.
-		// where obj is ['nope', 'yes', {a: {b: 1}, foo: 2}]
-		// then [1] returns 'yes'; [2].a.b returns 1; [2].a[foo] returns 2;
-		path = path.split(/[\.\[\]]/).filter(d => d);
-		return path.reduce((r, p) => {
-			if (r) {
-				return r[p];
-			}
-		}, obj);
-	},
-	assignPathValue(obj, path, value) {
-		path = path.split(/[\.\[\]]/).filter(d => d);
-		// enable look-ahead to determine if type is array or object
-		const pathCopy = path.slice();
-		// last item in path used to assign value on the resolved object
-		const name = path.pop();
-		const resolvedObj = path.reduce((r, p, i) => {
-			if (typeof(r[p]) !== 'object') {
-				// look-ahead to see if next path item is a number
-				const isArray = !isNaN(parseInt(pathCopy[i + 1], 10));
-				r[p] = isArray ? [] : {}
-			}
-			return r[p];
-		}, obj);
-		resolvedObj[name] = value;
-	}
-};
+// var utils = {
+// 	resolvePath(obj, path) {
+// 		// supports a.b, a[1] and foo[bar], etc.
+// 		// where obj is ['nope', 'yes', {a: {b: 1}, foo: 2}]
+// 		// then [1] returns 'yes'; [2].a.b returns 1; [2].a[foo] returns 2;
+// 		path = path.split(/[\.\[\]]/).filter(d => d);
+// 		return path.reduce((r, p) => {
+// 			if (r) {
+// 				return r[p];
+// 			}
+// 		}, obj);
+// 	},
+// 	assignPathValue(obj, path, value) {
+// 		path = path.split(/[\.\[\]]/).filter(d => d);
+// 		// enable look-ahead to determine if type is array or object
+// 		const pathCopy = path.slice();
+// 		// last item in path used to assign value on the resolved object
+// 		const name = path.pop();
+// 		const resolvedObj = path.reduce((r, p, i) => {
+// 			if (typeof(r[p]) !== 'object') {
+// 				// look-ahead to see if next path item is a number
+// 				const isArray = !isNaN(parseInt(pathCopy[i + 1], 10));
+// 				r[p] = isArray ? [] : {}
+// 			}
+// 			return r[p];
+// 		}, obj);
+// 		resolvedObj[name] = value;
+// 	}
+// };
 
-var isType = d => /^(leaf|leaf-list|list|container|choice|case|uses)$/.test(d);
+// var isType = d => /^(leaf|leaf-list|list|container|choice|case|uses)$/.test(d);
 
-function deriveCardinalityFromProperty(property, typeName) {
-	if (String(property.mandatory) === 'true') {
-		return '1';
-	}
-	let min = 0, max = Infinity;
-	if (property.hasOwnProperty('min-elements')) {
-		min = parseInt(property['min-elements'], 10) || 0;
-	}
-	if (property.hasOwnProperty('max-elements')) {
-		max = parseInt(property['max-elements'], 10) || Infinity;
-	} else {
-		if (!/^(list|leaf-list)$/.test(typeName)) {
-			max = '1';
-		}
-	}
-	if (min > max) {
-		return String(min);
-	}
-	if (min === max) {
-		return String(min);
-	}
-	return String(min) + '..' + (max === Infinity ? 'N' : max);
-}
+// function deriveCardinalityFromProperty(property, typeName) {
+// 	if (String(property.mandatory) === 'true') {
+// 		return '1';
+// 	}
+// 	let min = 0, max = Infinity;
+// 	if (property.hasOwnProperty('min-elements')) {
+// 		min = parseInt(property['min-elements'], 10) || 0;
+// 	}
+// 	if (property.hasOwnProperty('max-elements')) {
+// 		max = parseInt(property['max-elements'], 10) || Infinity;
+// 	} else {
+// 		if (!/^(list|leaf-list)$/.test(typeName)) {
+// 			max = '1';
+// 		}
+// 	}
+// 	if (min > max) {
+// 		return String(min);
+// 	}
+// 	if (min === max) {
+// 		return String(min);
+// 	}
+// 	return String(min) + '..' + (max === Infinity ? 'N' : max);
+// }
 
-function cleanWhitespace(text) {
-	if (typeof text === 'string') {
-		return text.replace(/\s+/g, ' ');
-	}
-	return text;
-}
+// function cleanWhitespace(text) {
+// 	if (typeof text === 'string') {
+// 		return text.replace(/\s+/g, ' ');
+// 	}
+// 	return text;
+// }
 
-function buildProperties(typeData, typeName) {
-	var properties = [];
-	Object.keys(typeData).forEach(name => {
-		var property = typeData[name];
-		var listKey = typeName === 'list' ? String(property.key).split(/\s/).filter(k => k && k !== 'undefined') : false;
-		var meta = {
-			name: name,
-			type: typeName,
-			description: cleanWhitespace(property.description),
-			cardinality: deriveCardinalityFromProperty(property, typeName),
-			'data-type': property.type,
-			properties: Object.keys(property).filter(isType).reduce((r, childType) => {
-				return r.concat(buildProperties(property[childType], childType));
-			}, [])
-		};
-		if (listKey) {
-			meta.key = listKey;
-		}
-		properties.push(meta);
-	});
-	return properties;
-}
+// function buildProperties(typeData, typeName) {
+// 	var properties = [];
+// 	Object.keys(typeData).forEach(name => {
+// 		var property = typeData[name];
+// 		var listKey = typeName === 'list' ? String(property.key).split(/\s/).filter(k => k && k !== 'undefined') : false;
+// 		var meta = {
+// 			name: name,
+// 			type: typeName,
+// 			description: cleanWhitespace(property.description),
+// 			cardinality: deriveCardinalityFromProperty(property, typeName),
+// 			'data-type': property.type,
+// 			properties: Object.keys(property).filter(isType).reduce((r, childType) => {
+// 				return r.concat(buildProperties(property[childType], childType));
+// 			}, [])
+// 		};
+// 		if (listKey) {
+// 			meta.key = listKey;
+// 		}
+// 		properties.push(meta);
+// 	});
+// 	return properties;
+// }
 
-function lookupUses(uses, yang) {
-	function doLookup(lookupTypeName) {
-		var key;
-		// warn: hardcoded prefix support for mano-types - other prefixes will be ignored
-		if (/^manotypes:/.test(lookupTypeName)) {
-			var moduleName = lookupTypeName.split(':')[1];
-			key = ['dependencies.mano-types.module.mano-types.grouping', moduleName].join('.');
-		} else {
-			var name = yang.name.replace(/^rw-/, '');
-			key = ['dependencies', name, 'module', name, 'grouping', lookupTypeName].join('.');
-		}
-		return utils.resolvePath(yang, key);
-	}
-	if (typeof uses === 'object') {
-		return Object.keys(uses).reduce((result, key) => {
-			var found = doLookup(key);
-			Object.keys(found).filter(isType).forEach(type => {
-				var property = result[type] || (result[type] = {});
-				Object.assign(property, found[type]);
-			});
-			return result;
-		}, {});
-	} else if (typeof uses === 'string') {
-		return doLookup(uses);
-	}
-	return {};
-}
+// function lookupUses(uses, yang) {
+// 	function doLookup(lookupTypeName) {
+// 		var key;
+// 		// warn: hardcoded prefix support for mano-types - other prefixes will be ignored
+// 		if (/^manotypes:/.test(lookupTypeName)) {
+// 			var moduleName = lookupTypeName.split(':')[1];
+// 			key = ['dependencies.mano-types.module.mano-types.grouping', moduleName].join('.');
+// 		} else {
+// 			var name = yang.name.replace(/^rw-/, '');
+// 			key = ['dependencies', name, 'module', name, 'grouping', lookupTypeName].join('.');
+// 		}
+// 		return utils.resolvePath(yang, key);
+// 	}
+// 	if (typeof uses === 'object') {
+// 		return Object.keys(uses).reduce((result, key) => {
+// 			var found = doLookup(key);
+// 			Object.keys(found).filter(isType).forEach(type => {
+// 				var property = result[type] || (result[type] = {});
+// 				Object.assign(property, found[type]);
+// 			});
+// 			return result;
+// 		}, {});
+// 	} else if (typeof uses === 'string') {
+// 		return doLookup(uses);
+// 	}
+// 	return {};
+// }
 
-function lookupTypedef(property, yang) {
-	var key;
-	var lookupTypeName = property.type;
-	// warn: hardcoded prefix support - other prefixes will be ignored
-	if (/^manotypes:/.test(lookupTypeName)) {
-		var lookupName = lookupTypeName.split(':')[1];
-		key = ['dependencies.mano-types.module.mano-types.typedef', lookupName].join('.');
-	} else if (/^inet:/.test(lookupTypeName)) {
-		var lookupName = lookupTypeName.split(':')[1];
-		yang = inet;
-		key = ['schema.module.ietf-inet-types.typedef', lookupName].join('.');
-	}
-	if (key) {
-		return utils.resolvePath(yang, key);
-	}
-}
+// function lookupTypedef(property, yang) {
+// 	var key;
+// 	var lookupTypeName = property.type;
+// 	// warn: hardcoded prefix support - other prefixes will be ignored
+// 	if (/^manotypes:/.test(lookupTypeName)) {
+// 		var lookupName = lookupTypeName.split(':')[1];
+// 		key = ['dependencies.mano-types.module.mano-types.typedef', lookupName].join('.');
+// 	} else if (/^inet:/.test(lookupTypeName)) {
+// 		var lookupName = lookupTypeName.split(':')[1];
+// 		yang = inet;
+// 		key = ['schema.module.ietf-inet-types.typedef', lookupName].join('.');
+// 	}
+// 	if (key) {
+// 		return utils.resolvePath(yang, key);
+// 	}
+// }
 
-function resolveUses(property, yang) {
-	var childData = property.uses;
-	var resolved = lookupUses(childData, yang);
-	//console.log('uses', childData, 'found', resolved);
-	Object.keys(resolved).forEach(type => {
-		var parentTypes = property[type] || (property[type] = {});
-		// copy types into the parent types bucket
-		Object.assign(parentTypes, resolveReferences(yang, resolved[type]));
-	});
-	delete property.uses;
-}
+// function resolveUses(property, yang) {
+// 	var childData = property.uses;
+// 	var resolved = lookupUses(childData, yang);
+// 	//console.log('uses', childData, 'found', resolved);
+// 	Object.keys(resolved).forEach(type => {
+// 		var parentTypes = property[type] || (property[type] = {});
+// 		// copy types into the parent types bucket
+// 		Object.assign(parentTypes, resolveReferences(yang, resolved[type]));
+// 	});
+// 	delete property.uses;
+// }
 
-function resolveTypedef(property, yang) {
-	if (/:/.test(property.type)) {
-		var found = lookupTypedef(property, yang);
-		if (found) {
-			Object.assign(property, found);
-		}
-	}
-}
+// function resolveTypedef(property, yang) {
+// 	if (/:/.test(property.type)) {
+// 		var found = lookupTypedef(property, yang);
+// 		if (found) {
+// 			Object.assign(property, found);
+// 		}
+// 	}
+// }
 
-function resolveReferences(yang, data) {
-	var dataClone = _.cloneDeep(data);
-	function doResolve(typeData) {
-		Object.keys(typeData).forEach(name => {
-			var property = typeData[name];
-			resolveTypedef(property, yang);
-			Object.keys(property).filter(isType).forEach(childType => {
-				if (childType === 'uses') {
-					resolveUses(property, yang);
-				} else {
-					doResolve(property[childType]);
-				}
-			});
-		});
-	}
-	doResolve(dataClone);
-	return dataClone;
-}
+// function resolveReferences(yang, data) {
+// 	var dataClone = _.cloneDeep(data);
+// 	function doResolve(typeData) {
+// 		Object.keys(typeData).forEach(name => {
+// 			var property = typeData[name];
+// 			resolveTypedef(property, yang);
+// 			Object.keys(property).filter(isType).forEach(childType => {
+// 				if (childType === 'uses') {
+// 					resolveUses(property, yang);
+// 				} else {
+// 					doResolve(property[childType]);
+// 				}
+// 			});
+// 		});
+// 	}
+// 	doResolve(dataClone);
+// 	return dataClone;
+// }
 
-function module(yang) {
-	let module;
-	var name = yang.name.replace(/^rw-/, '');
-	if (!name) {
-		throw 'no name given in json yang';
-	}
-	const path = ['container', name + '-catalog'].join('.');
-	module = utils.resolvePath(yang, path);
+// function module(yang) {
+// 	let module;
+// 	var name = yang.name.replace(/^rw-/, '');
+// 	if (!name) {
+// 		throw 'no name given in json yang';
+// 	}
+// 	const path = ['container', name + '-catalog'].join('.');
+// 	module = utils.resolvePath(yang, path);
 
-	if (!module) {
-		module = utils.resolvePath(yang, ['schema', 'module', name, path].join('.'));
-	}
-	if (!module) {
-		module = utils.resolvePath(yang, ['dependencies', name, 'module', name, path].join('.'));
-	}
-	if (!module) {
-		throw 'cannot find the module' + name;
-	}
+// 	if (!module) {
+// 		module = utils.resolvePath(yang, ['schema', 'module', name, path].join('.'));
+// 	}
+// 	if (!module) {
+// 		module = utils.resolvePath(yang, ['dependencies', name, 'module', name, path].join('.'));
+// 	}
+// 	if (!module) {
+// 		throw 'cannot find the module' + name;
+// 	}
 
-	// module/agument/nsd:nsd-catalog/nsd:nsd/meta
-	const augLeafPath = ['schema.module', 'rw-' + name, 'augment', '/' + name + ':' + name + '-catalog/' + name + ':' + name, 'leaf'];
-	const meta = utils.resolvePath(yang, augLeafPath.concat('meta').join('.'));
+// 	// module/agument/nsd:nsd-catalog/nsd:nsd/meta
+// 	const augLeafPath = ['schema.module', 'rw-' + name, 'augment', '/' + name + ':' + name + '-catalog/' + name + ':' + name, 'leaf'];
+// 	const meta = utils.resolvePath(yang, augLeafPath.concat('meta').join('.'));
 
-	const putLeafPath = ['dependencies', name, 'module', name, path, 'list', name, 'leaf'];
+// 	const putLeafPath = ['dependencies', name, 'module', name, path, 'list', name, 'leaf'];
 
-	if (meta) {
-		utils.assignPathValue(yang, putLeafPath.concat(['meta']).join('.'), meta);
-	}
+// 	if (meta) {
+// 		utils.assignPathValue(yang, putLeafPath.concat(['meta']).join('.'), meta);
+// 	}
 
-	// module/agument/nsd:nsd-catalog/nsd:nsd/logo
-	const logo = utils.resolvePath(yang, augLeafPath.concat('logo').join('.'));
-	if (logo) {
-		utils.assignPathValue(yang, putLeafPath.concat(['logo']).join('.'), logo);
-	}
-	var data = module.list;
+// 	// module/agument/nsd:nsd-catalog/nsd:nsd/logo
+// 	const logo = utils.resolvePath(yang, augLeafPath.concat('logo').join('.'));
+// 	if (logo) {
+// 		utils.assignPathValue(yang, putLeafPath.concat(['logo']).join('.'), logo);
+// 	}
+// 	var data = module.list;
 
-	return {name: name, data: resolveReferences(yang, data)};
+// 	return {name: name, data: resolveReferences(yang, data)};
 
-}
+// }
 
-function reduceModule(result, module) {
-	result[module.name] = buildProperties(module.data, 'list')[0];
-	return result;
-}
+// function reduceModule(result, module) {
+// 	result[module.name] = buildProperties(module.data, 'list')[0];
+// 	return result;
+// }
 
-var result = yang.map(module).reduce(reduceModule, {});
+// var result = yang.map(module).reduce(reduceModule, {});
 
-console.log(JSON.stringify(result, null, 5));
+// console.log(JSON.stringify(result, null, 5));
diff --git a/skyquake/plugins/launchpad/src/monitoring_params/monitoringParamComponents.js b/skyquake/plugins/launchpad/src/monitoring_params/monitoringParamComponents.js
index 9d52bb8..2990d18 100644
--- a/skyquake/plugins/launchpad/src/monitoring_params/monitoringParamComponents.js
+++ b/skyquake/plugins/launchpad/src/monitoring_params/monitoringParamComponents.js
@@ -49,15 +49,16 @@
     //' + String((100/length) - 5) + '%'
     switch(node["widget-type"]) {
       case 'GAUGE':
-        return (
-            <div
-            className="monitoring_params_component"
-            key={prop + '-' + prop.name+ '-' + count}
-            mp={node["mp-id"]}>
-                <div>{node.name}</div>
-                <Components.default.Gauge value={node[valueProperty] || 0} min={numericConstraintsMinPresent ? node['numeric-constraints']['min-value'] : 0} max={numericConstraintsMaxPresent ? node['numeric-constraints']['max-value'] : 100} units={node['units'] || ''} />
-            </div>);
-        break;
+        // Disabled for OSM
+        // return (
+        //     <div
+        //     className="monitoring_params_component"
+        //     key={prop + '-' + prop.name+ '-' + count}
+        //     mp={node["mp-id"]}>
+        //         <div>{node.name}</div>
+        //         <Components.default.Gauge value={node[valueProperty] || 0} min={numericConstraintsMinPresent ? node['numeric-constraints']['min-value'] : 0} max={numericConstraintsMaxPresent ? node['numeric-constraints']['max-value'] : 100} units={node['units'] || ''} />
+        //     </div>);
+        // break;
       case 'TEXTBOX':
       case 'COUNTER':
         var displayValue = 0;
