You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ea...@apache.org on 2018/06/04 22:00:50 UTC

[1/3] qpid-dispatch git commit: DISPATCH-1017 Added console build.

Repository: qpid-dispatch
Updated Branches:
  refs/heads/master 43b3b2e03 -> 0310ac224


http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/0310ac22/console/stand-alone/package.json
----------------------------------------------------------------------
diff --git a/console/stand-alone/package.json b/console/stand-alone/package.json
index 23731e3..aa59f68 100644
--- a/console/stand-alone/package.json
+++ b/console/stand-alone/package.json
@@ -45,6 +45,26 @@
     "jquery.fancytree": "^2.26.0",
     "notifyjs-browser": "^0.4.2",
     "patternfly": "^3.30.0",
-    "rhea": "^0.2.10"
+    "rhea": "^0.2.13"
+  },
+  "devDependencies": {
+    "babel-core": "^6.26.3",
+    "babel-preset-env": "^1.7.0",
+    "del": "^3.0.0",
+    "fs": "0.0.1-security",
+    "gulp": "github:gulpjs/gulp#4.0",
+    "gulp-babel": "^7.0.1",
+    "gulp-clean-css": "^3.9.4",
+    "gulp-concat": "^2.6.1",
+    "gulp-eslint": "^4.0.2",
+    "gulp-insert": "^0.5.0",
+    "gulp-ng-annotate": "^2.1.0",
+    "gulp-rename": "^1.2.3",
+    "gulp-sourcemaps": "^2.6.4",
+    "gulp-tslint": "^8.1.3",
+    "gulp-typescript": "^4.0.2",
+    "gulp-uglify": "^3.0.0",
+    "tslint": "^5.10.0",
+    "typescript": "^2.9.1"
   }
 }

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/0310ac22/console/stand-alone/plugin/css/dispatch.css
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/css/dispatch.css b/console/stand-alone/plugin/css/dispatch.css
index 6478620..38495ad 100644
--- a/console/stand-alone/plugin/css/dispatch.css
+++ b/console/stand-alone/plugin/css/dispatch.css
@@ -22,7 +22,7 @@ main-display > .span8 {
 }
 
 ul.qdrListNodes > li > span {
-  padding: 6px 20px; 6px; 6px;
+  padding: 6px 20px 6px 6px;
   display: block;
 }
 

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/0310ac22/console/stand-alone/plugin/js/dispatchPlugin.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/dispatchPlugin.js b/console/stand-alone/plugin/js/dispatchPlugin.js
index c39cb9b..47c8a60 100644
--- a/console/stand-alone/plugin/js/dispatchPlugin.js
+++ b/console/stand-alone/plugin/js/dispatchPlugin.js
@@ -39,20 +39,12 @@ var QDR = (function(QDR) {
   QDR.isStandalone = true;
 
   /**
-   * @property log
-   * @type {Logging.Logger}
-   *
-   * This plugin's logger instance
-   */
-  //HIO QDR.log = Logger.get(QDR.pluginName);
-  /**
    * @property templatePath
    * @type {string}
    *
    * The top level path to this plugin's partials
    */
-  QDR.srcBase = 'plugin/';
-  QDR.templatePath = QDR.srcBase + 'html/';
+  QDR.templatePath = 'html/';
   /**
    * @property SETTINGS_KEY
    * @type {string}

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/0310ac22/console/stand-alone/plugin/js/topology/qdrTopology.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/topology/qdrTopology.js b/console/stand-alone/plugin/js/topology/qdrTopology.js
index 74ad417..15e73c4 100644
--- a/console/stand-alone/plugin/js/topology/qdrTopology.js
+++ b/console/stand-alone/plugin/js/topology/qdrTopology.js
@@ -1509,7 +1509,7 @@ var QDR = (function(QDR) {
           // add rows to the table for each link
           for (let l=0; l<links.length; l++) {
             if (l>=max_links) {
-              HTMLHeading = '<h4>Top ' + max_links + ' Links</h4>';
+              HTMLHeading = `<h4>Top ${max_links} Links</h4>`;
               break;
             }
             let link = links[l];
@@ -1523,7 +1523,7 @@ var QDR = (function(QDR) {
             let joinedVals = fnJoin(vals, function (v1) {
               return ['</td><td' + (isNaN(+v1) ? '': ' align="right"') + '>', QDRService.utilities.pretty(v1 || '0')];
             });
-            HTML += ('<tr><td>' + joinedVals + '</td></tr>');
+            HTML += `<tr><td> ${joinedVals} </td></tr>`;
           }
           HTML += '</table>';
           return HTMLHeading + HTML;

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/0310ac22/console/stand-alone/plugin/js/topology/traffic.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/topology/traffic.js b/console/stand-alone/plugin/js/topology/traffic.js
deleted file mode 100644
index e52df67..0000000
--- a/console/stand-alone/plugin/js/topology/traffic.js
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you 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';
-
-/* global d3 ChordData MIN_CHORD_THRESHOLD Promise */
-
-const transitionDuration = 1000;
-const CHORDFILTERKEY = 'chordFilter';
-
-function Traffic ($scope, $timeout, QDRService, converter, radius, topology, nextHop, type, prefix) {
-  $scope.addressColors = {};
-  this.QDRService = QDRService;
-  this.type = type; // moving dots or colored path
-  this.prefix = prefix; // url prefix used in svg url()s
-  this.topology = topology; // contains the list of router nodes
-  this.nextHop = nextHop; // fn that returns the route through the network between two routers
-  this.$scope = $scope;
-  this.$timeout = $timeout;
-  // internal variables
-  this.interval = null; // setInterval handle
-  this.setAnimationType(type, converter, radius);
-}
-
-// stop updating the traffic data
-Traffic.prototype.stop = function () {
-  if (this.interval) {
-    clearInterval(this.interval);
-    this.interval = null;
-  }
-};
-// start updating the traffic data
-Traffic.prototype.start = function () {
-  this.doUpdate();
-  this.interval = setInterval(this.doUpdate.bind(this), transitionDuration);
-};
-// remove any animations that are in progress
-Traffic.prototype.remove = function() {
-  if (this.vis)
-    this.vis.remove();
-};
-// called when one of the address checkboxes is toggled
-Traffic.prototype.setAnimationType = function (type, converter, radius) {
-  this.stop();
-  this.remove();
-  this.type = type;
-  this.vis = type === 'dots' ? new Dots(this, converter, radius) :
-    new Congestion(this);
-};
-// called periodically to refresh the traffic flow
-Traffic.prototype.doUpdate = function () {
-  this.vis.doUpdate();
-};
-
-/* Base class for congestion and dots visualizations */
-function TrafficAnimation (traffic) {
-  this.traffic = traffic;
-}
-TrafficAnimation.prototype.nodeIndexFor = function (nodes, name) {
-  for (let i=0; i<nodes.length; i++) {
-    let node = nodes[i];
-    if (node.container === name)
-      return i;
-  }
-  return -1;
-};
-
-/* Color the links between router to show how heavily used the links are. */
-function Congestion (traffic) {
-  TrafficAnimation.call(this, traffic);
-  this.init_markerDef();
-}
-Congestion.prototype = Object.create(TrafficAnimation.prototype);
-Congestion.prototype.constructor = Congestion;
-
-Congestion.prototype.init_markerDef = function () {
-  this.custom_markers_def = d3.select('#SVG_ID').select('defs.custom-markers');
-  if (this.custom_markers_def.empty()) {
-    this.custom_markers_def = d3.select('#SVG_ID').append('svg:defs').attr('class', 'custom-markers');
-  }
-};
-Congestion.prototype.findResult = function (node, entity, attribute, value) {
-  let attrIndex = node[entity].attributeNames.indexOf(attribute);
-  if (attrIndex >= 0) {
-    for (let i=0; i<node[entity].results.length; i++) {
-      if (node[entity].results[i][attrIndex] === value) {
-        return this.traffic.QDRService.utilities.flatten(node[entity].attributeNames, node[entity].results[i]);
-      }
-    }
-  }
-  return null;
-};
-Congestion.prototype.doUpdate = function () {
-  let self = this;
-  this.traffic.QDRService.management.topology.ensureAllEntities(
-    [{ entity: 'router.link', force: true},{entity: 'connection'}], function () {
-      let links = {};
-      let nodeInfo = self.traffic.QDRService.management.topology.nodeInfo();
-      // accumulate all the inter-router links in an object
-      // keyed by the svgs path id
-      for (let nodeId in nodeInfo) {
-        let node = nodeInfo[nodeId];
-        let nodeLinks = node['router.link'];
-        for (let n=0; n<nodeLinks.results.length; n++) {
-          let link = self.traffic.QDRService.utilities.flatten(nodeLinks.attributeNames, nodeLinks.results[n]);
-          if (link.linkType !== 'router-control') {
-            let f = self.nodeIndexFor(self.traffic.topology.nodes, 
-              self.traffic.QDRService.management.topology.nameFromId(nodeId));
-            let connection = self.findResult(node, 'connection', 'identity', link.connectionId);
-            if (connection) {
-              let t = self.nodeIndexFor(self.traffic.topology.nodes, connection.container);
-              let little = Math.min(f, t);
-              let big = Math.max(f, t);
-              let key = ['#path', little, big].join('-');
-              if (!links[key])
-                links[key] = [];
-              links[key].push(link);
-            }
-          }
-        }
-      }
-      // accumulate the colors/directions to be used
-      let colors = {};
-      for (let key in links) {
-        let congestion = self.congestion(links[key]);
-        let path = d3.select(key);
-        if (path && !path.empty()) {
-          let dir = path.attr('marker-end') === '' ? 'start' : 'end';
-          let small = path.attr('class').indexOf('small') > -1;
-          let id = dir + '-' + congestion.substr(1) + (small ? '-s' : '');
-          colors[id] = {dir: dir, color: congestion, small: small};
-          path
-            .attr('stroke', congestion)
-            .classed('traffic', true)
-            .attr('marker-start', function(d) {
-              return d.left ? 'url(' + self.traffic.prefix + '#' + id + ')' : '';
-            })
-            .attr('marker-end', function(d) {
-              return d.right ? 'url(' + self.traffic.prefix + '#' + id + ')' : '';
-            });
-        }
-      }
-
-      // create the svg:def that holds the custom markers
-      self.init_markerDef();
-
-      let colorKeys = Object.keys(colors);
-      let custom_markers = self.custom_markers_def.selectAll('marker')
-        .data(colorKeys, function (d) {return d;});
-
-      custom_markers.enter().append('svg:marker')
-        .attr('id', function (d) { return d; })
-        .attr('viewBox', '0 -5 10 10')
-        .attr('refX', function (d) {
-          return colors[d].dir === 'end' ? 24 : (colors[d].small) ? -24 : -14;
-        })
-        .attr('markerWidth', 4)
-        .attr('markerHeight', 4)
-        .attr('orient', 'auto')
-        .style('fill', function (d) {return colors[d].color;})
-        .append('svg:path')
-        .attr('d', function (d) {
-          return colors[d].dir === 'end' ? 'M 0 -5 L 10 0 L 0 5 z' : 'M 10 -5 L 0 0 L 10 5 z';
-        });
-      custom_markers.exit().remove();
-
-    });
-};
-Congestion.prototype.congestion = function (links) {
-  let v = 0;
-  for (let l=0; l<links.length; l++) {
-    let link = links[l];
-    v = Math.max(v, (link.undeliveredCount+link.unsettledCount)/link.capacity);
-  }
-  return this.fillColor(v);
-};
-Congestion.prototype.fillColor = function (v) {
-  let color = d3.scale.linear().domain([0, 1, 2, 3])
-    .interpolate(d3.interpolateHcl)
-    .range([d3.rgb('#CCCCCC'), d3.rgb('#00FF00'), d3.rgb('#FFA500'), d3.rgb('#FF0000')]);
-  return color(v);
-};
-Congestion.prototype.remove = function () {
-  d3.select('#SVG_ID').selectAll('path.traffic')
-    .classed('traffic', false);
-  d3.select('#SVG_ID').select('defs.custom-markers')
-    .selectAll('marker').remove();
-};
-
-/* Create animated dots moving along the links between routers
-   to show message flow */
-function Dots (traffic, converter, radius) {
-  TrafficAnimation.call(this, traffic);
-  this.excludedAddresses = localStorage[CHORDFILTERKEY] ? JSON.parse(localStorage[CHORDFILTERKEY]) : [];
-  this.radius = radius; // the radius of a router circle
-  this.lastFlows = {}; // the number of dots animated between routers
-  this.chordData = new ChordData(this.traffic.QDRService, true, converter); // gets ingressHistogram data
-  this.chordData.setFilter(this.excludedAddresses);
-  traffic.$scope.addresses = {};
-  this.chordData.getMatrix().then(function () {
-    this.traffic.$timeout(function () {
-      this.traffic.$scope.addresses = this.chordData.getAddresses();
-      for (let address in this.traffic.$scope.addresses) {
-        this.fillColor(address);
-      }
-    }.bind(this));
-  }.bind(this));
-  // colors
-  this.colorGen = d3.scale.category10();
-  let self = this;
-  // event notification that an address checkbox has changed
-  traffic.$scope.addressFilterChanged = function () {
-    self.updateAddresses()
-      .then(function () {
-      // don't wait for the next polling cycle. update now
-        self.traffic.stop();
-        self.traffic.start();
-      });
-  };
-  // called by angular when mouse enters one of the address legends
-  traffic.$scope.enterLegend = function (address) {
-    // fade all flows that aren't for this address
-    self.fadeOtherAddresses(address);
-  };
-  // called when the mouse leaves one of the address legends
-  traffic.$scope.leaveLegend = function () {
-    self.unFadeAll();
-  };
-  // clicked on the address name. toggle the address checkbox
-  traffic.$scope.addressClick = function (address) {
-    self.toggleAddress(address)
-      .then(function () {
-        self.updateAddresses();
-      });
-  };
-}
-Dots.prototype = Object.create(TrafficAnimation.prototype);
-Dots.prototype.constructor = Dots;
-
-Dots.prototype.remove = function () {
-  for (let id in this.lastFlows) {
-    d3.select('#SVG_ID').selectAll('circle.flow' + id).remove();
-  }
-  this.lastFlows = {};
-};
-Dots.prototype.updateAddresses = function () {
-  this.excludedAddresses = [];
-  for (let address in this.traffic.$scope.addresses) {
-    if (!this.traffic.$scope.addresses[address])
-      this.excludedAddresses.push(address);
-  }
-  localStorage[CHORDFILTERKEY] = JSON.stringify(this.excludedAddresses);
-  if (this.chordData)
-    this.chordData.setFilter(this.excludedAddresses);
-  return new Promise(function (resolve) {
-    return resolve();
-  });
-};
-Dots.prototype.toggleAddress = function (address) {
-  this.traffic.$scope.addresses[address] = !this.traffic.$scope.addresses[address];
-  return new Promise(function (resolve) {
-    return resolve();
-  });
-};
-Dots.prototype.fadeOtherAddresses = function (address) {
-  d3.selectAll('circle.flow').classed('fade', function (d) {
-    return d.address !== address;
-  });
-};
-Dots.prototype.unFadeAll = function () {
-  d3.selectAll('circle.flow').classed('fade', false);
-};
-Dots.prototype.doUpdate = function () {
-  let self = this;
-  // we need the nextHop data to show traffic between routers that are connected by intermediaries
-  this.traffic.QDRService.management.topology.ensureAllEntities([{ entity: 'router.node', attrs: ['id', 'nextHop'] }], function () {
-    // get the ingressHistogram data for all routers
-    self.chordData.getMatrix().then(self.render.bind(self), function (e) {
-      console.log('Could not get message histogram' + e);
-    });
-  });
-};
-Dots.prototype.render = function (matrix) {
-  this.traffic.$timeout(function () {
-    this.traffic.$scope.addresses = this.chordData.getAddresses();
-  }.bind(this));
-  // get the rate of message flow between routers
-  let hops = {}; // every hop between routers that is involved in message flow
-  let matrixMessages = matrix.matrixMessages();
-  // the fastest traffic rate gets 3 times as many dots as the slowest
-  let minmax = matrix.getMinMax();
-  let flowScale = d3.scale.linear().domain(minmax).range([1, 1.75]);
-  // row is ingress router, col is egress router. Value at [row][col] is the rate
-  matrixMessages.forEach(function (row, r) {
-    row.forEach(function (val, c) {
-      if (val > MIN_CHORD_THRESHOLD) {
-        // translate between matrix row/col and node index
-        let f = this.nodeIndexFor(this.traffic.topology.nodes, matrix.rows[r].egress);
-        let t = this.nodeIndexFor(this.traffic.topology.nodes, matrix.rows[r].ingress);
-        let address = matrix.getAddress(r, c);
-        if (r !== c) {
-          // accumulate the hops between the ingress and egress routers
-          this.traffic.nextHop(this.traffic.topology.nodes[f], this.traffic.topology.nodes[t], function (link, fnode, tnode) {
-            let key = '-' + link.uid;
-            let back = fnode.index < tnode.index;
-            if (!hops[key])
-              hops[key] = [];
-            hops[key].push({ val: val, back: back, address: address });
-          });
-        }
-        // Find the senders connected to nodes[f] and the receivers connected to nodes[t]
-        // and add their links to the animation
-        this.addClients(hops, this.traffic.topology.nodes, f, val, true, address);
-        this.addClients(hops, this.traffic.topology.nodes, t, val, false, address);
-      }
-    }.bind(this));
-  }.bind(this));
-  // for each link between routers that has traffic, start an animation
-  let keep = {};
-  for (let id in hops) {
-    let hop = hops[id];
-    for (let h = 0; h < hop.length; h++) {
-      let ahop = hop[h];
-      let flowId = id + '-' + this.addressIndex(this, ahop.address) + (ahop.back ? 'b' : '');
-      let path = d3.select('#path' + id);
-      // start the animation. If the animation is already running, this will have no effect
-      this.startAnimation(path, flowId, ahop, flowScale(ahop.val));
-      keep[flowId] = true;
-    }
-  }
-  // remove any existing animations that we don't have data for anymore
-  for (let id in this.lastFlows) {
-    if (this.lastFlows[id] && !keep[id]) {
-      this.lastFlows[id] = 0;
-      d3.select('#SVG_ID').selectAll('circle.flow' + id).remove();
-    }
-  }
-};
-// animate the d3 selection (flow) along the given path
-Dots.prototype.animateFlow = function (flow, path, count, back, rate) {
-  let self = this;
-  let l = path.node().getTotalLength();
-  flow.transition()
-    .ease('easeLinear')
-    .duration(l * 10 / rate)
-    .attrTween('transform', self.translateDots(self.radius, path, count, back))
-    .each('end', function () { self.animateFlow(flow, path, count, back, rate); });
-};
-// create dots along the path between routers
-Dots.prototype.startAnimation = function (path, id, hop, rate) {
-  if (!path.node())
-    return;
-  this.animateDots(path, id, hop, rate);
-};
-Dots.prototype.animateDots = function (path, id, hop, rate) {
-  let back = hop.back, address = hop.address;
-  // the density of dots is determined by the rate of this traffic relative to the other traffic
-  let len = Math.max(Math.floor(path.node().getTotalLength() / 50), 1);
-  let dots = [];
-  for (let i = 0, offset = this.addressIndex(this, address); i < len; ++i) {
-    dots[i] = { i: i + 10 * offset, address: address };
-  }
-  // keep track of the number of dots for each link. If the length of the link is changed,
-  // re-create the animation
-  if (!this.lastFlows[id])
-    this.lastFlows[id] = len;
-  else {
-    if (this.lastFlows[id] !== len) {
-      this.lastFlows[id] = len;
-      d3.select('#SVG_ID').selectAll('circle.flow' + id).remove();
-    }
-  }
-  let flow = d3.select('#SVG_ID').selectAll('circle.flow' + id)
-    .data(dots, function (d) { return d.i + d.address; });
-  let circles = flow
-    .enter().append('circle')
-    .attr('class', 'flow flow' + id)
-    .attr('fill', this.fillColor(address))
-    .attr('r', 5);
-  this.animateFlow(circles, path, dots.length, back, rate);
-  flow.exit()
-    .remove();
-};
-Dots.prototype.fillColor = function (n) {
-  if (!(n in this.traffic.$scope.addressColors)) {
-    let ci = Object.keys(this.traffic.$scope.addressColors).length;
-    this.traffic.$scope.addressColors[n] = this.colorGen(ci);
-  }
-  return this.traffic.$scope.addressColors[n];
-};
-Dots.prototype.addClients = function (hops, nodes, f, val, sender, address) {
-  let cdir = sender ? 'out' : 'in';
-  for (let n=0; n<nodes.length; n++) {
-    let node = nodes[n];
-    if (node.normals && node.key === nodes[f].key && node.cdir === cdir) {
-      let key = ['',f,n].join('-');
-      if (!hops[key])
-        hops[key] = [];
-      hops[key].push({val: val, back: node.cdir === 'in', address: address});
-      return;
-    }
-  }
-};
-Dots.prototype.addressIndex = function (vis, address) {
-  return Object.keys(vis.traffic.$scope.addresses).indexOf(address);
-};
-// calculate the translation for each dot along the path
-Dots.prototype.translateDots = function (radius, path, count, back) {
-  let pnode = path.node();
-  // will be called for each element in the flow selection (for each dot)
-  return function(d) {
-    // will be called with t going from 0 to 1 for each dot
-    return function(t) {
-      // start the points at different positions depending on their value (d)
-      let tt = t * 1000;
-      let f = ((tt + (d.i*1000/count)) % 1000)/1000;
-      if (back)
-        f = 1 - f;
-      // l needs to be calculated each tick because the path's length might be changed during the animation
-      let l = pnode.getTotalLength();
-      let p = pnode.getPointAtLength(f * l);
-      return 'translate(' + p.x + ',' + p.y + ')';
-    };
-  };
-};

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/0310ac22/console/stand-alone/plugin/js/topology/traffic.ts
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/topology/traffic.ts b/console/stand-alone/plugin/js/topology/traffic.ts
new file mode 100644
index 0000000..3f1e5c2
--- /dev/null
+++ b/console/stand-alone/plugin/js/topology/traffic.ts
@@ -0,0 +1,443 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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';
+
+/* global d3 ChordData MIN_CHORD_THRESHOLD Promise */
+declare var d3: any;
+declare var ChordData: any;
+declare var MIN_CHORD_THRESHOLD: number;
+
+const transitionDuration = 1000;
+const CHORDFILTERKEY = 'chordFilter';
+
+class Traffic { // eslint-disable-line no-unused-vars
+  [x: string]: any;
+  constructor($scope, $timeout, QDRService, converter, radius, topology, nextHop, type, prefix) {
+    $scope.addressColors = {};
+    this.QDRService = QDRService;
+    this.type = type; // moving dots or colored path
+    this.prefix = prefix; // url prefix used in svg url()s
+    this.topology = topology; // contains the list of router nodes
+    this.nextHop = nextHop; // fn that returns the route through the network between two routers
+    this.$scope = $scope;
+    this.$timeout = $timeout;
+    // internal variables
+    this.interval = null; // setInterval handle
+    this.setAnimationType(type, converter, radius);
+  }
+  // stop updating the traffic data
+  stop() {
+    if (this.interval) {
+      clearInterval(this.interval);
+      this.interval = null;
+    }
+  }
+  // start updating the traffic data
+  start() {
+    this.doUpdate();
+    this.interval = setInterval(this.doUpdate.bind(this), transitionDuration);
+  }
+  // remove any animations that are in progress
+  remove() {
+    if (this.vis) {
+      this.vis.remove();
+    }
+  }
+  // called when one of the address checkboxes is toggled
+  setAnimationType(type, converter, radius) {
+    this.stop();
+    this.remove();
+    this.type = type;
+    this.vis = type === 'dots' ? new Dots(this, converter, radius) :
+      new Congestion(this);
+  }
+  // called periodically to refresh the traffic flow
+  doUpdate() {
+    this.vis.doUpdate();
+  }
+}
+
+
+/* Base class for congestion and dots visualizations */
+class TrafficAnimation {
+  [x: string]: any;
+  constructor(traffic) {
+    this.traffic = traffic;
+  }
+  nodeIndexFor(nodes, name) {
+    for (let i = 0; i < nodes.length; i++) {
+      let node = nodes[i];
+      if (node.container === name) {
+        return i;
+      }
+    }
+    return -1;
+  }
+}
+
+/* Color the links between router to show how heavily used the links are. */
+class Congestion extends TrafficAnimation {
+  constructor(traffic) {
+    super(traffic);
+    this.init_markerDef();
+  }
+  init_markerDef() {
+    this.custom_markers_def = d3.select('#SVG_ID').select('defs.custom-markers');
+    if (this.custom_markers_def.empty()) {
+      this.custom_markers_def = d3.select('#SVG_ID').append('svg:defs').attr('class', 'custom-markers');
+    }
+  }
+  findResult(node, entity, attribute, value) {
+    let attrIndex = node[entity].attributeNames.indexOf(attribute);
+    if (attrIndex >= 0) {
+      for (let i = 0; i < node[entity].results.length; i++) {
+        if (node[entity].results[i][attrIndex] === value) {
+          return this.traffic.QDRService.utilities.flatten(node[entity].attributeNames, node[entity].results[i]);
+        }
+      }
+    }
+    return null;
+  }
+  doUpdate() {
+    let self = this;
+    this.traffic.QDRService.management.topology.ensureAllEntities(
+      [{ entity: 'router.link', force: true }, { entity: 'connection' }], function () {
+      let links = {};
+      let nodeInfo = self.traffic.QDRService.management.topology.nodeInfo();
+      // accumulate all the inter-router links in an object
+      // keyed by the svgs path id
+      for (const nodeId of Object.keys(nodeInfo)) {
+        let node = nodeInfo[nodeId];
+        let nodeLinks = node['router.link'];
+        for (let n = 0; n < nodeLinks.results.length; n++) {
+          let link = self.traffic.QDRService.utilities.flatten(nodeLinks.attributeNames, nodeLinks.results[n]);
+          if (link.linkType !== 'router-control') {
+            let f = self.nodeIndexFor(self.traffic.topology.nodes, self.traffic.QDRService.management.topology.nameFromId(nodeId));
+            let connection = self.findResult(node, 'connection', 'identity', link.connectionId);
+            if (connection) {
+              let t = self.nodeIndexFor(self.traffic.topology.nodes, connection.container);
+              let little = Math.min(f, t);
+              let big = Math.max(f, t);
+              let key = ['#path', little, big].join('-');
+              if (!links[key]) {
+                links[key] = [];
+              }
+              links[key].push(link);
+            }
+          }
+        }
+      }
+      // accumulate the colors/directions to be used
+      let colors = {};
+      for (const key of Object.keys(links)) {
+        let congestion = self.congestion(links[key]);
+        let path = d3.select(key);
+        if (path && !path.empty()) {
+          let dir = path.attr('marker-end') === '' ? 'start' : 'end';
+          let small = path.attr('class').indexOf('small') > -1;
+          let id = dir + '-' + congestion.substr(1) + (small ? '-s' : '');
+          colors[id] = { dir: dir, color: congestion, small: small };
+          path
+            .attr('stroke', congestion)
+            .classed('traffic', true)
+            .attr('marker-start', function (d) {
+              return d.left ? 'url(' + self.traffic.prefix + '#' + id + ')' : '';
+            })
+            .attr('marker-end', function (d) {
+              return d.right ? 'url(' + self.traffic.prefix + '#' + id + ')' : '';
+            });
+        }
+      }
+      // create the svg:def that holds the custom markers
+      self.init_markerDef();
+      let colorKeys = Object.keys(colors);
+      let custom_markers = self.custom_markers_def.selectAll('marker')
+        .data(colorKeys, function (d) { return d; });
+      custom_markers.enter().append('svg:marker')
+        .attr('id', function (d) { return d; })
+        .attr('viewBox', '0 -5 10 10')
+        .attr('refX', function (d) {
+          return colors[d].dir === 'end' ? 24 : (colors[d].small) ? -24 : -14;
+        })
+        .attr('markerWidth', 4)
+        .attr('markerHeight', 4)
+        .attr('orient', 'auto')
+        .style('fill', function (d) { return colors[d].color; })
+        .append('svg:path')
+        .attr('d', function (d) {
+          return colors[d].dir === 'end' ? 'M 0 -5 L 10 0 L 0 5 z' : 'M 10 -5 L 0 0 L 10 5 z';
+        });
+      custom_markers.exit().remove();
+    });
+  }
+  congestion(links) {
+    let v = 0;
+    for (let l = 0; l < links.length; l++) {
+      let link = links[l];
+      v = Math.max(v, (link.undeliveredCount + link.unsettledCount) / link.capacity);
+    }
+    return this.fillColor(v);
+  }
+  fillColor(v) {
+    let color = d3.scale.linear().domain([0, 1, 2, 3])
+      .interpolate(d3.interpolateHcl)
+      .range([d3.rgb('#CCCCCC'), d3.rgb('#00FF00'), d3.rgb('#FFA500'), d3.rgb('#FF0000')]);
+    return color(v);
+  }
+  remove() {
+    d3.select('#SVG_ID').selectAll('path.traffic')
+      .classed('traffic', false);
+    d3.select('#SVG_ID').select('defs.custom-markers')
+      .selectAll('marker').remove();
+  }
+}
+
+/* Create animated dots moving along the links between routers
+   to show message flow */
+class Dots extends TrafficAnimation {
+  constructor(traffic, converter, radius) {
+    super(traffic);
+    this.excludedAddresses = localStorage[CHORDFILTERKEY] ? JSON.parse(localStorage[CHORDFILTERKEY]) : [];
+    this.radius = radius; // the radius of a router circle
+    this.lastFlows = {}; // the number of dots animated between routers
+    this.chordData = new ChordData(this.traffic.QDRService, true, converter); // gets ingressHistogram data
+    this.chordData.setFilter(this.excludedAddresses);
+    traffic.$scope.addresses = {};
+    this.chordData.getMatrix().then(function () {
+      this.traffic.$timeout(function () {
+        this.traffic.$scope.addresses = this.chordData.getAddresses();
+        for (const address of Object.keys(this.traffic.$scope.addresses)) {
+          this.fillColor(address);
+        }
+      }.bind(this));
+    }.bind(this));
+    // colors
+    this.colorGen = d3.scale.category10();
+    let self = this;
+    // event notification that an address checkbox has changed
+    traffic.$scope.addressFilterChanged = function () {
+      self.updateAddresses();
+      // don't wait for the next polling cycle. update now
+      self.traffic.stop();
+      self.traffic.start();
+    };
+    // called by angular when mouse enters one of the address legends
+    traffic.$scope.enterLegend = function (address) {
+      // fade all flows that aren't for this address
+      self.fadeOtherAddresses(address);
+    };
+    // called when the mouse leaves one of the address legends
+    traffic.$scope.leaveLegend = function () {
+      self.unFadeAll();
+    };
+    // clicked on the address name. toggle the address checkbox
+    traffic.$scope.addressClick = function (address) {
+      self.toggleAddress(address);
+      self.updateAddresses();
+    };
+  }
+  remove() {
+    for (const id of Object.keys(this.lastFlows)) {
+      d3.select('#SVG_ID').selectAll('circle.flow' + id).remove();
+    }
+    this.lastFlows = {};
+  }
+  updateAddresses() {
+    this.excludedAddresses = [];
+    for (let address in this.traffic.$scope.addresses) {
+      if (!this.traffic.$scope.addresses[address]) {
+        this.excludedAddresses.push(address);
+      }
+    }
+    localStorage[CHORDFILTERKEY] = JSON.stringify(this.excludedAddresses);
+    if (this.chordData) {
+      this.chordData.setFilter(this.excludedAddresses);
+    }
+  }
+  toggleAddress(address) {
+    this.traffic.$scope.addresses[address] = !this.traffic.$scope.addresses[address];
+  }
+  fadeOtherAddresses(address) {
+    d3.selectAll('circle.flow').classed('fade', function (d) {
+      return d.address !== address;
+    });
+  }
+  unFadeAll() {
+    d3.selectAll('circle.flow').classed('fade', false);
+  }
+  doUpdate() {
+    let self = this;
+    // we need the nextHop data to show traffic between routers that are connected by intermediaries
+    this.traffic.QDRService.management.topology.ensureAllEntities([{ entity: 'router.node', attrs: ['id', 'nextHop'] }], function () {
+      // get the ingressHistogram data for all routers
+      self.chordData.getMatrix().then(self.render.bind(self), function (e) {
+        console.log('Could not get message histogram' + e);
+      });
+    });
+  }
+  render(matrix) {
+    this.traffic.$timeout(function () {
+      this.traffic.$scope.addresses = this.chordData.getAddresses();
+    }.bind(this));
+    // get the rate of message flow between routers
+    let hops = {}; // every hop between routers that is involved in message flow
+    let matrixMessages = matrix.matrixMessages();
+    // the fastest traffic rate gets 3 times as many dots as the slowest
+    let minmax = matrix.getMinMax();
+    let flowScale = d3.scale.linear().domain(minmax).range([1, 1.75]);
+    // row is ingress router, col is egress router. Value at [row][col] is the rate
+    matrixMessages.forEach(function (row, r) {
+      row.forEach(function (val, c) {
+        if (val > MIN_CHORD_THRESHOLD) {
+          // translate between matrix row/col and node index
+          let f = this.nodeIndexFor(this.traffic.topology.nodes, matrix.rows[r].egress);
+          let t = this.nodeIndexFor(this.traffic.topology.nodes, matrix.rows[r].ingress);
+          let address = matrix.getAddress(r, c);
+          if (r !== c) {
+            // accumulate the hops between the ingress and egress routers
+            this.traffic.nextHop(this.traffic.topology.nodes[f], this.traffic.topology.nodes[t], function (link, fnode, tnode) {
+              let key = '-' + link.uid;
+              let back = fnode.index < tnode.index;
+              if (!hops[key]) {
+                hops[key] = [];
+              }
+              hops[key].push({ val: val, back: back, address: address });
+            });
+          }
+          // Find the senders connected to nodes[f] and the receivers connected to nodes[t]
+          // and add their links to the animation
+          this.addClients(hops, this.traffic.topology.nodes, f, val, true, address);
+          this.addClients(hops, this.traffic.topology.nodes, t, val, false, address);
+        }
+      }.bind(this));
+    }.bind(this));
+    // for each link between routers that has traffic, start an animation
+    let keep = {};
+    for (const id of Object.keys(hops)) {
+      let hop = hops[id];
+      for (let h = 0; h < hop.length; h++) {
+        let ahop = hop[h];
+        let flowId = id + '-' + this.addressIndex(this, ahop.address) + (ahop.back ? 'b' : '');
+        let path = d3.select('#path' + id);
+        // start the animation. If the animation is already running, this will have no effect
+        this.startAnimation(path, flowId, ahop, flowScale(ahop.val));
+        keep[flowId] = true;
+      }
+    }
+    // remove any existing animations that we don't have data for anymore
+    for (let id in this.lastFlows) {
+      if (this.lastFlows[id] && !keep[id]) {
+        this.lastFlows[id] = 0;
+        d3.select('#SVG_ID').selectAll('circle.flow' + id).remove();
+      }
+    }
+  }
+  // animate the d3 selection (flow) along the given path
+  animateFlow(flow, path, count, back, rate) {
+    let self = this;
+    let l = path.node().getTotalLength();
+    flow.transition()
+      .ease('easeLinear')
+      .duration(l * 10 / rate)
+      .attrTween('transform', self.translateDots(self.radius, path, count, back))
+      .each('end', function () { self.animateFlow(flow, path, count, back, rate); });
+  }
+  // create dots along the path between routers
+  startAnimation(path, id, hop, rate) {
+    if (!path.node()) {
+      return;
+    }
+    this.animateDots(path, id, hop, rate);
+  }
+  animateDots(path, id, hop, rate) {
+    let back = hop.back, address = hop.address;
+    // the density of dots is determined by the rate of this traffic relative to the other traffic
+    let len = Math.max(Math.floor(path.node().getTotalLength() / 50), 1);
+    let dots = [];
+    for (let i = 0, offset = this.addressIndex(this, address); i < len; ++i) {
+      dots[i] = { i: i + 10 * offset, address: address };
+    }
+    // keep track of the number of dots for each link. If the length of the link is changed,
+    // re-create the animation
+    if (!this.lastFlows[id]) {
+      this.lastFlows[id] = len;
+    } else {
+      if (this.lastFlows[id] !== len) {
+        this.lastFlows[id] = len;
+        d3.select('#SVG_ID').selectAll('circle.flow' + id).remove();
+      }
+    }
+    let flow = d3.select('#SVG_ID').selectAll('circle.flow' + id)
+      .data(dots, function (d) { return d.i + d.address; });
+    let circles = flow
+      .enter().append('circle')
+      .attr('class', 'flow flow' + id)
+      .attr('fill', this.fillColor(address))
+      .attr('r', 5);
+    this.animateFlow(circles, path, dots.length, back, rate);
+    flow.exit()
+      .remove();
+  }
+  fillColor(n) {
+    if (!(n in this.traffic.$scope.addressColors)) {
+      let ci = Object.keys(this.traffic.$scope.addressColors).length;
+      this.traffic.$scope.addressColors[n] = this.colorGen(ci);
+    }
+    return this.traffic.$scope.addressColors[n];
+  }
+  addClients(hops, nodes, f, val, sender, address) {
+    let cdir = sender ? 'out' : 'in';
+    for (let n = 0; n < nodes.length; n++) {
+      let node = nodes[n];
+      if (node.normals && node.key === nodes[f].key && node.cdir === cdir) {
+        let key = ['', f, n].join('-');
+        if (!hops[key]) {
+          hops[key] = [];
+        }
+        hops[key].push({ val: val, back: node.cdir === 'in', address: address });
+        return;
+      }
+    }
+  }
+  addressIndex(vis, address) {
+    return Object.keys(vis.traffic.$scope.addresses).indexOf(address);
+  }
+  // calculate the translation for each dot along the path
+  translateDots(radius, path, count, back) {
+    let pnode = path.node();
+    // will be called for each element in the flow selection (for each dot)
+    return function (d) {
+      // will be called with t going from 0 to 1 for each dot
+      return function (t) {
+        // start the points at different positions depending on their value (d)
+        let tt = t * 1000;
+        let f = ((tt + (d.i * 1000 / count)) % 1000) / 1000;
+        if (back) {
+          f = 1 - f;
+        }
+        // l needs to be calculated each tick because the path's length might be changed during the animation
+        let l = pnode.getTotalLength();
+        let p = pnode.getPointAtLength(f * l);
+        return 'translate(' + p.x + ',' + p.y + ')';
+      };
+    };
+  }
+}
+
+

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/0310ac22/console/stand-alone/tsconfig.json
----------------------------------------------------------------------
diff --git a/console/stand-alone/tsconfig.json b/console/stand-alone/tsconfig.json
new file mode 100644
index 0000000..056e773
--- /dev/null
+++ b/console/stand-alone/tsconfig.json
@@ -0,0 +1,31 @@
+{
+  "compilerOptions": {
+    "allowJs": true,
+    "checkJs": true,
+    "lib": [
+      "dom",
+      "dom.iterable",
+      "es5",
+      "es6",
+      "es7",
+      "esnext",
+      "esnext.asynciterable",
+      "es2015.iterable",
+      "es2017"
+    ]
+  },
+  "compileOnSave": true,
+  "include": [
+    "plugin/*"
+  ],
+  "exclude": [
+    "node_modules/*"
+  ],
+  "typeAcquisition": {
+    "enable": true
+  },
+  "files": [
+    "plugin/**/*.ts"
+  ]
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/0310ac22/console/stand-alone/tslint.json
----------------------------------------------------------------------
diff --git a/console/stand-alone/tslint.json b/console/stand-alone/tslint.json
new file mode 100644
index 0000000..ad645d3
--- /dev/null
+++ b/console/stand-alone/tslint.json
@@ -0,0 +1,64 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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.
+*/
+{
+  "rules": {
+    "class-name": true,
+    "curly": true,
+    "eofline": false,
+    "forin": true,
+    "indent": [true, 4],
+    "label-position": true,
+    "max-line-length": [true, 140],
+    "no-arg": true,
+    "no-bitwise": true,
+    "no-console": [true,
+      "debug",
+      "info",
+      "time",
+      "timeEnd",
+      "trace"
+    ],
+    "no-construct": true,
+    "no-debugger": true,
+    "no-duplicate-variable": true,
+    "no-empty": true,
+    "no-eval": true,
+    "no-string-literal": false,
+    "no-trailing-whitespace": true,
+    "no-unused-variable": false,
+    //"no-use-before-declare": true,
+    "one-line": [true,
+      "check-open-brace",
+      "check-catch",
+      "check-else",
+      "check-whitespace"
+    ],
+    "quotemark": [true, "single"],
+    "radix": true,
+    "semicolon": true,
+    "triple-equals": [true, "allow-null-check"],
+    "variable-name": false,
+    "whitespace": [true,
+      "check-branch",
+      "check-decl",
+      "check-operator",
+      "check-separator"
+    ]
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/0310ac22/console/stand-alone/vendor-css.txt
----------------------------------------------------------------------
diff --git a/console/stand-alone/vendor-css.txt b/console/stand-alone/vendor-css.txt
new file mode 100644
index 0000000..333e38c
--- /dev/null
+++ b/console/stand-alone/vendor-css.txt
@@ -0,0 +1,25 @@
+- Licensed to the Apache Software Foundation (ASF) under one
+- or more contributor license agreements.  See the NOTICE file
+- distributed with this work for additional information
+- regarding copyright ownership.  The ASF licenses this file
+- to you 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.
+
+-- The following files get packaged into a single vendor.min.css
+
+node_modules/jquery-ui-dist/jquery-ui.css
+node_modules/patternfly/dist/css/patternfly.min.css
+node_modules/patternfly/dist/css/patternfly-additions.min.css
+node_modules/jquery.fancytree/dist/skin-bootstrap-n/ui.fancytree.css
+node_modules/c3/c3.css
+node_modules/angular-ui-grid/ui-grid.css

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/0310ac22/console/stand-alone/vendor-js.txt
----------------------------------------------------------------------
diff --git a/console/stand-alone/vendor-js.txt b/console/stand-alone/vendor-js.txt
new file mode 100644
index 0000000..5af21f4
--- /dev/null
+++ b/console/stand-alone/vendor-js.txt
@@ -0,0 +1,43 @@
+- Licensed to the Apache Software Foundation (ASF) under one
+- or more contributor license agreements.  See the NOTICE file
+- distributed with this work for additional information
+- regarding copyright ownership.  The ASF licenses this file
+- to you 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.
+
+-- The following files get packaged into a single vendor.min.js
+
+node_modules/bluebird/js/browser/bluebird.min.js
+node_modules/jquery/dist/jquery.min.js
+node_modules/jquery-ui-dist/jquery-ui.min.js
+node_modules/jquery.fancytree/dist/jquery.fancytree-all.min.js
+node_modules/angular/angular.min.js
+node_modules/angular-animate/angular-animate.min.js
+node_modules/angular-sanitize/angular-sanitize.min.js
+node_modules/angular-route/angular-route.min.js
+node_modules/angular-resource/angular-resource.min.js
+node_modules/bootstrap/dist/js/bootstrap.min.js
+node_modules/angular-ui-bootstrap/dist/ui-bootstrap.js
+node_modules/angular-ui-bootstrap/dist/ui-bootstrap-tpls.js
+node_modules/d3/d3.min.js
+node_modules/d3-queue/build/d3-queue.min.js
+node_modules/d3-time/build/d3-time.min.js
+node_modules/d3-time-format/build/d3-time-format.min.js
+node_modules/d3-path/build/d3-path.min.js
+node_modules/c3/c3.min.js
+node_modules/angular-ui-slider/src/slider.js
+node_modules/angular-ui-grid/ui-grid.min.js
+node_modules/angular-bootstrap-checkbox/angular-bootstrap-checkbox.js
+node_modules/notifyjs-browser/dist/notify.js
+node_modules/patternfly/dist/js/patternfly.min.js
+node_modules/dispatch-management/dist/dispatch-management.min.js


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[2/3] qpid-dispatch git commit: DISPATCH-1017 Added console build.

Posted by ea...@apache.org.
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/0310ac22/console/stand-alone/package-lock.json
----------------------------------------------------------------------
diff --git a/console/stand-alone/package-lock.json b/console/stand-alone/package-lock.json
index 98afefe..a94c1cf 100644
--- a/console/stand-alone/package-lock.json
+++ b/console/stand-alone/package-lock.json
@@ -4,26 +4,7576 @@
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
-    "debug": {
+    "@gulp-sourcemaps/identity-map": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-1.0.1.tgz",
+      "integrity": "sha1-z6I7xYQPkQTOMqZedNt+epdLvuE=",
+      "dev": true,
+      "requires": {
+        "acorn": "5.6.1",
+        "css": "2.2.3",
+        "normalize-path": "2.1.1",
+        "source-map": "0.5.7",
+        "through2": "2.0.3"
+      }
+    },
+    "@gulp-sourcemaps/map-sources": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz",
+      "integrity": "sha1-iQrnxdjId/bThIYCFazp1+yUW9o=",
+      "dev": true,
+      "requires": {
+        "normalize-path": "2.1.1",
+        "through2": "2.0.3"
+      }
+    },
+    "@types/fancy-log": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/@types/fancy-log/-/fancy-log-1.3.0.tgz",
+      "integrity": "sha512-mQjDxyOM1Cpocd+vm1kZBP7smwKZ4TNokFeds9LV7OZibmPJFEzY3+xZMrKfUdNT71lv8GoCPD6upKwHxubClw==",
+      "dev": true
+    },
+    "acorn": {
+      "version": "5.6.1",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.6.1.tgz",
+      "integrity": "sha512-XH4o5BK5jmw9PzSGK7mNf+/xV+mPxQxGZoeC36OVsJZYV77JAG9NnI7T90hoUpI/C1TOfXWTvugRdZ9ZR3iE2Q==",
+      "dev": true
+    },
+    "acorn-jsx": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
+      "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
+      "dev": true,
+      "requires": {
+        "acorn": "3.3.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "3.3.0",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
+          "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
+          "dev": true
+        }
+      }
+    },
+    "ajv": {
+      "version": "5.5.2",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+      "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+      "dev": true,
+      "requires": {
+        "co": "4.6.0",
+        "fast-deep-equal": "1.1.0",
+        "fast-json-stable-stringify": "2.0.0",
+        "json-schema-traverse": "0.3.1"
+      }
+    },
+    "ajv-keywords": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz",
+      "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=",
+      "dev": true
+    },
+    "alter": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/alter/-/alter-0.2.0.tgz",
+      "integrity": "sha1-x1iICGF1cgNKrmJICvJrHU0cs80=",
+      "dev": true,
+      "requires": {
+        "stable": "0.1.8"
+      }
+    },
+    "amdefine": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+      "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
+      "dev": true
+    },
+    "angular": {
+      "version": "1.5.11",
+      "resolved": "https://registry.npmjs.org/angular/-/angular-1.5.11.tgz",
+      "integrity": "sha1-jFunOG8VllyazzQp9ogVU6raMNY="
+    },
+    "angular-animate": {
+      "version": "1.5.11",
+      "resolved": "https://registry.npmjs.org/angular-animate/-/angular-animate-1.5.11.tgz",
+      "integrity": "sha1-G6pDwwPRuTxOaqiUU7ORFLehxmk="
+    },
+    "angular-bootstrap-checkbox": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/angular-bootstrap-checkbox/-/angular-bootstrap-checkbox-0.5.0.tgz",
+      "integrity": "sha1-zX+oSlN/5+tWnjlhLwVzGCw+MRg="
+    },
+    "angular-resource": {
+      "version": "1.5.11",
+      "resolved": "https://registry.npmjs.org/angular-resource/-/angular-resource-1.5.11.tgz",
+      "integrity": "sha1-2T6mGRhKLg7jrjOCZXWDYxcpKfA="
+    },
+    "angular-route": {
+      "version": "1.5.11",
+      "resolved": "https://registry.npmjs.org/angular-route/-/angular-route-1.5.11.tgz",
+      "integrity": "sha1-SWFPOhZ/VCkeRJ/ougXTnFiSS4M="
+    },
+    "angular-sanitize": {
+      "version": "1.5.11",
+      "resolved": "https://registry.npmjs.org/angular-sanitize/-/angular-sanitize-1.5.11.tgz",
+      "integrity": "sha1-6/s/ND5UP5su8FD7TC6e4EjRdy8="
+    },
+    "angular-ui-bootstrap": {
+      "version": "2.5.6",
+      "resolved": "https://registry.npmjs.org/angular-ui-bootstrap/-/angular-ui-bootstrap-2.5.6.tgz",
+      "integrity": "sha512-yzcHpPMLQl0232nDzm5P4iAFTFQ9dMw0QgFLuKYbDj9M0xJ62z0oudYD/Lvh1pWfRsukiytP4Xj6BHOSrSXP8A=="
+    },
+    "angular-ui-grid": {
+      "version": "4.4.11",
+      "resolved": "https://registry.npmjs.org/angular-ui-grid/-/angular-ui-grid-4.4.11.tgz",
+      "integrity": "sha512-tOZrlgmmV8LXS5yDXxry53uibZxFOC3dNNUOH+5AA0SwVTg1B0rE4+4zdU7NfW6bKClshoPE7mik8/VrS1rXAQ==",
+      "requires": {
+        "angular": "1.7.0"
+      },
+      "dependencies": {
+        "angular": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/angular/-/angular-1.7.0.tgz",
+          "integrity": "sha512-3LboCLjrOuC7dWh953O0+dI3dJ7PexYRSCIrfqoN5qoHyja/wak3eWoxPKb2Sl2qwiPbrUV5KJXwgpUQ48McBQ=="
+        }
+      }
+    },
+    "angular-ui-slider": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/angular-ui-slider/-/angular-ui-slider-0.4.0.tgz",
+      "integrity": "sha1-12wKVGSNDRjVnIfmyDOPrnQTXHU="
+    },
+    "ansi-colors": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz",
+      "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==",
+      "dev": true,
+      "requires": {
+        "ansi-wrap": "0.1.0"
+      }
+    },
+    "ansi-cyan": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz",
+      "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=",
+      "dev": true,
+      "requires": {
+        "ansi-wrap": "0.1.0"
+      }
+    },
+    "ansi-escapes": {
       "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
-      "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
+      "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==",
+      "dev": true
+    },
+    "ansi-gray": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz",
+      "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=",
+      "dev": true,
+      "requires": {
+        "ansi-wrap": "0.1.0"
+      }
+    },
+    "ansi-red": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz",
+      "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=",
+      "dev": true,
+      "requires": {
+        "ansi-wrap": "0.1.0"
+      }
+    },
+    "ansi-regex": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+      "dev": true
+    },
+    "ansi-styles": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+      "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+      "dev": true
+    },
+    "ansi-wrap": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz",
+      "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=",
+      "dev": true
+    },
+    "anymatch": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
+      "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==",
+      "dev": true,
+      "requires": {
+        "micromatch": "2.3.11",
+        "normalize-path": "2.1.1"
+      }
+    },
+    "append-buffer": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz",
+      "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=",
+      "dev": true,
+      "requires": {
+        "buffer-equal": "1.0.0"
+      }
+    },
+    "archy": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
+      "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=",
+      "dev": true
+    },
+    "argparse": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+      "dev": true,
+      "requires": {
+        "sprintf-js": "1.0.3"
+      }
+    },
+    "arr-diff": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
+      "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
+      "dev": true,
+      "requires": {
+        "arr-flatten": "1.1.0"
+      }
+    },
+    "arr-filter": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz",
+      "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=",
+      "dev": true,
+      "requires": {
+        "make-iterator": "1.0.1"
+      }
+    },
+    "arr-flatten": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+      "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+      "dev": true
+    },
+    "arr-map": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz",
+      "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=",
+      "dev": true,
+      "requires": {
+        "make-iterator": "1.0.1"
+      }
+    },
+    "arr-union": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+      "dev": true
+    },
+    "array-each": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz",
+      "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=",
+      "dev": true
+    },
+    "array-initial": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz",
+      "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=",
+      "dev": true,
+      "requires": {
+        "array-slice": "1.1.0",
+        "is-number": "4.0.0"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+          "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
+          "dev": true
+        }
+      }
+    },
+    "array-last": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz",
+      "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==",
+      "dev": true,
+      "requires": {
+        "is-number": "4.0.0"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+          "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
+          "dev": true
+        }
+      }
+    },
+    "array-slice": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
+      "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==",
+      "dev": true
+    },
+    "array-sort": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz",
+      "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==",
+      "dev": true,
+      "requires": {
+        "default-compare": "1.0.0",
+        "get-value": "2.0.6",
+        "kind-of": "5.1.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        }
+      }
+    },
+    "array-union": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+      "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+      "dev": true,
+      "requires": {
+        "array-uniq": "1.0.3"
+      }
+    },
+    "array-uniq": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+      "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+      "dev": true
+    },
+    "array-unique": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+      "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
+      "dev": true
+    },
+    "arrify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+      "dev": true
+    },
+    "assign-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+      "dev": true
+    },
+    "async-done": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.1.tgz",
+      "integrity": "sha512-R1BaUeJ4PMoLNJuk+0tLJgjmEqVsdN118+Z8O+alhnQDQgy0kmD5Mqi0DNEmMx2LM0Ed5yekKu+ZXYvIHceicg==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "1.4.1",
+        "once": "1.4.0",
+        "process-nextick-args": "1.0.7",
+        "stream-exhaust": "1.0.2"
+      }
+    },
+    "async-each": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
+      "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
+      "dev": true
+    },
+    "async-settle": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz",
+      "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=",
+      "dev": true,
+      "requires": {
+        "async-done": "1.3.1"
+      }
+    },
+    "atob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz",
+      "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=",
+      "dev": true
+    },
+    "babel-code-frame": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+      "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3",
+        "esutils": "2.0.2",
+        "js-tokens": "3.0.2"
+      }
+    },
+    "babel-core": {
+      "version": "6.26.3",
+      "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz",
+      "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==",
+      "dev": true,
+      "requires": {
+        "babel-code-frame": "6.26.0",
+        "babel-generator": "6.26.1",
+        "babel-helpers": "6.24.1",
+        "babel-messages": "6.23.0",
+        "babel-register": "6.26.0",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0",
+        "babylon": "6.18.0",
+        "convert-source-map": "1.5.1",
+        "debug": "2.6.9",
+        "json5": "0.5.1",
+        "lodash": "4.17.10",
+        "minimatch": "3.0.4",
+        "path-is-absolute": "1.0.1",
+        "private": "0.1.8",
+        "slash": "1.0.0",
+        "source-map": "0.5.7"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "babel-generator": {
+      "version": "6.26.1",
+      "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz",
+      "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==",
+      "dev": true,
+      "requires": {
+        "babel-messages": "6.23.0",
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0",
+        "detect-indent": "4.0.0",
+        "jsesc": "1.3.0",
+        "lodash": "4.17.10",
+        "source-map": "0.5.7",
+        "trim-right": "1.0.1"
+      }
+    },
+    "babel-helper-builder-binary-assignment-operator-visitor": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz",
+      "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=",
+      "dev": true,
+      "requires": {
+        "babel-helper-explode-assignable-expression": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-call-delegate": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz",
+      "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=",
+      "dev": true,
+      "requires": {
+        "babel-helper-hoist-variables": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-define-map": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz",
+      "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=",
+      "dev": true,
+      "requires": {
+        "babel-helper-function-name": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0",
+        "lodash": "4.17.10"
+      }
+    },
+    "babel-helper-explode-assignable-expression": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz",
+      "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-function-name": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz",
+      "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=",
+      "dev": true,
+      "requires": {
+        "babel-helper-get-function-arity": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-get-function-arity": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz",
+      "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-hoist-variables": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz",
+      "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-optimise-call-expression": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz",
+      "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-regex": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz",
+      "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0",
+        "lodash": "4.17.10"
+      }
+    },
+    "babel-helper-remap-async-to-generator": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz",
+      "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=",
+      "dev": true,
+      "requires": {
+        "babel-helper-function-name": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-replace-supers": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz",
+      "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=",
+      "dev": true,
+      "requires": {
+        "babel-helper-optimise-call-expression": "6.24.1",
+        "babel-messages": "6.23.0",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helpers": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz",
+      "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0"
+      }
+    },
+    "babel-messages": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
+      "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-check-es2015-constants": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz",
+      "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-syntax-async-functions": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
+      "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=",
+      "dev": true
+    },
+    "babel-plugin-syntax-exponentiation-operator": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz",
+      "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=",
+      "dev": true
+    },
+    "babel-plugin-syntax-trailing-function-commas": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz",
+      "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=",
+      "dev": true
+    },
+    "babel-plugin-transform-async-to-generator": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz",
+      "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=",
+      "dev": true,
+      "requires": {
+        "babel-helper-remap-async-to-generator": "6.24.1",
+        "babel-plugin-syntax-async-functions": "6.13.0",
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-arrow-functions": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
+      "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-block-scoped-functions": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz",
+      "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-block-scoping": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz",
+      "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0",
+        "lodash": "4.17.10"
+      }
+    },
+    "babel-plugin-transform-es2015-classes": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz",
+      "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=",
+      "dev": true,
+      "requires": {
+        "babel-helper-define-map": "6.26.0",
+        "babel-helper-function-name": "6.24.1",
+        "babel-helper-optimise-call-expression": "6.24.1",
+        "babel-helper-replace-supers": "6.24.1",
+        "babel-messages": "6.23.0",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-computed-properties": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz",
+      "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-destructuring": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz",
+      "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-duplicate-keys": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz",
+      "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-for-of": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz",
+      "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-function-name": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz",
+      "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=",
+      "dev": true,
+      "requires": {
+        "babel-helper-function-name": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-literals": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz",
+      "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-modules-amd": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz",
+      "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-transform-es2015-modules-commonjs": "6.26.2",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-modules-commonjs": {
+      "version": "6.26.2",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz",
+      "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==",
+      "dev": true,
+      "requires": {
+        "babel-plugin-transform-strict-mode": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-modules-systemjs": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz",
+      "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=",
+      "dev": true,
+      "requires": {
+        "babel-helper-hoist-variables": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-modules-umd": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz",
+      "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-transform-es2015-modules-amd": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-object-super": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz",
+      "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=",
+      "dev": true,
+      "requires": {
+        "babel-helper-replace-supers": "6.24.1",
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-parameters": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz",
+      "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=",
+      "dev": true,
+      "requires": {
+        "babel-helper-call-delegate": "6.24.1",
+        "babel-helper-get-function-arity": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-shorthand-properties": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz",
+      "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-spread": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz",
+      "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-sticky-regex": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz",
+      "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=",
+      "dev": true,
+      "requires": {
+        "babel-helper-regex": "6.26.0",
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-template-literals": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz",
+      "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-typeof-symbol": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz",
+      "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-unicode-regex": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz",
+      "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=",
+      "dev": true,
+      "requires": {
+        "babel-helper-regex": "6.26.0",
+        "babel-runtime": "6.26.0",
+        "regexpu-core": "2.0.0"
+      }
+    },
+    "babel-plugin-transform-exponentiation-operator": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz",
+      "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=",
+      "dev": true,
+      "requires": {
+        "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1",
+        "babel-plugin-syntax-exponentiation-operator": "6.13.0",
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-regenerator": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz",
+      "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=",
+      "dev": true,
+      "requires": {
+        "regenerator-transform": "0.10.1"
+      }
+    },
+    "babel-plugin-transform-strict-mode": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz",
+      "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-preset-env": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz",
+      "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==",
+      "dev": true,
+      "requires": {
+        "babel-plugin-check-es2015-constants": "6.22.0",
+        "babel-plugin-syntax-trailing-function-commas": "6.22.0",
+        "babel-plugin-transform-async-to-generator": "6.24.1",
+        "babel-plugin-transform-es2015-arrow-functions": "6.22.0",
+        "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0",
+        "babel-plugin-transform-es2015-block-scoping": "6.26.0",
+        "babel-plugin-transform-es2015-classes": "6.24.1",
+        "babel-plugin-transform-es2015-computed-properties": "6.24.1",
+        "babel-plugin-transform-es2015-destructuring": "6.23.0",
+        "babel-plugin-transform-es2015-duplicate-keys": "6.24.1",
+        "babel-plugin-transform-es2015-for-of": "6.23.0",
+        "babel-plugin-transform-es2015-function-name": "6.24.1",
+        "babel-plugin-transform-es2015-literals": "6.22.0",
+        "babel-plugin-transform-es2015-modules-amd": "6.24.1",
+        "babel-plugin-transform-es2015-modules-commonjs": "6.26.2",
+        "babel-plugin-transform-es2015-modules-systemjs": "6.24.1",
+        "babel-plugin-transform-es2015-modules-umd": "6.24.1",
+        "babel-plugin-transform-es2015-object-super": "6.24.1",
+        "babel-plugin-transform-es2015-parameters": "6.24.1",
+        "babel-plugin-transform-es2015-shorthand-properties": "6.24.1",
+        "babel-plugin-transform-es2015-spread": "6.22.0",
+        "babel-plugin-transform-es2015-sticky-regex": "6.24.1",
+        "babel-plugin-transform-es2015-template-literals": "6.22.0",
+        "babel-plugin-transform-es2015-typeof-symbol": "6.23.0",
+        "babel-plugin-transform-es2015-unicode-regex": "6.24.1",
+        "babel-plugin-transform-exponentiation-operator": "6.24.1",
+        "babel-plugin-transform-regenerator": "6.26.0",
+        "browserslist": "3.2.8",
+        "invariant": "2.2.4",
+        "semver": "5.5.0"
+      }
+    },
+    "babel-register": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
+      "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=",
+      "dev": true,
+      "requires": {
+        "babel-core": "6.26.3",
+        "babel-runtime": "6.26.0",
+        "core-js": "2.5.7",
+        "home-or-tmp": "2.0.0",
+        "lodash": "4.17.10",
+        "mkdirp": "0.5.1",
+        "source-map-support": "0.4.18"
+      }
+    },
+    "babel-runtime": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+      "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+      "dev": true,
+      "requires": {
+        "core-js": "2.5.7",
+        "regenerator-runtime": "0.11.1"
+      }
+    },
+    "babel-template": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
+      "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0",
+        "babylon": "6.18.0",
+        "lodash": "4.17.10"
+      }
+    },
+    "babel-traverse": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
+      "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
+      "dev": true,
+      "requires": {
+        "babel-code-frame": "6.26.0",
+        "babel-messages": "6.23.0",
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0",
+        "babylon": "6.18.0",
+        "debug": "2.6.9",
+        "globals": "9.18.0",
+        "invariant": "2.2.4",
+        "lodash": "4.17.10"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "babel-types": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
+      "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "esutils": "2.0.2",
+        "lodash": "4.17.10",
+        "to-fast-properties": "1.0.3"
+      }
+    },
+    "babylon": {
+      "version": "6.18.0",
+      "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+      "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
+      "dev": true
+    },
+    "bach": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz",
+      "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=",
+      "dev": true,
+      "requires": {
+        "arr-filter": "1.1.2",
+        "arr-flatten": "1.1.0",
+        "arr-map": "2.0.2",
+        "array-each": "1.0.1",
+        "array-initial": "1.1.0",
+        "array-last": "1.3.0",
+        "async-done": "1.3.1",
+        "async-settle": "1.0.0",
+        "now-and-later": "2.0.0"
+      }
+    },
+    "balanced-match": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+      "dev": true
+    },
+    "base": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+      "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+      "dev": true,
+      "requires": {
+        "cache-base": "1.0.1",
+        "class-utils": "0.3.6",
+        "component-emitter": "1.2.1",
+        "define-property": "1.0.0",
+        "isobject": "3.0.1",
+        "mixin-deep": "1.3.1",
+        "pascalcase": "0.1.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "1.0.2"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "1.0.0",
+            "is-data-descriptor": "1.0.0",
+            "kind-of": "6.0.2"
+          }
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "binary-extensions": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
+      "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=",
+      "dev": true
+    },
+    "bluebird": {
+      "version": "3.5.1",
+      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
+      "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA=="
+    },
+    "bootstrap": {
+      "version": "3.3.7",
+      "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.3.7.tgz",
+      "integrity": "sha1-WjiTlFSfIzMIdaOxUGVldPip63E="
+    },
+    "brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
+      "requires": {
+        "balanced-match": "1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "braces": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
+      "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
+      "dev": true,
+      "requires": {
+        "expand-range": "1.8.2",
+        "preserve": "0.2.0",
+        "repeat-element": "1.1.2"
+      }
+    },
+    "browserslist": {
+      "version": "3.2.8",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz",
+      "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==",
+      "dev": true,
+      "requires": {
+        "caniuse-lite": "1.0.30000847",
+        "electron-to-chromium": "1.3.48"
+      }
+    },
+    "buffer-equal": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz",
+      "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=",
+      "dev": true
+    },
+    "buffer-from": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz",
+      "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==",
+      "dev": true
+    },
+    "bufferstreams": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/bufferstreams/-/bufferstreams-1.1.3.tgz",
+      "integrity": "sha512-HaJnVuslRF4g2kSDeyl++AaVizoitCpL9PglzCYwy0uHHyvWerfvEb8jWmYbF1z4kiVFolGomnxSGl+GUQp2jg==",
+      "dev": true,
+      "requires": {
+        "readable-stream": "2.3.6"
+      }
+    },
+    "builtin-modules": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+      "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
+      "dev": true
+    },
+    "c3": {
+      "version": "0.4.23",
+      "resolved": "https://registry.npmjs.org/c3/-/c3-0.4.23.tgz",
+      "integrity": "sha512-fI6hbx1QoATU0gRQtPWsUGWX+ssXhxGH1ogew32KjVmGHFE4WmfmBkh+RkuHDoeCIoGFon7XTpKcwUZpBGW4mQ==",
+      "requires": {
+        "d3": "3.5.17"
+      }
+    },
+    "cache-base": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+      "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+      "dev": true,
+      "requires": {
+        "collection-visit": "1.0.0",
+        "component-emitter": "1.2.1",
+        "get-value": "2.0.6",
+        "has-value": "1.0.0",
+        "isobject": "3.0.1",
+        "set-value": "2.0.0",
+        "to-object-path": "0.3.0",
+        "union-value": "1.0.0",
+        "unset-value": "1.0.0"
+      },
+      "dependencies": {
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "caller-path": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
+      "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
+      "dev": true,
+      "requires": {
+        "callsites": "0.2.0"
+      }
+    },
+    "callsites": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
+      "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
+      "dev": true
+    },
+    "camelcase": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+      "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
+      "dev": true
+    },
+    "caniuse-lite": {
+      "version": "1.0.30000847",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000847.tgz",
+      "integrity": "sha512-Weo+tRtVWcN2da782Ebx/27hFNEb+KP+uP6tdqAa+2S5bp1zOJhVH9tEpDygagrfvU4QjeuPwi/5VGsgT4SLaA==",
+      "dev": true
+    },
+    "chalk": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+      "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+      "dev": true,
+      "requires": {
+        "ansi-styles": "2.2.1",
+        "escape-string-regexp": "1.0.5",
+        "has-ansi": "2.0.0",
+        "strip-ansi": "3.0.1",
+        "supports-color": "2.0.0"
+      }
+    },
+    "chardet": {
+      "version": "0.4.2",
+      "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
+      "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=",
+      "dev": true
+    },
+    "chokidar": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
+      "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=",
+      "dev": true,
+      "requires": {
+        "anymatch": "1.3.2",
+        "async-each": "1.0.1",
+        "fsevents": "1.2.4",
+        "glob-parent": "2.0.0",
+        "inherits": "2.0.3",
+        "is-binary-path": "1.0.1",
+        "is-glob": "2.0.1",
+        "path-is-absolute": "1.0.1",
+        "readdirp": "2.1.0"
+      }
+    },
+    "circular-json": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
+      "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==",
+      "dev": true
+    },
+    "class-utils": {
+      "version": "0.3.6",
+      "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+      "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+      "dev": true,
+      "requires": {
+        "arr-union": "3.1.0",
+        "define-property": "0.2.5",
+        "isobject": "3.0.1",
+        "static-extend": "0.1.2"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "0.1.6"
+          }
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "clean-css": {
+      "version": "4.1.11",
+      "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.1.11.tgz",
+      "integrity": "sha1-Ls3xRaujj1R0DybO/Q/z4D4SXWo=",
+      "dev": true,
+      "requires": {
+        "source-map": "0.5.7"
+      }
+    },
+    "cli-cursor": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+      "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+      "dev": true,
+      "requires": {
+        "restore-cursor": "2.0.0"
+      }
+    },
+    "cli-width": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
+      "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
+      "dev": true
+    },
+    "cliui": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+      "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+      "dev": true,
+      "requires": {
+        "string-width": "1.0.2",
+        "strip-ansi": "3.0.1",
+        "wrap-ansi": "2.1.0"
+      }
+    },
+    "clone": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz",
+      "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=",
+      "dev": true
+    },
+    "clone-buffer": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
+      "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=",
+      "dev": true
+    },
+    "clone-stats": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
+      "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=",
+      "dev": true
+    },
+    "cloneable-readable": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.2.tgz",
+      "integrity": "sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg==",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "process-nextick-args": "2.0.0",
+        "readable-stream": "2.3.6"
+      },
+      "dependencies": {
+        "process-nextick-args": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+          "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
+          "dev": true
+        }
+      }
+    },
+    "co": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+      "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+      "dev": true
+    },
+    "code-point-at": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+      "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+      "dev": true
+    },
+    "collection-map": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz",
+      "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=",
+      "dev": true,
+      "requires": {
+        "arr-map": "2.0.2",
+        "for-own": "1.0.0",
+        "make-iterator": "1.0.1"
+      },
+      "dependencies": {
+        "for-own": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
+          "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
+          "dev": true,
+          "requires": {
+            "for-in": "1.0.2"
+          }
+        }
+      }
+    },
+    "collection-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+      "dev": true,
+      "requires": {
+        "map-visit": "1.0.0",
+        "object-visit": "1.0.1"
+      }
+    },
+    "color-convert": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
+      "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
+      "dev": true,
+      "requires": {
+        "color-name": "1.1.3"
+      }
+    },
+    "color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "dev": true
+    },
+    "color-support": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
+      "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
+      "dev": true
+    },
+    "commander": {
+      "version": "2.15.1",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
+      "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
+      "dev": true
+    },
+    "component-emitter": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+      "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+      "dev": true
+    },
+    "concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+      "dev": true
+    },
+    "concat-stream": {
+      "version": "1.6.2",
+      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+      "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+      "dev": true,
+      "requires": {
+        "buffer-from": "1.1.0",
+        "inherits": "2.0.3",
+        "readable-stream": "2.3.6",
+        "typedarray": "0.0.6"
+      }
+    },
+    "concat-with-sourcemaps": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz",
+      "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==",
+      "dev": true,
+      "requires": {
+        "source-map": "0.6.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "convert-source-map": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz",
+      "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=",
+      "dev": true
+    },
+    "copy-descriptor": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+      "dev": true
+    },
+    "copy-props": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.4.tgz",
+      "integrity": "sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==",
+      "dev": true,
+      "requires": {
+        "each-props": "1.3.2",
+        "is-plain-object": "2.0.4"
+      }
+    },
+    "core-js": {
+      "version": "2.5.7",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz",
+      "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==",
+      "dev": true
+    },
+    "core-util-is": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+      "dev": true
+    },
+    "cross-spawn": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+      "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+      "dev": true,
+      "requires": {
+        "lru-cache": "4.1.3",
+        "shebang-command": "1.2.0",
+        "which": "1.3.1"
+      }
+    },
+    "css": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/css/-/css-2.2.3.tgz",
+      "integrity": "sha512-0W171WccAjQGGTKLhw4m2nnl0zPHUlTO/I8td4XzJgIB8Hg3ZZx71qT4G4eX8OVsSiaAKiUMy73E3nsbPlg2DQ==",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "source-map": "0.1.43",
+        "source-map-resolve": "0.5.2",
+        "urix": "0.1.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.1.43",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz",
+          "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=",
+          "dev": true,
+          "requires": {
+            "amdefine": "1.0.1"
+          }
+        }
+      }
+    },
+    "d": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
+      "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
+      "dev": true,
+      "requires": {
+        "es5-ext": "0.10.45"
+      }
+    },
+    "d3": {
+      "version": "3.5.17",
+      "resolved": "https://registry.npmjs.org/d3/-/d3-3.5.17.tgz",
+      "integrity": "sha1-vEZ0gAQ3iyGjYMn8fPUjF5B2L7g="
+    },
+    "d3-path": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.5.tgz",
+      "integrity": "sha1-JB6xhJvZ6egCHA0KeZ+KDo5EF2Q="
+    },
+    "d3-queue": {
+      "version": "3.0.7",
+      "resolved": "https://registry.npmjs.org/d3-queue/-/d3-queue-3.0.7.tgz",
+      "integrity": "sha1-yTouVLQXwJWRKdfXP2z31Ckudhg="
+    },
+    "d3-time": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.0.8.tgz",
+      "integrity": "sha512-YRZkNhphZh3KcnBfitvF3c6E0JOFGikHZ4YqD+Lzv83ZHn1/u6yGenRU1m+KAk9J1GnZMnKcrtfvSktlA1DXNQ=="
+    },
+    "d3-time-format": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.1.1.tgz",
+      "integrity": "sha512-8kAkymq2WMfzW7e+s/IUNAtN/y3gZXGRrdGfo6R8NKPAA85UBTxZg5E61bR6nLwjPjj4d3zywSQe1CkYLPFyrw==",
+      "requires": {
+        "d3-time": "1.0.8"
+      }
+    },
+    "debug": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+      "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+      "requires": {
+        "ms": "2.0.0"
+      }
+    },
+    "debug-fabulous": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.1.0.tgz",
+      "integrity": "sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg==",
+      "dev": true,
+      "requires": {
+        "debug": "3.1.0",
+        "memoizee": "0.4.12",
+        "object-assign": "4.1.1"
+      }
+    },
+    "decamelize": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+      "dev": true
+    },
+    "decode-uri-component": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+      "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+      "dev": true
+    },
+    "deep-is": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+      "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+      "dev": true
+    },
+    "default-compare": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz",
+      "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==",
+      "dev": true,
+      "requires": {
+        "kind-of": "5.1.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        }
+      }
+    },
+    "default-resolution": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz",
+      "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=",
+      "dev": true
+    },
+    "define-properties": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz",
+      "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=",
+      "dev": true,
+      "requires": {
+        "foreach": "2.0.5",
+        "object-keys": "1.0.11"
+      }
+    },
+    "define-property": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+      "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+      "dev": true,
+      "requires": {
+        "is-descriptor": "1.0.2",
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "1.0.0",
+            "is-data-descriptor": "1.0.0",
+            "kind-of": "6.0.2"
+          }
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "del": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz",
+      "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=",
+      "dev": true,
+      "requires": {
+        "globby": "6.1.0",
+        "is-path-cwd": "1.0.0",
+        "is-path-in-cwd": "1.0.1",
+        "p-map": "1.2.0",
+        "pify": "3.0.0",
+        "rimraf": "2.6.2"
+      }
+    },
+    "detect-file": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
+      "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
+      "dev": true
+    },
+    "detect-indent": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
+      "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=",
+      "dev": true,
+      "requires": {
+        "repeating": "2.0.1"
+      }
+    },
+    "detect-newline": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz",
+      "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=",
+      "dev": true
+    },
+    "diff": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
+      "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
+      "dev": true
+    },
+    "dispatch-management": {
+      "version": "0.1.21",
+      "resolved": "https://registry.npmjs.org/dispatch-management/-/dispatch-management-0.1.21.tgz",
+      "integrity": "sha512-BfD3w/61q4mshOKIQKpzS5NBZNiUkJgdL65soyBghsU+ICFgshXWxwHsIl4fPaTezR3IuHAaWqS4wGnzAfhDlg==",
+      "requires": {
+        "d3-queue": "3.0.7"
+      }
+    },
+    "doctrine": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+      "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+      "dev": true,
+      "requires": {
+        "esutils": "2.0.2"
+      }
+    },
+    "duplexify": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz",
+      "integrity": "sha512-fO3Di4tBKJpYTFHAxTU00BcfWMY9w24r/x21a6rZRbsD/ToUgGxsMbiGRmB7uVAXeGKXD9MwiLZa5E97EVgIRQ==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "1.4.1",
+        "inherits": "2.0.3",
+        "readable-stream": "2.3.6",
+        "stream-shift": "1.0.0"
+      }
+    },
+    "each-props": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz",
+      "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==",
+      "dev": true,
+      "requires": {
+        "is-plain-object": "2.0.4",
+        "object.defaults": "1.1.0"
+      }
+    },
+    "electron-to-chromium": {
+      "version": "1.3.48",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.48.tgz",
+      "integrity": "sha1-07DYWTgUBE4JLs4hCPw6ya6kuQA=",
+      "dev": true
+    },
+    "end-of-stream": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
+      "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
+      "dev": true,
+      "requires": {
+        "once": "1.4.0"
+      }
+    },
+    "error-ex": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
+      "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
+      "dev": true,
+      "requires": {
+        "is-arrayish": "0.2.1"
+      }
+    },
+    "es5-ext": {
+      "version": "0.10.45",
+      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz",
+      "integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==",
+      "dev": true,
+      "requires": {
+        "es6-iterator": "2.0.3",
+        "es6-symbol": "3.1.1",
+        "next-tick": "1.0.0"
+      }
+    },
+    "es6-iterator": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+      "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.45",
+        "es6-symbol": "3.1.1"
+      }
+    },
+    "es6-symbol": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
+      "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.45"
+      }
+    },
+    "es6-weak-map": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz",
+      "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.45",
+        "es6-iterator": "2.0.3",
+        "es6-symbol": "3.1.1"
+      }
+    },
+    "escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+      "dev": true
+    },
+    "eslint": {
+      "version": "4.19.1",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz",
+      "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==",
+      "dev": true,
+      "requires": {
+        "ajv": "5.5.2",
+        "babel-code-frame": "6.26.0",
+        "chalk": "2.4.1",
+        "concat-stream": "1.6.2",
+        "cross-spawn": "5.1.0",
+        "debug": "3.1.0",
+        "doctrine": "2.1.0",
+        "eslint-scope": "3.7.1",
+        "eslint-visitor-keys": "1.0.0",
+        "espree": "3.5.4",
+        "esquery": "1.0.1",
+        "esutils": "2.0.2",
+        "file-entry-cache": "2.0.0",
+        "functional-red-black-tree": "1.0.1",
+        "glob": "7.1.2",
+        "globals": "11.5.0",
+        "ignore": "3.3.8",
+        "imurmurhash": "0.1.4",
+        "inquirer": "3.3.0",
+        "is-resolvable": "1.1.0",
+        "js-yaml": "3.12.0",
+        "json-stable-stringify-without-jsonify": "1.0.1",
+        "levn": "0.3.0",
+        "lodash": "4.17.10",
+        "minimatch": "3.0.4",
+        "mkdirp": "0.5.1",
+        "natural-compare": "1.4.0",
+        "optionator": "0.8.2",
+        "path-is-inside": "1.0.2",
+        "pluralize": "7.0.0",
+        "progress": "2.0.0",
+        "regexpp": "1.1.0",
+        "require-uncached": "1.0.3",
+        "semver": "5.5.0",
+        "strip-ansi": "4.0.0",
+        "strip-json-comments": "2.0.1",
+        "table": "4.0.2",
+        "text-table": "0.2.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.1"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.1",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "5.4.0"
+          }
+        },
+        "globals": {
+          "version": "11.5.0",
+          "resolved": "https://registry.npmjs.org/globals/-/globals-11.5.0.tgz",
+          "integrity": "sha512-hYyf+kI8dm3nORsiiXUQigOU62hDLfJ9G01uyGMxhc6BKsircrUhC4uJPQPUSuq2GrTmiiEt7ewxlMdBewfmKQ==",
+          "dev": true
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "3.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+          "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+          "dev": true,
+          "requires": {
+            "has-flag": "3.0.0"
+          }
+        }
+      }
+    },
+    "eslint-scope": {
+      "version": "3.7.1",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz",
+      "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=",
+      "dev": true,
+      "requires": {
+        "esrecurse": "4.2.1",
+        "estraverse": "4.2.0"
+      }
+    },
+    "eslint-visitor-keys": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
+      "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==",
+      "dev": true
+    },
+    "espree": {
+      "version": "3.5.4",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz",
+      "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==",
+      "dev": true,
+      "requires": {
+        "acorn": "5.6.1",
+        "acorn-jsx": "3.0.1"
+      }
+    },
+    "esprima": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
+      "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
+      "dev": true
+    },
+    "esquery": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz",
+      "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==",
+      "dev": true,
+      "requires": {
+        "estraverse": "4.2.0"
+      }
+    },
+    "esrecurse": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+      "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
+      "dev": true,
+      "requires": {
+        "estraverse": "4.2.0"
+      }
+    },
+    "estraverse": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+      "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+      "dev": true
+    },
+    "esutils": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+      "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
+      "dev": true
+    },
+    "event-emitter": {
+      "version": "0.3.5",
+      "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+      "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.45"
+      }
+    },
+    "expand-brackets": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
+      "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
+      "dev": true,
+      "requires": {
+        "is-posix-bracket": "0.1.1"
+      }
+    },
+    "expand-range": {
+      "version": "1.8.2",
+      "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
+      "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
+      "dev": true,
+      "requires": {
+        "fill-range": "2.2.4"
+      }
+    },
+    "expand-tilde": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
+      "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
+      "dev": true,
+      "requires": {
+        "homedir-polyfill": "1.0.1"
+      }
+    },
+    "extend": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+      "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
+      "dev": true
+    },
+    "extend-shallow": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+      "dev": true,
+      "requires": {
+        "assign-symbols": "1.0.0",
+        "is-extendable": "1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "2.0.4"
+          }
+        }
+      }
+    },
+    "external-editor": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
+      "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==",
+      "dev": true,
+      "requires": {
+        "chardet": "0.4.2",
+        "iconv-lite": "0.4.23",
+        "tmp": "0.0.33"
+      }
+    },
+    "extglob": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
+      "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
+      "dev": true,
+      "requires": {
+        "is-extglob": "1.0.0"
+      }
+    },
+    "fancy-log": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.2.tgz",
+      "integrity": "sha1-9BEl49hPLn2JpD0G2VjI94vha+E=",
+      "dev": true,
+      "requires": {
+        "ansi-gray": "0.1.1",
+        "color-support": "1.1.3",
+        "time-stamp": "1.1.0"
+      }
+    },
+    "fast-deep-equal": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
+      "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=",
+      "dev": true
+    },
+    "fast-json-stable-stringify": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+      "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
+      "dev": true
+    },
+    "fast-levenshtein": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+      "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+      "dev": true
+    },
+    "figures": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+      "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+      "dev": true,
+      "requires": {
+        "escape-string-regexp": "1.0.5"
+      }
+    },
+    "file-entry-cache": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
+      "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
+      "dev": true,
+      "requires": {
+        "flat-cache": "1.3.0",
+        "object-assign": "4.1.1"
+      }
+    },
+    "filename-regex": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
+      "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=",
+      "dev": true
+    },
+    "fill-range": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz",
+      "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==",
+      "dev": true,
+      "requires": {
+        "is-number": "2.1.0",
+        "isobject": "2.1.0",
+        "randomatic": "3.0.0",
+        "repeat-element": "1.1.2",
+        "repeat-string": "1.6.1"
+      }
+    },
+    "find-up": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+      "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+      "dev": true,
+      "requires": {
+        "path-exists": "2.1.0",
+        "pinkie-promise": "2.0.1"
+      }
+    },
+    "findup-sync": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz",
+      "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=",
+      "dev": true,
+      "requires": {
+        "detect-file": "1.0.0",
+        "is-glob": "3.1.0",
+        "micromatch": "3.1.10",
+        "resolve-dir": "1.0.1"
+      },
+      "dependencies": {
+        "arr-diff": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+          "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+          "dev": true
+        },
+        "array-unique": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+          "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+          "dev": true
+        },
+        "braces": {
+          "version": "2.3.2",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+          "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+          "dev": true,
+          "requires": {
+            "arr-flatten": "1.1.0",
+            "array-unique": "0.3.2",
+            "extend-shallow": "2.0.1",
+            "fill-range": "4.0.0",
+            "isobject": "3.0.1",
+            "repeat-element": "1.1.2",
+            "snapdragon": "0.8.2",
+            "snapdragon-node": "2.1.1",
+            "split-string": "3.1.0",
+            "to-regex": "3.0.2"
+          },
+          "dependencies": {
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "0.1.1"
+              }
+            }
+          }
+        },
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "expand-brackets": {
+          "version": "2.1.4",
+          "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+          "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+          "dev": true,
+          "requires": {
+            "debug": "2.6.9",
+            "define-property": "0.2.5",
+            "extend-shallow": "2.0.1",
+            "posix-character-classes": "0.1.1",
+            "regex-not": "1.0.2",
+            "snapdragon": "0.8.2",
+            "to-regex": "3.0.2"
+          },
+          "dependencies": {
+            "define-property": {
+              "version": "0.2.5",
+              "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+              "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+              "dev": true,
+              "requires": {
+                "is-descriptor": "0.1.6"
+              }
+            },
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "0.1.1"
+              }
+            },
+            "is-accessor-descriptor": {
+              "version": "0.1.6",
+              "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+              "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+              "dev": true,
+              "requires": {
+                "kind-of": "3.2.2"
+              },
+              "dependencies": {
+                "kind-of": {
+                  "version": "3.2.2",
+                  "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+                  "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+                  "dev": true,
+                  "requires": {
+                    "is-buffer": "1.1.6"
+                  }
+                }
+              }
+            },
+            "is-data-descriptor": {
+              "version": "0.1.4",
+              "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+              "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+              "dev": true,
+              "requires": {
+                "kind-of": "3.2.2"
+              },
+              "dependencies": {
+                "kind-of": {
+                  "version": "3.2.2",
+                  "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+

<TRUNCATED>

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[3/3] qpid-dispatch git commit: DISPATCH-1017 Added console build.

Posted by ea...@apache.org.
DISPATCH-1017 Added console build.


Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/0310ac22
Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/0310ac22
Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/0310ac22

Branch: refs/heads/master
Commit: 0310ac224a61e9ee2aca447fe6fdf9d75ec5de11
Parents: 43b3b2e
Author: Ernest Allen <ea...@redhat.com>
Authored: Mon Jun 4 18:00:00 2018 -0400
Committer: Ernest Allen <ea...@redhat.com>
Committed: Mon Jun 4 18:00:00 2018 -0400

----------------------------------------------------------------------
 .gitignore                                      |    2 +
 console/CMakeLists.txt                          |  105 +-
 console/hawtio/pom.xml                          |   37 +-
 console/stand-alone/gulpfile.js                 |  190 +
 console/stand-alone/index.html                  |  102 +-
 console/stand-alone/package-lock.json           | 7570 +++++++++++++++++-
 console/stand-alone/package.json                |   22 +-
 console/stand-alone/plugin/css/dispatch.css     |    2 +-
 console/stand-alone/plugin/js/dispatchPlugin.js |   10 +-
 .../plugin/js/topology/qdrTopology.js           |    4 +-
 .../stand-alone/plugin/js/topology/traffic.js   |  440 -
 .../stand-alone/plugin/js/topology/traffic.ts   |  443 +
 console/stand-alone/tsconfig.json               |   31 +
 console/stand-alone/tslint.json                 |   64 +
 console/stand-alone/vendor-css.txt              |   25 +
 console/stand-alone/vendor-js.txt               |   43 +
 16 files changed, 8524 insertions(+), 566 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/0310ac22/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 0b06144..49a9c44 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,5 @@ console/test/topolgies/config-*
 .history
 .tox
 .vscode
+console/stand-alone/node_modules/
+console/stand-alone/dist/

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/0310ac22/console/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/console/CMakeLists.txt b/console/CMakeLists.txt
index 8918936..38b2de3 100644
--- a/console/CMakeLists.txt
+++ b/console/CMakeLists.txt
@@ -17,20 +17,105 @@
 ## under the License.
 ##
 
-set(CONSOLE_BASE_SOURCE_DIR "${CMAKE_SOURCE_DIR}/console/stand-alone/")
-
 ##
-## Add option to not install the stand-alone console
+## Add cmake option to choose whether to install stand-alone console
 ##
-option(CONSOLE_INSTALL "Install stand-alone console" ON)
+option(CONSOLE_INSTALL "Build and install console (requires npm)" ON)
+
 if(CONSOLE_INSTALL)
+  find_program(NPM_EXE npm DOC "Location of the npm package manager")
+    if (NPM_EXE)
 
-       # Static console files
-       install(
-         DIRECTORY ${CONSOLE_BASE_SOURCE_DIR}
-          DESTINATION ${CONSOLE_STAND_ALONE_INSTALL_DIR}
-    )
+      set(CONSOLE_SOURCE_DIR "${CMAKE_SOURCE_DIR}/console/stand-alone")
+      set(CONSOLE_BUILD_DIR "${CMAKE_BINARY_DIR}/console")
+
+      ## Files needed to create the ${CONSOLE_ARTIFACTS}
+      file (GLOB_RECURSE CONSOLE_JS_SOURCES ${CONSOLE_SOURCE_DIR}/plugin/js/*.js)
+      file (GLOB_RECURSE CONSOLE_TS_SOURCES ${CONSOLE_SOURCE_DIR}/plugin/js/*.ts)
+      set(CONSOLE_CSS_SOURCE ${CONSOLE_SOURCE_DIR}/plugin/css/dispatch.css)
+      set(ALL_CONSOLE_SOURCES ${CONSOLE_JS_SOURCES} ${CONSOLE_TS_SOURCES} ${CONSOLE_CSS_SOURCE})
+
+      ## Files created during the console build
+      set(CONSOLE_ARTIFACTS
+        ${CONSOLE_BUILD_DIR}/dist/js/dispatch.min.js
+        ${CONSOLE_BUILD_DIR}/dist/js/vendor.min.js
+        ${CONSOLE_BUILD_DIR}/dist/css/dispatch.min.css
+        ${CONSOLE_BUILD_DIR}/dist/css/vendor.min.css
+      )
+
+      ## copy the build config files
+      configure_file( ${CONSOLE_SOURCE_DIR}/package.json ${CONSOLE_BUILD_DIR}/ COPYONLY)
+      configure_file( ${CONSOLE_SOURCE_DIR}/package-lock.json ${CONSOLE_BUILD_DIR}/ COPYONLY)
+      configure_file( ${CONSOLE_SOURCE_DIR}/tslint.json ${CONSOLE_BUILD_DIR}/ COPYONLY)
+      configure_file( ${CONSOLE_SOURCE_DIR}/gulpfile.js ${CONSOLE_BUILD_DIR}/ COPYONLY)
+      configure_file( ${CONSOLE_SOURCE_DIR}/vendor-js.txt ${CONSOLE_BUILD_DIR}/ COPYONLY)
+      configure_file( ${CONSOLE_SOURCE_DIR}/vendor-css.txt ${CONSOLE_BUILD_DIR}/ COPYONLY)
+
+      ## Tell cmake how and when to build ${CONSOLE_ARTIFACTS}
+      add_custom_command (
+        OUTPUT ${CONSOLE_ARTIFACTS}
+        COMMENT "Running console build"
+        COMMAND npm install --loglevel=error
+        COMMAND npx gulp --src ${CONSOLE_SOURCE_DIR}
+        DEPENDS ${ALL_CONSOLE_SOURCES}
+        WORKING_DIRECTORY ${CONSOLE_BUILD_DIR}/
+        )
+
+      ## Ensure ${CONSOLE_ARTIFACTS} is built on a make when needed
+      add_custom_target(console ALL
+        DEPENDS ${CONSOLE_ARTIFACTS}
+      )
+
+      ##
+      ## Install the static and built console files
+      ##
+
+      ## Files copied to the root of the console's install dir
+      set(BASE_FILES
+        ${CONSOLE_SOURCE_DIR}/index.html
+        ${CONSOLE_SOURCE_DIR}/favicon-32x32.png
+      )
+      ## Files copied to the css/ dir
+      set(CSS_FONTS
+        ${CONSOLE_SOURCE_DIR}/plugin/css/brokers.ttf
+        ${CONSOLE_BUILD_DIR}/node_modules/angular-ui-grid/ui-grid.woff
+        ${CONSOLE_BUILD_DIR}/node_modules/angular-ui-grid/ui-grid.ttf
+      )
+      ## Files copied to the fonts/ dir
+      set(VENDOR_FONTS
+        ${CONSOLE_BUILD_DIR}/node_modules/patternfly/dist/fonts/OpenSans-Regular-webfont.woff2
+        ${CONSOLE_BUILD_DIR}/node_modules/patternfly/dist/fonts/OpenSans-Bold-webfont.woff2
+        ${CONSOLE_BUILD_DIR}/node_modules/patternfly/dist/fonts/OpenSans-Light-webfont.woff2
+        ${CONSOLE_BUILD_DIR}/node_modules/patternfly/dist/fonts/OpenSans-Semibold-webfont.woff2
+        ${CONSOLE_BUILD_DIR}/node_modules/patternfly/dist/fonts/OpenSans-BoldItalic-webfont.woff2
+        ${CONSOLE_BUILD_DIR}/node_modules/patternfly/dist/fonts/OpenSans-Italic-webfont.woff2
+        ${CONSOLE_BUILD_DIR}/node_modules/patternfly/dist/fonts/fontawesome-webfont.woff2
+        ${CONSOLE_BUILD_DIR}/node_modules/patternfly/dist/fonts/fontawesome-webfont.eot
+        ${CONSOLE_BUILD_DIR}/node_modules/patternfly/dist/fonts/PatternFlyIcons-webfont.ttf
+        ${CONSOLE_BUILD_DIR}/node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2
+      )
+
+      install(DIRECTORY ${CONSOLE_BUILD_DIR}/dist/
+        DESTINATION ${CONSOLE_STAND_ALONE_INSTALL_DIR}
+        PATTERN "*.map" EXCLUDE
+      )
+      install(DIRECTORY ${CONSOLE_SOURCE_DIR}/plugin/html/
+        DESTINATION ${CONSOLE_STAND_ALONE_INSTALL_DIR}/html
+        FILES_MATCHING PATTERN "*.html"
+      )
+      install(FILES ${BASE_FILES}
+        DESTINATION ${CONSOLE_STAND_ALONE_INSTALL_DIR}
+      )
+      install(FILES ${CSS_FONTS}
+        DESTINATION ${CONSOLE_STAND_ALONE_INSTALL_DIR}/css/
+      )
+      install(FILES ${VENDOR_FONTS}
+        DESTINATION ${CONSOLE_STAND_ALONE_INSTALL_DIR}/fonts/
+      )
 
+    else(NPM_EXE)
+      message(WARNING "Cannot build console, npm not found")
+    endif(NPM_EXE)
 endif(CONSOLE_INSTALL)
 
 ##
@@ -50,7 +135,7 @@ if (MAVEN_EXE)
        # install the built war file into the console dir
        install(
            # We don't know in advance what the name of the final .war will be because
-               # the war file name depends on the version in the pom.xml. The version will change each release
+           # the war file name depends on the version in the pom.xml. The version will change each release
            CODE "file( GLOB builtwar \"${HAWTIO_BUILD_DIR}/dispatch-hawtio-console*.war\" )"
            CODE "file( INSTALL \${builtwar} DESTINATION \"${CONSOLE_INSTALL_DIR}/hawtio\" )"
        )

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/0310ac22/console/hawtio/pom.xml
----------------------------------------------------------------------
diff --git a/console/hawtio/pom.xml b/console/hawtio/pom.xml
index 7dcb70c..6bf687f 100644
--- a/console/hawtio/pom.xml
+++ b/console/hawtio/pom.xml
@@ -44,16 +44,12 @@
     <url>https://git-wip-us.apache.org/repos/asf?p=qpid-dispatch.git</url>
   </scm>
 
-  <prerequisites>
-    <maven>3.0.4</maven>
-  </prerequisites>
-
   <properties>
     <!-- filtered plugin properties, we don't define plugin-scripts here
       as we build that dynamically using maven-antrun-plugin below. -->
     <!-- plugin-context is what context this plugin will handle requests on
       in the application server -->
-    <plugin-context>/${artifactId}</plugin-context>
+    <plugin-context>/${project.artifactId}</plugin-context>
 
     <!-- plugin-name is the name of our plugin, affects the name used for
       the plugin's mbean -->
@@ -207,7 +203,14 @@
 
       <!-- maven-bundle-plugin config, needed to make this war
         deployable in karaf, defines the context that this bundle
-        should handle requests on -->
+        should handle requests on 
+
+        commented out because of:
+        [WARNING] Manifest org.apache.qpid:dispatch-hawtio-console:war:1.2.0-SNAPSHOT : None of Export-Package, Provide-Package, Private-Package, -testpackages, or -exportcontents is set, therefore no packages will be included
+        [WARNING] Manifest org.apache.qpid:dispatch-hawtio-console:war:1.2.0-SNAPSHOT : No sub JAR or directory WEB-INF/classes
+      -->
+
+      <!--
       <plugin>
         <groupId>org.apache.felix</groupId>
         <artifactId>maven-bundle-plugin</artifactId>
@@ -249,6 +252,28 @@
             <Implementation-Version>${project.version}</Implementation-Version>
           </instructions>
         </configuration>
+      </plugin>-->
+
+      <!-- maven-enforcer-plugin is now used instead of prerequisites for non maven-plugin projects -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-enforcer-plugin</artifactId>
+        <version>3.0.0-M1</version>
+        <executions>
+          <execution>
+            <id>enforce-maven</id>
+            <goals>
+              <goal>enforce</goal>
+            </goals>
+            <configuration>
+              <rules>
+                <requireMavenVersion>
+                  <version>3.0.4</version>
+                </requireMavenVersion>
+              </rules>    
+            </configuration>
+          </execution>
+        </executions>
       </plugin>
 
       <!-- We define the maven-war-plugin here and make sure it uses

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/0310ac22/console/stand-alone/gulpfile.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/gulpfile.js b/console/stand-alone/gulpfile.js
new file mode 100644
index 0000000..46531c3
--- /dev/null
+++ b/console/stand-alone/gulpfile.js
@@ -0,0 +1,190 @@
+var license = `/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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.
+*/
+`;
+
+const gulp = require('gulp'),
+  babel = require('gulp-babel'),
+  concat = require('gulp-concat'),
+  uglify = require('gulp-uglify'),
+  ngAnnotate = require('gulp-ng-annotate'),
+  rename = require('gulp-rename'),
+  cleanCSS = require('gulp-clean-css'),
+  del = require('del'),
+  eslint = require('gulp-eslint'),
+  maps = require('gulp-sourcemaps'),
+  insert = require('gulp-insert'),
+  fs = require('fs'),
+  tsc = require('gulp-typescript'),
+  tslint = require('gulp-tslint');
+  //tsProject = tsc.createProject('tsconfig.json');
+
+  // temp directory for converted typescript files
+const built_ts = 'built_ts';
+
+// fetch command line arguments
+const arg = (argList => {
+  let arg = {}, a, opt, thisOpt, curOpt;
+  for (a = 0; a < argList.length; a++) {
+    thisOpt = argList[a].trim();
+    opt = thisOpt.replace(/^-+/, '');
+
+    if (opt === thisOpt) {
+      // argument value
+      if (curOpt) arg[curOpt] = opt;
+      curOpt = null;
+    }
+    else {
+      // argument name
+      curOpt = opt;
+      arg[curOpt] = true;
+    }
+  }
+  return arg;
+})(process.argv);
+
+var src = arg.src ? arg.src + '/' : '';
+
+const paths = {
+  typescript: {
+    src: src + 'plugin/**/*.ts',
+    dest: built_ts
+  },
+  styles: {
+    src: src + 'plugin/css/**/*.css',
+    dest: 'dist/css/'
+  },
+  scripts: {
+    src: [src + 'plugin/js/**/*.js', built_ts + '/**/*.js'],
+    dest: 'dist/js/'
+  }
+};
+
+function clean() {
+  return del(['dist',built_ts ]);
+}
+function cleanup() {
+  return del([built_ts]);
+}
+function styles() {
+  return gulp.src(paths.styles.src)
+    .pipe(maps.init())
+    .pipe(cleanCSS())
+    .pipe(rename({
+      basename: 'dispatch',
+      suffix: '.min'
+    }))
+    .pipe(insert.prepend(license))
+    .pipe(maps.write('./'))
+    .pipe(gulp.dest(paths.styles.dest));
+}
+function vendor_styles() {
+  var vendor_lines = fs.readFileSync('vendor-css.txt').toString().split('\n');
+  var vendor_files = vendor_lines.filter( function (line) {
+    return (!line.startsWith('-') && line.length > 0);
+  });
+  return gulp.src(vendor_files)
+    .pipe(maps.init())
+    .pipe(concat('vendor.css'))
+    .pipe(cleanCSS())
+    .pipe(rename({
+      basename: 'vendor',
+      suffix: '.min'
+    }))
+    .pipe(maps.write('./'))
+    .pipe(gulp.dest(paths.styles.dest));
+}
+
+function scripts() {
+  return gulp.src(paths.scripts.src, { sourcemaps: true })
+    .pipe(babel({
+      presets: [require.resolve('babel-preset-env')]
+    }))
+    .pipe(ngAnnotate())
+    .pipe(maps.init())
+    .pipe(uglify())
+    .pipe(concat('dispatch.min.js'))
+    .pipe(insert.prepend(license))
+    .pipe(maps.write('./'))
+    .pipe(gulp.dest(paths.scripts.dest));
+}
+
+function vendor_scripts() {
+  var vendor_lines = fs.readFileSync('vendor-js.txt').toString().split('\n');
+  var vendor_files = vendor_lines.filter( function (line) {
+    return (!line.startsWith('-') && line.length > 0);
+  });
+  return gulp.src(vendor_files)
+    .pipe(maps.init())
+    .pipe(uglify())
+    .pipe(concat('vendor.min.js'))
+    .pipe(maps.write('./'))
+    .pipe(gulp.dest(paths.scripts.dest));
+}
+function watch() {
+  gulp.watch(paths.scripts.src, scripts);
+  gulp.watch(paths.styles.src, styles);
+}
+function lint() {
+  return gulp.src('plugin/**/*.js')
+    .pipe(eslint())
+    .pipe(eslint.format())
+    .pipe(eslint.failAfterError());
+}
+
+//function _typescript() {
+//  return tsProject.src({files: src + 'plugin/**/*.ts'})
+//    .pipe(tsProject())
+//    .js.pipe(gulp.dest('build/dist'));
+//}
+
+function typescript() {
+  var tsResult = gulp.src(paths.typescript.src)
+    .pipe(tsc());
+  return tsResult.js.pipe(gulp.dest(paths.typescript.dest));
+}
+
+function ts_lint() {
+  return gulp.src('plugin/js/**/*.ts')
+    .pipe(tslint({
+      formatter: 'verbose'
+    }))
+    .pipe(tslint.report());
+}
+
+var build = gulp.series(
+  clean,                          // removes the dist/ dir
+  gulp.parallel(lint, ts_lint),   // lints the .js, .ts files
+  typescript,                     // converts .ts to .js
+  gulp.parallel(vendor_styles, vendor_scripts, styles, scripts), // uglify and concat
+  cleanup                         // remove .js that were converted from .ts
+);
+
+var vendor = gulp.parallel(vendor_styles, vendor_scripts);
+
+exports.clean = clean;
+exports.watch = watch;
+exports.build = build;
+exports.lint = lint;
+exports.tslint = ts_lint;
+exports.tsc = typescript;
+exports.scripts = scripts;
+exports.styles = styles;
+exports.vendor = vendor;
+
+gulp.task('default', build);

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/0310ac22/console/stand-alone/index.html
----------------------------------------------------------------------
diff --git a/console/stand-alone/index.html b/console/stand-alone/index.html
index 734fcd5..68070a3 100644
--- a/console/stand-alone/index.html
+++ b/console/stand-alone/index.html
@@ -28,24 +28,14 @@ under the License.
 
     <link rel="shortcut icon" type="image/png" href="favicon-32x32.png" sizes="32x32" />
 
-    <link rel="stylesheet" href="node_modules/jquery-ui-dist/jquery-ui.css">
-
-    <!-- PatternFly Styles -->
-    <link rel="stylesheet" href="node_modules/patternfly/dist/css/patternfly.min.css" >
-    <link rel="stylesheet" href="node_modules/patternfly/dist/css/patternfly-additions.min.css" >
-
-    <!-- jquery Styles -->
-    <link rel="stylesheet" href="node_modules/jquery.fancytree/dist/skin-bootstrap-n/ui.fancytree.css" type="text/css"/>
-
-    <!-- charting styles -->
-    <link rel="stylesheet" href="node_modules/c3/c3.css" type="text/css"/>
-
-    <!-- angular Styles -->
-    <link rel="stylesheet" href="node_modules/angular-ui-grid/ui-grid.css" type="text/css"/>
-
-    <!-- local Styles -->
-    <link rel="stylesheet" href="plugin/css/dispatch.css" type="text/css"/>
-
+    <link rel="stylesheet" href="css/vendor.min.css" type="text/css"/>
+    <link rel="stylesheet" href="css/dispatch.min.css" type="text/css"/>
+
+    <style>
+        #installError {
+            display: none;
+        }
+    </style>
 </head>
 <body ng-app="QDR" ng-controller="QDR.Core">
 
@@ -81,84 +71,22 @@ under the License.
 <div class="container-fluid">
     <div class="row">
         <div id="main_container" class="col-md-12">
-            <div ng-view><div id="no-npm">Please run 'npm install' in the console/stand-alone/ directory.</div>
+            <div ng-view><div id="installError">There was an error when installing the console. Please run make install for the router and check for errors.</div></div>
         </div>
     </div>
 </div>
 
-<style>
-    #no-npm {
-        display: none;
-    }
-</style>
-
-<!-- Only needed for IE -->
-<script src="node_modules/bluebird/js/browser/bluebird.js"></script>
+<script type="text/javascript" src="js/vendor.min.js"></script>
+<script type="text/javascript" src="js/dispatch.min.js"></script>
 
-<!-- jQuery -->
-<script src="node_modules/jquery/dist/jquery.js"></script>
-<script src="node_modules/jquery-ui-dist/jquery-ui.js"></script>
-<script src="node_modules/jquery.fancytree/dist/jquery.fancytree-all.js"></script>
 
-<!-- Angular -->
-<script src="node_modules/angular/angular.js"></script>
-<script src="node_modules/angular-animate/angular-animate.min.js"></script>
-<script src="node_modules/angular-sanitize/angular-sanitize.min.js"></script>
-<script src="node_modules/angular-route/angular-route.min.js"></script>
-<script src="node_modules/angular-resource/angular-resource.min.js"></script>
-
-<!-- Bootstrap -->
-<script src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
-<script src="node_modules/angular-ui-bootstrap/dist/ui-bootstrap.js"></script>
-<script src="node_modules/angular-ui-bootstrap/dist/ui-bootstrap-tpls.js"></script>
-
-<!-- d3 -->
-<script src='node_modules/d3/d3.min.js'></script>
-<script src='node_modules/d3-queue/build/d3-queue.min.js'></script>
-<script src='node_modules/d3-time/build/d3-time.min.js'></script>
-<script src='node_modules/d3-time-format/build/d3-time-format.min.js'></script>
-<script src='node_modules/d3-path/build/d3-path.min.js'></script>
-
-<!-- c3 for charts -->
-<script src="node_modules/c3/c3.js"></script>
-
-<script src="node_modules/angular-ui-slider/src/slider.js"></script>
-<script src="node_modules/angular-ui-grid/ui-grid.js"></script>
-<script src="node_modules/angular-bootstrap-checkbox/angular-bootstrap-checkbox.js"></script>
-<script src="node_modules/notifyjs-browser/dist/notify.js"></script>
-<script src="node_modules/patternfly/dist/js/patternfly.min.js"></script>
-
-<script type="text/javascript" src="node_modules/dispatch-management/dist/dispatch-management.js"></script>
-<script type="text/javascript" src="plugin/js/dispatchPlugin.js"></script>
-<script type="text/javascript" src="plugin/js/navbar.js"></script>
-<script type="text/javascript" src="plugin/js/qdrGlobals.js"></script>
-<script type="text/javascript" src="plugin/js/qdrOverview.js"></script>
-<script type="text/javascript" src="plugin/js/qdrOverviewLogsController.js"></script>
-<script type="text/javascript" src="plugin/js/qdrOverviewChartsController.js"></script>
-<script type="text/javascript" src="plugin/js/qdrTopAddressesController.js"></script>
-<script type="text/javascript" src="plugin/js/dlgChartController.js"></script>
-<script type="text/javascript" src="plugin/js/qdrList.js"></script>
-<script type="text/javascript" src="plugin/js/qdrListChart.js"></script>
-<script type="text/javascript" src="plugin/js/qdrCharts.js"></script>
-<script type="text/javascript" src="plugin/js/qdrSchema.js"></script>
-<script type="text/javascript" src="plugin/js/qdrService.js"></script>
-<script type="text/javascript" src="plugin/js/qdrChartService.js"></script>
-<script type="text/javascript" src="plugin/js/topology/qdrTopology.js"></script>
-<script type="text/javascript" src="plugin/js/topology/traffic.js"></script>
-<script type="text/javascript" src="plugin/js/qdrSettings.js"></script>
-<script type="text/javascript" src="plugin/js/chord/ribbon/ribbon.js"></script>
-<script type="text/javascript" src="plugin/js/chord/matrix.js"></script>
-<script type="text/javascript" src="plugin/js/chord/filters.js"></script>
-<script type="text/javascript" src="plugin/js/chord/data.js"></script>
-<script type="text/javascript" src="plugin/js/chord/layout/layout.js"></script>
-<script type="text/javascript" src="plugin/js/chord/qdrChord.js"></script>
 <script>
+    // If angular hasn't loaded a page after 1 second, display the error message
     setTimeout(function () {
-        var no_npm = document.getElementById('no-npm');
-        if (no_npm)
-            no_npm.style.display = "block";
+        var installError = document.getElementById('installError');
+        if (installError)
+            installError.style.display = "block";
     }, 1000);
-
     $(function(){
         $('.nav a').on('click', function(){
             $('.navbar-collapse').collapse('hide');


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org