define(["jupyter-js-widgets"], function(__WEBPACK_EXTERNAL_MODULE_2__) { return /******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId])
/******/ 			return installedModules[moduleId].exports;
/******/
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			exports: {},
/******/ 			id: moduleId,
/******/ 			loaded: false
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.loaded = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {

	// Entry point for the notebook bundle containing custom model definitions.
	//
	// Setup notebook base URL
	//
	// Some static assets may be required by the custom widget javascript. The base
	// url for the notebook is not known at build time and is therefore computed
	// dynamically.
	__webpack_require__.p = document.querySelector('body').getAttribute('data-base-url') + 'nbextensions/clustergrammer_widget/';
	
	// Export widget models and views, and the npm package version number.
	module.exports = __webpack_require__(1);
	module.exports['version'] = __webpack_require__(13).version;


/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {

	var widgets = __webpack_require__(2);
	var _ = __webpack_require__(3);
	var d3 = __webpack_require__(4)
	var cgm_fun = __webpack_require__(5);
	var ini_hzome = __webpack_require__(6);
	var Enrichrgram = __webpack_require__(7);
	var url = __webpack_require__(8);
	
	// version 1.10.0
	
	__webpack_require__(9);
	
	// Custom Model. Custom widgets models must at least provide default values
	// for model attributes, including `_model_name`, `_view_name`, `_model_module`
	// and `_view_module` when different from the base class.
	//
	// When serialiazing entire widget state for embedding, only values different from the
	// defaults will be specified.
	var hello_model = widgets.DOMWidgetModel.extend({
	  defaults: _.extend({}, widgets.DOMWidgetModel.prototype.defaults, {
	    _view_name : 'hello_view',
	    _model_name : 'hello_model',
	    _view_module : 'clustergrammer_widget',
	    _model_module : 'clustergrammer_widget',
	    viz_title : 'default value',
	    network: ''
	  })
	});
	
	
	// Custom View. Renders the widget model.
	var hello_view = widgets.DOMWidgetView.extend({
	
	  render: render_function,
	
	  value_changed: function() {
	
	    // this.el.textContent = this.model.get('viz_title');
	    // var inst_network_string = this.model.get('network');
	    // inst_network = JSON.parse(inst_network_string);
	    // d3.select(this.el)
	    //   .classed('.widget_viz',true);
	
	  }
	});
	
	function render_function() {
	
	  // generate unique id for each visualization
	  var viz_number = String(Math.round(Math.random()*10000));
	  var container_name = 'cgm_notebook_' + String(viz_number) ;
	  if (d3.select('#'+container_name).empty() === false){
	    var backup_number = String(Math.round(Math.random()*10000));
	    container_name = container_name + backup_number;
	  }
	
	  // widget-subarea appears to be limited to a width of ~960px in nbviewer
	  d3.select(this.el)
	      .append('div')
	      .classed('clustergrammer_widget', true)
	      .attr('id', container_name)
	      .style('width', '975px')
	      .style('height', '800px');
	
	  var inst_network_string = this.model.get('network');
	
	  inst_network = JSON.parse(inst_network_string);
	
	  var about_string = "<a href='http://clustergrammer.readthedocs.io/clustergrammer_widget.html' target='_blank' ><img src='http://amp.pharm.mssm.edu/clustergrammer/static/img/clustergrammer_logo.png' style='width:130px; margin-left:-5px' alt='clustergrammer'></a>";
	
	  var hzome = ini_hzome();
	
	  // cgm_model needs to be global
	  cgm_model = this;
	
	  var container_id = '#'+container_name;
	  // define arguments object
	  var args = {
	      root: container_id,
	      'network_data': inst_network,
	      'about':about_string,
	      'row_tip_callback':hzome.gene_info,
	      'matrix_update_callback':matrix_update_callback,
	      'cat_update_callback': cat_update_callback,
	      'sidebar_width':135,
	  };
	
	  setTimeout(make_viz, 10, args);
	
	}
	
	function make_viz(args){
	
	  cgm = cgm_fun(args);
	
	  check_setup_enrichr(cgm);
	
	  console.log('DO NOT UPDATE MATRIX STRING WHEN MAKING VIZ')
	
	}
	
	// hack to prevent matrix update string from running in nbviewer
	var inst_url = window.location.href;
	var in_nbviewer = false;
	if (inst_url.indexOf('nbviewer.jupyter.org') > 0){
	  in_nbviewer = true;
	}
	
	// Enrichrgram specific functions
	///////////////////////////////////////////////////////////////
	
	function matrix_update_callback(){
	
	  console.log('matrix_update_callback')
	
	  if (in_nbviewer === false){
	    // wait to update matrix string until updating has finished
	    setTimeout(update_matrix_string, 1500);
	  }
	
	  if (genes_were_found[this.root]){
	    enr_obj[this.root].clear_enrichr_results();
	  }
	
	}
	
	function cat_update_callback(){
	  if (in_nbviewer === false){
	    setTimeout(update_matrix_string, 1500);
	  }
	}
	
	function update_matrix_string(){
	  console.log('*** update matrix string')
	  // update model with matrix string
	  var inst_mat_string = cgm.export_matrix_string();
	  cgm_model.model.set("mat_string", inst_mat_string);
	  cgm_model.touch();
	}
	
	
	var genes_were_found = {};
	enr_obj = {};
	
	function check_setup_enrichr(inst_cgm){
	
	  var has_enrichrgram = _.has(inst_cgm.params.network_data, 'enrichrgram');
	
	  var make_enrichrgram = false;
	  if (has_enrichrgram){
	    make_enrichrgram = inst_cgm.params.network_data.enrichrgram;
	  }
	
	  // Toggle Enrichrgram function
	  if (has_enrichrgram === false){
	
	    // check with Hzome whether rows are genes
	    ////////////////////////////////////////////
	    genes_were_found[inst_cgm.params.root] = false;
	
	    var all_rows = inst_cgm.params.network_data.row_nodes_names;
	    var max_num_genes = 20;
	
	    if (all_rows.length > 20){
	      all_rows = all_rows.slice(0,20);
	    }
	
	    var wait_unit = 500;
	    var wait_time = 0;
	
	    _.each(all_rows, function(inst_name){
	      setTimeout(check_gene_request, wait_time, inst_cgm, inst_name, run_ini_enrichr);
	      wait_time = wait_time + wait_unit;
	    });
	
	  } else if (make_enrichrgram) {
	
	    // make enrichrgram without checking with Hzome
	    /////////////////////////////////////////////////
	    run_ini_enrichr(inst_cgm);
	
	    genes_were_found[inst_cgm.params.root] = true;
	  }
	
	}
	
	function run_ini_enrichr(inst_cgm){
	
	  var inst_root = inst_cgm.params.root;
	
	  var has_enrichrgram = _.has(inst_cgm.params.network_data, 'enrichrgram');
	
	  var make_enrichrgram = false;
	  if (has_enrichrgram){
	    make_enrichrgram = inst_cgm.params.network_data.enrichrgram;
	  }
	
	  if (genes_were_found[inst_root] || make_enrichrgram){
	
	    if (d3.select(inst_root + ' .enrichr_logo').empty()){
	
	      // set up Enrichr category import
	      enr_obj[inst_root] = Enrichrgram(inst_cgm);
	      enr_obj[inst_root].enrichr_icon();
	
	      // set up Enrichr export in dendro modal
	      //////////////////////////////////////////
	
	      // only display for rows
	      var enrichr_section = d3.selectAll(inst_root + ' .dendro_info')
	        .select('.modal-body')
	        .append('div')
	        .classed('enrichr_export_section', true)
	        .style('margin-top', '10px')
	        .style('display','none');
	
	      enrichr_section
	        .append('text')
	        .text('Send genes to ');
	
	      enrichr_section
	        .append('a')
	        .html('Enrichr')
	        .on('click', function(){
	
	          var group_string = d3.select(inst_root + ' .dendro_text input').attr('value');
	
	          // replace all instances of commas with new line
	          var gene_list = group_string.replace(/, /g, '\n');
	
	          ///////////////
	          // clean list
	          ///////////////
	          var enrichr_info = {list: gene_list, description: 'Clustergrammer gene-cluster list' , popup: true};
	
	          // defined globally - will improve
	          enrich(enrichr_info);
	
	        });
	
	    }
	
	  }
	
	}
	
	function check_gene_request(inst_cgm, gene_symbol, run_ini_enrichr){
	
	  if (gene_symbol.indexOf(' ') > 0){
	    gene_symbol = gene_symbol.split(' ')[0];
	  } else if (gene_symbol.indexOf('_') > 0){
	    gene_symbol = gene_symbol.split('_')[0];
	  }
	
	
	  var base_url = 'https://amp.pharm.mssm.edu/Harmonizome/api/1.0/gene/';
	  var url = base_url + gene_symbol;
	
	  if (genes_were_found[inst_cgm.params.root] === false){
	
	    // make sure value is non-numeric
	    if (isNaN(gene_symbol)){
	
	      $.get(url, function(data) {
	
	        data = JSON.parse(data);
	
	        if (data.name != undefined){
	          genes_were_found[inst_cgm.params.root] = true;
	        }
	
	        run_ini_enrichr(inst_cgm, gene_symbol);
	
	      });
	
	    }
	  }
	
	}
	
	function send_to_Enrichr(options) { // http://amp.pharm.mssm.edu/Enrichr/#help
	    var defaultOptions = {
	    description: "",
	    popup: false
	  };
	
	  if (typeof options.description == 'undefined')
	    options.description = defaultOptions.description;
	  if (typeof options.popup == 'undefined')
	    options.popup = defaultOptions.popup;
	  if (typeof options.list == 'undefined')
	    alert('No genes defined.');
	
	  var form = document.createElement('form');
	  form.setAttribute('method', 'post');
	  form.setAttribute('action', 'https://amp.pharm.mssm.edu/Enrichr/enrich');
	  if (options.popup)
	    form.setAttribute('target', '_blank');
	  form.setAttribute('enctype', 'multipart/form-data');
	
	  var listField = document.createElement('input');
	  listField.setAttribute('type', 'hidden');
	  listField.setAttribute('name', 'list');
	  listField.setAttribute('value', options.list);
	  form.appendChild(listField);
	
	  var descField = document.createElement('input');
	  descField.setAttribute('type', 'hidden');
	  descField.setAttribute('name', 'description');
	  descField.setAttribute('value', options.description);
	  form.appendChild(descField);
	
	  document.body.appendChild(form);
	  form.submit();
	  document.body.removeChild(form);
	}
	
	function abort_request(inst_request){
	  console.log('ABORTING REQUEST');
	  inst_request.abort();
	}
	
	module.exports = {
	  hello_model : hello_model,
	  hello_view : hello_view
	};


/***/ },
/* 2 */
/***/ function(module, exports) {

	module.exports = __WEBPACK_EXTERNAL_MODULE_2__;

/***/ },
/* 3 */
/***/ function(module, exports, __webpack_require__) {

	var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;//     Underscore.js 1.8.3
	//     http://underscorejs.org
	//     (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
	//     Underscore may be freely distributed under the MIT license.
	
	(function() {
	
	  // Baseline setup
	  // --------------
	
	  // Establish the root object, `window` in the browser, or `exports` on the server.
	  var root = this;
	
	  // Save the previous value of the `_` variable.
	  var previousUnderscore = root._;
	
	  // Save bytes in the minified (but not gzipped) version:
	  var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
	
	  // Create quick reference variables for speed access to core prototypes.
	  var
	    push             = ArrayProto.push,
	    slice            = ArrayProto.slice,
	    toString         = ObjProto.toString,
	    hasOwnProperty   = ObjProto.hasOwnProperty;
	
	  // All **ECMAScript 5** native function implementations that we hope to use
	  // are declared here.
	  var
	    nativeIsArray      = Array.isArray,
	    nativeKeys         = Object.keys,
	    nativeBind         = FuncProto.bind,
	    nativeCreate       = Object.create;
	
	  // Naked function reference for surrogate-prototype-swapping.
	  var Ctor = function(){};
	
	  // Create a safe reference to the Underscore object for use below.
	  var _ = function(obj) {
	    if (obj instanceof _) return obj;
	    if (!(this instanceof _)) return new _(obj);
	    this._wrapped = obj;
	  };
	
	  // Export the Underscore object for **Node.js**, with
	  // backwards-compatibility for the old `require()` API. If we're in
	  // the browser, add `_` as a global object.
	  if (true) {
	    if (typeof module !== 'undefined' && module.exports) {
	      exports = module.exports = _;
	    }
	    exports._ = _;
	  } else {
	    root._ = _;
	  }
	
	  // Current version.
	  _.VERSION = '1.8.3';
	
	  // Internal function that returns an efficient (for current engines) version
	  // of the passed-in callback, to be repeatedly applied in other Underscore
	  // functions.
	  var optimizeCb = function(func, context, argCount) {
	    if (context === void 0) return func;
	    switch (argCount == null ? 3 : argCount) {
	      case 1: return function(value) {
	        return func.call(context, value);
	      };
	      case 2: return function(value, other) {
	        return func.call(context, value, other);
	      };
	      case 3: return function(value, index, collection) {
	        return func.call(context, value, index, collection);
	      };
	      case 4: return function(accumulator, value, index, collection) {
	        return func.call(context, accumulator, value, index, collection);
	      };
	    }
	    return function() {
	      return func.apply(context, arguments);
	    };
	  };
	
	  // A mostly-internal function to generate callbacks that can be applied
	  // to each element in a collection, returning the desired result — either
	  // identity, an arbitrary callback, a property matcher, or a property accessor.
	  var cb = function(value, context, argCount) {
	    if (value == null) return _.identity;
	    if (_.isFunction(value)) return optimizeCb(value, context, argCount);
	    if (_.isObject(value)) return _.matcher(value);
	    return _.property(value);
	  };
	  _.iteratee = function(value, context) {
	    return cb(value, context, Infinity);
	  };
	
	  // An internal function for creating assigner functions.
	  var createAssigner = function(keysFunc, undefinedOnly) {
	    return function(obj) {
	      var length = arguments.length;
	      if (length < 2 || obj == null) return obj;
	      for (var index = 1; index < length; index++) {
	        var source = arguments[index],
	            keys = keysFunc(source),
	            l = keys.length;
	        for (var i = 0; i < l; i++) {
	          var key = keys[i];
	          if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
	        }
	      }
	      return obj;
	    };
	  };
	
	  // An internal function for creating a new object that inherits from another.
	  var baseCreate = function(prototype) {
	    if (!_.isObject(prototype)) return {};
	    if (nativeCreate) return nativeCreate(prototype);
	    Ctor.prototype = prototype;
	    var result = new Ctor;
	    Ctor.prototype = null;
	    return result;
	  };
	
	  var property = function(key) {
	    return function(obj) {
	      return obj == null ? void 0 : obj[key];
	    };
	  };
	
	  // Helper for collection methods to determine whether a collection
	  // should be iterated as an array or as an object
	  // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
	  // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
	  var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
	  var getLength = property('length');
	  var isArrayLike = function(collection) {
	    var length = getLength(collection);
	    return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
	  };
	
	  // Collection Functions
	  // --------------------
	
	  // The cornerstone, an `each` implementation, aka `forEach`.
	  // Handles raw objects in addition to array-likes. Treats all
	  // sparse array-likes as if they were dense.
	  _.each = _.forEach = function(obj, iteratee, context) {
	    iteratee = optimizeCb(iteratee, context);
	    var i, length;
	    if (isArrayLike(obj)) {
	      for (i = 0, length = obj.length; i < length; i++) {
	        iteratee(obj[i], i, obj);
	      }
	    } else {
	      var keys = _.keys(obj);
	      for (i = 0, length = keys.length; i < length; i++) {
	        iteratee(obj[keys[i]], keys[i], obj);
	      }
	    }
	    return obj;
	  };
	
	  // Return the results of applying the iteratee to each element.
	  _.map = _.collect = function(obj, iteratee, context) {
	    iteratee = cb(iteratee, context);
	    var keys = !isArrayLike(obj) && _.keys(obj),
	        length = (keys || obj).length,
	        results = Array(length);
	    for (var index = 0; index < length; index++) {
	      var currentKey = keys ? keys[index] : index;
	      results[index] = iteratee(obj[currentKey], currentKey, obj);
	    }
	    return results;
	  };
	
	  // Create a reducing function iterating left or right.
	  function createReduce(dir) {
	    // Optimized iterator function as using arguments.length
	    // in the main function will deoptimize the, see #1991.
	    function iterator(obj, iteratee, memo, keys, index, length) {
	      for (; index >= 0 && index < length; index += dir) {
	        var currentKey = keys ? keys[index] : index;
	        memo = iteratee(memo, obj[currentKey], currentKey, obj);
	      }
	      return memo;
	    }
	
	    return function(obj, iteratee, memo, context) {
	      iteratee = optimizeCb(iteratee, context, 4);
	      var keys = !isArrayLike(obj) && _.keys(obj),
	          length = (keys || obj).length,
	          index = dir > 0 ? 0 : length - 1;
	      // Determine the initial value if none is provided.
	      if (arguments.length < 3) {
	        memo = obj[keys ? keys[index] : index];
	        index += dir;
	      }
	      return iterator(obj, iteratee, memo, keys, index, length);
	    };
	  }
	
	  // **Reduce** builds up a single result from a list of values, aka `inject`,
	  // or `foldl`.
	  _.reduce = _.foldl = _.inject = createReduce(1);
	
	  // The right-associative version of reduce, also known as `foldr`.
	  _.reduceRight = _.foldr = createReduce(-1);
	
	  // Return the first value which passes a truth test. Aliased as `detect`.
	  _.find = _.detect = function(obj, predicate, context) {
	    var key;
	    if (isArrayLike(obj)) {
	      key = _.findIndex(obj, predicate, context);
	    } else {
	      key = _.findKey(obj, predicate, context);
	    }
	    if (key !== void 0 && key !== -1) return obj[key];
	  };
	
	  // Return all the elements that pass a truth test.
	  // Aliased as `select`.
	  _.filter = _.select = function(obj, predicate, context) {
	    var results = [];
	    predicate = cb(predicate, context);
	    _.each(obj, function(value, index, list) {
	      if (predicate(value, index, list)) results.push(value);
	    });
	    return results;
	  };
	
	  // Return all the elements for which a truth test fails.
	  _.reject = function(obj, predicate, context) {
	    return _.filter(obj, _.negate(cb(predicate)), context);
	  };
	
	  // Determine whether all of the elements match a truth test.
	  // Aliased as `all`.
	  _.every = _.all = function(obj, predicate, context) {
	    predicate = cb(predicate, context);
	    var keys = !isArrayLike(obj) && _.keys(obj),
	        length = (keys || obj).length;
	    for (var index = 0; index < length; index++) {
	      var currentKey = keys ? keys[index] : index;
	      if (!predicate(obj[currentKey], currentKey, obj)) return false;
	    }
	    return true;
	  };
	
	  // Determine if at least one element in the object matches a truth test.
	  // Aliased as `any`.
	  _.some = _.any = function(obj, predicate, context) {
	    predicate = cb(predicate, context);
	    var keys = !isArrayLike(obj) && _.keys(obj),
	        length = (keys || obj).length;
	    for (var index = 0; index < length; index++) {
	      var currentKey = keys ? keys[index] : index;
	      if (predicate(obj[currentKey], currentKey, obj)) return true;
	    }
	    return false;
	  };
	
	  // Determine if the array or object contains a given item (using `===`).
	  // Aliased as `includes` and `include`.
	  _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) {
	    if (!isArrayLike(obj)) obj = _.values(obj);
	    if (typeof fromIndex != 'number' || guard) fromIndex = 0;
	    return _.indexOf(obj, item, fromIndex) >= 0;
	  };
	
	  // Invoke a method (with arguments) on every item in a collection.
	  _.invoke = function(obj, method) {
	    var args = slice.call(arguments, 2);
	    var isFunc = _.isFunction(method);
	    return _.map(obj, function(value) {
	      var func = isFunc ? method : value[method];
	      return func == null ? func : func.apply(value, args);
	    });
	  };
	
	  // Convenience version of a common use case of `map`: fetching a property.
	  _.pluck = function(obj, key) {
	    return _.map(obj, _.property(key));
	  };
	
	  // Convenience version of a common use case of `filter`: selecting only objects
	  // containing specific `key:value` pairs.
	  _.where = function(obj, attrs) {
	    return _.filter(obj, _.matcher(attrs));
	  };
	
	  // Convenience version of a common use case of `find`: getting the first object
	  // containing specific `key:value` pairs.
	  _.findWhere = function(obj, attrs) {
	    return _.find(obj, _.matcher(attrs));
	  };
	
	  // Return the maximum element (or element-based computation).
	  _.max = function(obj, iteratee, context) {
	    var result = -Infinity, lastComputed = -Infinity,
	        value, computed;
	    if (iteratee == null && obj != null) {
	      obj = isArrayLike(obj) ? obj : _.values(obj);
	      for (var i = 0, length = obj.length; i < length; i++) {
	        value = obj[i];
	        if (value > result) {
	          result = value;
	        }
	      }
	    } else {
	      iteratee = cb(iteratee, context);
	      _.each(obj, function(value, index, list) {
	        computed = iteratee(value, index, list);
	        if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
	          result = value;
	          lastComputed = computed;
	        }
	      });
	    }
	    return result;
	  };
	
	  // Return the minimum element (or element-based computation).
	  _.min = function(obj, iteratee, context) {
	    var result = Infinity, lastComputed = Infinity,
	        value, computed;
	    if (iteratee == null && obj != null) {
	      obj = isArrayLike(obj) ? obj : _.values(obj);
	      for (var i = 0, length = obj.length; i < length; i++) {
	        value = obj[i];
	        if (value < result) {
	          result = value;
	        }
	      }
	    } else {
	      iteratee = cb(iteratee, context);
	      _.each(obj, function(value, index, list) {
	        computed = iteratee(value, index, list);
	        if (computed < lastComputed || computed === Infinity && result === Infinity) {
	          result = value;
	          lastComputed = computed;
	        }
	      });
	    }
	    return result;
	  };
	
	  // Shuffle a collection, using the modern version of the
	  // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
	  _.shuffle = function(obj) {
	    var set = isArrayLike(obj) ? obj : _.values(obj);
	    var length = set.length;
	    var shuffled = Array(length);
	    for (var index = 0, rand; index < length; index++) {
	      rand = _.random(0, index);
	      if (rand !== index) shuffled[index] = shuffled[rand];
	      shuffled[rand] = set[index];
	    }
	    return shuffled;
	  };
	
	  // Sample **n** random values from a collection.
	  // If **n** is not specified, returns a single random element.
	  // The internal `guard` argument allows it to work with `map`.
	  _.sample = function(obj, n, guard) {
	    if (n == null || guard) {
	      if (!isArrayLike(obj)) obj = _.values(obj);
	      return obj[_.random(obj.length - 1)];
	    }
	    return _.shuffle(obj).slice(0, Math.max(0, n));
	  };
	
	  // Sort the object's values by a criterion produced by an iteratee.
	  _.sortBy = function(obj, iteratee, context) {
	    iteratee = cb(iteratee, context);
	    return _.pluck(_.map(obj, function(value, index, list) {
	      return {
	        value: value,
	        index: index,
	        criteria: iteratee(value, index, list)
	      };
	    }).sort(function(left, right) {
	      var a = left.criteria;
	      var b = right.criteria;
	      if (a !== b) {
	        if (a > b || a === void 0) return 1;
	        if (a < b || b === void 0) return -1;
	      }
	      return left.index - right.index;
	    }), 'value');
	  };
	
	  // An internal function used for aggregate "group by" operations.
	  var group = function(behavior) {
	    return function(obj, iteratee, context) {
	      var result = {};
	      iteratee = cb(iteratee, context);
	      _.each(obj, function(value, index) {
	        var key = iteratee(value, index, obj);
	        behavior(result, value, key);
	      });
	      return result;
	    };
	  };
	
	  // Groups the object's values by a criterion. Pass either a string attribute
	  // to group by, or a function that returns the criterion.
	  _.groupBy = group(function(result, value, key) {
	    if (_.has(result, key)) result[key].push(value); else result[key] = [value];
	  });
	
	  // Indexes the object's values by a criterion, similar to `groupBy`, but for
	  // when you know that your index values will be unique.
	  _.indexBy = group(function(result, value, key) {
	    result[key] = value;
	  });
	
	  // Counts instances of an object that group by a certain criterion. Pass
	  // either a string attribute to count by, or a function that returns the
	  // criterion.
	  _.countBy = group(function(result, value, key) {
	    if (_.has(result, key)) result[key]++; else result[key] = 1;
	  });
	
	  // Safely create a real, live array from anything iterable.
	  _.toArray = function(obj) {
	    if (!obj) return [];
	    if (_.isArray(obj)) return slice.call(obj);
	    if (isArrayLike(obj)) return _.map(obj, _.identity);
	    return _.values(obj);
	  };
	
	  // Return the number of elements in an object.
	  _.size = function(obj) {
	    if (obj == null) return 0;
	    return isArrayLike(obj) ? obj.length : _.keys(obj).length;
	  };
	
	  // Split a collection into two arrays: one whose elements all satisfy the given
	  // predicate, and one whose elements all do not satisfy the predicate.
	  _.partition = function(obj, predicate, context) {
	    predicate = cb(predicate, context);
	    var pass = [], fail = [];
	    _.each(obj, function(value, key, obj) {
	      (predicate(value, key, obj) ? pass : fail).push(value);
	    });
	    return [pass, fail];
	  };
	
	  // Array Functions
	  // ---------------
	
	  // Get the first element of an array. Passing **n** will return the first N
	  // values in the array. Aliased as `head` and `take`. The **guard** check
	  // allows it to work with `_.map`.
	  _.first = _.head = _.take = function(array, n, guard) {
	    if (array == null) return void 0;
	    if (n == null || guard) return array[0];
	    return _.initial(array, array.length - n);
	  };
	
	  // Returns everything but the last entry of the array. Especially useful on
	  // the arguments object. Passing **n** will return all the values in
	  // the array, excluding the last N.
	  _.initial = function(array, n, guard) {
	    return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
	  };
	
	  // Get the last element of an array. Passing **n** will return the last N
	  // values in the array.
	  _.last = function(array, n, guard) {
	    if (array == null) return void 0;
	    if (n == null || guard) return array[array.length - 1];
	    return _.rest(array, Math.max(0, array.length - n));
	  };
	
	  // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
	  // Especially useful on the arguments object. Passing an **n** will return
	  // the rest N values in the array.
	  _.rest = _.tail = _.drop = function(array, n, guard) {
	    return slice.call(array, n == null || guard ? 1 : n);
	  };
	
	  // Trim out all falsy values from an array.
	  _.compact = function(array) {
	    return _.filter(array, _.identity);
	  };
	
	  // Internal implementation of a recursive `flatten` function.
	  var flatten = function(input, shallow, strict, startIndex) {
	    var output = [], idx = 0;
	    for (var i = startIndex || 0, length = getLength(input); i < length; i++) {
	      var value = input[i];
	      if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
	        //flatten current level of array or arguments object
	        if (!shallow) value = flatten(value, shallow, strict);
	        var j = 0, len = value.length;
	        output.length += len;
	        while (j < len) {
	          output[idx++] = value[j++];
	        }
	      } else if (!strict) {
	        output[idx++] = value;
	      }
	    }
	    return output;
	  };
	
	  // Flatten out an array, either recursively (by default), or just one level.
	  _.flatten = function(array, shallow) {
	    return flatten(array, shallow, false);
	  };
	
	  // Return a version of the array that does not contain the specified value(s).
	  _.without = function(array) {
	    return _.difference(array, slice.call(arguments, 1));
	  };
	
	  // Produce a duplicate-free version of the array. If the array has already
	  // been sorted, you have the option of using a faster algorithm.
	  // Aliased as `unique`.
	  _.uniq = _.unique = function(array, isSorted, iteratee, context) {
	    if (!_.isBoolean(isSorted)) {
	      context = iteratee;
	      iteratee = isSorted;
	      isSorted = false;
	    }
	    if (iteratee != null) iteratee = cb(iteratee, context);
	    var result = [];
	    var seen = [];
	    for (var i = 0, length = getLength(array); i < length; i++) {
	      var value = array[i],
	          computed = iteratee ? iteratee(value, i, array) : value;
	      if (isSorted) {
	        if (!i || seen !== computed) result.push(value);
	        seen = computed;
	      } else if (iteratee) {
	        if (!_.contains(seen, computed)) {
	          seen.push(computed);
	          result.push(value);
	        }
	      } else if (!_.contains(result, value)) {
	        result.push(value);
	      }
	    }
	    return result;
	  };
	
	  // Produce an array that contains the union: each distinct element from all of
	  // the passed-in arrays.
	  _.union = function() {
	    return _.uniq(flatten(arguments, true, true));
	  };
	
	  // Produce an array that contains every item shared between all the
	  // passed-in arrays.
	  _.intersection = function(array) {
	    var result = [];
	    var argsLength = arguments.length;
	    for (var i = 0, length = getLength(array); i < length; i++) {
	      var item = array[i];
	      if (_.contains(result, item)) continue;
	      for (var j = 1; j < argsLength; j++) {
	        if (!_.contains(arguments[j], item)) break;
	      }
	      if (j === argsLength) result.push(item);
	    }
	    return result;
	  };
	
	  // Take the difference between one array and a number of other arrays.
	  // Only the elements present in just the first array will remain.
	  _.difference = function(array) {
	    var rest = flatten(arguments, true, true, 1);
	    return _.filter(array, function(value){
	      return !_.contains(rest, value);
	    });
	  };
	
	  // Zip together multiple lists into a single array -- elements that share
	  // an index go together.
	  _.zip = function() {
	    return _.unzip(arguments);
	  };
	
	  // Complement of _.zip. Unzip accepts an array of arrays and groups
	  // each array's elements on shared indices
	  _.unzip = function(array) {
	    var length = array && _.max(array, getLength).length || 0;
	    var result = Array(length);
	
	    for (var index = 0; index < length; index++) {
	      result[index] = _.pluck(array, index);
	    }
	    return result;
	  };
	
	  // Converts lists into objects. Pass either a single array of `[key, value]`
	  // pairs, or two parallel arrays of the same length -- one of keys, and one of
	  // the corresponding values.
	  _.object = function(list, values) {
	    var result = {};
	    for (var i = 0, length = getLength(list); i < length; i++) {
	      if (values) {
	        result[list[i]] = values[i];
	      } else {
	        result[list[i][0]] = list[i][1];
	      }
	    }
	    return result;
	  };
	
	  // Generator function to create the findIndex and findLastIndex functions
	  function createPredicateIndexFinder(dir) {
	    return function(array, predicate, context) {
	      predicate = cb(predicate, context);
	      var length = getLength(array);
	      var index = dir > 0 ? 0 : length - 1;
	      for (; index >= 0 && index < length; index += dir) {
	        if (predicate(array[index], index, array)) return index;
	      }
	      return -1;
	    };
	  }
	
	  // Returns the first index on an array-like that passes a predicate test
	  _.findIndex = createPredicateIndexFinder(1);
	  _.findLastIndex = createPredicateIndexFinder(-1);
	
	  // Use a comparator function to figure out the smallest index at which
	  // an object should be inserted so as to maintain order. Uses binary search.
	  _.sortedIndex = function(array, obj, iteratee, context) {
	    iteratee = cb(iteratee, context, 1);
	    var value = iteratee(obj);
	    var low = 0, high = getLength(array);
	    while (low < high) {
	      var mid = Math.floor((low + high) / 2);
	      if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
	    }
	    return low;
	  };
	
	  // Generator function to create the indexOf and lastIndexOf functions
	  function createIndexFinder(dir, predicateFind, sortedIndex) {
	    return function(array, item, idx) {
	      var i = 0, length = getLength(array);
	      if (typeof idx == 'number') {
	        if (dir > 0) {
	            i = idx >= 0 ? idx : Math.max(idx + length, i);
	        } else {
	            length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
	        }
	      } else if (sortedIndex && idx && length) {
	        idx = sortedIndex(array, item);
	        return array[idx] === item ? idx : -1;
	      }
	      if (item !== item) {
	        idx = predicateFind(slice.call(array, i, length), _.isNaN);
	        return idx >= 0 ? idx + i : -1;
	      }
	      for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {
	        if (array[idx] === item) return idx;
	      }
	      return -1;
	    };
	  }
	
	  // Return the position of the first occurrence of an item in an array,
	  // or -1 if the item is not included in the array.
	  // If the array is large and already in sort order, pass `true`
	  // for **isSorted** to use binary search.
	  _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex);
	  _.lastIndexOf = createIndexFinder(-1, _.findLastIndex);
	
	  // Generate an integer Array containing an arithmetic progression. A port of
	  // the native Python `range()` function. See
	  // [the Python documentation](http://docs.python.org/library/functions.html#range).
	  _.range = function(start, stop, step) {
	    if (stop == null) {
	      stop = start || 0;
	      start = 0;
	    }
	    step = step || 1;
	
	    var length = Math.max(Math.ceil((stop - start) / step), 0);
	    var range = Array(length);
	
	    for (var idx = 0; idx < length; idx++, start += step) {
	      range[idx] = start;
	    }
	
	    return range;
	  };
	
	  // Function (ahem) Functions
	  // ------------------
	
	  // Determines whether to execute a function as a constructor
	  // or a normal function with the provided arguments
	  var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
	    if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
	    var self = baseCreate(sourceFunc.prototype);
	    var result = sourceFunc.apply(self, args);
	    if (_.isObject(result)) return result;
	    return self;
	  };
	
	  // Create a function bound to a given object (assigning `this`, and arguments,
	  // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
	  // available.
	  _.bind = function(func, context) {
	    if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
	    if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
	    var args = slice.call(arguments, 2);
	    var bound = function() {
	      return executeBound(func, bound, context, this, args.concat(slice.call(arguments)));
	    };
	    return bound;
	  };
	
	  // Partially apply a function by creating a version that has had some of its
	  // arguments pre-filled, without changing its dynamic `this` context. _ acts
	  // as a placeholder, allowing any combination of arguments to be pre-filled.
	  _.partial = function(func) {
	    var boundArgs = slice.call(arguments, 1);
	    var bound = function() {
	      var position = 0, length = boundArgs.length;
	      var args = Array(length);
	      for (var i = 0; i < length; i++) {
	        args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i];
	      }
	      while (position < arguments.length) args.push(arguments[position++]);
	      return executeBound(func, bound, this, this, args);
	    };
	    return bound;
	  };
	
	  // Bind a number of an object's methods to that object. Remaining arguments
	  // are the method names to be bound. Useful for ensuring that all callbacks
	  // defined on an object belong to it.
	  _.bindAll = function(obj) {
	    var i, length = arguments.length, key;
	    if (length <= 1) throw new Error('bindAll must be passed function names');
	    for (i = 1; i < length; i++) {
	      key = arguments[i];
	      obj[key] = _.bind(obj[key], obj);
	    }
	    return obj;
	  };
	
	  // Memoize an expensive function by storing its results.
	  _.memoize = function(func, hasher) {
	    var memoize = function(key) {
	      var cache = memoize.cache;
	      var address = '' + (hasher ? hasher.apply(this, arguments) : key);
	      if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
	      return cache[address];
	    };
	    memoize.cache = {};
	    return memoize;
	  };
	
	  // Delays a function for the given number of milliseconds, and then calls
	  // it with the arguments supplied.
	  _.delay = function(func, wait) {
	    var args = slice.call(arguments, 2);
	    return setTimeout(function(){
	      return func.apply(null, args);
	    }, wait);
	  };
	
	  // Defers a function, scheduling it to run after the current call stack has
	  // cleared.
	  _.defer = _.partial(_.delay, _, 1);
	
	  // Returns a function, that, when invoked, will only be triggered at most once
	  // during a given window of time. Normally, the throttled function will run
	  // as much as it can, without ever going more than once per `wait` duration;
	  // but if you'd like to disable the execution on the leading edge, pass
	  // `{leading: false}`. To disable execution on the trailing edge, ditto.
	  _.throttle = function(func, wait, options) {
	    var context, args, result;
	    var timeout = null;
	    var previous = 0;
	    if (!options) options = {};
	    var later = function() {
	      previous = options.leading === false ? 0 : _.now();
	      timeout = null;
	      result = func.apply(context, args);
	      if (!timeout) context = args = null;
	    };
	    return function() {
	      var now = _.now();
	      if (!previous && options.leading === false) previous = now;
	      var remaining = wait - (now - previous);
	      context = this;
	      args = arguments;
	      if (remaining <= 0 || remaining > wait) {
	        if (timeout) {
	          clearTimeout(timeout);
	          timeout = null;
	        }
	        previous = now;
	        result = func.apply(context, args);
	        if (!timeout) context = args = null;
	      } else if (!timeout && options.trailing !== false) {
	        timeout = setTimeout(later, remaining);
	      }
	      return result;
	    };
	  };
	
	  // Returns a function, that, as long as it continues to be invoked, will not
	  // be triggered. The function will be called after it stops being called for
	  // N milliseconds. If `immediate` is passed, trigger the function on the
	  // leading edge, instead of the trailing.
	  _.debounce = function(func, wait, immediate) {
	    var timeout, args, context, timestamp, result;
	
	    var later = function() {
	      var last = _.now() - timestamp;
	
	      if (last < wait && last >= 0) {
	        timeout = setTimeout(later, wait - last);
	      } else {
	        timeout = null;
	        if (!immediate) {
	          result = func.apply(context, args);
	          if (!timeout) context = args = null;
	        }
	      }
	    };
	
	    return function() {
	      context = this;
	      args = arguments;
	      timestamp = _.now();
	      var callNow = immediate && !timeout;
	      if (!timeout) timeout = setTimeout(later, wait);
	      if (callNow) {
	        result = func.apply(context, args);
	        context = args = null;
	      }
	
	      return result;
	    };
	  };
	
	  // Returns the first function passed as an argument to the second,
	  // allowing you to adjust arguments, run code before and after, and
	  // conditionally execute the original function.
	  _.wrap = function(func, wrapper) {
	    return _.partial(wrapper, func);
	  };
	
	  // Returns a negated version of the passed-in predicate.
	  _.negate = function(predicate) {
	    return function() {
	      return !predicate.apply(this, arguments);
	    };
	  };
	
	  // Returns a function that is the composition of a list of functions, each
	  // consuming the return value of the function that follows.
	  _.compose = function() {
	    var args = arguments;
	    var start = args.length - 1;
	    return function() {
	      var i = start;
	      var result = args[start].apply(this, arguments);
	      while (i--) result = args[i].call(this, result);
	      return result;
	    };
	  };
	
	  // Returns a function that will only be executed on and after the Nth call.
	  _.after = function(times, func) {
	    return function() {
	      if (--times < 1) {
	        return func.apply(this, arguments);
	      }
	    };
	  };
	
	  // Returns a function that will only be executed up to (but not including) the Nth call.
	  _.before = function(times, func) {
	    var memo;
	    return function() {
	      if (--times > 0) {
	        memo = func.apply(this, arguments);
	      }
	      if (times <= 1) func = null;
	      return memo;
	    };
	  };
	
	  // Returns a function that will be executed at most one time, no matter how
	  // often you call it. Useful for lazy initialization.
	  _.once = _.partial(_.before, 2);
	
	  // Object Functions
	  // ----------------
	
	  // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
	  var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
	  var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
	                      'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
	
	  function collectNonEnumProps(obj, keys) {
	    var nonEnumIdx = nonEnumerableProps.length;
	    var constructor = obj.constructor;
	    var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;
	
	    // Constructor is a special case.
	    var prop = 'constructor';
	    if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);
	
	    while (nonEnumIdx--) {
	      prop = nonEnumerableProps[nonEnumIdx];
	      if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
	        keys.push(prop);
	      }
	    }
	  }
	
	  // Retrieve the names of an object's own properties.
	  // Delegates to **ECMAScript 5**'s native `Object.keys`
	  _.keys = function(obj) {
	    if (!_.isObject(obj)) return [];
	    if (nativeKeys) return nativeKeys(obj);
	    var keys = [];
	    for (var key in obj) if (_.has(obj, key)) keys.push(key);
	    // Ahem, IE < 9.
	    if (hasEnumBug) collectNonEnumProps(obj, keys);
	    return keys;
	  };
	
	  // Retrieve all the property names of an object.
	  _.allKeys = function(obj) {
	    if (!_.isObject(obj)) return [];
	    var keys = [];
	    for (var key in obj) keys.push(key);
	    // Ahem, IE < 9.
	    if (hasEnumBug) collectNonEnumProps(obj, keys);
	    return keys;
	  };
	
	  // Retrieve the values of an object's properties.
	  _.values = function(obj) {
	    var keys = _.keys(obj);
	    var length = keys.length;
	    var values = Array(length);
	    for (var i = 0; i < length; i++) {
	      values[i] = obj[keys[i]];
	    }
	    return values;
	  };
	
	  // Returns the results of applying the iteratee to each element of the object
	  // In contrast to _.map it returns an object
	  _.mapObject = function(obj, iteratee, context) {
	    iteratee = cb(iteratee, context);
	    var keys =  _.keys(obj),
	          length = keys.length,
	          results = {},
	          currentKey;
	      for (var index = 0; index < length; index++) {
	        currentKey = keys[index];
	        results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
	      }
	      return results;
	  };
	
	  // Convert an object into a list of `[key, value]` pairs.
	  _.pairs = function(obj) {
	    var keys = _.keys(obj);
	    var length = keys.length;
	    var pairs = Array(length);
	    for (var i = 0; i < length; i++) {
	      pairs[i] = [keys[i], obj[keys[i]]];
	    }
	    return pairs;
	  };
	
	  // Invert the keys and values of an object. The values must be serializable.
	  _.invert = function(obj) {
	    var result = {};
	    var keys = _.keys(obj);
	    for (var i = 0, length = keys.length; i < length; i++) {
	      result[obj[keys[i]]] = keys[i];
	    }
	    return result;
	  };
	
	  // Return a sorted list of the function names available on the object.
	  // Aliased as `methods`
	  _.functions = _.methods = function(obj) {
	    var names = [];
	    for (var key in obj) {
	      if (_.isFunction(obj[key])) names.push(key);
	    }
	    return names.sort();
	  };
	
	  // Extend a given object with all the properties in passed-in object(s).
	  _.extend = createAssigner(_.allKeys);
	
	  // Assigns a given object with all the own properties in the passed-in object(s)
	  // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
	  _.extendOwn = _.assign = createAssigner(_.keys);
	
	  // Returns the first key on an object that passes a predicate test
	  _.findKey = function(obj, predicate, context) {
	    predicate = cb(predicate, context);
	    var keys = _.keys(obj), key;
	    for (var i = 0, length = keys.length; i < length; i++) {
	      key = keys[i];
	      if (predicate(obj[key], key, obj)) return key;
	    }
	  };
	
	  // Return a copy of the object only containing the whitelisted properties.
	  _.pick = function(object, oiteratee, context) {
	    var result = {}, obj = object, iteratee, keys;
	    if (obj == null) return result;
	    if (_.isFunction(oiteratee)) {
	      keys = _.allKeys(obj);
	      iteratee = optimizeCb(oiteratee, context);
	    } else {
	      keys = flatten(arguments, false, false, 1);
	      iteratee = function(value, key, obj) { return key in obj; };
	      obj = Object(obj);
	    }
	    for (var i = 0, length = keys.length; i < length; i++) {
	      var key = keys[i];
	      var value = obj[key];
	      if (iteratee(value, key, obj)) result[key] = value;
	    }
	    return result;
	  };
	
	   // Return a copy of the object without the blacklisted properties.
	  _.omit = function(obj, iteratee, context) {
	    if (_.isFunction(iteratee)) {
	      iteratee = _.negate(iteratee);
	    } else {
	      var keys = _.map(flatten(arguments, false, false, 1), String);
	      iteratee = function(value, key) {
	        return !_.contains(keys, key);
	      };
	    }
	    return _.pick(obj, iteratee, context);
	  };
	
	  // Fill in a given object with default properties.
	  _.defaults = createAssigner(_.allKeys, true);
	
	  // Creates an object that inherits from the given prototype object.
	  // If additional properties are provided then they will be added to the
	  // created object.
	  _.create = function(prototype, props) {
	    var result = baseCreate(prototype);
	    if (props) _.extendOwn(result, props);
	    return result;
	  };
	
	  // Create a (shallow-cloned) duplicate of an object.
	  _.clone = function(obj) {
	    if (!_.isObject(obj)) return obj;
	    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
	  };
	
	  // Invokes interceptor with the obj, and then returns obj.
	  // The primary purpose of this method is to "tap into" a method chain, in
	  // order to perform operations on intermediate results within the chain.
	  _.tap = function(obj, interceptor) {
	    interceptor(obj);
	    return obj;
	  };
	
	  // Returns whether an object has a given set of `key:value` pairs.
	  _.isMatch = function(object, attrs) {
	    var keys = _.keys(attrs), length = keys.length;
	    if (object == null) return !length;
	    var obj = Object(object);
	    for (var i = 0; i < length; i++) {
	      var key = keys[i];
	      if (attrs[key] !== obj[key] || !(key in obj)) return false;
	    }
	    return true;
	  };
	
	
	  // Internal recursive comparison function for `isEqual`.
	  var eq = function(a, b, aStack, bStack) {
	    // Identical objects are equal. `0 === -0`, but they aren't identical.
	    // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
	    if (a === b) return a !== 0 || 1 / a === 1 / b;
	    // A strict comparison is necessary because `null == undefined`.
	    if (a == null || b == null) return a === b;
	    // Unwrap any wrapped objects.
	    if (a instanceof _) a = a._wrapped;
	    if (b instanceof _) b = b._wrapped;
	    // Compare `[[Class]]` names.
	    var className = toString.call(a);
	    if (className !== toString.call(b)) return false;
	    switch (className) {
	      // Strings, numbers, regular expressions, dates, and booleans are compared by value.
	      case '[object RegExp]':
	      // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
	      case '[object String]':
	        // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
	        // equivalent to `new String("5")`.
	        return '' + a === '' + b;
	      case '[object Number]':
	        // `NaN`s are equivalent, but non-reflexive.
	        // Object(NaN) is equivalent to NaN
	        if (+a !== +a) return +b !== +b;
	        // An `egal` comparison is performed for other numeric values.
	        return +a === 0 ? 1 / +a === 1 / b : +a === +b;
	      case '[object Date]':
	      case '[object Boolean]':
	        // Coerce dates and booleans to numeric primitive values. Dates are compared by their
	        // millisecond representations. Note that invalid dates with millisecond representations
	        // of `NaN` are not equivalent.
	        return +a === +b;
	    }
	
	    var areArrays = className === '[object Array]';
	    if (!areArrays) {
	      if (typeof a != 'object' || typeof b != 'object') return false;
	
	      // Objects with different constructors are not equivalent, but `Object`s or `Array`s
	      // from different frames are.
	      var aCtor = a.constructor, bCtor = b.constructor;
	      if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
	                               _.isFunction(bCtor) && bCtor instanceof bCtor)
	                          && ('constructor' in a && 'constructor' in b)) {
	        return false;
	      }
	    }
	    // Assume equality for cyclic structures. The algorithm for detecting cyclic
	    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
	
	    // Initializing stack of traversed objects.
	    // It's done here since we only need them for objects and arrays comparison.
	    aStack = aStack || [];
	    bStack = bStack || [];
	    var length = aStack.length;
	    while (length--) {
	      // Linear search. Performance is inversely proportional to the number of
	      // unique nested structures.
	      if (aStack[length] === a) return bStack[length] === b;
	    }
	
	    // Add the first object to the stack of traversed objects.
	    aStack.push(a);
	    bStack.push(b);
	
	    // Recursively compare objects and arrays.
	    if (areArrays) {
	      // Compare array lengths to determine if a deep comparison is necessary.
	      length = a.length;
	      if (length !== b.length) return false;
	      // Deep compare the contents, ignoring non-numeric properties.
	      while (length--) {
	        if (!eq(a[length], b[length], aStack, bStack)) return false;
	      }
	    } else {
	      // Deep compare objects.
	      var keys = _.keys(a), key;
	      length = keys.length;
	      // Ensure that both objects contain the same number of properties before comparing deep equality.
	      if (_.keys(b).length !== length) return false;
	      while (length--) {
	        // Deep compare each member
	        key = keys[length];
	        if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
	      }
	    }
	    // Remove the first object from the stack of traversed objects.
	    aStack.pop();
	    bStack.pop();
	    return true;
	  };
	
	  // Perform a deep comparison to check if two objects are equal.
	  _.isEqual = function(a, b) {
	    return eq(a, b);
	  };
	
	  // Is a given array, string, or object empty?
	  // An "empty" object has no enumerable own-properties.
	  _.isEmpty = function(obj) {
	    if (obj == null) return true;
	    if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;
	    return _.keys(obj).length === 0;
	  };
	
	  // Is a given value a DOM element?
	  _.isElement = function(obj) {
	    return !!(obj && obj.nodeType === 1);
	  };
	
	  // Is a given value an array?
	  // Delegates to ECMA5's native Array.isArray
	  _.isArray = nativeIsArray || function(obj) {
	    return toString.call(obj) === '[object Array]';
	  };
	
	  // Is a given variable an object?
	  _.isObject = function(obj) {
	    var type = typeof obj;
	    return type === 'function' || type === 'object' && !!obj;
	  };
	
	  // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.
	  _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {
	    _['is' + name] = function(obj) {
	      return toString.call(obj) === '[object ' + name + ']';
	    };
	  });
	
	  // Define a fallback version of the method in browsers (ahem, IE < 9), where
	  // there isn't any inspectable "Arguments" type.
	  if (!_.isArguments(arguments)) {
	    _.isArguments = function(obj) {
	      return _.has(obj, 'callee');
	    };
	  }
	
	  // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
	  // IE 11 (#1621), and in Safari 8 (#1929).
	  if (typeof /./ != 'function' && typeof Int8Array != 'object') {
	    _.isFunction = function(obj) {
	      return typeof obj == 'function' || false;
	    };
	  }
	
	  // Is a given object a finite number?
	  _.isFinite = function(obj) {
	    return isFinite(obj) && !isNaN(parseFloat(obj));
	  };
	
	  // Is the given value `NaN`? (NaN is the only number which does not equal itself).
	  _.isNaN = function(obj) {
	    return _.isNumber(obj) && obj !== +obj;
	  };
	
	  // Is a given value a boolean?
	  _.isBoolean = function(obj) {
	    return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
	  };
	
	  // Is a given value equal to null?
	  _.isNull = function(obj) {
	    return obj === null;
	  };
	
	  // Is a given variable undefined?
	  _.isUndefined = function(obj) {
	    return obj === void 0;
	  };
	
	  // Shortcut function for checking if an object has a given property directly
	  // on itself (in other words, not on a prototype).
	  _.has = function(obj, key) {
	    return obj != null && hasOwnProperty.call(obj, key);
	  };
	
	  // Utility Functions
	  // -----------------
	
	  // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
	  // previous owner. Returns a reference to the Underscore object.
	  _.noConflict = function() {
	    root._ = previousUnderscore;
	    return this;
	  };
	
	  // Keep the identity function around for default iteratees.
	  _.identity = function(value) {
	    return value;
	  };
	
	  // Predicate-generating functions. Often useful outside of Underscore.
	  _.constant = function(value) {
	    return function() {
	      return value;
	    };
	  };
	
	  _.noop = function(){};
	
	  _.property = property;
	
	  // Generates a function for a given object that returns a given property.
	  _.propertyOf = function(obj) {
	    return obj == null ? function(){} : function(key) {
	      return obj[key];
	    };
	  };
	
	  // Returns a predicate for checking whether an object has a given set of
	  // `key:value` pairs.
	  _.matcher = _.matches = function(attrs) {
	    attrs = _.extendOwn({}, attrs);
	    return function(obj) {
	      return _.isMatch(obj, attrs);
	    };
	  };
	
	  // Run a function **n** times.
	  _.times = function(n, iteratee, context) {
	    var accum = Array(Math.max(0, n));
	    iteratee = optimizeCb(iteratee, context, 1);
	    for (var i = 0; i < n; i++) accum[i] = iteratee(i);
	    return accum;
	  };
	
	  // Return a random integer between min and max (inclusive).
	  _.random = function(min, max) {
	    if (max == null) {
	      max = min;
	      min = 0;
	    }
	    return min + Math.floor(Math.random() * (max - min + 1));
	  };
	
	  // A (possibly faster) way to get the current timestamp as an integer.
	  _.now = Date.now || function() {
	    return new Date().getTime();
	  };
	
	   // List of HTML entities for escaping.
	  var escapeMap = {
	    '&': '&amp;',
	    '<': '&lt;',
	    '>': '&gt;',
	    '"': '&quot;',
	    "'": '&#x27;',
	    '`': '&#x60;'
	  };
	  var unescapeMap = _.invert(escapeMap);
	
	  // Functions for escaping and unescaping strings to/from HTML interpolation.
	  var createEscaper = function(map) {
	    var escaper = function(match) {
	      return map[match];
	    };
	    // Regexes for identifying a key that needs to be escaped
	    var source = '(?:' + _.keys(map).join('|') + ')';
	    var testRegexp = RegExp(source);
	    var replaceRegexp = RegExp(source, 'g');
	    return function(string) {
	      string = string == null ? '' : '' + string;
	      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
	    };
	  };
	  _.escape = createEscaper(escapeMap);
	  _.unescape = createEscaper(unescapeMap);
	
	  // If the value of the named `property` is a function then invoke it with the
	  // `object` as context; otherwise, return it.
	  _.result = function(object, property, fallback) {
	    var value = object == null ? void 0 : object[property];
	    if (value === void 0) {
	      value = fallback;
	    }
	    return _.isFunction(value) ? value.call(object) : value;
	  };
	
	  // Generate a unique integer id (unique within the entire client session).
	  // Useful for temporary DOM ids.
	  var idCounter = 0;
	  _.uniqueId = function(prefix) {
	    var id = ++idCounter + '';
	    return prefix ? prefix + id : id;
	  };
	
	  // By default, Underscore uses ERB-style template delimiters, change the
	  // following template settings to use alternative delimiters.
	  _.templateSettings = {
	    evaluate    : /<%([\s\S]+?)%>/g,
	    interpolate : /<%=([\s\S]+?)%>/g,
	    escape      : /<%-([\s\S]+?)%>/g
	  };
	
	  // When customizing `templateSettings`, if you don't want to define an
	  // interpolation, evaluation or escaping regex, we need one that is
	  // guaranteed not to match.
	  var noMatch = /(.)^/;
	
	  // Certain characters need to be escaped so that they can be put into a
	  // string literal.
	  var escapes = {
	    "'":      "'",
	    '\\':     '\\',
	    '\r':     'r',
	    '\n':     'n',
	    '\u2028': 'u2028',
	    '\u2029': 'u2029'
	  };
	
	  var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
	
	  var escapeChar = function(match) {
	    return '\\' + escapes[match];
	  };
	
	  // JavaScript micro-templating, similar to John Resig's implementation.
	  // Underscore templating handles arbitrary delimiters, preserves whitespace,
	  // and correctly escapes quotes within interpolated code.
	  // NB: `oldSettings` only exists for backwards compatibility.
	  _.template = function(text, settings, oldSettings) {
	    if (!settings && oldSettings) settings = oldSettings;
	    settings = _.defaults({}, settings, _.templateSettings);
	
	    // Combine delimiters into one regular expression via alternation.
	    var matcher = RegExp([
	      (settings.escape || noMatch).source,
	      (settings.interpolate || noMatch).source,
	      (settings.evaluate || noMatch).source
	    ].join('|') + '|$', 'g');
	
	    // Compile the template source, escaping string literals appropriately.
	    var index = 0;
	    var source = "__p+='";
	    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
	      source += text.slice(index, offset).replace(escaper, escapeChar);
	      index = offset + match.length;
	
	      if (escape) {
	        source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
	      } else if (interpolate) {
	        source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
	      } else if (evaluate) {
	        source += "';\n" + evaluate + "\n__p+='";
	      }
	
	      // Adobe VMs need the match returned to produce the correct offest.
	      return match;
	    });
	    source += "';\n";
	
	    // If a variable is not specified, place data values in local scope.
	    if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
	
	    source = "var __t,__p='',__j=Array.prototype.join," +
	      "print=function(){__p+=__j.call(arguments,'');};\n" +
	      source + 'return __p;\n';
	
	    try {
	      var render = new Function(settings.variable || 'obj', '_', source);
	    } catch (e) {
	      e.source = source;
	      throw e;
	    }
	
	    var template = function(data) {
	      return render.call(this, data, _);
	    };
	
	    // Provide the compiled source as a convenience for precompilation.
	    var argument = settings.variable || 'obj';
	    template.source = 'function(' + argument + '){\n' + source + '}';
	
	    return template;
	  };
	
	  // Add a "chain" function. Start chaining a wrapped Underscore object.
	  _.chain = function(obj) {
	    var instance = _(obj);
	    instance._chain = true;
	    return instance;
	  };
	
	  // OOP
	  // ---------------
	  // If Underscore is called as a function, it returns a wrapped object that
	  // can be used OO-style. This wrapper holds altered versions of all the
	  // underscore functions. Wrapped objects may be chained.
	
	  // Helper function to continue chaining intermediate results.
	  var result = function(instance, obj) {
	    return instance._chain ? _(obj).chain() : obj;
	  };
	
	  // Add your own custom functions to the Underscore object.
	  _.mixin = function(obj) {
	    _.each(_.functions(obj), function(name) {
	      var func = _[name] = obj[name];
	      _.prototype[name] = function() {
	        var args = [this._wrapped];
	        push.apply(args, arguments);
	        return result(this, func.apply(_, args));
	      };
	    });
	  };
	
	  // Add all of the Underscore functions to the wrapper object.
	  _.mixin(_);
	
	  // Add all mutator Array functions to the wrapper.
	  _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
	    var method = ArrayProto[name];
	    _.prototype[name] = function() {
	      var obj = this._wrapped;
	      method.apply(obj, arguments);
	      if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
	      return result(this, obj);
	    };
	  });
	
	  // Add all accessor Array functions to the wrapper.
	  _.each(['concat', 'join', 'slice'], function(name) {
	    var method = ArrayProto[name];
	    _.prototype[name] = function() {
	      return result(this, method.apply(this._wrapped, arguments));
	    };
	  });
	
	  // Extracts the result from a wrapped and chained object.
	  _.prototype.value = function() {
	    return this._wrapped;
	  };
	
	  // Provide unwrapping proxy for some methods used in engine operations
	  // such as arithmetic and JSON stringification.
	  _.prototype.valueOf = _.prototype.toJSON = _.prototype.value;
	
	  _.prototype.toString = function() {
	    return '' + this._wrapped;
	  };
	
	  // AMD registration happens at the end for compatibility with AMD loaders
	  // that may not enforce next-turn semantics on modules. Even though general
	  // practice for AMD registration is to be anonymous, underscore registers
	  // as a named module because, like jQuery, it is a base library that is
	  // popular enough to be bundled in a third party lib, but not be part of
	  // an AMD load request. Those cases could generate an error when an
	  // anonymous define() is called outside of a loader request.
	  if (true) {
	    !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() {
	      return _;
	    }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	  }
	}.call(this));


/***/ },
/* 4 */
/***/ function(module, exports, __webpack_require__) {

	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;!function() {
	  var d3 = {
	    version: "3.5.17"
	  };
	  var d3_arraySlice = [].slice, d3_array = function(list) {
	    return d3_arraySlice.call(list);
	  };
	  var d3_document = this.document;
	  function d3_documentElement(node) {
	    return node && (node.ownerDocument || node.document || node).documentElement;
	  }
	  function d3_window(node) {
	    return node && (node.ownerDocument && node.ownerDocument.defaultView || node.document && node || node.defaultView);
	  }
	  if (d3_document) {
	    try {
	      d3_array(d3_document.documentElement.childNodes)[0].nodeType;
	    } catch (e) {
	      d3_array = function(list) {
	        var i = list.length, array = new Array(i);
	        while (i--) array[i] = list[i];
	        return array;
	      };
	    }
	  }
	  if (!Date.now) Date.now = function() {
	    return +new Date();
	  };
	  if (d3_document) {
	    try {
	      d3_document.createElement("DIV").style.setProperty("opacity", 0, "");
	    } catch (error) {
	      var d3_element_prototype = this.Element.prototype, d3_element_setAttribute = d3_element_prototype.setAttribute, d3_element_setAttributeNS = d3_element_prototype.setAttributeNS, d3_style_prototype = this.CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty;
	      d3_element_prototype.setAttribute = function(name, value) {
	        d3_element_setAttribute.call(this, name, value + "");
	      };
	      d3_element_prototype.setAttributeNS = function(space, local, value) {
	        d3_element_setAttributeNS.call(this, space, local, value + "");
	      };
	      d3_style_prototype.setProperty = function(name, value, priority) {
	        d3_style_setProperty.call(this, name, value + "", priority);
	      };
	    }
	  }
	  d3.ascending = d3_ascending;
	  function d3_ascending(a, b) {
	    return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
	  }
	  d3.descending = function(a, b) {
	    return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
	  };
	  d3.min = function(array, f) {
	    var i = -1, n = array.length, a, b;
	    if (arguments.length === 1) {
	      while (++i < n) if ((b = array[i]) != null && b >= b) {
	        a = b;
	        break;
	      }
	      while (++i < n) if ((b = array[i]) != null && a > b) a = b;
	    } else {
	      while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) {
	        a = b;
	        break;
	      }
	      while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b;
	    }
	    return a;
	  };
	  d3.max = function(array, f) {
	    var i = -1, n = array.length, a, b;
	    if (arguments.length === 1) {
	      while (++i < n) if ((b = array[i]) != null && b >= b) {
	        a = b;
	        break;
	      }
	      while (++i < n) if ((b = array[i]) != null && b > a) a = b;
	    } else {
	      while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) {
	        a = b;
	        break;
	      }
	      while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b;
	    }
	    return a;
	  };
	  d3.extent = function(array, f) {
	    var i = -1, n = array.length, a, b, c;
	    if (arguments.length === 1) {
	      while (++i < n) if ((b = array[i]) != null && b >= b) {
	        a = c = b;
	        break;
	      }
	      while (++i < n) if ((b = array[i]) != null) {
	        if (a > b) a = b;
	        if (c < b) c = b;
	      }
	    } else {
	      while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) {
	        a = c = b;
	        break;
	      }
	      while (++i < n) if ((b = f.call(array, array[i], i)) != null) {
	        if (a > b) a = b;
	        if (c < b) c = b;
	      }
	    }
	    return [ a, c ];
	  };
	  function d3_number(x) {
	    return x === null ? NaN : +x;
	  }
	  function d3_numeric(x) {
	    return !isNaN(x);
	  }
	  d3.sum = function(array, f) {
	    var s = 0, n = array.length, a, i = -1;
	    if (arguments.length === 1) {
	      while (++i < n) if (d3_numeric(a = +array[i])) s += a;
	    } else {
	      while (++i < n) if (d3_numeric(a = +f.call(array, array[i], i))) s += a;
	    }
	    return s;
	  };
	  d3.mean = function(array, f) {
	    var s = 0, n = array.length, a, i = -1, j = n;
	    if (arguments.length === 1) {
	      while (++i < n) if (d3_numeric(a = d3_number(array[i]))) s += a; else --j;
	    } else {
	      while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) s += a; else --j;
	    }
	    if (j) return s / j;
	  };
	  d3.quantile = function(values, p) {
	    var H = (values.length - 1) * p + 1, h = Math.floor(H), v = +values[h - 1], e = H - h;
	    return e ? v + e * (values[h] - v) : v;
	  };
	  d3.median = function(array, f) {
	    var numbers = [], n = array.length, a, i = -1;
	    if (arguments.length === 1) {
	      while (++i < n) if (d3_numeric(a = d3_number(array[i]))) numbers.push(a);
	    } else {
	      while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) numbers.push(a);
	    }
	    if (numbers.length) return d3.quantile(numbers.sort(d3_ascending), .5);
	  };
	  d3.variance = function(array, f) {
	    var n = array.length, m = 0, a, d, s = 0, i = -1, j = 0;
	    if (arguments.length === 1) {
	      while (++i < n) {
	        if (d3_numeric(a = d3_number(array[i]))) {
	          d = a - m;
	          m += d / ++j;
	          s += d * (a - m);
	        }
	      }
	    } else {
	      while (++i < n) {
	        if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) {
	          d = a - m;
	          m += d / ++j;
	          s += d * (a - m);
	        }
	      }
	    }
	    if (j > 1) return s / (j - 1);
	  };
	  d3.deviation = function() {
	    var v = d3.variance.apply(this, arguments);
	    return v ? Math.sqrt(v) : v;
	  };
	  function d3_bisector(compare) {
	    return {
	      left: function(a, x, lo, hi) {
	        if (arguments.length < 3) lo = 0;
	        if (arguments.length < 4) hi = a.length;
	        while (lo < hi) {
	          var mid = lo + hi >>> 1;
	          if (compare(a[mid], x) < 0) lo = mid + 1; else hi = mid;
	        }
	        return lo;
	      },
	      right: function(a, x, lo, hi) {
	        if (arguments.length < 3) lo = 0;
	        if (arguments.length < 4) hi = a.length;
	        while (lo < hi) {
	          var mid = lo + hi >>> 1;
	          if (compare(a[mid], x) > 0) hi = mid; else lo = mid + 1;
	        }
	        return lo;
	      }
	    };
	  }
	  var d3_bisect = d3_bisector(d3_ascending);
	  d3.bisectLeft = d3_bisect.left;
	  d3.bisect = d3.bisectRight = d3_bisect.right;
	  d3.bisector = function(f) {
	    return d3_bisector(f.length === 1 ? function(d, x) {
	      return d3_ascending(f(d), x);
	    } : f);
	  };
	  d3.shuffle = function(array, i0, i1) {
	    if ((m = arguments.length) < 3) {
	      i1 = array.length;
	      if (m < 2) i0 = 0;
	    }
	    var m = i1 - i0, t, i;
	    while (m) {
	      i = Math.random() * m-- | 0;
	      t = array[m + i0], array[m + i0] = array[i + i0], array[i + i0] = t;
	    }
	    return array;
	  };
	  d3.permute = function(array, indexes) {
	    var i = indexes.length, permutes = new Array(i);
	    while (i--) permutes[i] = array[indexes[i]];
	    return permutes;
	  };
	  d3.pairs = function(array) {
	    var i = 0, n = array.length - 1, p0, p1 = array[0], pairs = new Array(n < 0 ? 0 : n);
	    while (i < n) pairs[i] = [ p0 = p1, p1 = array[++i] ];
	    return pairs;
	  };
	  d3.transpose = function(matrix) {
	    if (!(n = matrix.length)) return [];
	    for (var i = -1, m = d3.min(matrix, d3_transposeLength), transpose = new Array(m); ++i < m; ) {
	      for (var j = -1, n, row = transpose[i] = new Array(n); ++j < n; ) {
	        row[j] = matrix[j][i];
	      }
	    }
	    return transpose;
	  };
	  function d3_transposeLength(d) {
	    return d.length;
	  }
	  d3.zip = function() {
	    return d3.transpose(arguments);
	  };
	  d3.keys = function(map) {
	    var keys = [];
	    for (var key in map) keys.push(key);
	    return keys;
	  };
	  d3.values = function(map) {
	    var values = [];
	    for (var key in map) values.push(map[key]);
	    return values;
	  };
	  d3.entries = function(map) {
	    var entries = [];
	    for (var key in map) entries.push({
	      key: key,
	      value: map[key]
	    });
	    return entries;
	  };
	  d3.merge = function(arrays) {
	    var n = arrays.length, m, i = -1, j = 0, merged, array;
	    while (++i < n) j += arrays[i].length;
	    merged = new Array(j);
	    while (--n >= 0) {
	      array = arrays[n];
	      m = array.length;
	      while (--m >= 0) {
	        merged[--j] = array[m];
	      }
	    }
	    return merged;
	  };
	  var abs = Math.abs;
	  d3.range = function(start, stop, step) {
	    if (arguments.length < 3) {
	      step = 1;
	      if (arguments.length < 2) {
	        stop = start;
	        start = 0;
	      }
	    }
	    if ((stop - start) / step === Infinity) throw new Error("infinite range");
	    var range = [], k = d3_range_integerScale(abs(step)), i = -1, j;
	    start *= k, stop *= k, step *= k;
	    if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k); else while ((j = start + step * ++i) < stop) range.push(j / k);
	    return range;
	  };
	  function d3_range_integerScale(x) {
	    var k = 1;
	    while (x * k % 1) k *= 10;
	    return k;
	  }
	  function d3_class(ctor, properties) {
	    for (var key in properties) {
	      Object.defineProperty(ctor.prototype, key, {
	        value: properties[key],
	        enumerable: false
	      });
	    }
	  }
	  d3.map = function(object, f) {
	    var map = new d3_Map();
	    if (object instanceof d3_Map) {
	      object.forEach(function(key, value) {
	        map.set(key, value);
	      });
	    } else if (Array.isArray(object)) {
	      var i = -1, n = object.length, o;
	      if (arguments.length === 1) while (++i < n) map.set(i, object[i]); else while (++i < n) map.set(f.call(object, o = object[i], i), o);
	    } else {
	      for (var key in object) map.set(key, object[key]);
	    }
	    return map;
	  };
	  function d3_Map() {
	    this._ = Object.create(null);
	  }
	  var d3_map_proto = "__proto__", d3_map_zero = "\x00";
	  d3_class(d3_Map, {
	    has: d3_map_has,
	    get: function(key) {
	      return this._[d3_map_escape(key)];
	    },
	    set: function(key, value) {
	      return this._[d3_map_escape(key)] = value;
	    },
	    remove: d3_map_remove,
	    keys: d3_map_keys,
	    values: function() {
	      var values = [];
	      for (var key in this._) values.push(this._[key]);
	      return values;
	    },
	    entries: function() {
	      var entries = [];
	      for (var key in this._) entries.push({
	        key: d3_map_unescape(key),
	        value: this._[key]
	      });
	      return entries;
	    },
	    size: d3_map_size,
	    empty: d3_map_empty,
	    forEach: function(f) {
	      for (var key in this._) f.call(this, d3_map_unescape(key), this._[key]);
	    }
	  });
	  function d3_map_escape(key) {
	    return (key += "") === d3_map_proto || key[0] === d3_map_zero ? d3_map_zero + key : key;
	  }
	  function d3_map_unescape(key) {
	    return (key += "")[0] === d3_map_zero ? key.slice(1) : key;
	  }
	  function d3_map_has(key) {
	    return d3_map_escape(key) in this._;
	  }
	  function d3_map_remove(key) {
	    return (key = d3_map_escape(key)) in this._ && delete this._[key];
	  }
	  function d3_map_keys() {
	    var keys = [];
	    for (var key in this._) keys.push(d3_map_unescape(key));
	    return keys;
	  }
	  function d3_map_size() {
	    var size = 0;
	    for (var key in this._) ++size;
	    return size;
	  }
	  function d3_map_empty() {
	    for (var key in this._) return false;
	    return true;
	  }
	  d3.nest = function() {
	    var nest = {}, keys = [], sortKeys = [], sortValues, rollup;
	    function map(mapType, array, depth) {
	      if (depth >= keys.length) return rollup ? rollup.call(nest, array) : sortValues ? array.sort(sortValues) : array;
	      var i = -1, n = array.length, key = keys[depth++], keyValue, object, setter, valuesByKey = new d3_Map(), values;
	      while (++i < n) {
	        if (values = valuesByKey.get(keyValue = key(object = array[i]))) {
	          values.push(object);
	        } else {
	          valuesByKey.set(keyValue, [ object ]);
	        }
	      }
	      if (mapType) {
	        object = mapType();
	        setter = function(keyValue, values) {
	          object.set(keyValue, map(mapType, values, depth));
	        };
	      } else {
	        object = {};
	        setter = function(keyValue, values) {
	          object[keyValue] = map(mapType, values, depth);
	        };
	      }
	      valuesByKey.forEach(setter);
	      return object;
	    }
	    function entries(map, depth) {
	      if (depth >= keys.length) return map;
	      var array = [], sortKey = sortKeys[depth++];
	      map.forEach(function(key, keyMap) {
	        array.push({
	          key: key,
	          values: entries(keyMap, depth)
	        });
	      });
	      return sortKey ? array.sort(function(a, b) {
	        return sortKey(a.key, b.key);
	      }) : array;
	    }
	    nest.map = function(array, mapType) {
	      return map(mapType, array, 0);
	    };
	    nest.entries = function(array) {
	      return entries(map(d3.map, array, 0), 0);
	    };
	    nest.key = function(d) {
	      keys.push(d);
	      return nest;
	    };
	    nest.sortKeys = function(order) {
	      sortKeys[keys.length - 1] = order;
	      return nest;
	    };
	    nest.sortValues = function(order) {
	      sortValues = order;
	      return nest;
	    };
	    nest.rollup = function(f) {
	      rollup = f;
	      return nest;
	    };
	    return nest;
	  };
	  d3.set = function(array) {
	    var set = new d3_Set();
	    if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]);
	    return set;
	  };
	  function d3_Set() {
	    this._ = Object.create(null);
	  }
	  d3_class(d3_Set, {
	    has: d3_map_has,
	    add: function(key) {
	      this._[d3_map_escape(key += "")] = true;
	      return key;
	    },
	    remove: d3_map_remove,
	    values: d3_map_keys,
	    size: d3_map_size,
	    empty: d3_map_empty,
	    forEach: function(f) {
	      for (var key in this._) f.call(this, d3_map_unescape(key));
	    }
	  });
	  d3.behavior = {};
	  function d3_identity(d) {
	    return d;
	  }
	  d3.rebind = function(target, source) {
	    var i = 1, n = arguments.length, method;
	    while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]);
	    return target;
	  };
	  function d3_rebind(target, source, method) {
	    return function() {
	      var value = method.apply(source, arguments);
	      return value === source ? target : value;
	    };
	  }
	  function d3_vendorSymbol(object, name) {
	    if (name in object) return name;
	    name = name.charAt(0).toUpperCase() + name.slice(1);
	    for (var i = 0, n = d3_vendorPrefixes.length; i < n; ++i) {
	      var prefixName = d3_vendorPrefixes[i] + name;
	      if (prefixName in object) return prefixName;
	    }
	  }
	  var d3_vendorPrefixes = [ "webkit", "ms", "moz", "Moz", "o", "O" ];
	  function d3_noop() {}
	  d3.dispatch = function() {
	    var dispatch = new d3_dispatch(), i = -1, n = arguments.length;
	    while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);
	    return dispatch;
	  };
	  function d3_dispatch() {}
	  d3_dispatch.prototype.on = function(type, listener) {
	    var i = type.indexOf("."), name = "";
	    if (i >= 0) {
	      name = type.slice(i + 1);
	      type = type.slice(0, i);
	    }
	    if (type) return arguments.length < 2 ? this[type].on(name) : this[type].on(name, listener);
	    if (arguments.length === 2) {
	      if (listener == null) for (type in this) {
	        if (this.hasOwnProperty(type)) this[type].on(name, null);
	      }
	      return this;
	    }
	  };
	  function d3_dispatch_event(dispatch) {
	    var listeners = [], listenerByName = new d3_Map();
	    function event() {
	      var z = listeners, i = -1, n = z.length, l;
	      while (++i < n) if (l = z[i].on) l.apply(this, arguments);
	      return dispatch;
	    }
	    event.on = function(name, listener) {
	      var l = listenerByName.get(name), i;
	      if (arguments.length < 2) return l && l.on;
	      if (l) {
	        l.on = null;
	        listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1));
	        listenerByName.remove(name);
	      }
	      if (listener) listeners.push(listenerByName.set(name, {
	        on: listener
	      }));
	      return dispatch;
	    };
	    return event;
	  }
	  d3.event = null;
	  function d3_eventPreventDefault() {
	    d3.event.preventDefault();
	  }
	  function d3_eventSource() {
	    var e = d3.event, s;
	    while (s = e.sourceEvent) e = s;
	    return e;
	  }
	  function d3_eventDispatch(target) {
	    var dispatch = new d3_dispatch(), i = 0, n = arguments.length;
	    while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);
	    dispatch.of = function(thiz, argumentz) {
	      return function(e1) {
	        try {
	          var e0 = e1.sourceEvent = d3.event;
	          e1.target = target;
	          d3.event = e1;
	          dispatch[e1.type].apply(thiz, argumentz);
	        } finally {
	          d3.event = e0;
	        }
	      };
	    };
	    return dispatch;
	  }
	  d3.requote = function(s) {
	    return s.replace(d3_requote_re, "\\$&");
	  };
	  var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;
	  var d3_subclass = {}.__proto__ ? function(object, prototype) {
	    object.__proto__ = prototype;
	  } : function(object, prototype) {
	    for (var property in prototype) object[property] = prototype[property];
	  };
	  function d3_selection(groups) {
	    d3_subclass(groups, d3_selectionPrototype);
	    return groups;
	  }
	  var d3_select = function(s, n) {
	    return n.querySelector(s);
	  }, d3_selectAll = function(s, n) {
	    return n.querySelectorAll(s);
	  }, d3_selectMatches = function(n, s) {
	    var d3_selectMatcher = n.matches || n[d3_vendorSymbol(n, "matchesSelector")];
	    d3_selectMatches = function(n, s) {
	      return d3_selectMatcher.call(n, s);
	    };
	    return d3_selectMatches(n, s);
	  };
	  if (typeof Sizzle === "function") {
	    d3_select = function(s, n) {
	      return Sizzle(s, n)[0] || null;
	    };
	    d3_selectAll = Sizzle;
	    d3_selectMatches = Sizzle.matchesSelector;
	  }
	  d3.selection = function() {
	    return d3.select(d3_document.documentElement);
	  };
	  var d3_selectionPrototype = d3.selection.prototype = [];
	  d3_selectionPrototype.select = function(selector) {
	    var subgroups = [], subgroup, subnode, group, node;
	    selector = d3_selection_selector(selector);
	    for (var j = -1, m = this.length; ++j < m; ) {
	      subgroups.push(subgroup = []);
	      subgroup.parentNode = (group = this[j]).parentNode;
	      for (var i = -1, n = group.length; ++i < n; ) {
	        if (node = group[i]) {
	          subgroup.push(subnode = selector.call(node, node.__data__, i, j));
	          if (subnode && "__data__" in node) subnode.__data__ = node.__data__;
	        } else {
	          subgroup.push(null);
	        }
	      }
	    }
	    return d3_selection(subgroups);
	  };
	  function d3_selection_selector(selector) {
	    return typeof selector === "function" ? selector : function() {
	      return d3_select(selector, this);
	    };
	  }
	  d3_selectionPrototype.selectAll = function(selector) {
	    var subgroups = [], subgroup, node;
	    selector = d3_selection_selectorAll(selector);
	    for (var j = -1, m = this.length; ++j < m; ) {
	      for (var group = this[j], i = -1, n = group.length; ++i < n; ) {
	        if (node = group[i]) {
	          subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i, j)));
	          subgroup.parentNode = node;
	        }
	      }
	    }
	    return d3_selection(subgroups);
	  };
	  function d3_selection_selectorAll(selector) {
	    return typeof selector === "function" ? selector : function() {
	      return d3_selectAll(selector, this);
	    };
	  }
	  var d3_nsXhtml = "http://www.w3.org/1999/xhtml";
	  var d3_nsPrefix = {
	    svg: "http://www.w3.org/2000/svg",
	    xhtml: d3_nsXhtml,
	    xlink: "http://www.w3.org/1999/xlink",
	    xml: "http://www.w3.org/XML/1998/namespace",
	    xmlns: "http://www.w3.org/2000/xmlns/"
	  };
	  d3.ns = {
	    prefix: d3_nsPrefix,
	    qualify: function(name) {
	      var i = name.indexOf(":"), prefix = name;
	      if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1);
	      return d3_nsPrefix.hasOwnProperty(prefix) ? {
	        space: d3_nsPrefix[prefix],
	        local: name
	      } : name;
	    }
	  };
	  d3_selectionPrototype.attr = function(name, value) {
	    if (arguments.length < 2) {
	      if (typeof name === "string") {
	        var node = this.node();
	        name = d3.ns.qualify(name);
	        return name.local ? node.getAttributeNS(name.space, name.local) : node.getAttribute(name);
	      }
	      for (value in name) this.each(d3_selection_attr(value, name[value]));
	      return this;
	    }
	    return this.each(d3_selection_attr(name, value));
	  };
	  function d3_selection_attr(name, value) {
	    name = d3.ns.qualify(name);
	    function attrNull() {
	      this.removeAttribute(name);
	    }
	    function attrNullNS() {
	      this.removeAttributeNS(name.space, name.local);
	    }
	    function attrConstant() {
	      this.setAttribute(name, value);
	    }
	    function attrConstantNS() {
	      this.setAttributeNS(name.space, name.local, value);
	    }
	    function attrFunction() {
	      var x = value.apply(this, arguments);
	      if (x == null) this.removeAttribute(name); else this.setAttribute(name, x);
	    }
	    function attrFunctionNS() {
	      var x = value.apply(this, arguments);
	      if (x == null) this.removeAttributeNS(name.space, name.local); else this.setAttributeNS(name.space, name.local, x);
	    }
	    return value == null ? name.local ? attrNullNS : attrNull : typeof value === "function" ? name.local ? attrFunctionNS : attrFunction : name.local ? attrConstantNS : attrConstant;
	  }
	  function d3_collapse(s) {
	    return s.trim().replace(/\s+/g, " ");
	  }
	  d3_selectionPrototype.classed = function(name, value) {
	    if (arguments.length < 2) {
	      if (typeof name === "string") {
	        var node = this.node(), n = (name = d3_selection_classes(name)).length, i = -1;
	        if (value = node.classList) {
	          while (++i < n) if (!value.contains(name[i])) return false;
	        } else {
	          value = node.getAttribute("class");
	          while (++i < n) if (!d3_selection_classedRe(name[i]).test(value)) return false;
	        }
	        return true;
	      }
	      for (value in name) this.each(d3_selection_classed(value, name[value]));
	      return this;
	    }
	    return this.each(d3_selection_classed(name, value));
	  };
	  function d3_selection_classedRe(name) {
	    return new RegExp("(?:^|\\s+)" + d3.requote(name) + "(?:\\s+|$)", "g");
	  }
	  function d3_selection_classes(name) {
	    return (name + "").trim().split(/^|\s+/);
	  }
	  function d3_selection_classed(name, value) {
	    name = d3_selection_classes(name).map(d3_selection_classedName);
	    var n = name.length;
	    function classedConstant() {
	      var i = -1;
	      while (++i < n) name[i](this, value);
	    }
	    function classedFunction() {
	      var i = -1, x = value.apply(this, arguments);
	      while (++i < n) name[i](this, x);
	    }
	    return typeof value === "function" ? classedFunction : classedConstant;
	  }
	  function d3_selection_classedName(name) {
	    var re = d3_selection_classedRe(name);
	    return function(node, value) {
	      if (c = node.classList) return value ? c.add(name) : c.remove(name);
	      var c = node.getAttribute("class") || "";
	      if (value) {
	        re.lastIndex = 0;
	        if (!re.test(c)) node.setAttribute("class", d3_collapse(c + " " + name));
	      } else {
	        node.setAttribute("class", d3_collapse(c.replace(re, " ")));
	      }
	    };
	  }
	  d3_selectionPrototype.style = function(name, value, priority) {
	    var n = arguments.length;
	    if (n < 3) {
	      if (typeof name !== "string") {
	        if (n < 2) value = "";
	        for (priority in name) this.each(d3_selection_style(priority, name[priority], value));
	        return this;
	      }
	      if (n < 2) {
	        var node = this.node();
	        return d3_window(node).getComputedStyle(node, null).getPropertyValue(name);
	      }
	      priority = "";
	    }
	    return this.each(d3_selection_style(name, value, priority));
	  };
	  function d3_selection_style(name, value, priority) {
	    function styleNull() {
	      this.style.removeProperty(name);
	    }
	    function styleConstant() {
	      this.style.setProperty(name, value, priority);
	    }
	    function styleFunction() {
	      var x = value.apply(this, arguments);
	      if (x == null) this.style.removeProperty(name); else this.style.setProperty(name, x, priority);
	    }
	    return value == null ? styleNull : typeof value === "function" ? styleFunction : styleConstant;
	  }
	  d3_selectionPrototype.property = function(name, value) {
	    if (arguments.length < 2) {
	      if (typeof name === "string") return this.node()[name];
	      for (value in name) this.each(d3_selection_property(value, name[value]));
	      return this;
	    }
	    return this.each(d3_selection_property(name, value));
	  };
	  function d3_selection_property(name, value) {
	    function propertyNull() {
	      delete this[name];
	    }
	    function propertyConstant() {
	      this[name] = value;
	    }
	    function propertyFunction() {
	      var x = value.apply(this, arguments);
	      if (x == null) delete this[name]; else this[name] = x;
	    }
	    return value == null ? propertyNull : typeof value === "function" ? propertyFunction : propertyConstant;
	  }
	  d3_selectionPrototype.text = function(value) {
	    return arguments.length ? this.each(typeof value === "function" ? function() {
	      var v = value.apply(this, arguments);
	      this.textContent = v == null ? "" : v;
	    } : value == null ? function() {
	      this.textContent = "";
	    } : function() {
	      this.textContent = value;
	    }) : this.node().textContent;
	  };
	  d3_selectionPrototype.html = function(value) {
	    return arguments.length ? this.each(typeof value === "function" ? function() {
	      var v = value.apply(this, arguments);
	      this.innerHTML = v == null ? "" : v;
	    } : value == null ? function() {
	      this.innerHTML = "";
	    } : function() {
	      this.innerHTML = value;
	    }) : this.node().innerHTML;
	  };
	  d3_selectionPrototype.append = function(name) {
	    name = d3_selection_creator(name);
	    return this.select(function() {
	      return this.appendChild(name.apply(this, arguments));
	    });
	  };
	  function d3_selection_creator(name) {
	    function create() {
	      var document = this.ownerDocument, namespace = this.namespaceURI;
	      return namespace === d3_nsXhtml && document.documentElement.namespaceURI === d3_nsXhtml ? document.createElement(name) : document.createElementNS(namespace, name);
	    }
	    function createNS() {
	      return this.ownerDocument.createElementNS(name.space, name.local);
	    }
	    return typeof name === "function" ? name : (name = d3.ns.qualify(name)).local ? createNS : create;
	  }
	  d3_selectionPrototype.insert = function(name, before) {
	    name = d3_selection_creator(name);
	    before = d3_selection_selector(before);
	    return this.select(function() {
	      return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments) || null);
	    });
	  };
	  d3_selectionPrototype.remove = function() {
	    return this.each(d3_selectionRemove);
	  };
	  function d3_selectionRemove() {
	    var parent = this.parentNode;
	    if (parent) parent.removeChild(this);
	  }
	  d3_selectionPrototype.data = function(value, key) {
	    var i = -1, n = this.length, group, node;
	    if (!arguments.length) {
	      value = new Array(n = (group = this[0]).length);
	      while (++i < n) {
	        if (node = group[i]) {
	          value[i] = node.__data__;
	        }
	      }
	      return value;
	    }
	    function bind(group, groupData) {
	      var i, n = group.length, m = groupData.length, n0 = Math.min(n, m), updateNodes = new Array(m), enterNodes = new Array(m), exitNodes = new Array(n), node, nodeData;
	      if (key) {
	        var nodeByKeyValue = new d3_Map(), keyValues = new Array(n), keyValue;
	        for (i = -1; ++i < n; ) {
	          if (node = group[i]) {
	            if (nodeByKeyValue.has(keyValue = key.call(node, node.__data__, i))) {
	              exitNodes[i] = node;
	            } else {
	              nodeByKeyValue.set(keyValue, node);
	            }
	            keyValues[i] = keyValue;
	          }
	        }
	        for (i = -1; ++i < m; ) {
	          if (!(node = nodeByKeyValue.get(keyValue = key.call(groupData, nodeData = groupData[i], i)))) {
	            enterNodes[i] = d3_selection_dataNode(nodeData);
	          } else if (node !== true) {
	            updateNodes[i] = node;
	            node.__data__ = nodeData;
	          }
	          nodeByKeyValue.set(keyValue, true);
	        }
	        for (i = -1; ++i < n; ) {
	          if (i in keyValues && nodeByKeyValue.get(keyValues[i]) !== true) {
	            exitNodes[i] = group[i];
	          }
	        }
	      } else {
	        for (i = -1; ++i < n0; ) {
	          node = group[i];
	          nodeData = groupData[i];
	          if (node) {
	            node.__data__ = nodeData;
	            updateNodes[i] = node;
	          } else {
	            enterNodes[i] = d3_selection_dataNode(nodeData);
	          }
	        }
	        for (;i < m; ++i) {
	          enterNodes[i] = d3_selection_dataNode(groupData[i]);
	        }
	        for (;i < n; ++i) {
	          exitNodes[i] = group[i];
	        }
	      }
	      enterNodes.update = updateNodes;
	      enterNodes.parentNode = updateNodes.parentNode = exitNodes.parentNode = group.parentNode;
	      enter.push(enterNodes);
	      update.push(updateNodes);
	      exit.push(exitNodes);
	    }
	    var enter = d3_selection_enter([]), update = d3_selection([]), exit = d3_selection([]);
	    if (typeof value === "function") {
	      while (++i < n) {
	        bind(group = this[i], value.call(group, group.parentNode.__data__, i));
	      }
	    } else {
	      while (++i < n) {
	        bind(group = this[i], value);
	      }
	    }
	    update.enter = function() {
	      return enter;
	    };
	    update.exit = function() {
	      return exit;
	    };
	    return update;
	  };
	  function d3_selection_dataNode(data) {
	    return {
	      __data__: data
	    };
	  }
	  d3_selectionPrototype.datum = function(value) {
	    return arguments.length ? this.property("__data__", value) : this.property("__data__");
	  };
	  d3_selectionPrototype.filter = function(filter) {
	    var subgroups = [], subgroup, group, node;
	    if (typeof filter !== "function") filter = d3_selection_filter(filter);
	    for (var j = 0, m = this.length; j < m; j++) {
	      subgroups.push(subgroup = []);
	      subgroup.parentNode = (group = this[j]).parentNode;
	      for (var i = 0, n = group.length; i < n; i++) {
	        if ((node = group[i]) && filter.call(node, node.__data__, i, j)) {
	          subgroup.push(node);
	        }
	      }
	    }
	    return d3_selection(subgroups);
	  };
	  function d3_selection_filter(selector) {
	    return function() {
	      return d3_selectMatches(this, selector);
	    };
	  }
	  d3_selectionPrototype.order = function() {
	    for (var j = -1, m = this.length; ++j < m; ) {
	      for (var group = this[j], i = group.length - 1, next = group[i], node; --i >= 0; ) {
	        if (node = group[i]) {
	          if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next);
	          next = node;
	        }
	      }
	    }
	    return this;
	  };
	  d3_selectionPrototype.sort = function(comparator) {
	    comparator = d3_selection_sortComparator.apply(this, arguments);
	    for (var j = -1, m = this.length; ++j < m; ) this[j].sort(comparator);
	    return this.order();
	  };
	  function d3_selection_sortComparator(comparator) {
	    if (!arguments.length) comparator = d3_ascending;
	    return function(a, b) {
	      return a && b ? comparator(a.__data__, b.__data__) : !a - !b;
	    };
	  }
	  d3_selectionPrototype.each = function(callback) {
	    return d3_selection_each(this, function(node, i, j) {
	      callback.call(node, node.__data__, i, j);
	    });
	  };
	  function d3_selection_each(groups, callback) {
	    for (var j = 0, m = groups.length; j < m; j++) {
	      for (var group = groups[j], i = 0, n = group.length, node; i < n; i++) {
	        if (node = group[i]) callback(node, i, j);
	      }
	    }
	    return groups;
	  }
	  d3_selectionPrototype.call = function(callback) {
	    var args = d3_array(arguments);
	    callback.apply(args[0] = this, args);
	    return this;
	  };
	  d3_selectionPrototype.empty = function() {
	    return !this.node();
	  };
	  d3_selectionPrototype.node = function() {
	    for (var j = 0, m = this.length; j < m; j++) {
	      for (var group = this[j], i = 0, n = group.length; i < n; i++) {
	        var node = group[i];
	        if (node) return node;
	      }
	    }
	    return null;
	  };
	  d3_selectionPrototype.size = function() {
	    var n = 0;
	    d3_selection_each(this, function() {
	      ++n;
	    });
	    return n;
	  };
	  function d3_selection_enter(selection) {
	    d3_subclass(selection, d3_selection_enterPrototype);
	    return selection;
	  }
	  var d3_selection_enterPrototype = [];
	  d3.selection.enter = d3_selection_enter;
	  d3.selection.enter.prototype = d3_selection_enterPrototype;
	  d3_selection_enterPrototype.append = d3_selectionPrototype.append;
	  d3_selection_enterPrototype.empty = d3_selectionPrototype.empty;
	  d3_selection_enterPrototype.node = d3_selectionPrototype.node;
	  d3_selection_enterPrototype.call = d3_selectionPrototype.call;
	  d3_selection_enterPrototype.size = d3_selectionPrototype.size;
	  d3_selection_enterPrototype.select = function(selector) {
	    var subgroups = [], subgroup, subnode, upgroup, group, node;
	    for (var j = -1, m = this.length; ++j < m; ) {
	      upgroup = (group = this[j]).update;
	      subgroups.push(subgroup = []);
	      subgroup.parentNode = group.parentNode;
	      for (var i = -1, n = group.length; ++i < n; ) {
	        if (node = group[i]) {
	          subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i, j));
	          subnode.__data__ = node.__data__;
	        } else {
	          subgroup.push(null);
	        }
	      }
	    }
	    return d3_selection(subgroups);
	  };
	  d3_selection_enterPrototype.insert = function(name, before) {
	    if (arguments.length < 2) before = d3_selection_enterInsertBefore(this);
	    return d3_selectionPrototype.insert.call(this, name, before);
	  };
	  function d3_selection_enterInsertBefore(enter) {
	    var i0, j0;
	    return function(d, i, j) {
	      var group = enter[j].update, n = group.length, node;
	      if (j != j0) j0 = j, i0 = 0;
	      if (i >= i0) i0 = i + 1;
	      while (!(node = group[i0]) && ++i0 < n) ;
	      return node;
	    };
	  }
	  d3.select = function(node) {
	    var group;
	    if (typeof node === "string") {
	      group = [ d3_select(node, d3_document) ];
	      group.parentNode = d3_document.documentElement;
	    } else {
	      group = [ node ];
	      group.parentNode = d3_documentElement(node);
	    }
	    return d3_selection([ group ]);
	  };
	  d3.selectAll = function(nodes) {
	    var group;
	    if (typeof nodes === "string") {
	      group = d3_array(d3_selectAll(nodes, d3_document));
	      group.parentNode = d3_document.documentElement;
	    } else {
	      group = d3_array(nodes);
	      group.parentNode = null;
	    }
	    return d3_selection([ group ]);
	  };
	  d3_selectionPrototype.on = function(type, listener, capture) {
	    var n = arguments.length;
	    if (n < 3) {
	      if (typeof type !== "string") {
	        if (n < 2) listener = false;
	        for (capture in type) this.each(d3_selection_on(capture, type[capture], listener));
	        return this;
	      }
	      if (n < 2) return (n = this.node()["__on" + type]) && n._;
	      capture = false;
	    }
	    return this.each(d3_selection_on(type, listener, capture));
	  };
	  function d3_selection_on(type, listener, capture) {
	    var name = "__on" + type, i = type.indexOf("."), wrap = d3_selection_onListener;
	    if (i > 0) type = type.slice(0, i);
	    var filter = d3_selection_onFilters.get(type);
	    if (filter) type = filter, wrap = d3_selection_onFilter;
	    function onRemove() {
	      var l = this[name];
	      if (l) {
	        this.removeEventListener(type, l, l.$);
	        delete this[name];
	      }
	    }
	    function onAdd() {
	      var l = wrap(listener, d3_array(arguments));
	      onRemove.call(this);
	      this.addEventListener(type, this[name] = l, l.$ = capture);
	      l._ = listener;
	    }
	    function removeAll() {
	      var re = new RegExp("^__on([^.]+)" + d3.requote(type) + "$"), match;
	      for (var name in this) {
	        if (match = name.match(re)) {
	          var l = this[name];
	          this.removeEventListener(match[1], l, l.$);
	          delete this[name];
	        }
	      }
	    }
	    return i ? listener ? onAdd : onRemove : listener ? d3_noop : removeAll;
	  }
	  var d3_selection_onFilters = d3.map({
	    mouseenter: "mouseover",
	    mouseleave: "mouseout"
	  });
	  if (d3_document) {
	    d3_selection_onFilters.forEach(function(k) {
	      if ("on" + k in d3_document) d3_selection_onFilters.remove(k);
	    });
	  }
	  function d3_selection_onListener(listener, argumentz) {
	    return function(e) {
	      var o = d3.event;
	      d3.event = e;
	      argumentz[0] = this.__data__;
	      try {
	        listener.apply(this, argumentz);
	      } finally {
	        d3.event = o;
	      }
	    };
	  }
	  function d3_selection_onFilter(listener, argumentz) {
	    var l = d3_selection_onListener(listener, argumentz);
	    return function(e) {
	      var target = this, related = e.relatedTarget;
	      if (!related || related !== target && !(related.compareDocumentPosition(target) & 8)) {
	        l.call(target, e);
	      }
	    };
	  }
	  var d3_event_dragSelect, d3_event_dragId = 0;
	  function d3_event_dragSuppress(node) {
	    var name = ".dragsuppress-" + ++d3_event_dragId, click = "click" + name, w = d3.select(d3_window(node)).on("touchmove" + name, d3_eventPreventDefault).on("dragstart" + name, d3_eventPreventDefault).on("selectstart" + name, d3_eventPreventDefault);
	    if (d3_event_dragSelect == null) {
	      d3_event_dragSelect = "onselectstart" in node ? false : d3_vendorSymbol(node.style, "userSelect");
	    }
	    if (d3_event_dragSelect) {
	      var style = d3_documentElement(node).style, select = style[d3_event_dragSelect];
	      style[d3_event_dragSelect] = "none";
	    }
	    return function(suppressClick) {
	      w.on(name, null);
	      if (d3_event_dragSelect) style[d3_event_dragSelect] = select;
	      if (suppressClick) {
	        var off = function() {
	          w.on(click, null);
	        };
	        w.on(click, function() {
	          d3_eventPreventDefault();
	          off();
	        }, true);
	        setTimeout(off, 0);
	      }
	    };
	  }
	  d3.mouse = function(container) {
	    return d3_mousePoint(container, d3_eventSource());
	  };
	  var d3_mouse_bug44083 = this.navigator && /WebKit/.test(this.navigator.userAgent) ? -1 : 0;
	  function d3_mousePoint(container, e) {
	    if (e.changedTouches) e = e.changedTouches[0];
	    var svg = container.ownerSVGElement || container;
	    if (svg.createSVGPoint) {
	      var point = svg.createSVGPoint();
	      if (d3_mouse_bug44083 < 0) {
	        var window = d3_window(container);
	        if (window.scrollX || window.scrollY) {
	          svg = d3.select("body").append("svg").style({
	            position: "absolute",
	            top: 0,
	            left: 0,
	            margin: 0,
	            padding: 0,
	            border: "none"
	          }, "important");
	          var ctm = svg[0][0].getScreenCTM();
	          d3_mouse_bug44083 = !(ctm.f || ctm.e);
	          svg.remove();
	        }
	      }
	      if (d3_mouse_bug44083) point.x = e.pageX, point.y = e.pageY; else point.x = e.clientX, 
	      point.y = e.clientY;
	      point = point.matrixTransform(container.getScreenCTM().inverse());
	      return [ point.x, point.y ];
	    }
	    var rect = container.getBoundingClientRect();
	    return [ e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop ];
	  }
	  d3.touch = function(container, touches, identifier) {
	    if (arguments.length < 3) identifier = touches, touches = d3_eventSource().changedTouches;
	    if (touches) for (var i = 0, n = touches.length, touch; i < n; ++i) {
	      if ((touch = touches[i]).identifier === identifier) {
	        return d3_mousePoint(container, touch);
	      }
	    }
	  };
	  d3.behavior.drag = function() {
	    var event = d3_eventDispatch(drag, "drag", "dragstart", "dragend"), origin = null, mousedown = dragstart(d3_noop, d3.mouse, d3_window, "mousemove", "mouseup"), touchstart = dragstart(d3_behavior_dragTouchId, d3.touch, d3_identity, "touchmove", "touchend");
	    function drag() {
	      this.on("mousedown.drag", mousedown).on("touchstart.drag", touchstart);
	    }
	    function dragstart(id, position, subject, move, end) {
	      return function() {
	        var that = this, target = d3.event.target.correspondingElement || d3.event.target, parent = that.parentNode, dispatch = event.of(that, arguments), dragged = 0, dragId = id(), dragName = ".drag" + (dragId == null ? "" : "-" + dragId), dragOffset, dragSubject = d3.select(subject(target)).on(move + dragName, moved).on(end + dragName, ended), dragRestore = d3_event_dragSuppress(target), position0 = position(parent, dragId);
	        if (origin) {
	          dragOffset = origin.apply(that, arguments);
	          dragOffset = [ dragOffset.x - position0[0], dragOffset.y - position0[1] ];
	        } else {
	          dragOffset = [ 0, 0 ];
	        }
	        dispatch({
	          type: "dragstart"
	        });
	        function moved() {
	          var position1 = position(parent, dragId), dx, dy;
	          if (!position1) return;
	          dx = position1[0] - position0[0];
	          dy = position1[1] - position0[1];
	          dragged |= dx | dy;
	          position0 = position1;
	          dispatch({
	            type: "drag",
	            x: position1[0] + dragOffset[0],
	            y: position1[1] + dragOffset[1],
	            dx: dx,
	            dy: dy
	          });
	        }
	        function ended() {
	          if (!position(parent, dragId)) return;
	          dragSubject.on(move + dragName, null).on(end + dragName, null);
	          dragRestore(dragged);
	          dispatch({
	            type: "dragend"
	          });
	        }
	      };
	    }
	    drag.origin = function(x) {
	      if (!arguments.length) return origin;
	      origin = x;
	      return drag;
	    };
	    return d3.rebind(drag, event, "on");
	  };
	  function d3_behavior_dragTouchId() {
	    return d3.event.changedTouches[0].identifier;
	  }
	  d3.touches = function(container, touches) {
	    if (arguments.length < 2) touches = d3_eventSource().touches;
	    return touches ? d3_array(touches).map(function(touch) {
	      var point = d3_mousePoint(container, touch);
	      point.identifier = touch.identifier;
	      return point;
	    }) : [];
	  };
	  var ε = 1e-6, ε2 = ε * ε, π = Math.PI, τ = 2 * π, τε = τ - ε, halfπ = π / 2, d3_radians = π / 180, d3_degrees = 180 / π;
	  function d3_sgn(x) {
	    return x > 0 ? 1 : x < 0 ? -1 : 0;
	  }
	  function d3_cross2d(a, b, c) {
	    return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);
	  }
	  function d3_acos(x) {
	    return x > 1 ? 0 : x < -1 ? π : Math.acos(x);
	  }
	  function d3_asin(x) {
	    return x > 1 ? halfπ : x < -1 ? -halfπ : Math.asin(x);
	  }
	  function d3_sinh(x) {
	    return ((x = Math.exp(x)) - 1 / x) / 2;
	  }
	  function d3_cosh(x) {
	    return ((x = Math.exp(x)) + 1 / x) / 2;
	  }
	  function d3_tanh(x) {
	    return ((x = Math.exp(2 * x)) - 1) / (x + 1);
	  }
	  function d3_haversin(x) {
	    return (x = Math.sin(x / 2)) * x;
	  }
	  var ρ = Math.SQRT2, ρ2 = 2, ρ4 = 4;
	  d3.interpolateZoom = function(p0, p1) {
	    var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2], dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, i, S;
	    if (d2 < ε2) {
	      S = Math.log(w1 / w0) / ρ;
	      i = function(t) {
	        return [ ux0 + t * dx, uy0 + t * dy, w0 * Math.exp(ρ * t * S) ];
	      };
	    } else {
	      var d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + ρ4 * d2) / (2 * w0 * ρ2 * d1), b1 = (w1 * w1 - w0 * w0 - ρ4 * d2) / (2 * w1 * ρ2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);
	      S = (r1 - r0) / ρ;
	      i = function(t) {
	        var s = t * S, coshr0 = d3_cosh(r0), u = w0 / (ρ2 * d1) * (coshr0 * d3_tanh(ρ * s + r0) - d3_sinh(r0));
	        return [ ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / d3_cosh(ρ * s + r0) ];
	      };
	    }
	    i.duration = S * 1e3;
	    return i;
	  };
	  d3.behavior.zoom = function() {
	    var view = {
	      x: 0,
	      y: 0,
	      k: 1
	    }, translate0, center0, center, size = [ 960, 500 ], scaleExtent = d3_behavior_zoomInfinity, duration = 250, zooming = 0, mousedown = "mousedown.zoom", mousemove = "mousemove.zoom", mouseup = "mouseup.zoom", mousewheelTimer, touchstart = "touchstart.zoom", touchtime, event = d3_eventDispatch(zoom, "zoomstart", "zoom", "zoomend"), x0, x1, y0, y1;
	    if (!d3_behavior_zoomWheel) {
	      d3_behavior_zoomWheel = "onwheel" in d3_document ? (d3_behavior_zoomDelta = function() {
	        return -d3.event.deltaY * (d3.event.deltaMode ? 120 : 1);
	      }, "wheel") : "onmousewheel" in d3_document ? (d3_behavior_zoomDelta = function() {
	        return d3.event.wheelDelta;
	      }, "mousewheel") : (d3_behavior_zoomDelta = function() {
	        return -d3.event.detail;
	      }, "MozMousePixelScroll");
	    }
	    function zoom(g) {
	      g.on(mousedown, mousedowned).on(d3_behavior_zoomWheel + ".zoom", mousewheeled).on("dblclick.zoom", dblclicked).on(touchstart, touchstarted);
	    }
	    zoom.event = function(g) {
	      g.each(function() {
	        var dispatch = event.of(this, arguments), view1 = view;
	        if (d3_transitionInheritId) {
	          d3.select(this).transition().each("start.zoom", function() {
	            view = this.__chart__ || {
	              x: 0,
	              y: 0,
	              k: 1
	            };
	            zoomstarted(dispatch);
	          }).tween("zoom:zoom", function() {
	            var dx = size[0], dy = size[1], cx = center0 ? center0[0] : dx / 2, cy = center0 ? center0[1] : dy / 2, i = d3.interpolateZoom([ (cx - view.x) / view.k, (cy - view.y) / view.k, dx / view.k ], [ (cx - view1.x) / view1.k, (cy - view1.y) / view1.k, dx / view1.k ]);
	            return function(t) {
	              var l = i(t), k = dx / l[2];
	              this.__chart__ = view = {
	                x: cx - l[0] * k,
	                y: cy - l[1] * k,
	                k: k
	              };
	              zoomed(dispatch);
	            };
	          }).each("interrupt.zoom", function() {
	            zoomended(dispatch);
	          }).each("end.zoom", function() {
	            zoomended(dispatch);
	          });
	        } else {
	          this.__chart__ = view;
	          zoomstarted(dispatch);
	          zoomed(dispatch);
	          zoomended(dispatch);
	        }
	      });
	    };
	    zoom.translate = function(_) {
	      if (!arguments.length) return [ view.x, view.y ];
	      view = {
	        x: +_[0],
	        y: +_[1],
	        k: view.k
	      };
	      rescale();
	      return zoom;
	    };
	    zoom.scale = function(_) {
	      if (!arguments.length) return view.k;
	      view = {
	        x: view.x,
	        y: view.y,
	        k: null
	      };
	      scaleTo(+_);
	      rescale();
	      return zoom;
	    };
	    zoom.scaleExtent = function(_) {
	      if (!arguments.length) return scaleExtent;
	      scaleExtent = _ == null ? d3_behavior_zoomInfinity : [ +_[0], +_[1] ];
	      return zoom;
	    };
	    zoom.center = function(_) {
	      if (!arguments.length) return center;
	      center = _ && [ +_[0], +_[1] ];
	      return zoom;
	    };
	    zoom.size = function(_) {
	      if (!arguments.length) return size;
	      size = _ && [ +_[0], +_[1] ];
	      return zoom;
	    };
	    zoom.duration = function(_) {
	      if (!arguments.length) return duration;
	      duration = +_;
	      return zoom;
	    };
	    zoom.x = function(z) {
	      if (!arguments.length) return x1;
	      x1 = z;
	      x0 = z.copy();
	      view = {
	        x: 0,
	        y: 0,
	        k: 1
	      };
	      return zoom;
	    };
	    zoom.y = function(z) {
	      if (!arguments.length) return y1;
	      y1 = z;
	      y0 = z.copy();
	      view = {
	        x: 0,
	        y: 0,
	        k: 1
	      };
	      return zoom;
	    };
	    function location(p) {
	      return [ (p[0] - view.x) / view.k, (p[1] - view.y) / view.k ];
	    }
	    function point(l) {
	      return [ l[0] * view.k + view.x, l[1] * view.k + view.y ];
	    }
	    function scaleTo(s) {
	      view.k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s));
	    }
	    function translateTo(p, l) {
	      l = point(l);
	      view.x += p[0] - l[0];
	      view.y += p[1] - l[1];
	    }
	    function zoomTo(that, p, l, k) {
	      that.__chart__ = {
	        x: view.x,
	        y: view.y,
	        k: view.k
	      };
	      scaleTo(Math.pow(2, k));
	      translateTo(center0 = p, l);
	      that = d3.select(that);
	      if (duration > 0) that = that.transition().duration(duration);
	      that.call(zoom.event);
	    }
	    function rescale() {
	      if (x1) x1.domain(x0.range().map(function(x) {
	        return (x - view.x) / view.k;
	      }).map(x0.invert));
	      if (y1) y1.domain(y0.range().map(function(y) {
	        return (y - view.y) / view.k;
	      }).map(y0.invert));
	    }
	    function zoomstarted(dispatch) {
	      if (!zooming++) dispatch({
	        type: "zoomstart"
	      });
	    }
	    function zoomed(dispatch) {
	      rescale();
	      dispatch({
	        type: "zoom",
	        scale: view.k,
	        translate: [ view.x, view.y ]
	      });
	    }
	    function zoomended(dispatch) {
	      if (!--zooming) dispatch({
	        type: "zoomend"
	      }), center0 = null;
	    }
	    function mousedowned() {
	      var that = this, dispatch = event.of(that, arguments), dragged = 0, subject = d3.select(d3_window(that)).on(mousemove, moved).on(mouseup, ended), location0 = location(d3.mouse(that)), dragRestore = d3_event_dragSuppress(that);
	      d3_selection_interrupt.call(that);
	      zoomstarted(dispatch);
	      function moved() {
	        dragged = 1;
	        translateTo(d3.mouse(that), location0);
	        zoomed(dispatch);
	      }
	      function ended() {
	        subject.on(mousemove, null).on(mouseup, null);
	        dragRestore(dragged);
	        zoomended(dispatch);
	      }
	    }
	    function touchstarted() {
	      var that = this, dispatch = event.of(that, arguments), locations0 = {}, distance0 = 0, scale0, zoomName = ".zoom-" + d3.event.changedTouches[0].identifier, touchmove = "touchmove" + zoomName, touchend = "touchend" + zoomName, targets = [], subject = d3.select(that), dragRestore = d3_event_dragSuppress(that);
	      started();
	      zoomstarted(dispatch);
	      subject.on(mousedown, null).on(touchstart, started);
	      function relocate() {
	        var touches = d3.touches(that);
	        scale0 = view.k;
	        touches.forEach(function(t) {
	          if (t.identifier in locations0) locations0[t.identifier] = location(t);
	        });
	        return touches;
	      }
	      function started() {
	        var target = d3.event.target;
	        d3.select(target).on(touchmove, moved).on(touchend, ended);
	        targets.push(target);
	        var changed = d3.event.changedTouches;
	        for (var i = 0, n = changed.length; i < n; ++i) {
	          locations0[changed[i].identifier] = null;
	        }
	        var touches = relocate(), now = Date.now();
	        if (touches.length === 1) {
	          if (now - touchtime < 500) {
	            var p = touches[0];
	            zoomTo(that, p, locations0[p.identifier], Math.floor(Math.log(view.k) / Math.LN2) + 1);
	            d3_eventPreventDefault();
	          }
	          touchtime = now;
	        } else if (touches.length > 1) {
	          var p = touches[0], q = touches[1], dx = p[0] - q[0], dy = p[1] - q[1];
	          distance0 = dx * dx + dy * dy;
	        }
	      }
	      function moved() {
	        var touches = d3.touches(that), p0, l0, p1, l1;
	        d3_selection_interrupt.call(that);
	        for (var i = 0, n = touches.length; i < n; ++i, l1 = null) {
	          p1 = touches[i];
	          if (l1 = locations0[p1.identifier]) {
	            if (l0) break;
	            p0 = p1, l0 = l1;
	          }
	        }
	        if (l1) {
	          var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1, scale1 = distance0 && Math.sqrt(distance1 / distance0);
	          p0 = [ (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2 ];
	          l0 = [ (l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2 ];
	          scaleTo(scale1 * scale0);
	        }
	        touchtime = null;
	        translateTo(p0, l0);
	        zoomed(dispatch);
	      }
	      function ended() {
	        if (d3.event.touches.length) {
	          var changed = d3.event.changedTouches;
	          for (var i = 0, n = changed.length; i < n; ++i) {
	            delete locations0[changed[i].identifier];
	          }
	          for (var identifier in locations0) {
	            return void relocate();
	          }
	        }
	        d3.selectAll(targets).on(zoomName, null);
	        subject.on(mousedown, mousedowned).on(touchstart, touchstarted);
	        dragRestore();
	        zoomended(dispatch);
	      }
	    }
	    function mousewheeled() {
	      var dispatch = event.of(this, arguments);
	      if (mousewheelTimer) clearTimeout(mousewheelTimer); else d3_selection_interrupt.call(this), 
	      translate0 = location(center0 = center || d3.mouse(this)), zoomstarted(dispatch);
	      mousewheelTimer = setTimeout(function() {
	        mousewheelTimer = null;
	        zoomended(dispatch);
	      }, 50);
	      d3_eventPreventDefault();
	      scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * view.k);
	      translateTo(center0, translate0);
	      zoomed(dispatch);
	    }
	    function dblclicked() {
	      var p = d3.mouse(this), k = Math.log(view.k) / Math.LN2;
	      zoomTo(this, p, location(p), d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1);
	    }
	    return d3.rebind(zoom, event, "on");
	  };
	  var d3_behavior_zoomInfinity = [ 0, Infinity ], d3_behavior_zoomDelta, d3_behavior_zoomWheel;
	  d3.color = d3_color;
	  function d3_color() {}
	  d3_color.prototype.toString = function() {
	    return this.rgb() + "";
	  };
	  d3.hsl = d3_hsl;
	  function d3_hsl(h, s, l) {
	    return this instanceof d3_hsl ? void (this.h = +h, this.s = +s, this.l = +l) : arguments.length < 2 ? h instanceof d3_hsl ? new d3_hsl(h.h, h.s, h.l) : d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl) : new d3_hsl(h, s, l);
	  }
	  var d3_hslPrototype = d3_hsl.prototype = new d3_color();
	  d3_hslPrototype.brighter = function(k) {
	    k = Math.pow(.7, arguments.length ? k : 1);
	    return new d3_hsl(this.h, this.s, this.l / k);
	  };
	  d3_hslPrototype.darker = function(k) {
	    k = Math.pow(.7, arguments.length ? k : 1);
	    return new d3_hsl(this.h, this.s, k * this.l);
	  };
	  d3_hslPrototype.rgb = function() {
	    return d3_hsl_rgb(this.h, this.s, this.l);
	  };
	  function d3_hsl_rgb(h, s, l) {
	    var m1, m2;
	    h = isNaN(h) ? 0 : (h %= 360) < 0 ? h + 360 : h;
	    s = isNaN(s) ? 0 : s < 0 ? 0 : s > 1 ? 1 : s;
	    l = l < 0 ? 0 : l > 1 ? 1 : l;
	    m2 = l <= .5 ? l * (1 + s) : l + s - l * s;
	    m1 = 2 * l - m2;
	    function v(h) {
	      if (h > 360) h -= 360; else if (h < 0) h += 360;
	      if (h < 60) return m1 + (m2 - m1) * h / 60;
	      if (h < 180) return m2;
	      if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60;
	      return m1;
	    }
	    function vv(h) {
	      return Math.round(v(h) * 255);
	    }
	    return new d3_rgb(vv(h + 120), vv(h), vv(h - 120));
	  }
	  d3.hcl = d3_hcl;
	  function d3_hcl(h, c, l) {
	    return this instanceof d3_hcl ? void (this.h = +h, this.c = +c, this.l = +l) : arguments.length < 2 ? h instanceof d3_hcl ? new d3_hcl(h.h, h.c, h.l) : h instanceof d3_lab ? d3_lab_hcl(h.l, h.a, h.b) : d3_lab_hcl((h = d3_rgb_lab((h = d3.rgb(h)).r, h.g, h.b)).l, h.a, h.b) : new d3_hcl(h, c, l);
	  }
	  var d3_hclPrototype = d3_hcl.prototype = new d3_color();
	  d3_hclPrototype.brighter = function(k) {
	    return new d3_hcl(this.h, this.c, Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)));
	  };
	  d3_hclPrototype.darker = function(k) {
	    return new d3_hcl(this.h, this.c, Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)));
	  };
	  d3_hclPrototype.rgb = function() {
	    return d3_hcl_lab(this.h, this.c, this.l).rgb();
	  };
	  function d3_hcl_lab(h, c, l) {
	    if (isNaN(h)) h = 0;
	    if (isNaN(c)) c = 0;
	    return new d3_lab(l, Math.cos(h *= d3_radians) * c, Math.sin(h) * c);
	  }
	  d3.lab = d3_lab;
	  function d3_lab(l, a, b) {
	    return this instanceof d3_lab ? void (this.l = +l, this.a = +a, this.b = +b) : arguments.length < 2 ? l instanceof d3_lab ? new d3_lab(l.l, l.a, l.b) : l instanceof d3_hcl ? d3_hcl_lab(l.h, l.c, l.l) : d3_rgb_lab((l = d3_rgb(l)).r, l.g, l.b) : new d3_lab(l, a, b);
	  }
	  var d3_lab_K = 18;
	  var d3_lab_X = .95047, d3_lab_Y = 1, d3_lab_Z = 1.08883;
	  var d3_labPrototype = d3_lab.prototype = new d3_color();
	  d3_labPrototype.brighter = function(k) {
	    return new d3_lab(Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)), this.a, this.b);
	  };
	  d3_labPrototype.darker = function(k) {
	    return new d3_lab(Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)), this.a, this.b);
	  };
	  d3_labPrototype.rgb = function() {
	    return d3_lab_rgb(this.l, this.a, this.b);
	  };
	  function d3_lab_rgb(l, a, b) {
	    var y = (l + 16) / 116, x = y + a / 500, z = y - b / 200;
	    x = d3_lab_xyz(x) * d3_lab_X;
	    y = d3_lab_xyz(y) * d3_lab_Y;
	    z = d3_lab_xyz(z) * d3_lab_Z;
	    return new d3_rgb(d3_xyz_rgb(3.2404542 * x - 1.5371385 * y - .4985314 * z), d3_xyz_rgb(-.969266 * x + 1.8760108 * y + .041556 * z), d3_xyz_rgb(.0556434 * x - .2040259 * y + 1.0572252 * z));
	  }
	  function d3_lab_hcl(l, a, b) {
	    return l > 0 ? new d3_hcl(Math.atan2(b, a) * d3_degrees, Math.sqrt(a * a + b * b), l) : new d3_hcl(NaN, NaN, l);
	  }
	  function d3_lab_xyz(x) {
	    return x > .206893034 ? x * x * x : (x - 4 / 29) / 7.787037;
	  }
	  function d3_xyz_lab(x) {
	    return x > .008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29;
	  }
	  function d3_xyz_rgb(r) {
	    return Math.round(255 * (r <= .00304 ? 12.92 * r : 1.055 * Math.pow(r, 1 / 2.4) - .055));
	  }
	  d3.rgb = d3_rgb;
	  function d3_rgb(r, g, b) {
	    return this instanceof d3_rgb ? void (this.r = ~~r, this.g = ~~g, this.b = ~~b) : arguments.length < 2 ? r instanceof d3_rgb ? new d3_rgb(r.r, r.g, r.b) : d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb) : new d3_rgb(r, g, b);
	  }
	  function d3_rgbNumber(value) {
	    return new d3_rgb(value >> 16, value >> 8 & 255, value & 255);
	  }
	  function d3_rgbString(value) {
	    return d3_rgbNumber(value) + "";
	  }
	  var d3_rgbPrototype = d3_rgb.prototype = new d3_color();
	  d3_rgbPrototype.brighter = function(k) {
	    k = Math.pow(.7, arguments.length ? k : 1);
	    var r = this.r, g = this.g, b = this.b, i = 30;
	    if (!r && !g && !b) return new d3_rgb(i, i, i);
	    if (r && r < i) r = i;
	    if (g && g < i) g = i;
	    if (b && b < i) b = i;
	    return new d3_rgb(Math.min(255, r / k), Math.min(255, g / k), Math.min(255, b / k));
	  };
	  d3_rgbPrototype.darker = function(k) {
	    k = Math.pow(.7, arguments.length ? k : 1);
	    return new d3_rgb(k * this.r, k * this.g, k * this.b);
	  };
	  d3_rgbPrototype.hsl = function() {
	    return d3_rgb_hsl(this.r, this.g, this.b);
	  };
	  d3_rgbPrototype.toString = function() {
	    return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b);
	  };
	  function d3_rgb_hex(v) {
	    return v < 16 ? "0" + Math.max(0, v).toString(16) : Math.min(255, v).toString(16);
	  }
	  function d3_rgb_parse(format, rgb, hsl) {
	    var r = 0, g = 0, b = 0, m1, m2, color;
	    m1 = /([a-z]+)\((.*)\)/.exec(format = format.toLowerCase());
	    if (m1) {
	      m2 = m1[2].split(",");
	      switch (m1[1]) {
	       case "hsl":
	        {
	          return hsl(parseFloat(m2[0]), parseFloat(m2[1]) / 100, parseFloat(m2[2]) / 100);
	        }
	
	       case "rgb":
	        {
	          return rgb(d3_rgb_parseNumber(m2[0]), d3_rgb_parseNumber(m2[1]), d3_rgb_parseNumber(m2[2]));
	        }
	      }
	    }
	    if (color = d3_rgb_names.get(format)) {
	      return rgb(color.r, color.g, color.b);
	    }
	    if (format != null && format.charAt(0) === "#" && !isNaN(color = parseInt(format.slice(1), 16))) {
	      if (format.length === 4) {
	        r = (color & 3840) >> 4;
	        r = r >> 4 | r;
	        g = color & 240;
	        g = g >> 4 | g;
	        b = color & 15;
	        b = b << 4 | b;
	      } else if (format.length === 7) {
	        r = (color & 16711680) >> 16;
	        g = (color & 65280) >> 8;
	        b = color & 255;
	      }
	    }
	    return rgb(r, g, b);
	  }
	  function d3_rgb_hsl(r, g, b) {
	    var min = Math.min(r /= 255, g /= 255, b /= 255), max = Math.max(r, g, b), d = max - min, h, s, l = (max + min) / 2;
	    if (d) {
	      s = l < .5 ? d / (max + min) : d / (2 - max - min);
	      if (r == max) h = (g - b) / d + (g < b ? 6 : 0); else if (g == max) h = (b - r) / d + 2; else h = (r - g) / d + 4;
	      h *= 60;
	    } else {
	      h = NaN;
	      s = l > 0 && l < 1 ? 0 : h;
	    }
	    return new d3_hsl(h, s, l);
	  }
	  function d3_rgb_lab(r, g, b) {
	    r = d3_rgb_xyz(r);
	    g = d3_rgb_xyz(g);
	    b = d3_rgb_xyz(b);
	    var x = d3_xyz_lab((.4124564 * r + .3575761 * g + .1804375 * b) / d3_lab_X), y = d3_xyz_lab((.2126729 * r + .7151522 * g + .072175 * b) / d3_lab_Y), z = d3_xyz_lab((.0193339 * r + .119192 * g + .9503041 * b) / d3_lab_Z);
	    return d3_lab(116 * y - 16, 500 * (x - y), 200 * (y - z));
	  }
	  function d3_rgb_xyz(r) {
	    return (r /= 255) <= .04045 ? r / 12.92 : Math.pow((r + .055) / 1.055, 2.4);
	  }
	  function d3_rgb_parseNumber(c) {
	    var f = parseFloat(c);
	    return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f;
	  }
	  var d3_rgb_names = d3.map({
	    aliceblue: 15792383,
	    antiquewhite: 16444375,
	    aqua: 65535,
	    aquamarine: 8388564,
	    azure: 15794175,
	    beige: 16119260,
	    bisque: 16770244,
	    black: 0,
	    blanchedalmond: 16772045,
	    blue: 255,
	    blueviolet: 9055202,
	    brown: 10824234,
	    burlywood: 14596231,
	    cadetblue: 6266528,
	    chartreuse: 8388352,
	    chocolate: 13789470,
	    coral: 16744272,
	    cornflowerblue: 6591981,
	    cornsilk: 16775388,
	    crimson: 14423100,
	    cyan: 65535,
	    darkblue: 139,
	    darkcyan: 35723,
	    darkgoldenrod: 12092939,
	    darkgray: 11119017,
	    darkgreen: 25600,
	    darkgrey: 11119017,
	    darkkhaki: 12433259,
	    darkmagenta: 9109643,
	    darkolivegreen: 5597999,
	    darkorange: 16747520,
	    darkorchid: 10040012,
	    darkred: 9109504,
	    darksalmon: 15308410,
	    darkseagreen: 9419919,
	    darkslateblue: 4734347,
	    darkslategray: 3100495,
	    darkslategrey: 3100495,
	    darkturquoise: 52945,
	    darkviolet: 9699539,
	    deeppink: 16716947,
	    deepskyblue: 49151,
	    dimgray: 6908265,
	    dimgrey: 6908265,
	    dodgerblue: 2003199,
	    firebrick: 11674146,
	    floralwhite: 16775920,
	    forestgreen: 2263842,
	    fuchsia: 16711935,
	    gainsboro: 14474460,
	    ghostwhite: 16316671,
	    gold: 16766720,
	    goldenrod: 14329120,
	    gray: 8421504,
	    green: 32768,
	    greenyellow: 11403055,
	    grey: 8421504,
	    honeydew: 15794160,
	    hotpink: 16738740,
	    indianred: 13458524,
	    indigo: 4915330,
	    ivory: 16777200,
	    khaki: 15787660,
	    lavender: 15132410,
	    lavenderblush: 16773365,
	    lawngreen: 8190976,
	    lemonchiffon: 16775885,
	    lightblue: 11393254,
	    lightcoral: 15761536,
	    lightcyan: 14745599,
	    lightgoldenrodyellow: 16448210,
	    lightgray: 13882323,
	    lightgreen: 9498256,
	    lightgrey: 13882323,
	    lightpink: 16758465,
	    lightsalmon: 16752762,
	    lightseagreen: 2142890,
	    lightskyblue: 8900346,
	    lightslategray: 7833753,
	    lightslategrey: 7833753,
	    lightsteelblue: 11584734,
	    lightyellow: 16777184,
	    lime: 65280,
	    limegreen: 3329330,
	    linen: 16445670,
	    magenta: 16711935,
	    maroon: 8388608,
	    mediumaquamarine: 6737322,
	    mediumblue: 205,
	    mediumorchid: 12211667,
	    mediumpurple: 9662683,
	    mediumseagreen: 3978097,
	    mediumslateblue: 8087790,
	    mediumspringgreen: 64154,
	    mediumturquoise: 4772300,
	    mediumvioletred: 13047173,
	    midnightblue: 1644912,
	    mintcream: 16121850,
	    mistyrose: 16770273,
	    moccasin: 16770229,
	    navajowhite: 16768685,
	    navy: 128,
	    oldlace: 16643558,
	    olive: 8421376,
	    olivedrab: 7048739,
	    orange: 16753920,
	    orangered: 16729344,
	    orchid: 14315734,
	    palegoldenrod: 15657130,
	    palegreen: 10025880,
	    paleturquoise: 11529966,
	    palevioletred: 14381203,
	    papayawhip: 16773077,
	    peachpuff: 16767673,
	    peru: 13468991,
	    pink: 16761035,
	    plum: 14524637,
	    powderblue: 11591910,
	    purple: 8388736,
	    rebeccapurple: 6697881,
	    red: 16711680,
	    rosybrown: 12357519,
	    royalblue: 4286945,
	    saddlebrown: 9127187,
	    salmon: 16416882,
	    sandybrown: 16032864,
	    seagreen: 3050327,
	    seashell: 16774638,
	    sienna: 10506797,
	    silver: 12632256,
	    skyblue: 8900331,
	    slateblue: 6970061,
	    slategray: 7372944,
	    slategrey: 7372944,
	    snow: 16775930,
	    springgreen: 65407,
	    steelblue: 4620980,
	    tan: 13808780,
	    teal: 32896,
	    thistle: 14204888,
	    tomato: 16737095,
	    turquoise: 4251856,
	    violet: 15631086,
	    wheat: 16113331,
	    white: 16777215,
	    whitesmoke: 16119285,
	    yellow: 16776960,
	    yellowgreen: 10145074
	  });
	  d3_rgb_names.forEach(function(key, value) {
	    d3_rgb_names.set(key, d3_rgbNumber(value));
	  });
	  function d3_functor(v) {
	    return typeof v === "function" ? v : function() {
	      return v;
	    };
	  }
	  d3.functor = d3_functor;
	  d3.xhr = d3_xhrType(d3_identity);
	  function d3_xhrType(response) {
	    return function(url, mimeType, callback) {
	      if (arguments.length === 2 && typeof mimeType === "function") callback = mimeType, 
	      mimeType = null;
	      return d3_xhr(url, mimeType, response, callback);
	    };
	  }
	  function d3_xhr(url, mimeType, response, callback) {
	    var xhr = {}, dispatch = d3.dispatch("beforesend", "progress", "load", "error"), headers = {}, request = new XMLHttpRequest(), responseType = null;
	    if (this.XDomainRequest && !("withCredentials" in request) && /^(http(s)?:)?\/\//.test(url)) request = new XDomainRequest();
	    "onload" in request ? request.onload = request.onerror = respond : request.onreadystatechange = function() {
	      request.readyState > 3 && respond();
	    };
	    function respond() {
	      var status = request.status, result;
	      if (!status && d3_xhrHasResponse(request) || status >= 200 && status < 300 || status === 304) {
	        try {
	          result = response.call(xhr, request);
	        } catch (e) {
	          dispatch.error.call(xhr, e);
	          return;
	        }
	        dispatch.load.call(xhr, result);
	      } else {
	        dispatch.error.call(xhr, request);
	      }
	    }
	    request.onprogress = function(event) {
	      var o = d3.event;
	      d3.event = event;
	      try {
	        dispatch.progress.call(xhr, request);
	      } finally {
	        d3.event = o;
	      }
	    };
	    xhr.header = function(name, value) {
	      name = (name + "").toLowerCase();
	      if (arguments.length < 2) return headers[name];
	      if (value == null) delete headers[name]; else headers[name] = value + "";
	      return xhr;
	    };
	    xhr.mimeType = function(value) {
	      if (!arguments.length) return mimeType;
	      mimeType = value == null ? null : value + "";
	      return xhr;
	    };
	    xhr.responseType = function(value) {
	      if (!arguments.length) return responseType;
	      responseType = value;
	      return xhr;
	    };
	    xhr.response = function(value) {
	      response = value;
	      return xhr;
	    };
	    [ "get", "post" ].forEach(function(method) {
	      xhr[method] = function() {
	        return xhr.send.apply(xhr, [ method ].concat(d3_array(arguments)));
	      };
	    });
	    xhr.send = function(method, data, callback) {
	      if (arguments.length === 2 && typeof data === "function") callback = data, data = null;
	      request.open(method, url, true);
	      if (mimeType != null && !("accept" in headers)) headers["accept"] = mimeType + ",*/*";
	      if (request.setRequestHeader) for (var name in headers) request.setRequestHeader(name, headers[name]);
	      if (mimeType != null && request.overrideMimeType) request.overrideMimeType(mimeType);
	      if (responseType != null) request.responseType = responseType;
	      if (callback != null) xhr.on("error", callback).on("load", function(request) {
	        callback(null, request);
	      });
	      dispatch.beforesend.call(xhr, request);
	      request.send(data == null ? null : data);
	      return xhr;
	    };
	    xhr.abort = function() {
	      request.abort();
	      return xhr;
	    };
	    d3.rebind(xhr, dispatch, "on");
	    return callback == null ? xhr : xhr.get(d3_xhr_fixCallback(callback));
	  }
	  function d3_xhr_fixCallback(callback) {
	    return callback.length === 1 ? function(error, request) {
	      callback(error == null ? request : null);
	    } : callback;
	  }
	  function d3_xhrHasResponse(request) {
	    var type = request.responseType;
	    return type && type !== "text" ? request.response : request.responseText;
	  }
	  d3.dsv = function(delimiter, mimeType) {
	    var reFormat = new RegExp('["' + delimiter + "\n]"), delimiterCode = delimiter.charCodeAt(0);
	    function dsv(url, row, callback) {
	      if (arguments.length < 3) callback = row, row = null;
	      var xhr = d3_xhr(url, mimeType, row == null ? response : typedResponse(row), callback);
	      xhr.row = function(_) {
	        return arguments.length ? xhr.response((row = _) == null ? response : typedResponse(_)) : row;
	      };
	      return xhr;
	    }
	    function response(request) {
	      return dsv.parse(request.responseText);
	    }
	    function typedResponse(f) {
	      return function(request) {
	        return dsv.parse(request.responseText, f);
	      };
	    }
	    dsv.parse = function(text, f) {
	      var o;
	      return dsv.parseRows(text, function(row, i) {
	        if (o) return o(row, i - 1);
	        var a = new Function("d", "return {" + row.map(function(name, i) {
	          return JSON.stringify(name) + ": d[" + i + "]";
	        }).join(",") + "}");
	        o = f ? function(row, i) {
	          return f(a(row), i);
	        } : a;
	      });
	    };
	    dsv.parseRows = function(text, f) {
	      var EOL = {}, EOF = {}, rows = [], N = text.length, I = 0, n = 0, t, eol;
	      function token() {
	        if (I >= N) return EOF;
	        if (eol) return eol = false, EOL;
	        var j = I;
	        if (text.charCodeAt(j) === 34) {
	          var i = j;
	          while (i++ < N) {
	            if (text.charCodeAt(i) === 34) {
	              if (text.charCodeAt(i + 1) !== 34) break;
	              ++i;
	            }
	          }
	          I = i + 2;
	          var c = text.charCodeAt(i + 1);
	          if (c === 13) {
	            eol = true;
	            if (text.charCodeAt(i + 2) === 10) ++I;
	          } else if (c === 10) {
	            eol = true;
	          }
	          return text.slice(j + 1, i).replace(/""/g, '"');
	        }
	        while (I < N) {
	          var c = text.charCodeAt(I++), k = 1;
	          if (c === 10) eol = true; else if (c === 13) {
	            eol = true;
	            if (text.charCodeAt(I) === 10) ++I, ++k;
	          } else if (c !== delimiterCode) continue;
	          return text.slice(j, I - k);
	        }
	        return text.slice(j);
	      }
	      while ((t = token()) !== EOF) {
	        var a = [];
	        while (t !== EOL && t !== EOF) {
	          a.push(t);
	          t = token();
	        }
	        if (f && (a = f(a, n++)) == null) continue;
	        rows.push(a);
	      }
	      return rows;
	    };
	    dsv.format = function(rows) {
	      if (Array.isArray(rows[0])) return dsv.formatRows(rows);
	      var fieldSet = new d3_Set(), fields = [];
	      rows.forEach(function(row) {
	        for (var field in row) {
	          if (!fieldSet.has(field)) {
	            fields.push(fieldSet.add(field));
	          }
	        }
	      });
	      return [ fields.map(formatValue).join(delimiter) ].concat(rows.map(function(row) {
	        return fields.map(function(field) {
	          return formatValue(row[field]);
	        }).join(delimiter);
	      })).join("\n");
	    };
	    dsv.formatRows = function(rows) {
	      return rows.map(formatRow).join("\n");
	    };
	    function formatRow(row) {
	      return row.map(formatValue).join(delimiter);
	    }
	    function formatValue(text) {
	      return reFormat.test(text) ? '"' + text.replace(/\"/g, '""') + '"' : text;
	    }
	    return dsv;
	  };
	  d3.csv = d3.dsv(",", "text/csv");
	  d3.tsv = d3.dsv("	", "text/tab-separated-values");
	  var d3_timer_queueHead, d3_timer_queueTail, d3_timer_interval, d3_timer_timeout, d3_timer_frame = this[d3_vendorSymbol(this, "requestAnimationFrame")] || function(callback) {
	    setTimeout(callback, 17);
	  };
	  d3.timer = function() {
	    d3_timer.apply(this, arguments);
	  };
	  function d3_timer(callback, delay, then) {
	    var n = arguments.length;
	    if (n < 2) delay = 0;
	    if (n < 3) then = Date.now();
	    var time = then + delay, timer = {
	      c: callback,
	      t: time,
	      n: null
	    };
	    if (d3_timer_queueTail) d3_timer_queueTail.n = timer; else d3_timer_queueHead = timer;
	    d3_timer_queueTail = timer;
	    if (!d3_timer_interval) {
	      d3_timer_timeout = clearTimeout(d3_timer_timeout);
	      d3_timer_interval = 1;
	      d3_timer_frame(d3_timer_step);
	    }
	    return timer;
	  }
	  function d3_timer_step() {
	    var now = d3_timer_mark(), delay = d3_timer_sweep() - now;
	    if (delay > 24) {
	      if (isFinite(delay)) {
	        clearTimeout(d3_timer_timeout);
	        d3_timer_timeout = setTimeout(d3_timer_step, delay);
	      }
	      d3_timer_interval = 0;
	    } else {
	      d3_timer_interval = 1;
	      d3_timer_frame(d3_timer_step);
	    }
	  }
	  d3.timer.flush = function() {
	    d3_timer_mark();
	    d3_timer_sweep();
	  };
	  function d3_timer_mark() {
	    var now = Date.now(), timer = d3_timer_queueHead;
	    while (timer) {
	      if (now >= timer.t && timer.c(now - timer.t)) timer.c = null;
	      timer = timer.n;
	    }
	    return now;
	  }
	  function d3_timer_sweep() {
	    var t0, t1 = d3_timer_queueHead, time = Infinity;
	    while (t1) {
	      if (t1.c) {
	        if (t1.t < time) time = t1.t;
	        t1 = (t0 = t1).n;
	      } else {
	        t1 = t0 ? t0.n = t1.n : d3_timer_queueHead = t1.n;
	      }
	    }
	    d3_timer_queueTail = t0;
	    return time;
	  }
	  function d3_format_precision(x, p) {
	    return p - (x ? Math.ceil(Math.log(x) / Math.LN10) : 1);
	  }
	  d3.round = function(x, n) {
	    return n ? Math.round(x * (n = Math.pow(10, n))) / n : Math.round(x);
	  };
	  var d3_formatPrefixes = [ "y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y" ].map(d3_formatPrefix);
	  d3.formatPrefix = function(value, precision) {
	    var i = 0;
	    if (value = +value) {
	      if (value < 0) value *= -1;
	      if (precision) value = d3.round(value, d3_format_precision(value, precision));
	      i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10);
	      i = Math.max(-24, Math.min(24, Math.floor((i - 1) / 3) * 3));
	    }
	    return d3_formatPrefixes[8 + i / 3];
	  };
	  function d3_formatPrefix(d, i) {
	    var k = Math.pow(10, abs(8 - i) * 3);
	    return {
	      scale: i > 8 ? function(d) {
	        return d / k;
	      } : function(d) {
	        return d * k;
	      },
	      symbol: d
	    };
	  }
	  function d3_locale_numberFormat(locale) {
	    var locale_decimal = locale.decimal, locale_thousands = locale.thousands, locale_grouping = locale.grouping, locale_currency = locale.currency, formatGroup = locale_grouping && locale_thousands ? function(value, width) {
	      var i = value.length, t = [], j = 0, g = locale_grouping[0], length = 0;
	      while (i > 0 && g > 0) {
	        if (length + g + 1 > width) g = Math.max(1, width - length);
	        t.push(value.substring(i -= g, i + g));
	        if ((length += g + 1) > width) break;
	        g = locale_grouping[j = (j + 1) % locale_grouping.length];
	      }
	      return t.reverse().join(locale_thousands);
	    } : d3_identity;
	    return function(specifier) {
	      var match = d3_format_re.exec(specifier), fill = match[1] || " ", align = match[2] || ">", sign = match[3] || "-", symbol = match[4] || "", zfill = match[5], width = +match[6], comma = match[7], precision = match[8], type = match[9], scale = 1, prefix = "", suffix = "", integer = false, exponent = true;
	      if (precision) precision = +precision.substring(1);
	      if (zfill || fill === "0" && align === "=") {
	        zfill = fill = "0";
	        align = "=";
	      }
	      switch (type) {
	       case "n":
	        comma = true;
	        type = "g";
	        break;
	
	       case "%":
	        scale = 100;
	        suffix = "%";
	        type = "f";
	        break;
	
	       case "p":
	        scale = 100;
	        suffix = "%";
	        type = "r";
	        break;
	
	       case "b":
	       case "o":
	       case "x":
	       case "X":
	        if (symbol === "#") prefix = "0" + type.toLowerCase();
	
	       case "c":
	        exponent = false;
	
	       case "d":
	        integer = true;
	        precision = 0;
	        break;
	
	       case "s":
	        scale = -1;
	        type = "r";
	        break;
	      }
	      if (symbol === "$") prefix = locale_currency[0], suffix = locale_currency[1];
	      if (type == "r" && !precision) type = "g";
	      if (precision != null) {
	        if (type == "g") precision = Math.max(1, Math.min(21, precision)); else if (type == "e" || type == "f") precision = Math.max(0, Math.min(20, precision));
	      }
	      type = d3_format_types.get(type) || d3_format_typeDefault;
	      var zcomma = zfill && comma;
	      return function(value) {
	        var fullSuffix = suffix;
	        if (integer && value % 1) return "";
	        var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, "-") : sign === "-" ? "" : sign;
	        if (scale < 0) {
	          var unit = d3.formatPrefix(value, precision);
	          value = unit.scale(value);
	          fullSuffix = unit.symbol + suffix;
	        } else {
	          value *= scale;
	        }
	        value = type(value, precision);
	        var i = value.lastIndexOf("."), before, after;
	        if (i < 0) {
	          var j = exponent ? value.lastIndexOf("e") : -1;
	          if (j < 0) before = value, after = ""; else before = value.substring(0, j), after = value.substring(j);
	        } else {
	          before = value.substring(0, i);
	          after = locale_decimal + value.substring(i + 1);
	        }
	        if (!zfill && comma) before = formatGroup(before, Infinity);
	        var length = prefix.length + before.length + after.length + (zcomma ? 0 : negative.length), padding = length < width ? new Array(length = width - length + 1).join(fill) : "";
	        if (zcomma) before = formatGroup(padding + before, padding.length ? width - after.length : Infinity);
	        negative += prefix;
	        value = before + after;
	        return (align === "<" ? negative + value + padding : align === ">" ? padding + negative + value : align === "^" ? padding.substring(0, length >>= 1) + negative + value + padding.substring(length) : negative + (zcomma ? value : padding + value)) + fullSuffix;
	      };
	    };
	  }
	  var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i;
	  var d3_format_types = d3.map({
	    b: function(x) {
	      return x.toString(2);
	    },
	    c: function(x) {
	      return String.fromCharCode(x);
	    },
	    o: function(x) {
	      return x.toString(8);
	    },
	    x: function(x) {
	      return x.toString(16);
	    },
	    X: function(x) {
	      return x.toString(16).toUpperCase();
	    },
	    g: function(x, p) {
	      return x.toPrecision(p);
	    },
	    e: function(x, p) {
	      return x.toExponential(p);
	    },
	    f: function(x, p) {
	      return x.toFixed(p);
	    },
	    r: function(x, p) {
	      return (x = d3.round(x, d3_format_precision(x, p))).toFixed(Math.max(0, Math.min(20, d3_format_precision(x * (1 + 1e-15), p))));
	    }
	  });
	  function d3_format_typeDefault(x) {
	    return x + "";
	  }
	  var d3_time = d3.time = {}, d3_date = Date;
	  function d3_date_utc() {
	    this._ = new Date(arguments.length > 1 ? Date.UTC.apply(this, arguments) : arguments[0]);
	  }
	  d3_date_utc.prototype = {
	    getDate: function() {
	      return this._.getUTCDate();
	    },
	    getDay: function() {
	      return this._.getUTCDay();
	    },
	    getFullYear: function() {
	      return this._.getUTCFullYear();
	    },
	    getHours: function() {
	      return this._.getUTCHours();
	    },
	    getMilliseconds: function() {
	      return this._.getUTCMilliseconds();
	    },
	    getMinutes: function() {
	      return this._.getUTCMinutes();
	    },
	    getMonth: function() {
	      return this._.getUTCMonth();
	    },
	    getSeconds: function() {
	      return this._.getUTCSeconds();
	    },
	    getTime: function() {
	      return this._.getTime();
	    },
	    getTimezoneOffset: function() {
	      return 0;
	    },
	    valueOf: function() {
	      return this._.valueOf();
	    },
	    setDate: function() {
	      d3_time_prototype.setUTCDate.apply(this._, arguments);
	    },
	    setDay: function() {
	      d3_time_prototype.setUTCDay.apply(this._, arguments);
	    },
	    setFullYear: function() {
	      d3_time_prototype.setUTCFullYear.apply(this._, arguments);
	    },
	    setHours: function() {
	      d3_time_prototype.setUTCHours.apply(this._, arguments);
	    },
	    setMilliseconds: function() {
	      d3_time_prototype.setUTCMilliseconds.apply(this._, arguments);
	    },
	    setMinutes: function() {
	      d3_time_prototype.setUTCMinutes.apply(this._, arguments);
	    },
	    setMonth: function() {
	      d3_time_prototype.setUTCMonth.apply(this._, arguments);
	    },
	    setSeconds: function() {
	      d3_time_prototype.setUTCSeconds.apply(this._, arguments);
	    },
	    setTime: function() {
	      d3_time_prototype.setTime.apply(this._, arguments);
	    }
	  };
	  var d3_time_prototype = Date.prototype;
	  function d3_time_interval(local, step, number) {
	    function round(date) {
	      var d0 = local(date), d1 = offset(d0, 1);
	      return date - d0 < d1 - date ? d0 : d1;
	    }
	    function ceil(date) {
	      step(date = local(new d3_date(date - 1)), 1);
	      return date;
	    }
	    function offset(date, k) {
	      step(date = new d3_date(+date), k);
	      return date;
	    }
	    function range(t0, t1, dt) {
	      var time = ceil(t0), times = [];
	      if (dt > 1) {
	        while (time < t1) {
	          if (!(number(time) % dt)) times.push(new Date(+time));
	          step(time, 1);
	        }
	      } else {
	        while (time < t1) times.push(new Date(+time)), step(time, 1);
	      }
	      return times;
	    }
	    function range_utc(t0, t1, dt) {
	      try {
	        d3_date = d3_date_utc;
	        var utc = new d3_date_utc();
	        utc._ = t0;
	        return range(utc, t1, dt);
	      } finally {
	        d3_date = Date;
	      }
	    }
	    local.floor = local;
	    local.round = round;
	    local.ceil = ceil;
	    local.offset = offset;
	    local.range = range;
	    var utc = local.utc = d3_time_interval_utc(local);
	    utc.floor = utc;
	    utc.round = d3_time_interval_utc(round);
	    utc.ceil = d3_time_interval_utc(ceil);
	    utc.offset = d3_time_interval_utc(offset);
	    utc.range = range_utc;
	    return local;
	  }
	  function d3_time_interval_utc(method) {
	    return function(date, k) {
	      try {
	        d3_date = d3_date_utc;
	        var utc = new d3_date_utc();
	        utc._ = date;
	        return method(utc, k)._;
	      } finally {
	        d3_date = Date;
	      }
	    };
	  }
	  d3_time.year = d3_time_interval(function(date) {
	    date = d3_time.day(date);
	    date.setMonth(0, 1);
	    return date;
	  }, function(date, offset) {
	    date.setFullYear(date.getFullYear() + offset);
	  }, function(date) {
	    return date.getFullYear();
	  });
	  d3_time.years = d3_time.year.range;
	  d3_time.years.utc = d3_time.year.utc.range;
	  d3_time.day = d3_time_interval(function(date) {
	    var day = new d3_date(2e3, 0);
	    day.setFullYear(date.getFullYear(), date.getMonth(), date.getDate());
	    return day;
	  }, function(date, offset) {
	    date.setDate(date.getDate() + offset);
	  }, function(date) {
	    return date.getDate() - 1;
	  });
	  d3_time.days = d3_time.day.range;
	  d3_time.days.utc = d3_time.day.utc.range;
	  d3_time.dayOfYear = function(date) {
	    var year = d3_time.year(date);
	    return Math.floor((date - year - (date.getTimezoneOffset() - year.getTimezoneOffset()) * 6e4) / 864e5);
	  };
	  [ "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday" ].forEach(function(day, i) {
	    i = 7 - i;
	    var interval = d3_time[day] = d3_time_interval(function(date) {
	      (date = d3_time.day(date)).setDate(date.getDate() - (date.getDay() + i) % 7);
	      return date;
	    }, function(date, offset) {
	      date.setDate(date.getDate() + Math.floor(offset) * 7);
	    }, function(date) {
	      var day = d3_time.year(date).getDay();
	      return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7) - (day !== i);
	    });
	    d3_time[day + "s"] = interval.range;
	    d3_time[day + "s"].utc = interval.utc.range;
	    d3_time[day + "OfYear"] = function(date) {
	      var day = d3_time.year(date).getDay();
	      return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7);
	    };
	  });
	  d3_time.week = d3_time.sunday;
	  d3_time.weeks = d3_time.sunday.range;
	  d3_time.weeks.utc = d3_time.sunday.utc.range;
	  d3_time.weekOfYear = d3_time.sundayOfYear;
	  function d3_locale_timeFormat(locale) {
	    var locale_dateTime = locale.dateTime, locale_date = locale.date, locale_time = locale.time, locale_periods = locale.periods, locale_days = locale.days, locale_shortDays = locale.shortDays, locale_months = locale.months, locale_shortMonths = locale.shortMonths;
	    function d3_time_format(template) {
	      var n = template.length;
	      function format(date) {
	        var string = [], i = -1, j = 0, c, p, f;
	        while (++i < n) {
	          if (template.charCodeAt(i) === 37) {
	            string.push(template.slice(j, i));
	            if ((p = d3_time_formatPads[c = template.charAt(++i)]) != null) c = template.charAt(++i);
	            if (f = d3_time_formats[c]) c = f(date, p == null ? c === "e" ? " " : "0" : p);
	            string.push(c);
	            j = i + 1;
	          }
	        }
	        string.push(template.slice(j, i));
	        return string.join("");
	      }
	      format.parse = function(string) {
	        var d = {
	          y: 1900,
	          m: 0,
	          d: 1,
	          H: 0,
	          M: 0,
	          S: 0,
	          L: 0,
	          Z: null
	        }, i = d3_time_parse(d, template, string, 0);
	        if (i != string.length) return null;
	        if ("p" in d) d.H = d.H % 12 + d.p * 12;
	        var localZ = d.Z != null && d3_date !== d3_date_utc, date = new (localZ ? d3_date_utc : d3_date)();
	        if ("j" in d) date.setFullYear(d.y, 0, d.j); else if ("W" in d || "U" in d) {
	          if (!("w" in d)) d.w = "W" in d ? 1 : 0;
	          date.setFullYear(d.y, 0, 1);
	          date.setFullYear(d.y, 0, "W" in d ? (d.w + 6) % 7 + d.W * 7 - (date.getDay() + 5) % 7 : d.w + d.U * 7 - (date.getDay() + 6) % 7);
	        } else date.setFullYear(d.y, d.m, d.d);
	        date.setHours(d.H + (d.Z / 100 | 0), d.M + d.Z % 100, d.S, d.L);
	        return localZ ? date._ : date;
	      };
	      format.toString = function() {
	        return template;
	      };
	      return format;
	    }
	    function d3_time_parse(date, template, string, j) {
	      var c, p, t, i = 0, n = template.length, m = string.length;
	      while (i < n) {
	        if (j >= m) return -1;
	        c = template.charCodeAt(i++);
	        if (c === 37) {
	          t = template.charAt(i++);
	          p = d3_time_parsers[t in d3_time_formatPads ? template.charAt(i++) : t];
	          if (!p || (j = p(date, string, j)) < 0) return -1;
	        } else if (c != string.charCodeAt(j++)) {
	          return -1;
	        }
	      }
	      return j;
	    }
	    d3_time_format.utc = function(template) {
	      var local = d3_time_format(template);
	      function format(date) {
	        try {
	          d3_date = d3_date_utc;
	          var utc = new d3_date();
	          utc._ = date;
	          return local(utc);
	        } finally {
	          d3_date = Date;
	        }
	      }
	      format.parse = function(string) {
	        try {
	          d3_date = d3_date_utc;
	          var date = local.parse(string);
	          return date && date._;
	        } finally {
	          d3_date = Date;
	        }
	      };
	      format.toString = local.toString;
	      return format;
	    };
	    d3_time_format.multi = d3_time_format.utc.multi = d3_time_formatMulti;
	    var d3_time_periodLookup = d3.map(), d3_time_dayRe = d3_time_formatRe(locale_days), d3_time_dayLookup = d3_time_formatLookup(locale_days), d3_time_dayAbbrevRe = d3_time_formatRe(locale_shortDays), d3_time_dayAbbrevLookup = d3_time_formatLookup(locale_shortDays), d3_time_monthRe = d3_time_formatRe(locale_months), d3_time_monthLookup = d3_time_formatLookup(locale_months), d3_time_monthAbbrevRe = d3_time_formatRe(locale_shortMonths), d3_time_monthAbbrevLookup = d3_time_formatLookup(locale_shortMonths);
	    locale_periods.forEach(function(p, i) {
	      d3_time_periodLookup.set(p.toLowerCase(), i);
	    });
	    var d3_time_formats = {
	      a: function(d) {
	        return locale_shortDays[d.getDay()];
	      },
	      A: function(d) {
	        return locale_days[d.getDay()];
	      },
	      b: function(d) {
	        return locale_shortMonths[d.getMonth()];
	      },
	      B: function(d) {
	        return locale_months[d.getMonth()];
	      },
	      c: d3_time_format(locale_dateTime),
	      d: function(d, p) {
	        return d3_time_formatPad(d.getDate(), p, 2);
	      },
	      e: function(d, p) {
	        return d3_time_formatPad(d.getDate(), p, 2);
	      },
	      H: function(d, p) {
	        return d3_time_formatPad(d.getHours(), p, 2);
	      },
	      I: function(d, p) {
	        return d3_time_formatPad(d.getHours() % 12 || 12, p, 2);
	      },
	      j: function(d, p) {
	        return d3_time_formatPad(1 + d3_time.dayOfYear(d), p, 3);
	      },
	      L: function(d, p) {
	        return d3_time_formatPad(d.getMilliseconds(), p, 3);
	      },
	      m: function(d, p) {
	        return d3_time_formatPad(d.getMonth() + 1, p, 2);
	      },
	      M: function(d, p) {
	        return d3_time_formatPad(d.getMinutes(), p, 2);
	      },
	      p: function(d) {
	        return locale_periods[+(d.getHours() >= 12)];
	      },
	      S: function(d, p) {
	        return d3_time_formatPad(d.getSeconds(), p, 2);
	      },
	      U: function(d, p) {
	        return d3_time_formatPad(d3_time.sundayOfYear(d), p, 2);
	      },
	      w: function(d) {
	        return d.getDay();
	      },
	      W: function(d, p) {
	        return d3_time_formatPad(d3_time.mondayOfYear(d), p, 2);
	      },
	      x: d3_time_format(locale_date),
	      X: d3_time_format(locale_time),
	      y: function(d, p) {
	        return d3_time_formatPad(d.getFullYear() % 100, p, 2);
	      },
	      Y: function(d, p) {
	        return d3_time_formatPad(d.getFullYear() % 1e4, p, 4);
	      },
	      Z: d3_time_zone,
	      "%": function() {
	        return "%";
	      }
	    };
	    var d3_time_parsers = {
	      a: d3_time_parseWeekdayAbbrev,
	      A: d3_time_parseWeekday,
	      b: d3_time_parseMonthAbbrev,
	      B: d3_time_parseMonth,
	      c: d3_time_parseLocaleFull,
	      d: d3_time_parseDay,
	      e: d3_time_parseDay,
	      H: d3_time_parseHour24,
	      I: d3_time_parseHour24,
	      j: d3_time_parseDayOfYear,
	      L: d3_time_parseMilliseconds,
	      m: d3_time_parseMonthNumber,
	      M: d3_time_parseMinutes,
	      p: d3_time_parseAmPm,
	      S: d3_time_parseSeconds,
	      U: d3_time_parseWeekNumberSunday,
	      w: d3_time_parseWeekdayNumber,
	      W: d3_time_parseWeekNumberMonday,
	      x: d3_time_parseLocaleDate,
	      X: d3_time_parseLocaleTime,
	      y: d3_time_parseYear,
	      Y: d3_time_parseFullYear,
	      Z: d3_time_parseZone,
	      "%": d3_time_parseLiteralPercent
	    };
	    function d3_time_parseWeekdayAbbrev(date, string, i) {
	      d3_time_dayAbbrevRe.lastIndex = 0;
	      var n = d3_time_dayAbbrevRe.exec(string.slice(i));
	      return n ? (date.w = d3_time_dayAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
	    }
	    function d3_time_parseWeekday(date, string, i) {
	      d3_time_dayRe.lastIndex = 0;
	      var n = d3_time_dayRe.exec(string.slice(i));
	      return n ? (date.w = d3_time_dayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
	    }
	    function d3_time_parseMonthAbbrev(date, string, i) {
	      d3_time_monthAbbrevRe.lastIndex = 0;
	      var n = d3_time_monthAbbrevRe.exec(string.slice(i));
	      return n ? (date.m = d3_time_monthAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
	    }
	    function d3_time_parseMonth(date, string, i) {
	      d3_time_monthRe.lastIndex = 0;
	      var n = d3_time_monthRe.exec(string.slice(i));
	      return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
	    }
	    function d3_time_parseLocaleFull(date, string, i) {
	      return d3_time_parse(date, d3_time_formats.c.toString(), string, i);
	    }
	    function d3_time_parseLocaleDate(date, string, i) {
	      return d3_time_parse(date, d3_time_formats.x.toString(), string, i);
	    }
	    function d3_time_parseLocaleTime(date, string, i) {
	      return d3_time_parse(date, d3_time_formats.X.toString(), string, i);
	    }
	    function d3_time_parseAmPm(date, string, i) {
	      var n = d3_time_periodLookup.get(string.slice(i, i += 2).toLowerCase());
	      return n == null ? -1 : (date.p = n, i);
	    }
	    return d3_time_format;
	  }
	  var d3_time_formatPads = {
	    "-": "",
	    _: " ",
	    "0": "0"
	  }, d3_time_numberRe = /^\s*\d+/, d3_time_percentRe = /^%/;
	  function d3_time_formatPad(value, fill, width) {
	    var sign = value < 0 ? "-" : "", string = (sign ? -value : value) + "", length = string.length;
	    return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);
	  }
	  function d3_time_formatRe(names) {
	    return new RegExp("^(?:" + names.map(d3.requote).join("|") + ")", "i");
	  }
	  function d3_time_formatLookup(names) {
	    var map = new d3_Map(), i = -1, n = names.length;
	    while (++i < n) map.set(names[i].toLowerCase(), i);
	    return map;
	  }
	  function d3_time_parseWeekdayNumber(date, string, i) {
	    d3_time_numberRe.lastIndex = 0;
	    var n = d3_time_numberRe.exec(string.slice(i, i + 1));
	    return n ? (date.w = +n[0], i + n[0].length) : -1;
	  }
	  function d3_time_parseWeekNumberSunday(date, string, i) {
	    d3_time_numberRe.lastIndex = 0;
	    var n = d3_time_numberRe.exec(string.slice(i));
	    return n ? (date.U = +n[0], i + n[0].length) : -1;
	  }
	  function d3_time_parseWeekNumberMonday(date, string, i) {
	    d3_time_numberRe.lastIndex = 0;
	    var n = d3_time_numberRe.exec(string.slice(i));
	    return n ? (date.W = +n[0], i + n[0].length) : -1;
	  }
	  function d3_time_parseFullYear(date, string, i) {
	    d3_time_numberRe.lastIndex = 0;
	    var n = d3_time_numberRe.exec(string.slice(i, i + 4));
	    return n ? (date.y = +n[0], i + n[0].length) : -1;
	  }
	  function d3_time_parseYear(date, string, i) {
	    d3_time_numberRe.lastIndex = 0;
	    var n = d3_time_numberRe.exec(string.slice(i, i + 2));
	    return n ? (date.y = d3_time_expandYear(+n[0]), i + n[0].length) : -1;
	  }
	  function d3_time_parseZone(date, string, i) {
	    return /^[+-]\d{4}$/.test(string = string.slice(i, i + 5)) ? (date.Z = -string, 
	    i + 5) : -1;
	  }
	  function d3_time_expandYear(d) {
	    return d + (d > 68 ? 1900 : 2e3);
	  }
	  function d3_time_parseMonthNumber(date, string, i) {
	    d3_time_numberRe.lastIndex = 0;
	    var n = d3_time_numberRe.exec(string.slice(i, i + 2));
	    return n ? (date.m = n[0] - 1, i + n[0].length) : -1;
	  }
	  function d3_time_parseDay(date, string, i) {
	    d3_time_numberRe.lastIndex = 0;
	    var n = d3_time_numberRe.exec(string.slice(i, i + 2));
	    return n ? (date.d = +n[0], i + n[0].length) : -1;
	  }
	  function d3_time_parseDayOfYear(date, string, i) {
	    d3_time_numberRe.lastIndex = 0;
	    var n = d3_time_numberRe.exec(string.slice(i, i + 3));
	    return n ? (date.j = +n[0], i + n[0].length) : -1;
	  }
	  function d3_time_parseHour24(date, string, i) {
	    d3_time_numberRe.lastIndex = 0;
	    var n = d3_time_numberRe.exec(string.slice(i, i + 2));
	    return n ? (date.H = +n[0], i + n[0].length) : -1;
	  }
	  function d3_time_parseMinutes(date, string, i) {
	    d3_time_numberRe.lastIndex = 0;
	    var n = d3_time_numberRe.exec(string.slice(i, i + 2));
	    return n ? (date.M = +n[0], i + n[0].length) : -1;
	  }
	  function d3_time_parseSeconds(date, string, i) {
	    d3_time_numberRe.lastIndex = 0;
	    var n = d3_time_numberRe.exec(string.slice(i, i + 2));
	    return n ? (date.S = +n[0], i + n[0].length) : -1;
	  }
	  function d3_time_parseMilliseconds(date, string, i) {
	    d3_time_numberRe.lastIndex = 0;
	    var n = d3_time_numberRe.exec(string.slice(i, i + 3));
	    return n ? (date.L = +n[0], i + n[0].length) : -1;
	  }
	  function d3_time_zone(d) {
	    var z = d.getTimezoneOffset(), zs = z > 0 ? "-" : "+", zh = abs(z) / 60 | 0, zm = abs(z) % 60;
	    return zs + d3_time_formatPad(zh, "0", 2) + d3_time_formatPad(zm, "0", 2);
	  }
	  function d3_time_parseLiteralPercent(date, string, i) {
	    d3_time_percentRe.lastIndex = 0;
	    var n = d3_time_percentRe.exec(string.slice(i, i + 1));
	    return n ? i + n[0].length : -1;
	  }
	  function d3_time_formatMulti(formats) {
	    var n = formats.length, i = -1;
	    while (++i < n) formats[i][0] = this(formats[i][0]);
	    return function(date) {
	      var i = 0, f = formats[i];
	      while (!f[1](date)) f = formats[++i];
	      return f[0](date);
	    };
	  }
	  d3.locale = function(locale) {
	    return {
	      numberFormat: d3_locale_numberFormat(locale),
	      timeFormat: d3_locale_timeFormat(locale)
	    };
	  };
	  var d3_locale_enUS = d3.locale({
	    decimal: ".",
	    thousands: ",",
	    grouping: [ 3 ],
	    currency: [ "$", "" ],
	    dateTime: "%a %b %e %X %Y",
	    date: "%m/%d/%Y",
	    time: "%H:%M:%S",
	    periods: [ "AM", "PM" ],
	    days: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ],
	    shortDays: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ],
	    months: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ],
	    shortMonths: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]
	  });
	  d3.format = d3_locale_enUS.numberFormat;
	  d3.geo = {};
	  function d3_adder() {}
	  d3_adder.prototype = {
	    s: 0,
	    t: 0,
	    add: function(y) {
	      d3_adderSum(y, this.t, d3_adderTemp);
	      d3_adderSum(d3_adderTemp.s, this.s, this);
	      if (this.s) this.t += d3_adderTemp.t; else this.s = d3_adderTemp.t;
	    },
	    reset: function() {
	      this.s = this.t = 0;
	    },
	    valueOf: function() {
	      return this.s;
	    }
	  };
	  var d3_adderTemp = new d3_adder();
	  function d3_adderSum(a, b, o) {
	    var x = o.s = a + b, bv = x - a, av = x - bv;
	    o.t = a - av + (b - bv);
	  }
	  d3.geo.stream = function(object, listener) {
	    if (object && d3_geo_streamObjectType.hasOwnProperty(object.type)) {
	      d3_geo_streamObjectType[object.type](object, listener);
	    } else {
	      d3_geo_streamGeometry(object, listener);
	    }
	  };
	  function d3_geo_streamGeometry(geometry, listener) {
	    if (geometry && d3_geo_streamGeometryType.hasOwnProperty(geometry.type)) {
	      d3_geo_streamGeometryType[geometry.type](geometry, listener);
	    }
	  }
	  var d3_geo_streamObjectType = {
	    Feature: function(feature, listener) {
	      d3_geo_streamGeometry(feature.geometry, listener);
	    },
	    FeatureCollection: function(object, listener) {
	      var features = object.features, i = -1, n = features.length;
	      while (++i < n) d3_geo_streamGeometry(features[i].geometry, listener);
	    }
	  };
	  var d3_geo_streamGeometryType = {
	    Sphere: function(object, listener) {
	      listener.sphere();
	    },
	    Point: function(object, listener) {
	      object = object.coordinates;
	      listener.point(object[0], object[1], object[2]);
	    },
	    MultiPoint: function(object, listener) {
	      var coordinates = object.coordinates, i = -1, n = coordinates.length;
	      while (++i < n) object = coordinates[i], listener.point(object[0], object[1], object[2]);
	    },
	    LineString: function(object, listener) {
	      d3_geo_streamLine(object.coordinates, listener, 0);
	    },
	    MultiLineString: function(object, listener) {
	      var coordinates = object.coordinates, i = -1, n = coordinates.length;
	      while (++i < n) d3_geo_streamLine(coordinates[i], listener, 0);
	    },
	    Polygon: function(object, listener) {
	      d3_geo_streamPolygon(object.coordinates, listener);
	    },
	    MultiPolygon: function(object, listener) {
	      var coordinates = object.coordinates, i = -1, n = coordinates.length;
	      while (++i < n) d3_geo_streamPolygon(coordinates[i], listener);
	    },
	    GeometryCollection: function(object, listener) {
	      var geometries = object.geometries, i = -1, n = geometries.length;
	      while (++i < n) d3_geo_streamGeometry(geometries[i], listener);
	    }
	  };
	  function d3_geo_streamLine(coordinates, listener, closed) {
	    var i = -1, n = coordinates.length - closed, coordinate;
	    listener.lineStart();
	    while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1], coordinate[2]);
	    listener.lineEnd();
	  }
	  function d3_geo_streamPolygon(coordinates, listener) {
	    var i = -1, n = coordinates.length;
	    listener.polygonStart();
	    while (++i < n) d3_geo_streamLine(coordinates[i], listener, 1);
	    listener.polygonEnd();
	  }
	  d3.geo.area = function(object) {
	    d3_geo_areaSum = 0;
	    d3.geo.stream(object, d3_geo_area);
	    return d3_geo_areaSum;
	  };
	  var d3_geo_areaSum, d3_geo_areaRingSum = new d3_adder();
	  var d3_geo_area = {
	    sphere: function() {
	      d3_geo_areaSum += 4 * π;
	    },
	    point: d3_noop,
	    lineStart: d3_noop,
	    lineEnd: d3_noop,
	    polygonStart: function() {
	      d3_geo_areaRingSum.reset();
	      d3_geo_area.lineStart = d3_geo_areaRingStart;
	    },
	    polygonEnd: function() {
	      var area = 2 * d3_geo_areaRingSum;
	      d3_geo_areaSum += area < 0 ? 4 * π + area : area;
	      d3_geo_area.lineStart = d3_geo_area.lineEnd = d3_geo_area.point = d3_noop;
	    }
	  };
	  function d3_geo_areaRingStart() {
	    var λ00, φ00, λ0, cosφ0, sinφ0;
	    d3_geo_area.point = function(λ, φ) {
	      d3_geo_area.point = nextPoint;
	      λ0 = (λ00 = λ) * d3_radians, cosφ0 = Math.cos(φ = (φ00 = φ) * d3_radians / 2 + π / 4), 
	      sinφ0 = Math.sin(φ);
	    };
	    function nextPoint(λ, φ) {
	      λ *= d3_radians;
	      φ = φ * d3_radians / 2 + π / 4;
	      var dλ = λ - λ0, sdλ = dλ >= 0 ? 1 : -1, adλ = sdλ * dλ, cosφ = Math.cos(φ), sinφ = Math.sin(φ), k = sinφ0 * sinφ, u = cosφ0 * cosφ + k * Math.cos(adλ), v = k * sdλ * Math.sin(adλ);
	      d3_geo_areaRingSum.add(Math.atan2(v, u));
	      λ0 = λ, cosφ0 = cosφ, sinφ0 = sinφ;
	    }
	    d3_geo_area.lineEnd = function() {
	      nextPoint(λ00, φ00);
	    };
	  }
	  function d3_geo_cartesian(spherical) {
	    var λ = spherical[0], φ = spherical[1], cosφ = Math.cos(φ);
	    return [ cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ) ];
	  }
	  function d3_geo_cartesianDot(a, b) {
	    return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
	  }
	  function d3_geo_cartesianCross(a, b) {
	    return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0] ];
	  }
	  function d3_geo_cartesianAdd(a, b) {
	    a[0] += b[0];
	    a[1] += b[1];
	    a[2] += b[2];
	  }
	  function d3_geo_cartesianScale(vector, k) {
	    return [ vector[0] * k, vector[1] * k, vector[2] * k ];
	  }
	  function d3_geo_cartesianNormalize(d) {
	    var l = Math.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
	    d[0] /= l;
	    d[1] /= l;
	    d[2] /= l;
	  }
	  function d3_geo_spherical(cartesian) {
	    return [ Math.atan2(cartesian[1], cartesian[0]), d3_asin(cartesian[2]) ];
	  }
	  function d3_geo_sphericalEqual(a, b) {
	    return abs(a[0] - b[0]) < ε && abs(a[1] - b[1]) < ε;
	  }
	  d3.geo.bounds = function() {
	    var λ0, φ0, λ1, φ1, λ_, λ__, φ__, p0, dλSum, ranges, range;
	    var bound = {
	      point: point,
	      lineStart: lineStart,
	      lineEnd: lineEnd,
	      polygonStart: function() {
	        bound.point = ringPoint;
	        bound.lineStart = ringStart;
	        bound.lineEnd = ringEnd;
	        dλSum = 0;
	        d3_geo_area.polygonStart();
	      },
	      polygonEnd: function() {
	        d3_geo_area.polygonEnd();
	        bound.point = point;
	        bound.lineStart = lineStart;
	        bound.lineEnd = lineEnd;
	        if (d3_geo_areaRingSum < 0) λ0 = -(λ1 = 180), φ0 = -(φ1 = 90); else if (dλSum > ε) φ1 = 90; else if (dλSum < -ε) φ0 = -90;
	        range[0] = λ0, range[1] = λ1;
	      }
	    };
	    function point(λ, φ) {
	      ranges.push(range = [ λ0 = λ, λ1 = λ ]);
	      if (φ < φ0) φ0 = φ;
	      if (φ > φ1) φ1 = φ;
	    }
	    function linePoint(λ, φ) {
	      var p = d3_geo_cartesian([ λ * d3_radians, φ * d3_radians ]);
	      if (p0) {
	        var normal = d3_geo_cartesianCross(p0, p), equatorial = [ normal[1], -normal[0], 0 ], inflection = d3_geo_cartesianCross(equatorial, normal);
	        d3_geo_cartesianNormalize(inflection);
	        inflection = d3_geo_spherical(inflection);
	        var dλ = λ - λ_, s = dλ > 0 ? 1 : -1, λi = inflection[0] * d3_degrees * s, antimeridian = abs(dλ) > 180;
	        if (antimeridian ^ (s * λ_ < λi && λi < s * λ)) {
	          var φi = inflection[1] * d3_degrees;
	          if (φi > φ1) φ1 = φi;
	        } else if (λi = (λi + 360) % 360 - 180, antimeridian ^ (s * λ_ < λi && λi < s * λ)) {
	          var φi = -inflection[1] * d3_degrees;
	          if (φi < φ0) φ0 = φi;
	        } else {
	          if (φ < φ0) φ0 = φ;
	          if (φ > φ1) φ1 = φ;
	        }
	        if (antimeridian) {
	          if (λ < λ_) {
	            if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ;
	          } else {
	            if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ;
	          }
	        } else {
	          if (λ1 >= λ0) {
	            if (λ < λ0) λ0 = λ;
	            if (λ > λ1) λ1 = λ;
	          } else {
	            if (λ > λ_) {
	              if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ;
	            } else {
	              if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ;
	            }
	          }
	        }
	      } else {
	        point(λ, φ);
	      }
	      p0 = p, λ_ = λ;
	    }
	    function lineStart() {
	      bound.point = linePoint;
	    }
	    function lineEnd() {
	      range[0] = λ0, range[1] = λ1;
	      bound.point = point;
	      p0 = null;
	    }
	    function ringPoint(λ, φ) {
	      if (p0) {
	        var dλ = λ - λ_;
	        dλSum += abs(dλ) > 180 ? dλ + (dλ > 0 ? 360 : -360) : dλ;
	      } else λ__ = λ, φ__ = φ;
	      d3_geo_area.point(λ, φ);
	      linePoint(λ, φ);
	    }
	    function ringStart() {
	      d3_geo_area.lineStart();
	    }
	    function ringEnd() {
	      ringPoint(λ__, φ__);
	      d3_geo_area.lineEnd();
	      if (abs(dλSum) > ε) λ0 = -(λ1 = 180);
	      range[0] = λ0, range[1] = λ1;
	      p0 = null;
	    }
	    function angle(λ0, λ1) {
	      return (λ1 -= λ0) < 0 ? λ1 + 360 : λ1;
	    }
	    function compareRanges(a, b) {
	      return a[0] - b[0];
	    }
	    function withinRange(x, range) {
	      return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x;
	    }
	    return function(feature) {
	      φ1 = λ1 = -(λ0 = φ0 = Infinity);
	      ranges = [];
	      d3.geo.stream(feature, bound);
	      var n = ranges.length;
	      if (n) {
	        ranges.sort(compareRanges);
	        for (var i = 1, a = ranges[0], b, merged = [ a ]; i < n; ++i) {
	          b = ranges[i];
	          if (withinRange(b[0], a) || withinRange(b[1], a)) {
	            if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1];
	            if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0];
	          } else {
	            merged.push(a = b);
	          }
	        }
	        var best = -Infinity, dλ;
	        for (var n = merged.length - 1, i = 0, a = merged[n], b; i <= n; a = b, ++i) {
	          b = merged[i];
	          if ((dλ = angle(a[1], b[0])) > best) best = dλ, λ0 = b[0], λ1 = a[1];
	        }
	      }
	      ranges = range = null;
	      return λ0 === Infinity || φ0 === Infinity ? [ [ NaN, NaN ], [ NaN, NaN ] ] : [ [ λ0, φ0 ], [ λ1, φ1 ] ];
	    };
	  }();
	  d3.geo.centroid = function(object) {
	    d3_geo_centroidW0 = d3_geo_centroidW1 = d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0;
	    d3.geo.stream(object, d3_geo_centroid);
	    var x = d3_geo_centroidX2, y = d3_geo_centroidY2, z = d3_geo_centroidZ2, m = x * x + y * y + z * z;
	    if (m < ε2) {
	      x = d3_geo_centroidX1, y = d3_geo_centroidY1, z = d3_geo_centroidZ1;
	      if (d3_geo_centroidW1 < ε) x = d3_geo_centroidX0, y = d3_geo_centroidY0, z = d3_geo_centroidZ0;
	      m = x * x + y * y + z * z;
	      if (m < ε2) return [ NaN, NaN ];
	    }
	    return [ Math.atan2(y, x) * d3_degrees, d3_asin(z / Math.sqrt(m)) * d3_degrees ];
	  };
	  var d3_geo_centroidW0, d3_geo_centroidW1, d3_geo_centroidX0, d3_geo_centroidY0, d3_geo_centroidZ0, d3_geo_centroidX1, d3_geo_centroidY1, d3_geo_centroidZ1, d3_geo_centroidX2, d3_geo_centroidY2, d3_geo_centroidZ2;
	  var d3_geo_centroid = {
	    sphere: d3_noop,
	    point: d3_geo_centroidPoint,
	    lineStart: d3_geo_centroidLineStart,
	    lineEnd: d3_geo_centroidLineEnd,
	    polygonStart: function() {
	      d3_geo_centroid.lineStart = d3_geo_centroidRingStart;
	    },
	    polygonEnd: function() {
	      d3_geo_centroid.lineStart = d3_geo_centroidLineStart;
	    }
	  };
	  function d3_geo_centroidPoint(λ, φ) {
	    λ *= d3_radians;
	    var cosφ = Math.cos(φ *= d3_radians);
	    d3_geo_centroidPointXYZ(cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ));
	  }
	  function d3_geo_centroidPointXYZ(x, y, z) {
	    ++d3_geo_centroidW0;
	    d3_geo_centroidX0 += (x - d3_geo_centroidX0) / d3_geo_centroidW0;
	    d3_geo_centroidY0 += (y - d3_geo_centroidY0) / d3_geo_centroidW0;
	    d3_geo_centroidZ0 += (z - d3_geo_centroidZ0) / d3_geo_centroidW0;
	  }
	  function d3_geo_centroidLineStart() {
	    var x0, y0, z0;
	    d3_geo_centroid.point = function(λ, φ) {
	      λ *= d3_radians;
	      var cosφ = Math.cos(φ *= d3_radians);
	      x0 = cosφ * Math.cos(λ);
	      y0 = cosφ * Math.sin(λ);
	      z0 = Math.sin(φ);
	      d3_geo_centroid.point = nextPoint;
	      d3_geo_centroidPointXYZ(x0, y0, z0);
	    };
	    function nextPoint(λ, φ) {
	      λ *= d3_radians;
	      var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), w = Math.atan2(Math.sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z);
	      d3_geo_centroidW1 += w;
	      d3_geo_centroidX1 += w * (x0 + (x0 = x));
	      d3_geo_centroidY1 += w * (y0 + (y0 = y));
	      d3_geo_centroidZ1 += w * (z0 + (z0 = z));
	      d3_geo_centroidPointXYZ(x0, y0, z0);
	    }
	  }
	  function d3_geo_centroidLineEnd() {
	    d3_geo_centroid.point = d3_geo_centroidPoint;
	  }
	  function d3_geo_centroidRingStart() {
	    var λ00, φ00, x0, y0, z0;
	    d3_geo_centroid.point = function(λ, φ) {
	      λ00 = λ, φ00 = φ;
	      d3_geo_centroid.point = nextPoint;
	      λ *= d3_radians;
	      var cosφ = Math.cos(φ *= d3_radians);
	      x0 = cosφ * Math.cos(λ);
	      y0 = cosφ * Math.sin(λ);
	      z0 = Math.sin(φ);
	      d3_geo_centroidPointXYZ(x0, y0, z0);
	    };
	    d3_geo_centroid.lineEnd = function() {
	      nextPoint(λ00, φ00);
	      d3_geo_centroid.lineEnd = d3_geo_centroidLineEnd;
	      d3_geo_centroid.point = d3_geo_centroidPoint;
	    };
	    function nextPoint(λ, φ) {
	      λ *= d3_radians;
	      var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), cx = y0 * z - z0 * y, cy = z0 * x - x0 * z, cz = x0 * y - y0 * x, m = Math.sqrt(cx * cx + cy * cy + cz * cz), u = x0 * x + y0 * y + z0 * z, v = m && -d3_acos(u) / m, w = Math.atan2(m, u);
	      d3_geo_centroidX2 += v * cx;
	      d3_geo_centroidY2 += v * cy;
	      d3_geo_centroidZ2 += v * cz;
	      d3_geo_centroidW1 += w;
	      d3_geo_centroidX1 += w * (x0 + (x0 = x));
	      d3_geo_centroidY1 += w * (y0 + (y0 = y));
	      d3_geo_centroidZ1 += w * (z0 + (z0 = z));
	      d3_geo_centroidPointXYZ(x0, y0, z0);
	    }
	  }
	  function d3_geo_compose(a, b) {
	    function compose(x, y) {
	      return x = a(x, y), b(x[0], x[1]);
	    }
	    if (a.invert && b.invert) compose.invert = function(x, y) {
	      return x = b.invert(x, y), x && a.invert(x[0], x[1]);
	    };
	    return compose;
	  }
	  function d3_true() {
	    return true;
	  }
	  function d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener) {
	    var subject = [], clip = [];
	    segments.forEach(function(segment) {
	      if ((n = segment.length - 1) <= 0) return;
	      var n, p0 = segment[0], p1 = segment[n];
	      if (d3_geo_sphericalEqual(p0, p1)) {
	        listener.lineStart();
	        for (var i = 0; i < n; ++i) listener.point((p0 = segment[i])[0], p0[1]);
	        listener.lineEnd();
	        return;
	      }
	      var a = new d3_geo_clipPolygonIntersection(p0, segment, null, true), b = new d3_geo_clipPolygonIntersection(p0, null, a, false);
	      a.o = b;
	      subject.push(a);
	      clip.push(b);
	      a = new d3_geo_clipPolygonIntersection(p1, segment, null, false);
	      b = new d3_geo_clipPolygonIntersection(p1, null, a, true);
	      a.o = b;
	      subject.push(a);
	      clip.push(b);
	    });
	    clip.sort(compare);
	    d3_geo_clipPolygonLinkCircular(subject);
	    d3_geo_clipPolygonLinkCircular(clip);
	    if (!subject.length) return;
	    for (var i = 0, entry = clipStartInside, n = clip.length; i < n; ++i) {
	      clip[i].e = entry = !entry;
	    }
	    var start = subject[0], points, point;
	    while (1) {
	      var current = start, isSubject = true;
	      while (current.v) if ((current = current.n) === start) return;
	      points = current.z;
	      listener.lineStart();
	      do {
	        current.v = current.o.v = true;
	        if (current.e) {
	          if (isSubject) {
	            for (var i = 0, n = points.length; i < n; ++i) listener.point((point = points[i])[0], point[1]);
	          } else {
	            interpolate(current.x, current.n.x, 1, listener);
	          }
	          current = current.n;
	        } else {
	          if (isSubject) {
	            points = current.p.z;
	            for (var i = points.length - 1; i >= 0; --i) listener.point((point = points[i])[0], point[1]);
	          } else {
	            interpolate(current.x, current.p.x, -1, listener);
	          }
	          current = current.p;
	        }
	        current = current.o;
	        points = current.z;
	        isSubject = !isSubject;
	      } while (!current.v);
	      listener.lineEnd();
	    }
	  }
	  function d3_geo_clipPolygonLinkCircular(array) {
	    if (!(n = array.length)) return;
	    var n, i = 0, a = array[0], b;
	    while (++i < n) {
	      a.n = b = array[i];
	      b.p = a;
	      a = b;
	    }
	    a.n = b = array[0];
	    b.p = a;
	  }
	  function d3_geo_clipPolygonIntersection(point, points, other, entry) {
	    this.x = point;
	    this.z = points;
	    this.o = other;
	    this.e = entry;
	    this.v = false;
	    this.n = this.p = null;
	  }
	  function d3_geo_clip(pointVisible, clipLine, interpolate, clipStart) {
	    return function(rotate, listener) {
	      var line = clipLine(listener), rotatedClipStart = rotate.invert(clipStart[0], clipStart[1]);
	      var clip = {
	        point: point,
	        lineStart: lineStart,
	        lineEnd: lineEnd,
	        polygonStart: function() {
	          clip.point = pointRing;
	          clip.lineStart = ringStart;
	          clip.lineEnd = ringEnd;
	          segments = [];
	          polygon = [];
	        },
	        polygonEnd: function() {
	          clip.point = point;
	          clip.lineStart = lineStart;
	          clip.lineEnd = lineEnd;
	          segments = d3.merge(segments);
	          var clipStartInside = d3_geo_pointInPolygon(rotatedClipStart, polygon);
	          if (segments.length) {
	            if (!polygonStarted) listener.polygonStart(), polygonStarted = true;
	            d3_geo_clipPolygon(segments, d3_geo_clipSort, clipStartInside, interpolate, listener);
	          } else if (clipStartInside) {
	            if (!polygonStarted) listener.polygonStart(), polygonStarted = true;
	            listener.lineStart();
	            interpolate(null, null, 1, listener);
	            listener.lineEnd();
	          }
	          if (polygonStarted) listener.polygonEnd(), polygonStarted = false;
	          segments = polygon = null;
	        },
	        sphere: function() {
	          listener.polygonStart();
	          listener.lineStart();
	          interpolate(null, null, 1, listener);
	          listener.lineEnd();
	          listener.polygonEnd();
	        }
	      };
	      function point(λ, φ) {
	        var point = rotate(λ, φ);
	        if (pointVisible(λ = point[0], φ = point[1])) listener.point(λ, φ);
	      }
	      function pointLine(λ, φ) {
	        var point = rotate(λ, φ);
	        line.point(point[0], point[1]);
	      }
	      function lineStart() {
	        clip.point = pointLine;
	        line.lineStart();
	      }
	      function lineEnd() {
	        clip.point = point;
	        line.lineEnd();
	      }
	      var segments;
	      var buffer = d3_geo_clipBufferListener(), ringListener = clipLine(buffer), polygonStarted = false, polygon, ring;
	      function pointRing(λ, φ) {
	        ring.push([ λ, φ ]);
	        var point = rotate(λ, φ);
	        ringListener.point(point[0], point[1]);
	      }
	      function ringStart() {
	        ringListener.lineStart();
	        ring = [];
	      }
	      function ringEnd() {
	        pointRing(ring[0][0], ring[0][1]);
	        ringListener.lineEnd();
	        var clean = ringListener.clean(), ringSegments = buffer.buffer(), segment, n = ringSegments.length;
	        ring.pop();
	        polygon.push(ring);
	        ring = null;
	        if (!n) return;
	        if (clean & 1) {
	          segment = ringSegments[0];
	          var n = segment.length - 1, i = -1, point;
	          if (n > 0) {
	            if (!polygonStarted) listener.polygonStart(), polygonStarted = true;
	            listener.lineStart();
	            while (++i < n) listener.point((point = segment[i])[0], point[1]);
	            listener.lineEnd();
	          }
	          return;
	        }
	        if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));
	        segments.push(ringSegments.filter(d3_geo_clipSegmentLength1));
	      }
	      return clip;
	    };
	  }
	  function d3_geo_clipSegmentLength1(segment) {
	    return segment.length > 1;
	  }
	  function d3_geo_clipBufferListener() {
	    var lines = [], line;
	    return {
	      lineStart: function() {
	        lines.push(line = []);
	      },
	      point: function(λ, φ) {
	        line.push([ λ, φ ]);
	      },
	      lineEnd: d3_noop,
	      buffer: function() {
	        var buffer = lines;
	        lines = [];
	        line = null;
	        return buffer;
	      },
	      rejoin: function() {
	        if (lines.length > 1) lines.push(lines.pop().concat(lines.shift()));
	      }
	    };
	  }
	  function d3_geo_clipSort(a, b) {
	    return ((a = a.x)[0] < 0 ? a[1] - halfπ - ε : halfπ - a[1]) - ((b = b.x)[0] < 0 ? b[1] - halfπ - ε : halfπ - b[1]);
	  }
	  var d3_geo_clipAntimeridian = d3_geo_clip(d3_true, d3_geo_clipAntimeridianLine, d3_geo_clipAntimeridianInterpolate, [ -π, -π / 2 ]);
	  function d3_geo_clipAntimeridianLine(listener) {
	    var λ0 = NaN, φ0 = NaN, sλ0 = NaN, clean;
	    return {
	      lineStart: function() {
	        listener.lineStart();
	        clean = 1;
	      },
	      point: function(λ1, φ1) {
	        var sλ1 = λ1 > 0 ? π : -π, dλ = abs(λ1 - λ0);
	        if (abs(dλ - π) < ε) {
	          listener.point(λ0, φ0 = (φ0 + φ1) / 2 > 0 ? halfπ : -halfπ);
	          listener.point(sλ0, φ0);
	          listener.lineEnd();
	          listener.lineStart();
	          listener.point(sλ1, φ0);
	          listener.point(λ1, φ0);
	          clean = 0;
	        } else if (sλ0 !== sλ1 && dλ >= π) {
	          if (abs(λ0 - sλ0) < ε) λ0 -= sλ0 * ε;
	          if (abs(λ1 - sλ1) < ε) λ1 -= sλ1 * ε;
	          φ0 = d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1);
	          listener.point(sλ0, φ0);
	          listener.lineEnd();
	          listener.lineStart();
	          listener.point(sλ1, φ0);
	          clean = 0;
	        }
	        listener.point(λ0 = λ1, φ0 = φ1);
	        sλ0 = sλ1;
	      },
	      lineEnd: function() {
	        listener.lineEnd();
	        λ0 = φ0 = NaN;
	      },
	      clean: function() {
	        return 2 - clean;
	      }
	    };
	  }
	  function d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1) {
	    var cosφ0, cosφ1, sinλ0_λ1 = Math.sin(λ0 - λ1);
	    return abs(sinλ0_λ1) > ε ? Math.atan((Math.sin(φ0) * (cosφ1 = Math.cos(φ1)) * Math.sin(λ1) - Math.sin(φ1) * (cosφ0 = Math.cos(φ0)) * Math.sin(λ0)) / (cosφ0 * cosφ1 * sinλ0_λ1)) : (φ0 + φ1) / 2;
	  }
	  function d3_geo_clipAntimeridianInterpolate(from, to, direction, listener) {
	    var φ;
	    if (from == null) {
	      φ = direction * halfπ;
	      listener.point(-π, φ);
	      listener.point(0, φ);
	      listener.point(π, φ);
	      listener.point(π, 0);
	      listener.point(π, -φ);
	      listener.point(0, -φ);
	      listener.point(-π, -φ);
	      listener.point(-π, 0);
	      listener.point(-π, φ);
	    } else if (abs(from[0] - to[0]) > ε) {
	      var s = from[0] < to[0] ? π : -π;
	      φ = direction * s / 2;
	      listener.point(-s, φ);
	      listener.point(0, φ);
	      listener.point(s, φ);
	    } else {
	      listener.point(to[0], to[1]);
	    }
	  }
	  function d3_geo_pointInPolygon(point, polygon) {
	    var meridian = point[0], parallel = point[1], meridianNormal = [ Math.sin(meridian), -Math.cos(meridian), 0 ], polarAngle = 0, winding = 0;
	    d3_geo_areaRingSum.reset();
	    for (var i = 0, n = polygon.length; i < n; ++i) {
	      var ring = polygon[i], m = ring.length;
	      if (!m) continue;
	      var point0 = ring[0], λ0 = point0[0], φ0 = point0[1] / 2 + π / 4, sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), j = 1;
	      while (true) {
	        if (j === m) j = 0;
	        point = ring[j];
	        var λ = point[0], φ = point[1] / 2 + π / 4, sinφ = Math.sin(φ), cosφ = Math.cos(φ), dλ = λ - λ0, sdλ = dλ >= 0 ? 1 : -1, adλ = sdλ * dλ, antimeridian = adλ > π, k = sinφ0 * sinφ;
	        d3_geo_areaRingSum.add(Math.atan2(k * sdλ * Math.sin(adλ), cosφ0 * cosφ + k * Math.cos(adλ)));
	        polarAngle += antimeridian ? dλ + sdλ * τ : dλ;
	        if (antimeridian ^ λ0 >= meridian ^ λ >= meridian) {
	          var arc = d3_geo_cartesianCross(d3_geo_cartesian(point0), d3_geo_cartesian(point));
	          d3_geo_cartesianNormalize(arc);
	          var intersection = d3_geo_cartesianCross(meridianNormal, arc);
	          d3_geo_cartesianNormalize(intersection);
	          var φarc = (antimeridian ^ dλ >= 0 ? -1 : 1) * d3_asin(intersection[2]);
	          if (parallel > φarc || parallel === φarc && (arc[0] || arc[1])) {
	            winding += antimeridian ^ dλ >= 0 ? 1 : -1;
	          }
	        }
	        if (!j++) break;
	        λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ, point0 = point;
	      }
	    }
	    return (polarAngle < -ε || polarAngle < ε && d3_geo_areaRingSum < -ε) ^ winding & 1;
	  }
	  function d3_geo_clipCircle(radius) {
	    var cr = Math.cos(radius), smallRadius = cr > 0, notHemisphere = abs(cr) > ε, interpolate = d3_geo_circleInterpolate(radius, 6 * d3_radians);
	    return d3_geo_clip(visible, clipLine, interpolate, smallRadius ? [ 0, -radius ] : [ -π, radius - π ]);
	    function visible(λ, φ) {
	      return Math.cos(λ) * Math.cos(φ) > cr;
	    }
	    function clipLine(listener) {
	      var point0, c0, v0, v00, clean;
	      return {
	        lineStart: function() {
	          v00 = v0 = false;
	          clean = 1;
	        },
	        point: function(λ, φ) {
	          var point1 = [ λ, φ ], point2, v = visible(λ, φ), c = smallRadius ? v ? 0 : code(λ, φ) : v ? code(λ + (λ < 0 ? π : -π), φ) : 0;
	          if (!point0 && (v00 = v0 = v)) listener.lineStart();
	          if (v !== v0) {
	            point2 = intersect(point0, point1);
	            if (d3_geo_sphericalEqual(point0, point2) || d3_geo_sphericalEqual(point1, point2)) {
	              point1[0] += ε;
	              point1[1] += ε;
	              v = visible(point1[0], point1[1]);
	            }
	          }
	          if (v !== v0) {
	            clean = 0;
	            if (v) {
	              listener.lineStart();
	              point2 = intersect(point1, point0);
	              listener.point(point2[0], point2[1]);
	            } else {
	              point2 = intersect(point0, point1);
	              listener.point(point2[0], point2[1]);
	              listener.lineEnd();
	            }
	            point0 = point2;
	          } else if (notHemisphere && point0 && smallRadius ^ v) {
	            var t;
	            if (!(c & c0) && (t = intersect(point1, point0, true))) {
	              clean = 0;
	              if (smallRadius) {
	                listener.lineStart();
	                listener.point(t[0][0], t[0][1]);
	                listener.point(t[1][0], t[1][1]);
	                listener.lineEnd();
	              } else {
	                listener.point(t[1][0], t[1][1]);
	                listener.lineEnd();
	                listener.lineStart();
	                listener.point(t[0][0], t[0][1]);
	              }
	            }
	          }
	          if (v && (!point0 || !d3_geo_sphericalEqual(point0, point1))) {
	            listener.point(point1[0], point1[1]);
	          }
	          point0 = point1, v0 = v, c0 = c;
	        },
	        lineEnd: function() {
	          if (v0) listener.lineEnd();
	          point0 = null;
	        },
	        clean: function() {
	          return clean | (v00 && v0) << 1;
	        }
	      };
	    }
	    function intersect(a, b, two) {
	      var pa = d3_geo_cartesian(a), pb = d3_geo_cartesian(b);
	      var n1 = [ 1, 0, 0 ], n2 = d3_geo_cartesianCross(pa, pb), n2n2 = d3_geo_cartesianDot(n2, n2), n1n2 = n2[0], determinant = n2n2 - n1n2 * n1n2;
	      if (!determinant) return !two && a;
	      var c1 = cr * n2n2 / determinant, c2 = -cr * n1n2 / determinant, n1xn2 = d3_geo_cartesianCross(n1, n2), A = d3_geo_cartesianScale(n1, c1), B = d3_geo_cartesianScale(n2, c2);
	      d3_geo_cartesianAdd(A, B);
	      var u = n1xn2, w = d3_geo_cartesianDot(A, u), uu = d3_geo_cartesianDot(u, u), t2 = w * w - uu * (d3_geo_cartesianDot(A, A) - 1);
	      if (t2 < 0) return;
	      var t = Math.sqrt(t2), q = d3_geo_cartesianScale(u, (-w - t) / uu);
	      d3_geo_cartesianAdd(q, A);
	      q = d3_geo_spherical(q);
	      if (!two) return q;
	      var λ0 = a[0], λ1 = b[0], φ0 = a[1], φ1 = b[1], z;
	      if (λ1 < λ0) z = λ0, λ0 = λ1, λ1 = z;
	      var δλ = λ1 - λ0, polar = abs(δλ - π) < ε, meridian = polar || δλ < ε;
	      if (!polar && φ1 < φ0) z = φ0, φ0 = φ1, φ1 = z;
	      if (meridian ? polar ? φ0 + φ1 > 0 ^ q[1] < (abs(q[0] - λ0) < ε ? φ0 : φ1) : φ0 <= q[1] && q[1] <= φ1 : δλ > π ^ (λ0 <= q[0] && q[0] <= λ1)) {
	        var q1 = d3_geo_cartesianScale(u, (-w + t) / uu);
	        d3_geo_cartesianAdd(q1, A);
	        return [ q, d3_geo_spherical(q1) ];
	      }
	    }
	    function code(λ, φ) {
	      var r = smallRadius ? radius : π - radius, code = 0;
	      if (λ < -r) code |= 1; else if (λ > r) code |= 2;
	      if (φ < -r) code |= 4; else if (φ > r) code |= 8;
	      return code;
	    }
	  }
	  function d3_geom_clipLine(x0, y0, x1, y1) {
	    return function(line) {
	      var a = line.a, b = line.b, ax = a.x, ay = a.y, bx = b.x, by = b.y, t0 = 0, t1 = 1, dx = bx - ax, dy = by - ay, r;
	      r = x0 - ax;
	      if (!dx && r > 0) return;
	      r /= dx;
	      if (dx < 0) {
	        if (r < t0) return;
	        if (r < t1) t1 = r;
	      } else if (dx > 0) {
	        if (r > t1) return;
	        if (r > t0) t0 = r;
	      }
	      r = x1 - ax;
	      if (!dx && r < 0) return;
	      r /= dx;
	      if (dx < 0) {
	        if (r > t1) return;
	        if (r > t0) t0 = r;
	      } else if (dx > 0) {
	        if (r < t0) return;
	        if (r < t1) t1 = r;
	      }
	      r = y0 - ay;
	      if (!dy && r > 0) return;
	      r /= dy;
	      if (dy < 0) {
	        if (r < t0) return;
	        if (r < t1) t1 = r;
	      } else if (dy > 0) {
	        if (r > t1) return;
	        if (r > t0) t0 = r;
	      }
	      r = y1 - ay;
	      if (!dy && r < 0) return;
	      r /= dy;
	      if (dy < 0) {
	        if (r > t1) return;
	        if (r > t0) t0 = r;
	      } else if (dy > 0) {
	        if (r < t0) return;
	        if (r < t1) t1 = r;
	      }
	      if (t0 > 0) line.a = {
	        x: ax + t0 * dx,
	        y: ay + t0 * dy
	      };
	      if (t1 < 1) line.b = {
	        x: ax + t1 * dx,
	        y: ay + t1 * dy
	      };
	      return line;
	    };
	  }
	  var d3_geo_clipExtentMAX = 1e9;
	  d3.geo.clipExtent = function() {
	    var x0, y0, x1, y1, stream, clip, clipExtent = {
	      stream: function(output) {
	        if (stream) stream.valid = false;
	        stream = clip(output);
	        stream.valid = true;
	        return stream;
	      },
	      extent: function(_) {
	        if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ];
	        clip = d3_geo_clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]);
	        if (stream) stream.valid = false, stream = null;
	        return clipExtent;
	      }
	    };
	    return clipExtent.extent([ [ 0, 0 ], [ 960, 500 ] ]);
	  };
	  function d3_geo_clipExtent(x0, y0, x1, y1) {
	    return function(listener) {
	      var listener_ = listener, bufferListener = d3_geo_clipBufferListener(), clipLine = d3_geom_clipLine(x0, y0, x1, y1), segments, polygon, ring;
	      var clip = {
	        point: point,
	        lineStart: lineStart,
	        lineEnd: lineEnd,
	        polygonStart: function() {
	          listener = bufferListener;
	          segments = [];
	          polygon = [];
	          clean = true;
	        },
	        polygonEnd: function() {
	          listener = listener_;
	          segments = d3.merge(segments);
	          var clipStartInside = insidePolygon([ x0, y1 ]), inside = clean && clipStartInside, visible = segments.length;
	          if (inside || visible) {
	            listener.polygonStart();
	            if (inside) {
	              listener.lineStart();
	              interpolate(null, null, 1, listener);
	              listener.lineEnd();
	            }
	            if (visible) {
	              d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener);
	            }
	            listener.polygonEnd();
	          }
	          segments = polygon = ring = null;
	        }
	      };
	      function insidePolygon(p) {
	        var wn = 0, n = polygon.length, y = p[1];
	        for (var i = 0; i < n; ++i) {
	          for (var j = 1, v = polygon[i], m = v.length, a = v[0], b; j < m; ++j) {
	            b = v[j];
	            if (a[1] <= y) {
	              if (b[1] > y && d3_cross2d(a, b, p) > 0) ++wn;
	            } else {
	              if (b[1] <= y && d3_cross2d(a, b, p) < 0) --wn;
	            }
	            a = b;
	          }
	        }
	        return wn !== 0;
	      }
	      function interpolate(from, to, direction, listener) {
	        var a = 0, a1 = 0;
	        if (from == null || (a = corner(from, direction)) !== (a1 = corner(to, direction)) || comparePoints(from, to) < 0 ^ direction > 0) {
	          do {
	            listener.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0);
	          } while ((a = (a + direction + 4) % 4) !== a1);
	        } else {
	          listener.point(to[0], to[1]);
	        }
	      }
	      function pointVisible(x, y) {
	        return x0 <= x && x <= x1 && y0 <= y && y <= y1;
	      }
	      function point(x, y) {
	        if (pointVisible(x, y)) listener.point(x, y);
	      }
	      var x__, y__, v__, x_, y_, v_, first, clean;
	      function lineStart() {
	        clip.point = linePoint;
	        if (polygon) polygon.push(ring = []);
	        first = true;
	        v_ = false;
	        x_ = y_ = NaN;
	      }
	      function lineEnd() {
	        if (segments) {
	          linePoint(x__, y__);
	          if (v__ && v_) bufferListener.rejoin();
	          segments.push(bufferListener.buffer());
	        }
	        clip.point = point;
	        if (v_) listener.lineEnd();
	      }
	      function linePoint(x, y) {
	        x = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, x));
	        y = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, y));
	        var v = pointVisible(x, y);
	        if (polygon) ring.push([ x, y ]);
	        if (first) {
	          x__ = x, y__ = y, v__ = v;
	          first = false;
	          if (v) {
	            listener.lineStart();
	            listener.point(x, y);
	          }
	        } else {
	          if (v && v_) listener.point(x, y); else {
	            var l = {
	              a: {
	                x: x_,
	                y: y_
	              },
	              b: {
	                x: x,
	                y: y
	              }
	            };
	            if (clipLine(l)) {
	              if (!v_) {
	                listener.lineStart();
	                listener.point(l.a.x, l.a.y);
	              }
	              listener.point(l.b.x, l.b.y);
	              if (!v) listener.lineEnd();
	              clean = false;
	            } else if (v) {
	              listener.lineStart();
	              listener.point(x, y);
	              clean = false;
	            }
	          }
	        }
	        x_ = x, y_ = y, v_ = v;
	      }
	      return clip;
	    };
	    function corner(p, direction) {
	      return abs(p[0] - x0) < ε ? direction > 0 ? 0 : 3 : abs(p[0] - x1) < ε ? direction > 0 ? 2 : 1 : abs(p[1] - y0) < ε ? direction > 0 ? 1 : 0 : direction > 0 ? 3 : 2;
	    }
	    function compare(a, b) {
	      return comparePoints(a.x, b.x);
	    }
	    function comparePoints(a, b) {
	      var ca = corner(a, 1), cb = corner(b, 1);
	      return ca !== cb ? ca - cb : ca === 0 ? b[1] - a[1] : ca === 1 ? a[0] - b[0] : ca === 2 ? a[1] - b[1] : b[0] - a[0];
	    }
	  }
	  function d3_geo_conic(projectAt) {
	    var φ0 = 0, φ1 = π / 3, m = d3_geo_projectionMutator(projectAt), p = m(φ0, φ1);
	    p.parallels = function(_) {
	      if (!arguments.length) return [ φ0 / π * 180, φ1 / π * 180 ];
	      return m(φ0 = _[0] * π / 180, φ1 = _[1] * π / 180);
	    };
	    return p;
	  }
	  function d3_geo_conicEqualArea(φ0, φ1) {
	    var sinφ0 = Math.sin(φ0), n = (sinφ0 + Math.sin(φ1)) / 2, C = 1 + sinφ0 * (2 * n - sinφ0), ρ0 = Math.sqrt(C) / n;
	    function forward(λ, φ) {
	      var ρ = Math.sqrt(C - 2 * n * Math.sin(φ)) / n;
	      return [ ρ * Math.sin(λ *= n), ρ0 - ρ * Math.cos(λ) ];
	    }
	    forward.invert = function(x, y) {
	      var ρ0_y = ρ0 - y;
	      return [ Math.atan2(x, ρ0_y) / n, d3_asin((C - (x * x + ρ0_y * ρ0_y) * n * n) / (2 * n)) ];
	    };
	    return forward;
	  }
	  (d3.geo.conicEqualArea = function() {
	    return d3_geo_conic(d3_geo_conicEqualArea);
	  }).raw = d3_geo_conicEqualArea;
	  d3.geo.albers = function() {
	    return d3.geo.conicEqualArea().rotate([ 96, 0 ]).center([ -.6, 38.7 ]).parallels([ 29.5, 45.5 ]).scale(1070);
	  };
	  d3.geo.albersUsa = function() {
	    var lower48 = d3.geo.albers();
	    var alaska = d3.geo.conicEqualArea().rotate([ 154, 0 ]).center([ -2, 58.5 ]).parallels([ 55, 65 ]);
	    var hawaii = d3.geo.conicEqualArea().rotate([ 157, 0 ]).center([ -3, 19.9 ]).parallels([ 8, 18 ]);
	    var point, pointStream = {
	      point: function(x, y) {
	        point = [ x, y ];
	      }
	    }, lower48Point, alaskaPoint, hawaiiPoint;
	    function albersUsa(coordinates) {
	      var x = coordinates[0], y = coordinates[1];
	      point = null;
	      (lower48Point(x, y), point) || (alaskaPoint(x, y), point) || hawaiiPoint(x, y);
	      return point;
	    }
	    albersUsa.invert = function(coordinates) {
	      var k = lower48.scale(), t = lower48.translate(), x = (coordinates[0] - t[0]) / k, y = (coordinates[1] - t[1]) / k;
	      return (y >= .12 && y < .234 && x >= -.425 && x < -.214 ? alaska : y >= .166 && y < .234 && x >= -.214 && x < -.115 ? hawaii : lower48).invert(coordinates);
	    };
	    albersUsa.stream = function(stream) {
	      var lower48Stream = lower48.stream(stream), alaskaStream = alaska.stream(stream), hawaiiStream = hawaii.stream(stream);
	      return {
	        point: function(x, y) {
	          lower48Stream.point(x, y);
	          alaskaStream.point(x, y);
	          hawaiiStream.point(x, y);
	        },
	        sphere: function() {
	          lower48Stream.sphere();
	          alaskaStream.sphere();
	          hawaiiStream.sphere();
	        },
	        lineStart: function() {
	          lower48Stream.lineStart();
	          alaskaStream.lineStart();
	          hawaiiStream.lineStart();
	        },
	        lineEnd: function() {
	          lower48Stream.lineEnd();
	          alaskaStream.lineEnd();
	          hawaiiStream.lineEnd();
	        },
	        polygonStart: function() {
	          lower48Stream.polygonStart();
	          alaskaStream.polygonStart();
	          hawaiiStream.polygonStart();
	        },
	        polygonEnd: function() {
	          lower48Stream.polygonEnd();
	          alaskaStream.polygonEnd();
	          hawaiiStream.polygonEnd();
	        }
	      };
	    };
	    albersUsa.precision = function(_) {
	      if (!arguments.length) return lower48.precision();
	      lower48.precision(_);
	      alaska.precision(_);
	      hawaii.precision(_);
	      return albersUsa;
	    };
	    albersUsa.scale = function(_) {
	      if (!arguments.length) return lower48.scale();
	      lower48.scale(_);
	      alaska.scale(_ * .35);
	      hawaii.scale(_);
	      return albersUsa.translate(lower48.translate());
	    };
	    albersUsa.translate = function(_) {
	      if (!arguments.length) return lower48.translate();
	      var k = lower48.scale(), x = +_[0], y = +_[1];
	      lower48Point = lower48.translate(_).clipExtent([ [ x - .455 * k, y - .238 * k ], [ x + .455 * k, y + .238 * k ] ]).stream(pointStream).point;
	      alaskaPoint = alaska.translate([ x - .307 * k, y + .201 * k ]).clipExtent([ [ x - .425 * k + ε, y + .12 * k + ε ], [ x - .214 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point;
	      hawaiiPoint = hawaii.translate([ x - .205 * k, y + .212 * k ]).clipExtent([ [ x - .214 * k + ε, y + .166 * k + ε ], [ x - .115 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point;
	      return albersUsa;
	    };
	    return albersUsa.scale(1070);
	  };
	  var d3_geo_pathAreaSum, d3_geo_pathAreaPolygon, d3_geo_pathArea = {
	    point: d3_noop,
	    lineStart: d3_noop,
	    lineEnd: d3_noop,
	    polygonStart: function() {
	      d3_geo_pathAreaPolygon = 0;
	      d3_geo_pathArea.lineStart = d3_geo_pathAreaRingStart;
	    },
	    polygonEnd: function() {
	      d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop;
	      d3_geo_pathAreaSum += abs(d3_geo_pathAreaPolygon / 2);
	    }
	  };
	  function d3_geo_pathAreaRingStart() {
	    var x00, y00, x0, y0;
	    d3_geo_pathArea.point = function(x, y) {
	      d3_geo_pathArea.point = nextPoint;
	      x00 = x0 = x, y00 = y0 = y;
	    };
	    function nextPoint(x, y) {
	      d3_geo_pathAreaPolygon += y0 * x - x0 * y;
	      x0 = x, y0 = y;
	    }
	    d3_geo_pathArea.lineEnd = function() {
	      nextPoint(x00, y00);
	    };
	  }
	  var d3_geo_pathBoundsX0, d3_geo_pathBoundsY0, d3_geo_pathBoundsX1, d3_geo_pathBoundsY1;
	  var d3_geo_pathBounds = {
	    point: d3_geo_pathBoundsPoint,
	    lineStart: d3_noop,
	    lineEnd: d3_noop,
	    polygonStart: d3_noop,
	    polygonEnd: d3_noop
	  };
	  function d3_geo_pathBoundsPoint(x, y) {
	    if (x < d3_geo_pathBoundsX0) d3_geo_pathBoundsX0 = x;
	    if (x > d3_geo_pathBoundsX1) d3_geo_pathBoundsX1 = x;
	    if (y < d3_geo_pathBoundsY0) d3_geo_pathBoundsY0 = y;
	    if (y > d3_geo_pathBoundsY1) d3_geo_pathBoundsY1 = y;
	  }
	  function d3_geo_pathBuffer() {
	    var pointCircle = d3_geo_pathBufferCircle(4.5), buffer = [];
	    var stream = {
	      point: point,
	      lineStart: function() {
	        stream.point = pointLineStart;
	      },
	      lineEnd: lineEnd,
	      polygonStart: function() {
	        stream.lineEnd = lineEndPolygon;
	      },
	      polygonEnd: function() {
	        stream.lineEnd = lineEnd;
	        stream.point = point;
	      },
	      pointRadius: function(_) {
	        pointCircle = d3_geo_pathBufferCircle(_);
	        return stream;
	      },
	      result: function() {
	        if (buffer.length) {
	          var result = buffer.join("");
	          buffer = [];
	          return result;
	        }
	      }
	    };
	    function point(x, y) {
	      buffer.push("M", x, ",", y, pointCircle);
	    }
	    function pointLineStart(x, y) {
	      buffer.push("M", x, ",", y);
	      stream.point = pointLine;
	    }
	    function pointLine(x, y) {
	      buffer.push("L", x, ",", y);
	    }
	    function lineEnd() {
	      stream.point = point;
	    }
	    function lineEndPolygon() {
	      buffer.push("Z");
	    }
	    return stream;
	  }
	  function d3_geo_pathBufferCircle(radius) {
	    return "m0," + radius + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius + "z";
	  }
	  var d3_geo_pathCentroid = {
	    point: d3_geo_pathCentroidPoint,
	    lineStart: d3_geo_pathCentroidLineStart,
	    lineEnd: d3_geo_pathCentroidLineEnd,
	    polygonStart: function() {
	      d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidRingStart;
	    },
	    polygonEnd: function() {
	      d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint;
	      d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidLineStart;
	      d3_geo_pathCentroid.lineEnd = d3_geo_pathCentroidLineEnd;
	    }
	  };
	  function d3_geo_pathCentroidPoint(x, y) {
	    d3_geo_centroidX0 += x;
	    d3_geo_centroidY0 += y;
	    ++d3_geo_centroidZ0;
	  }
	  function d3_geo_pathCentroidLineStart() {
	    var x0, y0;
	    d3_geo_pathCentroid.point = function(x, y) {
	      d3_geo_pathCentroid.point = nextPoint;
	      d3_geo_pathCentroidPoint(x0 = x, y0 = y);
	    };
	    function nextPoint(x, y) {
	      var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy);
	      d3_geo_centroidX1 += z * (x0 + x) / 2;
	      d3_geo_centroidY1 += z * (y0 + y) / 2;
	      d3_geo_centroidZ1 += z;
	      d3_geo_pathCentroidPoint(x0 = x, y0 = y);
	    }
	  }
	  function d3_geo_pathCentroidLineEnd() {
	    d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint;
	  }
	  function d3_geo_pathCentroidRingStart() {
	    var x00, y00, x0, y0;
	    d3_geo_pathCentroid.point = function(x, y) {
	      d3_geo_pathCentroid.point = nextPoint;
	      d3_geo_pathCentroidPoint(x00 = x0 = x, y00 = y0 = y);
	    };
	    function nextPoint(x, y) {
	      var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy);
	      d3_geo_centroidX1 += z * (x0 + x) / 2;
	      d3_geo_centroidY1 += z * (y0 + y) / 2;
	      d3_geo_centroidZ1 += z;
	      z = y0 * x - x0 * y;
	      d3_geo_centroidX2 += z * (x0 + x);
	      d3_geo_centroidY2 += z * (y0 + y);
	      d3_geo_centroidZ2 += z * 3;
	      d3_geo_pathCentroidPoint(x0 = x, y0 = y);
	    }
	    d3_geo_pathCentroid.lineEnd = function() {
	      nextPoint(x00, y00);
	    };
	  }
	  function d3_geo_pathContext(context) {
	    var pointRadius = 4.5;
	    var stream = {
	      point: point,
	      lineStart: function() {
	        stream.point = pointLineStart;
	      },
	      lineEnd: lineEnd,
	      polygonStart: function() {
	        stream.lineEnd = lineEndPolygon;
	      },
	      polygonEnd: function() {
	        stream.lineEnd = lineEnd;
	        stream.point = point;
	      },
	      pointRadius: function(_) {
	        pointRadius = _;
	        return stream;
	      },
	      result: d3_noop
	    };
	    function point(x, y) {
	      context.moveTo(x + pointRadius, y);
	      context.arc(x, y, pointRadius, 0, τ);
	    }
	    function pointLineStart(x, y) {
	      context.moveTo(x, y);
	      stream.point = pointLine;
	    }
	    function pointLine(x, y) {
	      context.lineTo(x, y);
	    }
	    function lineEnd() {
	      stream.point = point;
	    }
	    function lineEndPolygon() {
	      context.closePath();
	    }
	    return stream;
	  }
	  function d3_geo_resample(project) {
	    var δ2 = .5, cosMinDistance = Math.cos(30 * d3_radians), maxDepth = 16;
	    function resample(stream) {
	      return (maxDepth ? resampleRecursive : resampleNone)(stream);
	    }
	    function resampleNone(stream) {
	      return d3_geo_transformPoint(stream, function(x, y) {
	        x = project(x, y);
	        stream.point(x[0], x[1]);
	      });
	    }
	    function resampleRecursive(stream) {
	      var λ00, φ00, x00, y00, a00, b00, c00, λ0, x0, y0, a0, b0, c0;
	      var resample = {
	        point: point,
	        lineStart: lineStart,
	        lineEnd: lineEnd,
	        polygonStart: function() {
	          stream.polygonStart();
	          resample.lineStart = ringStart;
	        },
	        polygonEnd: function() {
	          stream.polygonEnd();
	          resample.lineStart = lineStart;
	        }
	      };
	      function point(x, y) {
	        x = project(x, y);
	        stream.point(x[0], x[1]);
	      }
	      function lineStart() {
	        x0 = NaN;
	        resample.point = linePoint;
	        stream.lineStart();
	      }
	      function linePoint(λ, φ) {
	        var c = d3_geo_cartesian([ λ, φ ]), p = project(λ, φ);
	        resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream);
	        stream.point(x0, y0);
	      }
	      function lineEnd() {
	        resample.point = point;
	        stream.lineEnd();
	      }
	      function ringStart() {
	        lineStart();
	        resample.point = ringPoint;
	        resample.lineEnd = ringEnd;
	      }
	      function ringPoint(λ, φ) {
	        linePoint(λ00 = λ, φ00 = φ), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0;
	        resample.point = linePoint;
	      }
	      function ringEnd() {
	        resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, stream);
	        resample.lineEnd = lineEnd;
	        lineEnd();
	      }
	      return resample;
	    }
	    function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, stream) {
	      var dx = x1 - x0, dy = y1 - y0, d2 = dx * dx + dy * dy;
	      if (d2 > 4 * δ2 && depth--) {
	        var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = Math.sqrt(a * a + b * b + c * c), φ2 = Math.asin(c /= m), λ2 = abs(abs(c) - 1) < ε || abs(λ0 - λ1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a), p = project(λ2, φ2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, dz = dy * dx2 - dx * dy2;
	        if (dz * dz / d2 > δ2 || abs((dx * dx2 + dy * dy2) / d2 - .5) > .3 || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) {
	          resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream);
	          stream.point(x2, y2);
	          resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, stream);
	        }
	      }
	    }
	    resample.precision = function(_) {
	      if (!arguments.length) return Math.sqrt(δ2);
	      maxDepth = (δ2 = _ * _) > 0 && 16;
	      return resample;
	    };
	    return resample;
	  }
	  d3.geo.path = function() {
	    var pointRadius = 4.5, projection, context, projectStream, contextStream, cacheStream;
	    function path(object) {
	      if (object) {
	        if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments));
	        if (!cacheStream || !cacheStream.valid) cacheStream = projectStream(contextStream);
	        d3.geo.stream(object, cacheStream);
	      }
	      return contextStream.result();
	    }
	    path.area = function(object) {
	      d3_geo_pathAreaSum = 0;
	      d3.geo.stream(object, projectStream(d3_geo_pathArea));
	      return d3_geo_pathAreaSum;
	    };
	    path.centroid = function(object) {
	      d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0;
	      d3.geo.stream(object, projectStream(d3_geo_pathCentroid));
	      return d3_geo_centroidZ2 ? [ d3_geo_centroidX2 / d3_geo_centroidZ2, d3_geo_centroidY2 / d3_geo_centroidZ2 ] : d3_geo_centroidZ1 ? [ d3_geo_centroidX1 / d3_geo_centroidZ1, d3_geo_centroidY1 / d3_geo_centroidZ1 ] : d3_geo_centroidZ0 ? [ d3_geo_centroidX0 / d3_geo_centroidZ0, d3_geo_centroidY0 / d3_geo_centroidZ0 ] : [ NaN, NaN ];
	    };
	    path.bounds = function(object) {
	      d3_geo_pathBoundsX1 = d3_geo_pathBoundsY1 = -(d3_geo_pathBoundsX0 = d3_geo_pathBoundsY0 = Infinity);
	      d3.geo.stream(object, projectStream(d3_geo_pathBounds));
	      return [ [ d3_geo_pathBoundsX0, d3_geo_pathBoundsY0 ], [ d3_geo_pathBoundsX1, d3_geo_pathBoundsY1 ] ];
	    };
	    path.projection = function(_) {
	      if (!arguments.length) return projection;
	      projectStream = (projection = _) ? _.stream || d3_geo_pathProjectStream(_) : d3_identity;
	      return reset();
	    };
	    path.context = function(_) {
	      if (!arguments.length) return context;
	      contextStream = (context = _) == null ? new d3_geo_pathBuffer() : new d3_geo_pathContext(_);
	      if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius);
	      return reset();
	    };
	    path.pointRadius = function(_) {
	      if (!arguments.length) return pointRadius;
	      pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_);
	      return path;
	    };
	    function reset() {
	      cacheStream = null;
	      return path;
	    }
	    return path.projection(d3.geo.albersUsa()).context(null);
	  };
	  function d3_geo_pathProjectStream(project) {
	    var resample = d3_geo_resample(function(x, y) {
	      return project([ x * d3_degrees, y * d3_degrees ]);
	    });
	    return function(stream) {
	      return d3_geo_projectionRadians(resample(stream));
	    };
	  }
	  d3.geo.transform = function(methods) {
	    return {
	      stream: function(stream) {
	        var transform = new d3_geo_transform(stream);
	        for (var k in methods) transform[k] = methods[k];
	        return transform;
	      }
	    };
	  };
	  function d3_geo_transform(stream) {
	    this.stream = stream;
	  }
	  d3_geo_transform.prototype = {
	    point: function(x, y) {
	      this.stream.point(x, y);
	    },
	    sphere: function() {
	      this.stream.sphere();
	    },
	    lineStart: function() {
	      this.stream.lineStart();
	    },
	    lineEnd: function() {
	      this.stream.lineEnd();
	    },
	    polygonStart: function() {
	      this.stream.polygonStart();
	    },
	    polygonEnd: function() {
	      this.stream.polygonEnd();
	    }
	  };
	  function d3_geo_transformPoint(stream, point) {
	    return {
	      point: point,
	      sphere: function() {
	        stream.sphere();
	      },
	      lineStart: function() {
	        stream.lineStart();
	      },
	      lineEnd: function() {
	        stream.lineEnd();
	      },
	      polygonStart: function() {
	        stream.polygonStart();
	      },
	      polygonEnd: function() {
	        stream.polygonEnd();
	      }
	    };
	  }
	  d3.geo.projection = d3_geo_projection;
	  d3.geo.projectionMutator = d3_geo_projectionMutator;
	  function d3_geo_projection(project) {
	    return d3_geo_projectionMutator(function() {
	      return project;
	    })();
	  }
	  function d3_geo_projectionMutator(projectAt) {
	    var project, rotate, projectRotate, projectResample = d3_geo_resample(function(x, y) {
	      x = project(x, y);
	      return [ x[0] * k + δx, δy - x[1] * k ];
	    }), k = 150, x = 480, y = 250, λ = 0, φ = 0, δλ = 0, δφ = 0, δγ = 0, δx, δy, preclip = d3_geo_clipAntimeridian, postclip = d3_identity, clipAngle = null, clipExtent = null, stream;
	    function projection(point) {
	      point = projectRotate(point[0] * d3_radians, point[1] * d3_radians);
	      return [ point[0] * k + δx, δy - point[1] * k ];
	    }
	    function invert(point) {
	      point = projectRotate.invert((point[0] - δx) / k, (δy - point[1]) / k);
	      return point && [ point[0] * d3_degrees, point[1] * d3_degrees ];
	    }
	    projection.stream = function(output) {
	      if (stream) stream.valid = false;
	      stream = d3_geo_projectionRadians(preclip(rotate, projectResample(postclip(output))));
	      stream.valid = true;
	      return stream;
	    };
	    projection.clipAngle = function(_) {
	      if (!arguments.length) return clipAngle;
	      preclip = _ == null ? (clipAngle = _, d3_geo_clipAntimeridian) : d3_geo_clipCircle((clipAngle = +_) * d3_radians);
	      return invalidate();
	    };
	    projection.clipExtent = function(_) {
	      if (!arguments.length) return clipExtent;
	      clipExtent = _;
	      postclip = _ ? d3_geo_clipExtent(_[0][0], _[0][1], _[1][0], _[1][1]) : d3_identity;
	      return invalidate();
	    };
	    projection.scale = function(_) {
	      if (!arguments.length) return k;
	      k = +_;
	      return reset();
	    };
	    projection.translate = function(_) {
	      if (!arguments.length) return [ x, y ];
	      x = +_[0];
	      y = +_[1];
	      return reset();
	    };
	    projection.center = function(_) {
	      if (!arguments.length) return [ λ * d3_degrees, φ * d3_degrees ];
	      λ = _[0] % 360 * d3_radians;
	      φ = _[1] % 360 * d3_radians;
	      return reset();
	    };
	    projection.rotate = function(_) {
	      if (!arguments.length) return [ δλ * d3_degrees, δφ * d3_degrees, δγ * d3_degrees ];
	      δλ = _[0] % 360 * d3_radians;
	      δφ = _[1] % 360 * d3_radians;
	      δγ = _.length > 2 ? _[2] % 360 * d3_radians : 0;
	      return reset();
	    };
	    d3.rebind(projection, projectResample, "precision");
	    function reset() {
	      projectRotate = d3_geo_compose(rotate = d3_geo_rotation(δλ, δφ, δγ), project);
	      var center = project(λ, φ);
	      δx = x - center[0] * k;
	      δy = y + center[1] * k;
	      return invalidate();
	    }
	    function invalidate() {
	      if (stream) stream.valid = false, stream = null;
	      return projection;
	    }
	    return function() {
	      project = projectAt.apply(this, arguments);
	      projection.invert = project.invert && invert;
	      return reset();
	    };
	  }
	  function d3_geo_projectionRadians(stream) {
	    return d3_geo_transformPoint(stream, function(x, y) {
	      stream.point(x * d3_radians, y * d3_radians);
	    });
	  }
	  function d3_geo_equirectangular(λ, φ) {
	    return [ λ, φ ];
	  }
	  (d3.geo.equirectangular = function() {
	    return d3_geo_projection(d3_geo_equirectangular);
	  }).raw = d3_geo_equirectangular.invert = d3_geo_equirectangular;
	  d3.geo.rotation = function(rotate) {
	    rotate = d3_geo_rotation(rotate[0] % 360 * d3_radians, rotate[1] * d3_radians, rotate.length > 2 ? rotate[2] * d3_radians : 0);
	    function forward(coordinates) {
	      coordinates = rotate(coordinates[0] * d3_radians, coordinates[1] * d3_radians);
	      return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates;
	    }
	    forward.invert = function(coordinates) {
	      coordinates = rotate.invert(coordinates[0] * d3_radians, coordinates[1] * d3_radians);
	      return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates;
	    };
	    return forward;
	  };
	  function d3_geo_identityRotation(λ, φ) {
	    return [ λ > π ? λ - τ : λ < -π ? λ + τ : λ, φ ];
	  }
	  d3_geo_identityRotation.invert = d3_geo_equirectangular;
	  function d3_geo_rotation(δλ, δφ, δγ) {
	    return δλ ? δφ || δγ ? d3_geo_compose(d3_geo_rotationλ(δλ), d3_geo_rotationφγ(δφ, δγ)) : d3_geo_rotationλ(δλ) : δφ || δγ ? d3_geo_rotationφγ(δφ, δγ) : d3_geo_identityRotation;
	  }
	  function d3_geo_forwardRotationλ(δλ) {
	    return function(λ, φ) {
	      return λ += δλ, [ λ > π ? λ - τ : λ < -π ? λ + τ : λ, φ ];
	    };
	  }
	  function d3_geo_rotationλ(δλ) {
	    var rotation = d3_geo_forwardRotationλ(δλ);
	    rotation.invert = d3_geo_forwardRotationλ(-δλ);
	    return rotation;
	  }
	  function d3_geo_rotationφγ(δφ, δγ) {
	    var cosδφ = Math.cos(δφ), sinδφ = Math.sin(δφ), cosδγ = Math.cos(δγ), sinδγ = Math.sin(δγ);
	    function rotation(λ, φ) {
	      var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδφ + x * sinδφ;
	      return [ Math.atan2(y * cosδγ - k * sinδγ, x * cosδφ - z * sinδφ), d3_asin(k * cosδγ + y * sinδγ) ];
	    }
	    rotation.invert = function(λ, φ) {
	      var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδγ - y * sinδγ;
	      return [ Math.atan2(y * cosδγ + z * sinδγ, x * cosδφ + k * sinδφ), d3_asin(k * cosδφ - x * sinδφ) ];
	    };
	    return rotation;
	  }
	  d3.geo.circle = function() {
	    var origin = [ 0, 0 ], angle, precision = 6, interpolate;
	    function circle() {
	      var center = typeof origin === "function" ? origin.apply(this, arguments) : origin, rotate = d3_geo_rotation(-center[0] * d3_radians, -center[1] * d3_radians, 0).invert, ring = [];
	      interpolate(null, null, 1, {
	        point: function(x, y) {
	          ring.push(x = rotate(x, y));
	          x[0] *= d3_degrees, x[1] *= d3_degrees;
	        }
	      });
	      return {
	        type: "Polygon",
	        coordinates: [ ring ]
	      };
	    }
	    circle.origin = function(x) {
	      if (!arguments.length) return origin;
	      origin = x;
	      return circle;
	    };
	    circle.angle = function(x) {
	      if (!arguments.length) return angle;
	      interpolate = d3_geo_circleInterpolate((angle = +x) * d3_radians, precision * d3_radians);
	      return circle;
	    };
	    circle.precision = function(_) {
	      if (!arguments.length) return precision;
	      interpolate = d3_geo_circleInterpolate(angle * d3_radians, (precision = +_) * d3_radians);
	      return circle;
	    };
	    return circle.angle(90);
	  };
	  function d3_geo_circleInterpolate(radius, precision) {
	    var cr = Math.cos(radius), sr = Math.sin(radius);
	    return function(from, to, direction, listener) {
	      var step = direction * precision;
	      if (from != null) {
	        from = d3_geo_circleAngle(cr, from);
	        to = d3_geo_circleAngle(cr, to);
	        if (direction > 0 ? from < to : from > to) from += direction * τ;
	      } else {
	        from = radius + direction * τ;
	        to = radius - .5 * step;
	      }
	      for (var point, t = from; direction > 0 ? t > to : t < to; t -= step) {
	        listener.point((point = d3_geo_spherical([ cr, -sr * Math.cos(t), -sr * Math.sin(t) ]))[0], point[1]);
	      }
	    };
	  }
	  function d3_geo_circleAngle(cr, point) {
	    var a = d3_geo_cartesian(point);
	    a[0] -= cr;
	    d3_geo_cartesianNormalize(a);
	    var angle = d3_acos(-a[1]);
	    return ((-a[2] < 0 ? -angle : angle) + 2 * Math.PI - ε) % (2 * Math.PI);
	  }
	  d3.geo.distance = function(a, b) {
	    var Δλ = (b[0] - a[0]) * d3_radians, φ0 = a[1] * d3_radians, φ1 = b[1] * d3_radians, sinΔλ = Math.sin(Δλ), cosΔλ = Math.cos(Δλ), sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), sinφ1 = Math.sin(φ1), cosφ1 = Math.cos(φ1), t;
	    return Math.atan2(Math.sqrt((t = cosφ1 * sinΔλ) * t + (t = cosφ0 * sinφ1 - sinφ0 * cosφ1 * cosΔλ) * t), sinφ0 * sinφ1 + cosφ0 * cosφ1 * cosΔλ);
	  };
	  d3.geo.graticule = function() {
	    var x1, x0, X1, X0, y1, y0, Y1, Y0, dx = 10, dy = dx, DX = 90, DY = 360, x, y, X, Y, precision = 2.5;
	    function graticule() {
	      return {
	        type: "MultiLineString",
	        coordinates: lines()
	      };
	    }
	    function lines() {
	      return d3.range(Math.ceil(X0 / DX) * DX, X1, DX).map(X).concat(d3.range(Math.ceil(Y0 / DY) * DY, Y1, DY).map(Y)).concat(d3.range(Math.ceil(x0 / dx) * dx, x1, dx).filter(function(x) {
	        return abs(x % DX) > ε;
	      }).map(x)).concat(d3.range(Math.ceil(y0 / dy) * dy, y1, dy).filter(function(y) {
	        return abs(y % DY) > ε;
	      }).map(y));
	    }
	    graticule.lines = function() {
	      return lines().map(function(coordinates) {
	        return {
	          type: "LineString",
	          coordinates: coordinates
	        };
	      });
	    };
	    graticule.outline = function() {
	      return {
	        type: "Polygon",
	        coordinates: [ X(X0).concat(Y(Y1).slice(1), X(X1).reverse().slice(1), Y(Y0).reverse().slice(1)) ]
	      };
	    };
	    graticule.extent = function(_) {
	      if (!arguments.length) return graticule.minorExtent();
	      return graticule.majorExtent(_).minorExtent(_);
	    };
	    graticule.majorExtent = function(_) {
	      if (!arguments.length) return [ [ X0, Y0 ], [ X1, Y1 ] ];
	      X0 = +_[0][0], X1 = +_[1][0];
	      Y0 = +_[0][1], Y1 = +_[1][1];
	      if (X0 > X1) _ = X0, X0 = X1, X1 = _;
	      if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _;
	      return graticule.precision(precision);
	    };
	    graticule.minorExtent = function(_) {
	      if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ];
	      x0 = +_[0][0], x1 = +_[1][0];
	      y0 = +_[0][1], y1 = +_[1][1];
	      if (x0 > x1) _ = x0, x0 = x1, x1 = _;
	      if (y0 > y1) _ = y0, y0 = y1, y1 = _;
	      return graticule.precision(precision);
	    };
	    graticule.step = function(_) {
	      if (!arguments.length) return graticule.minorStep();
	      return graticule.majorStep(_).minorStep(_);
	    };
	    graticule.majorStep = function(_) {
	      if (!arguments.length) return [ DX, DY ];
	      DX = +_[0], DY = +_[1];
	      return graticule;
	    };
	    graticule.minorStep = function(_) {
	      if (!arguments.length) return [ dx, dy ];
	      dx = +_[0], dy = +_[1];
	      return graticule;
	    };
	    graticule.precision = function(_) {
	      if (!arguments.length) return precision;
	      precision = +_;
	      x = d3_geo_graticuleX(y0, y1, 90);
	      y = d3_geo_graticuleY(x0, x1, precision);
	      X = d3_geo_graticuleX(Y0, Y1, 90);
	      Y = d3_geo_graticuleY(X0, X1, precision);
	      return graticule;
	    };
	    return graticule.majorExtent([ [ -180, -90 + ε ], [ 180, 90 - ε ] ]).minorExtent([ [ -180, -80 - ε ], [ 180, 80 + ε ] ]);
	  };
	  function d3_geo_graticuleX(y0, y1, dy) {
	    var y = d3.range(y0, y1 - ε, dy).concat(y1);
	    return function(x) {
	      return y.map(function(y) {
	        return [ x, y ];
	      });
	    };
	  }
	  function d3_geo_graticuleY(x0, x1, dx) {
	    var x = d3.range(x0, x1 - ε, dx).concat(x1);
	    return function(y) {
	      return x.map(function(x) {
	        return [ x, y ];
	      });
	    };
	  }
	  function d3_source(d) {
	    return d.source;
	  }
	  function d3_target(d) {
	    return d.target;
	  }
	  d3.geo.greatArc = function() {
	    var source = d3_source, source_, target = d3_target, target_;
	    function greatArc() {
	      return {
	        type: "LineString",
	        coordinates: [ source_ || source.apply(this, arguments), target_ || target.apply(this, arguments) ]
	      };
	    }
	    greatArc.distance = function() {
	      return d3.geo.distance(source_ || source.apply(this, arguments), target_ || target.apply(this, arguments));
	    };
	    greatArc.source = function(_) {
	      if (!arguments.length) return source;
	      source = _, source_ = typeof _ === "function" ? null : _;
	      return greatArc;
	    };
	    greatArc.target = function(_) {
	      if (!arguments.length) return target;
	      target = _, target_ = typeof _ === "function" ? null : _;
	      return greatArc;
	    };
	    greatArc.precision = function() {
	      return arguments.length ? greatArc : 0;
	    };
	    return greatArc;
	  };
	  d3.geo.interpolate = function(source, target) {
	    return d3_geo_interpolate(source[0] * d3_radians, source[1] * d3_radians, target[0] * d3_radians, target[1] * d3_radians);
	  };
	  function d3_geo_interpolate(x0, y0, x1, y1) {
	    var cy0 = Math.cos(y0), sy0 = Math.sin(y0), cy1 = Math.cos(y1), sy1 = Math.sin(y1), kx0 = cy0 * Math.cos(x0), ky0 = cy0 * Math.sin(x0), kx1 = cy1 * Math.cos(x1), ky1 = cy1 * Math.sin(x1), d = 2 * Math.asin(Math.sqrt(d3_haversin(y1 - y0) + cy0 * cy1 * d3_haversin(x1 - x0))), k = 1 / Math.sin(d);
	    var interpolate = d ? function(t) {
	      var B = Math.sin(t *= d) * k, A = Math.sin(d - t) * k, x = A * kx0 + B * kx1, y = A * ky0 + B * ky1, z = A * sy0 + B * sy1;
	      return [ Math.atan2(y, x) * d3_degrees, Math.atan2(z, Math.sqrt(x * x + y * y)) * d3_degrees ];
	    } : function() {
	      return [ x0 * d3_degrees, y0 * d3_degrees ];
	    };
	    interpolate.distance = d;
	    return interpolate;
	  }
	  d3.geo.length = function(object) {
	    d3_geo_lengthSum = 0;
	    d3.geo.stream(object, d3_geo_length);
	    return d3_geo_lengthSum;
	  };
	  var d3_geo_lengthSum;
	  var d3_geo_length = {
	    sphere: d3_noop,
	    point: d3_noop,
	    lineStart: d3_geo_lengthLineStart,
	    lineEnd: d3_noop,
	    polygonStart: d3_noop,
	    polygonEnd: d3_noop
	  };
	  function d3_geo_lengthLineStart() {
	    var λ0, sinφ0, cosφ0;
	    d3_geo_length.point = function(λ, φ) {
	      λ0 = λ * d3_radians, sinφ0 = Math.sin(φ *= d3_radians), cosφ0 = Math.cos(φ);
	      d3_geo_length.point = nextPoint;
	    };
	    d3_geo_length.lineEnd = function() {
	      d3_geo_length.point = d3_geo_length.lineEnd = d3_noop;
	    };
	    function nextPoint(λ, φ) {
	      var sinφ = Math.sin(φ *= d3_radians), cosφ = Math.cos(φ), t = abs((λ *= d3_radians) - λ0), cosΔλ = Math.cos(t);
	      d3_geo_lengthSum += Math.atan2(Math.sqrt((t = cosφ * Math.sin(t)) * t + (t = cosφ0 * sinφ - sinφ0 * cosφ * cosΔλ) * t), sinφ0 * sinφ + cosφ0 * cosφ * cosΔλ);
	      λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ;
	    }
	  }
	  function d3_geo_azimuthal(scale, angle) {
	    function azimuthal(λ, φ) {
	      var cosλ = Math.cos(λ), cosφ = Math.cos(φ), k = scale(cosλ * cosφ);
	      return [ k * cosφ * Math.sin(λ), k * Math.sin(φ) ];
	    }
	    azimuthal.invert = function(x, y) {
	      var ρ = Math.sqrt(x * x + y * y), c = angle(ρ), sinc = Math.sin(c), cosc = Math.cos(c);
	      return [ Math.atan2(x * sinc, ρ * cosc), Math.asin(ρ && y * sinc / ρ) ];
	    };
	    return azimuthal;
	  }
	  var d3_geo_azimuthalEqualArea = d3_geo_azimuthal(function(cosλcosφ) {
	    return Math.sqrt(2 / (1 + cosλcosφ));
	  }, function(ρ) {
	    return 2 * Math.asin(ρ / 2);
	  });
	  (d3.geo.azimuthalEqualArea = function() {
	    return d3_geo_projection(d3_geo_azimuthalEqualArea);
	  }).raw = d3_geo_azimuthalEqualArea;
	  var d3_geo_azimuthalEquidistant = d3_geo_azimuthal(function(cosλcosφ) {
	    var c = Math.acos(cosλcosφ);
	    return c && c / Math.sin(c);
	  }, d3_identity);
	  (d3.geo.azimuthalEquidistant = function() {
	    return d3_geo_projection(d3_geo_azimuthalEquidistant);
	  }).raw = d3_geo_azimuthalEquidistant;
	  function d3_geo_conicConformal(φ0, φ1) {
	    var cosφ0 = Math.cos(φ0), t = function(φ) {
	      return Math.tan(π / 4 + φ / 2);
	    }, n = φ0 === φ1 ? Math.sin(φ0) : Math.log(cosφ0 / Math.cos(φ1)) / Math.log(t(φ1) / t(φ0)), F = cosφ0 * Math.pow(t(φ0), n) / n;
	    if (!n) return d3_geo_mercator;
	    function forward(λ, φ) {
	      if (F > 0) {
	        if (φ < -halfπ + ε) φ = -halfπ + ε;
	      } else {
	        if (φ > halfπ - ε) φ = halfπ - ε;
	      }
	      var ρ = F / Math.pow(t(φ), n);
	      return [ ρ * Math.sin(n * λ), F - ρ * Math.cos(n * λ) ];
	    }
	    forward.invert = function(x, y) {
	      var ρ0_y = F - y, ρ = d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y);
	      return [ Math.atan2(x, ρ0_y) / n, 2 * Math.atan(Math.pow(F / ρ, 1 / n)) - halfπ ];
	    };
	    return forward;
	  }
	  (d3.geo.conicConformal = function() {
	    return d3_geo_conic(d3_geo_conicConformal);
	  }).raw = d3_geo_conicConformal;
	  function d3_geo_conicEquidistant(φ0, φ1) {
	    var cosφ0 = Math.cos(φ0), n = φ0 === φ1 ? Math.sin(φ0) : (cosφ0 - Math.cos(φ1)) / (φ1 - φ0), G = cosφ0 / n + φ0;
	    if (abs(n) < ε) return d3_geo_equirectangular;
	    function forward(λ, φ) {
	      var ρ = G - φ;
	      return [ ρ * Math.sin(n * λ), G - ρ * Math.cos(n * λ) ];
	    }
	    forward.invert = function(x, y) {
	      var ρ0_y = G - y;
	      return [ Math.atan2(x, ρ0_y) / n, G - d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y) ];
	    };
	    return forward;
	  }
	  (d3.geo.conicEquidistant = function() {
	    return d3_geo_conic(d3_geo_conicEquidistant);
	  }).raw = d3_geo_conicEquidistant;
	  var d3_geo_gnomonic = d3_geo_azimuthal(function(cosλcosφ) {
	    return 1 / cosλcosφ;
	  }, Math.atan);
	  (d3.geo.gnomonic = function() {
	    return d3_geo_projection(d3_geo_gnomonic);
	  }).raw = d3_geo_gnomonic;
	  function d3_geo_mercator(λ, φ) {
	    return [ λ, Math.log(Math.tan(π / 4 + φ / 2)) ];
	  }
	  d3_geo_mercator.invert = function(x, y) {
	    return [ x, 2 * Math.atan(Math.exp(y)) - halfπ ];
	  };
	  function d3_geo_mercatorProjection(project) {
	    var m = d3_geo_projection(project), scale = m.scale, translate = m.translate, clipExtent = m.clipExtent, clipAuto;
	    m.scale = function() {
	      var v = scale.apply(m, arguments);
	      return v === m ? clipAuto ? m.clipExtent(null) : m : v;
	    };
	    m.translate = function() {
	      var v = translate.apply(m, arguments);
	      return v === m ? clipAuto ? m.clipExtent(null) : m : v;
	    };
	    m.clipExtent = function(_) {
	      var v = clipExtent.apply(m, arguments);
	      if (v === m) {
	        if (clipAuto = _ == null) {
	          var k = π * scale(), t = translate();
	          clipExtent([ [ t[0] - k, t[1] - k ], [ t[0] + k, t[1] + k ] ]);
	        }
	      } else if (clipAuto) {
	        v = null;
	      }
	      return v;
	    };
	    return m.clipExtent(null);
	  }
	  (d3.geo.mercator = function() {
	    return d3_geo_mercatorProjection(d3_geo_mercator);
	  }).raw = d3_geo_mercator;
	  var d3_geo_orthographic = d3_geo_azimuthal(function() {
	    return 1;
	  }, Math.asin);
	  (d3.geo.orthographic = function() {
	    return d3_geo_projection(d3_geo_orthographic);
	  }).raw = d3_geo_orthographic;
	  var d3_geo_stereographic = d3_geo_azimuthal(function(cosλcosφ) {
	    return 1 / (1 + cosλcosφ);
	  }, function(ρ) {
	    return 2 * Math.atan(ρ);
	  });
	  (d3.geo.stereographic = function() {
	    return d3_geo_projection(d3_geo_stereographic);
	  }).raw = d3_geo_stereographic;
	  function d3_geo_transverseMercator(λ, φ) {
	    return [ Math.log(Math.tan(π / 4 + φ / 2)), -λ ];
	  }
	  d3_geo_transverseMercator.invert = function(x, y) {
	    return [ -y, 2 * Math.atan(Math.exp(x)) - halfπ ];
	  };
	  (d3.geo.transverseMercator = function() {
	    var projection = d3_geo_mercatorProjection(d3_geo_transverseMercator), center = projection.center, rotate = projection.rotate;
	    projection.center = function(_) {
	      return _ ? center([ -_[1], _[0] ]) : (_ = center(), [ _[1], -_[0] ]);
	    };
	    projection.rotate = function(_) {
	      return _ ? rotate([ _[0], _[1], _.length > 2 ? _[2] + 90 : 90 ]) : (_ = rotate(), 
	      [ _[0], _[1], _[2] - 90 ]);
	    };
	    return rotate([ 0, 0, 90 ]);
	  }).raw = d3_geo_transverseMercator;
	  d3.geom = {};
	  function d3_geom_pointX(d) {
	    return d[0];
	  }
	  function d3_geom_pointY(d) {
	    return d[1];
	  }
	  d3.geom.hull = function(vertices) {
	    var x = d3_geom_pointX, y = d3_geom_pointY;
	    if (arguments.length) return hull(vertices);
	    function hull(data) {
	      if (data.length < 3) return [];
	      var fx = d3_functor(x), fy = d3_functor(y), i, n = data.length, points = [], flippedPoints = [];
	      for (i = 0; i < n; i++) {
	        points.push([ +fx.call(this, data[i], i), +fy.call(this, data[i], i), i ]);
	      }
	      points.sort(d3_geom_hullOrder);
	      for (i = 0; i < n; i++) flippedPoints.push([ points[i][0], -points[i][1] ]);
	      var upper = d3_geom_hullUpper(points), lower = d3_geom_hullUpper(flippedPoints);
	      var skipLeft = lower[0] === upper[0], skipRight = lower[lower.length - 1] === upper[upper.length - 1], polygon = [];
	      for (i = upper.length - 1; i >= 0; --i) polygon.push(data[points[upper[i]][2]]);
	      for (i = +skipLeft; i < lower.length - skipRight; ++i) polygon.push(data[points[lower[i]][2]]);
	      return polygon;
	    }
	    hull.x = function(_) {
	      return arguments.length ? (x = _, hull) : x;
	    };
	    hull.y = function(_) {
	      return arguments.length ? (y = _, hull) : y;
	    };
	    return hull;
	  };
	  function d3_geom_hullUpper(points) {
	    var n = points.length, hull = [ 0, 1 ], hs = 2;
	    for (var i = 2; i < n; i++) {
	      while (hs > 1 && d3_cross2d(points[hull[hs - 2]], points[hull[hs - 1]], points[i]) <= 0) --hs;
	      hull[hs++] = i;
	    }
	    return hull.slice(0, hs);
	  }
	  function d3_geom_hullOrder(a, b) {
	    return a[0] - b[0] || a[1] - b[1];
	  }
	  d3.geom.polygon = function(coordinates) {
	    d3_subclass(coordinates, d3_geom_polygonPrototype);
	    return coordinates;
	  };
	  var d3_geom_polygonPrototype = d3.geom.polygon.prototype = [];
	  d3_geom_polygonPrototype.area = function() {
	    var i = -1, n = this.length, a, b = this[n - 1], area = 0;
	    while (++i < n) {
	      a = b;
	      b = this[i];
	      area += a[1] * b[0] - a[0] * b[1];
	    }
	    return area * .5;
	  };
	  d3_geom_polygonPrototype.centroid = function(k) {
	    var i = -1, n = this.length, x = 0, y = 0, a, b = this[n - 1], c;
	    if (!arguments.length) k = -1 / (6 * this.area());
	    while (++i < n) {
	      a = b;
	      b = this[i];
	      c = a[0] * b[1] - b[0] * a[1];
	      x += (a[0] + b[0]) * c;
	      y += (a[1] + b[1]) * c;
	    }
	    return [ x * k, y * k ];
	  };
	  d3_geom_polygonPrototype.clip = function(subject) {
	    var input, closed = d3_geom_polygonClosed(subject), i = -1, n = this.length - d3_geom_polygonClosed(this), j, m, a = this[n - 1], b, c, d;
	    while (++i < n) {
	      input = subject.slice();
	      subject.length = 0;
	      b = this[i];
	      c = input[(m = input.length - closed) - 1];
	      j = -1;
	      while (++j < m) {
	        d = input[j];
	        if (d3_geom_polygonInside(d, a, b)) {
	          if (!d3_geom_polygonInside(c, a, b)) {
	            subject.push(d3_geom_polygonIntersect(c, d, a, b));
	          }
	          subject.push(d);
	        } else if (d3_geom_polygonInside(c, a, b)) {
	          subject.push(d3_geom_polygonIntersect(c, d, a, b));
	        }
	        c = d;
	      }
	      if (closed) subject.push(subject[0]);
	      a = b;
	    }
	    return subject;
	  };
	  function d3_geom_polygonInside(p, a, b) {
	    return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]);
	  }
	  function d3_geom_polygonIntersect(c, d, a, b) {
	    var x1 = c[0], x3 = a[0], x21 = d[0] - x1, x43 = b[0] - x3, y1 = c[1], y3 = a[1], y21 = d[1] - y1, y43 = b[1] - y3, ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21);
	    return [ x1 + ua * x21, y1 + ua * y21 ];
	  }
	  function d3_geom_polygonClosed(coordinates) {
	    var a = coordinates[0], b = coordinates[coordinates.length - 1];
	    return !(a[0] - b[0] || a[1] - b[1]);
	  }
	  var d3_geom_voronoiEdges, d3_geom_voronoiCells, d3_geom_voronoiBeaches, d3_geom_voronoiBeachPool = [], d3_geom_voronoiFirstCircle, d3_geom_voronoiCircles, d3_geom_voronoiCirclePool = [];
	  function d3_geom_voronoiBeach() {
	    d3_geom_voronoiRedBlackNode(this);
	    this.edge = this.site = this.circle = null;
	  }
	  function d3_geom_voronoiCreateBeach(site) {
	    var beach = d3_geom_voronoiBeachPool.pop() || new d3_geom_voronoiBeach();
	    beach.site = site;
	    return beach;
	  }
	  function d3_geom_voronoiDetachBeach(beach) {
	    d3_geom_voronoiDetachCircle(beach);
	    d3_geom_voronoiBeaches.remove(beach);
	    d3_geom_voronoiBeachPool.push(beach);
	    d3_geom_voronoiRedBlackNode(beach);
	  }
	  function d3_geom_voronoiRemoveBeach(beach) {
	    var circle = beach.circle, x = circle.x, y = circle.cy, vertex = {
	      x: x,
	      y: y
	    }, previous = beach.P, next = beach.N, disappearing = [ beach ];
	    d3_geom_voronoiDetachBeach(beach);
	    var lArc = previous;
	    while (lArc.circle && abs(x - lArc.circle.x) < ε && abs(y - lArc.circle.cy) < ε) {
	      previous = lArc.P;
	      disappearing.unshift(lArc);
	      d3_geom_voronoiDetachBeach(lArc);
	      lArc = previous;
	    }
	    disappearing.unshift(lArc);
	    d3_geom_voronoiDetachCircle(lArc);
	    var rArc = next;
	    while (rArc.circle && abs(x - rArc.circle.x) < ε && abs(y - rArc.circle.cy) < ε) {
	      next = rArc.N;
	      disappearing.push(rArc);
	      d3_geom_voronoiDetachBeach(rArc);
	      rArc = next;
	    }
	    disappearing.push(rArc);
	    d3_geom_voronoiDetachCircle(rArc);
	    var nArcs = disappearing.length, iArc;
	    for (iArc = 1; iArc < nArcs; ++iArc) {
	      rArc = disappearing[iArc];
	      lArc = disappearing[iArc - 1];
	      d3_geom_voronoiSetEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex);
	    }
	    lArc = disappearing[0];
	    rArc = disappearing[nArcs - 1];
	    rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, rArc.site, null, vertex);
	    d3_geom_voronoiAttachCircle(lArc);
	    d3_geom_voronoiAttachCircle(rArc);
	  }
	  function d3_geom_voronoiAddBeach(site) {
	    var x = site.x, directrix = site.y, lArc, rArc, dxl, dxr, node = d3_geom_voronoiBeaches._;
	    while (node) {
	      dxl = d3_geom_voronoiLeftBreakPoint(node, directrix) - x;
	      if (dxl > ε) node = node.L; else {
	        dxr = x - d3_geom_voronoiRightBreakPoint(node, directrix);
	        if (dxr > ε) {
	          if (!node.R) {
	            lArc = node;
	            break;
	          }
	          node = node.R;
	        } else {
	          if (dxl > -ε) {
	            lArc = node.P;
	            rArc = node;
	          } else if (dxr > -ε) {
	            lArc = node;
	            rArc = node.N;
	          } else {
	            lArc = rArc = node;
	          }
	          break;
	        }
	      }
	    }
	    var newArc = d3_geom_voronoiCreateBeach(site);
	    d3_geom_voronoiBeaches.insert(lArc, newArc);
	    if (!lArc && !rArc) return;
	    if (lArc === rArc) {
	      d3_geom_voronoiDetachCircle(lArc);
	      rArc = d3_geom_voronoiCreateBeach(lArc.site);
	      d3_geom_voronoiBeaches.insert(newArc, rArc);
	      newArc.edge = rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site);
	      d3_geom_voronoiAttachCircle(lArc);
	      d3_geom_voronoiAttachCircle(rArc);
	      return;
	    }
	    if (!rArc) {
	      newArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site);
	      return;
	    }
	    d3_geom_voronoiDetachCircle(lArc);
	    d3_geom_voronoiDetachCircle(rArc);
	    var lSite = lArc.site, ax = lSite.x, ay = lSite.y, bx = site.x - ax, by = site.y - ay, rSite = rArc.site, cx = rSite.x - ax, cy = rSite.y - ay, d = 2 * (bx * cy - by * cx), hb = bx * bx + by * by, hc = cx * cx + cy * cy, vertex = {
	      x: (cy * hb - by * hc) / d + ax,
	      y: (bx * hc - cx * hb) / d + ay
	    };
	    d3_geom_voronoiSetEdgeEnd(rArc.edge, lSite, rSite, vertex);
	    newArc.edge = d3_geom_voronoiCreateEdge(lSite, site, null, vertex);
	    rArc.edge = d3_geom_voronoiCreateEdge(site, rSite, null, vertex);
	    d3_geom_voronoiAttachCircle(lArc);
	    d3_geom_voronoiAttachCircle(rArc);
	  }
	  function d3_geom_voronoiLeftBreakPoint(arc, directrix) {
	    var site = arc.site, rfocx = site.x, rfocy = site.y, pby2 = rfocy - directrix;
	    if (!pby2) return rfocx;
	    var lArc = arc.P;
	    if (!lArc) return -Infinity;
	    site = lArc.site;
	    var lfocx = site.x, lfocy = site.y, plby2 = lfocy - directrix;
	    if (!plby2) return lfocx;
	    var hl = lfocx - rfocx, aby2 = 1 / pby2 - 1 / plby2, b = hl / plby2;
	    if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx;
	    return (rfocx + lfocx) / 2;
	  }
	  function d3_geom_voronoiRightBreakPoint(arc, directrix) {
	    var rArc = arc.N;
	    if (rArc) return d3_geom_voronoiLeftBreakPoint(rArc, directrix);
	    var site = arc.site;
	    return site.y === directrix ? site.x : Infinity;
	  }
	  function d3_geom_voronoiCell(site) {
	    this.site = site;
	    this.edges = [];
	  }
	  d3_geom_voronoiCell.prototype.prepare = function() {
	    var halfEdges = this.edges, iHalfEdge = halfEdges.length, edge;
	    while (iHalfEdge--) {
	      edge = halfEdges[iHalfEdge].edge;
	      if (!edge.b || !edge.a) halfEdges.splice(iHalfEdge, 1);
	    }
	    halfEdges.sort(d3_geom_voronoiHalfEdgeOrder);
	    return halfEdges.length;
	  };
	  function d3_geom_voronoiCloseCells(extent) {
	    var x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], x2, y2, x3, y3, cells = d3_geom_voronoiCells, iCell = cells.length, cell, iHalfEdge, halfEdges, nHalfEdges, start, end;
	    while (iCell--) {
	      cell = cells[iCell];
	      if (!cell || !cell.prepare()) continue;
	      halfEdges = cell.edges;
	      nHalfEdges = halfEdges.length;
	      iHalfEdge = 0;
	      while (iHalfEdge < nHalfEdges) {
	        end = halfEdges[iHalfEdge].end(), x3 = end.x, y3 = end.y;
	        start = halfEdges[++iHalfEdge % nHalfEdges].start(), x2 = start.x, y2 = start.y;
	        if (abs(x3 - x2) > ε || abs(y3 - y2) > ε) {
	          halfEdges.splice(iHalfEdge, 0, new d3_geom_voronoiHalfEdge(d3_geom_voronoiCreateBorderEdge(cell.site, end, abs(x3 - x0) < ε && y1 - y3 > ε ? {
	            x: x0,
	            y: abs(x2 - x0) < ε ? y2 : y1
	          } : abs(y3 - y1) < ε && x1 - x3 > ε ? {
	            x: abs(y2 - y1) < ε ? x2 : x1,
	            y: y1
	          } : abs(x3 - x1) < ε && y3 - y0 > ε ? {
	            x: x1,
	            y: abs(x2 - x1) < ε ? y2 : y0
	          } : abs(y3 - y0) < ε && x3 - x0 > ε ? {
	            x: abs(y2 - y0) < ε ? x2 : x0,
	            y: y0
	          } : null), cell.site, null));
	          ++nHalfEdges;
	        }
	      }
	    }
	  }
	  function d3_geom_voronoiHalfEdgeOrder(a, b) {
	    return b.angle - a.angle;
	  }
	  function d3_geom_voronoiCircle() {
	    d3_geom_voronoiRedBlackNode(this);
	    this.x = this.y = this.arc = this.site = this.cy = null;
	  }
	  function d3_geom_voronoiAttachCircle(arc) {
	    var lArc = arc.P, rArc = arc.N;
	    if (!lArc || !rArc) return;
	    var lSite = lArc.site, cSite = arc.site, rSite = rArc.site;
	    if (lSite === rSite) return;
	    var bx = cSite.x, by = cSite.y, ax = lSite.x - bx, ay = lSite.y - by, cx = rSite.x - bx, cy = rSite.y - by;
	    var d = 2 * (ax * cy - ay * cx);
	    if (d >= -ε2) return;
	    var ha = ax * ax + ay * ay, hc = cx * cx + cy * cy, x = (cy * ha - ay * hc) / d, y = (ax * hc - cx * ha) / d, cy = y + by;
	    var circle = d3_geom_voronoiCirclePool.pop() || new d3_geom_voronoiCircle();
	    circle.arc = arc;
	    circle.site = cSite;
	    circle.x = x + bx;
	    circle.y = cy + Math.sqrt(x * x + y * y);
	    circle.cy = cy;
	    arc.circle = circle;
	    var before = null, node = d3_geom_voronoiCircles._;
	    while (node) {
	      if (circle.y < node.y || circle.y === node.y && circle.x <= node.x) {
	        if (node.L) node = node.L; else {
	          before = node.P;
	          break;
	        }
	      } else {
	        if (node.R) node = node.R; else {
	          before = node;
	          break;
	        }
	      }
	    }
	    d3_geom_voronoiCircles.insert(before, circle);
	    if (!before) d3_geom_voronoiFirstCircle = circle;
	  }
	  function d3_geom_voronoiDetachCircle(arc) {
	    var circle = arc.circle;
	    if (circle) {
	      if (!circle.P) d3_geom_voronoiFirstCircle = circle.N;
	      d3_geom_voronoiCircles.remove(circle);
	      d3_geom_voronoiCirclePool.push(circle);
	      d3_geom_voronoiRedBlackNode(circle);
	      arc.circle = null;
	    }
	  }
	  function d3_geom_voronoiClipEdges(extent) {
	    var edges = d3_geom_voronoiEdges, clip = d3_geom_clipLine(extent[0][0], extent[0][1], extent[1][0], extent[1][1]), i = edges.length, e;
	    while (i--) {
	      e = edges[i];
	      if (!d3_geom_voronoiConnectEdge(e, extent) || !clip(e) || abs(e.a.x - e.b.x) < ε && abs(e.a.y - e.b.y) < ε) {
	        e.a = e.b = null;
	        edges.splice(i, 1);
	      }
	    }
	  }
	  function d3_geom_voronoiConnectEdge(edge, extent) {
	    var vb = edge.b;
	    if (vb) return true;
	    var va = edge.a, x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], lSite = edge.l, rSite = edge.r, lx = lSite.x, ly = lSite.y, rx = rSite.x, ry = rSite.y, fx = (lx + rx) / 2, fy = (ly + ry) / 2, fm, fb;
	    if (ry === ly) {
	      if (fx < x0 || fx >= x1) return;
	      if (lx > rx) {
	        if (!va) va = {
	          x: fx,
	          y: y0
	        }; else if (va.y >= y1) return;
	        vb = {
	          x: fx,
	          y: y1
	        };
	      } else {
	        if (!va) va = {
	          x: fx,
	          y: y1
	        }; else if (va.y < y0) return;
	        vb = {
	          x: fx,
	          y: y0
	        };
	      }
	    } else {
	      fm = (lx - rx) / (ry - ly);
	      fb = fy - fm * fx;
	      if (fm < -1 || fm > 1) {
	        if (lx > rx) {
	          if (!va) va = {
	            x: (y0 - fb) / fm,
	            y: y0
	          }; else if (va.y >= y1) return;
	          vb = {
	            x: (y1 - fb) / fm,
	            y: y1
	          };
	        } else {
	          if (!va) va = {
	            x: (y1 - fb) / fm,
	            y: y1
	          }; else if (va.y < y0) return;
	          vb = {
	            x: (y0 - fb) / fm,
	            y: y0
	          };
	        }
	      } else {
	        if (ly < ry) {
	          if (!va) va = {
	            x: x0,
	            y: fm * x0 + fb
	          }; else if (va.x >= x1) return;
	          vb = {
	            x: x1,
	            y: fm * x1 + fb
	          };
	        } else {
	          if (!va) va = {
	            x: x1,
	            y: fm * x1 + fb
	          }; else if (va.x < x0) return;
	          vb = {
	            x: x0,
	            y: fm * x0 + fb
	          };
	        }
	      }
	    }
	    edge.a = va;
	    edge.b = vb;
	    return true;
	  }
	  function d3_geom_voronoiEdge(lSite, rSite) {
	    this.l = lSite;
	    this.r = rSite;
	    this.a = this.b = null;
	  }
	  function d3_geom_voronoiCreateEdge(lSite, rSite, va, vb) {
	    var edge = new d3_geom_voronoiEdge(lSite, rSite);
	    d3_geom_voronoiEdges.push(edge);
	    if (va) d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, va);
	    if (vb) d3_geom_voronoiSetEdgeEnd(edge, rSite, lSite, vb);
	    d3_geom_voronoiCells[lSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, lSite, rSite));
	    d3_geom_voronoiCells[rSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, rSite, lSite));
	    return edge;
	  }
	  function d3_geom_voronoiCreateBorderEdge(lSite, va, vb) {
	    var edge = new d3_geom_voronoiEdge(lSite, null);
	    edge.a = va;
	    edge.b = vb;
	    d3_geom_voronoiEdges.push(edge);
	    return edge;
	  }
	  function d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, vertex) {
	    if (!edge.a && !edge.b) {
	      edge.a = vertex;
	      edge.l = lSite;
	      edge.r = rSite;
	    } else if (edge.l === rSite) {
	      edge.b = vertex;
	    } else {
	      edge.a = vertex;
	    }
	  }
	  function d3_geom_voronoiHalfEdge(edge, lSite, rSite) {
	    var va = edge.a, vb = edge.b;
	    this.edge = edge;
	    this.site = lSite;
	    this.angle = rSite ? Math.atan2(rSite.y - lSite.y, rSite.x - lSite.x) : edge.l === lSite ? Math.atan2(vb.x - va.x, va.y - vb.y) : Math.atan2(va.x - vb.x, vb.y - va.y);
	  }
	  d3_geom_voronoiHalfEdge.prototype = {
	    start: function() {
	      return this.edge.l === this.site ? this.edge.a : this.edge.b;
	    },
	    end: function() {
	      return this.edge.l === this.site ? this.edge.b : this.edge.a;
	    }
	  };
	  function d3_geom_voronoiRedBlackTree() {
	    this._ = null;
	  }
	  function d3_geom_voronoiRedBlackNode(node) {
	    node.U = node.C = node.L = node.R = node.P = node.N = null;
	  }
	  d3_geom_voronoiRedBlackTree.prototype = {
	    insert: function(after, node) {
	      var parent, grandpa, uncle;
	      if (after) {
	        node.P = after;
	        node.N = after.N;
	        if (after.N) after.N.P = node;
	        after.N = node;
	        if (after.R) {
	          after = after.R;
	          while (after.L) after = after.L;
	          after.L = node;
	        } else {
	          after.R = node;
	        }
	        parent = after;
	      } else if (this._) {
	        after = d3_geom_voronoiRedBlackFirst(this._);
	        node.P = null;
	        node.N = after;
	        after.P = after.L = node;
	        parent = after;
	      } else {
	        node.P = node.N = null;
	        this._ = node;
	        parent = null;
	      }
	      node.L = node.R = null;
	      node.U = parent;
	      node.C = true;
	      after = node;
	      while (parent && parent.C) {
	        grandpa = parent.U;
	        if (parent === grandpa.L) {
	          uncle = grandpa.R;
	          if (uncle && uncle.C) {
	            parent.C = uncle.C = false;
	            grandpa.C = true;
	            after = grandpa;
	          } else {
	            if (after === parent.R) {
	              d3_geom_voronoiRedBlackRotateLeft(this, parent);
	              after = parent;
	              parent = after.U;
	            }
	            parent.C = false;
	            grandpa.C = true;
	            d3_geom_voronoiRedBlackRotateRight(this, grandpa);
	          }
	        } else {
	          uncle = grandpa.L;
	          if (uncle && uncle.C) {
	            parent.C = uncle.C = false;
	            grandpa.C = true;
	            after = grandpa;
	          } else {
	            if (after === parent.L) {
	              d3_geom_voronoiRedBlackRotateRight(this, parent);
	              after = parent;
	              parent = after.U;
	            }
	            parent.C = false;
	            grandpa.C = true;
	            d3_geom_voronoiRedBlackRotateLeft(this, grandpa);
	          }
	        }
	        parent = after.U;
	      }
	      this._.C = false;
	    },
	    remove: function(node) {
	      if (node.N) node.N.P = node.P;
	      if (node.P) node.P.N = node.N;
	      node.N = node.P = null;
	      var parent = node.U, sibling, left = node.L, right = node.R, next, red;
	      if (!left) next = right; else if (!right) next = left; else next = d3_geom_voronoiRedBlackFirst(right);
	      if (parent) {
	        if (parent.L === node) parent.L = next; else parent.R = next;
	      } else {
	        this._ = next;
	      }
	      if (left && right) {
	        red = next.C;
	        next.C = node.C;
	        next.L = left;
	        left.U = next;
	        if (next !== right) {
	          parent = next.U;
	          next.U = node.U;
	          node = next.R;
	          parent.L = node;
	          next.R = right;
	          right.U = next;
	        } else {
	          next.U = parent;
	          parent = next;
	          node = next.R;
	        }
	      } else {
	        red = node.C;
	        node = next;
	      }
	      if (node) node.U = parent;
	      if (red) return;
	      if (node && node.C) {
	        node.C = false;
	        return;
	      }
	      do {
	        if (node === this._) break;
	        if (node === parent.L) {
	          sibling = parent.R;
	          if (sibling.C) {
	            sibling.C = false;
	            parent.C = true;
	            d3_geom_voronoiRedBlackRotateLeft(this, parent);
	            sibling = parent.R;
	          }
	          if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) {
	            if (!sibling.R || !sibling.R.C) {
	              sibling.L.C = false;
	              sibling.C = true;
	              d3_geom_voronoiRedBlackRotateRight(this, sibling);
	              sibling = parent.R;
	            }
	            sibling.C = parent.C;
	            parent.C = sibling.R.C = false;
	            d3_geom_voronoiRedBlackRotateLeft(this, parent);
	            node = this._;
	            break;
	          }
	        } else {
	          sibling = parent.L;
	          if (sibling.C) {
	            sibling.C = false;
	            parent.C = true;
	            d3_geom_voronoiRedBlackRotateRight(this, parent);
	            sibling = parent.L;
	          }
	          if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) {
	            if (!sibling.L || !sibling.L.C) {
	              sibling.R.C = false;
	              sibling.C = true;
	              d3_geom_voronoiRedBlackRotateLeft(this, sibling);
	              sibling = parent.L;
	            }
	            sibling.C = parent.C;
	            parent.C = sibling.L.C = false;
	            d3_geom_voronoiRedBlackRotateRight(this, parent);
	            node = this._;
	            break;
	          }
	        }
	        sibling.C = true;
	        node = parent;
	        parent = parent.U;
	      } while (!node.C);
	      if (node) node.C = false;
	    }
	  };
	  function d3_geom_voronoiRedBlackRotateLeft(tree, node) {
	    var p = node, q = node.R, parent = p.U;
	    if (parent) {
	      if (parent.L === p) parent.L = q; else parent.R = q;
	    } else {
	      tree._ = q;
	    }
	    q.U = parent;
	    p.U = q;
	    p.R = q.L;
	    if (p.R) p.R.U = p;
	    q.L = p;
	  }
	  function d3_geom_voronoiRedBlackRotateRight(tree, node) {
	    var p = node, q = node.L, parent = p.U;
	    if (parent) {
	      if (parent.L === p) parent.L = q; else parent.R = q;
	    } else {
	      tree._ = q;
	    }
	    q.U = parent;
	    p.U = q;
	    p.L = q.R;
	    if (p.L) p.L.U = p;
	    q.R = p;
	  }
	  function d3_geom_voronoiRedBlackFirst(node) {
	    while (node.L) node = node.L;
	    return node;
	  }
	  function d3_geom_voronoi(sites, bbox) {
	    var site = sites.sort(d3_geom_voronoiVertexOrder).pop(), x0, y0, circle;
	    d3_geom_voronoiEdges = [];
	    d3_geom_voronoiCells = new Array(sites.length);
	    d3_geom_voronoiBeaches = new d3_geom_voronoiRedBlackTree();
	    d3_geom_voronoiCircles = new d3_geom_voronoiRedBlackTree();
	    while (true) {
	      circle = d3_geom_voronoiFirstCircle;
	      if (site && (!circle || site.y < circle.y || site.y === circle.y && site.x < circle.x)) {
	        if (site.x !== x0 || site.y !== y0) {
	          d3_geom_voronoiCells[site.i] = new d3_geom_voronoiCell(site);
	          d3_geom_voronoiAddBeach(site);
	          x0 = site.x, y0 = site.y;
	        }
	        site = sites.pop();
	      } else if (circle) {
	        d3_geom_voronoiRemoveBeach(circle.arc);
	      } else {
	        break;
	      }
	    }
	    if (bbox) d3_geom_voronoiClipEdges(bbox), d3_geom_voronoiCloseCells(bbox);
	    var diagram = {
	      cells: d3_geom_voronoiCells,
	      edges: d3_geom_voronoiEdges
	    };
	    d3_geom_voronoiBeaches = d3_geom_voronoiCircles = d3_geom_voronoiEdges = d3_geom_voronoiCells = null;
	    return diagram;
	  }
	  function d3_geom_voronoiVertexOrder(a, b) {
	    return b.y - a.y || b.x - a.x;
	  }
	  d3.geom.voronoi = function(points) {
	    var x = d3_geom_pointX, y = d3_geom_pointY, fx = x, fy = y, clipExtent = d3_geom_voronoiClipExtent;
	    if (points) return voronoi(points);
	    function voronoi(data) {
	      var polygons = new Array(data.length), x0 = clipExtent[0][0], y0 = clipExtent[0][1], x1 = clipExtent[1][0], y1 = clipExtent[1][1];
	      d3_geom_voronoi(sites(data), clipExtent).cells.forEach(function(cell, i) {
	        var edges = cell.edges, site = cell.site, polygon = polygons[i] = edges.length ? edges.map(function(e) {
	          var s = e.start();
	          return [ s.x, s.y ];
	        }) : site.x >= x0 && site.x <= x1 && site.y >= y0 && site.y <= y1 ? [ [ x0, y1 ], [ x1, y1 ], [ x1, y0 ], [ x0, y0 ] ] : [];
	        polygon.point = data[i];
	      });
	      return polygons;
	    }
	    function sites(data) {
	      return data.map(function(d, i) {
	        return {
	          x: Math.round(fx(d, i) / ε) * ε,
	          y: Math.round(fy(d, i) / ε) * ε,
	          i: i
	        };
	      });
	    }
	    voronoi.links = function(data) {
	      return d3_geom_voronoi(sites(data)).edges.filter(function(edge) {
	        return edge.l && edge.r;
	      }).map(function(edge) {
	        return {
	          source: data[edge.l.i],
	          target: data[edge.r.i]
	        };
	      });
	    };
	    voronoi.triangles = function(data) {
	      var triangles = [];
	      d3_geom_voronoi(sites(data)).cells.forEach(function(cell, i) {
	        var site = cell.site, edges = cell.edges.sort(d3_geom_voronoiHalfEdgeOrder), j = -1, m = edges.length, e0, s0, e1 = edges[m - 1].edge, s1 = e1.l === site ? e1.r : e1.l;
	        while (++j < m) {
	          e0 = e1;
	          s0 = s1;
	          e1 = edges[j].edge;
	          s1 = e1.l === site ? e1.r : e1.l;
	          if (i < s0.i && i < s1.i && d3_geom_voronoiTriangleArea(site, s0, s1) < 0) {
	            triangles.push([ data[i], data[s0.i], data[s1.i] ]);
	          }
	        }
	      });
	      return triangles;
	    };
	    voronoi.x = function(_) {
	      return arguments.length ? (fx = d3_functor(x = _), voronoi) : x;
	    };
	    voronoi.y = function(_) {
	      return arguments.length ? (fy = d3_functor(y = _), voronoi) : y;
	    };
	    voronoi.clipExtent = function(_) {
	      if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent;
	      clipExtent = _ == null ? d3_geom_voronoiClipExtent : _;
	      return voronoi;
	    };
	    voronoi.size = function(_) {
	      if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent && clipExtent[1];
	      return voronoi.clipExtent(_ && [ [ 0, 0 ], _ ]);
	    };
	    return voronoi;
	  };
	  var d3_geom_voronoiClipExtent = [ [ -1e6, -1e6 ], [ 1e6, 1e6 ] ];
	  function d3_geom_voronoiTriangleArea(a, b, c) {
	    return (a.x - c.x) * (b.y - a.y) - (a.x - b.x) * (c.y - a.y);
	  }
	  d3.geom.delaunay = function(vertices) {
	    return d3.geom.voronoi().triangles(vertices);
	  };
	  d3.geom.quadtree = function(points, x1, y1, x2, y2) {
	    var x = d3_geom_pointX, y = d3_geom_pointY, compat;
	    if (compat = arguments.length) {
	      x = d3_geom_quadtreeCompatX;
	      y = d3_geom_quadtreeCompatY;
	      if (compat === 3) {
	        y2 = y1;
	        x2 = x1;
	        y1 = x1 = 0;
	      }
	      return quadtree(points);
	    }
	    function quadtree(data) {
	      var d, fx = d3_functor(x), fy = d3_functor(y), xs, ys, i, n, x1_, y1_, x2_, y2_;
	      if (x1 != null) {
	        x1_ = x1, y1_ = y1, x2_ = x2, y2_ = y2;
	      } else {
	        x2_ = y2_ = -(x1_ = y1_ = Infinity);
	        xs = [], ys = [];
	        n = data.length;
	        if (compat) for (i = 0; i < n; ++i) {
	          d = data[i];
	          if (d.x < x1_) x1_ = d.x;
	          if (d.y < y1_) y1_ = d.y;
	          if (d.x > x2_) x2_ = d.x;
	          if (d.y > y2_) y2_ = d.y;
	          xs.push(d.x);
	          ys.push(d.y);
	        } else for (i = 0; i < n; ++i) {
	          var x_ = +fx(d = data[i], i), y_ = +fy(d, i);
	          if (x_ < x1_) x1_ = x_;
	          if (y_ < y1_) y1_ = y_;
	          if (x_ > x2_) x2_ = x_;
	          if (y_ > y2_) y2_ = y_;
	          xs.push(x_);
	          ys.push(y_);
	        }
	      }
	      var dx = x2_ - x1_, dy = y2_ - y1_;
	      if (dx > dy) y2_ = y1_ + dx; else x2_ = x1_ + dy;
	      function insert(n, d, x, y, x1, y1, x2, y2) {
	        if (isNaN(x) || isNaN(y)) return;
	        if (n.leaf) {
	          var nx = n.x, ny = n.y;
	          if (nx != null) {
	            if (abs(nx - x) + abs(ny - y) < .01) {
	              insertChild(n, d, x, y, x1, y1, x2, y2);
	            } else {
	              var nPoint = n.point;
	              n.x = n.y = n.point = null;
	              insertChild(n, nPoint, nx, ny, x1, y1, x2, y2);
	              insertChild(n, d, x, y, x1, y1, x2, y2);
	            }
	          } else {
	            n.x = x, n.y = y, n.point = d;
	          }
	        } else {
	          insertChild(n, d, x, y, x1, y1, x2, y2);
	        }
	      }
	      function insertChild(n, d, x, y, x1, y1, x2, y2) {
	        var xm = (x1 + x2) * .5, ym = (y1 + y2) * .5, right = x >= xm, below = y >= ym, i = below << 1 | right;
	        n.leaf = false;
	        n = n.nodes[i] || (n.nodes[i] = d3_geom_quadtreeNode());
	        if (right) x1 = xm; else x2 = xm;
	        if (below) y1 = ym; else y2 = ym;
	        insert(n, d, x, y, x1, y1, x2, y2);
	      }
	      var root = d3_geom_quadtreeNode();
	      root.add = function(d) {
	        insert(root, d, +fx(d, ++i), +fy(d, i), x1_, y1_, x2_, y2_);
	      };
	      root.visit = function(f) {
	        d3_geom_quadtreeVisit(f, root, x1_, y1_, x2_, y2_);
	      };
	      root.find = function(point) {
	        return d3_geom_quadtreeFind(root, point[0], point[1], x1_, y1_, x2_, y2_);
	      };
	      i = -1;
	      if (x1 == null) {
	        while (++i < n) {
	          insert(root, data[i], xs[i], ys[i], x1_, y1_, x2_, y2_);
	        }
	        --i;
	      } else data.forEach(root.add);
	      xs = ys = data = d = null;
	      return root;
	    }
	    quadtree.x = function(_) {
	      return arguments.length ? (x = _, quadtree) : x;
	    };
	    quadtree.y = function(_) {
	      return arguments.length ? (y = _, quadtree) : y;
	    };
	    quadtree.extent = function(_) {
	      if (!arguments.length) return x1 == null ? null : [ [ x1, y1 ], [ x2, y2 ] ];
	      if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = +_[0][0], y1 = +_[0][1], x2 = +_[1][0], 
	      y2 = +_[1][1];
	      return quadtree;
	    };
	    quadtree.size = function(_) {
	      if (!arguments.length) return x1 == null ? null : [ x2 - x1, y2 - y1 ];
	      if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = y1 = 0, x2 = +_[0], y2 = +_[1];
	      return quadtree;
	    };
	    return quadtree;
	  };
	  function d3_geom_quadtreeCompatX(d) {
	    return d.x;
	  }
	  function d3_geom_quadtreeCompatY(d) {
	    return d.y;
	  }
	  function d3_geom_quadtreeNode() {
	    return {
	      leaf: true,
	      nodes: [],
	      point: null,
	      x: null,
	      y: null
	    };
	  }
	  function d3_geom_quadtreeVisit(f, node, x1, y1, x2, y2) {
	    if (!f(node, x1, y1, x2, y2)) {
	      var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, children = node.nodes;
	      if (children[0]) d3_geom_quadtreeVisit(f, children[0], x1, y1, sx, sy);
	      if (children[1]) d3_geom_quadtreeVisit(f, children[1], sx, y1, x2, sy);
	      if (children[2]) d3_geom_quadtreeVisit(f, children[2], x1, sy, sx, y2);
	      if (children[3]) d3_geom_quadtreeVisit(f, children[3], sx, sy, x2, y2);
	    }
	  }
	  function d3_geom_quadtreeFind(root, x, y, x0, y0, x3, y3) {
	    var minDistance2 = Infinity, closestPoint;
	    (function find(node, x1, y1, x2, y2) {
	      if (x1 > x3 || y1 > y3 || x2 < x0 || y2 < y0) return;
	      if (point = node.point) {
	        var point, dx = x - node.x, dy = y - node.y, distance2 = dx * dx + dy * dy;
	        if (distance2 < minDistance2) {
	          var distance = Math.sqrt(minDistance2 = distance2);
	          x0 = x - distance, y0 = y - distance;
	          x3 = x + distance, y3 = y + distance;
	          closestPoint = point;
	        }
	      }
	      var children = node.nodes, xm = (x1 + x2) * .5, ym = (y1 + y2) * .5, right = x >= xm, below = y >= ym;
	      for (var i = below << 1 | right, j = i + 4; i < j; ++i) {
	        if (node = children[i & 3]) switch (i & 3) {
	         case 0:
	          find(node, x1, y1, xm, ym);
	          break;
	
	         case 1:
	          find(node, xm, y1, x2, ym);
	          break;
	
	         case 2:
	          find(node, x1, ym, xm, y2);
	          break;
	
	         case 3:
	          find(node, xm, ym, x2, y2);
	          break;
	        }
	      }
	    })(root, x0, y0, x3, y3);
	    return closestPoint;
	  }
	  d3.interpolateRgb = d3_interpolateRgb;
	  function d3_interpolateRgb(a, b) {
	    a = d3.rgb(a);
	    b = d3.rgb(b);
	    var ar = a.r, ag = a.g, ab = a.b, br = b.r - ar, bg = b.g - ag, bb = b.b - ab;
	    return function(t) {
	      return "#" + d3_rgb_hex(Math.round(ar + br * t)) + d3_rgb_hex(Math.round(ag + bg * t)) + d3_rgb_hex(Math.round(ab + bb * t));
	    };
	  }
	  d3.interpolateObject = d3_interpolateObject;
	  function d3_interpolateObject(a, b) {
	    var i = {}, c = {}, k;
	    for (k in a) {
	      if (k in b) {
	        i[k] = d3_interpolate(a[k], b[k]);
	      } else {
	        c[k] = a[k];
	      }
	    }
	    for (k in b) {
	      if (!(k in a)) {
	        c[k] = b[k];
	      }
	    }
	    return function(t) {
	      for (k in i) c[k] = i[k](t);
	      return c;
	    };
	  }
	  d3.interpolateNumber = d3_interpolateNumber;
	  function d3_interpolateNumber(a, b) {
	    a = +a, b = +b;
	    return function(t) {
	      return a * (1 - t) + b * t;
	    };
	  }
	  d3.interpolateString = d3_interpolateString;
	  function d3_interpolateString(a, b) {
	    var bi = d3_interpolate_numberA.lastIndex = d3_interpolate_numberB.lastIndex = 0, am, bm, bs, i = -1, s = [], q = [];
	    a = a + "", b = b + "";
	    while ((am = d3_interpolate_numberA.exec(a)) && (bm = d3_interpolate_numberB.exec(b))) {
	      if ((bs = bm.index) > bi) {
	        bs = b.slice(bi, bs);
	        if (s[i]) s[i] += bs; else s[++i] = bs;
	      }
	      if ((am = am[0]) === (bm = bm[0])) {
	        if (s[i]) s[i] += bm; else s[++i] = bm;
	      } else {
	        s[++i] = null;
	        q.push({
	          i: i,
	          x: d3_interpolateNumber(am, bm)
	        });
	      }
	      bi = d3_interpolate_numberB.lastIndex;
	    }
	    if (bi < b.length) {
	      bs = b.slice(bi);
	      if (s[i]) s[i] += bs; else s[++i] = bs;
	    }
	    return s.length < 2 ? q[0] ? (b = q[0].x, function(t) {
	      return b(t) + "";
	    }) : function() {
	      return b;
	    } : (b = q.length, function(t) {
	      for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);
	      return s.join("");
	    });
	  }
	  var d3_interpolate_numberA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g, d3_interpolate_numberB = new RegExp(d3_interpolate_numberA.source, "g");
	  d3.interpolate = d3_interpolate;
	  function d3_interpolate(a, b) {
	    var i = d3.interpolators.length, f;
	    while (--i >= 0 && !(f = d3.interpolators[i](a, b))) ;
	    return f;
	  }
	  d3.interpolators = [ function(a, b) {
	    var t = typeof b;
	    return (t === "string" ? d3_rgb_names.has(b.toLowerCase()) || /^(#|rgb\(|hsl\()/i.test(b) ? d3_interpolateRgb : d3_interpolateString : b instanceof d3_color ? d3_interpolateRgb : Array.isArray(b) ? d3_interpolateArray : t === "object" && isNaN(b) ? d3_interpolateObject : d3_interpolateNumber)(a, b);
	  } ];
	  d3.interpolateArray = d3_interpolateArray;
	  function d3_interpolateArray(a, b) {
	    var x = [], c = [], na = a.length, nb = b.length, n0 = Math.min(a.length, b.length), i;
	    for (i = 0; i < n0; ++i) x.push(d3_interpolate(a[i], b[i]));
	    for (;i < na; ++i) c[i] = a[i];
	    for (;i < nb; ++i) c[i] = b[i];
	    return function(t) {
	      for (i = 0; i < n0; ++i) c[i] = x[i](t);
	      return c;
	    };
	  }
	  var d3_ease_default = function() {
	    return d3_identity;
	  };
	  var d3_ease = d3.map({
	    linear: d3_ease_default,
	    poly: d3_ease_poly,
	    quad: function() {
	      return d3_ease_quad;
	    },
	    cubic: function() {
	      return d3_ease_cubic;
	    },
	    sin: function() {
	      return d3_ease_sin;
	    },
	    exp: function() {
	      return d3_ease_exp;
	    },
	    circle: function() {
	      return d3_ease_circle;
	    },
	    elastic: d3_ease_elastic,
	    back: d3_ease_back,
	    bounce: function() {
	      return d3_ease_bounce;
	    }
	  });
	  var d3_ease_mode = d3.map({
	    "in": d3_identity,
	    out: d3_ease_reverse,
	    "in-out": d3_ease_reflect,
	    "out-in": function(f) {
	      return d3_ease_reflect(d3_ease_reverse(f));
	    }
	  });
	  d3.ease = function(name) {
	    var i = name.indexOf("-"), t = i >= 0 ? name.slice(0, i) : name, m = i >= 0 ? name.slice(i + 1) : "in";
	    t = d3_ease.get(t) || d3_ease_default;
	    m = d3_ease_mode.get(m) || d3_identity;
	    return d3_ease_clamp(m(t.apply(null, d3_arraySlice.call(arguments, 1))));
	  };
	  function d3_ease_clamp(f) {
	    return function(t) {
	      return t <= 0 ? 0 : t >= 1 ? 1 : f(t);
	    };
	  }
	  function d3_ease_reverse(f) {
	    return function(t) {
	      return 1 - f(1 - t);
	    };
	  }
	  function d3_ease_reflect(f) {
	    return function(t) {
	      return .5 * (t < .5 ? f(2 * t) : 2 - f(2 - 2 * t));
	    };
	  }
	  function d3_ease_quad(t) {
	    return t * t;
	  }
	  function d3_ease_cubic(t) {
	    return t * t * t;
	  }
	  function d3_ease_cubicInOut(t) {
	    if (t <= 0) return 0;
	    if (t >= 1) return 1;
	    var t2 = t * t, t3 = t2 * t;
	    return 4 * (t < .5 ? t3 : 3 * (t - t2) + t3 - .75);
	  }
	  function d3_ease_poly(e) {
	    return function(t) {
	      return Math.pow(t, e);
	    };
	  }
	  function d3_ease_sin(t) {
	    return 1 - Math.cos(t * halfπ);
	  }
	  function d3_ease_exp(t) {
	    return Math.pow(2, 10 * (t - 1));
	  }
	  function d3_ease_circle(t) {
	    return 1 - Math.sqrt(1 - t * t);
	  }
	  function d3_ease_elastic(a, p) {
	    var s;
	    if (arguments.length < 2) p = .45;
	    if (arguments.length) s = p / τ * Math.asin(1 / a); else a = 1, s = p / 4;
	    return function(t) {
	      return 1 + a * Math.pow(2, -10 * t) * Math.sin((t - s) * τ / p);
	    };
	  }
	  function d3_ease_back(s) {
	    if (!s) s = 1.70158;
	    return function(t) {
	      return t * t * ((s + 1) * t - s);
	    };
	  }
	  function d3_ease_bounce(t) {
	    return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375;
	  }
	  d3.interpolateHcl = d3_interpolateHcl;
	  function d3_interpolateHcl(a, b) {
	    a = d3.hcl(a);
	    b = d3.hcl(b);
	    var ah = a.h, ac = a.c, al = a.l, bh = b.h - ah, bc = b.c - ac, bl = b.l - al;
	    if (isNaN(bc)) bc = 0, ac = isNaN(ac) ? b.c : ac;
	    if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360;
	    return function(t) {
	      return d3_hcl_lab(ah + bh * t, ac + bc * t, al + bl * t) + "";
	    };
	  }
	  d3.interpolateHsl = d3_interpolateHsl;
	  function d3_interpolateHsl(a, b) {
	    a = d3.hsl(a);
	    b = d3.hsl(b);
	    var ah = a.h, as = a.s, al = a.l, bh = b.h - ah, bs = b.s - as, bl = b.l - al;
	    if (isNaN(bs)) bs = 0, as = isNaN(as) ? b.s : as;
	    if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360;
	    return function(t) {
	      return d3_hsl_rgb(ah + bh * t, as + bs * t, al + bl * t) + "";
	    };
	  }
	  d3.interpolateLab = d3_interpolateLab;
	  function d3_interpolateLab(a, b) {
	    a = d3.lab(a);
	    b = d3.lab(b);
	    var al = a.l, aa = a.a, ab = a.b, bl = b.l - al, ba = b.a - aa, bb = b.b - ab;
	    return function(t) {
	      return d3_lab_rgb(al + bl * t, aa + ba * t, ab + bb * t) + "";
	    };
	  }
	  d3.interpolateRound = d3_interpolateRound;
	  function d3_interpolateRound(a, b) {
	    b -= a;
	    return function(t) {
	      return Math.round(a + b * t);
	    };
	  }
	  d3.transform = function(string) {
	    var g = d3_document.createElementNS(d3.ns.prefix.svg, "g");
	    return (d3.transform = function(string) {
	      if (string != null) {
	        g.setAttribute("transform", string);
	        var t = g.transform.baseVal.consolidate();
	      }
	      return new d3_transform(t ? t.matrix : d3_transformIdentity);
	    })(string);
	  };
	  function d3_transform(m) {
	    var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0;
	    if (r0[0] * r1[1] < r1[0] * r0[1]) {
	      r0[0] *= -1;
	      r0[1] *= -1;
	      kx *= -1;
	      kz *= -1;
	    }
	    this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_degrees;
	    this.translate = [ m.e, m.f ];
	    this.scale = [ kx, ky ];
	    this.skew = ky ? Math.atan2(kz, ky) * d3_degrees : 0;
	  }
	  d3_transform.prototype.toString = function() {
	    return "translate(" + this.translate + ")rotate(" + this.rotate + ")skewX(" + this.skew + ")scale(" + this.scale + ")";
	  };
	  function d3_transformDot(a, b) {
	    return a[0] * b[0] + a[1] * b[1];
	  }
	  function d3_transformNormalize(a) {
	    var k = Math.sqrt(d3_transformDot(a, a));
	    if (k) {
	      a[0] /= k;
	      a[1] /= k;
	    }
	    return k;
	  }
	  function d3_transformCombine(a, b, k) {
	    a[0] += k * b[0];
	    a[1] += k * b[1];
	    return a;
	  }
	  var d3_transformIdentity = {
	    a: 1,
	    b: 0,
	    c: 0,
	    d: 1,
	    e: 0,
	    f: 0
	  };
	  d3.interpolateTransform = d3_interpolateTransform;
	  function d3_interpolateTransformPop(s) {
	    return s.length ? s.pop() + "," : "";
	  }
	  function d3_interpolateTranslate(ta, tb, s, q) {
	    if (ta[0] !== tb[0] || ta[1] !== tb[1]) {
	      var i = s.push("translate(", null, ",", null, ")");
	      q.push({
	        i: i - 4,
	        x: d3_interpolateNumber(ta[0], tb[0])
	      }, {
	        i: i - 2,
	        x: d3_interpolateNumber(ta[1], tb[1])
	      });
	    } else if (tb[0] || tb[1]) {
	      s.push("translate(" + tb + ")");
	    }
	  }
	  function d3_interpolateRotate(ra, rb, s, q) {
	    if (ra !== rb) {
	      if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360;
	      q.push({
	        i: s.push(d3_interpolateTransformPop(s) + "rotate(", null, ")") - 2,
	        x: d3_interpolateNumber(ra, rb)
	      });
	    } else if (rb) {
	      s.push(d3_interpolateTransformPop(s) + "rotate(" + rb + ")");
	    }
	  }
	  function d3_interpolateSkew(wa, wb, s, q) {
	    if (wa !== wb) {
	      q.push({
	        i: s.push(d3_interpolateTransformPop(s) + "skewX(", null, ")") - 2,
	        x: d3_interpolateNumber(wa, wb)
	      });
	    } else if (wb) {
	      s.push(d3_interpolateTransformPop(s) + "skewX(" + wb + ")");
	    }
	  }
	  function d3_interpolateScale(ka, kb, s, q) {
	    if (ka[0] !== kb[0] || ka[1] !== kb[1]) {
	      var i = s.push(d3_interpolateTransformPop(s) + "scale(", null, ",", null, ")");
	      q.push({
	        i: i - 4,
	        x: d3_interpolateNumber(ka[0], kb[0])
	      }, {
	        i: i - 2,
	        x: d3_interpolateNumber(ka[1], kb[1])
	      });
	    } else if (kb[0] !== 1 || kb[1] !== 1) {
	      s.push(d3_interpolateTransformPop(s) + "scale(" + kb + ")");
	    }
	  }
	  function d3_interpolateTransform(a, b) {
	    var s = [], q = [];
	    a = d3.transform(a), b = d3.transform(b);
	    d3_interpolateTranslate(a.translate, b.translate, s, q);
	    d3_interpolateRotate(a.rotate, b.rotate, s, q);
	    d3_interpolateSkew(a.skew, b.skew, s, q);
	    d3_interpolateScale(a.scale, b.scale, s, q);
	    a = b = null;
	    return function(t) {
	      var i = -1, n = q.length, o;
	      while (++i < n) s[(o = q[i]).i] = o.x(t);
	      return s.join("");
	    };
	  }
	  function d3_uninterpolateNumber(a, b) {
	    b = (b -= a = +a) || 1 / b;
	    return function(x) {
	      return (x - a) / b;
	    };
	  }
	  function d3_uninterpolateClamp(a, b) {
	    b = (b -= a = +a) || 1 / b;
	    return function(x) {
	      return Math.max(0, Math.min(1, (x - a) / b));
	    };
	  }
	  d3.layout = {};
	  d3.layout.bundle = function() {
	    return function(links) {
	      var paths = [], i = -1, n = links.length;
	      while (++i < n) paths.push(d3_layout_bundlePath(links[i]));
	      return paths;
	    };
	  };
	  function d3_layout_bundlePath(link) {
	    var start = link.source, end = link.target, lca = d3_layout_bundleLeastCommonAncestor(start, end), points = [ start ];
	    while (start !== lca) {
	      start = start.parent;
	      points.push(start);
	    }
	    var k = points.length;
	    while (end !== lca) {
	      points.splice(k, 0, end);
	      end = end.parent;
	    }
	    return points;
	  }
	  function d3_layout_bundleAncestors(node) {
	    var ancestors = [], parent = node.parent;
	    while (parent != null) {
	      ancestors.push(node);
	      node = parent;
	      parent = parent.parent;
	    }
	    ancestors.push(node);
	    return ancestors;
	  }
	  function d3_layout_bundleLeastCommonAncestor(a, b) {
	    if (a === b) return a;
	    var aNodes = d3_layout_bundleAncestors(a), bNodes = d3_layout_bundleAncestors(b), aNode = aNodes.pop(), bNode = bNodes.pop(), sharedNode = null;
	    while (aNode === bNode) {
	      sharedNode = aNode;
	      aNode = aNodes.pop();
	      bNode = bNodes.pop();
	    }
	    return sharedNode;
	  }
	  d3.layout.chord = function() {
	    var chord = {}, chords, groups, matrix, n, padding = 0, sortGroups, sortSubgroups, sortChords;
	    function relayout() {
	      var subgroups = {}, groupSums = [], groupIndex = d3.range(n), subgroupIndex = [], k, x, x0, i, j;
	      chords = [];
	      groups = [];
	      k = 0, i = -1;
	      while (++i < n) {
	        x = 0, j = -1;
	        while (++j < n) {
	          x += matrix[i][j];
	        }
	        groupSums.push(x);
	        subgroupIndex.push(d3.range(n));
	        k += x;
	      }
	      if (sortGroups) {
	        groupIndex.sort(function(a, b) {
	          return sortGroups(groupSums[a], groupSums[b]);
	        });
	      }
	      if (sortSubgroups) {
	        subgroupIndex.forEach(function(d, i) {
	          d.sort(function(a, b) {
	            return sortSubgroups(matrix[i][a], matrix[i][b]);
	          });
	        });
	      }
	      k = (τ - padding * n) / k;
	      x = 0, i = -1;
	      while (++i < n) {
	        x0 = x, j = -1;
	        while (++j < n) {
	          var di = groupIndex[i], dj = subgroupIndex[di][j], v = matrix[di][dj], a0 = x, a1 = x += v * k;
	          subgroups[di + "-" + dj] = {
	            index: di,
	            subindex: dj,
	            startAngle: a0,
	            endAngle: a1,
	            value: v
	          };
	        }
	        groups[di] = {
	          index: di,
	          startAngle: x0,
	          endAngle: x,
	          value: groupSums[di]
	        };
	        x += padding;
	      }
	      i = -1;
	      while (++i < n) {
	        j = i - 1;
	        while (++j < n) {
	          var source = subgroups[i + "-" + j], target = subgroups[j + "-" + i];
	          if (source.value || target.value) {
	            chords.push(source.value < target.value ? {
	              source: target,
	              target: source
	            } : {
	              source: source,
	              target: target
	            });
	          }
	        }
	      }
	      if (sortChords) resort();
	    }
	    function resort() {
	      chords.sort(function(a, b) {
	        return sortChords((a.source.value + a.target.value) / 2, (b.source.value + b.target.value) / 2);
	      });
	    }
	    chord.matrix = function(x) {
	      if (!arguments.length) return matrix;
	      n = (matrix = x) && matrix.length;
	      chords = groups = null;
	      return chord;
	    };
	    chord.padding = function(x) {
	      if (!arguments.length) return padding;
	      padding = x;
	      chords = groups = null;
	      return chord;
	    };
	    chord.sortGroups = function(x) {
	      if (!arguments.length) return sortGroups;
	      sortGroups = x;
	      chords = groups = null;
	      return chord;
	    };
	    chord.sortSubgroups = function(x) {
	      if (!arguments.length) return sortSubgroups;
	      sortSubgroups = x;
	      chords = null;
	      return chord;
	    };
	    chord.sortChords = function(x) {
	      if (!arguments.length) return sortChords;
	      sortChords = x;
	      if (chords) resort();
	      return chord;
	    };
	    chord.chords = function() {
	      if (!chords) relayout();
	      return chords;
	    };
	    chord.groups = function() {
	      if (!groups) relayout();
	      return groups;
	    };
	    return chord;
	  };
	  d3.layout.force = function() {
	    var force = {}, event = d3.dispatch("start", "tick", "end"), timer, size = [ 1, 1 ], drag, alpha, friction = .9, linkDistance = d3_layout_forceLinkDistance, linkStrength = d3_layout_forceLinkStrength, charge = -30, chargeDistance2 = d3_layout_forceChargeDistance2, gravity = .1, theta2 = .64, nodes = [], links = [], distances, strengths, charges;
	    function repulse(node) {
	      return function(quad, x1, _, x2) {
	        if (quad.point !== node) {
	          var dx = quad.cx - node.x, dy = quad.cy - node.y, dw = x2 - x1, dn = dx * dx + dy * dy;
	          if (dw * dw / theta2 < dn) {
	            if (dn < chargeDistance2) {
	              var k = quad.charge / dn;
	              node.px -= dx * k;
	              node.py -= dy * k;
	            }
	            return true;
	          }
	          if (quad.point && dn && dn < chargeDistance2) {
	            var k = quad.pointCharge / dn;
	            node.px -= dx * k;
	            node.py -= dy * k;
	          }
	        }
	        return !quad.charge;
	      };
	    }
	    force.tick = function() {
	      if ((alpha *= .99) < .005) {
	        timer = null;
	        event.end({
	          type: "end",
	          alpha: alpha = 0
	        });
	        return true;
	      }
	      var n = nodes.length, m = links.length, q, i, o, s, t, l, k, x, y;
	      for (i = 0; i < m; ++i) {
	        o = links[i];
	        s = o.source;
	        t = o.target;
	        x = t.x - s.x;
	        y = t.y - s.y;
	        if (l = x * x + y * y) {
	          l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l;
	          x *= l;
	          y *= l;
	          t.x -= x * (k = s.weight + t.weight ? s.weight / (s.weight + t.weight) : .5);
	          t.y -= y * k;
	          s.x += x * (k = 1 - k);
	          s.y += y * k;
	        }
	      }
	      if (k = alpha * gravity) {
	        x = size[0] / 2;
	        y = size[1] / 2;
	        i = -1;
	        if (k) while (++i < n) {
	          o = nodes[i];
	          o.x += (x - o.x) * k;
	          o.y += (y - o.y) * k;
	        }
	      }
	      if (charge) {
	        d3_layout_forceAccumulate(q = d3.geom.quadtree(nodes), alpha, charges);
	        i = -1;
	        while (++i < n) {
	          if (!(o = nodes[i]).fixed) {
	            q.visit(repulse(o));
	          }
	        }
	      }
	      i = -1;
	      while (++i < n) {
	        o = nodes[i];
	        if (o.fixed) {
	          o.x = o.px;
	          o.y = o.py;
	        } else {
	          o.x -= (o.px - (o.px = o.x)) * friction;
	          o.y -= (o.py - (o.py = o.y)) * friction;
	        }
	      }
	      event.tick({
	        type: "tick",
	        alpha: alpha
	      });
	    };
	    force.nodes = function(x) {
	      if (!arguments.length) return nodes;
	      nodes = x;
	      return force;
	    };
	    force.links = function(x) {
	      if (!arguments.length) return links;
	      links = x;
	      return force;
	    };
	    force.size = function(x) {
	      if (!arguments.length) return size;
	      size = x;
	      return force;
	    };
	    force.linkDistance = function(x) {
	      if (!arguments.length) return linkDistance;
	      linkDistance = typeof x === "function" ? x : +x;
	      return force;
	    };
	    force.distance = force.linkDistance;
	    force.linkStrength = function(x) {
	      if (!arguments.length) return linkStrength;
	      linkStrength = typeof x === "function" ? x : +x;
	      return force;
	    };
	    force.friction = function(x) {
	      if (!arguments.length) return friction;
	      friction = +x;
	      return force;
	    };
	    force.charge = function(x) {
	      if (!arguments.length) return charge;
	      charge = typeof x === "function" ? x : +x;
	      return force;
	    };
	    force.chargeDistance = function(x) {
	      if (!arguments.length) return Math.sqrt(chargeDistance2);
	      chargeDistance2 = x * x;
	      return force;
	    };
	    force.gravity = function(x) {
	      if (!arguments.length) return gravity;
	      gravity = +x;
	      return force;
	    };
	    force.theta = function(x) {
	      if (!arguments.length) return Math.sqrt(theta2);
	      theta2 = x * x;
	      return force;
	    };
	    force.alpha = function(x) {
	      if (!arguments.length) return alpha;
	      x = +x;
	      if (alpha) {
	        if (x > 0) {
	          alpha = x;
	        } else {
	          timer.c = null, timer.t = NaN, timer = null;
	          event.end({
	            type: "end",
	            alpha: alpha = 0
	          });
	        }
	      } else if (x > 0) {
	        event.start({
	          type: "start",
	          alpha: alpha = x
	        });
	        timer = d3_timer(force.tick);
	      }
	      return force;
	    };
	    force.start = function() {
	      var i, n = nodes.length, m = links.length, w = size[0], h = size[1], neighbors, o;
	      for (i = 0; i < n; ++i) {
	        (o = nodes[i]).index = i;
	        o.weight = 0;
	      }
	      for (i = 0; i < m; ++i) {
	        o = links[i];
	        if (typeof o.source == "number") o.source = nodes[o.source];
	        if (typeof o.target == "number") o.target = nodes[o.target];
	        ++o.source.weight;
	        ++o.target.weight;
	      }
	      for (i = 0; i < n; ++i) {
	        o = nodes[i];
	        if (isNaN(o.x)) o.x = position("x", w);
	        if (isNaN(o.y)) o.y = position("y", h);
	        if (isNaN(o.px)) o.px = o.x;
	        if (isNaN(o.py)) o.py = o.y;
	      }
	      distances = [];
	      if (typeof linkDistance === "function") for (i = 0; i < m; ++i) distances[i] = +linkDistance.call(this, links[i], i); else for (i = 0; i < m; ++i) distances[i] = linkDistance;
	      strengths = [];
	      if (typeof linkStrength === "function") for (i = 0; i < m; ++i) strengths[i] = +linkStrength.call(this, links[i], i); else for (i = 0; i < m; ++i) strengths[i] = linkStrength;
	      charges = [];
	      if (typeof charge === "function") for (i = 0; i < n; ++i) charges[i] = +charge.call(this, nodes[i], i); else for (i = 0; i < n; ++i) charges[i] = charge;
	      function position(dimension, size) {
	        if (!neighbors) {
	          neighbors = new Array(n);
	          for (j = 0; j < n; ++j) {
	            neighbors[j] = [];
	          }
	          for (j = 0; j < m; ++j) {
	            var o = links[j];
	            neighbors[o.source.index].push(o.target);
	            neighbors[o.target.index].push(o.source);
	          }
	        }
	        var candidates = neighbors[i], j = -1, l = candidates.length, x;
	        while (++j < l) if (!isNaN(x = candidates[j][dimension])) return x;
	        return Math.random() * size;
	      }
	      return force.resume();
	    };
	    force.resume = function() {
	      return force.alpha(.1);
	    };
	    force.stop = function() {
	      return force.alpha(0);
	    };
	    force.drag = function() {
	      if (!drag) drag = d3.behavior.drag().origin(d3_identity).on("dragstart.force", d3_layout_forceDragstart).on("drag.force", dragmove).on("dragend.force", d3_layout_forceDragend);
	      if (!arguments.length) return drag;
	      this.on("mouseover.force", d3_layout_forceMouseover).on("mouseout.force", d3_layout_forceMouseout).call(drag);
	    };
	    function dragmove(d) {
	      d.px = d3.event.x, d.py = d3.event.y;
	      force.resume();
	    }
	    return d3.rebind(force, event, "on");
	  };
	  function d3_layout_forceDragstart(d) {
	    d.fixed |= 2;
	  }
	  function d3_layout_forceDragend(d) {
	    d.fixed &= ~6;
	  }
	  function d3_layout_forceMouseover(d) {
	    d.fixed |= 4;
	    d.px = d.x, d.py = d.y;
	  }
	  function d3_layout_forceMouseout(d) {
	    d.fixed &= ~4;
	  }
	  function d3_layout_forceAccumulate(quad, alpha, charges) {
	    var cx = 0, cy = 0;
	    quad.charge = 0;
	    if (!quad.leaf) {
	      var nodes = quad.nodes, n = nodes.length, i = -1, c;
	      while (++i < n) {
	        c = nodes[i];
	        if (c == null) continue;
	        d3_layout_forceAccumulate(c, alpha, charges);
	        quad.charge += c.charge;
	        cx += c.charge * c.cx;
	        cy += c.charge * c.cy;
	      }
	    }
	    if (quad.point) {
	      if (!quad.leaf) {
	        quad.point.x += Math.random() - .5;
	        quad.point.y += Math.random() - .5;
	      }
	      var k = alpha * charges[quad.point.index];
	      quad.charge += quad.pointCharge = k;
	      cx += k * quad.point.x;
	      cy += k * quad.point.y;
	    }
	    quad.cx = cx / quad.charge;
	    quad.cy = cy / quad.charge;
	  }
	  var d3_layout_forceLinkDistance = 20, d3_layout_forceLinkStrength = 1, d3_layout_forceChargeDistance2 = Infinity;
	  d3.layout.hierarchy = function() {
	    var sort = d3_layout_hierarchySort, children = d3_layout_hierarchyChildren, value = d3_layout_hierarchyValue;
	    function hierarchy(root) {
	      var stack = [ root ], nodes = [], node;
	      root.depth = 0;
	      while ((node = stack.pop()) != null) {
	        nodes.push(node);
	        if ((childs = children.call(hierarchy, node, node.depth)) && (n = childs.length)) {
	          var n, childs, child;
	          while (--n >= 0) {
	            stack.push(child = childs[n]);
	            child.parent = node;
	            child.depth = node.depth + 1;
	          }
	          if (value) node.value = 0;
	          node.children = childs;
	        } else {
	          if (value) node.value = +value.call(hierarchy, node, node.depth) || 0;
	          delete node.children;
	        }
	      }
	      d3_layout_hierarchyVisitAfter(root, function(node) {
	        var childs, parent;
	        if (sort && (childs = node.children)) childs.sort(sort);
	        if (value && (parent = node.parent)) parent.value += node.value;
	      });
	      return nodes;
	    }
	    hierarchy.sort = function(x) {
	      if (!arguments.length) return sort;
	      sort = x;
	      return hierarchy;
	    };
	    hierarchy.children = function(x) {
	      if (!arguments.length) return children;
	      children = x;
	      return hierarchy;
	    };
	    hierarchy.value = function(x) {
	      if (!arguments.length) return value;
	      value = x;
	      return hierarchy;
	    };
	    hierarchy.revalue = function(root) {
	      if (value) {
	        d3_layout_hierarchyVisitBefore(root, function(node) {
	          if (node.children) node.value = 0;
	        });
	        d3_layout_hierarchyVisitAfter(root, function(node) {
	          var parent;
	          if (!node.children) node.value = +value.call(hierarchy, node, node.depth) || 0;
	          if (parent = node.parent) parent.value += node.value;
	        });
	      }
	      return root;
	    };
	    return hierarchy;
	  };
	  function d3_layout_hierarchyRebind(object, hierarchy) {
	    d3.rebind(object, hierarchy, "sort", "children", "value");
	    object.nodes = object;
	    object.links = d3_layout_hierarchyLinks;
	    return object;
	  }
	  function d3_layout_hierarchyVisitBefore(node, callback) {
	    var nodes = [ node ];
	    while ((node = nodes.pop()) != null) {
	      callback(node);
	      if ((children = node.children) && (n = children.length)) {
	        var n, children;
	        while (--n >= 0) nodes.push(children[n]);
	      }
	    }
	  }
	  function d3_layout_hierarchyVisitAfter(node, callback) {
	    var nodes = [ node ], nodes2 = [];
	    while ((node = nodes.pop()) != null) {
	      nodes2.push(node);
	      if ((children = node.children) && (n = children.length)) {
	        var i = -1, n, children;
	        while (++i < n) nodes.push(children[i]);
	      }
	    }
	    while ((node = nodes2.pop()) != null) {
	      callback(node);
	    }
	  }
	  function d3_layout_hierarchyChildren(d) {
	    return d.children;
	  }
	  function d3_layout_hierarchyValue(d) {
	    return d.value;
	  }
	  function d3_layout_hierarchySort(a, b) {
	    return b.value - a.value;
	  }
	  function d3_layout_hierarchyLinks(nodes) {
	    return d3.merge(nodes.map(function(parent) {
	      return (parent.children || []).map(function(child) {
	        return {
	          source: parent,
	          target: child
	        };
	      });
	    }));
	  }
	  d3.layout.partition = function() {
	    var hierarchy = d3.layout.hierarchy(), size = [ 1, 1 ];
	    function position(node, x, dx, dy) {
	      var children = node.children;
	      node.x = x;
	      node.y = node.depth * dy;
	      node.dx = dx;
	      node.dy = dy;
	      if (children && (n = children.length)) {
	        var i = -1, n, c, d;
	        dx = node.value ? dx / node.value : 0;
	        while (++i < n) {
	          position(c = children[i], x, d = c.value * dx, dy);
	          x += d;
	        }
	      }
	    }
	    function depth(node) {
	      var children = node.children, d = 0;
	      if (children && (n = children.length)) {
	        var i = -1, n;
	        while (++i < n) d = Math.max(d, depth(children[i]));
	      }
	      return 1 + d;
	    }
	    function partition(d, i) {
	      var nodes = hierarchy.call(this, d, i);
	      position(nodes[0], 0, size[0], size[1] / depth(nodes[0]));
	      return nodes;
	    }
	    partition.size = function(x) {
	      if (!arguments.length) return size;
	      size = x;
	      return partition;
	    };
	    return d3_layout_hierarchyRebind(partition, hierarchy);
	  };
	  d3.layout.pie = function() {
	    var value = Number, sort = d3_layout_pieSortByValue, startAngle = 0, endAngle = τ, padAngle = 0;
	    function pie(data) {
	      var n = data.length, values = data.map(function(d, i) {
	        return +value.call(pie, d, i);
	      }), a = +(typeof startAngle === "function" ? startAngle.apply(this, arguments) : startAngle), da = (typeof endAngle === "function" ? endAngle.apply(this, arguments) : endAngle) - a, p = Math.min(Math.abs(da) / n, +(typeof padAngle === "function" ? padAngle.apply(this, arguments) : padAngle)), pa = p * (da < 0 ? -1 : 1), sum = d3.sum(values), k = sum ? (da - n * pa) / sum : 0, index = d3.range(n), arcs = [], v;
	      if (sort != null) index.sort(sort === d3_layout_pieSortByValue ? function(i, j) {
	        return values[j] - values[i];
	      } : function(i, j) {
	        return sort(data[i], data[j]);
	      });
	      index.forEach(function(i) {
	        arcs[i] = {
	          data: data[i],
	          value: v = values[i],
	          startAngle: a,
	          endAngle: a += v * k + pa,
	          padAngle: p
	        };
	      });
	      return arcs;
	    }
	    pie.value = function(_) {
	      if (!arguments.length) return value;
	      value = _;
	      return pie;
	    };
	    pie.sort = function(_) {
	      if (!arguments.length) return sort;
	      sort = _;
	      return pie;
	    };
	    pie.startAngle = function(_) {
	      if (!arguments.length) return startAngle;
	      startAngle = _;
	      return pie;
	    };
	    pie.endAngle = function(_) {
	      if (!arguments.length) return endAngle;
	      endAngle = _;
	      return pie;
	    };
	    pie.padAngle = function(_) {
	      if (!arguments.length) return padAngle;
	      padAngle = _;
	      return pie;
	    };
	    return pie;
	  };
	  var d3_layout_pieSortByValue = {};
	  d3.layout.stack = function() {
	    var values = d3_identity, order = d3_layout_stackOrderDefault, offset = d3_layout_stackOffsetZero, out = d3_layout_stackOut, x = d3_layout_stackX, y = d3_layout_stackY;
	    function stack(data, index) {
	      if (!(n = data.length)) return data;
	      var series = data.map(function(d, i) {
	        return values.call(stack, d, i);
	      });
	      var points = series.map(function(d) {
	        return d.map(function(v, i) {
	          return [ x.call(stack, v, i), y.call(stack, v, i) ];
	        });
	      });
	      var orders = order.call(stack, points, index);
	      series = d3.permute(series, orders);
	      points = d3.permute(points, orders);
	      var offsets = offset.call(stack, points, index);
	      var m = series[0].length, n, i, j, o;
	      for (j = 0; j < m; ++j) {
	        out.call(stack, series[0][j], o = offsets[j], points[0][j][1]);
	        for (i = 1; i < n; ++i) {
	          out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]);
	        }
	      }
	      return data;
	    }
	    stack.values = function(x) {
	      if (!arguments.length) return values;
	      values = x;
	      return stack;
	    };
	    stack.order = function(x) {
	      if (!arguments.length) return order;
	      order = typeof x === "function" ? x : d3_layout_stackOrders.get(x) || d3_layout_stackOrderDefault;
	      return stack;
	    };
	    stack.offset = function(x) {
	      if (!arguments.length) return offset;
	      offset = typeof x === "function" ? x : d3_layout_stackOffsets.get(x) || d3_layout_stackOffsetZero;
	      return stack;
	    };
	    stack.x = function(z) {
	      if (!arguments.length) return x;
	      x = z;
	      return stack;
	    };
	    stack.y = function(z) {
	      if (!arguments.length) return y;
	      y = z;
	      return stack;
	    };
	    stack.out = function(z) {
	      if (!arguments.length) return out;
	      out = z;
	      return stack;
	    };
	    return stack;
	  };
	  function d3_layout_stackX(d) {
	    return d.x;
	  }
	  function d3_layout_stackY(d) {
	    return d.y;
	  }
	  function d3_layout_stackOut(d, y0, y) {
	    d.y0 = y0;
	    d.y = y;
	  }
	  var d3_layout_stackOrders = d3.map({
	    "inside-out": function(data) {
	      var n = data.length, i, j, max = data.map(d3_layout_stackMaxIndex), sums = data.map(d3_layout_stackReduceSum), index = d3.range(n).sort(function(a, b) {
	        return max[a] - max[b];
	      }), top = 0, bottom = 0, tops = [], bottoms = [];
	      for (i = 0; i < n; ++i) {
	        j = index[i];
	        if (top < bottom) {
	          top += sums[j];
	          tops.push(j);
	        } else {
	          bottom += sums[j];
	          bottoms.push(j);
	        }
	      }
	      return bottoms.reverse().concat(tops);
	    },
	    reverse: function(data) {
	      return d3.range(data.length).reverse();
	    },
	    "default": d3_layout_stackOrderDefault
	  });
	  var d3_layout_stackOffsets = d3.map({
	    silhouette: function(data) {
	      var n = data.length, m = data[0].length, sums = [], max = 0, i, j, o, y0 = [];
	      for (j = 0; j < m; ++j) {
	        for (i = 0, o = 0; i < n; i++) o += data[i][j][1];
	        if (o > max) max = o;
	        sums.push(o);
	      }
	      for (j = 0; j < m; ++j) {
	        y0[j] = (max - sums[j]) / 2;
	      }
	      return y0;
	    },
	    wiggle: function(data) {
	      var n = data.length, x = data[0], m = x.length, i, j, k, s1, s2, s3, dx, o, o0, y0 = [];
	      y0[0] = o = o0 = 0;
	      for (j = 1; j < m; ++j) {
	        for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1];
	        for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) {
	          for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) {
	            s3 += (data[k][j][1] - data[k][j - 1][1]) / dx;
	          }
	          s2 += s3 * data[i][j][1];
	        }
	        y0[j] = o -= s1 ? s2 / s1 * dx : 0;
	        if (o < o0) o0 = o;
	      }
	      for (j = 0; j < m; ++j) y0[j] -= o0;
	      return y0;
	    },
	    expand: function(data) {
	      var n = data.length, m = data[0].length, k = 1 / n, i, j, o, y0 = [];
	      for (j = 0; j < m; ++j) {
	        for (i = 0, o = 0; i < n; i++) o += data[i][j][1];
	        if (o) for (i = 0; i < n; i++) data[i][j][1] /= o; else for (i = 0; i < n; i++) data[i][j][1] = k;
	      }
	      for (j = 0; j < m; ++j) y0[j] = 0;
	      return y0;
	    },
	    zero: d3_layout_stackOffsetZero
	  });
	  function d3_layout_stackOrderDefault(data) {
	    return d3.range(data.length);
	  }
	  function d3_layout_stackOffsetZero(data) {
	    var j = -1, m = data[0].length, y0 = [];
	    while (++j < m) y0[j] = 0;
	    return y0;
	  }
	  function d3_layout_stackMaxIndex(array) {
	    var i = 1, j = 0, v = array[0][1], k, n = array.length;
	    for (;i < n; ++i) {
	      if ((k = array[i][1]) > v) {
	        j = i;
	        v = k;
	      }
	    }
	    return j;
	  }
	  function d3_layout_stackReduceSum(d) {
	    return d.reduce(d3_layout_stackSum, 0);
	  }
	  function d3_layout_stackSum(p, d) {
	    return p + d[1];
	  }
	  d3.layout.histogram = function() {
	    var frequency = true, valuer = Number, ranger = d3_layout_histogramRange, binner = d3_layout_histogramBinSturges;
	    function histogram(data, i) {
	      var bins = [], values = data.map(valuer, this), range = ranger.call(this, values, i), thresholds = binner.call(this, range, values, i), bin, i = -1, n = values.length, m = thresholds.length - 1, k = frequency ? 1 : 1 / n, x;
	      while (++i < m) {
	        bin = bins[i] = [];
	        bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]);
	        bin.y = 0;
	      }
	      if (m > 0) {
	        i = -1;
	        while (++i < n) {
	          x = values[i];
	          if (x >= range[0] && x <= range[1]) {
	            bin = bins[d3.bisect(thresholds, x, 1, m) - 1];
	            bin.y += k;
	            bin.push(data[i]);
	          }
	        }
	      }
	      return bins;
	    }
	    histogram.value = function(x) {
	      if (!arguments.length) return valuer;
	      valuer = x;
	      return histogram;
	    };
	    histogram.range = function(x) {
	      if (!arguments.length) return ranger;
	      ranger = d3_functor(x);
	      return histogram;
	    };
	    histogram.bins = function(x) {
	      if (!arguments.length) return binner;
	      binner = typeof x === "number" ? function(range) {
	        return d3_layout_histogramBinFixed(range, x);
	      } : d3_functor(x);
	      return histogram;
	    };
	    histogram.frequency = function(x) {
	      if (!arguments.length) return frequency;
	      frequency = !!x;
	      return histogram;
	    };
	    return histogram;
	  };
	  function d3_layout_histogramBinSturges(range, values) {
	    return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1));
	  }
	  function d3_layout_histogramBinFixed(range, n) {
	    var x = -1, b = +range[0], m = (range[1] - b) / n, f = [];
	    while (++x <= n) f[x] = m * x + b;
	    return f;
	  }
	  function d3_layout_histogramRange(values) {
	    return [ d3.min(values), d3.max(values) ];
	  }
	  d3.layout.pack = function() {
	    var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), padding = 0, size = [ 1, 1 ], radius;
	    function pack(d, i) {
	      var nodes = hierarchy.call(this, d, i), root = nodes[0], w = size[0], h = size[1], r = radius == null ? Math.sqrt : typeof radius === "function" ? radius : function() {
	        return radius;
	      };
	      root.x = root.y = 0;
	      d3_layout_hierarchyVisitAfter(root, function(d) {
	        d.r = +r(d.value);
	      });
	      d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings);
	      if (padding) {
	        var dr = padding * (radius ? 1 : Math.max(2 * root.r / w, 2 * root.r / h)) / 2;
	        d3_layout_hierarchyVisitAfter(root, function(d) {
	          d.r += dr;
	        });
	        d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings);
	        d3_layout_hierarchyVisitAfter(root, function(d) {
	          d.r -= dr;
	        });
	      }
	      d3_layout_packTransform(root, w / 2, h / 2, radius ? 1 : 1 / Math.max(2 * root.r / w, 2 * root.r / h));
	      return nodes;
	    }
	    pack.size = function(_) {
	      if (!arguments.length) return size;
	      size = _;
	      return pack;
	    };
	    pack.radius = function(_) {
	      if (!arguments.length) return radius;
	      radius = _ == null || typeof _ === "function" ? _ : +_;
	      return pack;
	    };
	    pack.padding = function(_) {
	      if (!arguments.length) return padding;
	      padding = +_;
	      return pack;
	    };
	    return d3_layout_hierarchyRebind(pack, hierarchy);
	  };
	  function d3_layout_packSort(a, b) {
	    return a.value - b.value;
	  }
	  function d3_layout_packInsert(a, b) {
	    var c = a._pack_next;
	    a._pack_next = b;
	    b._pack_prev = a;
	    b._pack_next = c;
	    c._pack_prev = b;
	  }
	  function d3_layout_packSplice(a, b) {
	    a._pack_next = b;
	    b._pack_prev = a;
	  }
	  function d3_layout_packIntersects(a, b) {
	    var dx = b.x - a.x, dy = b.y - a.y, dr = a.r + b.r;
	    return .999 * dr * dr > dx * dx + dy * dy;
	  }
	  function d3_layout_packSiblings(node) {
	    if (!(nodes = node.children) || !(n = nodes.length)) return;
	    var nodes, xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, a, b, c, i, j, k, n;
	    function bound(node) {
	      xMin = Math.min(node.x - node.r, xMin);
	      xMax = Math.max(node.x + node.r, xMax);
	      yMin = Math.min(node.y - node.r, yMin);
	      yMax = Math.max(node.y + node.r, yMax);
	    }
	    nodes.forEach(d3_layout_packLink);
	    a = nodes[0];
	    a.x = -a.r;
	    a.y = 0;
	    bound(a);
	    if (n > 1) {
	      b = nodes[1];
	      b.x = b.r;
	      b.y = 0;
	      bound(b);
	      if (n > 2) {
	        c = nodes[2];
	        d3_layout_packPlace(a, b, c);
	        bound(c);
	        d3_layout_packInsert(a, c);
	        a._pack_prev = c;
	        d3_layout_packInsert(c, b);
	        b = a._pack_next;
	        for (i = 3; i < n; i++) {
	          d3_layout_packPlace(a, b, c = nodes[i]);
	          var isect = 0, s1 = 1, s2 = 1;
	          for (j = b._pack_next; j !== b; j = j._pack_next, s1++) {
	            if (d3_layout_packIntersects(j, c)) {
	              isect = 1;
	              break;
	            }
	          }
	          if (isect == 1) {
	            for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) {
	              if (d3_layout_packIntersects(k, c)) {
	                break;
	              }
	            }
	          }
	          if (isect) {
	            if (s1 < s2 || s1 == s2 && b.r < a.r) d3_layout_packSplice(a, b = j); else d3_layout_packSplice(a = k, b);
	            i--;
	          } else {
	            d3_layout_packInsert(a, c);
	            b = c;
	            bound(c);
	          }
	        }
	      }
	    }
	    var cx = (xMin + xMax) / 2, cy = (yMin + yMax) / 2, cr = 0;
	    for (i = 0; i < n; i++) {
	      c = nodes[i];
	      c.x -= cx;
	      c.y -= cy;
	      cr = Math.max(cr, c.r + Math.sqrt(c.x * c.x + c.y * c.y));
	    }
	    node.r = cr;
	    nodes.forEach(d3_layout_packUnlink);
	  }
	  function d3_layout_packLink(node) {
	    node._pack_next = node._pack_prev = node;
	  }
	  function d3_layout_packUnlink(node) {
	    delete node._pack_next;
	    delete node._pack_prev;
	  }
	  function d3_layout_packTransform(node, x, y, k) {
	    var children = node.children;
	    node.x = x += k * node.x;
	    node.y = y += k * node.y;
	    node.r *= k;
	    if (children) {
	      var i = -1, n = children.length;
	      while (++i < n) d3_layout_packTransform(children[i], x, y, k);
	    }
	  }
	  function d3_layout_packPlace(a, b, c) {
	    var db = a.r + c.r, dx = b.x - a.x, dy = b.y - a.y;
	    if (db && (dx || dy)) {
	      var da = b.r + c.r, dc = dx * dx + dy * dy;
	      da *= da;
	      db *= db;
	      var x = .5 + (db - da) / (2 * dc), y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc);
	      c.x = a.x + x * dx + y * dy;
	      c.y = a.y + x * dy - y * dx;
	    } else {
	      c.x = a.x + db;
	      c.y = a.y;
	    }
	  }
	  d3.layout.tree = function() {
	    var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = null;
	    function tree(d, i) {
	      var nodes = hierarchy.call(this, d, i), root0 = nodes[0], root1 = wrapTree(root0);
	      d3_layout_hierarchyVisitAfter(root1, firstWalk), root1.parent.m = -root1.z;
	      d3_layout_hierarchyVisitBefore(root1, secondWalk);
	      if (nodeSize) d3_layout_hierarchyVisitBefore(root0, sizeNode); else {
	        var left = root0, right = root0, bottom = root0;
	        d3_layout_hierarchyVisitBefore(root0, function(node) {
	          if (node.x < left.x) left = node;
	          if (node.x > right.x) right = node;
	          if (node.depth > bottom.depth) bottom = node;
	        });
	        var tx = separation(left, right) / 2 - left.x, kx = size[0] / (right.x + separation(right, left) / 2 + tx), ky = size[1] / (bottom.depth || 1);
	        d3_layout_hierarchyVisitBefore(root0, function(node) {
	          node.x = (node.x + tx) * kx;
	          node.y = node.depth * ky;
	        });
	      }
	      return nodes;
	    }
	    function wrapTree(root0) {
	      var root1 = {
	        A: null,
	        children: [ root0 ]
	      }, queue = [ root1 ], node1;
	      while ((node1 = queue.pop()) != null) {
	        for (var children = node1.children, child, i = 0, n = children.length; i < n; ++i) {
	          queue.push((children[i] = child = {
	            _: children[i],
	            parent: node1,
	            children: (child = children[i].children) && child.slice() || [],
	            A: null,
	            a: null,
	            z: 0,
	            m: 0,
	            c: 0,
	            s: 0,
	            t: null,
	            i: i
	          }).a = child);
	        }
	      }
	      return root1.children[0];
	    }
	    function firstWalk(v) {
	      var children = v.children, siblings = v.parent.children, w = v.i ? siblings[v.i - 1] : null;
	      if (children.length) {
	        d3_layout_treeShift(v);
	        var midpoint = (children[0].z + children[children.length - 1].z) / 2;
	        if (w) {
	          v.z = w.z + separation(v._, w._);
	          v.m = v.z - midpoint;
	        } else {
	          v.z = midpoint;
	        }
	      } else if (w) {
	        v.z = w.z + separation(v._, w._);
	      }
	      v.parent.A = apportion(v, w, v.parent.A || siblings[0]);
	    }
	    function secondWalk(v) {
	      v._.x = v.z + v.parent.m;
	      v.m += v.parent.m;
	    }
	    function apportion(v, w, ancestor) {
	      if (w) {
	        var vip = v, vop = v, vim = w, vom = vip.parent.children[0], sip = vip.m, sop = vop.m, sim = vim.m, som = vom.m, shift;
	        while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) {
	          vom = d3_layout_treeLeft(vom);
	          vop = d3_layout_treeRight(vop);
	          vop.a = v;
	          shift = vim.z + sim - vip.z - sip + separation(vim._, vip._);
	          if (shift > 0) {
	            d3_layout_treeMove(d3_layout_treeAncestor(vim, v, ancestor), v, shift);
	            sip += shift;
	            sop += shift;
	          }
	          sim += vim.m;
	          sip += vip.m;
	          som += vom.m;
	          sop += vop.m;
	        }
	        if (vim && !d3_layout_treeRight(vop)) {
	          vop.t = vim;
	          vop.m += sim - sop;
	        }
	        if (vip && !d3_layout_treeLeft(vom)) {
	          vom.t = vip;
	          vom.m += sip - som;
	          ancestor = v;
	        }
	      }
	      return ancestor;
	    }
	    function sizeNode(node) {
	      node.x *= size[0];
	      node.y = node.depth * size[1];
	    }
	    tree.separation = function(x) {
	      if (!arguments.length) return separation;
	      separation = x;
	      return tree;
	    };
	    tree.size = function(x) {
	      if (!arguments.length) return nodeSize ? null : size;
	      nodeSize = (size = x) == null ? sizeNode : null;
	      return tree;
	    };
	    tree.nodeSize = function(x) {
	      if (!arguments.length) return nodeSize ? size : null;
	      nodeSize = (size = x) == null ? null : sizeNode;
	      return tree;
	    };
	    return d3_layout_hierarchyRebind(tree, hierarchy);
	  };
	  function d3_layout_treeSeparation(a, b) {
	    return a.parent == b.parent ? 1 : 2;
	  }
	  function d3_layout_treeLeft(v) {
	    var children = v.children;
	    return children.length ? children[0] : v.t;
	  }
	  function d3_layout_treeRight(v) {
	    var children = v.children, n;
	    return (n = children.length) ? children[n - 1] : v.t;
	  }
	  function d3_layout_treeMove(wm, wp, shift) {
	    var change = shift / (wp.i - wm.i);
	    wp.c -= change;
	    wp.s += shift;
	    wm.c += change;
	    wp.z += shift;
	    wp.m += shift;
	  }
	  function d3_layout_treeShift(v) {
	    var shift = 0, change = 0, children = v.children, i = children.length, w;
	    while (--i >= 0) {
	      w = children[i];
	      w.z += shift;
	      w.m += shift;
	      shift += w.s + (change += w.c);
	    }
	  }
	  function d3_layout_treeAncestor(vim, v, ancestor) {
	    return vim.a.parent === v.parent ? vim.a : ancestor;
	  }
	  d3.layout.cluster = function() {
	    var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = false;
	    function cluster(d, i) {
	      var nodes = hierarchy.call(this, d, i), root = nodes[0], previousNode, x = 0;
	      d3_layout_hierarchyVisitAfter(root, function(node) {
	        var children = node.children;
	        if (children && children.length) {
	          node.x = d3_layout_clusterX(children);
	          node.y = d3_layout_clusterY(children);
	        } else {
	          node.x = previousNode ? x += separation(node, previousNode) : 0;
	          node.y = 0;
	          previousNode = node;
	        }
	      });
	      var left = d3_layout_clusterLeft(root), right = d3_layout_clusterRight(root), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2;
	      d3_layout_hierarchyVisitAfter(root, nodeSize ? function(node) {
	        node.x = (node.x - root.x) * size[0];
	        node.y = (root.y - node.y) * size[1];
	      } : function(node) {
	        node.x = (node.x - x0) / (x1 - x0) * size[0];
	        node.y = (1 - (root.y ? node.y / root.y : 1)) * size[1];
	      });
	      return nodes;
	    }
	    cluster.separation = function(x) {
	      if (!arguments.length) return separation;
	      separation = x;
	      return cluster;
	    };
	    cluster.size = function(x) {
	      if (!arguments.length) return nodeSize ? null : size;
	      nodeSize = (size = x) == null;
	      return cluster;
	    };
	    cluster.nodeSize = function(x) {
	      if (!arguments.length) return nodeSize ? size : null;
	      nodeSize = (size = x) != null;
	      return cluster;
	    };
	    return d3_layout_hierarchyRebind(cluster, hierarchy);
	  };
	  function d3_layout_clusterY(children) {
	    return 1 + d3.max(children, function(child) {
	      return child.y;
	    });
	  }
	  function d3_layout_clusterX(children) {
	    return children.reduce(function(x, child) {
	      return x + child.x;
	    }, 0) / children.length;
	  }
	  function d3_layout_clusterLeft(node) {
	    var children = node.children;
	    return children && children.length ? d3_layout_clusterLeft(children[0]) : node;
	  }
	  function d3_layout_clusterRight(node) {
	    var children = node.children, n;
	    return children && (n = children.length) ? d3_layout_clusterRight(children[n - 1]) : node;
	  }
	  d3.layout.treemap = function() {
	    var hierarchy = d3.layout.hierarchy(), round = Math.round, size = [ 1, 1 ], padding = null, pad = d3_layout_treemapPadNull, sticky = false, stickies, mode = "squarify", ratio = .5 * (1 + Math.sqrt(5));
	    function scale(children, k) {
	      var i = -1, n = children.length, child, area;
	      while (++i < n) {
	        area = (child = children[i]).value * (k < 0 ? 0 : k);
	        child.area = isNaN(area) || area <= 0 ? 0 : area;
	      }
	    }
	    function squarify(node) {
	      var children = node.children;
	      if (children && children.length) {
	        var rect = pad(node), row = [], remaining = children.slice(), child, best = Infinity, score, u = mode === "slice" ? rect.dx : mode === "dice" ? rect.dy : mode === "slice-dice" ? node.depth & 1 ? rect.dy : rect.dx : Math.min(rect.dx, rect.dy), n;
	        scale(remaining, rect.dx * rect.dy / node.value);
	        row.area = 0;
	        while ((n = remaining.length) > 0) {
	          row.push(child = remaining[n - 1]);
	          row.area += child.area;
	          if (mode !== "squarify" || (score = worst(row, u)) <= best) {
	            remaining.pop();
	            best = score;
	          } else {
	            row.area -= row.pop().area;
	            position(row, u, rect, false);
	            u = Math.min(rect.dx, rect.dy);
	            row.length = row.area = 0;
	            best = Infinity;
	          }
	        }
	        if (row.length) {
	          position(row, u, rect, true);
	          row.length = row.area = 0;
	        }
	        children.forEach(squarify);
	      }
	    }
	    function stickify(node) {
	      var children = node.children;
	      if (children && children.length) {
	        var rect = pad(node), remaining = children.slice(), child, row = [];
	        scale(remaining, rect.dx * rect.dy / node.value);
	        row.area = 0;
	        while (child = remaining.pop()) {
	          row.push(child);
	          row.area += child.area;
	          if (child.z != null) {
	            position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length);
	            row.length = row.area = 0;
	          }
	        }
	        children.forEach(stickify);
	      }
	    }
	    function worst(row, u) {
	      var s = row.area, r, rmax = 0, rmin = Infinity, i = -1, n = row.length;
	      while (++i < n) {
	        if (!(r = row[i].area)) continue;
	        if (r < rmin) rmin = r;
	        if (r > rmax) rmax = r;
	      }
	      s *= s;
	      u *= u;
	      return s ? Math.max(u * rmax * ratio / s, s / (u * rmin * ratio)) : Infinity;
	    }
	    function position(row, u, rect, flush) {
	      var i = -1, n = row.length, x = rect.x, y = rect.y, v = u ? round(row.area / u) : 0, o;
	      if (u == rect.dx) {
	        if (flush || v > rect.dy) v = rect.dy;
	        while (++i < n) {
	          o = row[i];
	          o.x = x;
	          o.y = y;
	          o.dy = v;
	          x += o.dx = Math.min(rect.x + rect.dx - x, v ? round(o.area / v) : 0);
	        }
	        o.z = true;
	        o.dx += rect.x + rect.dx - x;
	        rect.y += v;
	        rect.dy -= v;
	      } else {
	        if (flush || v > rect.dx) v = rect.dx;
	        while (++i < n) {
	          o = row[i];
	          o.x = x;
	          o.y = y;
	          o.dx = v;
	          y += o.dy = Math.min(rect.y + rect.dy - y, v ? round(o.area / v) : 0);
	        }
	        o.z = false;
	        o.dy += rect.y + rect.dy - y;
	        rect.x += v;
	        rect.dx -= v;
	      }
	    }
	    function treemap(d) {
	      var nodes = stickies || hierarchy(d), root = nodes[0];
	      root.x = root.y = 0;
	      if (root.value) root.dx = size[0], root.dy = size[1]; else root.dx = root.dy = 0;
	      if (stickies) hierarchy.revalue(root);
	      scale([ root ], root.dx * root.dy / root.value);
	      (stickies ? stickify : squarify)(root);
	      if (sticky) stickies = nodes;
	      return nodes;
	    }
	    treemap.size = function(x) {
	      if (!arguments.length) return size;
	      size = x;
	      return treemap;
	    };
	    treemap.padding = function(x) {
	      if (!arguments.length) return padding;
	      function padFunction(node) {
	        var p = x.call(treemap, node, node.depth);
	        return p == null ? d3_layout_treemapPadNull(node) : d3_layout_treemapPad(node, typeof p === "number" ? [ p, p, p, p ] : p);
	      }
	      function padConstant(node) {
	        return d3_layout_treemapPad(node, x);
	      }
	      var type;
	      pad = (padding = x) == null ? d3_layout_treemapPadNull : (type = typeof x) === "function" ? padFunction : type === "number" ? (x = [ x, x, x, x ], 
	      padConstant) : padConstant;
	      return treemap;
	    };
	    treemap.round = function(x) {
	      if (!arguments.length) return round != Number;
	      round = x ? Math.round : Number;
	      return treemap;
	    };
	    treemap.sticky = function(x) {
	      if (!arguments.length) return sticky;
	      sticky = x;
	      stickies = null;
	      return treemap;
	    };
	    treemap.ratio = function(x) {
	      if (!arguments.length) return ratio;
	      ratio = x;
	      return treemap;
	    };
	    treemap.mode = function(x) {
	      if (!arguments.length) return mode;
	      mode = x + "";
	      return treemap;
	    };
	    return d3_layout_hierarchyRebind(treemap, hierarchy);
	  };
	  function d3_layout_treemapPadNull(node) {
	    return {
	      x: node.x,
	      y: node.y,
	      dx: node.dx,
	      dy: node.dy
	    };
	  }
	  function d3_layout_treemapPad(node, padding) {
	    var x = node.x + padding[3], y = node.y + padding[0], dx = node.dx - padding[1] - padding[3], dy = node.dy - padding[0] - padding[2];
	    if (dx < 0) {
	      x += dx / 2;
	      dx = 0;
	    }
	    if (dy < 0) {
	      y += dy / 2;
	      dy = 0;
	    }
	    return {
	      x: x,
	      y: y,
	      dx: dx,
	      dy: dy
	    };
	  }
	  d3.random = {
	    normal: function(µ, σ) {
	      var n = arguments.length;
	      if (n < 2) σ = 1;
	      if (n < 1) µ = 0;
	      return function() {
	        var x, y, r;
	        do {
	          x = Math.random() * 2 - 1;
	          y = Math.random() * 2 - 1;
	          r = x * x + y * y;
	        } while (!r || r > 1);
	        return µ + σ * x * Math.sqrt(-2 * Math.log(r) / r);
	      };
	    },
	    logNormal: function() {
	      var random = d3.random.normal.apply(d3, arguments);
	      return function() {
	        return Math.exp(random());
	      };
	    },
	    bates: function(m) {
	      var random = d3.random.irwinHall(m);
	      return function() {
	        return random() / m;
	      };
	    },
	    irwinHall: function(m) {
	      return function() {
	        for (var s = 0, j = 0; j < m; j++) s += Math.random();
	        return s;
	      };
	    }
	  };
	  d3.scale = {};
	  function d3_scaleExtent(domain) {
	    var start = domain[0], stop = domain[domain.length - 1];
	    return start < stop ? [ start, stop ] : [ stop, start ];
	  }
	  function d3_scaleRange(scale) {
	    return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range());
	  }
	  function d3_scale_bilinear(domain, range, uninterpolate, interpolate) {
	    var u = uninterpolate(domain[0], domain[1]), i = interpolate(range[0], range[1]);
	    return function(x) {
	      return i(u(x));
	    };
	  }
	  function d3_scale_nice(domain, nice) {
	    var i0 = 0, i1 = domain.length - 1, x0 = domain[i0], x1 = domain[i1], dx;
	    if (x1 < x0) {
	      dx = i0, i0 = i1, i1 = dx;
	      dx = x0, x0 = x1, x1 = dx;
	    }
	    domain[i0] = nice.floor(x0);
	    domain[i1] = nice.ceil(x1);
	    return domain;
	  }
	  function d3_scale_niceStep(step) {
	    return step ? {
	      floor: function(x) {
	        return Math.floor(x / step) * step;
	      },
	      ceil: function(x) {
	        return Math.ceil(x / step) * step;
	      }
	    } : d3_scale_niceIdentity;
	  }
	  var d3_scale_niceIdentity = {
	    floor: d3_identity,
	    ceil: d3_identity
	  };
	  function d3_scale_polylinear(domain, range, uninterpolate, interpolate) {
	    var u = [], i = [], j = 0, k = Math.min(domain.length, range.length) - 1;
	    if (domain[k] < domain[0]) {
	      domain = domain.slice().reverse();
	      range = range.slice().reverse();
	    }
	    while (++j <= k) {
	      u.push(uninterpolate(domain[j - 1], domain[j]));
	      i.push(interpolate(range[j - 1], range[j]));
	    }
	    return function(x) {
	      var j = d3.bisect(domain, x, 1, k) - 1;
	      return i[j](u[j](x));
	    };
	  }
	  d3.scale.linear = function() {
	    return d3_scale_linear([ 0, 1 ], [ 0, 1 ], d3_interpolate, false);
	  };
	  function d3_scale_linear(domain, range, interpolate, clamp) {
	    var output, input;
	    function rescale() {
	      var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear, uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber;
	      output = linear(domain, range, uninterpolate, interpolate);
	      input = linear(range, domain, uninterpolate, d3_interpolate);
	      return scale;
	    }
	    function scale(x) {
	      return output(x);
	    }
	    scale.invert = function(y) {
	      return input(y);
	    };
	    scale.domain = function(x) {
	      if (!arguments.length) return domain;
	      domain = x.map(Number);
	      return rescale();
	    };
	    scale.range = function(x) {
	      if (!arguments.length) return range;
	      range = x;
	      return rescale();
	    };
	    scale.rangeRound = function(x) {
	      return scale.range(x).interpolate(d3_interpolateRound);
	    };
	    scale.clamp = function(x) {
	      if (!arguments.length) return clamp;
	      clamp = x;
	      return rescale();
	    };
	    scale.interpolate = function(x) {
	      if (!arguments.length) return interpolate;
	      interpolate = x;
	      return rescale();
	    };
	    scale.ticks = function(m) {
	      return d3_scale_linearTicks(domain, m);
	    };
	    scale.tickFormat = function(m, format) {
	      return d3_scale_linearTickFormat(domain, m, format);
	    };
	    scale.nice = function(m) {
	      d3_scale_linearNice(domain, m);
	      return rescale();
	    };
	    scale.copy = function() {
	      return d3_scale_linear(domain, range, interpolate, clamp);
	    };
	    return rescale();
	  }
	  function d3_scale_linearRebind(scale, linear) {
	    return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp");
	  }
	  function d3_scale_linearNice(domain, m) {
	    d3_scale_nice(domain, d3_scale_niceStep(d3_scale_linearTickRange(domain, m)[2]));
	    d3_scale_nice(domain, d3_scale_niceStep(d3_scale_linearTickRange(domain, m)[2]));
	    return domain;
	  }
	  function d3_scale_linearTickRange(domain, m) {
	    if (m == null) m = 10;
	    var extent = d3_scaleExtent(domain), span = extent[1] - extent[0], step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), err = m / span * step;
	    if (err <= .15) step *= 10; else if (err <= .35) step *= 5; else if (err <= .75) step *= 2;
	    extent[0] = Math.ceil(extent[0] / step) * step;
	    extent[1] = Math.floor(extent[1] / step) * step + step * .5;
	    extent[2] = step;
	    return extent;
	  }
	  function d3_scale_linearTicks(domain, m) {
	    return d3.range.apply(d3, d3_scale_linearTickRange(domain, m));
	  }
	  function d3_scale_linearTickFormat(domain, m, format) {
	    var range = d3_scale_linearTickRange(domain, m);
	    if (format) {
	      var match = d3_format_re.exec(format);
	      match.shift();
	      if (match[8] === "s") {
	        var prefix = d3.formatPrefix(Math.max(abs(range[0]), abs(range[1])));
	        if (!match[7]) match[7] = "." + d3_scale_linearPrecision(prefix.scale(range[2]));
	        match[8] = "f";
	        format = d3.format(match.join(""));
	        return function(d) {
	          return format(prefix.scale(d)) + prefix.symbol;
	        };
	      }
	      if (!match[7]) match[7] = "." + d3_scale_linearFormatPrecision(match[8], range);
	      format = match.join("");
	    } else {
	      format = ",." + d3_scale_linearPrecision(range[2]) + "f";
	    }
	    return d3.format(format);
	  }
	  var d3_scale_linearFormatSignificant = {
	    s: 1,
	    g: 1,
	    p: 1,
	    r: 1,
	    e: 1
	  };
	  function d3_scale_linearPrecision(value) {
	    return -Math.floor(Math.log(value) / Math.LN10 + .01);
	  }
	  function d3_scale_linearFormatPrecision(type, range) {
	    var p = d3_scale_linearPrecision(range[2]);
	    return type in d3_scale_linearFormatSignificant ? Math.abs(p - d3_scale_linearPrecision(Math.max(abs(range[0]), abs(range[1])))) + +(type !== "e") : p - (type === "%") * 2;
	  }
	  d3.scale.log = function() {
	    return d3_scale_log(d3.scale.linear().domain([ 0, 1 ]), 10, true, [ 1, 10 ]);
	  };
	  function d3_scale_log(linear, base, positive, domain) {
	    function log(x) {
	      return (positive ? Math.log(x < 0 ? 0 : x) : -Math.log(x > 0 ? 0 : -x)) / Math.log(base);
	    }
	    function pow(x) {
	      return positive ? Math.pow(base, x) : -Math.pow(base, -x);
	    }
	    function scale(x) {
	      return linear(log(x));
	    }
	    scale.invert = function(x) {
	      return pow(linear.invert(x));
	    };
	    scale.domain = function(x) {
	      if (!arguments.length) return domain;
	      positive = x[0] >= 0;
	      linear.domain((domain = x.map(Number)).map(log));
	      return scale;
	    };
	    scale.base = function(_) {
	      if (!arguments.length) return base;
	      base = +_;
	      linear.domain(domain.map(log));
	      return scale;
	    };
	    scale.nice = function() {
	      var niced = d3_scale_nice(domain.map(log), positive ? Math : d3_scale_logNiceNegative);
	      linear.domain(niced);
	      domain = niced.map(pow);
	      return scale;
	    };
	    scale.ticks = function() {
	      var extent = d3_scaleExtent(domain), ticks = [], u = extent[0], v = extent[1], i = Math.floor(log(u)), j = Math.ceil(log(v)), n = base % 1 ? 2 : base;
	      if (isFinite(j - i)) {
	        if (positive) {
	          for (;i < j; i++) for (var k = 1; k < n; k++) ticks.push(pow(i) * k);
	          ticks.push(pow(i));
	        } else {
	          ticks.push(pow(i));
	          for (;i++ < j; ) for (var k = n - 1; k > 0; k--) ticks.push(pow(i) * k);
	        }
	        for (i = 0; ticks[i] < u; i++) {}
	        for (j = ticks.length; ticks[j - 1] > v; j--) {}
	        ticks = ticks.slice(i, j);
	      }
	      return ticks;
	    };
	    scale.tickFormat = function(n, format) {
	      if (!arguments.length) return d3_scale_logFormat;
	      if (arguments.length < 2) format = d3_scale_logFormat; else if (typeof format !== "function") format = d3.format(format);
	      var k = Math.max(1, base * n / scale.ticks().length);
	      return function(d) {
	        var i = d / pow(Math.round(log(d)));
	        if (i * base < base - .5) i *= base;
	        return i <= k ? format(d) : "";
	      };
	    };
	    scale.copy = function() {
	      return d3_scale_log(linear.copy(), base, positive, domain);
	    };
	    return d3_scale_linearRebind(scale, linear);
	  }
	  var d3_scale_logFormat = d3.format(".0e"), d3_scale_logNiceNegative = {
	    floor: function(x) {
	      return -Math.ceil(-x);
	    },
	    ceil: function(x) {
	      return -Math.floor(-x);
	    }
	  };
	  d3.scale.pow = function() {
	    return d3_scale_pow(d3.scale.linear(), 1, [ 0, 1 ]);
	  };
	  function d3_scale_pow(linear, exponent, domain) {
	    var powp = d3_scale_powPow(exponent), powb = d3_scale_powPow(1 / exponent);
	    function scale(x) {
	      return linear(powp(x));
	    }
	    scale.invert = function(x) {
	      return powb(linear.invert(x));
	    };
	    scale.domain = function(x) {
	      if (!arguments.length) return domain;
	      linear.domain((domain = x.map(Number)).map(powp));
	      return scale;
	    };
	    scale.ticks = function(m) {
	      return d3_scale_linearTicks(domain, m);
	    };
	    scale.tickFormat = function(m, format) {
	      return d3_scale_linearTickFormat(domain, m, format);
	    };
	    scale.nice = function(m) {
	      return scale.domain(d3_scale_linearNice(domain, m));
	    };
	    scale.exponent = function(x) {
	      if (!arguments.length) return exponent;
	      powp = d3_scale_powPow(exponent = x);
	      powb = d3_scale_powPow(1 / exponent);
	      linear.domain(domain.map(powp));
	      return scale;
	    };
	    scale.copy = function() {
	      return d3_scale_pow(linear.copy(), exponent, domain);
	    };
	    return d3_scale_linearRebind(scale, linear);
	  }
	  function d3_scale_powPow(e) {
	    return function(x) {
	      return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e);
	    };
	  }
	  d3.scale.sqrt = function() {
	    return d3.scale.pow().exponent(.5);
	  };
	  d3.scale.ordinal = function() {
	    return d3_scale_ordinal([], {
	      t: "range",
	      a: [ [] ]
	    });
	  };
	  function d3_scale_ordinal(domain, ranger) {
	    var index, range, rangeBand;
	    function scale(x) {
	      return range[((index.get(x) || (ranger.t === "range" ? index.set(x, domain.push(x)) : NaN)) - 1) % range.length];
	    }
	    function steps(start, step) {
	      return d3.range(domain.length).map(function(i) {
	        return start + step * i;
	      });
	    }
	    scale.domain = function(x) {
	      if (!arguments.length) return domain;
	      domain = [];
	      index = new d3_Map();
	      var i = -1, n = x.length, xi;
	      while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi));
	      return scale[ranger.t].apply(scale, ranger.a);
	    };
	    scale.range = function(x) {
	      if (!arguments.length) return range;
	      range = x;
	      rangeBand = 0;
	      ranger = {
	        t: "range",
	        a: arguments
	      };
	      return scale;
	    };
	    scale.rangePoints = function(x, padding) {
	      if (arguments.length < 2) padding = 0;
	      var start = x[0], stop = x[1], step = domain.length < 2 ? (start = (start + stop) / 2, 
	      0) : (stop - start) / (domain.length - 1 + padding);
	      range = steps(start + step * padding / 2, step);
	      rangeBand = 0;
	      ranger = {
	        t: "rangePoints",
	        a: arguments
	      };
	      return scale;
	    };
	    scale.rangeRoundPoints = function(x, padding) {
	      if (arguments.length < 2) padding = 0;
	      var start = x[0], stop = x[1], step = domain.length < 2 ? (start = stop = Math.round((start + stop) / 2), 
	      0) : (stop - start) / (domain.length - 1 + padding) | 0;
	      range = steps(start + Math.round(step * padding / 2 + (stop - start - (domain.length - 1 + padding) * step) / 2), step);
	      rangeBand = 0;
	      ranger = {
	        t: "rangeRoundPoints",
	        a: arguments
	      };
	      return scale;
	    };
	    scale.rangeBands = function(x, padding, outerPadding) {
	      if (arguments.length < 2) padding = 0;
	      if (arguments.length < 3) outerPadding = padding;
	      var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = (stop - start) / (domain.length - padding + 2 * outerPadding);
	      range = steps(start + step * outerPadding, step);
	      if (reverse) range.reverse();
	      rangeBand = step * (1 - padding);
	      ranger = {
	        t: "rangeBands",
	        a: arguments
	      };
	      return scale;
	    };
	    scale.rangeRoundBands = function(x, padding, outerPadding) {
	      if (arguments.length < 2) padding = 0;
	      if (arguments.length < 3) outerPadding = padding;
	      var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = Math.floor((stop - start) / (domain.length - padding + 2 * outerPadding));
	      range = steps(start + Math.round((stop - start - (domain.length - padding) * step) / 2), step);
	      if (reverse) range.reverse();
	      rangeBand = Math.round(step * (1 - padding));
	      ranger = {
	        t: "rangeRoundBands",
	        a: arguments
	      };
	      return scale;
	    };
	    scale.rangeBand = function() {
	      return rangeBand;
	    };
	    scale.rangeExtent = function() {
	      return d3_scaleExtent(ranger.a[0]);
	    };
	    scale.copy = function() {
	      return d3_scale_ordinal(domain, ranger);
	    };
	    return scale.domain(domain);
	  }
	  d3.scale.category10 = function() {
	    return d3.scale.ordinal().range(d3_category10);
	  };
	  d3.scale.category20 = function() {
	    return d3.scale.ordinal().range(d3_category20);
	  };
	  d3.scale.category20b = function() {
	    return d3.scale.ordinal().range(d3_category20b);
	  };
	  d3.scale.category20c = function() {
	    return d3.scale.ordinal().range(d3_category20c);
	  };
	  var d3_category10 = [ 2062260, 16744206, 2924588, 14034728, 9725885, 9197131, 14907330, 8355711, 12369186, 1556175 ].map(d3_rgbString);
	  var d3_category20 = [ 2062260, 11454440, 16744206, 16759672, 2924588, 10018698, 14034728, 16750742, 9725885, 12955861, 9197131, 12885140, 14907330, 16234194, 8355711, 13092807, 12369186, 14408589, 1556175, 10410725 ].map(d3_rgbString);
	  var d3_category20b = [ 3750777, 5395619, 7040719, 10264286, 6519097, 9216594, 11915115, 13556636, 9202993, 12426809, 15186514, 15190932, 8666169, 11356490, 14049643, 15177372, 8077683, 10834324, 13528509, 14589654 ].map(d3_rgbString);
	  var d3_category20c = [ 3244733, 7057110, 10406625, 13032431, 15095053, 16616764, 16625259, 16634018, 3253076, 7652470, 10607003, 13101504, 7695281, 10394312, 12369372, 14342891, 6513507, 9868950, 12434877, 14277081 ].map(d3_rgbString);
	  d3.scale.quantile = function() {
	    return d3_scale_quantile([], []);
	  };
	  function d3_scale_quantile(domain, range) {
	    var thresholds;
	    function rescale() {
	      var k = 0, q = range.length;
	      thresholds = [];
	      while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q);
	      return scale;
	    }
	    function scale(x) {
	      if (!isNaN(x = +x)) return range[d3.bisect(thresholds, x)];
	    }
	    scale.domain = function(x) {
	      if (!arguments.length) return domain;
	      domain = x.map(d3_number).filter(d3_numeric).sort(d3_ascending);
	      return rescale();
	    };
	    scale.range = function(x) {
	      if (!arguments.length) return range;
	      range = x;
	      return rescale();
	    };
	    scale.quantiles = function() {
	      return thresholds;
	    };
	    scale.invertExtent = function(y) {
	      y = range.indexOf(y);
	      return y < 0 ? [ NaN, NaN ] : [ y > 0 ? thresholds[y - 1] : domain[0], y < thresholds.length ? thresholds[y] : domain[domain.length - 1] ];
	    };
	    scale.copy = function() {
	      return d3_scale_quantile(domain, range);
	    };
	    return rescale();
	  }
	  d3.scale.quantize = function() {
	    return d3_scale_quantize(0, 1, [ 0, 1 ]);
	  };
	  function d3_scale_quantize(x0, x1, range) {
	    var kx, i;
	    function scale(x) {
	      return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))];
	    }
	    function rescale() {
	      kx = range.length / (x1 - x0);
	      i = range.length - 1;
	      return scale;
	    }
	    scale.domain = function(x) {
	      if (!arguments.length) return [ x0, x1 ];
	      x0 = +x[0];
	      x1 = +x[x.length - 1];
	      return rescale();
	    };
	    scale.range = function(x) {
	      if (!arguments.length) return range;
	      range = x;
	      return rescale();
	    };
	    scale.invertExtent = function(y) {
	      y = range.indexOf(y);
	      y = y < 0 ? NaN : y / kx + x0;
	      return [ y, y + 1 / kx ];
	    };
	    scale.copy = function() {
	      return d3_scale_quantize(x0, x1, range);
	    };
	    return rescale();
	  }
	  d3.scale.threshold = function() {
	    return d3_scale_threshold([ .5 ], [ 0, 1 ]);
	  };
	  function d3_scale_threshold(domain, range) {
	    function scale(x) {
	      if (x <= x) return range[d3.bisect(domain, x)];
	    }
	    scale.domain = function(_) {
	      if (!arguments.length) return domain;
	      domain = _;
	      return scale;
	    };
	    scale.range = function(_) {
	      if (!arguments.length) return range;
	      range = _;
	      return scale;
	    };
	    scale.invertExtent = function(y) {
	      y = range.indexOf(y);
	      return [ domain[y - 1], domain[y] ];
	    };
	    scale.copy = function() {
	      return d3_scale_threshold(domain, range);
	    };
	    return scale;
	  }
	  d3.scale.identity = function() {
	    return d3_scale_identity([ 0, 1 ]);
	  };
	  function d3_scale_identity(domain) {
	    function identity(x) {
	      return +x;
	    }
	    identity.invert = identity;
	    identity.domain = identity.range = function(x) {
	      if (!arguments.length) return domain;
	      domain = x.map(identity);
	      return identity;
	    };
	    identity.ticks = function(m) {
	      return d3_scale_linearTicks(domain, m);
	    };
	    identity.tickFormat = function(m, format) {
	      return d3_scale_linearTickFormat(domain, m, format);
	    };
	    identity.copy = function() {
	      return d3_scale_identity(domain);
	    };
	    return identity;
	  }
	  d3.svg = {};
	  function d3_zero() {
	    return 0;
	  }
	  d3.svg.arc = function() {
	    var innerRadius = d3_svg_arcInnerRadius, outerRadius = d3_svg_arcOuterRadius, cornerRadius = d3_zero, padRadius = d3_svg_arcAuto, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle, padAngle = d3_svg_arcPadAngle;
	    function arc() {
	      var r0 = Math.max(0, +innerRadius.apply(this, arguments)), r1 = Math.max(0, +outerRadius.apply(this, arguments)), a0 = startAngle.apply(this, arguments) - halfπ, a1 = endAngle.apply(this, arguments) - halfπ, da = Math.abs(a1 - a0), cw = a0 > a1 ? 0 : 1;
	      if (r1 < r0) rc = r1, r1 = r0, r0 = rc;
	      if (da >= τε) return circleSegment(r1, cw) + (r0 ? circleSegment(r0, 1 - cw) : "") + "Z";
	      var rc, cr, rp, ap, p0 = 0, p1 = 0, x0, y0, x1, y1, x2, y2, x3, y3, path = [];
	      if (ap = (+padAngle.apply(this, arguments) || 0) / 2) {
	        rp = padRadius === d3_svg_arcAuto ? Math.sqrt(r0 * r0 + r1 * r1) : +padRadius.apply(this, arguments);
	        if (!cw) p1 *= -1;
	        if (r1) p1 = d3_asin(rp / r1 * Math.sin(ap));
	        if (r0) p0 = d3_asin(rp / r0 * Math.sin(ap));
	      }
	      if (r1) {
	        x0 = r1 * Math.cos(a0 + p1);
	        y0 = r1 * Math.sin(a0 + p1);
	        x1 = r1 * Math.cos(a1 - p1);
	        y1 = r1 * Math.sin(a1 - p1);
	        var l1 = Math.abs(a1 - a0 - 2 * p1) <= π ? 0 : 1;
	        if (p1 && d3_svg_arcSweep(x0, y0, x1, y1) === cw ^ l1) {
	          var h1 = (a0 + a1) / 2;
	          x0 = r1 * Math.cos(h1);
	          y0 = r1 * Math.sin(h1);
	          x1 = y1 = null;
	        }
	      } else {
	        x0 = y0 = 0;
	      }
	      if (r0) {
	        x2 = r0 * Math.cos(a1 - p0);
	        y2 = r0 * Math.sin(a1 - p0);
	        x3 = r0 * Math.cos(a0 + p0);
	        y3 = r0 * Math.sin(a0 + p0);
	        var l0 = Math.abs(a0 - a1 + 2 * p0) <= π ? 0 : 1;
	        if (p0 && d3_svg_arcSweep(x2, y2, x3, y3) === 1 - cw ^ l0) {
	          var h0 = (a0 + a1) / 2;
	          x2 = r0 * Math.cos(h0);
	          y2 = r0 * Math.sin(h0);
	          x3 = y3 = null;
	        }
	      } else {
	        x2 = y2 = 0;
	      }
	      if (da > ε && (rc = Math.min(Math.abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments))) > .001) {
	        cr = r0 < r1 ^ cw ? 0 : 1;
	        var rc1 = rc, rc0 = rc;
	        if (da < π) {
	          var oc = x3 == null ? [ x2, y2 ] : x1 == null ? [ x0, y0 ] : d3_geom_polygonIntersect([ x0, y0 ], [ x3, y3 ], [ x1, y1 ], [ x2, y2 ]), ax = x0 - oc[0], ay = y0 - oc[1], bx = x1 - oc[0], by = y1 - oc[1], kc = 1 / Math.sin(Math.acos((ax * bx + ay * by) / (Math.sqrt(ax * ax + ay * ay) * Math.sqrt(bx * bx + by * by))) / 2), lc = Math.sqrt(oc[0] * oc[0] + oc[1] * oc[1]);
	          rc0 = Math.min(rc, (r0 - lc) / (kc - 1));
	          rc1 = Math.min(rc, (r1 - lc) / (kc + 1));
	        }
	        if (x1 != null) {
	          var t30 = d3_svg_arcCornerTangents(x3 == null ? [ x2, y2 ] : [ x3, y3 ], [ x0, y0 ], r1, rc1, cw), t12 = d3_svg_arcCornerTangents([ x1, y1 ], [ x2, y2 ], r1, rc1, cw);
	          if (rc === rc1) {
	            path.push("M", t30[0], "A", rc1, ",", rc1, " 0 0,", cr, " ", t30[1], "A", r1, ",", r1, " 0 ", 1 - cw ^ d3_svg_arcSweep(t30[1][0], t30[1][1], t12[1][0], t12[1][1]), ",", cw, " ", t12[1], "A", rc1, ",", rc1, " 0 0,", cr, " ", t12[0]);
	          } else {
	            path.push("M", t30[0], "A", rc1, ",", rc1, " 0 1,", cr, " ", t12[0]);
	          }
	        } else {
	          path.push("M", x0, ",", y0);
	        }
	        if (x3 != null) {
	          var t03 = d3_svg_arcCornerTangents([ x0, y0 ], [ x3, y3 ], r0, -rc0, cw), t21 = d3_svg_arcCornerTangents([ x2, y2 ], x1 == null ? [ x0, y0 ] : [ x1, y1 ], r0, -rc0, cw);
	          if (rc === rc0) {
	            path.push("L", t21[0], "A", rc0, ",", rc0, " 0 0,", cr, " ", t21[1], "A", r0, ",", r0, " 0 ", cw ^ d3_svg_arcSweep(t21[1][0], t21[1][1], t03[1][0], t03[1][1]), ",", 1 - cw, " ", t03[1], "A", rc0, ",", rc0, " 0 0,", cr, " ", t03[0]);
	          } else {
	            path.push("L", t21[0], "A", rc0, ",", rc0, " 0 0,", cr, " ", t03[0]);
	          }
	        } else {
	          path.push("L", x2, ",", y2);
	        }
	      } else {
	        path.push("M", x0, ",", y0);
	        if (x1 != null) path.push("A", r1, ",", r1, " 0 ", l1, ",", cw, " ", x1, ",", y1);
	        path.push("L", x2, ",", y2);
	        if (x3 != null) path.push("A", r0, ",", r0, " 0 ", l0, ",", 1 - cw, " ", x3, ",", y3);
	      }
	      path.push("Z");
	      return path.join("");
	    }
	    function circleSegment(r1, cw) {
	      return "M0," + r1 + "A" + r1 + "," + r1 + " 0 1," + cw + " 0," + -r1 + "A" + r1 + "," + r1 + " 0 1," + cw + " 0," + r1;
	    }
	    arc.innerRadius = function(v) {
	      if (!arguments.length) return innerRadius;
	      innerRadius = d3_functor(v);
	      return arc;
	    };
	    arc.outerRadius = function(v) {
	      if (!arguments.length) return outerRadius;
	      outerRadius = d3_functor(v);
	      return arc;
	    };
	    arc.cornerRadius = function(v) {
	      if (!arguments.length) return cornerRadius;
	      cornerRadius = d3_functor(v);
	      return arc;
	    };
	    arc.padRadius = function(v) {
	      if (!arguments.length) return padRadius;
	      padRadius = v == d3_svg_arcAuto ? d3_svg_arcAuto : d3_functor(v);
	      return arc;
	    };
	    arc.startAngle = function(v) {
	      if (!arguments.length) return startAngle;
	      startAngle = d3_functor(v);
	      return arc;
	    };
	    arc.endAngle = function(v) {
	      if (!arguments.length) return endAngle;
	      endAngle = d3_functor(v);
	      return arc;
	    };
	    arc.padAngle = function(v) {
	      if (!arguments.length) return padAngle;
	      padAngle = d3_functor(v);
	      return arc;
	    };
	    arc.centroid = function() {
	      var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2, a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - halfπ;
	      return [ Math.cos(a) * r, Math.sin(a) * r ];
	    };
	    return arc;
	  };
	  var d3_svg_arcAuto = "auto";
	  function d3_svg_arcInnerRadius(d) {
	    return d.innerRadius;
	  }
	  function d3_svg_arcOuterRadius(d) {
	    return d.outerRadius;
	  }
	  function d3_svg_arcStartAngle(d) {
	    return d.startAngle;
	  }
	  function d3_svg_arcEndAngle(d) {
	    return d.endAngle;
	  }
	  function d3_svg_arcPadAngle(d) {
	    return d && d.padAngle;
	  }
	  function d3_svg_arcSweep(x0, y0, x1, y1) {
	    return (x0 - x1) * y0 - (y0 - y1) * x0 > 0 ? 0 : 1;
	  }
	  function d3_svg_arcCornerTangents(p0, p1, r1, rc, cw) {
	    var x01 = p0[0] - p1[0], y01 = p0[1] - p1[1], lo = (cw ? rc : -rc) / Math.sqrt(x01 * x01 + y01 * y01), ox = lo * y01, oy = -lo * x01, x1 = p0[0] + ox, y1 = p0[1] + oy, x2 = p1[0] + ox, y2 = p1[1] + oy, x3 = (x1 + x2) / 2, y3 = (y1 + y2) / 2, dx = x2 - x1, dy = y2 - y1, d2 = dx * dx + dy * dy, r = r1 - rc, D = x1 * y2 - x2 * y1, d = (dy < 0 ? -1 : 1) * Math.sqrt(Math.max(0, r * r * d2 - D * D)), cx0 = (D * dy - dx * d) / d2, cy0 = (-D * dx - dy * d) / d2, cx1 = (D * dy + dx * d) / d2, cy1 = (-D * dx + dy * d) / d2, dx0 = cx0 - x3, dy0 = cy0 - y3, dx1 = cx1 - x3, dy1 = cy1 - y3;
	    if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;
	    return [ [ cx0 - ox, cy0 - oy ], [ cx0 * r1 / r, cy0 * r1 / r ] ];
	  }
	  function d3_svg_line(projection) {
	    var x = d3_geom_pointX, y = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, tension = .7;
	    function line(data) {
	      var segments = [], points = [], i = -1, n = data.length, d, fx = d3_functor(x), fy = d3_functor(y);
	      function segment() {
	        segments.push("M", interpolate(projection(points), tension));
	      }
	      while (++i < n) {
	        if (defined.call(this, d = data[i], i)) {
	          points.push([ +fx.call(this, d, i), +fy.call(this, d, i) ]);
	        } else if (points.length) {
	          segment();
	          points = [];
	        }
	      }
	      if (points.length) segment();
	      return segments.length ? segments.join("") : null;
	    }
	    line.x = function(_) {
	      if (!arguments.length) return x;
	      x = _;
	      return line;
	    };
	    line.y = function(_) {
	      if (!arguments.length) return y;
	      y = _;
	      return line;
	    };
	    line.defined = function(_) {
	      if (!arguments.length) return defined;
	      defined = _;
	      return line;
	    };
	    line.interpolate = function(_) {
	      if (!arguments.length) return interpolateKey;
	      if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key;
	      return line;
	    };
	    line.tension = function(_) {
	      if (!arguments.length) return tension;
	      tension = _;
	      return line;
	    };
	    return line;
	  }
	  d3.svg.line = function() {
	    return d3_svg_line(d3_identity);
	  };
	  var d3_svg_lineInterpolators = d3.map({
	    linear: d3_svg_lineLinear,
	    "linear-closed": d3_svg_lineLinearClosed,
	    step: d3_svg_lineStep,
	    "step-before": d3_svg_lineStepBefore,
	    "step-after": d3_svg_lineStepAfter,
	    basis: d3_svg_lineBasis,
	    "basis-open": d3_svg_lineBasisOpen,
	    "basis-closed": d3_svg_lineBasisClosed,
	    bundle: d3_svg_lineBundle,
	    cardinal: d3_svg_lineCardinal,
	    "cardinal-open": d3_svg_lineCardinalOpen,
	    "cardinal-closed": d3_svg_lineCardinalClosed,
	    monotone: d3_svg_lineMonotone
	  });
	  d3_svg_lineInterpolators.forEach(function(key, value) {
	    value.key = key;
	    value.closed = /-closed$/.test(key);
	  });
	  function d3_svg_lineLinear(points) {
	    return points.length > 1 ? points.join("L") : points + "Z";
	  }
	  function d3_svg_lineLinearClosed(points) {
	    return points.join("L") + "Z";
	  }
	  function d3_svg_lineStep(points) {
	    var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ];
	    while (++i < n) path.push("H", (p[0] + (p = points[i])[0]) / 2, "V", p[1]);
	    if (n > 1) path.push("H", p[0]);
	    return path.join("");
	  }
	  function d3_svg_lineStepBefore(points) {
	    var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ];
	    while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]);
	    return path.join("");
	  }
	  function d3_svg_lineStepAfter(points) {
	    var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ];
	    while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]);
	    return path.join("");
	  }
	  function d3_svg_lineCardinalOpen(points, tension) {
	    return points.length < 4 ? d3_svg_lineLinear(points) : points[1] + d3_svg_lineHermite(points.slice(1, -1), d3_svg_lineCardinalTangents(points, tension));
	  }
	  function d3_svg_lineCardinalClosed(points, tension) {
	    return points.length < 3 ? d3_svg_lineLinearClosed(points) : points[0] + d3_svg_lineHermite((points.push(points[0]), 
	    points), d3_svg_lineCardinalTangents([ points[points.length - 2] ].concat(points, [ points[1] ]), tension));
	  }
	  function d3_svg_lineCardinal(points, tension) {
	    return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineCardinalTangents(points, tension));
	  }
	  function d3_svg_lineHermite(points, tangents) {
	    if (tangents.length < 1 || points.length != tangents.length && points.length != tangents.length + 2) {
	      return d3_svg_lineLinear(points);
	    }
	    var quad = points.length != tangents.length, path = "", p0 = points[0], p = points[1], t0 = tangents[0], t = t0, pi = 1;
	    if (quad) {
	      path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3) + "," + p[0] + "," + p[1];
	      p0 = points[1];
	      pi = 2;
	    }
	    if (tangents.length > 1) {
	      t = tangents[1];
	      p = points[pi];
	      pi++;
	      path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1]) + "," + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1];
	      for (var i = 2; i < tangents.length; i++, pi++) {
	        p = points[pi];
	        t = tangents[i];
	        path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1];
	      }
	    }
	    if (quad) {
	      var lp = points[pi];
	      path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3) + "," + lp[0] + "," + lp[1];
	    }
	    return path;
	  }
	  function d3_svg_lineCardinalTangents(points, tension) {
	    var tangents = [], a = (1 - tension) / 2, p0, p1 = points[0], p2 = points[1], i = 1, n = points.length;
	    while (++i < n) {
	      p0 = p1;
	      p1 = p2;
	      p2 = points[i];
	      tangents.push([ a * (p2[0] - p0[0]), a * (p2[1] - p0[1]) ]);
	    }
	    return tangents;
	  }
	  function d3_svg_lineBasis(points) {
	    if (points.length < 3) return d3_svg_lineLinear(points);
	    var i = 1, n = points.length, pi = points[0], x0 = pi[0], y0 = pi[1], px = [ x0, x0, x0, (pi = points[1])[0] ], py = [ y0, y0, y0, pi[1] ], path = [ x0, ",", y0, "L", d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ];
	    points.push(points[n - 1]);
	    while (++i <= n) {
	      pi = points[i];
	      px.shift();
	      px.push(pi[0]);
	      py.shift();
	      py.push(pi[1]);
	      d3_svg_lineBasisBezier(path, px, py);
	    }
	    points.pop();
	    path.push("L", pi);
	    return path.join("");
	  }
	  function d3_svg_lineBasisOpen(points) {
	    if (points.length < 4) return d3_svg_lineLinear(points);
	    var path = [], i = -1, n = points.length, pi, px = [ 0 ], py = [ 0 ];
	    while (++i < 3) {
	      pi = points[i];
	      px.push(pi[0]);
	      py.push(pi[1]);
	    }
	    path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px) + "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py));
	    --i;
	    while (++i < n) {
	      pi = points[i];
	      px.shift();
	      px.push(pi[0]);
	      py.shift();
	      py.push(pi[1]);
	      d3_svg_lineBasisBezier(path, px, py);
	    }
	    return path.join("");
	  }
	  function d3_svg_lineBasisClosed(points) {
	    var path, i = -1, n = points.length, m = n + 4, pi, px = [], py = [];
	    while (++i < 4) {
	      pi = points[i % n];
	      px.push(pi[0]);
	      py.push(pi[1]);
	    }
	    path = [ d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ];
	    --i;
	    while (++i < m) {
	      pi = points[i % n];
	      px.shift();
	      px.push(pi[0]);
	      py.shift();
	      py.push(pi[1]);
	      d3_svg_lineBasisBezier(path, px, py);
	    }
	    return path.join("");
	  }
	  function d3_svg_lineBundle(points, tension) {
	    var n = points.length - 1;
	    if (n) {
	      var x0 = points[0][0], y0 = points[0][1], dx = points[n][0] - x0, dy = points[n][1] - y0, i = -1, p, t;
	      while (++i <= n) {
	        p = points[i];
	        t = i / n;
	        p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx);
	        p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy);
	      }
	    }
	    return d3_svg_lineBasis(points);
	  }
	  function d3_svg_lineDot4(a, b) {
	    return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
	  }
	  var d3_svg_lineBasisBezier1 = [ 0, 2 / 3, 1 / 3, 0 ], d3_svg_lineBasisBezier2 = [ 0, 1 / 3, 2 / 3, 0 ], d3_svg_lineBasisBezier3 = [ 0, 1 / 6, 2 / 3, 1 / 6 ];
	  function d3_svg_lineBasisBezier(path, x, y) {
	    path.push("C", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y));
	  }
	  function d3_svg_lineSlope(p0, p1) {
	    return (p1[1] - p0[1]) / (p1[0] - p0[0]);
	  }
	  function d3_svg_lineFiniteDifferences(points) {
	    var i = 0, j = points.length - 1, m = [], p0 = points[0], p1 = points[1], d = m[0] = d3_svg_lineSlope(p0, p1);
	    while (++i < j) {
	      m[i] = (d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]))) / 2;
	    }
	    m[i] = d;
	    return m;
	  }
	  function d3_svg_lineMonotoneTangents(points) {
	    var tangents = [], d, a, b, s, m = d3_svg_lineFiniteDifferences(points), i = -1, j = points.length - 1;
	    while (++i < j) {
	      d = d3_svg_lineSlope(points[i], points[i + 1]);
	      if (abs(d) < ε) {
	        m[i] = m[i + 1] = 0;
	      } else {
	        a = m[i] / d;
	        b = m[i + 1] / d;
	        s = a * a + b * b;
	        if (s > 9) {
	          s = d * 3 / Math.sqrt(s);
	          m[i] = s * a;
	          m[i + 1] = s * b;
	        }
	      }
	    }
	    i = -1;
	    while (++i <= j) {
	      s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i]));
	      tangents.push([ s || 0, m[i] * s || 0 ]);
	    }
	    return tangents;
	  }
	  function d3_svg_lineMonotone(points) {
	    return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points));
	  }
	  d3.svg.line.radial = function() {
	    var line = d3_svg_line(d3_svg_lineRadial);
	    line.radius = line.x, delete line.x;
	    line.angle = line.y, delete line.y;
	    return line;
	  };
	  function d3_svg_lineRadial(points) {
	    var point, i = -1, n = points.length, r, a;
	    while (++i < n) {
	      point = points[i];
	      r = point[0];
	      a = point[1] - halfπ;
	      point[0] = r * Math.cos(a);
	      point[1] = r * Math.sin(a);
	    }
	    return points;
	  }
	  function d3_svg_area(projection) {
	    var x0 = d3_geom_pointX, x1 = d3_geom_pointX, y0 = 0, y1 = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, interpolateReverse = interpolate, L = "L", tension = .7;
	    function area(data) {
	      var segments = [], points0 = [], points1 = [], i = -1, n = data.length, d, fx0 = d3_functor(x0), fy0 = d3_functor(y0), fx1 = x0 === x1 ? function() {
	        return x;
	      } : d3_functor(x1), fy1 = y0 === y1 ? function() {
	        return y;
	      } : d3_functor(y1), x, y;
	      function segment() {
	        segments.push("M", interpolate(projection(points1), tension), L, interpolateReverse(projection(points0.reverse()), tension), "Z");
	      }
	      while (++i < n) {
	        if (defined.call(this, d = data[i], i)) {
	          points0.push([ x = +fx0.call(this, d, i), y = +fy0.call(this, d, i) ]);
	          points1.push([ +fx1.call(this, d, i), +fy1.call(this, d, i) ]);
	        } else if (points0.length) {
	          segment();
	          points0 = [];
	          points1 = [];
	        }
	      }
	      if (points0.length) segment();
	      return segments.length ? segments.join("") : null;
	    }
	    area.x = function(_) {
	      if (!arguments.length) return x1;
	      x0 = x1 = _;
	      return area;
	    };
	    area.x0 = function(_) {
	      if (!arguments.length) return x0;
	      x0 = _;
	      return area;
	    };
	    area.x1 = function(_) {
	      if (!arguments.length) return x1;
	      x1 = _;
	      return area;
	    };
	    area.y = function(_) {
	      if (!arguments.length) return y1;
	      y0 = y1 = _;
	      return area;
	    };
	    area.y0 = function(_) {
	      if (!arguments.length) return y0;
	      y0 = _;
	      return area;
	    };
	    area.y1 = function(_) {
	      if (!arguments.length) return y1;
	      y1 = _;
	      return area;
	    };
	    area.defined = function(_) {
	      if (!arguments.length) return defined;
	      defined = _;
	      return area;
	    };
	    area.interpolate = function(_) {
	      if (!arguments.length) return interpolateKey;
	      if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key;
	      interpolateReverse = interpolate.reverse || interpolate;
	      L = interpolate.closed ? "M" : "L";
	      return area;
	    };
	    area.tension = function(_) {
	      if (!arguments.length) return tension;
	      tension = _;
	      return area;
	    };
	    return area;
	  }
	  d3_svg_lineStepBefore.reverse = d3_svg_lineStepAfter;
	  d3_svg_lineStepAfter.reverse = d3_svg_lineStepBefore;
	  d3.svg.area = function() {
	    return d3_svg_area(d3_identity);
	  };
	  d3.svg.area.radial = function() {
	    var area = d3_svg_area(d3_svg_lineRadial);
	    area.radius = area.x, delete area.x;
	    area.innerRadius = area.x0, delete area.x0;
	    area.outerRadius = area.x1, delete area.x1;
	    area.angle = area.y, delete area.y;
	    area.startAngle = area.y0, delete area.y0;
	    area.endAngle = area.y1, delete area.y1;
	    return area;
	  };
	  d3.svg.chord = function() {
	    var source = d3_source, target = d3_target, radius = d3_svg_chordRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle;
	    function chord(d, i) {
	      var s = subgroup(this, source, d, i), t = subgroup(this, target, d, i);
	      return "M" + s.p0 + arc(s.r, s.p1, s.a1 - s.a0) + (equals(s, t) ? curve(s.r, s.p1, s.r, s.p0) : curve(s.r, s.p1, t.r, t.p0) + arc(t.r, t.p1, t.a1 - t.a0) + curve(t.r, t.p1, s.r, s.p0)) + "Z";
	    }
	    function subgroup(self, f, d, i) {
	      var subgroup = f.call(self, d, i), r = radius.call(self, subgroup, i), a0 = startAngle.call(self, subgroup, i) - halfπ, a1 = endAngle.call(self, subgroup, i) - halfπ;
	      return {
	        r: r,
	        a0: a0,
	        a1: a1,
	        p0: [ r * Math.cos(a0), r * Math.sin(a0) ],
	        p1: [ r * Math.cos(a1), r * Math.sin(a1) ]
	      };
	    }
	    function equals(a, b) {
	      return a.a0 == b.a0 && a.a1 == b.a1;
	    }
	    function arc(r, p, a) {
	      return "A" + r + "," + r + " 0 " + +(a > π) + ",1 " + p;
	    }
	    function curve(r0, p0, r1, p1) {
	      return "Q 0,0 " + p1;
	    }
	    chord.radius = function(v) {
	      if (!arguments.length) return radius;
	      radius = d3_functor(v);
	      return chord;
	    };
	    chord.source = function(v) {
	      if (!arguments.length) return source;
	      source = d3_functor(v);
	      return chord;
	    };
	    chord.target = function(v) {
	      if (!arguments.length) return target;
	      target = d3_functor(v);
	      return chord;
	    };
	    chord.startAngle = function(v) {
	      if (!arguments.length) return startAngle;
	      startAngle = d3_functor(v);
	      return chord;
	    };
	    chord.endAngle = function(v) {
	      if (!arguments.length) return endAngle;
	      endAngle = d3_functor(v);
	      return chord;
	    };
	    return chord;
	  };
	  function d3_svg_chordRadius(d) {
	    return d.radius;
	  }
	  d3.svg.diagonal = function() {
	    var source = d3_source, target = d3_target, projection = d3_svg_diagonalProjection;
	    function diagonal(d, i) {
	      var p0 = source.call(this, d, i), p3 = target.call(this, d, i), m = (p0.y + p3.y) / 2, p = [ p0, {
	        x: p0.x,
	        y: m
	      }, {
	        x: p3.x,
	        y: m
	      }, p3 ];
	      p = p.map(projection);
	      return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3];
	    }
	    diagonal.source = function(x) {
	      if (!arguments.length) return source;
	      source = d3_functor(x);
	      return diagonal;
	    };
	    diagonal.target = function(x) {
	      if (!arguments.length) return target;
	      target = d3_functor(x);
	      return diagonal;
	    };
	    diagonal.projection = function(x) {
	      if (!arguments.length) return projection;
	      projection = x;
	      return diagonal;
	    };
	    return diagonal;
	  };
	  function d3_svg_diagonalProjection(d) {
	    return [ d.x, d.y ];
	  }
	  d3.svg.diagonal.radial = function() {
	    var diagonal = d3.svg.diagonal(), projection = d3_svg_diagonalProjection, projection_ = diagonal.projection;
	    diagonal.projection = function(x) {
	      return arguments.length ? projection_(d3_svg_diagonalRadialProjection(projection = x)) : projection;
	    };
	    return diagonal;
	  };
	  function d3_svg_diagonalRadialProjection(projection) {
	    return function() {
	      var d = projection.apply(this, arguments), r = d[0], a = d[1] - halfπ;
	      return [ r * Math.cos(a), r * Math.sin(a) ];
	    };
	  }
	  d3.svg.symbol = function() {
	    var type = d3_svg_symbolType, size = d3_svg_symbolSize;
	    function symbol(d, i) {
	      return (d3_svg_symbols.get(type.call(this, d, i)) || d3_svg_symbolCircle)(size.call(this, d, i));
	    }
	    symbol.type = function(x) {
	      if (!arguments.length) return type;
	      type = d3_functor(x);
	      return symbol;
	    };
	    symbol.size = function(x) {
	      if (!arguments.length) return size;
	      size = d3_functor(x);
	      return symbol;
	    };
	    return symbol;
	  };
	  function d3_svg_symbolSize() {
	    return 64;
	  }
	  function d3_svg_symbolType() {
	    return "circle";
	  }
	  function d3_svg_symbolCircle(size) {
	    var r = Math.sqrt(size / π);
	    return "M0," + r + "A" + r + "," + r + " 0 1,1 0," + -r + "A" + r + "," + r + " 0 1,1 0," + r + "Z";
	  }
	  var d3_svg_symbols = d3.map({
	    circle: d3_svg_symbolCircle,
	    cross: function(size) {
	      var r = Math.sqrt(size / 5) / 2;
	      return "M" + -3 * r + "," + -r + "H" + -r + "V" + -3 * r + "H" + r + "V" + -r + "H" + 3 * r + "V" + r + "H" + r + "V" + 3 * r + "H" + -r + "V" + r + "H" + -3 * r + "Z";
	    },
	    diamond: function(size) {
	      var ry = Math.sqrt(size / (2 * d3_svg_symbolTan30)), rx = ry * d3_svg_symbolTan30;
	      return "M0," + -ry + "L" + rx + ",0" + " 0," + ry + " " + -rx + ",0" + "Z";
	    },
	    square: function(size) {
	      var r = Math.sqrt(size) / 2;
	      return "M" + -r + "," + -r + "L" + r + "," + -r + " " + r + "," + r + " " + -r + "," + r + "Z";
	    },
	    "triangle-down": function(size) {
	      var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2;
	      return "M0," + ry + "L" + rx + "," + -ry + " " + -rx + "," + -ry + "Z";
	    },
	    "triangle-up": function(size) {
	      var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2;
	      return "M0," + -ry + "L" + rx + "," + ry + " " + -rx + "," + ry + "Z";
	    }
	  });
	  d3.svg.symbolTypes = d3_svg_symbols.keys();
	  var d3_svg_symbolSqrt3 = Math.sqrt(3), d3_svg_symbolTan30 = Math.tan(30 * d3_radians);
	  d3_selectionPrototype.transition = function(name) {
	    var id = d3_transitionInheritId || ++d3_transitionId, ns = d3_transitionNamespace(name), subgroups = [], subgroup, node, transition = d3_transitionInherit || {
	      time: Date.now(),
	      ease: d3_ease_cubicInOut,
	      delay: 0,
	      duration: 250
	    };
	    for (var j = -1, m = this.length; ++j < m; ) {
	      subgroups.push(subgroup = []);
	      for (var group = this[j], i = -1, n = group.length; ++i < n; ) {
	        if (node = group[i]) d3_transitionNode(node, i, ns, id, transition);
	        subgroup.push(node);
	      }
	    }
	    return d3_transition(subgroups, ns, id);
	  };
	  d3_selectionPrototype.interrupt = function(name) {
	    return this.each(name == null ? d3_selection_interrupt : d3_selection_interruptNS(d3_transitionNamespace(name)));
	  };
	  var d3_selection_interrupt = d3_selection_interruptNS(d3_transitionNamespace());
	  function d3_selection_interruptNS(ns) {
	    return function() {
	      var lock, activeId, active;
	      if ((lock = this[ns]) && (active = lock[activeId = lock.active])) {
	        active.timer.c = null;
	        active.timer.t = NaN;
	        if (--lock.count) delete lock[activeId]; else delete this[ns];
	        lock.active += .5;
	        active.event && active.event.interrupt.call(this, this.__data__, active.index);
	      }
	    };
	  }
	  function d3_transition(groups, ns, id) {
	    d3_subclass(groups, d3_transitionPrototype);
	    groups.namespace = ns;
	    groups.id = id;
	    return groups;
	  }
	  var d3_transitionPrototype = [], d3_transitionId = 0, d3_transitionInheritId, d3_transitionInherit;
	  d3_transitionPrototype.call = d3_selectionPrototype.call;
	  d3_transitionPrototype.empty = d3_selectionPrototype.empty;
	  d3_transitionPrototype.node = d3_selectionPrototype.node;
	  d3_transitionPrototype.size = d3_selectionPrototype.size;
	  d3.transition = function(selection, name) {
	    return selection && selection.transition ? d3_transitionInheritId ? selection.transition(name) : selection : d3.selection().transition(selection);
	  };
	  d3.transition.prototype = d3_transitionPrototype;
	  d3_transitionPrototype.select = function(selector) {
	    var id = this.id, ns = this.namespace, subgroups = [], subgroup, subnode, node;
	    selector = d3_selection_selector(selector);
	    for (var j = -1, m = this.length; ++j < m; ) {
	      subgroups.push(subgroup = []);
	      for (var group = this[j], i = -1, n = group.length; ++i < n; ) {
	        if ((node = group[i]) && (subnode = selector.call(node, node.__data__, i, j))) {
	          if ("__data__" in node) subnode.__data__ = node.__data__;
	          d3_transitionNode(subnode, i, ns, id, node[ns][id]);
	          subgroup.push(subnode);
	        } else {
	          subgroup.push(null);
	        }
	      }
	    }
	    return d3_transition(subgroups, ns, id);
	  };
	  d3_transitionPrototype.selectAll = function(selector) {
	    var id = this.id, ns = this.namespace, subgroups = [], subgroup, subnodes, node, subnode, transition;
	    selector = d3_selection_selectorAll(selector);
	    for (var j = -1, m = this.length; ++j < m; ) {
	      for (var group = this[j], i = -1, n = group.length; ++i < n; ) {
	        if (node = group[i]) {
	          transition = node[ns][id];
	          subnodes = selector.call(node, node.__data__, i, j);
	          subgroups.push(subgroup = []);
	          for (var k = -1, o = subnodes.length; ++k < o; ) {
	            if (subnode = subnodes[k]) d3_transitionNode(subnode, k, ns, id, transition);
	            subgroup.push(subnode);
	          }
	        }
	      }
	    }
	    return d3_transition(subgroups, ns, id);
	  };
	  d3_transitionPrototype.filter = function(filter) {
	    var subgroups = [], subgroup, group, node;
	    if (typeof filter !== "function") filter = d3_selection_filter(filter);
	    for (var j = 0, m = this.length; j < m; j++) {
	      subgroups.push(subgroup = []);
	      for (var group = this[j], i = 0, n = group.length; i < n; i++) {
	        if ((node = group[i]) && filter.call(node, node.__data__, i, j)) {
	          subgroup.push(node);
	        }
	      }
	    }
	    return d3_transition(subgroups, this.namespace, this.id);
	  };
	  d3_transitionPrototype.tween = function(name, tween) {
	    var id = this.id, ns = this.namespace;
	    if (arguments.length < 2) return this.node()[ns][id].tween.get(name);
	    return d3_selection_each(this, tween == null ? function(node) {
	      node[ns][id].tween.remove(name);
	    } : function(node) {
	      node[ns][id].tween.set(name, tween);
	    });
	  };
	  function d3_transition_tween(groups, name, value, tween) {
	    var id = groups.id, ns = groups.namespace;
	    return d3_selection_each(groups, typeof value === "function" ? function(node, i, j) {
	      node[ns][id].tween.set(name, tween(value.call(node, node.__data__, i, j)));
	    } : (value = tween(value), function(node) {
	      node[ns][id].tween.set(name, value);
	    }));
	  }
	  d3_transitionPrototype.attr = function(nameNS, value) {
	    if (arguments.length < 2) {
	      for (value in nameNS) this.attr(value, nameNS[value]);
	      return this;
	    }
	    var interpolate = nameNS == "transform" ? d3_interpolateTransform : d3_interpolate, name = d3.ns.qualify(nameNS);
	    function attrNull() {
	      this.removeAttribute(name);
	    }
	    function attrNullNS() {
	      this.removeAttributeNS(name.space, name.local);
	    }
	    function attrTween(b) {
	      return b == null ? attrNull : (b += "", function() {
	        var a = this.getAttribute(name), i;
	        return a !== b && (i = interpolate(a, b), function(t) {
	          this.setAttribute(name, i(t));
	        });
	      });
	    }
	    function attrTweenNS(b) {
	      return b == null ? attrNullNS : (b += "", function() {
	        var a = this.getAttributeNS(name.space, name.local), i;
	        return a !== b && (i = interpolate(a, b), function(t) {
	          this.setAttributeNS(name.space, name.local, i(t));
	        });
	      });
	    }
	    return d3_transition_tween(this, "attr." + nameNS, value, name.local ? attrTweenNS : attrTween);
	  };
	  d3_transitionPrototype.attrTween = function(nameNS, tween) {
	    var name = d3.ns.qualify(nameNS);
	    function attrTween(d, i) {
	      var f = tween.call(this, d, i, this.getAttribute(name));
	      return f && function(t) {
	        this.setAttribute(name, f(t));
	      };
	    }
	    function attrTweenNS(d, i) {
	      var f = tween.call(this, d, i, this.getAttributeNS(name.space, name.local));
	      return f && function(t) {
	        this.setAttributeNS(name.space, name.local, f(t));
	      };
	    }
	    return this.tween("attr." + nameNS, name.local ? attrTweenNS : attrTween);
	  };
	  d3_transitionPrototype.style = function(name, value, priority) {
	    var n = arguments.length;
	    if (n < 3) {
	      if (typeof name !== "string") {
	        if (n < 2) value = "";
	        for (priority in name) this.style(priority, name[priority], value);
	        return this;
	      }
	      priority = "";
	    }
	    function styleNull() {
	      this.style.removeProperty(name);
	    }
	    function styleString(b) {
	      return b == null ? styleNull : (b += "", function() {
	        var a = d3_window(this).getComputedStyle(this, null).getPropertyValue(name), i;
	        return a !== b && (i = d3_interpolate(a, b), function(t) {
	          this.style.setProperty(name, i(t), priority);
	        });
	      });
	    }
	    return d3_transition_tween(this, "style." + name, value, styleString);
	  };
	  d3_transitionPrototype.styleTween = function(name, tween, priority) {
	    if (arguments.length < 3) priority = "";
	    function styleTween(d, i) {
	      var f = tween.call(this, d, i, d3_window(this).getComputedStyle(this, null).getPropertyValue(name));
	      return f && function(t) {
	        this.style.setProperty(name, f(t), priority);
	      };
	    }
	    return this.tween("style." + name, styleTween);
	  };
	  d3_transitionPrototype.text = function(value) {
	    return d3_transition_tween(this, "text", value, d3_transition_text);
	  };
	  function d3_transition_text(b) {
	    if (b == null) b = "";
	    return function() {
	      this.textContent = b;
	    };
	  }
	  d3_transitionPrototype.remove = function() {
	    var ns = this.namespace;
	    return this.each("end.transition", function() {
	      var p;
	      if (this[ns].count < 2 && (p = this.parentNode)) p.removeChild(this);
	    });
	  };
	  d3_transitionPrototype.ease = function(value) {
	    var id = this.id, ns = this.namespace;
	    if (arguments.length < 1) return this.node()[ns][id].ease;
	    if (typeof value !== "function") value = d3.ease.apply(d3, arguments);
	    return d3_selection_each(this, function(node) {
	      node[ns][id].ease = value;
	    });
	  };
	  d3_transitionPrototype.delay = function(value) {
	    var id = this.id, ns = this.namespace;
	    if (arguments.length < 1) return this.node()[ns][id].delay;
	    return d3_selection_each(this, typeof value === "function" ? function(node, i, j) {
	      node[ns][id].delay = +value.call(node, node.__data__, i, j);
	    } : (value = +value, function(node) {
	      node[ns][id].delay = value;
	    }));
	  };
	  d3_transitionPrototype.duration = function(value) {
	    var id = this.id, ns = this.namespace;
	    if (arguments.length < 1) return this.node()[ns][id].duration;
	    return d3_selection_each(this, typeof value === "function" ? function(node, i, j) {
	      node[ns][id].duration = Math.max(1, value.call(node, node.__data__, i, j));
	    } : (value = Math.max(1, value), function(node) {
	      node[ns][id].duration = value;
	    }));
	  };
	  d3_transitionPrototype.each = function(type, listener) {
	    var id = this.id, ns = this.namespace;
	    if (arguments.length < 2) {
	      var inherit = d3_transitionInherit, inheritId = d3_transitionInheritId;
	      try {
	        d3_transitionInheritId = id;
	        d3_selection_each(this, function(node, i, j) {
	          d3_transitionInherit = node[ns][id];
	          type.call(node, node.__data__, i, j);
	        });
	      } finally {
	        d3_transitionInherit = inherit;
	        d3_transitionInheritId = inheritId;
	      }
	    } else {
	      d3_selection_each(this, function(node) {
	        var transition = node[ns][id];
	        (transition.event || (transition.event = d3.dispatch("start", "end", "interrupt"))).on(type, listener);
	      });
	    }
	    return this;
	  };
	  d3_transitionPrototype.transition = function() {
	    var id0 = this.id, id1 = ++d3_transitionId, ns = this.namespace, subgroups = [], subgroup, group, node, transition;
	    for (var j = 0, m = this.length; j < m; j++) {
	      subgroups.push(subgroup = []);
	      for (var group = this[j], i = 0, n = group.length; i < n; i++) {
	        if (node = group[i]) {
	          transition = node[ns][id0];
	          d3_transitionNode(node, i, ns, id1, {
	            time: transition.time,
	            ease: transition.ease,
	            delay: transition.delay + transition.duration,
	            duration: transition.duration
	          });
	        }
	        subgroup.push(node);
	      }
	    }
	    return d3_transition(subgroups, ns, id1);
	  };
	  function d3_transitionNamespace(name) {
	    return name == null ? "__transition__" : "__transition_" + name + "__";
	  }
	  function d3_transitionNode(node, i, ns, id, inherit) {
	    var lock = node[ns] || (node[ns] = {
	      active: 0,
	      count: 0
	    }), transition = lock[id], time, timer, duration, ease, tweens;
	    function schedule(elapsed) {
	      var delay = transition.delay;
	      timer.t = delay + time;
	      if (delay <= elapsed) return start(elapsed - delay);
	      timer.c = start;
	    }
	    function start(elapsed) {
	      var activeId = lock.active, active = lock[activeId];
	      if (active) {
	        active.timer.c = null;
	        active.timer.t = NaN;
	        --lock.count;
	        delete lock[activeId];
	        active.event && active.event.interrupt.call(node, node.__data__, active.index);
	      }
	      for (var cancelId in lock) {
	        if (+cancelId < id) {
	          var cancel = lock[cancelId];
	          cancel.timer.c = null;
	          cancel.timer.t = NaN;
	          --lock.count;
	          delete lock[cancelId];
	        }
	      }
	      timer.c = tick;
	      d3_timer(function() {
	        if (timer.c && tick(elapsed || 1)) {
	          timer.c = null;
	          timer.t = NaN;
	        }
	        return 1;
	      }, 0, time);
	      lock.active = id;
	      transition.event && transition.event.start.call(node, node.__data__, i);
	      tweens = [];
	      transition.tween.forEach(function(key, value) {
	        if (value = value.call(node, node.__data__, i)) {
	          tweens.push(value);
	        }
	      });
	      ease = transition.ease;
	      duration = transition.duration;
	    }
	    function tick(elapsed) {
	      var t = elapsed / duration, e = ease(t), n = tweens.length;
	      while (n > 0) {
	        tweens[--n].call(node, e);
	      }
	      if (t >= 1) {
	        transition.event && transition.event.end.call(node, node.__data__, i);
	        if (--lock.count) delete lock[id]; else delete node[ns];
	        return 1;
	      }
	    }
	    if (!transition) {
	      time = inherit.time;
	      timer = d3_timer(schedule, 0, time);
	      transition = lock[id] = {
	        tween: new d3_Map(),
	        time: time,
	        timer: timer,
	        delay: inherit.delay,
	        duration: inherit.duration,
	        ease: inherit.ease,
	        index: i
	      };
	      inherit = null;
	      ++lock.count;
	    }
	  }
	  d3.svg.axis = function() {
	    var scale = d3.scale.linear(), orient = d3_svg_axisDefaultOrient, innerTickSize = 6, outerTickSize = 6, tickPadding = 3, tickArguments_ = [ 10 ], tickValues = null, tickFormat_;
	    function axis(g) {
	      g.each(function() {
	        var g = d3.select(this);
	        var scale0 = this.__chart__ || scale, scale1 = this.__chart__ = scale.copy();
	        var ticks = tickValues == null ? scale1.ticks ? scale1.ticks.apply(scale1, tickArguments_) : scale1.domain() : tickValues, tickFormat = tickFormat_ == null ? scale1.tickFormat ? scale1.tickFormat.apply(scale1, tickArguments_) : d3_identity : tickFormat_, tick = g.selectAll(".tick").data(ticks, scale1), tickEnter = tick.enter().insert("g", ".domain").attr("class", "tick").style("opacity", ε), tickExit = d3.transition(tick.exit()).style("opacity", ε).remove(), tickUpdate = d3.transition(tick.order()).style("opacity", 1), tickSpacing = Math.max(innerTickSize, 0) + tickPadding, tickTransform;
	        var range = d3_scaleRange(scale1), path = g.selectAll(".domain").data([ 0 ]), pathUpdate = (path.enter().append("path").attr("class", "domain"), 
	        d3.transition(path));
	        tickEnter.append("line");
	        tickEnter.append("text");
	        var lineEnter = tickEnter.select("line"), lineUpdate = tickUpdate.select("line"), text = tick.select("text").text(tickFormat), textEnter = tickEnter.select("text"), textUpdate = tickUpdate.select("text"), sign = orient === "top" || orient === "left" ? -1 : 1, x1, x2, y1, y2;
	        if (orient === "bottom" || orient === "top") {
	          tickTransform = d3_svg_axisX, x1 = "x", y1 = "y", x2 = "x2", y2 = "y2";
	          text.attr("dy", sign < 0 ? "0em" : ".71em").style("text-anchor", "middle");
	          pathUpdate.attr("d", "M" + range[0] + "," + sign * outerTickSize + "V0H" + range[1] + "V" + sign * outerTickSize);
	        } else {
	          tickTransform = d3_svg_axisY, x1 = "y", y1 = "x", x2 = "y2", y2 = "x2";
	          text.attr("dy", ".32em").style("text-anchor", sign < 0 ? "end" : "start");
	          pathUpdate.attr("d", "M" + sign * outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + sign * outerTickSize);
	        }
	        lineEnter.attr(y2, sign * innerTickSize);
	        textEnter.attr(y1, sign * tickSpacing);
	        lineUpdate.attr(x2, 0).attr(y2, sign * innerTickSize);
	        textUpdate.attr(x1, 0).attr(y1, sign * tickSpacing);
	        if (scale1.rangeBand) {
	          var x = scale1, dx = x.rangeBand() / 2;
	          scale0 = scale1 = function(d) {
	            return x(d) + dx;
	          };
	        } else if (scale0.rangeBand) {
	          scale0 = scale1;
	        } else {
	          tickExit.call(tickTransform, scale1, scale0);
	        }
	        tickEnter.call(tickTransform, scale0, scale1);
	        tickUpdate.call(tickTransform, scale1, scale1);
	      });
	    }
	    axis.scale = function(x) {
	      if (!arguments.length) return scale;
	      scale = x;
	      return axis;
	    };
	    axis.orient = function(x) {
	      if (!arguments.length) return orient;
	      orient = x in d3_svg_axisOrients ? x + "" : d3_svg_axisDefaultOrient;
	      return axis;
	    };
	    axis.ticks = function() {
	      if (!arguments.length) return tickArguments_;
	      tickArguments_ = d3_array(arguments);
	      return axis;
	    };
	    axis.tickValues = function(x) {
	      if (!arguments.length) return tickValues;
	      tickValues = x;
	      return axis;
	    };
	    axis.tickFormat = function(x) {
	      if (!arguments.length) return tickFormat_;
	      tickFormat_ = x;
	      return axis;
	    };
	    axis.tickSize = function(x) {
	      var n = arguments.length;
	      if (!n) return innerTickSize;
	      innerTickSize = +x;
	      outerTickSize = +arguments[n - 1];
	      return axis;
	    };
	    axis.innerTickSize = function(x) {
	      if (!arguments.length) return innerTickSize;
	      innerTickSize = +x;
	      return axis;
	    };
	    axis.outerTickSize = function(x) {
	      if (!arguments.length) return outerTickSize;
	      outerTickSize = +x;
	      return axis;
	    };
	    axis.tickPadding = function(x) {
	      if (!arguments.length) return tickPadding;
	      tickPadding = +x;
	      return axis;
	    };
	    axis.tickSubdivide = function() {
	      return arguments.length && axis;
	    };
	    return axis;
	  };
	  var d3_svg_axisDefaultOrient = "bottom", d3_svg_axisOrients = {
	    top: 1,
	    right: 1,
	    bottom: 1,
	    left: 1
	  };
	  function d3_svg_axisX(selection, x0, x1) {
	    selection.attr("transform", function(d) {
	      var v0 = x0(d);
	      return "translate(" + (isFinite(v0) ? v0 : x1(d)) + ",0)";
	    });
	  }
	  function d3_svg_axisY(selection, y0, y1) {
	    selection.attr("transform", function(d) {
	      var v0 = y0(d);
	      return "translate(0," + (isFinite(v0) ? v0 : y1(d)) + ")";
	    });
	  }
	  d3.svg.brush = function() {
	    var event = d3_eventDispatch(brush, "brushstart", "brush", "brushend"), x = null, y = null, xExtent = [ 0, 0 ], yExtent = [ 0, 0 ], xExtentDomain, yExtentDomain, xClamp = true, yClamp = true, resizes = d3_svg_brushResizes[0];
	    function brush(g) {
	      g.each(function() {
	        var g = d3.select(this).style("pointer-events", "all").style("-webkit-tap-highlight-color", "rgba(0,0,0,0)").on("mousedown.brush", brushstart).on("touchstart.brush", brushstart);
	        var background = g.selectAll(".background").data([ 0 ]);
	        background.enter().append("rect").attr("class", "background").style("visibility", "hidden").style("cursor", "crosshair");
	        g.selectAll(".extent").data([ 0 ]).enter().append("rect").attr("class", "extent").style("cursor", "move");
	        var resize = g.selectAll(".resize").data(resizes, d3_identity);
	        resize.exit().remove();
	        resize.enter().append("g").attr("class", function(d) {
	          return "resize " + d;
	        }).style("cursor", function(d) {
	          return d3_svg_brushCursor[d];
	        }).append("rect").attr("x", function(d) {
	          return /[ew]$/.test(d) ? -3 : null;
	        }).attr("y", function(d) {
	          return /^[ns]/.test(d) ? -3 : null;
	        }).attr("width", 6).attr("height", 6).style("visibility", "hidden");
	        resize.style("display", brush.empty() ? "none" : null);
	        var gUpdate = d3.transition(g), backgroundUpdate = d3.transition(background), range;
	        if (x) {
	          range = d3_scaleRange(x);
	          backgroundUpdate.attr("x", range[0]).attr("width", range[1] - range[0]);
	          redrawX(gUpdate);
	        }
	        if (y) {
	          range = d3_scaleRange(y);
	          backgroundUpdate.attr("y", range[0]).attr("height", range[1] - range[0]);
	          redrawY(gUpdate);
	        }
	        redraw(gUpdate);
	      });
	    }
	    brush.event = function(g) {
	      g.each(function() {
	        var event_ = event.of(this, arguments), extent1 = {
	          x: xExtent,
	          y: yExtent,
	          i: xExtentDomain,
	          j: yExtentDomain
	        }, extent0 = this.__chart__ || extent1;
	        this.__chart__ = extent1;
	        if (d3_transitionInheritId) {
	          d3.select(this).transition().each("start.brush", function() {
	            xExtentDomain = extent0.i;
	            yExtentDomain = extent0.j;
	            xExtent = extent0.x;
	            yExtent = extent0.y;
	            event_({
	              type: "brushstart"
	            });
	          }).tween("brush:brush", function() {
	            var xi = d3_interpolateArray(xExtent, extent1.x), yi = d3_interpolateArray(yExtent, extent1.y);
	            xExtentDomain = yExtentDomain = null;
	            return function(t) {
	              xExtent = extent1.x = xi(t);
	              yExtent = extent1.y = yi(t);
	              event_({
	                type: "brush",
	                mode: "resize"
	              });
	            };
	          }).each("end.brush", function() {
	            xExtentDomain = extent1.i;
	            yExtentDomain = extent1.j;
	            event_({
	              type: "brush",
	              mode: "resize"
	            });
	            event_({
	              type: "brushend"
	            });
	          });
	        } else {
	          event_({
	            type: "brushstart"
	          });
	          event_({
	            type: "brush",
	            mode: "resize"
	          });
	          event_({
	            type: "brushend"
	          });
	        }
	      });
	    };
	    function redraw(g) {
	      g.selectAll(".resize").attr("transform", function(d) {
	        return "translate(" + xExtent[+/e$/.test(d)] + "," + yExtent[+/^s/.test(d)] + ")";
	      });
	    }
	    function redrawX(g) {
	      g.select(".extent").attr("x", xExtent[0]);
	      g.selectAll(".extent,.n>rect,.s>rect").attr("width", xExtent[1] - xExtent[0]);
	    }
	    function redrawY(g) {
	      g.select(".extent").attr("y", yExtent[0]);
	      g.selectAll(".extent,.e>rect,.w>rect").attr("height", yExtent[1] - yExtent[0]);
	    }
	    function brushstart() {
	      var target = this, eventTarget = d3.select(d3.event.target), event_ = event.of(target, arguments), g = d3.select(target), resizing = eventTarget.datum(), resizingX = !/^(n|s)$/.test(resizing) && x, resizingY = !/^(e|w)$/.test(resizing) && y, dragging = eventTarget.classed("extent"), dragRestore = d3_event_dragSuppress(target), center, origin = d3.mouse(target), offset;
	      var w = d3.select(d3_window(target)).on("keydown.brush", keydown).on("keyup.brush", keyup);
	      if (d3.event.changedTouches) {
	        w.on("touchmove.brush", brushmove).on("touchend.brush", brushend);
	      } else {
	        w.on("mousemove.brush", brushmove).on("mouseup.brush", brushend);
	      }
	      g.interrupt().selectAll("*").interrupt();
	      if (dragging) {
	        origin[0] = xExtent[0] - origin[0];
	        origin[1] = yExtent[0] - origin[1];
	      } else if (resizing) {
	        var ex = +/w$/.test(resizing), ey = +/^n/.test(resizing);
	        offset = [ xExtent[1 - ex] - origin[0], yExtent[1 - ey] - origin[1] ];
	        origin[0] = xExtent[ex];
	        origin[1] = yExtent[ey];
	      } else if (d3.event.altKey) center = origin.slice();
	      g.style("pointer-events", "none").selectAll(".resize").style("display", null);
	      d3.select("body").style("cursor", eventTarget.style("cursor"));
	      event_({
	        type: "brushstart"
	      });
	      brushmove();
	      function keydown() {
	        if (d3.event.keyCode == 32) {
	          if (!dragging) {
	            center = null;
	            origin[0] -= xExtent[1];
	            origin[1] -= yExtent[1];
	            dragging = 2;
	          }
	          d3_eventPreventDefault();
	        }
	      }
	      function keyup() {
	        if (d3.event.keyCode == 32 && dragging == 2) {
	          origin[0] += xExtent[1];
	          origin[1] += yExtent[1];
	          dragging = 0;
	          d3_eventPreventDefault();
	        }
	      }
	      function brushmove() {
	        var point = d3.mouse(target), moved = false;
	        if (offset) {
	          point[0] += offset[0];
	          point[1] += offset[1];
	        }
	        if (!dragging) {
	          if (d3.event.altKey) {
	            if (!center) center = [ (xExtent[0] + xExtent[1]) / 2, (yExtent[0] + yExtent[1]) / 2 ];
	            origin[0] = xExtent[+(point[0] < center[0])];
	            origin[1] = yExtent[+(point[1] < center[1])];
	          } else center = null;
	        }
	        if (resizingX && move1(point, x, 0)) {
	          redrawX(g);
	          moved = true;
	        }
	        if (resizingY && move1(point, y, 1)) {
	          redrawY(g);
	          moved = true;
	        }
	        if (moved) {
	          redraw(g);
	          event_({
	            type: "brush",
	            mode: dragging ? "move" : "resize"
	          });
	        }
	      }
	      function move1(point, scale, i) {
	        var range = d3_scaleRange(scale), r0 = range[0], r1 = range[1], position = origin[i], extent = i ? yExtent : xExtent, size = extent[1] - extent[0], min, max;
	        if (dragging) {
	          r0 -= position;
	          r1 -= size + position;
	        }
	        min = (i ? yClamp : xClamp) ? Math.max(r0, Math.min(r1, point[i])) : point[i];
	        if (dragging) {
	          max = (min += position) + size;
	        } else {
	          if (center) position = Math.max(r0, Math.min(r1, 2 * center[i] - min));
	          if (position < min) {
	            max = min;
	            min = position;
	          } else {
	            max = position;
	          }
	        }
	        if (extent[0] != min || extent[1] != max) {
	          if (i) yExtentDomain = null; else xExtentDomain = null;
	          extent[0] = min;
	          extent[1] = max;
	          return true;
	        }
	      }
	      function brushend() {
	        brushmove();
	        g.style("pointer-events", "all").selectAll(".resize").style("display", brush.empty() ? "none" : null);
	        d3.select("body").style("cursor", null);
	        w.on("mousemove.brush", null).on("mouseup.brush", null).on("touchmove.brush", null).on("touchend.brush", null).on("keydown.brush", null).on("keyup.brush", null);
	        dragRestore();
	        event_({
	          type: "brushend"
	        });
	      }
	    }
	    brush.x = function(z) {
	      if (!arguments.length) return x;
	      x = z;
	      resizes = d3_svg_brushResizes[!x << 1 | !y];
	      return brush;
	    };
	    brush.y = function(z) {
	      if (!arguments.length) return y;
	      y = z;
	      resizes = d3_svg_brushResizes[!x << 1 | !y];
	      return brush;
	    };
	    brush.clamp = function(z) {
	      if (!arguments.length) return x && y ? [ xClamp, yClamp ] : x ? xClamp : y ? yClamp : null;
	      if (x && y) xClamp = !!z[0], yClamp = !!z[1]; else if (x) xClamp = !!z; else if (y) yClamp = !!z;
	      return brush;
	    };
	    brush.extent = function(z) {
	      var x0, x1, y0, y1, t;
	      if (!arguments.length) {
	        if (x) {
	          if (xExtentDomain) {
	            x0 = xExtentDomain[0], x1 = xExtentDomain[1];
	          } else {
	            x0 = xExtent[0], x1 = xExtent[1];
	            if (x.invert) x0 = x.invert(x0), x1 = x.invert(x1);
	            if (x1 < x0) t = x0, x0 = x1, x1 = t;
	          }
	        }
	        if (y) {
	          if (yExtentDomain) {
	            y0 = yExtentDomain[0], y1 = yExtentDomain[1];
	          } else {
	            y0 = yExtent[0], y1 = yExtent[1];
	            if (y.invert) y0 = y.invert(y0), y1 = y.invert(y1);
	            if (y1 < y0) t = y0, y0 = y1, y1 = t;
	          }
	        }
	        return x && y ? [ [ x0, y0 ], [ x1, y1 ] ] : x ? [ x0, x1 ] : y && [ y0, y1 ];
	      }
	      if (x) {
	        x0 = z[0], x1 = z[1];
	        if (y) x0 = x0[0], x1 = x1[0];
	        xExtentDomain = [ x0, x1 ];
	        if (x.invert) x0 = x(x0), x1 = x(x1);
	        if (x1 < x0) t = x0, x0 = x1, x1 = t;
	        if (x0 != xExtent[0] || x1 != xExtent[1]) xExtent = [ x0, x1 ];
	      }
	      if (y) {
	        y0 = z[0], y1 = z[1];
	        if (x) y0 = y0[1], y1 = y1[1];
	        yExtentDomain = [ y0, y1 ];
	        if (y.invert) y0 = y(y0), y1 = y(y1);
	        if (y1 < y0) t = y0, y0 = y1, y1 = t;
	        if (y0 != yExtent[0] || y1 != yExtent[1]) yExtent = [ y0, y1 ];
	      }
	      return brush;
	    };
	    brush.clear = function() {
	      if (!brush.empty()) {
	        xExtent = [ 0, 0 ], yExtent = [ 0, 0 ];
	        xExtentDomain = yExtentDomain = null;
	      }
	      return brush;
	    };
	    brush.empty = function() {
	      return !!x && xExtent[0] == xExtent[1] || !!y && yExtent[0] == yExtent[1];
	    };
	    return d3.rebind(brush, event, "on");
	  };
	  var d3_svg_brushCursor = {
	    n: "ns-resize",
	    e: "ew-resize",
	    s: "ns-resize",
	    w: "ew-resize",
	    nw: "nwse-resize",
	    ne: "nesw-resize",
	    se: "nwse-resize",
	    sw: "nesw-resize"
	  };
	  var d3_svg_brushResizes = [ [ "n", "e", "s", "w", "nw", "ne", "se", "sw" ], [ "e", "w" ], [ "n", "s" ], [] ];
	  var d3_time_format = d3_time.format = d3_locale_enUS.timeFormat;
	  var d3_time_formatUtc = d3_time_format.utc;
	  var d3_time_formatIso = d3_time_formatUtc("%Y-%m-%dT%H:%M:%S.%LZ");
	  d3_time_format.iso = Date.prototype.toISOString && +new Date("2000-01-01T00:00:00.000Z") ? d3_time_formatIsoNative : d3_time_formatIso;
	  function d3_time_formatIsoNative(date) {
	    return date.toISOString();
	  }
	  d3_time_formatIsoNative.parse = function(string) {
	    var date = new Date(string);
	    return isNaN(date) ? null : date;
	  };
	  d3_time_formatIsoNative.toString = d3_time_formatIso.toString;
	  d3_time.second = d3_time_interval(function(date) {
	    return new d3_date(Math.floor(date / 1e3) * 1e3);
	  }, function(date, offset) {
	    date.setTime(date.getTime() + Math.floor(offset) * 1e3);
	  }, function(date) {
	    return date.getSeconds();
	  });
	  d3_time.seconds = d3_time.second.range;
	  d3_time.seconds.utc = d3_time.second.utc.range;
	  d3_time.minute = d3_time_interval(function(date) {
	    return new d3_date(Math.floor(date / 6e4) * 6e4);
	  }, function(date, offset) {
	    date.setTime(date.getTime() + Math.floor(offset) * 6e4);
	  }, function(date) {
	    return date.getMinutes();
	  });
	  d3_time.minutes = d3_time.minute.range;
	  d3_time.minutes.utc = d3_time.minute.utc.range;
	  d3_time.hour = d3_time_interval(function(date) {
	    var timezone = date.getTimezoneOffset() / 60;
	    return new d3_date((Math.floor(date / 36e5 - timezone) + timezone) * 36e5);
	  }, function(date, offset) {
	    date.setTime(date.getTime() + Math.floor(offset) * 36e5);
	  }, function(date) {
	    return date.getHours();
	  });
	  d3_time.hours = d3_time.hour.range;
	  d3_time.hours.utc = d3_time.hour.utc.range;
	  d3_time.month = d3_time_interval(function(date) {
	    date = d3_time.day(date);
	    date.setDate(1);
	    return date;
	  }, function(date, offset) {
	    date.setMonth(date.getMonth() + offset);
	  }, function(date) {
	    return date.getMonth();
	  });
	  d3_time.months = d3_time.month.range;
	  d3_time.months.utc = d3_time.month.utc.range;
	  function d3_time_scale(linear, methods, format) {
	    function scale(x) {
	      return linear(x);
	    }
	    scale.invert = function(x) {
	      return d3_time_scaleDate(linear.invert(x));
	    };
	    scale.domain = function(x) {
	      if (!arguments.length) return linear.domain().map(d3_time_scaleDate);
	      linear.domain(x);
	      return scale;
	    };
	    function tickMethod(extent, count) {
	      var span = extent[1] - extent[0], target = span / count, i = d3.bisect(d3_time_scaleSteps, target);
	      return i == d3_time_scaleSteps.length ? [ methods.year, d3_scale_linearTickRange(extent.map(function(d) {
	        return d / 31536e6;
	      }), count)[2] ] : !i ? [ d3_time_scaleMilliseconds, d3_scale_linearTickRange(extent, count)[2] ] : methods[target / d3_time_scaleSteps[i - 1] < d3_time_scaleSteps[i] / target ? i - 1 : i];
	    }
	    scale.nice = function(interval, skip) {
	      var domain = scale.domain(), extent = d3_scaleExtent(domain), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" && tickMethod(extent, interval);
	      if (method) interval = method[0], skip = method[1];
	      function skipped(date) {
	        return !isNaN(date) && !interval.range(date, d3_time_scaleDate(+date + 1), skip).length;
	      }
	      return scale.domain(d3_scale_nice(domain, skip > 1 ? {
	        floor: function(date) {
	          while (skipped(date = interval.floor(date))) date = d3_time_scaleDate(date - 1);
	          return date;
	        },
	        ceil: function(date) {
	          while (skipped(date = interval.ceil(date))) date = d3_time_scaleDate(+date + 1);
	          return date;
	        }
	      } : interval));
	    };
	    scale.ticks = function(interval, skip) {
	      var extent = d3_scaleExtent(scale.domain()), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" ? tickMethod(extent, interval) : !interval.range && [ {
	        range: interval
	      }, skip ];
	      if (method) interval = method[0], skip = method[1];
	      return interval.range(extent[0], d3_time_scaleDate(+extent[1] + 1), skip < 1 ? 1 : skip);
	    };
	    scale.tickFormat = function() {
	      return format;
	    };
	    scale.copy = function() {
	      return d3_time_scale(linear.copy(), methods, format);
	    };
	    return d3_scale_linearRebind(scale, linear);
	  }
	  function d3_time_scaleDate(t) {
	    return new Date(t);
	  }
	  var d3_time_scaleSteps = [ 1e3, 5e3, 15e3, 3e4, 6e4, 3e5, 9e5, 18e5, 36e5, 108e5, 216e5, 432e5, 864e5, 1728e5, 6048e5, 2592e6, 7776e6, 31536e6 ];
	  var d3_time_scaleLocalMethods = [ [ d3_time.second, 1 ], [ d3_time.second, 5 ], [ d3_time.second, 15 ], [ d3_time.second, 30 ], [ d3_time.minute, 1 ], [ d3_time.minute, 5 ], [ d3_time.minute, 15 ], [ d3_time.minute, 30 ], [ d3_time.hour, 1 ], [ d3_time.hour, 3 ], [ d3_time.hour, 6 ], [ d3_time.hour, 12 ], [ d3_time.day, 1 ], [ d3_time.day, 2 ], [ d3_time.week, 1 ], [ d3_time.month, 1 ], [ d3_time.month, 3 ], [ d3_time.year, 1 ] ];
	  var d3_time_scaleLocalFormat = d3_time_format.multi([ [ ".%L", function(d) {
	    return d.getMilliseconds();
	  } ], [ ":%S", function(d) {
	    return d.getSeconds();
	  } ], [ "%I:%M", function(d) {
	    return d.getMinutes();
	  } ], [ "%I %p", function(d) {
	    return d.getHours();
	  } ], [ "%a %d", function(d) {
	    return d.getDay() && d.getDate() != 1;
	  } ], [ "%b %d", function(d) {
	    return d.getDate() != 1;
	  } ], [ "%B", function(d) {
	    return d.getMonth();
	  } ], [ "%Y", d3_true ] ]);
	  var d3_time_scaleMilliseconds = {
	    range: function(start, stop, step) {
	      return d3.range(Math.ceil(start / step) * step, +stop, step).map(d3_time_scaleDate);
	    },
	    floor: d3_identity,
	    ceil: d3_identity
	  };
	  d3_time_scaleLocalMethods.year = d3_time.year;
	  d3_time.scale = function() {
	    return d3_time_scale(d3.scale.linear(), d3_time_scaleLocalMethods, d3_time_scaleLocalFormat);
	  };
	  var d3_time_scaleUtcMethods = d3_time_scaleLocalMethods.map(function(m) {
	    return [ m[0].utc, m[1] ];
	  });
	  var d3_time_scaleUtcFormat = d3_time_formatUtc.multi([ [ ".%L", function(d) {
	    return d.getUTCMilliseconds();
	  } ], [ ":%S", function(d) {
	    return d.getUTCSeconds();
	  } ], [ "%I:%M", function(d) {
	    return d.getUTCMinutes();
	  } ], [ "%I %p", function(d) {
	    return d.getUTCHours();
	  } ], [ "%a %d", function(d) {
	    return d.getUTCDay() && d.getUTCDate() != 1;
	  } ], [ "%b %d", function(d) {
	    return d.getUTCDate() != 1;
	  } ], [ "%B", function(d) {
	    return d.getUTCMonth();
	  } ], [ "%Y", d3_true ] ]);
	  d3_time_scaleUtcMethods.year = d3_time.year.utc;
	  d3_time.scale.utc = function() {
	    return d3_time_scale(d3.scale.linear(), d3_time_scaleUtcMethods, d3_time_scaleUtcFormat);
	  };
	  d3.text = d3_xhrType(function(request) {
	    return request.responseText;
	  });
	  d3.json = function(url, callback) {
	    return d3_xhr(url, "application/json", d3_json, callback);
	  };
	  function d3_json(request) {
	    return JSON.parse(request.responseText);
	  }
	  d3.html = function(url, callback) {
	    return d3_xhr(url, "text/html", d3_html, callback);
	  };
	  function d3_html(request) {
	    var range = d3_document.createRange();
	    range.selectNode(d3_document.body);
	    return range.createContextualFragment(request.responseText);
	  }
	  d3.xml = d3_xhrType(function(request) {
	    return request.responseXML;
	  });
	  if (true) this.d3 = d3, !(__WEBPACK_AMD_DEFINE_FACTORY__ = (d3), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); else if (typeof module === "object" && module.exports) module.exports = d3; else this.d3 = d3;
	}();

/***/ },
/* 5 */
/***/ function(module, exports, __webpack_require__) {

	module.exports =
	/******/ (function(modules) { // webpackBootstrap
	/******/ 	// The module cache
	/******/ 	var installedModules = {};
	
	/******/ 	// The require function
	/******/ 	function __webpack_require__(moduleId) {
	
	/******/ 		// Check if module is in cache
	/******/ 		if(installedModules[moduleId])
	/******/ 			return installedModules[moduleId].exports;
	
	/******/ 		// Create a new module (and put it into the cache)
	/******/ 		var module = installedModules[moduleId] = {
	/******/ 			exports: {},
	/******/ 			id: moduleId,
	/******/ 			loaded: false
	/******/ 		};
	
	/******/ 		// Execute the module function
	/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
	
	/******/ 		// Flag the module as loaded
	/******/ 		module.loaded = true;
	
	/******/ 		// Return the exports of the module
	/******/ 		return module.exports;
	/******/ 	}
	
	
	/******/ 	// expose the modules object (__webpack_modules__)
	/******/ 	__webpack_require__.m = modules;
	
	/******/ 	// expose the module cache
	/******/ 	__webpack_require__.c = installedModules;
	
	/******/ 	// __webpack_public_path__
	/******/ 	__webpack_require__.p = "";
	
	/******/ 	// Load entry module and return exports
	/******/ 	return __webpack_require__(0);
	/******/ })
	/************************************************************************/
	/******/ ([
	/* 0 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var make_config = __webpack_require__(1);
		var make_params = __webpack_require__(9);
		var make_viz = __webpack_require__(37);
		var resize_viz = __webpack_require__(88);
		var play_demo = __webpack_require__(129);
		var ini_demo = __webpack_require__(169);
		var filter_viz_using_nodes = __webpack_require__(172);
		var filter_viz_using_names = __webpack_require__(173);
		var update_cats = __webpack_require__(174);
		var reset_cats = __webpack_require__(175);
		var two_translate_zoom = __webpack_require__(80);
		var external_update_view = __webpack_require__(177);
		var save_matrix = __webpack_require__(180);
		var brush_crop_matrix = __webpack_require__(184);
		var run_zoom = __webpack_require__(89);
		var d3_tip_custom = __webpack_require__(48);
		var all_reorder = __webpack_require__(79);
		var make_matrix_string = __webpack_require__(182);
	
		// moved d3.slider to src
		d3.slider = __webpack_require__(186);
	
		/* eslint-disable */
	
		var awesomplete = __webpack_require__(188);
		// getting css from src
		__webpack_require__(190);
		__webpack_require__(194);
	
		/* clustergrammer v1.16.0
		 * Nicolas Fernandez, Ma'ayan Lab, Icahn School of Medicine at Mount Sinai
		 * (c) 2017
		 */
		function Clustergrammer(args) {
	
		  /* Main program
		   * ----------------------------------------------------------------------- */
		  // consume and validate user input
		  // build giant config object
		  // visualize based on config object
		  // handle user events
	
		  // consume and validate user arguments, produce configuration object
		  var config = make_config(args);
	
		  var cgm = {};
	
		  // make visualization parameters using configuration object
		  cgm.params = make_params(config);
		  cgm.config = config;
	
		  // set up zoom
		  cgm.params.zoom_behavior = d3.behavior.zoom().scaleExtent([1, cgm.params.viz.square_zoom * cgm.params.viz.zoom_ratio.x]).on('zoom', function () {
		    run_zoom(cgm);
		  });
	
		  cgm.params.zoom_behavior.translate([cgm.params.viz.clust.margin.left, cgm.params.viz.clust.margin.top]);
	
		  if (cgm.params.use_sidebar) {
		    var make_sidebar = __webpack_require__(196);
		    make_sidebar(cgm);
		  }
	
		  // make visualization using parameters
		  make_viz(cgm);
	
		  function external_resize() {
	
		    d3.select(cgm.params.viz.viz_svg).style('opacity', 0.5);
	
		    var wait_time = 500;
		    if (this.params.viz.run_trans === true) {
		      wait_time = 2500;
		    }
	
		    setTimeout(resize_fun, wait_time, this);
		  }
	
		  function resize_fun(cgm) {
		    resize_viz(cgm);
		  }
	
		  function run_update_cats(cat_data) {
		    update_cats(this, cat_data);
		  }
	
		  function zoom_api(pan_dx, pan_dy, fin_zoom) {
		    two_translate_zoom(this, pan_dx, pan_dy, fin_zoom);
		  }
	
		  function expose_d3_tip_custom() {
		    // this allows external modules to have access to d3_tip
		    return d3_tip_custom;
		  }
	
		  function api_reorder(inst_rc, inst_order) {
		    if (inst_order === 'sum') {
		      inst_order = 'rank';
		    }
		    if (inst_order === 'var') {
		      inst_order = 'rankvar';
		    }
		    all_reorder(this, inst_order, inst_rc);
		  }
	
		  function export_matrix_string() {
		    return make_matrix_string(this.params);
		  }
	
		  // add more API endpoints
		  cgm.update_view = external_update_view;
		  cgm.resize_viz = external_resize;
		  cgm.play_demo = play_demo;
		  cgm.ini_demo = ini_demo;
		  cgm.filter_viz_using_nodes = filter_viz_using_nodes;
		  cgm.filter_viz_using_names = filter_viz_using_names;
		  cgm.update_cats = run_update_cats;
		  cgm.reset_cats = reset_cats;
		  cgm.zoom = zoom_api;
		  cgm.save_matrix = save_matrix;
		  cgm.brush_crop_matrix = brush_crop_matrix;
		  cgm.d3_tip_custom = expose_d3_tip_custom;
		  cgm.reorder = api_reorder;
		  cgm.export_matrix_string = export_matrix_string;
	
		  return cgm;
		}
	
		module.exports = Clustergrammer;
	
	/***/ },
	/* 1 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var utils = __webpack_require__(2);
		var transpose_network = __webpack_require__(3);
		var get_available_filters = __webpack_require__(4);
		var get_filter_default_state = __webpack_require__(5);
		var set_defaults = __webpack_require__(6);
		var check_sim_mat = __webpack_require__(7);
		var check_nodes_for_categories = __webpack_require__(8);
	
		module.exports = function make_config(args) {
	
		  var defaults = set_defaults();
	
		  // Mixin defaults with user-defined arguments.
		  var config = utils.extend(defaults, args);
	
		  config.network_data = args.network_data;
	
		  var super_string = ': ';
	
		  // replace undersores with space in row/col names
		  _.each(['row', 'col'], function (inst_rc) {
	
		    var inst_nodes = config.network_data[inst_rc + '_nodes'];
	
		    var has_cats = check_nodes_for_categories(inst_nodes);
	
		    inst_nodes.forEach(function (d, i) {
	
		      // add index to row_nodes and col_nodes
		      d[inst_rc + '_index'] = i;
	
		      if (has_cats) {
		        config.super_labels = true;
		        config.super[inst_rc] = d.name.split(super_string)[0];
		        d.name = d.name.split(super_string)[1];
		      }
	
		      d.name = String(d.name);
	
		      d.name = d.name.replace(/_/g, ' ');
		    });
		  });
	
		  config.network_data.row_nodes_names = utils.pluck(config.network_data.row_nodes, 'name');
		  config.network_data.col_nodes_names = utils.pluck(config.network_data.col_nodes, 'name');
	
		  config.sim_mat = check_sim_mat(config);
	
		  var filters = get_available_filters(config.network_data.views);
	
		  var default_states = {};
		  _.each(_.keys(filters.possible_filters), function (inst_filter) {
		    var tmp_state = get_filter_default_state(filters.filter_data, inst_filter);
	
		    default_states[inst_filter] = tmp_state;
		  });
	
		  // process view
		  if (_.has(config.network_data, 'views')) {
		    config.network_data.views.forEach(function (inst_view) {
	
		      _.each(_.keys(filters.possible_filters), function (inst_filter) {
		        if (!_.has(inst_view, inst_filter)) {
		          inst_view[inst_filter] = default_states[inst_filter];
		        }
		      });
	
		      var inst_nodes = inst_view.nodes;
	
		      // proc row/col nodes names in views
		      _.each(['row', 'col'], function (inst_rc) {
	
		        var has_cats = check_nodes_for_categories(inst_nodes[inst_rc + '_nodes']);
	
		        inst_nodes[inst_rc + '_nodes'].forEach(function (d, i) {
	
		          // add index to row_nodes and col_nodes
		          d[inst_rc + '_index'] = i;
	
		          if (has_cats) {
		            d.name = d.name.split(super_string)[1];
		          }
	
		          d.name = String(d.name);
		          d.name = d.name.replace(/_/g, ' ');
		        });
		      });
		    });
		  }
	
		  var col_nodes = config.network_data.col_nodes;
		  var row_nodes = config.network_data.row_nodes;
	
		  // console.log( config.network_data.links[0] )
		  // console.log( config.network_data.links[1] )
		  // console.log( config.network_data.links[2] )
	
		  // console.log(_.has(config.network_data,'mat'));
	
		  ///////////////////////////
		  // convert 'mat' to links
		  ///////////////////////////
	
		  if (_.has(config.network_data, 'mat')) {
	
		    var links = [];
		    var mat = config.network_data.mat;
		    var inst_link = {};
	
		    // console.log('found mat')
		    for (var i = 0; i < mat.length; i++) {
		      for (var j = 0; j < mat[0].length; j++) {
		        // console.log(mat[i][j])
	
		        inst_link = {};
		        inst_link.source = i;
		        inst_link.target = j;
		        inst_link.value = mat[i][j];
		        links.push(inst_link);
		      }
		    }
	
		    // save to network_data
		    config.network_data.links = links;
		  }
	
		  // add names and instantaneous positions to links
		  config.network_data.links.forEach(function (d) {
		    d.name = row_nodes[d.source].name + '_' + col_nodes[d.target].name;
		    d.row_name = row_nodes[d.source].name;
		    d.col_name = col_nodes[d.target].name;
		  });
	
		  // transpose network if necessary
		  if (config.transpose) {
		    config.network_data = transpose_network(config.network_data);
		    var tmp_col_label = args.col_label;
		    var tmp_row_label = args.row_label;
		    args.row_label = tmp_col_label;
		    args.col_label = tmp_row_label;
		  }
	
		  // super-row/col labels
		  if (!utils.is_undefined(args.row_label) && !utils.is_undefined(args.col_label)) {
		    config.super_labels = true;
		    config.super = {};
		    config.super.row = args.row_label;
		    config.super.col = args.col_label;
		  }
	
		  // initialize cluster ordering - both rows and columns
		  config.inst_order = {};
		  if (!utils.is_undefined(args.order) && utils.is_supported_order(args.order)) {
		    config.inst_order.row = args.order;
		    config.inst_order.col = args.order;
		  } else {
		    config.inst_order.row = 'clust';
		    config.inst_order.col = 'clust';
		  }
	
		  // set row or column order directly -- note that row/col are swapped
		  // !! need to swap row/col orderings
		  if (!utils.is_undefined(args.row_order) && utils.is_supported_order(args.row_order)) {
		    // !! row and col orderings are swapped, need to fix
		    config.inst_order.col = args.row_order;
		  }
	
		  if (!utils.is_undefined(args.col_order) && utils.is_supported_order(args.col_order)) {
		    // !! row and col orderings are swapped, need to fix
		    config.inst_order.row = args.col_order;
		  }
	
		  var row_has_group = utils.has(config.network_data.row_nodes[0], 'group');
		  var col_has_group = utils.has(config.network_data.col_nodes[0], 'group');
	
		  config.show_dendrogram = row_has_group || col_has_group;
	
		  if (utils.has(config.network_data.links[0], 'value_orig')) {
		    config.keep_orig = true;
		  } else {
		    config.keep_orig = false;
		  }
	
		  return config;
		};
	
	/***/ },
	/* 2 */
	/***/ function(module, exports) {
	
		'use strict';
	
		var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
	
		/* Utility functions
		 * ----------------------------------------------------------------------- */
		module.exports = {
		  normal_name: function normal_name(d) {
		    var inst_name = d.name.replace(/_/g, ' ').split('#')[0];
		    return inst_name;
		  },
		  is_supported_order: function is_supported_order(order) {
		    return order === 'ini' || order === 'clust' || order === 'rank_var' || order === 'rank' || order === 'class' || order == 'alpha';
		  },
	
		  /* Returns whether or not an object has a certain property.
		   */
		  has: function has(obj, key) {
		    return obj != null && hasOwnProperty.call(obj, key);
		  },
	
		  property: function property(key) {
		    return function (obj) {
		      return obj == null ? void 0 : obj[key];
		    };
		  },
	
		  // Convenience version of a common use case of `map`: fetching a property.
		  pluck: function pluck(arr, key) {
		    var self = this;
		    // Double check that we have lodash or underscore available
		    if (window._) {
		      // Underscore provides a _.pluck function. Use that.
		      if (typeof _.pluck === 'function') {
		        return _.pluck(arr, key);
		      } else if (typeof _.map === 'function') {
		        // Lodash does not have a pluck function.
		        // Use _.map with the property function defined above.
		        return _.map(arr, self.property(key));
		      }
		    } else if (arr.map && typeof arr.map === 'function') {
		      // If lodash or underscore not available, check to see if the native arr.map is available.
		      // If so, use it with the property function defined above.
		      return arr.map(self.property(key));
		    }
		  },
	
		  /* Returns true if the object is undefined.
		   */
		  is_undefined: function is_undefined(obj) {
		    return obj === void 0;
		  },
	
		  /* Mixes two objects in together, overwriting a target with a source.
		   */
		  extend: function extend(target, source) {
		    target = target || {};
		    for (var prop in source) {
		      if (_typeof(source[prop]) === 'object') {
		        target[prop] = this.extend(target[prop], source[prop]);
		      } else {
		        target[prop] = source[prop];
		      }
		    }
		    return target;
		  }
			};
	
	/***/ },
	/* 3 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var utils = __webpack_require__(2);
		/* Transpose network.
		 */
		module.exports = function (net) {
		  var tnet = {},
		      inst_link,
		      i;
	
		  tnet.row_nodes = net.col_nodes;
		  tnet.col_nodes = net.row_nodes;
		  tnet.links = [];
	
		  for (i = 0; i < net.links.length; i++) {
		    inst_link = {};
		    inst_link.source = net.links[i].target;
		    inst_link.target = net.links[i].source;
		    inst_link.value = net.links[i].value;
	
		    // Optional highlight.
		    if (utils.has(net.links[i], 'highlight')) {
		      inst_link.highlight = net.links[i].highlight;
		    }
		    if (utils.has(net.links[i], 'value_up')) {
		      inst_link.value_up = net.links[i].value_up;
		    }
		    if (utils.has(net.links[i], 'value_dn')) {
		      inst_link.value_dn = net.links[i].value_dn;
		    }
		    if (utils.has(net.links[i], 'info')) {
		      inst_link.info = net.links[i].info;
		    }
		    tnet.links.push(inst_link);
		  }
	
		  return tnet;
		};
	
	/***/ },
	/* 4 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function get_available_filters(views) {
	
		  var possible_filters = {};
		  var filter_data = {};
	
		  _.each(views, function (inst_view) {
		    var inst_keys = _.keys(inst_view);
	
		    _.each(inst_keys, function (inst_key) {
	
		      if (inst_key != 'nodes') {
	
		        if (!_.has(filter_data, inst_key)) {
		          filter_data[inst_key] = [];
		        }
	
		        filter_data[inst_key].push(inst_view[inst_key]);
	
		        filter_data[inst_key] = _.uniq(filter_data[inst_key]);
		      }
		    });
		  });
	
		  var tmp_filters = _.keys(filter_data);
	
		  _.each(tmp_filters, function (inst_filter) {
	
		    var options = filter_data[inst_filter];
		    var num_options = options.length;
	
		    var filter_type = 'categorical';
		    _.each(options, function (inst_option) {
		      if (typeof inst_option === 'number') {
		        filter_type = 'numerical';
		      }
		    });
	
		    if (num_options > 1) {
		      possible_filters[inst_filter] = filter_type;
		    }
		  });
	
		  var filters = {};
		  filters.possible_filters = possible_filters;
		  filters.filter_data = filter_data;
	
		  return filters;
			};
	
	/***/ },
	/* 5 */
	/***/ function(module, exports) {
	
		"use strict";
	
		module.exports = function get_filter_default_state(filter_data, filter_type) {
	
		  var default_state = filter_data[filter_type].sort(function (a, b) {
		    return b - a;
		  })[0];
	
		  default_state = String(default_state);
	
		  return default_state;
		};
	
	/***/ },
	/* 6 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function set_defaults() {
	
		  var defaults = {
		    // Label options
		    row_label_scale: 1,
		    col_label_scale: 1,
		    super_labels: false,
		    super: {},
		    show_label_tooltips: true,
		    show_tile_tooltips: true,
		    // matrix options
		    transpose: false,
		    tile_colors: ['#FF0000', '#1C86EE'],
		    bar_colors: ['#FF0000', '#1C86EE'],
		    // value-cat colors
		    // cat_value_colors: ['#2F4F4F', '#8A2BE2'],
		    cat_value_colors: ['#2F4F4F', '#9370DB'],
		    outline_colors: ['orange', 'black'],
		    highlight_color: '#FFFF00',
		    tile_title: false,
		    // Default domain is set to 0: the domain will be set automatically
		    input_domain: 0,
		    opacity_scale: 'linear',
		    do_zoom: true,
		    is_zoom: 0,
		    is_slider_drag: false,
		    is_cropping: false,
		    background_color: '#FFFFFF',
		    super_border_color: '#F5F5F5',
		    outer_margins: {
		      top: 0,
		      bottom: 0,
		      left: 0,
		      right: 0
		    },
		    ini_expand: false,
		    grey_border_width: 2,
		    tile_click_hlight: false,
		    super_label_scale: 1,
		    make_tile_tooltip: function make_tile_tooltip(d) {
		      return d.info;
		    },
		    // initialize view, e.g. initialize with row filtering
		    ini_view: null,
		    // record of requested views
		    requested_view: null,
		    use_sidebar: true,
		    title: null,
		    about: null,
		    sidebar_width: 160,
		    sidebar_icons: true,
		    row_search_placeholder: 'Row',
		    buffer_width: 10,
		    show_sim_mat: false,
		    cat_colors: null,
		    resize: true,
		    clamp_opacity: 0.85,
		    expand_button: true,
		    max_allow_fs: 20,
		    dendro_filter: { 'row': false, 'col': false },
		    cat_filter: { 'row': false, 'col': false },
		    crop_filter_nodes: { 'row': false, 'col': false },
		    row_tip_callback: null,
		    col_tip_callback: null,
		    tile_tip_callback: null,
		    matrix_update_callback: null,
		    cat_update_callback: null,
		    dendro_callback: null,
		    dendro_click_callback: null,
		    new_row_cats: null,
		    make_modals: true,
		    show_viz_border: false
		  };
	
		  return defaults;
		};
	
	/***/ },
	/* 7 */
	/***/ function(module, exports) {
	
		"use strict";
	
		module.exports = function check_sim_mat(config) {
	
		  var sim_mat = false;
	
		  var num_rows = config.network_data.row_nodes_names.length;
		  var num_cols = config.network_data.col_nodes_names.length;
	
		  if (num_rows == num_cols) {
	
		    // the sort here was causing errors 
		    var rows = config.network_data.row_nodes_names;
		    var cols = config.network_data.col_nodes_names;
		    sim_mat = true;
	
		    _.each(rows, function (inst_row) {
		      var inst_index = rows.indexOf(inst_row);
		      if (inst_row !== cols[inst_index]) {
		        sim_mat = false;
		      }
		    });
		  }
	
		  if (sim_mat) {
		    config.expand_button = false;
		  }
	
		  return sim_mat;
		};
	
	/***/ },
	/* 8 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function check_nodes_for_categories(nodes) {
	
		  var super_string = ': ';
		  var has_cat = true;
	
		  _.each(nodes, function (inst_node) {
		    var inst_name = String(inst_node.name);
		    if (inst_name.indexOf(super_string) < 0) {
		      has_cat = false;
		    }
		  });
	
		  return has_cat;
			};
	
	/***/ },
	/* 9 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var make_network_using_view = __webpack_require__(10);
		var ini_sidebar_params = __webpack_require__(13);
		var make_requested_view = __webpack_require__(14);
		var get_available_filters = __webpack_require__(4);
		var calc_viz_params = __webpack_require__(15);
		var ini_zoom_info = __webpack_require__(36);
	
		/*
		Params: calculates the size of all the visualization elements in the
		clustergram.
		 */
	
		module.exports = function make_params(input_config) {
	
		  var config = $.extend(true, {}, input_config);
		  var params = config;
	
		  // keep a copy of inst_view
		  params.inst_nodes = {};
		  params.inst_nodes.row_nodes = params.network_data.row_nodes;
		  params.inst_nodes.col_nodes = params.network_data.col_nodes;
	
		  // when pre-loading the visualization using a view
		  if (params.ini_view !== null) {
	
		    var requested_view = params.ini_view;
	
		    var filters = get_available_filters(params.network_data.views);
	
		    params.viz = {};
		    params.viz.possible_filters = filters.possible_filters;
		    params.viz.filter_data = filters.filter_data;
	
		    requested_view = make_requested_view(params, requested_view);
		    params.network_data = make_network_using_view(config, params, requested_view);
	
		    // save ini_view as requested_view
		    params.requested_view = requested_view;
		  }
	
		  params = calc_viz_params(params);
	
		  if (params.use_sidebar) {
		    params.sidebar = ini_sidebar_params(params);
		  }
	
		  params.zoom_info = ini_zoom_info();
	
		  return params;
		};
	
	/***/ },
	/* 10 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var filter_network_using_new_nodes = __webpack_require__(11);
		var get_subset_views = __webpack_require__(12);
	
		module.exports = function make_network_using_view(config, params, requested_view) {
	
		  var orig_views = config.network_data.views;
	
		  var is_enr = false;
		  if (_.has(orig_views[0], 'enr_score_type')) {
		    is_enr = true;
		  }
	
		  var sub_views = get_subset_views(params, orig_views, requested_view);
	
		  //////////////////////////////
		  // Enrichr specific rules
		  //////////////////////////////
		  if (is_enr && sub_views.length == 0) {
		    requested_view = { 'N_row_sum': 'all', 'N_col_sum': '10' };
		    sub_views = get_subset_views(params, orig_views, requested_view);
		  }
	
		  var inst_view = sub_views[0];
	
		  var new_network_data;
	
		  // get new_network_data or default back to old_network_data
		  if (typeof inst_view !== 'undefined') {
		    var new_nodes = inst_view.nodes;
		    new_network_data = filter_network_using_new_nodes(config, new_nodes);
		  } else {
		    new_network_data = config.network_data;
		  }
	
		  return new_network_data;
		};
	
	/***/ },
	/* 11 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var utils = __webpack_require__(2);
	
		module.exports = function filter_network_using_new_nodes(config, new_nodes) {
	
		  var links = config.network_data.links;
	
		  // get new names of rows and cols
		  var row_names = utils.pluck(new_nodes.row_nodes, 'name');
		  var col_names = utils.pluck(new_nodes.col_nodes, 'name');
	
		  var new_links = _.filter(links, function (d) {
		    var inst_row = d.name.split('_')[0];
		    var inst_col = d.name.split('_')[1];
	
		    var row_index = _.indexOf(row_names, inst_row);
		    var col_index = _.indexOf(col_names, inst_col);
	
		    if (row_index > -1 & col_index > -1) {
		      // redefine source and target
		      d.source = row_index;
		      d.target = col_index;
		      return d;
		    }
		  });
	
		  // set up new_network_data
		  var new_network_data = {};
		  // rows
		  new_network_data.row_nodes = new_nodes.row_nodes;
		  new_network_data.row_nodes_names = row_names;
		  // cols
		  new_network_data.col_nodes = new_nodes.col_nodes;
		  new_network_data.col_nodes_names = col_names;
		  // links
		  new_network_data.links = new_links;
		  // save all links
		  new_network_data.all_links = links;
		  // add back all views
		  new_network_data.views = config.network_data.views;
	
		  // add cat_colors if necessary
		  if (_.has(config.network_data, 'cat_colors')) {
		    new_network_data.cat_colors = config.network_data.cat_colors;
		  }
	
		  return new_network_data;
		};
	
	/***/ },
	/* 12 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var utils = __webpack_require__(2);
		var get_filter_default_state = __webpack_require__(5);
	
		module.exports = function get_subset_views(params, views, requested_view) {
	
		  var inst_value;
		  var found_filter;
	
		  var request_filters = _.keys(requested_view);
	
		  // find a view that matches all of the requested view/filter-attributes 
		  _.each(request_filters, function (inst_filter) {
	
		    inst_value = requested_view[inst_filter];
	
		    // if the value is a number, then convert it to an integer 
		    if (/[^a-z_]/i.test(inst_value)) {
		      inst_value = parseInt(inst_value, 10);
		    }
	
		    // only run filtering if any of the views has the filter 
		    found_filter = false;
		    _.each(views, function (tmp_view) {
		      if (utils.has(tmp_view, inst_filter)) {
		        found_filter = true;
		      }
		    });
	
		    if (found_filter) {
		      views = _.filter(views, function (d) {
		        return d[inst_filter] == inst_value;
		      });
		    }
		  });
	
		  // remove duplicate complete default states 
		  var export_views = [];
		  var found_default = false;
		  var check_default;
		  var inst_default_state;
	
		  // check if each view is a default state: all filters are at default 
		  // there can only be one of these 
		  _.each(views, function (inst_view) {
	
		    check_default = true;
	
		    // check each filter in a view to see if it is in the default state 
		    _.each(_.keys(params.viz.possible_filters), function (inst_filter) {
	
		      inst_default_state = get_filter_default_state(params.viz.filter_data, inst_filter);
	
		      if (inst_view[inst_filter] != inst_default_state) {
		        check_default = false;
		      }
		    });
	
		    // found defaule view, only append if you have not already found a default
		    if (check_default) {
		      if (found_default === false) {
		        found_default = true;
		        export_views.push(inst_view);
		      }
		    } else {
		      export_views.push(inst_view);
		    }
		  });
	
		  // if (export_views.length > 1){
		  //   console.log('found more than one view in get_subset_views')
		  //   console.log(requested_view)
		  //   console.log(export_views)
		  // } else {
		  //   console.log('found single view in get_subset_views')
		  //   console.log(requested_view)
		  //   console.log(export_views[0])
		  //   console.log('\n')
		  // }
	
		  return export_views;
			};
	
	/***/ },
	/* 13 */
	/***/ function(module, exports) {
	
		"use strict";
	
		module.exports = function ini_sidebar_params(params) {
		  var sidebar = {};
	
		  sidebar.wrapper = {};
		  // sidebar.wrapper.width = 170;
	
		  sidebar.row_search = {};
		  sidebar.row_search.box = {};
		  sidebar.row_search.box.height = 34;
		  sidebar.row_search.box.width = 95;
		  sidebar.row_search.placeholder = params.row_search_placeholder;
		  sidebar.row_search.margin_left = 7;
	
		  sidebar.slider = {};
		  sidebar.slider.width = params.sidebar_width - 30;
		  sidebar.slider.margin_left = 15;
	
		  sidebar.key_cat = {};
		  sidebar.key_cat.width = params.sidebar_width - 15;
		  sidebar.key_cat.margin_left = 5;
		  sidebar.key_cat.max_height = 100;
	
		  sidebar.title = params.title;
		  sidebar.title_margin_left = 7;
		  sidebar.about = params.about;
		  sidebar.width = params.sidebar_width;
	
		  sidebar.buttons = {};
		  sidebar.buttons.width = params.sidebar_width - 15;
	
		  sidebar.text = {};
	
		  sidebar.icons = params.sidebar_icons;
		  sidebar.icon_margin_left = -5;
	
		  return sidebar;
		};
	
	/***/ },
	/* 14 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function make_view_request(params, requested_view) {
	
		  // this will add all necessary information to a view request 
		  // it will grab necessary view information from the sliders 
	
		  // only one component will be changed at a time 
		  var changed_component = _.keys(requested_view)[0];
	
		  // add additional filter information from othe possible filters 
		  _.each(_.keys(params.viz.possible_filters), function (inst_filter) {
	
		    if (inst_filter != changed_component) {
	
		      if (!d3.select(params.root + ' .slider_' + inst_filter).empty()) {
	
		        var inst_state = d3.select(params.root + ' .slider_' + inst_filter).attr('current_state');
	
		        requested_view[inst_filter] = inst_state;
		      }
		    }
		  });
	
		  return requested_view;
			};
	
	/***/ },
	/* 15 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var ini_label_params = __webpack_require__(16);
		var set_viz_wrapper_size = __webpack_require__(17);
		var get_svg_dim = __webpack_require__(19);
		var calc_label_params = __webpack_require__(20);
		var calc_clust_width = __webpack_require__(21);
		var calc_clust_height = __webpack_require__(22);
		var calc_val_max = __webpack_require__(23);
		var calc_matrix_params = __webpack_require__(24);
		var set_zoom_params = __webpack_require__(29);
		var calc_default_fs = __webpack_require__(31);
		var utils = __webpack_require__(2);
		var get_available_filters = __webpack_require__(4);
		var make_cat_params = __webpack_require__(32);
	
		module.exports = function calc_viz_params(params) {
		  var predefined_cat_colors = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];
	
	
		  params.labels = ini_label_params(params);
		  params.viz = ini_viz_params(params, predefined_cat_colors);
	
		  set_viz_wrapper_size(params);
	
		  params = get_svg_dim(params);
		  params.viz = calc_label_params(params.viz);
		  params.viz = calc_clust_width(params.viz);
		  params.viz = calc_clust_height(params.viz);
	
		  if (params.sim_mat) {
		    if (params.viz.clust.dim.width <= params.viz.clust.dim.height) {
		      params.viz.clust.dim.height = params.viz.clust.dim.width;
		    } else {
		      params.viz.clust.dim.width = params.viz.clust.dim.height;
		    }
		  }
	
		  params = calc_val_max(params);
		  params = calc_matrix_params(params);
		  params = set_zoom_params(params);
		  params = calc_default_fs(params);
	
		  function ini_viz_params(params) {
		    var predefined_cat_colors = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];
	
	
		    var viz = {};
	
		    viz.root = params.root;
	
		    viz.root_tips = params.root.replace('#', '.') + '_' + 'd3-tip';
	
		    viz.viz_wrapper = params.root + ' .viz_wrapper';
		    viz.do_zoom = params.do_zoom;
		    viz.background_color = params.background_color;
		    viz.super_border_color = params.super_border_color;
		    viz.outer_margins = params.outer_margins;
		    viz.is_expand = params.ini_expand;
		    viz.grey_border_width = params.grey_border_width;
		    viz.show_dendrogram = params.show_dendrogram;
		    viz.tile_click_hlight = params.tile_click_hlight;
		    viz.inst_order = params.inst_order;
		    viz.expand_button = params.expand_button;
		    viz.sim_mat = params.sim_mat;
		    viz.dendro_filter = params.dendro_filter;
		    viz.cat_filter = params.cat_filter;
		    viz.cat_value_colors = params.cat_value_colors;
	
		    viz.viz_svg = viz.viz_wrapper + ' .viz_svg';
	
		    viz.zoom_element = viz.viz_wrapper + ' .viz_svg';
	
		    viz.uni_duration = 1000;
		    // extra space below the clustergram (was 5)
		    // will increase this to accomidate dendro slider
		    viz.bottom_space = 10;
		    viz.run_trans = false;
		    viz.duration = 1000;
	
		    viz.resize = params.resize;
		    if (utils.has(params, 'size')) {
		      viz.fixed_size = params.size;
		    } else {
		      viz.fixed_size = false;
		    }
	
		    // width is 1 over this value
		    viz.border_fraction = 65;
		    viz.uni_margin = 5;
	
		    viz.super_labels = {};
		    viz.super_labels.margin = {};
		    viz.super_labels.dim = {};
		    viz.super_labels.margin.left = viz.grey_border_width;
		    viz.super_labels.margin.top = viz.grey_border_width;
		    viz.super_labels.dim.width = 0;
		    if (params.labels.super_labels) {
		      viz.super_labels.dim.width = 15 * params.labels.super_label_scale;
		    }
	
		    viz.triangle_opacity = 0.6;
	
		    viz.norm_labels = {};
		    viz.norm_labels.width = {};
	
		    viz.dendro_room = {};
		    if (viz.show_dendrogram) {
		      viz.dendro_room.symbol_width = 10;
		    } else {
		      viz.dendro_room.symbol_width = 0;
		    }
	
		    viz.cat_colors = params.cat_colors;
	
		    // console.log('ini_viz_params -> make_cat_params')
		    // console.log('predefined_cat_colors outside function ' + String(predefined_cat_colors))
	
		    viz = make_cat_params(params, viz, predefined_cat_colors);
	
		    if (_.has(params, 'group_level') == false) {
		      if (viz.show_dendrogram) {
		        params.group_level = {};
		      }
		      params.group_level.row = 5;
		      params.group_level.col = 5;
		    }
	
		    viz.dendro_opacity = 0.35;
	
		    viz.spillover_col_slant = viz.norm_labels.width.col;
	
		    var filters = get_available_filters(params.network_data.views);
	
		    viz.possible_filters = filters.possible_filters;
		    viz.filter_data = filters.filter_data;
	
		    viz.viz_nodes = {};
	
		    // nodes that should be visible based on visible area
		    viz.viz_nodes.row = params.network_data.row_nodes_names;
		    viz.viz_nodes.col = params.network_data.col_nodes_names;
	
		    // nodes that are currently visible
		    viz.viz_nodes.curr_row = params.network_data.row_nodes_names;
		    viz.viz_nodes.curr_col = params.network_data.col_nodes_names;
	
		    // correct panning in x direction
		    viz.x_offset = 0;
	
		    return viz;
		  }
	
		  return params;
		};
	
	/***/ },
	/* 16 */
	/***/ function(module, exports) {
	
		"use strict";
	
		module.exports = function ini_label_params(params) {
	
		  var labels = {};
		  labels.super_label_scale = params.super_label_scale;
		  labels.super_labels = params.super_labels;
		  labels.super_label_fs = 13.8;
	
		  if (labels.super_labels) {
		    labels.super = {};
		    labels.super.row = params.super.row;
		    labels.super.col = params.super.col;
		  }
	
		  labels.show_label_tooltips = params.show_label_tooltips;
	
		  labels.row_max_char = _.max(params.network_data.row_nodes, function (inst) {
		    return inst.name.length;
		  }).name.length;
	
		  labels.col_max_char = _.max(params.network_data.col_nodes, function (inst) {
		    return inst.name.length;
		  }).name.length;
	
		  labels.max_allow_fs = params.max_allow_fs;
	
		  return labels;
		};
	
	/***/ },
	/* 17 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var calc_viz_dimensions = __webpack_require__(18);
	
		module.exports = function set_viz_wrapper_size(params) {
	
		  // Create wrapper around SVG visualization
		  if (d3.select(params.root + ' .viz_wrapper').empty()) {
	
		    d3.select(params.root).append('div').classed('sidebar_wrapper', true);
	
		    d3.select(params.root).append('div').classed('viz_wrapper', true);
		  }
	
		  var cont_dim = calc_viz_dimensions(params);
	
		  d3.select(params.root + ' .sidebar_wrapper').style('float', 'left').style('width', params.sidebar_width + 'px').style('height', cont_dim.height + 'px').style('overflow', 'hidden');
	
		  d3.select(params.viz.viz_wrapper).style('float', 'left').style('width', cont_dim.width + 'px').style('height', cont_dim.height + 'px');
			};
	
	/***/ },
	/* 18 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function calc_viz_dimensions(params) {
	
		  var cont_dim = {};
		  var extra_space = params.buffer_width;
	
		  // var screen_width = window.innerWidth;
		  // var screen_height = window.innerHeight;
	
		  // // resize container, then resize visualization within container
		  // d3.select(params.root)
		  //   .style('width', screen_width+'px')
		  //   .style('height', screen_height+'px');
	
		  var container_width = d3.select(params.root).style('width').replace('px', '');
		  var container_height = d3.select(params.root).style('height').replace('px', '');
	
		  // get outer_margins
		  var outer_margins;
		  if (params.viz.is_expand === false) {
		    outer_margins = params.viz.outer_margins;
		    cont_dim.width = container_width - params.sidebar_width - extra_space;
		  } else {
		    outer_margins = params.viz.outer_margins;
		    cont_dim.width = container_width - extra_space;
		  }
	
		  cont_dim.top = outer_margins.top;
		  cont_dim.left = outer_margins.left;
	
		  if (params.viz.resize) {
	
		    cont_dim.height = container_height;
		  } else {
	
		    if (params.viz.is_expand) {
		      cont_dim.width = params.viz.fixed_size.width;
		    } else {
		      cont_dim.width = params.viz.fixed_size.width - params.sidebar_width;
		    }
	
		    cont_dim.height = params.viz.fixed_size.height;
		  }
	
		  return cont_dim;
			};
	
	/***/ },
	/* 19 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function get_svg_dim(params) {
	
		  params.viz.svg_dim = {};
		  params.viz.svg_dim.width = Number(d3.select(params.viz.viz_wrapper).style('width').replace('px', ''));
	
		  params.viz.svg_dim.height = Number(d3.select(params.viz.viz_wrapper).style('height').replace('px', ''));
	
		  return params;
		};
	
	/***/ },
	/* 20 */
	/***/ function(module, exports) {
	
		"use strict";
	
		module.exports = function calc_label_params(viz) {
	
		  viz.norm_labels.margin = {};
	
		  viz.norm_labels.margin.left = viz.super_labels.margin.left + viz.super_labels.dim.width;
	
		  viz.norm_labels.margin.top = viz.super_labels.margin.top + viz.super_labels.dim.width;
	
		  viz.label_background = {};
	
		  viz.label_background.row = viz.norm_labels.width.row + viz.cat_room.row + viz.uni_margin;
	
		  viz.label_background.col = viz.norm_labels.width.col + viz.cat_room.col + viz.uni_margin;
	
		  return viz;
		};
	
	/***/ },
	/* 21 */
	/***/ function(module, exports) {
	
		"use strict";
	
		module.exports = function calc_clust_width(viz) {
	
		  viz.clust = {};
		  viz.clust.margin = {};
	
		  // margin on left/top of the clustergram/matrix 
		  // 1) norm_label margin and width
		  // 2) cat_room and uni_margin 
		  viz.clust.margin.left = viz.norm_labels.margin.left + viz.norm_labels.width.row + viz.cat_room.row + viz.uni_margin;
	
		  viz.clust.margin.top = viz.norm_labels.margin.top + viz.norm_labels.width.col + viz.cat_room.col + viz.uni_margin;
	
		  // the clustergram/matrix width is the svg width minus:
		  // the margin of the clustergram on the left 
		  // the room for the spillover on the right 
		  // ** the dendro will fit in the spillover room on the right 
		  var ini_clust_width = viz.svg_dim.width - viz.clust.margin.left - viz.spillover_col_slant;
	
		  // make tmp scale to calc height of triangle col labels 
		  var tmp_x_scale = d3.scale.ordinal().rangeBands([0, ini_clust_width]).domain(_.range(viz.num_col_nodes));
	
		  var triangle_height = tmp_x_scale.rangeBand() / 2;
	
		  // prevent the visualization from being unnecessarily wide 
		  if (triangle_height > viz.norm_labels.width.col) {
		    var reduce_width = viz.norm_labels.width.col / triangle_height;
		    ini_clust_width = ini_clust_width * reduce_width;
		  }
	
		  viz.clust.dim = {};
		  viz.clust.dim.width = ini_clust_width;
	
		  return viz;
		};
	
	/***/ },
	/* 22 */
	/***/ function(module, exports) {
	
		"use strict";
	
		module.exports = function calc_clust_height(viz) {
	
		  // the clustergram/matrix height is the svg width minus: 
		  // the margin of the clustergram on the top 
		  // the dendrogram 
		  // the bottom_space 
		  var ini_clust_height = viz.svg_dim.height - viz.clust.margin.top - viz.dendro_room.col - viz.bottom_space;
	
		  viz.clust.dim.height = ini_clust_height;
	
		  return viz;
		};
	
	/***/ },
	/* 23 */
	/***/ function(module, exports) {
	
		"use strict";
	
		module.exports = function calc_val_max(params) {
	
		  var val_max = Math.abs(_.max(params.network_data.col_nodes, function (d) {
		    return Math.abs(d.value);
		  }).value);
	
		  params.labels.bar_scale_col = d3.scale.linear().domain([0, val_max]).range([0, 0.75 * params.viz.norm_labels.width.col]);
	
		  val_max = Math.abs(_.max(params.network_data.row_nodes, function (d) {
		    return Math.abs(d.value);
		  }).value);
	
		  params.labels.bar_scale_row = d3.scale.linear().domain([0, val_max]).range([0, params.viz.norm_labels.width.row]);
	
		  return params;
		};
	
	/***/ },
	/* 24 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var ini_matrix_params = __webpack_require__(25);
		var calc_downsampled_levels = __webpack_require__(27);
	
		module.exports = function calc_matrix_params(params) {
	
		  params.matrix = ini_matrix_params(params);
	
		  // X and Y scales: set domains and ranges
		  //////////////////////////////////////////////
		  params.viz.x_scale = d3.scale.ordinal().rangeBands([0, params.viz.clust.dim.width]);
	
		  params.viz.y_scale = d3.scale.ordinal().rangeBands([0, params.viz.clust.dim.height]);
	
		  var inst_order;
	
		  _.each(['row', 'col'], function (inst_rc) {
	
		    inst_order = params.viz.inst_order[inst_rc];
	
		    if (inst_order === 'custom') {
		      inst_order = 'clust';
		    }
	
		    if (inst_rc === 'row') {
		      params.viz.x_scale.domain(params.matrix.orders[inst_order + '_' + inst_rc]);
		    } else {
		      params.viz.y_scale.domain(params.matrix.orders[inst_order + '_' + inst_rc]);
		    }
		  });
	
		  // border width
		  params.viz.border_width = {};
		  params.viz.border_width.x = params.viz.x_scale.rangeBand() / params.viz.border_fraction;
		  params.viz.border_width.y = params.viz.y_scale.rangeBand() / params.viz.border_fraction;
	
		  // rect width needs matrix and zoom parameters
		  params.viz.rect_width = params.viz.x_scale.rangeBand() - params.viz.border_width.x;
	
		  // moved calculateion to calc_matrix_params
		  params.viz.rect_height = params.viz.y_scale.rangeBand() - params.viz.border_width.y;
	
		  calc_downsampled_levels(params);
	
		  return params;
			};
	
	/***/ },
	/* 25 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var utils = __webpack_require__(2);
		var initialize_matrix = __webpack_require__(26);
	
		module.exports = function ini_matrix_params(params) {
	
		  var matrix = {};
	
		  var network_data = params.network_data;
	
		  matrix.tile_colors = params.tile_colors;
		  matrix.bar_colors = params.bar_colors;
		  matrix.outline_colors = params.outline_colors;
		  matrix.hlight_color = params.highlight_color;
		  matrix.tile_title = params.tile_title;
		  matrix.show_tile_tooltips = params.show_tile_tooltips;
		  matrix.make_tile_tooltip = params.make_tile_tooltip;
	
		  // initialized clicked tile and rows
		  matrix.click_hlight_x = -666;
		  matrix.click_hlight_y = -666;
		  matrix.click_hlight_row = -666;
		  matrix.click_hlight_col = -666;
	
		  // definition of a large matrix (num links) determines if transition is run
		  matrix.def_large_matrix = 10000;
		  matrix.opacity_function = params.opacity_scale;
	
		  matrix.orders = {};
	
		  _.each(['row', 'col'], function (inst_rc) {
	
		    // row ordering is based on col info and vice versa
		    var other_rc;
		    if (inst_rc === 'row') {
		      other_rc = 'col';
		    } else {
		      other_rc = 'row';
		    }
	
		    // the nodes are defined using other_rc
		    var inst_nodes = network_data[other_rc + '_nodes'];
		    var num_nodes = inst_nodes.length;
	
		    var nodes_names = utils.pluck(inst_nodes, 'name');
		    var tmp = nodes_names.sort();
	
		    var alpha_index = _.map(tmp, function (d) {
		      return network_data[other_rc + '_nodes_names'].indexOf(d);
		    });
	
		    matrix.orders['alpha_' + inst_rc] = alpha_index;
	
		    var possible_orders = ['clust', 'rank'];
	
		    if (_.has(inst_nodes[0], 'rankvar')) {
		      possible_orders.push('rankvar');
		    }
	
		    if (params.viz.all_cats[other_rc].length > 0) {
		      _.each(params.viz.all_cats[other_rc], function (inst_cat) {
		        // the index of the category has replaced - with _
		        inst_cat = inst_cat.replace('-', '_');
		        possible_orders.push(inst_cat + '_index');
		      });
		    }
	
		    _.each(possible_orders, function (inst_order) {
	
		      var tmp_order_index = d3.range(num_nodes).sort(function (a, b) {
		        return inst_nodes[b][inst_order] - inst_nodes[a][inst_order];
		      });
	
		      matrix.orders[inst_order + '_' + inst_rc] = tmp_order_index;
		    });
		  });
	
		  if (utils.has(network_data, 'all_links')) {
		    matrix.max_link = _.max(network_data.all_links, function (d) {
		      return Math.abs(d.value);
		    }).value;
		  } else {
		    matrix.max_link = _.max(network_data.links, function (d) {
		      return Math.abs(d.value);
		    }).value;
		  }
	
		  matrix.abs_max_val = Math.abs(matrix.max_link) * params.clamp_opacity;
	
		  if (params.input_domain === 0) {
		    if (matrix.opacity_function === 'linear') {
		      matrix.opacity_scale = d3.scale.linear().domain([0, matrix.abs_max_val]).clamp(true).range([0.0, 1.0]);
		    } else if (matrix.opacity_function === 'log') {
		      matrix.opacity_scale = d3.scale.log().domain([0.001, matrix.abs_max_val]).clamp(true).range([0.0, 1.0]);
		    }
		  } else {
		    if (matrix.opacity_function === 'linear') {
		      matrix.opacity_scale = d3.scale.linear().domain([0, params.input_domain]).clamp(true).range([0.0, 1.0]);
		    } else if (matrix.opacity_function === 'log') {
		      matrix.opacity_scale = d3.scale.log().domain([0.001, params.input_domain]).clamp(true).range([0.0, 1.0]);
		    }
		  }
	
		  var has_val_up = utils.has(network_data.links[0], 'value_up');
		  var has_val_dn = utils.has(network_data.links[0], 'value_dn');
	
		  if (has_val_up || has_val_dn) {
		    matrix.tile_type = 'updn';
		  } else {
		    matrix.tile_type = 'simple';
		  }
	
		  if (utils.has(network_data.links[0], 'highlight')) {
		    matrix.highlight = 1;
		  } else {
		    matrix.highlight = 0;
		  }
	
		  matrix.matrix = initialize_matrix(network_data);
	
		  matrix.wait_tooltip = 0;
	
		  return matrix;
		};
	
	/***/ },
	/* 26 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var utils = __webpack_require__(2);
	
		module.exports = function (network_data) {
		  var matrix = [];
		  var ini_object;
	
		  var keep_orig;
		  if (utils.has(network_data.links[0], 'value_orig')) {
		    keep_orig = true;
		  } else {
		    keep_orig = false;
		  }
	
		  network_data.row_nodes.forEach(function (tmp, row_index) {
	
		    matrix[row_index] = {};
		    matrix[row_index].name = network_data.row_nodes[row_index].name;
		    matrix[row_index].row_index = row_index;
	
		    matrix[row_index].row_data = d3.range(network_data.col_nodes.length).map(function (col_index) {
	
		      if (utils.has(network_data.links[0], 'value_up') || utils.has(network_data.links[0], 'value_dn')) {
	
		        ini_object = {
		          pos_x: col_index,
		          pos_y: row_index,
		          value: 0,
		          value_up: 0,
		          value_dn: 0,
		          highlight: 0
		        };
		      } else {
	
		        ini_object = {
		          pos_x: col_index,
		          pos_y: row_index,
		          value: 0,
		          highlight: 0
		        };
		      }
	
		      if (keep_orig) {
		        ini_object.value_orig = 0;
		      }
	
		      return ini_object;
		    });
		  });
	
		  network_data.links.forEach(function (link) {
	
		    // transfer additional link information is necessary
		    matrix[link.source].row_data[link.target].value = link.value;
		    matrix[link.source].row_data[link.target].row_name = link.row_name;
		    matrix[link.source].row_data[link.target].col_name = link.col_name;
	
		    if (utils.has(link, 'value_up') || utils.has(link, 'value_dn')) {
		      matrix[link.source].row_data[link.target].value_up = link.value_up;
		      matrix[link.source].row_data[link.target].value_dn = link.value_dn;
		    }
	
		    if (keep_orig) {
		      matrix[link.source].row_data[link.target].value_orig = link.value_orig;
		    }
	
		    if (link.highlight) {
		      matrix[link.source].row_data[link.target].highlight = link.highlight;
		    }
		    if (link.info) {
		      matrix[link.source].row_data[link.target].info = link.info;
		    }
		  });
	
		  return matrix;
		};
	
	/***/ },
	/* 27 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var calc_downsampled_matrix = __webpack_require__(28);
	
		module.exports = function calc_downsampled_levels(params) {
	
		  // console.log('---- before ---------')
		  // console.log(params.matrix.matrix[0].row_data[0].value)
	
		  // height of downsampled rectangles
		  var ds_height = 3;
	
		  var min_rect_height = 2;
	
		  var total_zoom = ds_height / params.viz.rect_height;
	
		  // amount of zooming that is tolerated for the downsampled rows
		  var inst_zt = 2;
		  params.viz.ds_zt = inst_zt;
	
		  var num_levels = Math.floor(Math.log(total_zoom) / Math.log(inst_zt));
	
		  if (params.viz.rect_height < min_rect_height && num_levels > 0) {
	
		    // increase ds opacity, as more rows are compressed into a single downsampled
		    // row, increase the opacity of the downsampled row. Max increase will be 2x
		    // when 100 or more rows are compressed
		    var max_opacity_scale = 2;
		    params.viz.ds_opacity_scale = d3.scale.linear().domain([1, 100]).range([1, max_opacity_scale]).clamp(true);
	
		    var ds;
	
		    params.viz.ds_num_levels = num_levels;
	
		    // array of downsampled parameters
		    params.viz.ds = [];
	
		    // array of downsampled matrices at varying levels
		    params.matrix.ds_matrix = [];
	
		    var inst_order = params.viz.inst_order.row;
	
		    // cloning
		    var mat = $.extend(true, {}, params.matrix.matrix);
	
		    // calculate parameters for different levels
		    for (var i = 0; i < num_levels; i++) {
	
		      // instantaneous ds_level (-1 means no downsampling)
		      params.viz.ds_level = 0;
	
		      ds = {};
	
		      ds.height = ds_height;
		      ds.num_levels = num_levels;
	
		      var inst_zoom_tolerance = Math.pow(inst_zt, i);
	
		      ds.zt = inst_zoom_tolerance;
	
		      // the number of downsampled rows is given by the height of the clustergram
		      // divided by the adjusted height of the downsampled rect.
		      // the adjusted height is the height divided by the zooming tolerance of
		      // the downsampled layer
	
		      // number of downsampled rows
		      ds.num_rows = Math.round(params.viz.clust.dim.height / (ds.height / inst_zoom_tolerance));
	
		      // x_scale
		      /////////////////////////
		      ds.x_scale = d3.scale.ordinal().rangeBands([0, params.viz.clust.dim.width]);
	
		      ds.x_scale.domain(params.matrix.orders[inst_order + '_row']);
	
		      // y_scale
		      /////////////////////////
		      ds.y_scale = d3.scale.ordinal().rangeBands([0, params.viz.clust.dim.height]);
		      ds.y_scale.domain(d3.range(ds.num_rows + 1));
	
		      ds.rect_height = ds.y_scale.rangeBand() - params.viz.border_width.y;
	
		      params.viz.ds.push(ds);
	
		      var matrix = calc_downsampled_matrix(params, mat, i);
		      params.matrix.ds_matrix.push(matrix);
		    }
	
		    // reset row viz_nodes since downsampling
		    params.viz.viz_nodes.row = d3.range(params.matrix.ds_matrix[0].length).map(String);
		  } else {
		    // set ds to null if no downsampling is done
		    params.viz.ds = null;
		    // instantaneous ds_level (-1 means no downsampling)
		    params.viz.ds_level = -1;
		    params.viz.ds_num_levels = 0;
		  }
	
		  // console.log('---- after ---------')
		  // console.log(params.matrix.matrix[0].row_data[0].value)
			};
	
	/***/ },
	/* 28 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function calc_downsampled_matrix(params, mat, ds_level) {
	
		  var inst_num_rows = params.viz.ds[ds_level].num_rows;
	
		  var num_compressed_rows = params.network_data.row_nodes.length / inst_num_rows;
	
		  // increase ds opacity, as more rows are compressed into a single downsampled
		  // row, increase the opacity of the downsampled row.
		  var opacity_factor = params.viz.ds_opacity_scale(num_compressed_rows);
	
		  var mod_val = params.viz.clust.dim.height / inst_num_rows;
	
		  var ds_mat = [];
		  var inst_obj;
	
		  var len_ds_array = inst_num_rows + 1;
	
		  var i;
		  var x;
	
		  // initialize array of objects
		  for (i = 0; i < len_ds_array; i++) {
	
		    inst_obj = {};
		    inst_obj.row_index = i;
		    inst_obj.name = String(i);
		    inst_obj.all_names = [];
	
		    ds_mat.push(inst_obj);
		  }
	
		  _.each(mat, function (inst_row) {
	
		    // row ordering information is contained in y_scale
		    var inst_y = params.viz.y_scale(inst_row.row_index);
	
		    var ds_index = Math.round(inst_y / mod_val);
	
		    var inst_row_data = inst_row.row_data;
	
		    // gather names
		    ds_mat[ds_index].all_names.push(inst_row.name);
	
		    // gather row_data
		    if (_.has(ds_mat[ds_index], 'row_data')) {
	
		      for (x = 0; x < inst_row_data.length; x++) {
		        ds_mat[ds_index].row_data[x].value = ds_mat[ds_index].row_data[x].value + inst_row_data[x].value;
		      }
		    } else {
	
		      var new_data = [];
		      for (x = 0; x < inst_row_data.length; x++) {
		        new_data[x] = inst_row_data[x];
		      }
	
		      ds_mat[ds_index].row_data = new_data;
		    }
		  });
	
		  // average the values
		  _.each(ds_mat, function (tmp_ds) {
	
		    var tmp_row_data = tmp_ds.row_data;
	
		    var num_names = tmp_ds.all_names.length;
	
		    _.each(tmp_row_data, function (tmp_obj) {
		      tmp_obj.value = tmp_obj.value / num_names * opacity_factor;
		    });
		  });
	
		  // all names were found
		  var all_names = [];
	
		  _.each(ds_mat, function (inst_row) {
		    all_names = all_names.concat(inst_row.all_names);
		  });
	
		  return ds_mat;
			};
	
	/***/ },
	/* 29 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var calc_zoom_switching = __webpack_require__(30);
	
		module.exports = function set_zoom_params(params) {
	
		  params.viz.zoom_scale_font = {};
		  params.viz.zoom_scale_font.row = 1;
		  params.viz.zoom_scale_font.col = 1;
	
		  var max_zoom_limit = 0.75;
		  var half_col_height = params.viz.x_scale.rangeBand() / 2;
		  params.viz.square_zoom = params.viz.norm_labels.width.col / half_col_height * max_zoom_limit;
	
		  params.viz = calc_zoom_switching(params.viz);
	
		  return params;
		};
	
	/***/ },
	/* 30 */
	/***/ function(module, exports) {
	
		"use strict";
	
		module.exports = function calc_zoom_switching(viz) {
	
		  var width_by_col = viz.clust.dim.width / viz.num_col_nodes;
		  var height_by_row = viz.clust.dim.height / viz.num_row_nodes;
	
		  viz.zoom_ratio = {};
		  viz.zoom_ratio.x = width_by_col / height_by_row;
		  viz.zoom_ratio.y = 1;
	
		  if (viz.zoom_ratio.x < 1) {
		    viz.zoom_ratio.y = 1 / viz.zoom_ratio.x;
		    viz.zoom_ratio.x = 1;
		  }
	
		  return viz;
		};
	
	/***/ },
	/* 31 */
	/***/ function(module, exports) {
	
		"use strict";
	
		module.exports = function calc_default_fs(params) {
	
		  params.labels.default_fs_row = params.viz.y_scale.rangeBand() * 1.01;
		  params.labels.default_fs_col = params.viz.x_scale.rangeBand() * 0.87;
	
		  if (params.labels.default_fs_row > params.labels.max_allow_fs) {
		    params.labels.default_fs_row = params.labels.max_allow_fs;
		  }
	
		  if (params.labels.default_fs_col > params.labels.max_allow_fs) {
		    params.labels.default_fs_col = params.labels.max_allow_fs;
		  }
	
		  return params;
			};
	
	/***/ },
	/* 32 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var calc_cat_params = __webpack_require__(33);
		var utils = __webpack_require__(2);
		var colors = __webpack_require__(34);
		var check_if_value_cats = __webpack_require__(35);
	
		module.exports = function make_cat_params(params, viz) {
		  var predefined_cat_colors = arguments.length <= 2 || arguments[2] === undefined ? true : arguments[2];
	
	
		  // console.log('predefined_cat_colors ' + String(predefined_cat_colors))
	
		  var super_string = ': ';
		  var tmp_super;
		  var inst_info;
		  var inst_color;
	
		  viz.show_categories = {};
		  viz.all_cats = {};
		  viz.cat_names = {};
		  viz.cat_info = {};
	
		  // this will hold the information for calculating the opacity of the value
		  // function
		  var ini_val_opacity = {};
		  ini_val_opacity.row = null;
		  ini_val_opacity.col = null;
	
		  viz.cat_colors = {};
		  viz.cat_colors.value_opacity = ini_val_opacity;
	
		  var num_colors = 0;
		  _.each(['row', 'col'], function (inst_rc) {
	
		    viz.show_categories[inst_rc] = false;
	
		    viz.all_cats[inst_rc] = [];
		    var tmp_keys = _.keys(params.network_data[inst_rc + '_nodes'][0]);
	
		    // console.log(tmp_keys)
	
		    tmp_keys = tmp_keys.sort();
	
		    // console.log('-------------------------------')
		    // console.log('tmp_keys')
		    // console.log(tmp_keys)
		    // console.log('-------------------------------')
	
		    _.each(tmp_keys, function (d) {
		      if (d.indexOf('cat-') >= 0) {
		        // console.log(d)
		        viz.show_categories[inst_rc] = true;
		        viz.all_cats[inst_rc].push(d);
		      }
		    });
	
		    viz.cat_info[inst_rc] = null;
	
		    if (viz.show_categories[inst_rc]) {
	
		      viz.cat_colors[inst_rc] = {};
		      viz.cat_info[inst_rc] = {};
		      viz.cat_names[inst_rc] = {};
	
		      // console.log('***************************')
		      // console.log(viz.all_cats[inst_rc])
		      // console.log('***************************')
	
		      _.each(viz.all_cats[inst_rc], function (cat_title) {
	
		        // console.log( inst_rc + ': ' + cat_title)
	
		        var inst_node = params.network_data[inst_rc + '_nodes'][0];
	
		        // console.log('defining cat_names')
		        // console.log(cat_title)
		        // console.log(inst_node[cat_title])
		        // console.log('****************************')
	
		        // look for title of category in category name
		        if (typeof inst_node[cat_title] === 'string') {
	
		          if (inst_node[cat_title].indexOf(super_string) > 0) {
		            tmp_super = inst_node[cat_title].split(super_string)[0];
		            viz.cat_names[inst_rc][cat_title] = tmp_super;
		          } else {
		            viz.cat_names[inst_rc][cat_title] = cat_title;
		          }
		        } else {
		          viz.cat_names[inst_rc][cat_title] = cat_title;
		        }
	
		        // console.log(viz.cat_names[inst_rc][cat_title])
		        // console.log('-----------\n')
	
		        var cat_instances = utils.pluck(params.network_data[inst_rc + '_nodes'], cat_title);
		        var cat_states = _.uniq(cat_instances).sort();
	
		        // check whether all the categories are of value type
		        inst_info = check_if_value_cats(cat_states);
	
		        // add histogram to inst_info
		        if (inst_info.type === 'cat_strings') {
		          var cat_hist = _.countBy(cat_instances);
		          inst_info.cat_hist = cat_hist;
		        } else {
		          inst_info.cat_hist = null;
		        }
	
		        // pass info_info object
		        viz.cat_info[inst_rc][cat_title] = inst_info;
	
		        viz.cat_colors[inst_rc][cat_title] = {};
	
		        _.each(cat_states, function (cat_tmp, inst_index) {
	
		          inst_color = colors.get_random_color(inst_index + num_colors);
	
		          viz.cat_colors[inst_rc][cat_title][cat_tmp] = inst_color;
	
		          // hack to get 'Not' categories to not be dark colored
		          // also doing this for false
		          if (typeof cat_tmp === 'string') {
		            if (cat_tmp.indexOf('Not ') >= 0 || cat_tmp.indexOf(': false') > 0) {
		              viz.cat_colors[inst_rc][cat_title][cat_tmp] = '#eee';
		            }
		          }
	
		          num_colors = num_colors + 1;
		        });
		      });
		    }
	
		    if (_.has(params.network_data, 'cat_colors') && predefined_cat_colors === true) {
		      // console.log('-- use predefined_cat_colors for ' + inst_rc + 's')
		      viz.cat_colors[inst_rc] = params.network_data.cat_colors[inst_rc];
		    } else {
		      // console.log('-- did not use predefined_cat_colors for '+inst_rc+'s')
		    }
	
		    if (params.sim_mat) {
		      // sending row color info to columns since row color info can be updated
		      viz.cat_colors.col = viz.cat_colors.row;
		    }
		  });
		  // console.log('--------------------------\n\n');
	
		  viz.cat_colors = viz.cat_colors;
	
		  viz.cat_colors.opacity = 0.6;
		  viz.cat_colors.active_opacity = 0.9;
	
		  viz = calc_cat_params(params, viz);
	
		  return viz;
			};
	
	/***/ },
	/* 33 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function calc_cat_params(params, viz) {
	
		  var separtion_room;
	
		  // increase the width of the label container based on the label length
		  var label_scale = d3.scale.linear().domain([5, 15]).range([85, 120]).clamp('true');
	
		  viz.cat_room = {};
		  viz.cat_room.symbol_width = 12;
		  viz.cat_room.separation = 3;
	
		  _.each(['row', 'col'], function (inst_rc) {
	
		    viz.norm_labels.width[inst_rc] = label_scale(params.labels[inst_rc + '_max_char']) * params[inst_rc + '_label_scale'];
	
		    viz['num_' + inst_rc + '_nodes'] = params.network_data[inst_rc + '_nodes'].length;
	
		    // if (_.has(config, 'group_level')){
		    //   config.group_level[inst_rc] = 5;
		    // }
	
		    if (inst_rc === 'row') {
		      viz.dendro_room[inst_rc] = viz.dendro_room.symbol_width;
		    } else {
		      viz.dendro_room[inst_rc] = viz.dendro_room.symbol_width + 3 * viz.uni_margin;
		    }
	
		    var num_cats = viz.all_cats[inst_rc].length;
	
		    if (viz.show_categories[inst_rc]) {
	
		      separtion_room = (num_cats - 1) * viz.cat_room.separation;
	
		      var adjusted_cats;
		      if (inst_rc === 'row') {
		        adjusted_cats = num_cats + 1;
		      } else {
		        adjusted_cats = num_cats;
		      }
	
		      viz.cat_room[inst_rc] = adjusted_cats * viz.cat_room.symbol_width + separtion_room;
		    } else {
		      // no categories
		      if (inst_rc == 'row') {
		        viz.cat_room[inst_rc] = viz.cat_room.symbol_width;
		      } else {
		        viz.cat_room[inst_rc] = 0;
		      }
		    }
		  });
	
		  return viz;
			};
	
	/***/ },
	/* 34 */
	/***/ function(module, exports) {
	
		"use strict";
	
		// colors from http://graphicdesign.stackexchange.com/revisions/3815/8
		var all_colors;
	
		all_colors = ["#393b79", "#aec7e8", "#ff7f0e", "#ffbb78", "#98df8a", "#bcbd22", "#404040", "#ff9896", "#c5b0d5", "#8c564b", "#1f77b4", "#5254a3", "#FFDB58", "#c49c94", "#e377c2", "#7f7f7f", "#2ca02c", "#9467bd", "#dbdb8d", "#17becf", "#637939", "#6b6ecf", "#9c9ede", "#d62728", "#8ca252", "#8c6d31", "#bd9e39", "#e7cb94", "#843c39", "#ad494a", "#d6616b", "#7b4173", "#a55194", "#ce6dbd", "#de9ed6"];
	
		// too light colors 
		// "#e7969c",
		// "#c7c7c7", 
		// "#f7b6d2", 
		// "#cedb9c", 
		// "#9edae5", 
	
		function get_default_color() {
		  return '#EEE';
		}
	
		function get_random_color(i) {
		  return all_colors[i % get_num_colors()];
		}
	
		function get_num_colors() {
		  return all_colors.length;
		}
	
		module.exports = {
		  get_default_color: get_default_color,
		  get_random_color: get_random_color,
		  get_num_colors: get_num_colors
			};
	
	/***/ },
	/* 35 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function check_if_value_cats(cat_states) {
	
		  var tmp_cat = cat_states[0];
	
		  var has_title = false;
		  var might_have_values = false;
		  var cat_types = 'cat_strings';
		  var max_abs_val = NaN;
		  var all_values = [];
		  var cat_scale = null;
	
		  var super_string = ': ';
	
		  if (typeof tmp_cat === 'string') {
		    if (tmp_cat.indexOf(super_string) > -1) {
		      has_title = true;
		      tmp_cat = tmp_cat.split(super_string)[1];
		    }
		  }
	
		  if (isNaN(tmp_cat) == false) {
		    might_have_values = true;
		  }
	
		  // check each value for number
		  if (might_have_values) {
	
		    // the default state is that all are now values, check each one
		    cat_types = 'cat_values';
	
		    _.each(cat_states, function (inst_cat) {
	
		      if (has_title) {
		        inst_cat = inst_cat.split(super_string)[1];
		      }
	
		      // checking whether inst_cat is 'not a number'
		      if (isNaN(inst_cat) == true) {
		        cat_types = 'cat_strings';
		      } else {
		        inst_cat = parseFloat(inst_cat);
		        all_values.push(inst_cat);
		      }
		    });
		  }
	
		  if (cat_types === 'cat_values') {
	
		    // get absolute value
		    var max_value = _.max(all_values, function (d) {
		      return Math.abs(d);
		    });
	
		    max_abs_val = Math.abs(max_value);
	
		    cat_scale = d3.scale.linear().domain([0, max_abs_val]).range([0, 1]);
		  }
	
		  var inst_info = {};
		  inst_info.type = cat_types;
		  inst_info.max_abs_val = max_abs_val;
		  inst_info.cat_scale = cat_scale;
	
		  return inst_info;
			};
	
	/***/ },
	/* 36 */
	/***/ function(module, exports) {
	
		"use strict";
	
		module.exports = function ini_zoom_info() {
	
		  var zoom_info = {};
		  zoom_info.zoom_x = 1;
		  zoom_info.zoom_y = 1;
		  zoom_info.trans_x = 0;
		  zoom_info.trans_y = 0;
	
		  return zoom_info;
			};
	
	/***/ },
	/* 37 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var generate_matrix = __webpack_require__(38);
		var make_row_label_container = __webpack_require__(49);
		var make_col_label_container = __webpack_require__(67);
		var generate_super_labels = __webpack_require__(75);
		var spillover = __webpack_require__(76);
		var initialize_resizing = __webpack_require__(87);
		var ini_doubleclick = __webpack_require__(97);
		var make_col_cat = __webpack_require__(116);
		var make_row_cat = __webpack_require__(122);
		var trim_text = __webpack_require__(82);
		var make_row_dendro = __webpack_require__(123);
		var make_col_dendro = __webpack_require__(124);
		var make_svg_dendro_sliders = __webpack_require__(125);
		var make_row_dendro_spillover = __webpack_require__(128);
	
		module.exports = function make_viz(cgm) {
	
		  var params = cgm.params;
	
		  d3.select(params.viz.viz_wrapper + ' svg').remove();
	
		  var svg_group = d3.select(params.viz.viz_wrapper).append('svg').attr('class', 'viz_svg').attr('id', 'svg_' + params.root.replace('#', '')).attr('width', params.viz.svg_dim.width).attr('height', params.viz.svg_dim.height).attr('is_zoom', 0).attr('stopped_zoom', 1);
	
		  svg_group.append('rect').attr('class', 'super_background').style('width', params.viz.svg_dim.width).style('height', params.viz.svg_dim.height).style('fill', 'white');
	
		  generate_matrix(params, svg_group);
	
		  make_row_label_container(cgm);
	
		  if (params.viz.show_dendrogram) {
		    make_row_dendro(cgm);
		    make_col_dendro(cgm);
		  }
	
		  make_row_dendro_spillover(cgm);
	
		  make_col_label_container(cgm);
	
		  // initial trim text
		  if (params.viz.ds_level === -1) {
		    _.each(['row', 'col'], function (inst_rc) {
	
		      var inst_fs = Number(d3.select('.' + inst_rc + '_label_group').select('text').style('font-size').replace('px', ''));
	
		      var min_trim_fs = 8;
		      if (inst_fs > min_trim_fs) {
		        d3.selectAll(params.root + ' .' + inst_rc + '_label_group').each(function () {
		          trim_text(params, this, inst_rc);
		        });
		      }
		    });
		  }
	
		  // make category colorbars
		  make_row_cat(cgm);
		  if (params.viz.show_categories.col) {
		    make_col_cat(cgm);
		  }
	
		  spillover(cgm);
	
		  if (params.labels.super_labels) {
		    generate_super_labels(params);
		  }
	
		  // sliders should go above super labels
		  make_svg_dendro_sliders(cgm);
	
		  function border_colors() {
		    var inst_color = params.viz.super_border_color;
		    if (params.viz.is_expand || params.show_viz_border == false) {
		      inst_color = 'white';
		    }
		    return inst_color;
		  }
	
		  // left border
		  d3.select(params.viz.viz_svg).append('rect').classed('left_border', true).classed('borders', true).attr('fill', border_colors).attr('width', params.viz.grey_border_width).attr('height', params.viz.svg_dim.height).attr('transform', 'translate(0,0)');
	
		  // right border
		  d3.select(params.viz.viz_svg).append('rect').classed('right_border', true).classed('borders', true).attr('fill', border_colors).attr('width', params.viz.grey_border_width).attr('height', params.viz.svg_dim.height).attr('transform', function () {
		    var inst_offset = params.viz.svg_dim.width - params.viz.grey_border_width;
		    return 'translate(' + inst_offset + ',0)';
		  });
	
		  // top border
		  d3.select(params.viz.viz_svg).append('rect').classed('top_border', true).classed('borders', true).attr('fill', border_colors).attr('width', params.viz.svg_dim.width).attr('height', params.viz.grey_border_width).attr('transform', function () {
		    var inst_offset = 0;
		    return 'translate(' + inst_offset + ',0)';
		  });
	
		  // bottom border
		  d3.select(params.viz.viz_svg).append('rect').classed('bottom_border', true).classed('borders', true).attr('fill', border_colors).attr('width', params.viz.svg_dim.width).attr('height', params.viz.grey_border_width).attr('transform', function () {
		    var inst_offset = params.viz.svg_dim.height - params.viz.grey_border_width;
		    return 'translate(0,' + inst_offset + ')';
		  });
	
		  initialize_resizing(cgm);
	
		  ini_doubleclick(cgm);
	
		  if (params.viz.do_zoom) {
		    d3.select(params.viz.zoom_element).call(params.zoom_behavior);
		  }
	
		  d3.select(params.viz.zoom_element).on('dblclick.zoom', null);
			};
	
	/***/ },
	/* 38 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var utils = __webpack_require__(2);
		var draw_gridlines = __webpack_require__(39);
		var add_click_hlight = __webpack_require__(40);
		var make_matrix_rows = __webpack_require__(41);
	
		module.exports = function (params, svg_elem) {
		  var network_data = params.network_data;
	
		  var matrix = [];
		  var clust_group;
	
		  // append a group that will hold clust_group and position it once
		  clust_group = svg_elem.append('g').attr('class', 'clust_container').attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.clust.margin.top + ')').append('g').attr('class', 'clust_group').classed('clust_group', true);
	
		  // clustergram background rect
		  clust_group.append('rect').classed('background', true).classed('grey_background', true).style('fill', '#eee').style('opacity', 0.25).attr('width', params.viz.clust.dim.width).attr('height', params.viz.clust.dim.height);
	
		  // pass in params and the rows (row_nodes) that need to be made
		  // in this case all row nodes
		  // make_matrix_rows(params, params.matrix.matrix, params.network_data.row_nodes_names);
	
		  // initialize at ds_level 0
		  if (params.viz.ds === null) {
		    // do not use downsampled matrix
		    make_matrix_rows(params, params.matrix.matrix, 'all', params.viz.ds_level);
		  } else {
		    // use downsampled matrix
		    make_matrix_rows(params, params.matrix.ds_matrix[0], 'all', params.viz.ds_level);
		  }
	
		  // add callback function to tile group - if one is supplied by the user
		  if (typeof params.click_tile === 'function') {
		    d3.selectAll(params.root + ' .tile').on('click', function (d) {
	
		      // export row/col name and value from tile
		      var tile_info = {};
		      tile_info.row = params.network_data.row_nodes[d.pos_y].name;
		      tile_info.col = params.network_data.col_nodes[d.pos_x].name;
		      tile_info.value = d.value;
	
		      if (utils.has(d, 'value_up')) {
		        tile_info.value_up = d.value_up;
		      }
		      if (utils.has(d, 'value_dn')) {
		        tile_info.value_dn = d.value_dn;
		      }
		      if (utils.has(d, 'info')) {
		        tile_info.info = d.info;
		      }
		      // run the user supplied callback function
		      params.click_tile(tile_info);
		      add_click_hlight(params, this);
		    });
		  } else {
	
		    // highlight clicked tile
		    if (params.tile_click_hlight) {
		      d3.selectAll(params.root + ' .tile').on('click', function () {
		        add_click_hlight(params, this);
		      });
		    }
		  }
	
		  // draw grid lines after drawing tiles
		  var delays = {};
		  var duration = 0;
		  delays.enter = 0;
		  draw_gridlines(params, delays, duration);
	
		  // Matrix API
		  return {
		    get_clust_group: function get_clust_group() {
		      return clust_group;
		    },
		    get_matrix: function get_matrix() {
		      return matrix;
		    },
		    get_nodes: function get_nodes(type) {
		      if (type === 'row') {
		        return network_data.row_nodes;
		      }
		      return network_data.col_nodes;
		    }
		  };
			};
	
	/***/ },
	/* 39 */
	/***/ function(module, exports) {
	
		"use strict";
	
		// var grid_lines_viz = require('./grid_lines_viz');
		// var toggle_grid_lines = require('./toggle_grid_lines');
	
		module.exports = function draw_gridlines(params, delays, duration) {
	
		  // var row_nodes = params.network_data.row_nodes;
		  // var col_nodes = params.network_data.col_nodes;
	
		  // // Fade in new gridlines
		  // ///////////////////////////
	
		  // // append horizontal line groups
		  // var horz_lines = d3.select(params.root+' .clust_group')
		  //   .selectAll('.horz_lines')
		  //   .data(row_nodes, function(d){return d.name;})
		  //   .enter()
		  //   .append('g')
		  //   .attr('class','horz_lines');
	
		  // // append vertical line groups
		  // var vert_lines = d3.select(params.root+' .clust_group')
		  //   .selectAll('.vert_lines')
		  //   .data(col_nodes)
		  //   .enter()
		  //   .append('g')
		  //   .attr('class', 'vert_lines');
	
		  // grid_lines_viz(params, duration);
	
		  // horz_lines
		  //   .select('line')
		  //   .attr('opacity',0)
		  //   .attr('stroke','white')
		  //   .attr('opacity', 1);
	
		  // vert_lines
		  //   .select('line')
		  //   .style('stroke', 'white')
		  //   .attr('opacity',0)
		  //   .transition().delay(delays.enter).duration(2*duration)
		  //   .attr('opacity', 1);
	
		  // toggle_grid_lines(params);
	
		};
	
	/***/ },
	/* 40 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function (params, clicked_rect) {
	
		  // get x position of rectangle
		  d3.select(clicked_rect).each(function (d) {
		    var pos_x = d.pos_x;
		    var pos_y = d.pos_y;
	
		    d3.selectAll(params.root + ' .click_hlight').remove();
	
		    if (pos_x != params.matrix.click_hlight_x || pos_y != params.matrix.click_hlight_y) {
	
		      // save pos_x to params.viz.click_hlight_x
		      params.matrix.click_hlight_x = pos_x;
		      params.matrix.click_hlight_y = pos_y;
	
		      // draw the highlighting rectangle as four rectangles
		      // so that the width and height can be controlled
		      // separately
	
		      var rel_width_hlight = 6;
		      var opacity_hlight = 0.85;
	
		      var hlight_width = rel_width_hlight * params.viz.border_width.x;
		      var hlight_height = rel_width_hlight * params.viz.border_width.y;
	
		      // top highlight
		      d3.select(clicked_rect.parentNode).append('rect').classed('click_hlight', true).classed('top_hlight', true).attr('width', params.viz.x_scale.rangeBand()).attr('height', hlight_height).attr('fill', params.matrix.hlight_color).attr('transform', function () {
		        return 'translate(' + params.viz.x_scale(pos_x) + ',0)';
		      }).attr('opacity', opacity_hlight);
	
		      // left highlight
		      d3.select(clicked_rect.parentNode).append('rect').classed('click_hlight', true).classed('left_hlight', true).attr('width', hlight_width).attr('height', params.viz.y_scale.rangeBand() - hlight_height * 0.99).attr('fill', params.matrix.hlight_color).attr('transform', function () {
		        return 'translate(' + params.viz.x_scale(pos_x) + ',' + hlight_height * 0.99 + ')';
		      }).attr('opacity', opacity_hlight);
	
		      // right highlight
		      d3.select(clicked_rect.parentNode).append('rect').classed('click_hlight', true).classed('right_hlight', true).attr('width', hlight_width).attr('height', params.viz.y_scale.rangeBand() - hlight_height * 0.99).attr('fill', params.matrix.hlight_color).attr('transform', function () {
		        var tmp_translate = params.viz.x_scale(pos_x) + params.viz.x_scale.rangeBand() - hlight_width;
		        return 'translate(' + tmp_translate + ',' + hlight_height * 0.99 + ')';
		      }).attr('opacity', opacity_hlight);
	
		      // bottom highlight
		      d3.select(clicked_rect.parentNode).append('rect').classed('click_hlight', true).classed('bottom_hlight', true).attr('width', function () {
		        return params.viz.x_scale.rangeBand() - 1.98 * hlight_width;
		      }).attr('height', hlight_height).attr('fill', params.matrix.hlight_color).attr('transform', function () {
		        var tmp_translate_x = params.viz.x_scale(pos_x) + hlight_width * 0.99;
		        var tmp_translate_y = params.viz.y_scale.rangeBand() - hlight_height;
		        return 'translate(' + tmp_translate_x + ',' + tmp_translate_y + ')';
		      }).attr('opacity', opacity_hlight);
		    } else {
		      params.matrix.click_hlight_x = -666;
		      params.matrix.click_hlight_y = -666;
		    }
		  });
		};
	
	/***/ },
	/* 41 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var make_simple_rows = __webpack_require__(42);
		var d3_tip_custom = __webpack_require__(48);
	
		// current matrix can change with downsampling
		module.exports = function make_matrix_rows(params, current_matrix) {
		  var row_names = arguments.length <= 2 || arguments[2] === undefined ? 'all' : arguments[2];
		  var ds_level = arguments.length <= 3 || arguments[3] === undefined ? -1 : arguments[3];
	
	
		  // defaults
		  var y_scale = params.viz.y_scale;
		  var make_tip = true;
		  var row_class = 'row';
	
		  if (ds_level >= 0) {
		    y_scale = params.viz.ds[ds_level].y_scale;
	
		    // do not show tip when rows are downsampled
		    make_tip = false;
		    row_class = 'ds' + String(ds_level) + '_row';
		  }
	
		  if (make_tip) {
	
		    // do not remove tile_tip here
		    /////////////////////////////////
	
		    // make rows in the matrix - add key names to rows in matrix
		    /////////////////////////////////////////////////////////////
		    // d3-tooltip - for tiles
		    var tip = d3_tip_custom().attr('class', function () {
		      var root_tip_selector = params.viz.root_tips.replace('.', '');
		      var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_tile_tip';
		      return class_string;
		    }).style('display', 'none').direction('nw').offset([0, 0]).html(function (d) {
		      var inst_value = String(d.value.toFixed(3));
		      var tooltip_string;
	
		      if (params.keep_orig) {
		        var orig_value = String(d.value_orig.toFixed(3));
		        tooltip_string = '<p>' + d.row_name + ' and ' + d.col_name + '</p>' + '<p> normalized value: ' + inst_value + '</p>' + '<div> original value: ' + orig_value + '</div>';
		      } else {
		        tooltip_string = '<p>' + d.row_name + ' and ' + d.col_name + '</p>' + '<div> value: ' + inst_value + '</div>';
		      }
	
		      return tooltip_string;
		    });
		  } else {
		    tip = null;
		  }
	
		  // gather a subset of row data from the matrix or use all rows
		  var matrix_subset = [];
		  if (row_names === 'all') {
		    matrix_subset = current_matrix;
		  } else {
		    _.each(current_matrix, function (inst_row) {
		      if (_.contains(row_names, inst_row.name)) {
		        matrix_subset.push(inst_row);
		      }
		    });
		  }
	
		  d3.select(params.root + ' .clust_group').selectAll('.row').data(matrix_subset, function (d) {
		    return d.name;
		  }).enter().append('g').classed(row_class, true).attr('transform', function (d) {
		    return 'translate(0,' + y_scale(d.row_index) + ')';
		  }).each(function (d) {
		    make_simple_rows(params, d, tip, this, ds_level);
		  });
	
		  if (params.viz.ds_level === -1 && tip != null) {
		    d3.selectAll(params.root + ' .row').call(tip);
		  }
			};
	
	/***/ },
	/* 42 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		/* eslint-disable */
	
		var draw_up_tile = __webpack_require__(43);
		var draw_dn_tile = __webpack_require__(44);
		var mouseover_tile = __webpack_require__(45);
		var mouseout_tile = __webpack_require__(46);
		var fine_position_tile = __webpack_require__(47);
	
		module.exports = function make_simple_rows(params, inst_data, tip, row_selection) {
		  var ds_level = arguments.length <= 4 || arguments[4] === undefined ? -1 : arguments[4];
	
	
		  var inp_row_data = inst_data.row_data;
	
		  var make_tip = true;
		  var rect_height = params.viz.rect_height;
		  if (ds_level >= 0) {
		    // make_tip = false;
		    rect_height = params.viz.ds[ds_level].rect_height;
		  }
	
		  var keep_orig;
		  if (_.has(params.network_data.links[0], 'value_orig')) {
		    keep_orig = true;
		  } else {
		    keep_orig = false;
		  }
	
		  var row_values;
		  if (keep_orig === false) {
		    // value: remove zero values to make visualization faster
		    row_values = _.filter(inp_row_data, function (num) {
		      return num.value !== 0;
		    });
		  } else {
		    row_values = inp_row_data;
		  }
	
		  // generate tiles in the current row
		  var tile = d3.select(row_selection).selectAll('rect').data(row_values, function (d) {
		    return d.col_name;
		  }).enter().append('rect').attr('class', 'tile row_tile').attr('width', params.viz.rect_width).attr('height', rect_height).style('fill', function (d) {
		    // switch the color based on up/dn value
		    var inst_fill;
		    if (d.value_orig === 'NaN') {
		      inst_fill = '#000000';
		    } else {
		      inst_fill = d.value > 0 ? params.matrix.tile_colors[0] : params.matrix.tile_colors[1];
		    }
		    return inst_fill;
		  }).style('fill-opacity', function (d) {
		    // calculate output opacity using the opacity scale
		    var inst_opacity;
		    if (d.value_orig === 'NaN') {
		      // console.log('found NaN while making tiles');
		      inst_opacity = 0.175;
		    } else {
		      inst_opacity = params.matrix.opacity_scale(Math.abs(d.value));
		    }
		    return inst_opacity;
		  }).attr('transform', function (d) {
		    return fine_position_tile(params, d);
		  });
	
		  if (make_tip) {
		    tile.on('mouseover', function () {
		      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
		        args[_key] = arguments[_key];
		      }
		      mouseover_tile(params, this, tip, args);
		    }).on('mouseout', function () {
		      mouseout_tile(params, this, tip);
		    });
		  }
	
		  // // tile circles
		  // /////////////////////////////
		  // var tile = d3.select(row_selection)
		  //   .selectAll('circle')
		  //   .data(row_values, function(d){ return d.col_name; })
		  //   .enter()
		  //   .append('circle')
		  //   .attr('cx', params.viz.rect_height/2)
		  //   .attr('cy', params.viz.rect_height/2)
		  //   .attr('r', params.viz.rect_height/3)
		  //   .attr('class', 'tile_circle')
		  //   // .attr('width', params.viz.rect_width/2)
		  //   // .attr('height', params.viz.rect_height/2)
		  //   // // switch the color based on up/dn value
		  //   // .style('fill', function(d) {
		  //   //   // return d.value > 0 ? params.matrix.tile_colors[0] : params.matrix.tile_colors[1];
		  //   //   return 'black';
		  //   // })
		  //   .on('mouseover', function(...args) {
		  //       mouseover_tile(params, this, tip, args);
		  //   })
		  //   .on('mouseout', function() {
		  //     mouseout_tile(params, this, tip);
		  //   })
		  //   .style('fill-opacity', function(d) {
		  //     // calculate output opacity using the opacity scale
		  //     var output_opacity = params.matrix.opacity_scale(Math.abs(d.value));
		  //     if (output_opacity < 0.3){
		  //       output_opacity = 0;
		  //     } else if (output_opacity < 0.6){
		  //       output_opacity = 0.35;
		  //     } else {
		  //       output_opacity = 1;
		  //     }
		  //     return output_opacity;
		  //     // return 0.1;
		  //   })
		  //   .attr('transform', function(d) {
		  //     return fine_position_tile(params, d);
		  //   });
	
	
		  if (params.matrix.tile_type == 'updn') {
	
		    // value split
		    var row_split_data = _.filter(inp_row_data, function (num) {
		      return num.value_up != 0 || num.value_dn != 0;
		    });
	
		    // tile_up
		    d3.select(row_selection).selectAll('.tile_up').data(row_split_data, function (d) {
		      return d.col_name;
		    }).enter().append('path').attr('class', 'tile_up').attr('d', function () {
		      return draw_up_tile(params);
		    }).attr('transform', function (d) {
		      fine_position_tile(params, d);
		    }).style('fill', function () {
		      return params.matrix.tile_colors[0];
		    }).style('fill-opacity', function (d) {
		      var inst_opacity = 0;
		      if (Math.abs(d.value_dn) > 0) {
		        inst_opacity = params.matrix.opacity_scale(Math.abs(d.value_up));
		      }
		      return inst_opacity;
		    }).on('mouseover', function () {
		      for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
		        args[_key2] = arguments[_key2];
		      }
	
		      mouseover_tile(params, this, tip, args);
		    }).on('mouseout', function () {
		      mouseout_tile(params, this, tip);
		    });
	
		    // tile_dn
		    d3.select(row_selection).selectAll('.tile_dn').data(row_split_data, function (d) {
		      return d.col_name;
		    }).enter().append('path').attr('class', 'tile_dn').attr('d', function () {
		      return draw_dn_tile(params);
		    }).attr('transform', function (d) {
		      fine_position_tile(params, d);
		    }).style('fill', function () {
		      return params.matrix.tile_colors[1];
		    }).style('fill-opacity', function (d) {
		      var inst_opacity = 0;
		      if (Math.abs(d.value_up) > 0) {
		        inst_opacity = params.matrix.opacity_scale(Math.abs(d.value_dn));
		      }
		      return inst_opacity;
		    }).on('mouseover', function () {
		      for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
		        args[_key3] = arguments[_key3];
		      }
	
		      mouseover_tile(params, this, tip, args);
		    }).on('mouseout', function () {
		      mouseout_tile(params, this, tip);
		    });
	
		    // remove rect when tile is split
		    tile.each(function (d) {
		      if (Math.abs(d.value_up) > 0 && Math.abs(d.value_dn) > 0) {
		        d3.select(this).remove();
		      }
		    });
		  }
	
		  // append title to group
		  if (params.matrix.tile_title) {
		    tile.append('title').text(function (d) {
		      var inst_string = 'value: ' + d.value;
		      return inst_string;
		    });
		  }
			};
	
	/***/ },
	/* 43 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function draw_up_tile(params) {
	
		  var start_x = 0;
		  var final_x = params.viz.x_scale.rangeBand() - params.viz.border_width.x;
		  var start_y = 0;
		  var final_y = params.viz.y_scale.rangeBand() - params.viz.border_width.y;
	
		  var output_string = 'M' + start_x + ',' + start_y + ', L' + start_x + ', ' + final_y + ', L' + final_x + ',0 Z';
	
		  return output_string;
		};
	
	/***/ },
	/* 44 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function draw_dn_tile(params) {
	
		  var start_x = 0;
		  var final_x = params.viz.x_scale.rangeBand() - params.viz.border_width.x;
		  var start_y = params.viz.y_scale.rangeBand() - params.viz.border_width.y;
		  var final_y = params.viz.y_scale.rangeBand() - params.viz.border_width.y;
	
		  var output_string = 'M' + start_x + ', ' + start_y + ' ,   L' + final_x + ', ' + final_y + ',  L' + final_x + ',0 Z';
	
		  return output_string;
		};
	
	/***/ },
	/* 45 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function mouseover_tile(params, inst_selection, tip, inst_arguments) {
	
		  var inst_data = inst_arguments[0];
		  var args = [].slice.call(inst_arguments);
		  var timeout;
		  var delay = 1000;
	
		  d3.select(inst_selection).classed('hovering', true);
	
		  _.each(['row', 'col'], function (inst_rc) {
	
		    d3.selectAll(params.root + ' .' + inst_rc + '_label_group text').style('font-weight', function (d) {
		      var font_weight;
		      var inst_found = inst_data[inst_rc + '_name'].replace(/_/g, ' ') === d.name;
	
		      if (inst_found) {
		        font_weight = 'bold';
		      } else {
		        font_weight = 'normal';
		      }
		      return font_weight;
		    });
		  });
	
		  args.push(inst_selection);
		  clearTimeout(timeout);
		  timeout = setTimeout(check_if_hovering, delay, inst_selection);
	
		  function check_if_hovering() {
	
		    if (d3.select(inst_selection).classed('hovering')) {
	
		      var inst_zoom = Number(d3.select(params.root + ' .viz_svg').attr('is_zoom'));
	
		      if (inst_zoom === 0) {
	
		        if (params.matrix.show_tile_tooltips && tip !== null) {
	
		          d3.selectAll(params.viz.root_tips + '_tile_tip').style('display', 'block');
	
		          tip.show.apply(inst_selection, args);
	
		          if (params.tile_tip_callback != null) {
		            var tile_info = args[0];
		            params.tile_tip_callback(tile_info);
		          }
		        }
		      }
		    }
		  }
			};
	
	/***/ },
	/* 46 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function mouseout_tile(params, inst_selection, tip) {
	
		  d3.select(inst_selection).classed('hovering', false);
	
		  d3.selectAll(params.viz.root_tips + '_tile_tip').style('display', 'none');
	
		  _.each(['row', 'col'], function (inst_rc) {
	
		    d3.selectAll(params.root + ' .' + inst_rc + '_label_group text').style('font-weight', 'normal');
		  });
	
		  if (tip != null) {
		    tip.hide();
		  }
		};
	
	/***/ },
	/* 47 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function fine_position_tile(params, d) {
	
		  var offset_x;
	
		  // prevent rows not in x_scale domain from causing errors
		  if (d.pos_x in params.viz.x_scale.domain()) {
		    offset_x = params.viz.x_scale(d.pos_x);
		  } else {
		    offset_x = 0;
		  }
	
		  var x_pos = offset_x + 0.5 * params.viz.border_width.x;
		  var y_pos = 0.5 * params.viz.border_width.y;
		  return 'translate(' + x_pos + ',' + y_pos + ')';
		};
	
	/***/ },
	/* 48 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function d3_tip_custom() {
		  /* eslint-disable */
		  // Copyright (c) 2013 Justin Palmer
		  //
		  // Tooltips for d3.js SVG visualizations
	
		  // Public - contructs a new tooltip
		  //
		  // Returns a tip
		  // ******************
		  // Nick Fernandez modified version 4-19-2016
		  // improved multiple svg, scrolling+zooming support
		  // made syntax fixes
		  //////////////////////////////////////////////
		  var direction = d3_tip_direction,
		      offset = d3_tip_offset,
		      html = d3_tip_html,
		      node = initNode(),
		      svg = null,
		      point = null,
		      target = null;
	
		  function tip(vis) {
		    svg = getSVGNode(vis);
		    point = svg.createSVGPoint();
		    document.body.appendChild(node);
		  }
	
		  // Public - show the tooltip on the screen
		  //
		  // Returns a tip
		  tip.show = function () {
	
		    var args = Array.prototype.slice.call(arguments);
		    if (args[args.length - 1] instanceof SVGElement) {
		      target = args.pop();
		    }
	
		    var content = html.apply(this, args);
		    var poffset = offset.apply(this, args);
		    var dir = direction.apply(this, args);
		    var nodel = d3.select(node);
		    var i = 0;
		    var coords;
	
		    // add z-index to make sure tooltips appear on top
		    nodel.html(content).style({ opacity: 1, 'pointer-events': 'all' }).style('z-index', 99);
	
		    while (i--) {
		      nodel.classed(directions[i], false);
		    }
		    coords = direction_callbacks.get(dir).apply(this);
		    nodel.classed(dir, true).style({
		      top: coords.top + poffset[0] + 'px',
		      left: coords.left + poffset[1] + 'px'
		    });
	
		    // quick fix for fading tile tooltips
		    if (isFunction(this) === false) {
	
		      var inst_class = d3.select(this).attr('class');
	
		      if (inst_class.indexOf('tile') >= 0) {
		        setTimeout(fade_tips, 5000, this);
		      }
		    }
	
		    return tip;
		  };
	
		  // Public - hide the tooltip
		  //
		  // Returns a tip
		  tip.hide = function () {
	
		    // // hide all d3-tip tooltips
		    // d3.selectAll('.d3-tip')
		    //   .style('display', 'none');
	
		    var nodel = d3.select(node);
		    nodel.style({ opacity: 0, 'pointer-events': 'none' });
		    return tip;
		  };
	
		  // Public: Proxy attr calls to the d3 tip container.  Sets or gets attribute value.
		  //
		  // n - name of the attribute
		  // v - value of the attribute
		  //
		  // Returns tip or attribute value
		  tip.attr = function (n) {
		    if (arguments.length < 2 && typeof n === 'string') {
		      return d3.select(node).attr(n);
		    } else {
		      var args = Array.prototype.slice.call(arguments);
		      d3.selection.prototype.attr.apply(d3.select(node), args);
		    }
	
		    return tip;
		  };
	
		  // Public: Proxy style calls to the d3 tip container.  Sets or gets a style value.
		  //
		  // n - name of the property
		  // v - value of the property
		  //
		  // Returns tip or style property value
		  tip.style = function (n) {
		    if (arguments.length < 2 && typeof n === 'string') {
		      return d3.select(node).style(n);
		    } else {
		      var args = Array.prototype.slice.call(arguments);
		      d3.selection.prototype.style.apply(d3.select(node), args);
		    }
	
		    return tip;
		  };
	
		  // Public: Set or get the direction of the tooltip
		  //
		  // v - One of n(north), s(south), e(east), or w(west), nw(northwest),
		  //     sw(southwest), ne(northeast) or se(southeast)
		  //
		  // Returns tip or direction
		  tip.direction = function (v) {
		    if (!arguments.length) {
		      return direction;
		    }
		    direction = v == null ? v : d3.functor(v);
	
		    return tip;
		  };
	
		  // Public: Sets or gets the offset of the tip
		  //
		  // v - Array of [x, y] offset
		  //
		  // Returns offset or
		  tip.offset = function (v) {
		    if (!arguments.length) {
		      return offset;
		    }
		    offset = v == null ? v : d3.functor(v);
	
		    return tip;
		  };
	
		  // Public: sets or gets the html value of the tooltip
		  //
		  // v - String value of the tip
		  //
		  // Returns html value or tip
		  tip.html = function (v) {
		    if (!arguments.length) {
		      return html;
		    }
		    html = v == null ? v : d3.functor(v);
	
		    return tip;
		  };
	
		  function d3_tip_direction() {
		    return 'n';
		  }
		  function d3_tip_offset() {
		    return [0, 0];
		  }
		  function d3_tip_html() {
		    return ' ';
		  }
	
		  var direction_callbacks = d3.map({
		    n: direction_n,
		    s: direction_s,
		    e: direction_e,
		    w: direction_w,
		    nw: direction_nw,
		    ne: direction_ne,
		    sw: direction_sw,
		    se: direction_se,
		    south_custom: direction_south_custom
		  }),
		      directions = direction_callbacks.keys();
	
		  function direction_south_custom() {
		    var bbox = getScreenBBox();
	
		    return {
		      top: bbox.s.y,
		      left: bbox.s.x
		    };
		  }
	
		  function direction_n() {
		    var bbox = getScreenBBox();
		    return {
		      top: bbox.n.y - node.offsetHeight,
		      left: bbox.n.x - node.offsetWidth / 2
		    };
		  }
	
		  function direction_s() {
		    var bbox = getScreenBBox();
		    return {
		      top: bbox.s.y,
		      left: bbox.s.x - node.offsetWidth / 2
		    };
		  }
	
		  function direction_e() {
		    var bbox = getScreenBBox();
		    return {
		      top: bbox.e.y - node.offsetHeight / 2,
		      left: bbox.e.x
		    };
		  }
	
		  function direction_w() {
		    var bbox = getScreenBBox();
		    return {
		      top: bbox.w.y - node.offsetHeight / 2,
		      left: bbox.w.x - node.offsetWidth
		    };
		  }
	
		  function direction_nw() {
		    var bbox = getScreenBBox();
		    return {
		      top: bbox.nw.y - node.offsetHeight,
		      left: bbox.nw.x - node.offsetWidth
		    };
		  }
	
		  function direction_ne() {
		    var bbox = getScreenBBox();
		    return {
		      top: bbox.ne.y - node.offsetHeight,
		      left: bbox.ne.x
		    };
		  }
	
		  function direction_sw() {
		    var bbox = getScreenBBox();
		    return {
		      top: bbox.sw.y,
		      left: bbox.sw.x - node.offsetWidth
		    };
		  }
	
		  function direction_se() {
		    var bbox = getScreenBBox();
		    return {
		      top: bbox.se.y,
		      left: bbox.e.x
		    };
		  }
	
		  function initNode() {
		    var node = d3.select(document.createElement('div'));
		    node.style({
		      position: 'absolute',
		      opacity: 0,
		      pointerEvents: 'none',
		      boxSizing: 'border-box'
		    });
	
		    return node.node();
		  }
	
		  function getSVGNode(el) {
		    el = el.node();
		    if (el.tagName.toLowerCase() == 'svg') {
		      return el;
		    }
	
		    return el.ownerSVGElement;
		  }
	
		  // Private - gets the screen coordinates of a shape
		  //
		  // Given a shape on the screen, will return an SVGPoint for the directions
		  // n(north), s(south), e(east), w(west), ne(northeast), se(southeast), nw(northwest),
		  // sw(southwest).
		  //
		  //    +-+-+
		  //    |   |
		  //    +   +
		  //    |   |
		  //    +-+-+
		  //
		  // Returns an Object {n, s, e, w, nw, sw, ne, se}
		  function getScreenBBox() {
		    var targetel = target || d3.event.target;
		    var bbox = {};
		    var matrix = targetel.getScreenCTM();
		    var tbbox = targetel.getBBox();
		    var width = tbbox.width;
		    var height = tbbox.height;
		    var x = tbbox.x;
		    var y = tbbox.y;
		    var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
		    var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
	
		    // Nick - prevents bugs with scrolling and zooming on the same object
		    matrix.a = 1;
		    matrix.d = 1;
		    // changing order of adding scrolling,
		    // original ordering was causing problems with pre-translated or rotated
		    // elements.
		    matrix.e = matrix.e + scrollLeft;
		    matrix.f = matrix.f + scrollTop;
		    point.x = x; //+ scrollLeft
		    point.y = y; //+ scrollTop
	
		    bbox.nw = point.matrixTransform(matrix);
		    point.x = point.x + width;
		    bbox.ne = point.matrixTransform(matrix);
		    point.y = point.y + height;
		    bbox.se = point.matrixTransform(matrix);
		    point.x = point.x - width;
		    bbox.sw = point.matrixTransform(matrix);
		    point.y = point.y - height / 2;
		    bbox.w = point.matrixTransform(matrix);
		    point.x = point.x + width;
		    bbox.e = point.matrixTransform(matrix);
		    point.x = point.x - width / 2;
		    point.y = point.y - height / 2;
		    bbox.n = point.matrixTransform(matrix);
		    point.y = point.y + height;
		    bbox.s = point.matrixTransform(matrix);
	
		    return bbox;
		  }
	
		  // only fade tips if you are still hovering on the current tip
		  function fade_tips(inst_selection) {
	
		    var is_hovering = d3.select(inst_selection).classed('hovering');
	
		    if (is_hovering) {
		      d3.selectAll('.d3-tip').transition().duration(250).style('opacity', 0).style('display', 'none');
		    }
		  }
	
		  function isFunction(functionToCheck) {
		    var getType = {};
		    return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
		  }
	
		  return tip;
		};
	
	/***/ },
	/* 49 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var make_row_labels = __webpack_require__(50);
	
		module.exports = function make_row_label_container(cgm, text_delay) {
	
		  var params = cgm.params;
	
		  var row_container;
	
		  // row container holds all row text and row visualizations (triangles rects)
		  ////////////////////////////////////////////////////////////////////////////
		  if (d3.select(params.viz.viz_svg + ' .row_container').empty()) {
		    row_container = d3.select(params.viz.viz_svg).append('g').classed('row_container', true).attr('transform', 'translate(' + params.viz.norm_labels.margin.left + ',' + params.viz.clust.margin.top + ')');
		  } else {
		    row_container = d3.select(params.viz.viz_svg).select('.row_container').attr('transform', 'translate(' + params.viz.norm_labels.margin.left + ',' + params.viz.clust.margin.top + ')');
		  }
	
		  if (d3.select(params.root + ' .row_white_background').empty()) {
		    row_container.append('rect').classed('row_white_background', true).classed('white_bars', true).attr('fill', params.viz.background_color).attr('width', params.viz.label_background.row).attr('height', 30 * params.viz.clust.dim.height + 'px');
		  }
	
		  // add container to hold text row labels if not already there
		  if (d3.select(params.root + ' .row_label_container').empty()) {
		    row_container.append('g').classed('row_label_container', true).attr('transform', 'translate(' + params.viz.norm_labels.width.row + ',0)').append('g').classed('row_label_zoom_container', true);
		  } else {
		    row_container.select(params.root + ' .row_label_container').attr('transform', 'translate(' + params.viz.norm_labels.width.row + ',0)');
		  }
	
		  // make row labels in the container
		  ///////////////////////////////////////
		  if (params.viz.ds_level === -1) {
		    make_row_labels(cgm, 'all', text_delay);
		  }
			};
	
	/***/ },
	/* 50 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var utils = __webpack_require__(2);
		var add_row_click_hlight = __webpack_require__(51);
		var row_reorder = __webpack_require__(52);
		var make_row_tooltips = __webpack_require__(66);
	
		module.exports = function make_row_labels(cgm) {
		  var row_names = arguments.length <= 1 || arguments[1] === undefined ? 'all' : arguments[1];
		  var text_delay = arguments.length <= 2 || arguments[2] === undefined ? 0 : arguments[2];
	
	
		  // console.log('make_row_labels')
		  // console.log(row_names)
	
		  var params = cgm.params;
		  var row_nodes = [];
	
		  if (row_names === 'all') {
		    row_nodes = params.network_data.row_nodes;
		  } else {
		    _.each(params.network_data.row_nodes, function (inst_row) {
		      if (_.contains(row_names, inst_row.name)) {
		        row_nodes.push(inst_row);
		      }
		    });
		  }
	
		  // make row labels in row_label_zoom_container, bind row_nodes data
		  var row_labels = d3.select(params.root + ' .row_label_zoom_container').selectAll('g').data(row_nodes, function (d) {
		    return d.name;
		  }).enter().append('g').classed('row_label_group', true);
	
		  var row_nodes_names = params.network_data.row_nodes_names;
		  row_labels.attr('transform', function (d) {
		    // var inst_index = d.row_index;
		    var inst_index = _.indexOf(row_nodes_names, d.name);
		    return 'translate(0,' + params.viz.y_scale(inst_index) + ')';
		  });
	
		  row_labels.on('dblclick', function (d) {
	
		    var data_attr = '__data__';
		    var row_name = this[data_attr].name;
	
		    // if (params.sim_mat){
		    //   row_reorder(cgm, this, row_name);
	
		    //   d3.selectAll(params.root+' .col_label_text')
		    //     .filter(function(d){
		    //       return d.name == row_name;}
		    //       )[0][0];
	
		    //   // this is causing buggyness may reenable
		    //   // col_reorder -> two_translate_zoom -> show_visible_area -> make_row_labels -> col_reorder
		    //   // col_reorder(cgm, col_selection, row_name);
	
		    // } else {
		    //   row_reorder(cgm, this, row_name);
		    // }
	
		    row_reorder(cgm, this, row_name);
	
		    if (params.tile_click_hlight) {
		      add_row_click_hlight(this, d.ini);
		    }
		  });
	
		  make_row_tooltips(params);
	
		  // append rectangle behind text
		  row_labels.insert('rect').style('opacity', 0);
	
		  // append row label text
		  row_labels.append('text').attr('y', params.viz.rect_height * 0.5 + params.labels.default_fs_row * 0.35).attr('text-anchor', 'end').style('font-size', params.labels.default_fs_row + 'px').text(function (d) {
		    return utils.normal_name(d);
		  }).attr('pointer-events', 'none').style('opacity', 0).style('cursor', 'default').transition().delay(text_delay).duration(text_delay).style('opacity', 1);
	
		  // change the size of the highlighting rects
		  row_labels.each(function () {
		    var bbox = d3.select(this).select('text')[0][0].getBBox();
		    d3.select(this).select('rect').attr('x', bbox.x).attr('y', 0).attr('width', bbox.width).attr('height', params.viz.y_scale.rangeBand()).style('fill', function () {
		      var inst_hl = 'yellow';
		      return inst_hl;
		    }).style('opacity', function (d) {
		      var inst_opacity = 0;
		      // highlight target genes
		      if (d.target === 1) {
		        inst_opacity = 1;
		      }
		      return inst_opacity;
		    });
		  });
	
		  // almost-deprecated row value bars
		  ///////////////////////////////
		  if (utils.has(params.network_data.row_nodes[0], 'value')) {
	
		    row_labels.append('rect').classed('row_bars', true).attr('width', function (d) {
		      var inst_value = 0;
		      inst_value = params.labels.bar_scale_row(Math.abs(d.value));
		      return inst_value;
		    }).attr('x', function (d) {
		      var inst_value = 0;
		      inst_value = -params.labels.bar_scale_row(Math.abs(d.value));
		      return inst_value;
		    }).attr('height', params.viz.y_scale.rangeBand()).attr('fill', function (d) {
		      return d.value > 0 ? params.matrix.bar_colors[0] : params.matrix.bar_colors[1];
		    }).attr('opacity', 0.4);
		  }
			};
	
	/***/ },
	/* 51 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function (params, clicked_row, id_clicked_row) {
		  if (id_clicked_row != params.click_hlight_row) {
	
		    var rel_width_hlight = 6;
		    var opacity_hlight = 0.85;
		    var hlight_height = rel_width_hlight * params.viz.border_width.x;
	
		    d3.selectAll(params.root + ' .click_hlight').remove();
	
		    // // highlight selected row
		    // d3.selectAll(params.root+' .row_label_group')
		    //   .select('rect')
		    // d3.select(this)
		    //   .select('rect')
		    //   .style('opacity', 1);
	
		    d3.select(clicked_row).append('rect').classed('click_hlight', true).classed('row_top_hlight', true).attr('width', params.viz.svg_dim.width).attr('height', hlight_height).attr('fill', params.matrix.hlight_color).attr('opacity', opacity_hlight);
	
		    d3.select(clicked_row).append('rect').classed('click_hlight', true).classed('row_bottom_hlight', true).attr('width', params.viz.svg_dim.width).attr('height', hlight_height).attr('fill', params.matrix.hlight_color).attr('opacity', opacity_hlight).attr('transform', function () {
		      var tmp_translate_y = params.viz.y_scale.rangeBand() - hlight_height;
		      return 'translate(0,' + tmp_translate_y + ')';
		    });
		  } else {
		    d3.selectAll(params.root + ' .click_hlight').remove();
		    params.click_hlight_row = -666;
		  }
			};
	
	/***/ },
	/* 52 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var reposition_tile_highlight = __webpack_require__(53);
		var toggle_dendro_view = __webpack_require__(54);
		var ini_zoom_info = __webpack_require__(36);
		var get_previous_zoom = __webpack_require__(65);
		var calc_downsampled_levels = __webpack_require__(27);
	
		module.exports = function row_reorder(cgm, row_selection, inst_row) {
	
		  var params = cgm.params;
		  var prev_zoom = get_previous_zoom(params);
	
		  if (prev_zoom.zoom_y === 1 && prev_zoom.zoom_x === 1) {
	
		    params.viz.inst_order.row = 'custom';
		    toggle_dendro_view(cgm, 'col');
	
		    d3.selectAll(params.root + ' .toggle_col_order .btn').classed('active', false);
	
		    params.viz.run_trans = true;
	
		    var mat = $.extend(true, {}, params.matrix.matrix);
		    var row_nodes = params.network_data.row_nodes;
		    var col_nodes = params.network_data.col_nodes;
	
		    // find the index of the row
		    var tmp_arr = [];
		    row_nodes.forEach(function (node) {
		      tmp_arr.push(node.name);
		    });
	
		    // find index
		    inst_row = _.indexOf(tmp_arr, inst_row);
	
		    // gather the values of the input genes
		    tmp_arr = [];
		    col_nodes.forEach(function (node, index) {
		      tmp_arr.push(mat[inst_row].row_data[index].value);
		    });
	
		    // sort the rows
		    var tmp_sort = d3.range(tmp_arr.length).sort(function (a, b) {
		      return tmp_arr[b] - tmp_arr[a];
		    });
	
		    // resort cols (cols are reorderd by double clicking a row)
		    params.viz.x_scale.domain(tmp_sort);
	
		    // save to custom col order
		    params.matrix.orders.custom_row = tmp_sort;
	
		    // reorder matrix
		    ////////////////////
		    var t;
		    if (params.network_data.links.length > params.matrix.def_large_matrix) {
		      t = d3.select(params.root + ' .viz_svg');
		    } else {
		      t = d3.select(params.root + ' .viz_svg').transition().duration(2500);
		    }
	
		    var col_nodes_names = params.network_data.col_nodes_names;
	
		    // Move Col Labels
		    t.select('.col_zoom_container').selectAll('.col_label_text').attr('transform', function (d) {
		      var inst_index = _.indexOf(col_nodes_names, d.name);
		      return 'translate(' + params.viz.x_scale(inst_index) + ')rotate(-90)';
		    });
	
		    // reorder col_class groups
		    t.selectAll('.col_cat_group').attr('transform', function (d) {
		      var inst_index = _.indexOf(col_nodes_names, d.name);
		      return 'translate(' + params.viz.x_scale(inst_index) + ',0)';
		    });
	
		    // reorder tiles in matrix (do not change row order)
		    if (params.viz.ds_level === -1) {
		      t.selectAll('.tile').attr('transform', function (d) {
		        return 'translate(' + params.viz.x_scale(d.pos_x) + ',0)';
		      });
	
		      t.selectAll('.tile_up').attr('transform', function (d) {
		        return 'translate(' + params.viz.x_scale(d.pos_x) + ',0)';
		      });
	
		      t.selectAll('.tile_dn').attr('transform', function (d) {
		        return 'translate(' + params.viz.x_scale(d.pos_x) + ',0)';
		      });
		    }
	
		    // highlight selected row
		    ///////////////////////////////
		    // unhilight and unbold all columns (already unbolded earlier)
		    d3.selectAll(params.root + ' .row_label_group').select('rect').style('opacity', 0);
		    // highlight column name
		    d3.select(row_selection).select('rect').style('opacity', 1);
	
		    reposition_tile_highlight(params);
	
		    // redefine x and y positions
		    params.network_data.links.forEach(function (d) {
		      d.x = params.viz.x_scale(d.target);
		      d.y = params.viz.y_scale(d.source);
		    });
	
		    params.zoom_info = ini_zoom_info();
	
		    setTimeout(function () {
		      params.viz.run_trans = false;
		    }, 2500);
	
		    // calculate downsmapling if necessary
		    if (params.viz.ds_num_levels > 0 && params.viz.ds_level >= 0) {
	
		      calc_downsampled_levels(params);
	
		      // var zooming_stopped = true;
		      // var zooming_out = true;
		      // var make_all_rows = true;
		      // // show_visible_area is also run with two_translate_zoom, but at that point
		      // // the parameters were not updated and two_translate_zoom if only run
		      // // if needed to reset zoom
		      // show_visible_area(cgm, zooming_stopped, zooming_out, make_all_rows);
		    }
		  }
			};
	
	/***/ },
	/* 53 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function (params) {
	
		  // resize click hlight
		  var rel_width_hlight = 6;
		  // var opacity_hlight = 0.85;
	
		  var hlight_width = rel_width_hlight * params.viz.border_width.x;
		  var hlight_height = rel_width_hlight * params.viz.border_width.y;
	
		  // reposition tile highlight
		  ////////////////////////////////
		  // top highlight
		  d3.select(params.root + ' .top_hlight').attr('width', params.viz.x_scale.rangeBand()).attr('height', hlight_height).transition().duration(2500).attr('transform', function () {
		    return 'translate(' + params.viz.x_scale(params.matrix.click_hlight_x) + ',0)';
		  });
	
		  // left highlight
		  d3.select(params.root + ' .left_hlight').attr('width', hlight_width).attr('height', params.viz.y_scale.rangeBand() - hlight_height * 0.99).transition().duration(2500).attr('transform', function () {
		    return 'translate(' + params.viz.x_scale(params.matrix.click_hlight_x) + ',' + hlight_height * 0.99 + ')';
		  });
	
		  // right highlight
		  d3.select(params.root + ' .right_hlight').attr('width', hlight_width).attr('height', params.viz.y_scale.rangeBand() - hlight_height * 0.99).transition().duration(2500).attr('transform', function () {
		    var tmp_translate = params.viz.x_scale(params.matrix.click_hlight_x) + params.viz.x_scale.rangeBand() - hlight_width;
		    return 'translate(' + tmp_translate + ',' + hlight_height * 0.99 + ')';
		  });
	
		  // bottom highlight
		  d3.select(params.root + ' .bottom_hlight').attr('width', function () {
		    return params.viz.x_scale.rangeBand() - 1.98 * hlight_width;
		  }).attr('height', hlight_height).transition().duration(2500).attr('transform', function () {
		    var tmp_translate_x = params.viz.x_scale(params.matrix.click_hlight_x) + hlight_width * 0.99;
		    var tmp_translate_y = params.viz.y_scale.rangeBand() - hlight_height;
		    return 'translate(' + tmp_translate_x + ',' + tmp_translate_y + ')';
		  });
			};
	
	/***/ },
	/* 54 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var make_dendro_triangles = __webpack_require__(55);
	
		module.exports = function toggle_dendro_view(cgm, inst_rc) {
		  var wait_time = arguments.length <= 2 || arguments[2] === undefined ? 1500 : arguments[2];
	
	
		  var params = cgm.params;
	
		  // row and col are reversed
		  if (inst_rc === 'row') {
		    if (params.viz.inst_order.col === 'clust') {
		      // the last true tells the viz that I'm chaning group size and not to
		      // delay the change in dendro
		      setTimeout(make_dendro_triangles, wait_time, cgm, 'row', true);
		    }
		  }
	
		  if (inst_rc === 'col') {
		    if (params.viz.inst_order.row === 'clust') {
		      setTimeout(make_dendro_triangles, wait_time, cgm, 'col', true);
		    }
		  }
	
		  if (params.viz.inst_order.row != 'clust' && params.viz.dendro_filter.col === false) {
		    d3.selectAll(params.root + ' .col_dendro_group').style('opacity', 0).on('mouseover', null).on('mouseout', null);
	
		    d3.select(params.root + ' .col_slider_group').style('opacity', 0);
	
		    // toggle crop buttons
		    d3.selectAll(params.root + ' .col_dendro_crop_buttons').style('opacity', 0).on('mouseover', null).on('mouseout', null);
		  }
	
		  if (params.viz.inst_order.col != 'clust' && params.viz.dendro_filter.row === false) {
	
		    d3.selectAll(params.root + ' .row_dendro_group').style('opacity', 0).on('mouseover', null).on('mouseout', null).on('click', null);
	
		    d3.select(params.root + ' .row_slider_group').style('opacity', 0);
	
		    // toggle crop buttons
		    d3.selectAll(params.root + ' .row_dendro_crop_buttons').style('opacity', 0).on('mouseover', null).on('mouseout', null);
		  }
		};
	
	/***/ },
	/* 55 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var calc_row_dendro_triangles = __webpack_require__(56);
		var calc_col_dendro_triangles = __webpack_require__(57);
		var dendro_group_highlight = __webpack_require__(58);
		var d3_tip_custom = __webpack_require__(48);
		var make_dendro_crop_buttons = __webpack_require__(60);
		var make_cat_breakdown_graph = __webpack_require__(63);
	
		module.exports = function make_dendro_triangles(cgm, inst_rc) {
		  var is_change_group = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];
	
	
		  var params = cgm.params;
	
		  // in case sim_mat
		  if (inst_rc === 'both') {
		    inst_rc = 'row';
		  }
	
		  var other_rc;
		  if (inst_rc === 'row') {
		    other_rc = 'col';
		  } else {
		    other_rc = 'row';
		  }
	
		  // orders are switched!
		  if (params.viz.inst_order[other_rc] === 'clust') {
		    d3.select(params.root + ' .' + inst_rc + '_slider_group').style('opacity', 1);
		  }
	
		  var dendro_info;
	
		  if (inst_rc === 'row') {
		    dendro_info = calc_row_dendro_triangles(params);
		  } else {
		    dendro_info = calc_col_dendro_triangles(params);
		  }
	
		  if (d3.select(cgm.params.root + ' .' + inst_rc + '_dendro_crop_buttons').empty() === false) {
		    make_dendro_crop_buttons(cgm, inst_rc);
		  }
	
		  // constant dendrogram opacity
		  var inst_dendro_opacity = params.viz.dendro_opacity;
	
		  function still_hovering(inst_selection, inst_data, i) {
	
		    if (d3.select(inst_selection).classed('hovering')) {
	
		      // define where graph should be built
		      var inst_selector = params.viz.root_tips + '_' + inst_rc + '_dendro_tip';
	
		      // prevent mouseover from making multiple graphs
		      if (d3.select(inst_selector + ' .cat_graph').empty()) {
	
		        if (params.viz.cat_info[inst_rc] !== null) {
		          make_cat_breakdown_graph(params, inst_rc, inst_data, dendro_info[i], inst_selector, true);
		        }
		      }
	
		      d3.selectAll(params.viz.root_tips + '_' + inst_rc + '_dendro_tip').style('opacity', 1);
		    }
		  }
	
		  var wait_before_tooltip = 500;
	
		  // remove any old dendro tooltips from this visualization
		  d3.selectAll(cgm.params.viz.root_tips + '_' + inst_rc + '_dendro_tip').remove();
	
		  // run transition rules
		  var run_transition;
		  if (d3.selectAll(params.root + ' .' + inst_rc + '_dendro_group').empty()) {
		    run_transition = false;
		  } else {
		    run_transition = true;
		    d3.selectAll(params.root + ' .' + inst_rc + '_dendro_group').remove();
		    // d3.selectAll(params.root+' .dendro_tip').remove();
		  }
	
		  // d3-tooltip
		  var tmp_y_offset = 0;
		  var tmp_x_offset = -5;
		  var dendro_tip = d3_tip_custom().attr('class', function () {
		    // add root element to class
		    var root_tip_selector = params.viz.root_tips.replace('.', '');
		    var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_' + inst_rc + '_dendro_tip';
	
		    return class_string;
		  }).direction('nw').offset([tmp_y_offset, tmp_x_offset]).style('display', 'none').style('opacity', 0);
	
		  dendro_tip.html(function () {
		    var full_string = '<div class="cluster_info_container"></div>Click for cluster information <br>' + 'and additional options.';
		    return full_string;
		  });
	
		  if (is_change_group) {
		    run_transition = false;
		  }
	
		  var dendro_traps = d3.select(params.root + ' .' + inst_rc + '_dendro_container').selectAll('path').data(dendro_info, function (d) {
		    return d.name;
		  }).enter().append('path').style('opacity', 0).attr('class', inst_rc + '_dendro_group').style('fill', 'black');
	
		  // draw triangles (shown as trapezoids)
		  //////////////////////////////////////////
		  var start_x;
		  var start_y;
		  var mid_x;
		  var mid_y;
		  var final_x;
		  var final_y;
	
		  // row triangles
		  dendro_traps.attr('d', function (d) {
	
		    if (inst_rc === 'row') {
		      // row triangles
		      start_x = 0;
		      start_y = d.pos_top;
		      mid_x = 30;
		      mid_y = d.pos_mid;
		      final_x = 0;
		      final_y = d.pos_bot;
		    } else {
		      // column triangles
		      start_x = d.pos_top;
		      start_y = 0;
		      mid_x = d.pos_mid;
		      mid_y = 30;
		      final_x = d.pos_bot;
		      final_y = 0;
		    }
	
		    var output_string = 'M' + start_x + ',' + start_y + ', L' + mid_x + ', ' + mid_y + ', L' + final_x + ',' + final_y + ' Z';
		    return output_string;
		  });
	
		  dendro_traps.on('mouseover', function (d, i) {
	
		    // if (params.sim_mat){
		    //   inst_rc = 'both';
		    // }
	
		    // run instantly on mouseover
		    d3.select(this).classed('hovering', true);
	
		    if (cgm.params.dendro_callback != null) {
		      cgm.params.dendro_callback(this);
		    }
	
		    // display tip
		    // this is needed for it to show in the right place and the opacity
		    // will be toggled to delay the tooltip for the user
		    d3.select(params.viz.root_tips + '_' + inst_rc + '_dendro_tip').style('display', 'block');
	
		    dendro_group_highlight(params, this, d, inst_rc);
	
		    // show the tip (make sure it is displaying before it is shown)
		    dendro_tip.show(d);
	
		    // set opacity to zero
		    d3.select(params.viz.root_tips + '_' + inst_rc + '_dendro_tip').style('opacity', 0);
	
		    // check if still hovering
		    setTimeout(still_hovering, wait_before_tooltip, this, d, i);
		  }).on('mouseout', function () {
		    if (params.viz.inst_order[other_rc] === 'clust') {
		      d3.select(this).style('opacity', inst_dendro_opacity);
		    }
	
		    d3.selectAll(params.root + ' .dendro_shadow').remove();
	
		    d3.select(this).classed('hovering', false);
		    dendro_tip.hide(this);
		  }).on('click', function (d, i) {
	
		    $(params.root + ' .dendro_info').modal('toggle');
	
		    var group_string = d.all_names.join(', ');
		    d3.select(params.root + ' .dendro_info input').attr('value', group_string);
	
		    var inst_selector = '.dendro_info';
	
		    // remove old graphs
		    d3.select('.dendro_info .cluster_info_container .cat_graph').remove();
	
		    if (params.viz.cat_info[inst_rc] !== null) {
		      make_cat_breakdown_graph(params, inst_rc, d, dendro_info[i], inst_selector);
		    }
	
		    if (cgm.params.dendro_click_callback != null) {
		      cgm.params.dendro_click_callback(this);
		    }
		  }).call(dendro_tip);
	
		  var triangle_opacity;
		  if (params.viz.inst_order[other_rc] === 'clust') {
		    triangle_opacity = inst_dendro_opacity;
		  } else {
		    triangle_opacity = 0;
		  }
	
		  if (run_transition) {
	
		    d3.select(params.root + ' .' + inst_rc + '_dendro_container').selectAll('path').transition().delay(1000).duration(1000).style('opacity', triangle_opacity);
		  } else {
	
		    d3.select(params.root + ' .' + inst_rc + '_dendro_container').selectAll('path').style('opacity', triangle_opacity);
		  }
			};
	
	/***/ },
	/* 56 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function calc_row_dendro_triangles(params) {
	
		  var triangle_info = {};
		  var inst_level = params.group_level.row;
		  var row_nodes = params.network_data.row_nodes;
		  var row_nodes_names = params.network_data.row_nodes_names;
	
		  _.each(row_nodes, function (d) {
	
		    // console.log('row_node '+d.name)
	
		    var tmp_group = d.group[inst_level];
		    var inst_index = _.indexOf(row_nodes_names, d.name);
		    var inst_top = params.viz.y_scale(inst_index);
		    var inst_bot = inst_top + params.viz.y_scale.rangeBand();
	
		    if (_.has(triangle_info, tmp_group) === false) {
		      triangle_info[tmp_group] = {};
		      triangle_info[tmp_group].name_top = d.name;
		      triangle_info[tmp_group].name_bot = d.name;
		      triangle_info[tmp_group].pos_top = inst_top;
		      triangle_info[tmp_group].pos_bot = inst_bot;
		      triangle_info[tmp_group].pos_mid = (inst_top + inst_bot) / 2;
		      triangle_info[tmp_group].name = tmp_group;
		      triangle_info[tmp_group].all_names = [];
		      triangle_info[tmp_group].inst_rc = 'row';
		    }
	
		    triangle_info[tmp_group].all_names.push(d.name);
	
		    if (inst_top < triangle_info[tmp_group].pos_top) {
		      triangle_info[tmp_group].name_top = d.name;
		      triangle_info[tmp_group].pos_top = inst_top;
		      triangle_info[tmp_group].pos_mid = (inst_top + triangle_info[tmp_group].pos_bot) / 2;
		    }
	
		    if (inst_bot > triangle_info[tmp_group].pos_bot) {
		      triangle_info[tmp_group].name_bot = d.name;
		      triangle_info[tmp_group].pos_bot = inst_bot;
		      triangle_info[tmp_group].pos_mid = (triangle_info[tmp_group].pos_top + inst_bot) / 2;
		    }
		  });
	
		  var group_info = [];
	
		  _.each(triangle_info, function (d) {
		    group_info.push(d);
		  });
	
		  return group_info;
		};
	
	/***/ },
	/* 57 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function calc_col_dendro_triangles(params) {
	
		  var triangle_info = {};
		  var inst_level = params.group_level.col;
		  var col_nodes = params.network_data.col_nodes;
		  var col_nodes_names = params.network_data.col_nodes_names;
	
		  _.each(col_nodes, function (d) {
	
		    var tmp_group = d.group[inst_level];
		    var inst_index = _.indexOf(col_nodes_names, d.name);
		    var inst_top = params.viz.x_scale(inst_index);
		    var inst_bot = inst_top + params.viz.x_scale.rangeBand();
	
		    if (_.has(triangle_info, tmp_group) === false) {
		      triangle_info[tmp_group] = {};
		      triangle_info[tmp_group].name_top = d.name;
		      triangle_info[tmp_group].name_bot = d.name;
		      triangle_info[tmp_group].pos_top = inst_top;
		      triangle_info[tmp_group].pos_bot = inst_bot;
		      triangle_info[tmp_group].pos_mid = (inst_top + inst_bot) / 2;
		      triangle_info[tmp_group].name = tmp_group;
		      triangle_info[tmp_group].all_names = [];
		      triangle_info[tmp_group].inst_rc = 'col';
		    }
	
		    triangle_info[tmp_group].all_names.push(d.name);
	
		    if (inst_top < triangle_info[tmp_group].pos_top) {
		      triangle_info[tmp_group].name_top = d.name;
		      triangle_info[tmp_group].pos_top = inst_top;
		      triangle_info[tmp_group].pos_mid = (inst_top + triangle_info[tmp_group].pos_bot) / 2;
		    }
	
		    if (inst_bot > triangle_info[tmp_group].pos_bot) {
		      triangle_info[tmp_group].name_bot = d.name;
		      triangle_info[tmp_group].pos_bot = inst_bot;
		      triangle_info[tmp_group].pos_mid = (triangle_info[tmp_group].pos_top + inst_bot) / 2;
		    }
		  });
	
		  var group_info = [];
	
		  _.each(triangle_info, function (d) {
		    group_info.push(d);
		  });
	
		  return group_info;
			};
	
	/***/ },
	/* 58 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var dendro_shade_bars = __webpack_require__(59);
	
		module.exports = function dendro_group_highlight(params, inst_selection, inst_data, inst_rc) {
	
		  // only make shadows if there is more than one crop button
		  if (d3.selectAll(params.root + ' .' + inst_rc + '_dendro_crop_buttons')[0].length > 1) {
		    setTimeout(still_hovering, 500);
		  } else {
		    d3.selectAll(params.root + ' .dendro_shadow').remove();
		  }
	
		  function still_hovering() {
	
		    // check that user is still hovering over dendrogram group
		    if (d3.select(inst_selection).classed('hovering')) {
	
		      // check that user is not using dendrogram slider
		      if (params.is_slider_drag === false) {
	
		        d3.select(inst_selection).style('opacity', 0.7);
	
		        if (d3.select(params.viz.viz_svg).classed('running_update') === false) {
		          make_shadow_bars();
		        }
		      }
		    }
		  }
	
		  function make_shadow_bars() {
	
		    if (inst_rc === 'row') {
	
		      // row and col labling are reversed
		      if (params.viz.inst_order.col === 'clust') {
		        dendro_shade_bars(params, inst_selection, inst_rc, inst_data);
		      }
		    } else if (inst_rc === 'col') {
	
		      // row and col labeling are reversed
		      if (params.viz.inst_order.row === 'clust') {
		        dendro_shade_bars(params, inst_selection, inst_rc, inst_data);
		      }
		    } else if (inst_rc === 'both') {
	
		      if (params.viz.inst_order.col === 'clust') {
		        dendro_shade_bars(params, inst_selection, 'row', inst_data);
		      }
		      if (params.viz.inst_order.row === 'clust') {
		        dendro_shade_bars(params, inst_selection, 'col', inst_data);
		      }
		    }
		  }
		};
	
	/***/ },
	/* 59 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function dendro_shade_bars(params, inst_selection, inst_rc, inst_data) {
	
		  var inst_opacity = 0.2;
		  var bot_height;
	
		  d3.selectAll(params.root + ' .dendro_shadow').remove();
	
		  if (inst_rc == 'row') {
	
		    // top shade
		    d3.select(params.root + ' .clust_group').append('rect').style('width', params.viz.clust.dim.width + 'px').style('height', inst_data.pos_top + 'px').style('fill', 'black').classed('dendro_shadow', true).style('opacity', inst_opacity);
	
		    bot_height = params.viz.clust.dim.height - inst_data.pos_bot;
		    // bottom shade
		    d3.select(params.root + ' .clust_group').append('rect').style('width', params.viz.clust.dim.width + 'px').style('height', bot_height + 'px').attr('transform', 'translate(0,' + inst_data.pos_bot + ')').style('fill', 'black').classed('dendro_shadow', true).style('opacity', inst_opacity);
		  } else if (inst_rc === 'col') {
	
		    // top shade
		    d3.select(params.root + ' .clust_group').append('rect').style('width', inst_data.pos_top + 'px').style('height', params.viz.clust.dim.height + 'px').style('fill', 'black').classed('dendro_shadow', true).style('opacity', inst_opacity);
	
		    // bottom shade
		    bot_height = params.viz.clust.dim.width - inst_data.pos_bot;
		    d3.select(params.root + ' .clust_group').append('rect').style('width', bot_height + 'px').style('height', params.viz.clust.dim.height + 'px').attr('transform', 'translate(' + inst_data.pos_bot + ',0)').style('fill', 'black').classed('dendro_shadow', true).style('opacity', inst_opacity);
		  }
			};
	
	/***/ },
	/* 60 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var calc_row_dendro_triangles = __webpack_require__(56);
		var calc_col_dendro_triangles = __webpack_require__(57);
		var d3_tip_custom = __webpack_require__(48);
		var dendro_group_highlight = __webpack_require__(58);
		var run_dendro_filter = __webpack_require__(61);
		var zoom_crop_triangles = __webpack_require__(62);
	
		module.exports = function make_dendro_crop_buttons(cgm, inst_rc) {
	
		  var params = cgm.params;
	
		  var button_opacity = params.viz.dendro_opacity * 0.60;
	
		  // information needed to make dendro
		  var dendro_info;
		  var other_rc;
		  if (inst_rc === 'row') {
		    dendro_info = calc_row_dendro_triangles(params);
		    other_rc = 'col';
		  } else {
		    dendro_info = calc_col_dendro_triangles(params);
		    other_rc = 'row';
		  }
	
		  // d3-tooltip
		  var tmp_y_offset = 5;
		  var tmp_x_offset = -5;
		  var dendro_crop_tip = d3_tip_custom().attr('class', function () {
		    var root_tip_selector = params.viz.root_tips.replace('.', '');
		    var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_' + inst_rc + '_dendro_crop_tip';
	
		    return class_string;
		  }).direction('nw').style('display', 'none').offset([tmp_y_offset, tmp_x_offset]);
	
		  var wait_before_tooltip = 500;
	
		  d3.selectAll(params.viz.root_tips + '_' + inst_rc + '_dendro_crop_tip').remove();
		  d3.selectAll(params.root + ' .' + inst_rc + '_dendro_crop_buttons').remove();
	
		  var icons;
		  // position triangles
		  var start_x;
		  var start_y;
		  var mid_x;
		  var mid_y;
		  var final_x;
		  var final_y;
	
		  // need to improve to account for zooming
		  var min_tri_height = 45;
		  var scale_down_tri = 0.25;
		  var tri_height;
		  var tri_width;
		  var tri_dim;
	
		  // make crop buttons or undo buttons
		  var button_class = inst_rc + '_dendro_crop_buttons';
		  if (d3.select(cgm.params.root + ' .' + inst_rc + '_dendro_icons_group').classed('ran_filter') === false) {
	
		    // Crop Triangle
		    //////////////////////////////
		    icons = d3.select(params.root + ' .' + inst_rc + '_dendro_icons_group').selectAll('path').data(dendro_info, function (d) {
		      return d.name;
		    }).enter().append('path').classed(button_class, true).attr('d', function (d) {
	
		      // redefine
		      tri_height = 10;
		      tri_width = 10;
	
		      var tmp_height = d.pos_bot - d.pos_top;
	
		      // Row Dendrogram Crop Triangle
		      if (inst_rc === 'row') {
	
		        if (tmp_height < min_tri_height) {
		          tri_height = tmp_height * scale_down_tri;
		        }
	
		        // pointing left
		        start_x = tri_width;
		        start_y = -tri_height;
		        mid_x = 0;
		        mid_y = 0;
		        final_x = tri_width;
		        final_y = tri_height;
	
		        tri_dim = tri_height;
	
		        // Column Dendrogram Crop Triangle
		      } else {
	
		        if (tmp_height < min_tri_height) {
		          tri_width = tmp_height * scale_down_tri;
		        }
	
		        // pointing upward
		        start_x = -tri_width;
		        start_y = tri_height;
		        mid_x = 0;
		        mid_y = 0;
		        final_x = tri_width;
		        final_y = tri_height;
	
		        tri_dim = tri_width;
		      }
	
		      // save triangle height
		      // d3.select(this)[0][0].__data__.tri_dim = tri_dim;
		      var data_key = '__data__';
		      d3.select(this)[0][0][data_key].tri_dim = tri_dim;
	
		      var output_string = 'M' + start_x + ',' + start_y + ', L' + mid_x + ', ' + mid_y + ', L' + final_x + ',' + final_y + ' Z';
	
		      return output_string;
		    });
	
		    dendro_crop_tip.html(function () {
		      var full_string = 'Click to crop cluster';
		      return full_string;
		    });
		  } else {
	
		    // Undo Triangle
		    //////////////////////////////
		    icons = d3.select(params.root + ' .' + inst_rc + '_dendro_icons_group').selectAll('path').data(dendro_info, function (d) {
		      return d.name;
		    }).enter().append('path').classed(button_class, true).attr('d', function (d) {
	
		      // redefine
		      tri_height = 10;
		      tri_width = 12;
	
		      var tmp_height = d.pos_bot - d.pos_top;
	
		      if (inst_rc === 'row') {
	
		        if (tmp_height < min_tri_height) {
		          tri_height = tmp_height * scale_down_tri;
		        }
	
		        // pointing right
		        start_x = 0;
		        start_y = -tri_height;
		        mid_x = tri_width;
		        mid_y = 0;
		        final_x = 0;
		        final_y = tri_height;
		      } else {
	
		        if (tmp_height < min_tri_height) {
		          tri_width = tmp_height * scale_down_tri;
		        }
	
		        // pointing downward
		        start_x = -tri_width;
		        start_y = 0;
		        mid_x = 0;
		        mid_y = tri_height;
		        final_x = tri_width;
		        final_y = 0;
		      }
	
		      // save triangle height
		      var data_key = '__data__';
		      d3.select(this)[0][0][data_key].tri_dim = 10;
	
		      var output_string = 'M' + start_x + ',' + start_y + ', L' + mid_x + ', ' + mid_y + ', L' + final_x + ',' + final_y + ' Z';
	
		      return output_string;
		    });
	
		    dendro_crop_tip.html(function () {
		      var full_string = 'Click to undo crop';
		      return full_string;
		    });
		  }
	
		  icons.style('cursor', 'pointer').style('opacity', function () {
	
		    var inst_opacity;
	
		    // if (d3.select(this).classed('hide_crop')){
		    //   inst_opacity = 0;
		    // } else {
		    //   inst_opacity = button_opacity;
		    // }
	
		    inst_opacity = button_opacity;
		    return inst_opacity;
		  }).attr('transform', function (d) {
		    var inst_translate;
	
		    var inst_x;
		    var inst_y;
	
		    if (inst_rc === 'row') {
		      inst_x = params.viz.uni_margin;
		      inst_y = d.pos_mid;
		    } else {
		      inst_x = d.pos_mid;
		      inst_y = params.viz.uni_margin;
		    }
	
		    inst_translate = 'translate(' + inst_x + ',' + inst_y + ')';
		    return inst_translate;
		  }).on('mouseover', function (d) {
	
		    d3.select(this).classed('hovering', true);
	
		    dendro_crop_tip.show(d);
	
		    dendro_group_highlight(params, this, d, inst_rc);
	
		    // display with zero opacity
		    d3.selectAll(params.viz.root_tips + '_' + inst_rc + '_dendro_crop_tip').style('opacity', 0).style('display', 'block');
	
		    // check if still hovering
		    setTimeout(still_hovering, wait_before_tooltip, this);
		  }).on('mouseout', function () {
	
		    d3.select(this).classed('hovering', false);
	
		    d3.selectAll(params.root + ' .dendro_shadow').remove();
	
		    d3.select(this).style('opacity', button_opacity);
	
		    dendro_crop_tip.hide(this);
		  }).on('click', function (d) {
	
		    // give user visual cue
		    d3.select(this).style('opacity', 0.9).transition().duration(1000).style('opacity', 0);
	
		    // remove dendro shadows when clicked
		    d3.selectAll(params.root + ' .dendro_shadow').remove();
	
		    /* filter using dendrogram */
		    if (cgm.params.dendro_filter.row === false && cgm.params.dendro_filter.col === false && cgm.params.cat_filter.row === false && cgm.params.cat_filter.col === false) {
	
		      // Run Filtering
		      ///////////////////
	
		      // use class as 'global' variable
		      d3.select(cgm.params.root + ' .' + inst_rc + '_dendro_icons_group').attr('transform', 'translate(0,0), scale(1,1)').classed('ran_filter', true);
	
		      d3.select(cgm.params.root + ' .' + other_rc + '_dendro_icons_group').attr('transform', 'translate(0,0), scale(1,1)');
	
		      // do not display dendrogram slider if filtering has been run
		      d3.select(cgm.params.root + ' .' + inst_rc + '_slider_group').style('display', 'none');
	
		      // do not display other crop buttons since they are inactive
		      d3.select(cgm.params.root + ' .' + other_rc + '_dendro_icons_container').style('display', 'none');
	
		      // do not display brush-crop button if performing dendro crop
		      d3.select(cgm.params.root + ' .crop_button').style('opacity', 0.2);
		    } else {
	
		      // Undo Filtering
		      ///////////////////
		      // use class as 'global' variable
		      d3.select(cgm.params.root + ' .' + inst_rc + '_dendro_icons_group').attr('transform', 'translate(0,0), scale(1,1)').classed('ran_filter', false);
	
		      d3.select(cgm.params.root + ' .' + other_rc + '_dendro_icons_group').attr('transform', 'translate(0,0), scale(1,1)');
	
		      if (params.viz.inst_order[other_rc] === 'clust') {
		        // display slider when cropping has not been done
		        d3.select(cgm.params.root + ' .' + inst_rc + '_slider_group').style('display', 'block');
		      }
	
		      // display other crop buttons when cropping has not been done
		      d3.select(cgm.params.root + ' .' + other_rc + '_dendro_icons_container').style('display', 'block');
	
		      // display brush-crop button if not performing dendro crop
		      d3.select(cgm.params.root + ' .crop_button').style('opacity', 1);
		    }
	
		    run_dendro_filter(cgm, d, inst_rc);
		  }).call(dendro_crop_tip);
	
		  // ordering has been reversed
		  if (params.viz.inst_order[other_rc] != 'clust') {
		    // do not display if not in cluster order
		    d3.select(params.root + ' .' + inst_rc + '_dendro_icons_group').selectAll('path').style('display', 'none');
		  }
	
		  function still_hovering(inst_selection) {
	
		    if (d3.select(inst_selection).classed('hovering')) {
		      // increase opacity
		      d3.selectAll(params.viz.root_tips + '_' + inst_rc + '_dendro_crop_tip').style('opacity', 1).style('display', 'block');
		    }
		  }
	
		  zoom_crop_triangles(params, params.zoom_info, inst_rc);
			};
	
	/***/ },
	/* 61 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function run_dendro_filter(cgm, d, inst_rc) {
	
		  var names = {};
	
		  if (cgm.params.dendro_filter.row === false && cgm.params.dendro_filter.col === false && cgm.params.cat_filter.row === false && cgm.params.cat_filter.col === false) {
	
		    d3.select(cgm.params.root + ' .' + inst_rc + '_slider_group').style('opacity', 0.35).style('pointer-events', 'none');
	
		    names[inst_rc] = d.all_names;
	
		    var tmp_names = cgm.params.network_data[inst_rc + '_nodes_names'];
	
		    // keep a backup of the inst_view
		    var inst_row_nodes = cgm.params.network_data.row_nodes;
		    var inst_col_nodes = cgm.params.network_data.col_nodes;
	
		    cgm.filter_viz_using_names(names);
	
		    // overwrite with backup of original nodes
		    cgm.params.inst_nodes.row_nodes = inst_row_nodes;
		    cgm.params.inst_nodes.col_nodes = inst_col_nodes;
	
		    d3.selectAll(cgm.params.root + ' .dendro_shadow').transition().duration(1000).style('opacity', 0).remove();
	
		    // keep the names of all the nodes
		    cgm.params.dendro_filter[inst_rc] = tmp_names;
	
		    /* reset filter */
		  } else {
	
		    names[inst_rc] = cgm.params.dendro_filter[inst_rc];
	
		    cgm.filter_viz_using_names(names);
		    cgm.params.dendro_filter[inst_rc] = false;
		  }
			};
	
	/***/ },
	/* 62 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function zoom_crop_triangles(params, zoom_info, inst_rc) {
	
		  if (inst_rc === 'row') {
	
		    // transform icons (undo zoom on triangles)
		    d3.select(params.root + ' .row_dendro_icons_group').selectAll('path').attr('transform', function (d) {
		      var inst_x = params.viz.uni_margin;
		      var inst_y = d.pos_mid;
		      var curr_zoom = zoom_info.zoom_y;
		      var tri_dim = d3.select(this).data()[0].tri_dim;
		      var inst_zoom = constrain_zoom(curr_zoom, tri_dim);
		      return 'translate(' + inst_x + ',' + inst_y + ') ' + 'scale(1, ' + 1 / inst_zoom + ')';
		    });
		  } else {
	
		    // transform icons (undo zoom on triangles)
		    d3.select(params.root + ' .col_dendro_icons_group').selectAll('path').attr('transform', function (d) {
		      var inst_x = d.pos_mid;
		      var inst_y = params.viz.uni_margin;
		      var curr_zoom = zoom_info.zoom_x;
		      var tri_dim = d3.select(this).data()[0].tri_dim;
		      var inst_zoom = constrain_zoom(curr_zoom, tri_dim);
		      return 'translate(' + inst_x + ',' + inst_y + ') ' + 'scale(' + 1 / inst_zoom + ', 1)';
		    });
		  }
	
		  function constrain_zoom(curr_zoom, tri_height) {
		    var inst_zoom;
		    var default_tri_height = 10;
		    if (tri_height * curr_zoom < default_tri_height) {
		      inst_zoom = 1;
		    } else {
		      var max_zoom = default_tri_height / tri_height;
		      inst_zoom = curr_zoom / max_zoom;
		    }
		    return inst_zoom;
		  }
			};
	
	/***/ },
	/* 63 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var calc_cat_cluster_breakdown = __webpack_require__(64);
	
		module.exports = function make_cat_breakdown_graph(params, inst_rc, inst_data, dendro_info, selector) {
		  var tooltip = arguments.length <= 5 || arguments[5] === undefined ? false : arguments[5];
	
	
		  // in case sim_mat
		  if (inst_rc === 'both') {
		    inst_rc = 'row';
		  }
	
		  var cat_breakdown = calc_cat_cluster_breakdown(params, inst_data, inst_rc);
	
		  if (cat_breakdown.length > 0) {
	
		    // put cluster information in dendro_tip
		    ///////////////////////////////////////////
		    var cluster_info_container = d3.select(selector + ' .cluster_info_container');
	
		    // loop through cat_breakdown data
		    var super_string = ': ';
		    var paragraph_string = '<p>';
		    var width = 225;
		    var bar_offset = 23;
		    var bar_height = 20;
		    var max_string_length = 15;
		    var bar_width = 135;
		    var title_height = 27;
	
		    // limit on the number of category types shown
		    var max_cats = 3;
		    // limit the number of bars shown
		    var max_bars = 20;
	
		    // calculate height needed for svg based don cat_breakdown data
		    var svg_height = 20;
		    _.each(cat_breakdown.slice(0, max_cats), function (tmp_break) {
		      var num_bars = tmp_break.bar_data.length;
		      if (num_bars > max_bars) {
		        num_bars = max_bars;
		      }
		      svg_height = svg_height + title_height * (num_bars + 1);
		    });
	
		    // Cluster Information Title (for tooltip only not modal)
		    if (tooltip) {
		      cluster_info_container.append('text').text('Cluster Information');
		    }
	
		    var main_dendro_svg = cluster_info_container.append('div').style('margin-top', '5px').classed('cat_graph', true).append('svg').style('height', svg_height + 'px').style('width', width + 'px');
	
		    // make background
		    main_dendro_svg.append('rect').classed('cat_background', true).style('height', svg_height + 'px').style('width', width + 'px').style('fill', 'white').style('opacity', 1);
	
		    // the total amout to shift down the next category
		    var shift_down = title_height;
	
		    // limit the category-types
		    cat_breakdown = cat_breakdown.slice(0, max_cats);
	
		    _.each(cat_breakdown, function (cat_data) {
	
		      // only keep the top 5 categories
		      cat_data.bar_data = cat_data.bar_data.slice(0, max_bars);
	
		      cluster_info_container.style('margin-bottom', '5px');
	
		      var cat_graph_group = main_dendro_svg.append('g').classed('cat_graph_group', true).attr('transform', 'translate(10, ' + shift_down + ')');
	
		      // shift down based on number of bars
		      shift_down = shift_down + title_height * (cat_data.bar_data.length + 1);
	
		      var inst_title = cat_data.type_name;
		      // ensure that title is not too long
		      if (inst_title.length >= max_string_length) {
		        inst_title = inst_title.slice(0, max_string_length) + '..';
		      }
	
		      // make title
		      cat_graph_group.append('text').classed('cat_graph_title', true).text(inst_title).style('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').style('font-weight', 800);
	
		      var count_offset = 15;
		      // make P-value title
		      cat_graph_group.append('text').text('Count').attr('transform', function () {
		        var inst_x = bar_width + count_offset;
		        var inst_translate = 'translate(' + inst_x + ', 0)';
		        return inst_translate;
		      });
	
		      var line_y = 4;
		      cat_graph_group.append('line').attr('x1', 0).attr('x2', bar_width).attr('y1', line_y).attr('y2', line_y).style('stroke', 'blue').style('stroke-width', 1).style('opacity', 1.0);
	
		      var cat_bar_container = cat_graph_group.append('g').classed('cat_bar_container', true).attr('transform', 'translate(0, 10)');
	
		      // make bar groups (hold bar and text)
		      var cat_bar_groups = cat_bar_container.selectAll('g').data(cat_data.bar_data).enter().append('g').attr('transform', function (d, i) {
		        var inst_y = i * bar_offset;
		        return 'translate(0,' + inst_y + ')';
		      });
	
		      var bar_scale = d3.scale.linear()
		      // bar length is max when all nodes in cluster are of
		      // a single cat
		      // .domain([0, cat_data.num_in_clust])
		      // bar length is max based on the max number in one cat
		      .domain([0, cat_data.bar_data[0][2]]).range([0, bar_width]);
	
		      // make bars
		      cat_bar_groups.append('rect').style('height', bar_height + 'px').style('width', function (d) {
		        var inst_width = bar_scale(d[2]);
		        return inst_width + 'px';
		      }).style('fill', function (d) {
		        // cat color is stored in the third element
		        return d[3];
		      }).style('opacity', params.viz.cat_colors.opacity).style('stroke', 'grey').style('stroke-width', '0.5px');
	
		      // make bar labels
		      cat_bar_groups.append('text').classed('bar_labels', true).text(function (d) {
		        var inst_text = d[1];
		        if (inst_text.indexOf(super_string) > 0) {
		          inst_text = inst_text.split(super_string)[1];
		        }
		        if (inst_text.indexOf(paragraph_string) > 0) {
		          // required for Enrichr category names (needs improvements)
		          inst_text = inst_text.split(paragraph_string)[0];
		        }
		        // ensure that bar name is not too long
		        if (inst_text.length >= max_string_length) {
		          inst_text = inst_text.slice(0, max_string_length) + '..';
		        }
		        return inst_text;
		      }).attr('transform', function () {
		        return 'translate(5, ' + 0.75 * bar_height + ')';
		      }).style('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').style('font-weight', 400);
	
		      // make bar labels
		      var shift_count_num = 25;
		      cat_bar_groups.append('text').classed('count_labels', true).text(function (d) {
		        return String(d[4]);
		      }).attr('transform', function () {
		        var inst_x = bar_width + count_offset + shift_count_num;
		        var inst_y = 0.75 * bar_height;
		        return 'translate(' + inst_x + ', ' + inst_y + ')';
		      }).style('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').style('font-weight', 400).style('text-anchor', 'end');
		    });
	
		    // reposition tooltip
		    /////////////////////////////////////////////////
		    if (tooltip) {
	
		      var dendro_tip = d3.select(selector);
		      var old_top = dendro_tip.style('top').split('.px')[0];
		      var old_left = dendro_tip.style('left').split('.px')[0];
		      var shift_top = 0;
		      var shift_left = 0;
	
		      // shifting
		      if (inst_rc === 'row') {
	
		        // rows
		        //////////////
		        shift_top = svg_height + 30;
		        shift_left = 32;
	
		        // prevent graph from being too high
		        if (dendro_info.pos_top < svg_height) {
		          shift_top = -(svg_height + (dendro_info.pos_mid - dendro_info.pos_top) / 2);
		        }
		      } else {
	
		        // columns
		        //////////////
		        shift_top = svg_height + 32;
		        shift_left = 30;
		      }
	
		      dendro_tip.style('top', function () {
		        var new_top = String(parseInt(old_top, 10) - shift_top) + 'px';
		        return new_top;
		      }).style('left', function () {
		        var new_left = String(parseInt(old_left, 10) - shift_left) + 'px';
		        return new_left;
		      });
		    }
		  }
			};
	
	/***/ },
	/* 64 */
	/***/ function(module, exports) {
	
		'use strict';
	
		// var run_fisher_exact_clust = require('./run_fisher_exact_clust');
	
		module.exports = function calc_cat_cluster_breakdown(params, inst_data, inst_rc) {
		  // Category-breakdown of dendrogram-clusters
		  /////////////////////////////////////////////
		  /*
		   1. get information for nodes in cluster
		  2. find category-types that are string-type
		  3. count instances of each category name for each category-type
		   */
	
		  // in case sim_mat
		  if (inst_rc === 'both') {
		    inst_rc = 'row';
		  }
	
		  // 1: get information for nodes in cluster
		  ///////////////////////////////////////////
	
		  // names of nodes in cluster
		  var clust_names = inst_data.all_names;
		  // array of nodes in the cluster
		  var clust_nodes = [];
		  var all_nodes = params.network_data[inst_rc + '_nodes'];
	
		  // // n: number drawn in cluster
		  // var n = clust_names.length;
		  // // big_n: total number of nodes
		  // var big_n = all_nodes.length;
	
		  var inst_name;
		  _.each(all_nodes, function (inst_node) {
	
		    inst_name = inst_node.name;
	
		    if (clust_names.indexOf(inst_name) >= 0) {
		      clust_nodes.push(inst_node);
		    }
		  });
	
		  // 2: find category-types that are string-type
		  ///////////////////////////////////////////////
	
		  var cat_breakdown = [];
	
		  if (params.viz.cat_info[inst_rc] !== null) {
	
		    var inst_cat_info = params.viz.cat_info[inst_rc];
	
		    // tmp list of all categories
		    var tmp_types_index = _.keys(inst_cat_info);
		    // this will hold the indexes of string-type categories
		    var cat_types_index = [];
	
		    // var inst_node = params.network_data[inst_rc+'_nodes'][0];
	
		    // get category names (only include string-type categories)
		    var cat_types_names = [];
		    var type_name;
		    var inst_index;
		    var cat_index;
		    for (var i = 0; i < tmp_types_index.length; i++) {
	
		      cat_index = 'cat-' + String(i);
	
		      if (params.viz.cat_info[inst_rc][cat_index].type === 'cat_strings') {
		        type_name = params.viz.cat_names[inst_rc][cat_index];
		        cat_types_names.push(type_name);
		        cat_types_index.push(cat_index);
		      }
		    }
	
		    var tmp_run_count = {};
		    var inst_breakdown = {};
		    var bar_data;
		    var fraction_index = 2;
		    var radix_param = 10;
	
		    var no_title_given;
		    if (type_name === cat_index) {
		      no_title_given = true;
		    } else {
		      no_title_given = false;
		    }
	
		    if (cat_types_names.length > 0) {
	
		      // 3: count instances of each category name for each category-type
		      var cat_name;
		      var num_in_clust = clust_names.length;
		      _.each(cat_types_index, function (cat_index) {
	
		        inst_index = cat_index.split('-')[1];
		        type_name = cat_types_names[inst_index];
	
		        if (no_title_given) {
		          if (cat_index.indexOf('-') >= 0) {
		            var tmp_num = parseInt(cat_index.split('-')[1], radix_param) + 1;
		            type_name = 'Category ' + String(tmp_num);
		          } else {
		            // backup behavior
		            type_name = 'Category';
		          }
		        }
	
		        tmp_run_count[type_name] = {};
	
		        // loop throught nodes and keep running count of categories
		        _.each(clust_nodes, function (tmp_node) {
	
		          cat_name = tmp_node[cat_index];
	
		          if (cat_name.indexOf(': ') >= 0) {
		            cat_name = cat_name.split(': ')[1];
		          }
	
		          if (cat_name in tmp_run_count[type_name]) {
		            tmp_run_count[type_name][cat_name] = tmp_run_count[type_name][cat_name] + 1; // /num_in_clust;
		          } else {
		            tmp_run_count[type_name][cat_name] = 1; // /num_in_clust;
		          }
		        });
	
		        inst_breakdown = {};
		        inst_breakdown.type_name = type_name;
		        inst_breakdown.num_in_clust = num_in_clust;
	
		        // sort cat info in cat_breakdown
		        bar_data = [];
		        var bar_color;
		        var cat_title_and_name;
		        var inst_run_count = tmp_run_count[type_name];
	
		        for (var inst_cat in inst_run_count) {
	
		          // if no cat-title given
		          if (no_title_given) {
		            cat_title_and_name = inst_cat;
		          } else {
		            cat_title_and_name = type_name + ': ' + inst_cat;
		          }
	
		          // k: number of cat-nodes drawn in cluster
		          // var k = parseInt(inst_run_count[inst_cat] * n, 10);
		          var k = inst_run_count[inst_cat];
	
		          // // big_k: total number of cat-nodes
		          // var big_k = params.viz.cat_info[inst_rc][cat_index].cat_hist[cat_title_and_name];
	
		          // var ft = parseFloat(run_fisher_exact_clust(k, n, big_k, big_n));
	
		          bar_color = params.viz.cat_colors[inst_rc][cat_index][cat_title_and_name];
	
		          bar_data.push([cat_index, cat_title_and_name, inst_run_count[inst_cat], bar_color, k]);
		        }
	
		        bar_data.sort(function (a, b) {
		          return b[fraction_index] - a[fraction_index];
		        });
	
		        inst_breakdown.bar_data = bar_data;
	
		        cat_breakdown.push(inst_breakdown);
		      });
		    }
		  }
	
		  return cat_breakdown;
		};
	
	/***/ },
	/* 65 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function get_previous_zoom(params) {
		  var prev_zoom = {};
	
		  var inst_trans = d3.select(params.root + ' .clust_group').attr('transform');
	
		  if (inst_trans != null) {
	
		    // prevent from crashing if no scaling was done
		    if (inst_trans.indexOf('scale') > 0) {
		      prev_zoom.zoom_x = parseFloat(inst_trans.split('scale')[1].replace('(', '').replace(')', '').split(',')[0]);
	
		      prev_zoom.zoom_y = parseFloat(inst_trans.split('scale')[1].replace('(', '').replace(')', '').split(',')[1]);
		    } else {
		      prev_zoom.zoom_x = 1;
		      prev_zoom.zoom_y = 1;
		    }
		  } else {
		    prev_zoom.zoom_x = 1;
		    prev_zoom.zoom_y = 1;
		  }
	
		  return prev_zoom;
			};
	
	/***/ },
	/* 66 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var d3_tip_custom = __webpack_require__(48);
	
		module.exports = function make_row_tooltips(params) {
	
		  if (params.labels.show_label_tooltips) {
	
		    // remove old tooltips
		    d3.selectAll(params.viz.root_tips + '_row_tip').remove();
	
		    var root_tip_selector = params.viz.root_tips.replace('.', '');
	
		    // d3-tooltip
		    var row_tip = d3_tip_custom().attr('class', function () {
		      var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_row_tip';
		      return class_string;
		    }).direction('e').offset([0, 10]).style('display', 'none').html(function (d) {
		      var inst_name = d.name.replace(/_/g, ' ').split('#')[0];
		      return "<span>" + inst_name + "</span>";
		    });
	
		    d3.select(params.viz.viz_wrapper).select(params.root + ' .row_container').call(row_tip);
	
		    d3.select(params.root + ' .row_label_zoom_container').selectAll('g').on('mouseover', function (d) {
	
		      d3.select(params.viz.root_tips + '_row_tip').classed(d.name, true);
	
		      d3.selectAll(params.viz.root_tips + '_row_tip').style('display', 'block');
	
		      d3.select(this).select('text').classed('active', true);
	
		      row_tip.show(d);
	
		      if (params.row_tip_callback != null) {
		        params.row_tip_callback(params.viz.root_tips, d);
		      }
		    }).on('mouseout', function mouseout(d) {
	
		      d3.selectAll(params.viz.root_tips + '_row_tip').style('display', 'none').classed(d.name, false);
	
		      d3.select(this).select('text').classed('active', false);
	
		      row_tip.hide(d);
		    });
		  } else {
	
		    d3.select(params.root + ' .row_label_zoom_container').selectAll('g').on('mouseover', function () {
		      d3.select(this).select('text').classed('active', true);
		    }).on('mouseout', function mouseout() {
		      d3.select(this).select('text').classed('active', false);
		    });
		  }
			};
	
	/***/ },
	/* 67 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var utils = __webpack_require__(2);
		var add_col_click_hlight = __webpack_require__(68);
		var col_reorder = __webpack_require__(69);
		var row_reorder = __webpack_require__(52);
		var make_col_tooltips = __webpack_require__(73);
		var col_viz_aid_triangle = __webpack_require__(74);
	
		module.exports = function make_col_label_container(cgm) {
		  var text_delay = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];
	
	
		  var params = cgm.params;
		  var col_container;
	
		  var col_nodes = params.network_data.col_nodes;
	
		  // offset click group column label
		  var x_offset_click = params.viz.x_scale.rangeBand() / 2 + params.viz.border_width.x;
		  // reduce width of rotated rects
	
	
		  // make container to pre-position zoomable elements
		  if (d3.select(params.root + ' .col_container').empty()) {
	
		    col_container = d3.select(params.viz.viz_svg).append('g').attr('class', 'col_container').attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.norm_labels.margin.top + ')');
	
		    // white background rect for col labels
		    col_container.append('rect').attr('fill', params.viz.background_color) //!! prog_colors
		    .attr('width', 30 * params.viz.clust.dim.width + 'px').attr('height', params.viz.label_background.col).attr('class', 'white_bars');
	
		    // col labels
		    col_container.append('g').attr('class', 'col_label_outer_container')
		    // position the outer col label group
		    .attr('transform', 'translate(0,' + params.viz.norm_labels.width.col + ')').append('g').attr('class', 'col_zoom_container');
		  } else {
	
		    col_container = d3.select(params.root + ' .col_container').attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.norm_labels.margin.top + ')');
	
		    // white background rect for col labels
		    col_container.select('.white_bars').attr('fill', params.viz.background_color) //!! prog_colors
		    .attr('width', 30 * params.viz.clust.dim.width + 'px').attr('height', params.viz.label_background.col);
	
		    // col labels
		    col_container.select(params.root + ' .col_label_outer_container');
		  }
	
		  // add main column label group
		  var col_label_obj = d3.select(params.root + ' .col_zoom_container').selectAll('.col_label_text').data(col_nodes, function (d) {
		    return d.name;
		  }).enter().append('g').attr('class', 'col_label_text').attr('transform', function (d) {
		    var inst_index = d.col_index;
		    return 'translate(' + params.viz.x_scale(inst_index) + ', 0) rotate(-90)';
		  });
	
		  // append group for individual column label
		  var col_label_group = col_label_obj
		  // append new group for rect and label (not white lines)
		  .append('g').attr('class', 'col_label_group')
		  // rotate column labels
		  .attr('transform', 'translate(' + params.viz.x_scale.rangeBand() / 2 + ',' + x_offset_click + ') rotate(45)').on('mouseover', function () {
		    d3.select(this).select('text').classed('active', true);
		  }).on('mouseout', function () {
		    d3.select(this).select('text').classed('active', false);
		  });
	
		  // append column value bars
		  if (utils.has(params.network_data.col_nodes[0], 'value')) {
	
		    col_label_group.append('rect').attr('class', 'col_bars').attr('width', function (d) {
		      var inst_value = 0;
		      if (d.value > 0) {
		        inst_value = params.labels.bar_scale_col(d.value);
		      }
		      return inst_value;
		    })
		    // rotate labels - reduce width if rotating
		    .attr('height', params.viz.x_scale.rangeBand() * 0.66).style('fill', function (d) {
		      return d.value > 0 ? params.matrix.bar_colors[0] : params.matrix.bar_colors[1];
		    }).attr('opacity', 0.6);
		  }
	
		  // add column label
		  col_label_group.append('text').attr('x', 0)
		  // manually tuned
		  .attr('y', params.viz.x_scale.rangeBand() * 0.64).attr('dx', params.viz.border_width.x).attr('text-anchor', 'start').attr('full_name', function (d) {
		    return d.name;
		  })
		  // original font size
		  .style('font-size', params.labels.default_fs_col + 'px').style('cursor', 'default').text(function (d) {
		    return utils.normal_name(d);
		  })
		  // .attr('pointer-events','none')
		  .style('opacity', 0).transition().delay(text_delay).duration(text_delay).style('opacity', 1);
	
		  make_col_tooltips(params);
	
		  // add triangle under rotated labels
		  col_label_group.append('path').style('stroke-width', 0).attr('d', function () {
		    return col_viz_aid_triangle(params);
		  }).attr('fill', '#eee').style('opacity', 0).transition().delay(text_delay).duration(text_delay).style('opacity', params.viz.triangle_opacity);
	
		  // add col callback function
		  d3.selectAll(params.root + ' .col_label_text').on('click', function (d) {
	
		    if (typeof params.click_label == 'function') {
		      params.click_label(d.name, 'col');
		      add_col_click_hlight(params, this, d.ini);
		    } else {
	
		      if (params.tile_click_hlight) {
		        add_col_click_hlight(params, this, d.ini);
		      }
		    }
		  }).on('dblclick', function (d) {
	
		    var data_attr = '__data__';
		    var col_name = this[data_attr].name;
	
		    if (params.sim_mat) {
		      col_reorder(cgm, this, col_name);
	
		      var row_selection = d3.selectAll(params.root + ' .row_label_group').filter(function (d) {
		        return d.name == col_name;
		      })[0][0];
	
		      row_reorder(cgm, row_selection, col_name);
		    } else {
		      col_reorder(cgm, this, col_name);
		    }
	
		    if (params.tile_click_hlight) {
		      add_col_click_hlight(params, this, d.ini);
		    }
		  });
			};
	
	/***/ },
	/* 68 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function (params, clicked_col, id_clicked_col) {
	
		  if (id_clicked_col != params.click_hlight_col) {
	
		    params.click_hlight_col = id_clicked_col;
	
		    var rel_width_hlight = 6;
		    var opacity_hlight = 0.85;
		    var hlight_width = rel_width_hlight * params.viz.border_width.x;
	
		    d3.selectAll(params.root + ' .click_hlight').remove();
	
		    // // highlight selected column
		    // ///////////////////////////////
		    // // unhilight and unbold all columns (already unbolded earlier)
		    // d3.selectAll('.col_label_text')
		    //   .select('rect')
		    //   .style('opacity', 0);
		    // // highlight column name
		    // d3.select(clicked_col)
		    //   .select('rect')
		    //   .style('opacity', 1);
	
		    d3.select(clicked_col).append('rect').classed('click_hlight', true).classed('col_top_hlight', true).attr('width', params.viz.clust.dim.height).attr('height', hlight_width).attr('fill', params.matrix.hlight_color).attr('opacity', opacity_hlight).attr('transform', function () {
		      var tmp_translate_y = 0;
		      var tmp_translate_x = -(params.viz.clust.dim.height + params.viz.cat_room.col + params.viz.uni_margin);
		      return 'translate(' + tmp_translate_x + ',' + tmp_translate_y + ')';
		    });
	
		    d3.select(clicked_col).append('rect').classed('click_hlight', true).classed('col_bottom_hlight', true).attr('width', params.viz.clust.dim.height).attr('height', hlight_width).attr('fill', params.matrix.hlight_color).attr('opacity', opacity_hlight).attr('transform', function () {
		      // reverse x and y since rotated
		      var tmp_translate_y = params.viz.x_scale.rangeBand() - hlight_width;
		      var tmp_translate_x = -(params.viz.clust.dim.height + params.viz.cat_room.col + params.viz.uni_margin);
		      return 'translate(' + tmp_translate_x + ',' + tmp_translate_y + ')';
		    });
		  } else {
		    d3.selectAll(params.root + ' .click_hlight').remove();
		    params.click_hlight_col = -666;
		  }
			};
	
	/***/ },
	/* 69 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		// var utils = require('../Utils_clust');
		var reposition_tile_highlight = __webpack_require__(53);
		var toggle_dendro_view = __webpack_require__(54);
		var show_visible_area = __webpack_require__(70);
		var ini_zoom_info = __webpack_require__(36);
		var get_previous_zoom = __webpack_require__(65);
		var calc_downsampled_levels = __webpack_require__(27);
	
		module.exports = function col_reorder(cgm, col_selection, inst_term) {
	
		  var params = cgm.params;
		  var prev_zoom = get_previous_zoom(params);
	
		  if (prev_zoom.zoom_y === 1 && prev_zoom.zoom_x === 1) {
	
		    params.viz.inst_order.col = 'custom';
	
		    toggle_dendro_view(cgm, 'col');
	
		    d3.selectAll(params.root + ' .toggle_row_order .btn').classed('active', false);
	
		    params.viz.run_trans = true;
	
		    var mat = $.extend(true, {}, params.matrix.matrix);
		    var row_nodes = params.network_data.row_nodes;
		    var col_nodes = params.network_data.col_nodes;
	
		    // find the column number of col_selection term from col_nodes
		    // gather column node names
		    var tmp_arr = [];
		    col_nodes.forEach(function (node) {
		      tmp_arr.push(node.name);
		    });
	
		    // find index
		    var inst_col = _.indexOf(tmp_arr, inst_term);
	
		    // gather the values of the input genes
		    tmp_arr = [];
		    row_nodes.forEach(function (node, index) {
		      tmp_arr.push(mat[index].row_data[inst_col].value);
		    });
	
		    // sort the cols
		    var tmp_sort = d3.range(tmp_arr.length).sort(function (a, b) {
		      return tmp_arr[b] - tmp_arr[a];
		    });
	
		    // resort rows (rows are reorderd by double clicking a col)
		    params.viz.y_scale.domain(tmp_sort);
	
		    // save to custom row order
		    params.matrix.orders.custom_col = tmp_sort;
	
		    var t;
	
		    var row_nodes_names = params.network_data.row_nodes_names;
	
		    // reorder
		    if (params.network_data.links.length > params.matrix.def_large_matrix) {
		      t = d3.select(params.root + ' .viz_svg');
		    } else {
		      t = d3.select(params.root + ' .viz_svg').transition().duration(2500);
		    }
	
		    // reorder row_label_triangle groups
		    t.selectAll('.row_cat_group').attr('transform', function (d) {
		      var inst_index = _.indexOf(row_nodes_names, d.name);
		      return 'translate(0,' + params.viz.y_scale(inst_index) + ')';
		    });
	
		    // Move Row Labels
		    t.select('.row_label_zoom_container').selectAll('.row_label_group').attr('transform', function (d) {
		      var inst_index = _.indexOf(row_nodes_names, d.name);
		      return 'translate(0,' + params.viz.y_scale(inst_index) + ')';
		    });
	
		    // only update matri if not downsampled
		    if (params.viz.ds_level === -1) {
		      // reorder matrix rows
		      t.selectAll('.row').attr('transform', function (d) {
		        var inst_index = _.indexOf(row_nodes_names, d.name);
		        return 'translate(0,' + params.viz.y_scale(inst_index) + ')';
		      });
		    }
	
		    // highlight selected column
		    ///////////////////////////////
		    // unhilight and unbold all columns (already unbolded earlier)
		    d3.selectAll(params.root + ' .col_label_text').select('.highlight_rect').style('opacity', 0);
		    // highlight column name
		    d3.select(col_selection).select('.highlight_rect').style('opacity', 1);
	
		    // redefine x and y positions
		    params.network_data.links.forEach(function (d) {
		      d.x = params.viz.x_scale(d.target);
		      d.y = params.viz.y_scale(d.source);
		    });
	
		    reposition_tile_highlight(params);
	
		    params.zoom_info = ini_zoom_info();
	
		    setTimeout(function () {
		      params.viz.run_trans = false;
		    }, 2500);
	
		    // calculate downsmapling if necessary
		    if (params.viz.ds_num_levels > 0 && params.viz.ds_level >= 0) {
	
		      calc_downsampled_levels(params);
	
		      var zooming_stopped = true;
		      var zooming_out = true;
		      var make_all_rows = true;
		      // show_visible_area is also run with two_translate_zoom, but at that point
		      // the parameters were not updated and two_translate_zoom if only run
		      // if needed to reset zoom
		      show_visible_area(cgm, zooming_stopped, zooming_out, make_all_rows);
		    }
		  }
			};
	
	/***/ },
	/* 70 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var find_viz_rows = __webpack_require__(71);
		var make_matrix_rows = __webpack_require__(41);
		var make_row_labels = __webpack_require__(50);
		var make_row_visual_aid_triangles = __webpack_require__(72);
	
		module.exports = function show_visible_area(cgm) {
		  var zooming_stopped = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
		  var zooming_out = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];
		  var make_all_rows = arguments.length <= 3 || arguments[3] === undefined ? false : arguments[3];
	
	
		  // console.log('show_visible_area stopped: ' + String(zooming_stopped));
	
		  var params = cgm.params;
		  var zoom_info = params.zoom_info;
	
		  // update ds_level if necessary
		  //////////////////////////////////////////////
		  var check_ds_level = params.viz.ds_level;
		  var old_ds_level = params.viz.ds_level;
	
		  // toggle the downsampling level (if necessary)
		  if (params.viz.ds === null) {
		    check_ds_level = -1;
		  } else {
	
		    check_ds_level = Math.floor(Math.log(zoom_info.zoom_y) / Math.log(params.viz.ds_zt));
	
		    if (check_ds_level > params.viz.ds_num_levels - 1) {
		      check_ds_level = -1;
		    }
		  }
	
		  // check if override_ds is necessary
		  //////////////////////////////////////////////
		  // force update of view if moving to more coarse view
		  var override_ds = false;
	
		  if (old_ds_level == -1) {
		    // transitioning to more coarse downsampling view (from real data)
		    if (check_ds_level >= 0) {
		      override_ds = true;
		    }
		  } else {
		    // transitioning to more coarse downsampling view
		    if (check_ds_level < old_ds_level) {
		      override_ds = true;
		    }
		  }
	
		  // update level if zooming has stopped or if transitioning to more coarse view
		  var new_ds_level;
	
		  if (zooming_stopped === true || override_ds === true) {
	
		    // update new_ds_level if necessary (if decreasing detail, zooming out)
		    new_ds_level = check_ds_level;
	
		    // set zooming_stopped to true in case of override_ds
		    zooming_stopped = true;
	
		    params.viz.ds_level = new_ds_level;
		  } else {
		    // keep the old level (zooming is still occuring and not zooming out)
		    new_ds_level = old_ds_level;
		  }
	
		  var viz_area = {};
		  var buffer_size = 5;
		  // get translation vector absolute values
		  viz_area.min_x = Math.abs(zoom_info.trans_x) / zoom_info.zoom_x - (buffer_size + 1) * params.viz.rect_width;
		  viz_area.min_y = Math.abs(zoom_info.trans_y) / zoom_info.zoom_y - (buffer_size + 1) * params.viz.rect_height;
	
		  viz_area.max_x = Math.abs(zoom_info.trans_x) / zoom_info.zoom_x + params.viz.clust.dim.width / zoom_info.zoom_x + buffer_size * params.viz.rect_width;
	
		  viz_area.max_y = Math.abs(zoom_info.trans_y) / zoom_info.zoom_y + params.viz.clust.dim.height / zoom_info.zoom_y + buffer_size * params.viz.rect_height;
	
		  // generate lists of visible rows/cols
		  find_viz_rows(params, viz_area);
	
		  var missing_rows;
		  if (make_all_rows === false) {
		    missing_rows = _.difference(params.viz.viz_nodes.row, params.viz.viz_nodes.curr_row);
		  } else {
		    // make all rows (reordering)
		    missing_rows = 'all';
	
		    // remove downsampled rows
		    d3.selectAll(params.root + ' .ds' + String(new_ds_level) + '_row').remove();
		  }
	
		  if (params.viz.ds != null) {
		    var ds_row_class = '.ds' + String(params.viz.ds_level) + '_row';
		    d3.selectAll(ds_row_class).style('display', 'block');
		  }
	
		  // if downsampling
		  if (new_ds_level >= 0) {
		    // remove old rows
		    d3.selectAll(params.root + ' .row').remove();
		    // remove tile tooltips and row tooltips
		    d3.selectAll(params.viz.root_tips + '_tile_tip').remove();
		    d3.selectAll(params.viz.root_tips + '_row_tip').remove();
		  }
	
		  // default state for downsampling
		  var inst_matrix;
	
		  if (new_ds_level < 0) {
		    // set matrix to default matrix
		    inst_matrix = params.matrix.matrix;
	
		    // make row visual-aid triangles
		    make_row_visual_aid_triangles(params);
		  } else {
		    // set matrix to downsampled matrix
		    inst_matrix = params.matrix.ds_matrix[new_ds_level];
	
		    d3.selectAll(params.root + ' .row_cat_group path').remove();
		  }
	
		  // also remove row visual aid triangles if zooming out
		  if (zooming_out === true) {
		    d3.selectAll(params.root + ' .row_cat_group path').remove();
		  }
	
		  // remove rows and labels that are not visible and change ds_level
		  /* run when zooming has stopped */
		  if (zooming_stopped === true) {
	
		    // remove not visible matrix rows
		    if (new_ds_level >= 0) {
	
		      // remove downsampled rows
		      d3.selectAll(params.root + ' .ds' + String(new_ds_level) + '_row').each(function (d) {
		        if (_.contains(params.viz.viz_nodes.row, d.name) === false) {
		          d3.select(this).remove();
		        }
		      });
		    } else {
		      // remove real data rows
		      d3.selectAll(params.root + ' .row').each(function (d) {
		        if (_.contains(params.viz.viz_nodes.row, d.name) === false) {
		          d3.select(this).remove();
		        }
		      });
		    }
	
		    // remove not visible row labels
		    d3.selectAll(params.root + ' .row_label_group').each(function (d) {
		      if (_.contains(params.viz.viz_nodes.row, d.name) === false) {
		        d3.select(this).remove();
		      }
		    });
	
		    // level change
		    if (new_ds_level != old_ds_level) {
	
		      // console.log('old: ' + String(old_ds_level) + ' new: '+ String(new_ds_level));
	
		      // all visible rows are missing at new downsampling level
		      missing_rows = params.viz.viz_nodes.row;
	
		      // remove old level rows
		      d3.selectAll(params.root + ' .ds' + String(old_ds_level) + '_row').remove();
		    }
		  }
	
		  // console.log('missing_rows: ' + String(missing_rows))
		  // console.log(missing_rows)
	
		  // only make new matrix_rows if there are missing rows
		  if (missing_rows.length >= 1 || missing_rows === 'all') {
		    make_matrix_rows(params, inst_matrix, missing_rows, new_ds_level);
		  }
	
		  // only make new row_labels if there are missing row_labels, downsampled, and
		  // not zooming out or zooming has stopped
		  if (new_ds_level === -1) {
	
		    if (zooming_out === false || zooming_stopped) {
	
		      // check if labels need to be made
		      ///////////////////////////////////
		      // get the names visible row_labels
		      var visible_row_labels = [];
		      d3.selectAll(params.root + ' .row_label_group').each(function (d) {
		        visible_row_labels.push(d.name);
		      });
	
		      // find missing labels
		      var missing_row_labels = _.difference(params.viz.viz_nodes.row, visible_row_labels);
	
		      // make labels
		      //////////////////////////////////
		      // only make row labels if there are any missing
		      var addback_thresh = 1;
		      if (missing_row_labels.length > addback_thresh) {
		        make_row_labels(cgm, missing_row_labels);
		      }
		    }
		  }
			};
	
	/***/ },
	/* 71 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function find_viz_rows(params, viz_area) {
	
		  var should_be_rows = [];
		  var curr_rows = [];
	
		  // find rows that should be visible
		  var y_trans;
	
		  // default y_scale (no downsampling)
		  var y_scale = params.viz.y_scale;
		  var ds_level = params.viz.ds_level;
		  var row_names = params.network_data.row_nodes_names;
		  var row_class = '.row';
	
		  // if downsampling redefine variables
		  if (ds_level >= 0) {
		    y_scale = params.viz.ds[ds_level].y_scale;
		    row_names = d3.range(params.matrix.ds_matrix[ds_level].length).map(String);
		    row_class = '.ds' + String(ds_level) + '_row';
		  }
	
		  // find rows that should be visible
		  for (var i = 0; i < row_names.length; i++) {
		    y_trans = y_scale(i);
		    if (y_trans < viz_area.max_y && y_trans > viz_area.min_y) {
		      should_be_rows.push(row_names[i]);
		    }
		  }
	
		  // find currently visible rows
		  d3.selectAll(params.root + ' ' + row_class).each(function (d) {
		    curr_rows.push(d.name);
		  });
	
		  // nodes that should be visible
		  params.viz.viz_nodes.row = should_be_rows;
		  // nodes that are visible
		  params.viz.viz_nodes.curr_row = curr_rows;
			};
	
	/***/ },
	/* 72 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function make_row_visual_aid_triangles(params) {
	
		  if (d3.select(params.root + ' .row_cat_group path').empty() === true) {
		    d3.selectAll(params.root + ' .row_cat_group').append('path').attr('d', function () {
		      var origin_x = params.viz.cat_room.symbol_width - 1;
		      var origin_y = 0;
		      var mid_x = 1;
		      var mid_y = params.viz.y_scale.rangeBand() / 2;
		      var final_x = params.viz.cat_room.symbol_width - 1;
		      var final_y = params.viz.y_scale.rangeBand();
		      var output_string = 'M ' + origin_x + ',' + origin_y + ' L ' + mid_x + ',' + mid_y + ', L ' + final_x + ',' + final_y + ' Z';
		      return output_string;
		    }).attr('fill', '#eee').style('opacity', params.viz.triangle_opacity);
		  }
			};
	
	/***/ },
	/* 73 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var d3_tip_custom = __webpack_require__(48);
	
		module.exports = function make_col_tooltips(params) {
	
		  if (params.labels.show_label_tooltips) {
	
		    // remove old col tooltips
		    d3.selectAll(params.viz.root_tips + '_col_tip').remove();
	
		    // d3-tooltip
		    var col_tip = d3_tip_custom().attr('class', function () {
		      var root_tip_selector = params.viz.root_tips.replace('.', '');
		      var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_col_tip';
		      return class_string;
		    }).direction('w').offset([20, 0]).style('display', 'none').html(function (d) {
		      var inst_name = d.name.replace(/_/g, ' ').split('#')[0];
		      return "<span>" + inst_name + "</span>";
		    });
	
		    d3.select(params.viz.viz_wrapper).select('svg').select(params.root + ' .col_zoom_container').selectAll('.col_label_group').select('text').call(col_tip);
	
		    d3.select(params.root + ' .col_zoom_container').selectAll('.col_label_group').on('mouseover', function (d) {
	
		      d3.selectAll(params.viz.root_tips + '_col_tip').style('display', 'block');
	
		      col_tip.show(d);
		      if (params.col_tip_callback != null) {
		        params.col_tip_callback(d);
		      }
		    }).on('mouseout', function () {
		      col_tip.hide(this);
	
		      d3.selectAll(params.viz.root_tips + '_col_tip').style('display', 'none');
		    });
		  }
			};
	
	/***/ },
	/* 74 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function col_viz_aid_triangle(params) {
	
		  // x and y are flipped since its rotated
		  var reduce_rect_width = params.viz.x_scale.rangeBand() * 0.36;
		  var origin_y = -params.viz.border_width.x;
		  var start_x = 0;
		  var final_x = params.viz.x_scale.rangeBand() - reduce_rect_width;
		  var start_y = -(params.viz.x_scale.rangeBand() - reduce_rect_width + params.viz.border_width.x);
		  var final_y = -params.viz.border_width.x;
		  var output_string = 'M ' + origin_y + ',0 L ' + start_y + ',' + start_x + ', L ' + final_y + ',' + final_x + ' Z';
		  return output_string;
		};
	
	/***/ },
	/* 75 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function (params) {
	
		  d3.select(params.viz.viz_svg).append('rect').attr('fill', params.viz.background_color).attr('height', params.viz.super_labels.dim.width + 'px').attr('width', '3000px').classed('super_col_bkg', true).classed('white_bars', true).attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.super_labels.margin.top + ')');
	
		  d3.select(params.viz.viz_svg).append('text').attr('class', 'super_col').text(params.labels.super.col).attr('text-anchor', 'center').attr('transform', function () {
	
		    var inst_text_width = d3.select(this)[0][0].getBBox().width;
	
		    var inst_x = params.viz.clust.dim.width / 2 + params.viz.norm_labels.width.row - inst_text_width / 2;
		    var inst_y = params.viz.super_labels.dim.width;
		    return 'translate(' + inst_x + ',' + inst_y + ')';
		  }).style('font-size', function () {
		    var inst_font_size = params.labels.super_label_fs * params.labels.super_label_scale;
		    return inst_font_size + 'px';
		  }).style('font-weight', 300);
	
		  d3.select(params.viz.viz_svg).append('rect').attr('fill', params.viz.background_color).attr('width', params.viz.super_labels.dim.width + 'px').attr('height', '3000px').classed('super_row_bkg', true).classed('white_bars', true).attr('transform', 'translate(' + params.viz.super_labels.margin.left + ',0)');
	
		  // append super title row group - used to separate translation from rotation
		  d3.select(params.viz.viz_svg).append('g').classed('super_row', true).attr('transform', function () {
		    // position in the middle of the clustergram
		    var inst_x = params.viz.super_labels.dim.width;
		    var inst_y = params.viz.clust.dim.height / 2 + params.viz.norm_labels.width.col;
		    return 'translate(' + inst_x + ',' + inst_y + ')';
		  });
	
		  // super row label (rotate the already translated title )
		  d3.select(params.root + ' .super_row').append('text').text(params.labels.super.row).attr('text-anchor', 'center').attr('transform', function () {
		    var inst_text_width = d3.select(this)[0][0].getBBox().width;
		    var inst_x_offset = inst_text_width / 2 + params.viz.norm_labels.width.col;
		    var inst_offset = 'translate(0,' + inst_x_offset + '), rotate(-90)';
		    return inst_offset;
		  }).style('font-size', function () {
		    var inst_font_size = params.labels.super_label_fs * params.labels.super_label_scale;
		    return inst_font_size + 'px';
		  }).style('font-weight', 300);
			};
	
	/***/ },
	/* 76 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var get_cat_title = __webpack_require__(77);
		var ini_cat_reorder = __webpack_require__(78);
		var make_row_cat_super_labels = __webpack_require__(86);
		var make_dendro_crop_buttons = __webpack_require__(60);
	
		module.exports = function Spillover(cgm) {
	
		  var params = cgm.params;
	
		  var viz = params.viz;
	
		  // hide spillover from slanted column labels on right side
		  d3.select(viz.root + ' .col_container').append('path').style('stroke-width', '0').attr('d', 'M 0,0 L 1000,-1000, L 1000,0 Z').attr('fill', viz.background_color) //!! prog_colors
		  .attr('class', 'right_slant_triangle').attr('transform', 'translate(' + viz.clust.dim.width + ',' + viz.norm_labels.width.col + ')');
	
		  // hide spillover from slanted column labels on left side
		  d3.select(viz.root + ' .col_container').append('path').style('stroke-width', '0').attr('d', 'M 0,0 L 500,-500, L 0,-500 Z').attr('fill', viz.background_color).attr('class', 'left_slant_triangle')
		  // shift left by 1 px to prevent cutting off labels
		  .attr('transform', 'translate(-1,' + viz.norm_labels.width.col + ')');
	
		  var rect_height = viz.clust.margin.top + viz.uni_margin / 5;
		  // white rect to cover excess labels
		  d3.select(viz.viz_svg).append('rect').attr('fill', viz.background_color) //!! prog_colors
		  .attr('width', viz.clust.margin.left).attr('height', rect_height).attr('class', 'top_left_white');
	
		  var inst_height = viz.cat_room.col + 1.5 * viz.uni_margin;
		  // white rect to cover excess labels
		  d3.select(viz.viz_svg).append('rect').attr('fill', viz.background_color).attr('width', 2 * viz.clust.dim.width).attr('height', inst_height).attr('class', 'top_right_white').attr('transform', function () {
		    var tmp_left = viz.clust.margin.left + viz.clust.dim.width;
		    var tmp_top = viz.norm_labels.width.col + viz.norm_labels.margin.top - viz.uni_margin;
		    return 'translate(' + tmp_left + ', ' + tmp_top + ')';
		  });
	
		  x_offset = viz.clust.margin.left + viz.clust.dim.width + viz.uni_margin;
		  y_offset = viz.norm_labels.margin.top + viz.norm_labels.width.col + 2.5 * viz.uni_margin;
		  var cat_text_size = 1.15 * viz.cat_room.symbol_width;
		  var cat_super_opacity = 0.65;
		  var extra_y_room = 1.25;
	
		  // col category super labels
		  if (viz.show_categories.col) {
	
		    d3.select(viz.viz_svg).selectAll().data(viz.all_cats.col).enter().append('text').classed('col_cat_super', true).style('font-size', cat_text_size + 'px').style('opacity', cat_super_opacity).style('cursor', 'default').attr('transform', function (d) {
		      var inst_cat = parseInt(d.split('-')[1], 10);
		      var inst_y = y_offset + extra_y_room * viz.cat_room.symbol_width * inst_cat;
		      return 'translate(' + x_offset + ',' + inst_y + ')';
		    }).text(function (d) {
		      return get_cat_title(viz, d, 'col');
		    });
		  }
	
		  // row category super labels
		  make_row_cat_super_labels(cgm);
	
		  // white border bottom - prevent clustergram from hitting border
		  if (viz.show_dendrogram) {
		    // quick fix to make room for crop buttons
		    y_offset = viz.clust.margin.top + viz.clust.dim.height + viz.dendro_room.col - 2 * viz.uni_margin;
		  } else {
		    y_offset = viz.clust.margin.top + viz.clust.dim.height;
		  }
	
		  var b_spill_container = d3.select(viz.viz_svg).append('g').classed('bottom_spillover_container', true).attr('transform', function () {
		    // shift up enough to show the entire border width
		    return 'translate(0,' + y_offset + ')';
		  });
	
		  b_spill_container.append('rect').attr('class', 'bottom_spillover').attr('fill', viz.background_color) //!! prog_colors
		  .attr('width', viz.svg_dim.width).attr('height', 2 * viz.svg_dim.height);
	
		  x_offset = viz.clust.margin.left;
		  y_offset = 0;
		  b_spill_container.append('g').classed('col_dendro_icons_container', true).attr('transform', 'translate(' + x_offset + ',' + y_offset + ')').append('g').classed('col_dendro_icons_group', true);
	
		  make_dendro_crop_buttons(cgm, 'col');
	
		  var x_offset = viz.clust.margin.left + viz.clust.dim.width;
		  var y_offset = viz.clust.margin.top + viz.clust.dim.height;
		  var tmp_width = viz.cat_room.col + viz.clust.dim.width;
		  var tmp_height = viz.cat_room.row + 10 * viz.uni_margin;
		  d3.select(viz.viz_svg).append('rect').attr('fill', viz.background_color).attr('width', tmp_width).attr('height', tmp_height).attr('transform', function () {
		    return 'translate(' + x_offset + ',' + y_offset + ')';
		  }).classed('white_bars', true).classed('dendro_corner_spillover', true);
	
		  // hide spillover left top of col dendrogram
		  x_offset = 0;
		  y_offset = viz.clust.margin.top + viz.clust.dim.height;
		  tmp_width = viz.clust.margin.left;
		  tmp_height = viz.clust.dim.height * 10;
		  d3.select(viz.viz_svg).append('rect').attr('fill', viz.background_color).attr('width', tmp_width).attr('height', tmp_height).attr('transform', function () {
		    return 'translate(' + x_offset + ',' + y_offset + ')';
		  }).classed('white_bars', true).classed('dendro_col_spillover', true);
	
		  ini_cat_reorder(cgm);
			};
	
	/***/ },
	/* 77 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function get_cat_title(viz, inst_cat, inst_rc) {
		  var cat_title;
	
		  // make default title if none is given
		  if (viz.cat_names[inst_rc][inst_cat] === inst_cat) {
		    var inst_num = parseInt(inst_cat.split('-')[1], 10) + 1;
		    // generate placeholder title
		    cat_title = 'Category ' + inst_num;
		  } else {
		    // make real title
		    cat_title = viz.cat_names[inst_rc][inst_cat];
		  }
	
		  return cat_title;
			};
	
	/***/ },
	/* 78 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var all_reorder = __webpack_require__(79);
	
		module.exports = function ini_cat_reorder(cgm) {
		  /* eslint-disable */
	
		  var params = cgm.params;
	
		  _.each(['row', 'col'], function (inst_rc) {
	
		    if (params.viz.show_categories[inst_rc]) {
		      d3.selectAll(params.root + ' .' + inst_rc + '_cat_super').on('dblclick', function () {
	
		        if (params.sim_mat) {
		          inst_rc = 'both';
		        }
	
		        d3.selectAll(params.root + ' .toggle_' + inst_rc + '_order .btn').classed('active', false);
	
		        var order_id = this.__data__.replace('-', '_') + '_index';
		        if (params.viz.sim_mat) {
		          all_reorder(cgm, order_id, 'row');
		          all_reorder(cgm, order_id, 'col');
		        } else {
		          all_reorder(cgm, order_id, inst_rc);
		        }
		      });
		    }
		  });
		};
	
	/***/ },
	/* 79 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var toggle_dendro_view = __webpack_require__(54);
		var show_visible_area = __webpack_require__(70);
		var ini_zoom_info = __webpack_require__(36);
		var calc_downsampled_levels = __webpack_require__(27);
		var two_translate_zoom = __webpack_require__(80);
		var get_previous_zoom = __webpack_require__(65);
	
		module.exports = function (cgm, inst_order, inst_rc) {
	
		  var params = cgm.params;
	
		  var prev_zoom = get_previous_zoom(params);
	
		  var delay_reorder = 0;
		  if (prev_zoom.zoom_y != 1 || prev_zoom.zoom_x != 1) {
		    // reset zoom before reordering
		    two_translate_zoom(cgm, 0, 0, 1);
		    delay_reorder = 1200;
		  }
	
		  // row/col names are swapped, will improve later
		  var other_rc;
		  if (inst_rc === 'row') {
		    other_rc = 'col';
		  } else if (inst_rc === 'col') {
		    other_rc = 'row';
		  }
	
		  params.viz.run_trans = true;
	
		  // save order state
		  if (other_rc === 'row') {
		    params.viz.inst_order.row = inst_order;
		  } else if (other_rc === 'col') {
		    params.viz.inst_order.col = inst_order;
		  }
	
		  if (params.viz.show_dendrogram) {
		    toggle_dendro_view(cgm, inst_rc);
		  }
	
		  if (other_rc === 'row') {
		    params.viz.x_scale.domain(params.matrix.orders[params.viz.inst_order.row + '_row']);
		  } else if (other_rc == 'col') {
		    params.viz.y_scale.domain(params.matrix.orders[params.viz.inst_order.col + '_col']);
		  }
	
		  // only animate transition if there are a small number of tiles
		  var t;
		  if (d3.selectAll(params.root + ' .tile')[0].length < params.matrix.def_large_matrix) {
		    t = d3.select(params.root + ' .viz_svg').transition().duration(2500).delay(delay_reorder);
		  } else {
		    t = d3.select(params.root + ' .viz_svg');
		  }
	
		  var row_nodes_names = params.network_data.row_nodes_names;
		  var col_nodes_names = params.network_data.col_nodes_names;
	
		  // only update matrix if not downsampled (otherwise rows are updated)
		  if (params.viz.ds_level === -1) {
	
		    t.selectAll('.row').attr('transform', function (d) {
		      var inst_index = _.indexOf(row_nodes_names, d.name);
		      return 'translate(0,' + params.viz.y_scale(inst_index) + ')';
		    }).selectAll('.tile').attr('transform', function (d) {
		      return 'translate(' + params.viz.x_scale(d.pos_x) + ' , 0)';
		    });
	
		    t.selectAll('.tile_up').attr('transform', function (d) {
		      return 'translate(' + params.viz.x_scale(d.pos_x) + ' , 0)';
		    });
	
		    t.selectAll('.tile_dn').attr('transform', function (d) {
		      return 'translate(' + params.viz.x_scale(d.pos_x) + ' , 0)';
		    });
		  }
	
		  // Move Row Labels
		  t.select('.row_label_zoom_container').selectAll('.row_label_group').attr('transform', function (d) {
		    var inst_index = _.indexOf(row_nodes_names, d.name);
		    return 'translate(0,' + params.viz.y_scale(inst_index) + ')';
		  });
	
		  // Move Col Labels
		  t.select('.col_zoom_container').selectAll('.col_label_text').attr('transform', function (d) {
		    var inst_index = _.indexOf(col_nodes_names, d.name);
		    return 'translate(' + params.viz.x_scale(inst_index) + ') rotate(-90)';
		  });
	
		  // reorder row categories
		  t.selectAll('.row_cat_group').attr('transform', function (d) {
		    var inst_index = _.indexOf(row_nodes_names, d.name);
		    return 'translate(0,' + params.viz.y_scale(inst_index) + ')';
		  });
	
		  // reorder col_class groups
		  t.selectAll('.col_cat_group').attr('transform', function (d) {
		    var inst_index = _.indexOf(col_nodes_names, d.name);
		    return 'translate(' + params.viz.x_scale(inst_index) + ',0)';
		  });
	
		  // redefine x and y positions
		  params.network_data.links.forEach(function (d) {
		    d.x = params.viz.x_scale(d.target);
		    d.y = params.viz.y_scale(d.source);
		  });
	
		  params.zoom_info = ini_zoom_info();
	
		  // calculate downsmapling if necessary
		  if (params.viz.ds_num_levels > 0 && params.viz.ds_level >= 0) {
	
		    calc_downsampled_levels(params);
		    var zooming_stopped = true;
		    var zooming_out = true;
		    var make_all_rows = true;
	
		    // show_visible_area is also run with two_translate_zoom, but at that point
		    // the parameters were not updated and two_translate_zoom if only run
		    // if needed to reset zoom
		    show_visible_area(cgm, zooming_stopped, zooming_out, make_all_rows);
		  }
	
		  setTimeout(function () {
		    params.viz.run_trans = false;
		  }, 2500);
			};
	
	/***/ },
	/* 80 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var utils = __webpack_require__(2);
		var label_constrain_and_trim = __webpack_require__(81);
		var show_visible_area = __webpack_require__(70);
		var ini_zoom_info = __webpack_require__(36);
		var toggle_grid_lines = __webpack_require__(85);
	
		module.exports = function two_translate_zoom(cgm, pan_dx, pan_dy, fin_zoom) {
	
		  // console.log('pan_dy: ' + String(pan_dy))
	
		  var params = cgm.params;
	
		  d3.selectAll(params.viz.root_tips).style('display', 'none');
	
		  params.zoom_info = ini_zoom_info();
	
		  show_visible_area(cgm);
	
		  // do not allow while transitioning, e.g. reordering
		  if (!params.viz.run_trans) {
	
		    // define the commonly used variable half_height
		    var half_height = params.viz.clust.dim.height / 2;
	
		    // y pan room, the pan room has to be less than half_height since
		    // zooming in on a gene that is near the top of the clustergram also causes
		    // panning out of the visible region
		    var y_pan_room = half_height / fin_zoom;
	
		    // prevent visualization from panning down too much
		    // when zooming into genes near the top of the clustergram
		    if (pan_dy >= half_height - y_pan_room) {
	
		      // console.log(' prevent visualization from panning down too much')
	
		      // explanation of panning rules
		      /////////////////////////////////
		      /*
		        prevent the clustergram from panning down too much
		        if the amount of panning is equal to the half_height then it needs to be reduced
		        effectively, the the visualization needs to be moved up (negative) by some factor
		        of the half-width-of-the-visualization.
		         If there was no zooming involved, then the
		        visualization would be centered first, then panned to center the top term
		        this would require a
		        correction to re-center it. However, because of the zooming the offset is
		        reduced by the zoom factor (this is because the panning is occurring on something
		        that will be zoomed into - this is why the pan_dy value is not scaled in the two
		        translate transformations, but it has to be scaled afterwards to set the translate
		        vector)
		        pan_dy = half_height - (half_height)/fin_zoom
		         if pan_dy is greater than the pan room, then panning has to be restricted
		        start by shifting back up (negative) by half_height/fin_zoom then shift back down
		        by the difference between half_height and pan_dy (so that the top of the clustergram is
		        visible)
		      */
	
		      var shift_top_viz = half_height - pan_dy;
		      var shift_up_viz = -half_height / fin_zoom + shift_top_viz;
	
		      // reduce pan_dy so that the visualization does not get panned to far down
		      pan_dy = pan_dy + shift_up_viz;
		    }
	
		    // prevent visualization from panning up too much
		    // when zooming into genes at the bottom of the clustergram
		    if (pan_dy < -(half_height - y_pan_room)) {
	
		      shift_top_viz = half_height + pan_dy;
	
		      shift_up_viz = half_height / fin_zoom - shift_top_viz; //- move_up_one_row;
	
		      // reduce pan_dy so that the visualization does not get panned to far down
		      pan_dy = pan_dy + shift_up_viz;
		    }
	
		    // will improve this !!
		    var zoom_y = fin_zoom;
		    var zoom_x = 1;
	
		    // search duration - the duration of zooming and panning
		    var search_duration = 700;
	
		    // center_y
		    var center_y = -(zoom_y - 1) * half_height;
	
		    // transform clust group
		    ////////////////////////////
		    d3.select(params.root + ' .clust_group').transition().duration(search_duration)
		    // first apply the margin transformation
		    // then zoom, then apply the final transformation
		    .attr('transform', 'translate(' + [0, 0 + center_y] + ')' + ' scale(' + zoom_x + ',' + zoom_y + ')' + 'translate(' + [pan_dx, pan_dy] + ')');
	
		    // transform row labels
		    d3.select(params.root + ' .row_label_zoom_container').transition().duration(search_duration).attr('transform', 'translate(' + [0, center_y] + ')' + ' scale(' + zoom_y + ',' + zoom_y + ')' + 'translate(' + [0, pan_dy] + ')');
	
		    // transform row_cat_container
		    // use the offset saved in params, only zoom in the y direction
		    d3.select(params.root + ' .row_cat_container').transition().duration(search_duration).attr('transform', 'translate(' + [0, center_y] + ')' + ' scale(' + 1 + ',' + zoom_y + ')' + 'translate(' + [0, pan_dy] + ')');
	
		    d3.select(params.root + ' .row_dendro_container').transition().duration(search_duration).attr('transform', 'translate(' + [0, center_y] + ')' + ' scale(' + zoom_x + ',' + zoom_y + ')' + 'translate(' + [params.viz.uni_margin / 2, pan_dy] + ')');
	
		    // toggle crop buttons
		    var inst_button_opacity;
		    _.each(['row', 'col'], function (inst_rc) {
	
		      inst_button_opacity = d3.select(params.root + ' .' + inst_rc + '_dendro_crop_buttons').style('opacity');
		      d3.selectAll(params.root + ' .' + inst_rc + '_dendro_crop_buttons').style('opacity', 0);
		      setTimeout(show_crop_buttons, 700, inst_rc, inst_button_opacity);
		    });
	
		    // transform col labels
		    d3.select(params.root + ' .col_zoom_container').transition().duration(search_duration).attr('transform', ' scale(' + zoom_x + ',' + zoom_x + ')' + 'translate(' + [pan_dx, 0] + ')');
	
		    // transform col_class
		    d3.select(params.root + ' .col_cat_container').transition().duration(search_duration).attr('transform', ' scale(' + zoom_x + ',' + 1 + ')' + 'translate(' + [pan_dx, 0] + ')');
	
		    d3.select(params.root + ' .col_dendro_container').transition().duration(search_duration).attr('transform', ' scale(' + zoom_x + ',' + 1 + ')' + 'translate(' + [pan_dx, params.viz.uni_margin / 2] + ')');
	
		    // set y translate: center_y is positive, positive moves the visualization down
		    // the translate vector has the initial margin, the first y centering, and pan_dy
		    // times the scaling zoom_y
		    var net_y_offset = params.viz.clust.margin.top + center_y + pan_dy * zoom_y;
		    var net_x_offset = params.viz.clust.margin.left + pan_dx;
	
		    // reset the zoom and translate
		    params.zoom_behavior.scale(zoom_y).translate([net_x_offset, net_y_offset]);
	
		    label_constrain_and_trim(params);
	
		    // re-size of the highlighting rects
		    /////////////////////////////////////////
		    if (d3.select(params.root + ' .row_label_zoom_container text').empty() === false) {
		      d3.select(params.root + ' .row_label_zoom_container').each(function () {
		        // get the bounding box of the row label text
		        var bbox = d3.select(this).select('text')[0][0].getBBox();
	
		        // use the bounding box to set the size of the rect
		        d3.select(this).select('rect').attr('x', bbox.x * 0.5).attr('y', 0).attr('width', bbox.width * 0.5).attr('height', params.viz.y_scale.rangeBand()).style('fill', 'yellow');
		      });
		    }
	
		    // reset crop button zooming
		    d3.select(params.root + ' .row_dendro_icons_group').attr('transform', 'translate(' + [0, 0 + center_y] + ')' + ' scale(' + zoom_x + ',' + zoom_y + ')' + 'translate(' + [pan_dx, pan_dy] + ')');
	
		    d3.select(params.root + ' .row_dendro_icons_group').selectAll('path').attr('transform', function (d) {
		      var inst_x = params.viz.uni_margin;
		      var inst_y = d.pos_mid;
		      return 'translate(' + inst_x + ',' + inst_y + ') ' + 'scale(1, ' + 1 / zoom_y + ')';
		    });
	
		    // console.log('zooming x and y')
		    // console.log(zoom_x)
		    // console.log(zoom_y)
	
		    // need to improve behavior
		    d3.select(params.root + ' .col_dendro_icons_group').attr('transform', function () {
		      var inst_trans =
		      // 'translate(' + [0, 0 + center_y] + ')' +
		      ' scale(' + zoom_x + ',' + zoom_y + ')';
		      // + 'translate(' + [pan_dx, pan_dy ] + ')';
		      return inst_trans;
		    });
	
		    d3.select(params.root + ' .col_dendro_icons_group').selectAll('path').attr('transform', function (d) {
		      var inst_x = d.pos_mid;
		      var inst_y = params.viz.uni_margin;
		      // return 'translate('+ inst_x +',' + inst_y + ') ' + 'scale('+1/zoom_x+',1)';
		      return 'translate(' + inst_x + ',' + inst_y + ') ' + 'scale(1,1)';
		    });
	
		    // column value bars
		    ///////////////////////
		    // reduce the height of the column value bars based on the zoom applied
		    // recalculate the height and divide by the zooming scale
		    // col_label_obj.select('rect')
		    if (utils.has(params.network_data.col_nodes[0], 'value')) {
	
		      d3.selectAll(params.root + ' .col_bars').attr('width', function (d) {
		        var inst_value = 0;
		        if (d.value > 0) {
		          inst_value = params.labels.bar_scale_col(d.value) / zoom_x;
		        }
		        return inst_value;
		      });
		    }
	
		    if (utils.has(params.network_data.row_nodes[0], 'value')) {
	
		      d3.selectAll(params.root + ' .row_bars').transition().duration(search_duration).attr('width', function (d) {
		        var inst_value = 0;
		        inst_value = params.labels.bar_scale_row(Math.abs(d.value)) / zoom_y;
		        return inst_value;
		      }).attr('x', function (d) {
		        var inst_value = 0;
		        inst_value = -params.labels.bar_scale_row(Math.abs(d.value)) / zoom_y;
		        return inst_value;
		      });
		    }
	
		    toggle_grid_lines(params);
		  }
	
		  function show_crop_buttons(inst_rc, inst_button_opacity) {
		    d3.selectAll(params.root + ' .' + inst_rc + '_dendro_crop_buttons').transition().duration(search_duration).style('opacity', inst_button_opacity);
		  }
			};
	
	/***/ },
	/* 81 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var utils = __webpack_require__(2);
		var trim_text = __webpack_require__(82);
		var constrain_font_size = __webpack_require__(83);
	
		module.exports = function label_constrain_and_trim(params) {
	
		  // console.log('label_constrain_and_trim');
	
		  // reset text in rows and columns
		  d3.selectAll(params.root + ' .row_label_group').select('text').text(function (d) {
		    return utils.normal_name(d);
		  });
	
		  d3.selectAll(params.root + ' .col_label_text').select('text').text(function (d) {
		    return utils.normal_name(d);
		  });
	
		  constrain_font_size(params);
	
		  d3.selectAll(params.root + ' .row_label_group').each(function () {
		    trim_text(params, this, 'row');
		  });
	
		  d3.selectAll(params.root + ' .col_label_group').each(function () {
		    trim_text(params, this, 'col');
		  });
			};
	
	/***/ },
	/* 82 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function (params, inst_selection, inst_rc) {
		  if (d3.select(inst_selection).style('display') != 'none') {
	
		    // trim text that is longer than the container
		    var inst_zoom;
		    var inst_width;
		    var trimmed_text;
		    var current_num_char;
		    var inst_text;
		    var original_text;
		    var keep_num_char;
		    var i;
	
		    var max_width = params.viz.norm_labels.width[inst_rc];
	
		    if (inst_rc === 'row') {
		      if (params.viz.zoom_ratio.y) {
		        inst_zoom = params.zoom_behavior.scale() / params.viz.zoom_ratio.y;
		      } else {
		        inst_zoom = params.zoom_behavior.scale();
		      }
		      // num_trims = params.labels.row_max_char;
		    } else {
		      if (params.viz.zoom_ratio.x > 1) {
		        inst_zoom = params.zoom_behavior.scale() / params.viz.zoom_ratio.x;
		      } else {
		        inst_zoom = params.zoom_behavior.scale();
		      }
		      // num_trims = params.labels.col_max_char;
		    }
	
		    var num_trims;
		    d3.select(inst_selection).select('text').each(function (d) {
		      num_trims = d.name.length;
		    });
	
		    var tmp_width = d3.select(inst_selection).select('text').node().getBBox().width;
	
		    inst_width = calc_width(tmp_width, inst_zoom);
	
		    if (inst_width > max_width) {
	
		      for (i = 1; i < num_trims; i++) {
		        if (inst_width > max_width) {
	
		          d3.select(inst_selection).select('text').text(trim);
	
		          tmp_width = d3.select(inst_selection).select('text').node().getBBox().width;
	
		          inst_width = calc_width(tmp_width, inst_zoom);
		        }
		      }
		    } else if (inst_width < max_width * 0.75) {
	
		      for (i = 1; i < num_trims; i++) {
		        if (inst_width < max_width * 0.75) {
	
		          d3.select(inst_selection).select('text').text(add_back);
	
		          tmp_width = d3.select(inst_selection).select('text').node().getBBox().width;
	
		          inst_width = calc_width(tmp_width, inst_zoom);
		        }
		      }
		    }
		  }
	
		  function trim() {
		    inst_text = d3.select(this).text();
		    current_num_char = inst_text.length;
		    keep_num_char = current_num_char - 3;
		    trimmed_text = inst_text.substring(0, keep_num_char) + '..';
		    return trimmed_text;
		  }
	
		  function add_back(d) {
		    inst_text = d3.select(this).text();
		    if (inst_text.slice(-2) === '..') {
		      current_num_char = inst_text.length - 2;
		    } else {
		      current_num_char = inst_text.length;
		    }
	
		    original_text = d.name;
		    keep_num_char = current_num_char + 2;
		    trimmed_text = original_text.substring(0, keep_num_char) + '..';
	
		    // if '..' was added to original text
		    if (trimmed_text.length > original_text.length) {
		      trimmed_text = original_text;
		    }
	
		    return trimmed_text;
		  }
	
		  function calc_width(tmp_width, inst_zoom) {
		    if (inst_zoom < 1) {
		      inst_width = tmp_width;
		    } else {
		      inst_width = tmp_width * inst_zoom;
		    }
	
		    return inst_width;
		  }
			};
	
	/***/ },
	/* 83 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var calc_real_font_size = __webpack_require__(84);
	
		module.exports = function constrain_font_size(params) {
	
		  var tmp_font_size = params.labels.default_fs_row;
		  var inst_zoom;
		  var min_font_size = 3;
	
		  var real_font_size = calc_real_font_size(params);
	
		  // rows
		  ////////////////////////////////////
		  if (real_font_size.row > min_font_size) {
	
		    if (real_font_size.row > params.labels.max_allow_fs) {
	
		      if (params.viz.zoom_ratio.y) {
		        inst_zoom = params.zoom_behavior.scale() / params.viz.zoom_ratio.y;
		      } else {
		        inst_zoom = params.zoom_behavior.scale();
		      }
	
		      if (inst_zoom < 1) {
		        inst_zoom = 1;
		      }
	
		      tmp_font_size = params.labels.max_allow_fs / inst_zoom;
	
		      d3.selectAll(params.root + ' .row_label_group').select('text').style('font-size', tmp_font_size + 'px').attr('y', params.viz.rect_height * 0.5 + tmp_font_size * 0.35);
		    } else {
		      d3.selectAll(params.root + ' .row_label_group').select('text').style('font-size', params.labels.default_fs_row + 'px').attr('y', params.viz.rect_height * 0.5 + params.labels.default_fs_row * 0.35);
		    }
		  }
	
		  // columns
		  //////////////////////////////////////
		  if (real_font_size.col > min_font_size) {
	
		    if (real_font_size.col > params.labels.max_allow_fs) {
	
		      if (params.viz.zoom_ratio.x > 1) {
		        inst_zoom = params.zoom_behavior.scale() / params.viz.zoom_ratio.x;
		      } else {
		        inst_zoom = params.zoom_behavior.scale();
		      }
	
		      if (inst_zoom < 1) {
		        inst_zoom = 1;
		      }
	
		      tmp_font_size = params.labels.max_allow_fs / inst_zoom;
	
		      if (tmp_font_size > 0.7 * params.viz.rect_width) {
		        tmp_font_size = 0.7 * params.viz.rect_width;
		      }
	
		      d3.selectAll(params.root + ' .col_label_text').select('text').style('font-size', tmp_font_size + 'px');
		    } else {
		      d3.selectAll(params.root + ' .col_label_text').select('text').style('font-size', params.labels.default_fs_col + 'px');
		    }
		  }
			};
	
	/***/ },
	/* 84 */
	/***/ function(module, exports) {
	
		"use strict";
	
		module.exports = function calc_real_font_size(params) {
	
		  var real_font_size = {};
		  // zoom_switch behavior has to change with zoom_ratio.y
		  if (params.viz.zoom_ratio.x > 1) {
		    real_font_size.row = params.labels.default_fs_row * params.zoom_behavior.scale();
		    real_font_size.col = params.labels.default_fs_col * params.zoom_behavior.scale();
		  } else {
		    real_font_size.row = params.labels.default_fs_row * params.zoom_behavior.scale() / params.viz.zoom_ratio.y;
		    real_font_size.col = params.labels.default_fs_col * params.zoom_behavior.scale();
		  }
	
		  return real_font_size;
			};
	
	/***/ },
	/* 85 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function toggle_grid_lines(params) {
	
		  if (params.zoom_info.zoom_x * params.viz.border_width.x > 1) {
		    d3.selectAll(params.root + ' .vert_lines').select('line').style('display', 'block').style('opacity', 0).transition().style('opacity', 1);
		  } else {
		    d3.selectAll(params.root + ' .vert_lines').select('line').style('display', 'none');
		  }
	
		  if (params.zoom_info.zoom_y * params.viz.border_width.y > 1) {
		    d3.selectAll(params.root + ' .horz_lines').select('line').style('display', 'block').style('opacity', 0).transition().style('opacity', 1);
		  } else {
		    d3.selectAll(params.root + ' .horz_lines').select('line').style('display', 'none');
		  }
		};
	
	/***/ },
	/* 86 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var get_cat_title = __webpack_require__(77);
		var d3_tip_custom = __webpack_require__(48);
	
		module.exports = function make_row_cat_super_labels(cgm) {
	
		  var params = cgm.params;
	
		  var viz = params.viz;
		  var extra_x_room = 2.75;
	
		  if (d3.select(params.root + ' .row_cat_label_container').empty()) {
	
		    d3.select(cgm.params.viz.viz_svg).append('g').classed('row_cat_label_container', true);
	
		    // append background section for optional value-bars (e.g. enrichment pvals)
		    d3.select(cgm.params.viz.viz_svg + ' .row_cat_label_container').append('g').classed('row_cat_label_bar_container', true);
		  }
	
		  var x_offset = viz.clust.margin.left + viz.clust.dim.width + viz.uni_margin;
		  var y_offset = viz.norm_labels.margin.top + viz.norm_labels.width.col + 2.5 * viz.uni_margin;
		  var cat_text_size = 1.15 * viz.cat_room.symbol_width;
		  var cat_super_opacity = 0.65;
		  var extra_y_room = 1.25;
	
		  d3.select(params.root + ' .row_cat_label_container').attr('transform', function () {
		    x_offset = viz.norm_labels.margin.left + viz.norm_labels.width.row + viz.cat_room.symbol_width + extra_x_room * viz.uni_margin;
		    y_offset = viz.clust.margin.top - viz.uni_margin;
		    return 'translate(' + x_offset + ',' + y_offset + ') rotate(-90)';
		  });
	
		  // clear old categories
		  d3.selectAll(params.root + ' .row_cat_label_container text').remove();
		  d3.selectAll(params.root + ' .row_cat_selection_bar').remove();
		  // d3.selectAll(params.root+' .row_cat_label_bar_container rect').remove();
	
		  // remove any old row_cat_super tooltips from this visualization
		  d3.selectAll(cgm.params.viz.root_tips + '_row_cat_super').remove();
	
		  // d3-tooltip
		  var tmp_y_offset = 50; // viz.clust.margin.top - viz.uni_margin;
		  var tmp_x_offset = -75;
		  var cat_tip = d3_tip_custom().attr('class', function () {
		    var root_tip_selector = params.viz.root_tips.replace('.', '');
		    var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_row_cat_super';
		    return class_string;
		  }).direction('south_custom').offset([tmp_y_offset, tmp_x_offset]).style('display', 'none').style('opacity', 0).html(function (d) {
	
		    var full_string;
	
		    var tmp_string = params.network_data.row_nodes[0][d];
	
		    if (tmp_string.indexOf('<p>') > -1) {
	
		      var start_string = tmp_string.split(': ')[0];
		      var end_string = tmp_string.split('<p>')[1];
	
		      full_string = start_string + '<p>' + end_string;
		    } else {
	
		      full_string = get_cat_title(viz, d, 'row');
		    }
	
		    return full_string;
		  });
	
		  var unit_length = extra_y_room * viz.cat_room.symbol_width;
		  var bar_width = unit_length * 0.9;
	
		  // show row label categories even if viewing a simmilarity matrix
	
		  d3.select(params.root + ' .row_cat_label_container').selectAll().data(viz.all_cats.row).enter().append('text').style('width', '100px').style('height', bar_width + 'px').classed('row_cat_super', true).style('font-size', cat_text_size + 'px').style('opacity', cat_super_opacity).style('cursor', 'default').attr('transform', function (d) {
		    var inst_y = extra_y_room * viz.cat_room.symbol_width * parseInt(d.split('-')[1], 10);
		    return 'translate(0,' + inst_y + ')';
		  }).text(function (d) {
	
		    return get_cat_title(viz, d, 'row');
		  });
	
		  // selection bar
		  ///////////////////////////////
		  d3.select(params.root + ' .row_cat_label_container').selectAll().data(viz.all_cats.row).enter().append('rect').classed('row_cat_super', true).classed('row_cat_selection_bar', true).style('height', bar_width + 'px').style('fill', 'green').style('width', '120px').style('opacity', 0).attr('transform', function (d) {
		    var inst_y = unit_length * (parseInt(d.split('-')[1], 10) - 0.75);
		    return 'translate(0,' + inst_y + ')';
		  }).on('mouseover', function (d) {
	
		    d3.selectAll(params.viz.root_tips + '_row_cat_super').style('display', 'block').style('opacity', 1);
	
		    cat_tip.show(d);
		  }).on('mouseout', function () {
		    cat_tip.hide(this);
		    // might not need
		    d3.selectAll('.d3-tip').style('display', 'none');
	
		    d3.selectAll(params.viz.root_tips + '_row_cat_super').style('display', 'none').style('opacity', 0);
		  });
	
		  // row category super-label mouseover
		  //////////////////////////////////////
		  if (d3.select(params.root + ' .row_cat_selection_bar').empty() === false) {
		    d3.selectAll(params.root + ' .row_cat_selection_bar').call(cat_tip);
		  }
	
		  if (_.has(params.network_data, 'row_cat_bars')) {
	
		    // Enrichrgram title
		    /////////////////////
		    d3.select(params.root + ' .enr_title').remove();
	
		    var enr_title = d3.select(params.root + ' .viz_svg').append('g').classed('enr_title', true).attr('transform', function () {
		      var trans = d3.select(params.root + ' .row_cat_label_container').attr('transform').split('(')[1].split(')')[0];
		      var x_offset = Number(trans.split(',')[0]) - 10;
	
		      return 'translate(' + String(x_offset) + ', 0)';
		    });
	
		    enr_title.append('rect').attr('width', params.viz.cat_room.row).attr('height', 25).attr('fill', 'white');
	
		    var library_string = params.network_data.enrichrgram_lib.substring(0, 40);
	
		    enr_title.append('text').attr('transform', 'translate(0, 17)').text(library_string.replace(/_/g, ' ')).style('font-size', '15px').attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif');
	
		    // Enrichr bars
		    ////////////////////
		    d3.selectAll(params.root + ' .enrichr_bars').remove();
	
		    var bar_height = params.viz.clust.margin.top - 35;
		    var max_score = params.network_data.row_cat_bars[0];
		    var bar_scale = d3.scale.linear().domain([0, max_score]).range([0, bar_height]);
	
		    d3.select(params.root + ' .row_cat_label_bar_container').selectAll().data(params.network_data.row_cat_bars).enter().append('rect').classed('enrichr_bars', true).style('height', bar_width + 'px').style('fill', 'red').style('width', function (d) {
		      var bar_length = bar_scale(d);
		      return bar_length + 'px';
		    }).style('opacity', 0.4).attr('transform', function (d, i) {
		      var inst_y = unit_length * (i - 0.75);
		      return 'translate(0, ' + inst_y + ')';
		    });
		  }
			};
	
	/***/ },
	/* 87 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var resize_viz = __webpack_require__(88);
	
		module.exports = function initialize_resizing(cgm) {
	
		  var params = cgm.params;
	
		  var exp_button;
	
		  // d3.select(window).on('resize', null);
	
		  // // resize window
		  // if (params.viz.resize) {
		  //   d3.select(window).on('resize', function () {
	
		  //     d3.select(params.viz.viz_svg).style('opacity', 0.5);
	
		  //     var wait_time = 500;
		  //     if (params.viz.run_trans === true) {
		  //       wait_time = 2500;
		  //     }
	
		  //     setTimeout(resize_viz, wait_time, params);
		  //   });
		  // }
	
		  // if (params.viz.expand_button) {
	
		  d3.select(params.root + ' .expand_button').on('click', null);
		  var expand_opacity = 0.4;
	
		  if (d3.select(params.root + ' .expand_button').empty()) {
		    exp_button = d3.select(params.viz.viz_svg).append('text').attr('class', 'expand_button');
		  } else {
		    exp_button = d3.select(params.root + ' .expand_button');
		  }
	
		  exp_button.attr('text-anchor', 'middle').attr('dominant-baseline', 'central').attr('font-family', 'FontAwesome').attr('font-size', '30px').text(function () {
		    if (params.viz.is_expand === false) {
		      // expand button
		      return '';
		    } else {
		      // menu button
		      return '';
		    }
		  }).attr('y', '25px').attr('x', '25px').style('cursor', 'pointer').style('opacity', expand_opacity).on('mouseover', function () {
		    d3.select(this).style('opacity', 0.75);
		  }).on('mouseout', function () {
		    d3.select(this).style('opacity', expand_opacity);
		  }).on('click', function () {
	
		    // expand view
		    if (params.viz.is_expand === false) {
	
		      d3.select(this).text(function () {
		        // menu button
		        return '';
		      });
		      params.viz.is_expand = true;
	
		      d3.selectAll(params.root + ' .borders').style('fill', 'white');
		      // d3.select(params.root+' .footer_section').style('display', 'none');
		      d3.select(params.root + ' .sidebar_wrapper').style('display', 'none');
	
		      // contract view
		    } else {
	
		      d3.select(this).text(function () {
		        // expand button
		        return '';
		      });
	
		      params.viz.is_expand = false;
	
		      d3.selectAll(params.root + ' .borders').style('fill', '#eee');
		      // d3.select(params.root+' .footer_section').style('display', 'block');
		      d3.select(params.root + ' .viz_wrapper').style('width', '100px');
		      d3.select(params.root + ' .sidebar_wrapper').style('display', 'block');
		    }
	
		    // // resize parent div
		    // set_viz_wrapper_size(params);
	
		    d3.select(params.viz.viz_svg).style('opacity', 0.5);
		    var wait_time = 500;
		    if (params.viz.run_trans == true) {
		      wait_time = 2500;
		    }
		    setTimeout(resize_viz, wait_time, cgm);
		  });
		  // }
		};
	
	/***/ },
	/* 88 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var utils = __webpack_require__(2);
		var run_zoom = __webpack_require__(89);
		var ini_doubleclick = __webpack_require__(97);
		var reset_zoom = __webpack_require__(98);
		var resize_dendro = __webpack_require__(99);
		var resize_super_labels = __webpack_require__(100);
		var resize_spillover = __webpack_require__(101);
		var resize_borders = __webpack_require__(102);
		var resize_row_labels = __webpack_require__(103);
		var resize_highlights = __webpack_require__(104);
		var resize_row_viz = __webpack_require__(105);
		var resize_col_labels = __webpack_require__(106);
		var resize_col_text = __webpack_require__(107);
		var resize_col_triangle = __webpack_require__(108);
		var resize_col_hlight = __webpack_require__(109);
		var recalc_params_for_resize = __webpack_require__(110);
		var resize_row_tiles = __webpack_require__(111);
		var resize_label_bars = __webpack_require__(112);
		var label_constrain_and_trim = __webpack_require__(81);
		var make_dendro_triangles = __webpack_require__(55);
		var toggle_dendro_view = __webpack_require__(54);
		var show_visible_area = __webpack_require__(70);
		var calc_viz_dimensions = __webpack_require__(18);
		var position_play_button = __webpack_require__(113);
		var make_row_cat_super_labels = __webpack_require__(86);
		var ini_cat_reorder = __webpack_require__(78);
		var position_svg_dendro_slider = __webpack_require__(114);
		var ini_zoom_info = __webpack_require__(36);
		var grid_lines_viz = __webpack_require__(115);
	
		module.exports = function resize_viz(cgm) {
	
		  var params = cgm.params;
	
		  var cont_dim = calc_viz_dimensions(params);
	
		  d3.select(params.root + ' .play_button');
		  // .style('opacity', 0.2);
	
	
		  d3.select(params.root + ' .sidebar_wrapper').style('height', cont_dim.height + 'px');
	
		  d3.select(params.viz.viz_wrapper)
		  // .style('float', 'left')
		  .style('margin-top', cont_dim.top + 'px').style('width', cont_dim.width + 'px').style('height', cont_dim.height + 'px');
	
		  params = recalc_params_for_resize(params);
	
		  params.zoom_info = ini_zoom_info();
	
		  reset_zoom(params);
	
		  var svg_group = d3.select(params.viz.viz_svg);
	
		  // redefine x and y positions
		  _.each(params.network_data.links, function (d) {
		    d.x = params.viz.x_scale(d.target);
		    d.y = params.viz.y_scale(d.source);
		  });
	
		  // disable zoom while transitioning
		  svg_group.on('.zoom', null);
	
		  params.zoom_behavior.scaleExtent([1, params.viz.square_zoom * params.viz.zoom_ratio.x]).on('zoom', function () {
		    run_zoom(cgm);
		  });
	
		  // reenable zoom after transition
		  if (params.viz.do_zoom) {
		    svg_group.call(params.zoom_behavior);
		  }
	
		  // prevent normal double click zoom etc
		  ini_doubleclick(cgm);
	
		  svg_group.attr('width', params.viz.svg_dim.width).attr('height', params.viz.svg_dim.height);
	
		  svg_group.select('.super_background').style('width', params.viz.svg_dim.width).style('height', params.viz.svg_dim.height);
	
		  svg_group.select('.grey_background').attr('width', params.viz.clust.dim.width).attr('height', params.viz.clust.dim.height);
	
		  setTimeout(position_play_button, 100, params);
	
		  var row_nodes = params.network_data.row_nodes;
		  var row_nodes_names = utils.pluck(row_nodes, 'name');
	
		  resize_row_tiles(params, svg_group);
	
		  svg_group.selectAll('.highlighting_rect').attr('width', params.viz.x_scale.rangeBand() * 0.80).attr('height', params.viz.y_scale.rangeBand() * 0.80);
	
		  resize_highlights(params);
	
		  // resize row labels
		  ///////////////////////////
	
		  resize_row_labels(params, svg_group);
		  resize_row_viz(params, svg_group);
	
		  // change the size of the highlighting rects
		  svg_group.selectAll('.row_label_group').each(function () {
		    var bbox = d3.select(this).select('text')[0][0].getBBox();
		    d3.select(this).select('rect').attr('x', bbox.x).attr('y', 0).attr('width', bbox.width).attr('height', params.viz.rect_height).style('fill', 'yellow').style('opacity', function (d) {
		      var inst_opacity = 0;
		      // highlight target genes
		      if (d.target === 1) {
		        inst_opacity = 1;
		      }
		      return inst_opacity;
		    });
		  });
	
		  // necessary to properly position row labels vertically
		  svg_group.selectAll('.row_label_group').select('text').attr('y', params.viz.rect_height * 0.5 + params.labels.default_fs_row * 0.35);
	
		  if (utils.has(params.network_data.row_nodes[0], 'value')) {
		    resize_label_bars(cgm, svg_group);
		  }
	
		  svg_group.selectAll('.row_cat_group').attr('transform', function (d) {
		    var inst_index = _.indexOf(row_nodes_names, d.name);
		    return 'translate(0, ' + params.viz.y_scale(inst_index) + ')';
		  });
	
		  svg_group.selectAll('.row_cat_group').select('path').attr('d', function () {
		    var origin_x = params.viz.cat_room.symbol_width - 1;
		    var origin_y = 0;
		    var mid_x = 1;
		    var mid_y = params.viz.rect_height / 2;
		    var final_x = params.viz.cat_room.symbol_width - 1;
		    var final_y = params.viz.rect_height;
		    var output_string = 'M ' + origin_x + ',' + origin_y + ' L ' + mid_x + ',' + mid_y + ', L ' + final_x + ',' + final_y + ' Z';
		    return output_string;
		  });
	
		  var is_resize = true;
		  if (params.viz.show_dendrogram) {
		    make_dendro_triangles(cgm, 'row', is_resize);
		    make_dendro_triangles(cgm, 'col', is_resize);
		    resize_dendro(params, svg_group);
	
		    toggle_dendro_view(cgm, 'row', 0);
		    toggle_dendro_view(cgm, 'col', 0);
		  } else {
		    resize_dendro(params, svg_group);
		  }
	
		  resize_col_labels(params, svg_group);
		  resize_col_text(params, svg_group);
		  resize_col_triangle(params, svg_group);
		  resize_col_hlight(params, svg_group);
	
		  resize_super_labels(params, svg_group);
		  resize_spillover(params.viz, svg_group);
	
		  grid_lines_viz(params);
	
		  resize_borders(params, svg_group);
	
		  // reset zoom and translate
		  params.zoom_behavior.scale(1).translate([params.viz.clust.margin.left, params.viz.clust.margin.top]);
	
		  label_constrain_and_trim(params);
	
		  // reposition matrix
		  d3.select(params.root + ' .clust_container').attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.clust.margin.top + ')');
	
		  // removed, this was causing bugs
		  if (cgm.params.viz.ds_level === -1) {
		    show_visible_area(cgm);
		  }
	
		  make_row_cat_super_labels(cgm);
	
		  d3.select(params.viz.viz_svg).style('opacity', 1);
	
		  ini_cat_reorder(cgm);
	
		  d3.select(cgm.params.root + ' .row_slider_group').style('opacity', 0);
		  d3.select(cgm.params.root + ' .col_slider_group').style('opacity', 0);
	
		  setTimeout(position_svg_dendro_slider, 500, cgm, 'row');
		  setTimeout(position_svg_dendro_slider, 500, cgm, 'col');
			};
	
	/***/ },
	/* 89 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var run_transformation = __webpack_require__(90);
		var zoom_rules_y = __webpack_require__(95);
		var zoom_rules_x = __webpack_require__(96);
	
		module.exports = function zoomed(cgm) {
	
		  var params = cgm.params;
	
		  var zoom_info = {};
		  zoom_info.zoom_x = d3.event.scale;
		  zoom_info.zoom_y = d3.event.scale;
	
		  // subtract away the margin to easily calculate pan_room etc.
		  zoom_info.trans_x = params.zoom_behavior.translate()[0] - params.viz.clust.margin.left;
		  zoom_info.trans_y = params.zoom_behavior.translate()[1] - params.viz.clust.margin.top;
	
		  d3.selectAll(params.viz.root_tips).style('display', 'none');
	
		  // transfer zoom_info to params
		  params.zoom_info = zoom_rules_y(params, zoom_info);
		  params.zoom_info = zoom_rules_x(params, zoom_info);
	
		  // do not run transformation if moving slider
		  if (params.is_slider_drag === false && params.is_cropping === false) {
	
		    // reset translate vector - add back margins to trans_x and trans_y
		    var new_x = params.zoom_info.trans_x + params.viz.clust.margin.left;
		    var new_y = params.zoom_info.trans_y + params.viz.clust.margin.top;
	
		    params.zoom_behavior.translate([new_x, new_y]);
		    cgm.params = params;
	
		    run_transformation(cgm);
		  }
			};
	
	/***/ },
	/* 90 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var constrain_font_size = __webpack_require__(83);
		var show_visible_area = __webpack_require__(70);
		var resize_label_val_bars = __webpack_require__(91);
		var zoom_crop_triangles = __webpack_require__(62);
		var get_previous_zoom = __webpack_require__(65);
		var run_when_zoom_stopped = __webpack_require__(92);
		var check_zoom_stop_status = __webpack_require__(94);
	
		module.exports = function run_transformation(cgm) {
	
		  var params = cgm.params;
	
		  var zoom_info = params.zoom_info;
	
		  var prev_zoom = get_previous_zoom(params);
	
		  d3.select(params.root + ' .clust_group').attr('transform', 'translate(' + [zoom_info.trans_x, zoom_info.trans_y] + ') scale(' + zoom_info.zoom_x + ',' + zoom_info.zoom_y + ')');
	
		  d3.select(params.root + ' .row_label_zoom_container').attr('transform', 'translate(' + [0, zoom_info.trans_y] + ') scale(' + zoom_info.zoom_y + ')');
	
		  d3.select(params.root + ' .col_zoom_container').attr('transform', 'translate(' + [zoom_info.trans_x, 0] + ') scale(' + zoom_info.zoom_x + ')');
	
		  d3.select(params.root + ' .row_cat_container').attr('transform', 'translate(' + [0, zoom_info.trans_y] + ') scale( 1,' + zoom_info.zoom_y + ')');
	
		  d3.select(params.root + ' .row_dendro_container').attr('transform', 'translate(' + [params.viz.uni_margin / 2, zoom_info.trans_y] + ') ' + 'scale( 1,' + zoom_info.zoom_y + ')');
	
		  d3.select(params.root + ' .row_dendro_icons_group').attr('transform', function () {
		    var inst_y = zoom_info.trans_y;
		    var inst_translate = 'translate(' + [0, inst_y] + ') ';
		    var inst_zoom = 'scale(1, ' + zoom_info.zoom_y + ')';
		    var transform_string = inst_translate + inst_zoom;
		    return transform_string;
		  });
	
		  d3.select(params.root + ' .col_dendro_icons_group').attr('transform', function () {
		    var inst_x = zoom_info.trans_x;
		    var inst_translate = 'translate(' + [inst_x, 0] + ')';
		    var inst_zoom = 'scale(' + zoom_info.zoom_x + ', 1)';
		    var transform_string = inst_translate + inst_zoom;
		    return transform_string;
		  });
	
		  zoom_crop_triangles(params, zoom_info, 'row');
		  zoom_crop_triangles(params, zoom_info, 'col');
	
		  d3.select(params.root + ' .col_cat_container').attr('transform', 'translate(' + [zoom_info.trans_x, 0] + ') scale(' + zoom_info.zoom_x + ',1)');
	
		  d3.select(params.root + ' .col_dendro_container').attr('transform', 'translate(' + [zoom_info.trans_x, params.viz.uni_margin / 2] + ') scale(' + zoom_info.zoom_x + ',1)');
	
		  resize_label_val_bars(params, zoom_info);
	
		  d3.select(params.root + ' .viz_svg').attr('is_zoom', function () {
		    var inst_zoom = Number(d3.select(params.root + ' .viz_svg').attr('is_zoom'));
		    d3.select(params.root + ' .viz_svg').attr('stopped_zoom', 1);
		    return inst_zoom + 1;
		  });
	
		  // this function runs with a slight delay and tells the visualization that
		  // this particular zoom event is over, reducing the total number of zoom
		  // events that need to finish
		  var not_zooming = function not_zooming() {
	
		    d3.select(params.root + ' .viz_svg').attr('is_zoom', function () {
		      var inst_zoom = Number(d3.select(params.root + ' .viz_svg').attr('is_zoom'));
		      return inst_zoom - 1;
		    });
		  };
	
		  constrain_font_size(params);
	
		  if (zoom_info.zoom_y <= prev_zoom.zoom_y) {
	
		    var zooming_out = false;
		    if (zoom_info.zoom_y < prev_zoom.zoom_y) {
		      zooming_out = true;
		    }
	
		    // zooming has not stopped and zooming out is true
		    var zooming_stopped = false;
		    show_visible_area(cgm, zooming_stopped, zooming_out);
		  }
	
		  setTimeout(not_zooming, 50);
		  setTimeout(check_if_zooming_has_stopped, 100, cgm);
	
		  function check_if_zooming_has_stopped(cgm) {
		    var params = cgm.params;
	
		    var stop_attributes = check_zoom_stop_status(params);
	
		    if (stop_attributes === true) {
		      // wait and double check that zooming has stopped
		      setTimeout(run_when_zoom_stopped, 50, cgm);
		    }
		  }
			};
	
	/***/ },
	/* 91 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var utils = __webpack_require__(2);
	
		module.exports = function resize_label_val_bars(params) {
	
		  var zoom_info = params.zoom_info;
	
		  // resize label bars if necessary
		  if (utils.has(params.network_data.row_nodes[0], 'value')) {
		    d3.selectAll(params.root + ' .row_bars').attr('width', function (d) {
		      var inst_value = 0;
		      inst_value = params.labels.bar_scale_row(Math.abs(d.value)) / zoom_info.zoom_y;
		      return inst_value;
		    }).attr('x', function (d) {
		      var inst_value = 0;
		      inst_value = -params.labels.bar_scale_row(Math.abs(d.value)) / zoom_info.zoom_y;
		      return inst_value;
		    });
		  }
	
		  if (utils.has(params.network_data.col_nodes[0], 'value')) {
		    d3.selectAll(params.root + ' .col_bars').attr('width', function (d) {
		      var inst_value = 0;
		      if (d.value > 0) {
		        inst_value = params.labels.bar_scale_col(d.value) / zoom_info.zoom_x;
		      }
		      return inst_value;
		    });
		  }
			};
	
	/***/ },
	/* 92 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var constrain_font_size = __webpack_require__(83);
		var trim_text = __webpack_require__(82);
		var num_visible_labels = __webpack_require__(93);
		var toggle_grid_lines = __webpack_require__(85);
		var show_visible_area = __webpack_require__(70);
		var check_zoom_stop_status = __webpack_require__(94);
	
		module.exports = function run_when_zoom_stopped(cgm) {
	
		  var params = cgm.params;
	
		  var stop_attributes = check_zoom_stop_status(params);
	
		  if (stop_attributes === true) {
	
		    // ///////////////////////////////////////////////
		    // // zooming has stopped
		    // ///////////////////////////////////////////////
		    // console.log('\nZOOMING HAS ACTUALLY STOPPED\n============================');
		    // console.log(params.zoom_info.zoom_y)
	
		    _.each(['row', 'col'], function (inst_rc) {
	
		      d3.selectAll(params.root + ' .' + inst_rc + '_label_group').select('text').style('opacity', 1);
	
		      d3.selectAll(params.root + ' .' + inst_rc + '_cat_group').select('path').style('display', 'block');
		    });
	
		    show_visible_area(cgm, true);
	
		    d3.selectAll(params.viz.root_tips).style('display', 'block');
	
		    d3.selectAll(params.root + ' .row_label_group').select('text').style('display', 'none');
		    d3.selectAll(params.root + ' .row_label_group').select('text').style('display', 'block');
	
		    d3.select(params.root + ' .viz_svg').attr('stopped_zoom', 0);
	
		    d3.selectAll(params.root + ' .row_label_group').select('text').style('display', 'block');
		    d3.selectAll(params.root + ' .col_label_group').select('text').style('display', 'block');
	
		    toggle_grid_lines(params);
	
		    // reset x_offset
		    cgm.params.viz.x_offset = 0;
	
		    var max_labels_to_trim = 150;
		    // probably do not need
		    /////////////////////////
		    _.each(['row', 'col'], function (inst_rc) {
	
		      var inst_num_visible = num_visible_labels(params, inst_rc);
	
		      if (inst_num_visible < max_labels_to_trim) {
		        d3.selectAll(params.root + ' .' + inst_rc + '_label_group').each(function () {
		          trim_text(params, this, inst_rc);
		        });
		      }
		    });
	
		    text_patch();
	
		    constrain_font_size(params);
	
		    // this makes sure that the text is visible after zooming and trimming
		    // there is buggy behavior in chrome when zooming into large matrices
		    // I'm running it twice in quick succession
		    setTimeout(text_patch, 100);
		  }
	
		  function text_patch() {
	
		    _.each(['row', 'col'], function (inst_rc) {
	
		      d3.selectAll(params.root + ' .' + inst_rc + '_label_group').filter(function () {
		        return d3.select(this).style('display') != 'none';
		      }).select('text').style('font-size', function () {
		        var inst_fs = Number(d3.select(this).style('font-size').replace('px', ''));
		        return inst_fs;
		      });
		    });
		  }
			};
	
	/***/ },
	/* 93 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function num_visible_labels(params, inst_rc) {
	
		  // counting the number of visible labels, probably not necessary
	
		  var num_visible;
		  if (inst_rc === 'row') {
	
		    // initialize at high number
		    num_visible = 10000;
	
		    // only count visible rows if no downsampling
		    if (params.viz.ds_level === -1) {
		      num_visible = d3.selectAll(params.root + ' .row')[0].length;
		    }
		  } else if (inst_rc === 'col') {
	
		    num_visible = d3.selectAll(params.root + ' .' + inst_rc + '_label_text').filter(function () {
		      return d3.select(this).style('display') != 'none';
		    })[0].length;
		  }
	
		  return num_visible;
		};
	
	/***/ },
	/* 94 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function check_zoom_stop_status(params) {
	
		  var inst_zoom = Number(d3.select(params.root + ' .viz_svg').attr('is_zoom'));
	
		  var check_stop = Number(d3.select(params.root + ' .viz_svg').attr('stopped_zoom'));
	
		  var stop_attributes = false;
		  if (inst_zoom === 0 && check_stop != 0) {
		    stop_attributes = true;
		  }
	
		  return stop_attributes;
		};
	
	/***/ },
	/* 95 */
	/***/ function(module, exports) {
	
		"use strict";
	
		module.exports = function zoom_rules_y(params, zoom_info) {
	
		  var viz = params.viz;
		  // zoom in the x direction before zooming in the y direction
		  if (viz.zoom_ratio.y > 1) {
		    if (zoom_info.zoom_y < viz.zoom_ratio.y) {
		      zoom_info.trans_y = 0;
		      zoom_info.zoom_y = 1;
		    } else {
		      zoom_info.zoom_y = zoom_info.zoom_y / viz.zoom_ratio.y;
		    }
		  }
	
		  // calculate panning room available in the y direction
		  zoom_info.pan_room_y = (zoom_info.zoom_y - 1) * viz.clust.dim.height;
	
		  // console.log( 'pan_room_y: ' +  String(zoom_info.pan_room_y) + ' ' + String(-zoom_info.trans_y))
	
		  // no positive panning or panning more than pan_room
		  if (zoom_info.trans_y >= 0) {
		    zoom_info.trans_y = 0;
		    // console.log('y no positive panning\n\n')
		  } else if (zoom_info.trans_y <= -zoom_info.pan_room_y) {
		    zoom_info.trans_y = -zoom_info.pan_room_y;
		    // console.log('y restrict pan room \n\n')
		  }
	
		  return zoom_info;
		};
	
	/***/ },
	/* 96 */
	/***/ function(module, exports) {
	
		"use strict";
	
		module.exports = function zoom_rules_x(params, zoom_info) {
	
		  var viz = params.viz;
	
		  // zoom in the y direction before zooming in the x direction
		  if (viz.zoom_ratio.x > 1) {
	
		    if (zoom_info.zoom_x < viz.zoom_ratio.x) {
	
		      // remove this
		      // zoom_info.trans_x = - params.viz.clust.margin.left;
	
		      zoom_info.zoom_x = 1;
		    } else {
		      zoom_info.zoom_x = zoom_info.zoom_x / viz.zoom_ratio.x;
	
		      // console.log('********* zoom_x: ' + String(zoom_info.zoom_x))
	
		      // zoom_info.trans_x = zoom_info.trans_x + params.viz.x_offset;
		      // zoom_info.trans_x = zoom_info.trans_x * (params.zoom_info.zoom_x/params.zoom_info.zoom_y);
		    }
		  }
	
		  // calculate panning room available in the x direction
		  zoom_info.pan_room_x = (zoom_info.zoom_x - 1) * viz.clust.dim.width;
	
		  // console.log( 'pan_room_x: ' +  String(zoom_info.pan_room_x) + ' trans_x: ' + String(-zoom_info.trans_x))
	
		  // no positive panning or panning more than pan_room
		  if (zoom_info.trans_x > 0) {
		    zoom_info.trans_x = 0;
		    // console.log('no positive panning\n\n')
		  } else if (zoom_info.trans_x <= -zoom_info.pan_room_x) {
		    zoom_info.trans_x = -zoom_info.pan_room_x;
		    // console.log('******* restrict pan room\n\n')
		  }
	
		  return zoom_info;
		};
	
	/***/ },
	/* 97 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var two_translate_zoom = __webpack_require__(80);
	
		module.exports = function ini_doubleclick(cgm) {
	
		  var params = cgm.params;
		  // disable double-click zoom
		  d3.selectAll(params.viz.zoom_element).on('dblclick.zoom', null);
	
		  d3.select(params.viz.zoom_element).on('dblclick', function () {
		    two_translate_zoom(cgm, 0, 0, 1);
		  });
		};
	
	/***/ },
	/* 98 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function (params) {
	
		  // reset zoom
		  //////////////////////////////
		  var zoom_y = 1;
		  // var zoom_x = 1;
		  var pan_dx = 0;
		  var pan_dy = 0;
	
		  var half_height = params.viz.clust.dim.height / 2;
		  var center_y = -(zoom_y - 1) * half_height;
	
		  d3.select(params.root + ' .clust_group').attr('transform', 'translate(' + [0, 0 + center_y] + ')' + ' scale(' + 1 + ',' + zoom_y + ')' + 'translate(' + [pan_dx, pan_dy] + ')');
	
		  d3.select(params.root + ' .row_label_zoom_container').attr('transform', 'translate(' + [0, center_y] + ')' + ' scale(' + zoom_y + ',' + zoom_y + ')' + 'translate(' + [0, pan_dy] + ')');
	
		  d3.select(params.root + ' .row_cat_container').attr('transform', 'translate(' + [0, center_y] + ')' + ' scale(' + 1 + ',' + zoom_y + ')' + 'translate(' + [0, pan_dy] + ')');
	
		  d3.select(params.root + ' .row_dendro_container').attr('transform', 'translate(' + [0, center_y] + ')' + ' scale(' + zoom_y + ',' + zoom_y + ')' + 'translate(' + [params.viz.uni_margin / 2, pan_dy] + ')');
	
		  d3.select(params.root + ' .col_zoom_container').attr('transform', ' scale(' + 1 + ',' + 1 + ')' + 'translate(' + [pan_dx, 0] + ')');
	
		  d3.select(params.root + ' .col_cat_container').attr('transform', ' scale(' + 1 + ',' + 1 + ')' + 'translate(' + [pan_dx, 0] + ')');
	
		  d3.select(params.root + ' .col_dendro_container').attr('transform', ' scale(' + 1 + ',' + 1 + ')' + 'translate(' + [pan_dx, params.viz.uni_margin / 2] + ')');
	
		  // reset crop button zooming
		  d3.select(params.root + ' .row_dendro_icons_group').attr('transform', function () {
		    return 'translate(0,0) scale(1)';
		  });
	
		  d3.select(params.root + ' .row_dendro_icons_group').selectAll('path').attr('transform', function (d) {
		    var inst_x = 7;
		    var inst_y = d.pos_mid;
		    return 'translate(' + inst_x + ',' + inst_y + ') ' + 'scale(1, 1)';
		  });
			};
	
	/***/ },
	/* 99 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function resize_dendro(params, svg_group) {
		  var delay_info = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];
	
	
		  // resize dendrogram
		  ///////////////////
	
		  var delays = {};
	
		  if (delay_info === false) {
		    delays.run_transition = false;
		  } else {
		    delays = delay_info;
		  }
	
		  var duration = params.viz.duration;
		  var col_nodes = params.network_data.col_nodes;
		  var col_nodes_names = params.network_data.col_nodes_names;
	
		  var dendro_group;
		  if (delays.run_transition) {
	
		    dendro_group = svg_group.transition().delay(delays.update).duration(duration);
	
		    svg_group.selectAll('.col_cat_group')
		    // data binding needed for loss/gain of columns
		    .data(col_nodes, function (d) {
		      return d.name;
		    }).transition().delay(delays.update).duration(duration).attr('transform', function (d) {
		      var inst_index = _.indexOf(col_nodes_names, d.name);
		      return 'translate(' + params.viz.x_scale(inst_index) + ',0)';
		    });
	
		    svg_group.selectAll('.col_dendro_group')
		    // data binding needed for loss/gain of columns
		    .data(col_nodes, function (d) {
		      return d.name;
		    }).transition().delay(delays.update).duration(duration).attr('transform', function (d) {
		      var inst_index = _.indexOf(col_nodes_names, d.name);
		      return 'translate(' + params.viz.x_scale(inst_index) + ',0)';
		    });
		  } else {
	
		    dendro_group = svg_group;
	
		    svg_group.selectAll('.col_cat_group')
		    // data binding needed for loss/gain of columns
		    .data(col_nodes, function (d) {
		      return d.name;
		    }).attr('transform', function (d) {
		      var inst_index = _.indexOf(col_nodes_names, d.name);
		      return 'translate(' + params.viz.x_scale(inst_index) + ',0)';
		    });
	
		    d3.select(params.root).selectAll('.col_dendro_group')
		    // data binding needed for loss/gain of columns
		    .data(col_nodes, function (d) {
		      return d.name;
		    }).attr('transform', function (d) {
		      var inst_index = _.indexOf(col_nodes_names, d.name);
		      return 'translate(' + params.viz.x_scale(inst_index) + ',0)';
		    });
		  }
	
		  var i;
		  var inst_class;
	
		  _.each(['row', 'col'], function (inst_rc) {
	
		    var num_cats = params.viz.all_cats[inst_rc].length;
	
		    for (i = 0; i < num_cats; i++) {
		      inst_class = '.' + inst_rc + '_cat_rect_' + String(i);
	
		      if (inst_rc === 'row') {
		        dendro_group.selectAll(inst_class).attr('height', params.viz.y_scale.rangeBand());
		      } else {
		        dendro_group.selectAll(inst_class).attr('width', params.viz.x_scale.rangeBand());
		      }
		    }
		  });
	
		  // position row_dendro_outer_container
		  var x_offset = params.viz.clust.margin.left + params.viz.clust.dim.width;
		  var y_offset = params.viz.clust.margin.top;
		  var spillover_width = params.viz.dendro_room.row + params.viz.uni_margin;
	
		  d3.select(params.root + ' .viz_svg').select('row_dendro_outer_container').attr('transform', 'translate(' + x_offset + ',' + y_offset + ')');
	
		  d3.select(params.root + ' .row_dendro_outer_container').select('.row_dendro_spillover').attr('width', spillover_width + 'px').attr('height', params.viz.svg_dim.height);
	
		  x_offset = params.viz.clust.margin.left;
		  y_offset = params.viz.clust.margin.top + params.viz.clust.dim.height;
		  var spillover_height = params.viz.dendro_room.col + params.viz.uni_margin;
	
		  d3.select(params.root + ' .col_dendro_outer_container').select('.col_dendro_spillover').attr('width', params.viz.svg_dim.width).attr('height', spillover_height + 'px');
	
		  d3.select(params.root + ' .col_dendro_outer_container').select('.col_dendro_spillover_top').attr('width', params.viz.svg_dim.width).attr('height', params.viz.svg_dim.height).attr('transform', 'translate(0,' + params.viz.dendro_room.col + ')');
	
		  x_offset = params.viz.clust.margin.left;
		  y_offset = 0;
		  d3.select(params.root + ' .col_dendro_icons_container').attr('transform', 'translate(' + x_offset + ',' + y_offset + ')');
			};
	
	/***/ },
	/* 100 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function resize_super_labels(params, ini_svg_group) {
		  var delay_info = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];
	
	
		  var delays = {};
		  var duration = params.viz.duration;
		  var svg_group;
	
		  if (delay_info === false) {
		    delays.run_transition = false;
		  } else {
		    delays = delay_info;
		  }
	
		  if (delays.run_transition) {
		    svg_group = ini_svg_group.transition().delay(delays.update).duration(duration);
		  } else {
		    svg_group = ini_svg_group;
		  }
	
		  svg_group.select('.super_col_bkg').attr('height', params.viz.super_labels.dim.width + 'px').attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.grey_border_width + ')');
	
		  // super col title
		  svg_group.select('.super_col').attr('transform', function () {
		    var inst_x = params.viz.clust.dim.width / 2 + params.viz.norm_labels.width.row;
		    var inst_y = params.viz.super_labels.dim.width;
		    return 'translate(' + inst_x + ',' + inst_y + ')';
		  });
	
		  svg_group.select('.super_row_bkg').attr('width', params.viz.super_labels.dim.width + 'px').attr('transform', 'translate(' + params.viz.grey_border_width + ',0)');
	
		  svg_group.select('.super_row').attr('transform', function () {
		    var inst_x = params.viz.super_labels.dim.width;
		    var inst_y = params.viz.clust.dim.height / 2 + params.viz.norm_labels.width.col;
		    return 'translate(' + inst_x + ',' + inst_y + ')';
		  });
			};
	
	/***/ },
	/* 101 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function resize_spillover(viz, ini_svg_group) {
		  var delay_info = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];
	
	
		  var delays = {};
		  var duration = viz.duration;
		  var svg_group;
	
		  if (delay_info === false) {
		    delays.run_transition = false;
		  } else {
		    delays = delay_info;
		  }
	
		  if (delays.run_transition) {
		    svg_group = ini_svg_group.transition().delay(delays.update).duration(duration);
		  } else {
		    svg_group = ini_svg_group;
		  }
	
		  svg_group.select(viz.root + ' .right_slant_triangle').attr('transform', 'translate(' + viz.clust.dim.width + ',' + viz.norm_labels.width.col + ')');
	
		  svg_group.select(viz.root + ' .left_slant_triangle').attr('transform', 'translate(-1,' + viz.norm_labels.width.col + ')');
	
		  var rect_height = viz.clust.margin.top + viz.uni_margin / 5;
		  svg_group.select(viz.root + ' .top_left_white').attr('width', viz.clust.margin.left).attr('height', rect_height);
	
		  var tmp_left = viz.clust.margin.left + viz.clust.dim.width + viz.uni_margin + viz.dendro_room.row;
		  var tmp_top = viz.norm_labels.margin.top + viz.norm_labels.width.col;
	
		  svg_group.select(viz.root + ' .right_spillover_container').attr('transform', function () {
		    return 'translate(' + tmp_left + ', 0)';
		  });
	
		  tmp_top = viz.norm_labels.margin.top + viz.norm_labels.width.col;
	
		  svg_group.select(viz.root + ' .right_spillover_container rect').attr('transform', function () {
		    return 'translate( 0,' + tmp_top + ')';
		  });
	
		  svg_group.select(viz.root + ' .right_spillover').attr('height', viz.svg_dim.height + 'px');
	
		  // resize dendro spillovers
		  var x_offset = viz.clust.margin.left + viz.clust.dim.width;
		  var y_offset = tmp_top;
		  var tmp_width = viz.dendro_room.row + viz.uni_margin;
		  var tmp_height = viz.cat_room.col + viz.uni_margin;
		  d3.select(viz.root + ' .dendro_row_spillover').attr('width', tmp_width).attr('height', tmp_height).attr('transform', function () {
		    return 'translate(' + x_offset + ',' + y_offset + ')';
		  });
	
		  // hide spillover left top of col dendrogram
		  x_offset = 0;
		  y_offset = viz.clust.margin.top + viz.clust.dim.height;
		  tmp_width = viz.clust.margin.left;
		  tmp_height = viz.clust.dim.height * 10;
	
		  svg_group.select('.dendro_col_spillover').attr('width', tmp_width).attr('height', tmp_height).attr('transform', function () {
		    return 'translate(' + x_offset + ',' + y_offset + ')';
		  });
	
		  x_offset = viz.clust.margin.left + viz.clust.dim.width;
		  y_offset = viz.clust.margin.top + viz.clust.dim.height;
		  tmp_width = viz.cat_room.col + viz.clust.dim.width;
		  tmp_height = viz.cat_room.row + viz.uni_margin;
	
		  svg_group.select('.dendro_corner_spillover').attr('width', tmp_width).attr('height', tmp_height).attr('transform', function () {
		    return 'translate(' + x_offset + ',' + y_offset + ')';
		  });
	
		  x_offset = viz.clust.margin.left + viz.clust.dim.width + viz.uni_margin;
		  y_offset = viz.norm_labels.margin.top + viz.norm_labels.width.col + 2.5 * viz.uni_margin;
		  var extra_x_room = 2.75;
		  var extra_y_room = 1.2;
	
		  // reposition category superlabels
		  if (viz.show_categories.col) {
	
		    d3.selectAll(viz.root + ' .col_cat_super').attr('transform', function (d) {
		      var inst_cat = parseInt(d.split('-')[1], 10);
		      var inst_y = y_offset + extra_y_room * viz.cat_room.symbol_width * inst_cat;
		      return 'translate(' + x_offset + ',' + inst_y + ')';
		    });
		  }
	
		  if (viz.show_categories.row) {
		    d3.select(viz.root + ' .row_cat_label_container').attr('transform', function () {
		      x_offset = viz.norm_labels.margin.left + viz.norm_labels.width.row + viz.cat_room.symbol_width + extra_x_room * viz.uni_margin;
		      y_offset = viz.clust.margin.top - viz.uni_margin;
		      return 'translate(' + x_offset + ',' + y_offset + ') rotate(-90)';
		    });
		  }
	
		  // white border bottom - prevent clustergram from hitting border
		  if (viz.show_dendrogram) {
		    y_offset = viz.clust.margin.top + viz.clust.dim.height + viz.dendro_room.col - 2 * viz.uni_margin;
		  } else {
		    y_offset = viz.clust.margin.top + viz.clust.dim.height;
		  }
	
		  d3.select(viz.root + ' .bottom_spillover_container').attr('transform', function () {
		    // shift up enough to show the entire border width
		    return 'translate(0,' + y_offset + ')';
		  });
	
		  svg_group.select(viz.root + ' .bottom_spillover').attr('width', viz.svg_dim.width).attr('height', 2 * viz.svg_dim.height);
	
		  var inst_height = viz.cat_room.col + 1.5 * viz.uni_margin;
		  // white rect to cover excess labels
		  d3.select(viz.viz_svg + ' .top_right_white').attr('fill', viz.background_color).attr('width', 2 * viz.clust.dim.width).attr('height', inst_height).attr('transform', function () {
		    var tmp_left = viz.clust.margin.left + viz.clust.dim.width;
		    var tmp_top = viz.norm_labels.width.col + viz.norm_labels.margin.top - viz.uni_margin;
		    return 'translate(' + tmp_left + ', ' + tmp_top + ')';
		  });
			};
	
	/***/ },
	/* 102 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function resize_borders(params, svg_group) {
	
		  // left border
		  svg_group.select('.left_border').attr('width', params.viz.grey_border_width).attr('height', params.viz.svg_dim.height).attr('transform', 'translate(0,0)');
	
		  // right border
		  svg_group.select('.right_border').attr('width', params.viz.grey_border_width).attr('height', params.viz.svg_dim.height).attr('transform', function () {
		    var inst_offset = params.viz.svg_dim.width - params.viz.grey_border_width;
		    return 'translate(' + inst_offset + ',0)';
		  });
	
		  // top border
		  svg_group.select('.top_border').attr('width', params.viz.svg_dim.width).attr('height', params.viz.grey_border_width).attr('transform', function () {
		    var inst_offset = 0;
		    return 'translate(' + inst_offset + ',0)';
		  });
	
		  // bottom border
		  svg_group.select('.bottom_border').attr('width', params.viz.svg_dim.width).attr('height', params.viz.grey_border_width).attr('transform', function () {
		    var inst_offset = params.viz.svg_dim.height - params.viz.grey_border_width;
		    return 'translate(0,' + inst_offset + ')';
		  });
			};
	
	/***/ },
	/* 103 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function resize_row_labels(params, ini_svg_group) {
		  var delay_info = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];
	
	
		  var delays = {};
		  var duration = params.viz.duration;
		  var svg_group;
	
		  var row_nodes = params.network_data.row_nodes;
		  var row_nodes_names = params.network_data.row_nodes_names;
	
		  if (delay_info === false) {
		    delays.run_transition = false;
		  } else {
		    delays = delay_info;
		  }
	
		  if (delays.run_transition) {
	
		    ini_svg_group.selectAll('.row_label_group')
		    // data bind necessary for loss/gain of rows
		    .data(row_nodes, function (d) {
		      return d.name;
		    }).transition().delay(delays.update).duration(duration).attr('transform', function (d) {
		      var inst_index = _.indexOf(row_nodes_names, d.name);
		      return 'translate(0,' + params.viz.y_scale(inst_index) + ')';
		    }).attr('y', params.viz.rect_height * 0.5 + params.labels.default_fs_row * 0.35);
	
		    svg_group = ini_svg_group.transition().delay(delays.update).duration(duration);
		  } else {
	
		    ini_svg_group.selectAll('.row_label_group')
		    // data bind necessary for loss/gain of rows
		    .data(row_nodes, function (d) {
		      return d.name;
		    }).attr('transform', function (d) {
		      var inst_index = _.indexOf(row_nodes_names, d.name);
		      return 'translate(0,' + params.viz.y_scale(inst_index) + ')';
		    }).attr('y', params.viz.rect_height * 0.5 + params.labels.default_fs_row * 0.35);
	
		    svg_group = ini_svg_group;
		  }
	
		  svg_group.select(params.root + ' .row_container').attr('transform', 'translate(' + params.viz.norm_labels.margin.left + ',' + params.viz.clust.margin.top + ')');
	
		  svg_group.select(params.root + ' .row_container').select('.white_bars').attr('width', params.viz.label_background.row).attr('height', 30 * params.viz.clust.dim.height + 'px');
	
		  svg_group.select(params.root + ' .row_container').select('.row_label_container').attr('transform', 'translate(' + params.viz.norm_labels.width.row + ',0)');
			};
	
	/***/ },
	/* 104 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function resize_highlights(params) {
	
		  // reposition tile highlight
		  ////////////////////////////////
	
		  var rel_width_hlight = 6;
		  // var opacity_hlight = 0.85;
		  var hlight_width = rel_width_hlight * params.viz.border_width.x;
		  var hlight_height = rel_width_hlight * params.viz.border_width.y;
	
		  // top highlight
		  d3.select(params.root + ' .top_hlight').attr('width', params.viz.rect_width).attr('height', hlight_height).attr('transform', function () {
		    return 'translate(' + params.viz.x_scale(params.matrix.click_hlight_x) + ',0)';
		  });
	
		  // left highlight
		  d3.select(params.root + ' .left_hlight').attr('width', hlight_width).attr('height', params.viz.rect_width - hlight_height * 0.99).attr('transform', function () {
		    return 'translate(' + params.viz.x_scale(params.matrix.click_hlight_x) + ',' + hlight_height * 0.99 + ')';
		  });
	
		  // right highlight
		  d3.select(params.root + ' .right_hlight').attr('width', hlight_width).attr('height', params.viz.rect_height - hlight_height * 0.99).attr('transform', function () {
		    var tmp_translate = params.viz.x_scale(params.matrix.click_hlight_x) + params.viz.rect_width - hlight_width;
		    return 'translate(' + tmp_translate + ',' + hlight_height * 0.99 + ')';
		  });
	
		  // bottom highlight
		  d3.select(params.root + ' .bottom_hlight').attr('width', function () {
		    return params.viz.rect_width - 1.98 * hlight_width;
		  }).attr('height', hlight_height).attr('transform', function () {
		    var tmp_translate_x = params.viz.x_scale(params.matrix.click_hlight_x) + hlight_width * 0.99;
		    var tmp_translate_y = params.viz.rect_height - hlight_height;
		    return 'translate(' + tmp_translate_x + ',' + tmp_translate_y + ')';
		  });
	
		  // resize row highlight
		  /////////////////////////
		  d3.select(params.root + ' .row_top_hlight').attr('width', params.viz.svg_dim.width).attr('height', hlight_height);
	
		  d3.select(params.root + ' .row_bottom_hlight').attr('width', params.viz.svg_dim.width).attr('height', hlight_height).attr('transform', function () {
		    var tmp_translate_y = params.viz.rect_height - hlight_height;
		    return 'translate(0,' + tmp_translate_y + ')';
		  });
	
		  // resize col highlight
		  /////////////////////////
		  d3.select(params.root + ' .col_top_hlight').attr('width', params.viz.clust.dim.height).attr('height', hlight_width).attr('transform', function () {
		    var tmp_translate_y = 0;
		    var tmp_translate_x = -(params.viz.clust.dim.height + params.viz.cat_room.col + params.viz.uni_margin);
		    return 'translate(' + tmp_translate_x + ',' + tmp_translate_y + ')';
		  });
	
		  d3.select(params.root + ' .col_bottom_hlight').attr('width', params.viz.clust.dim.height).attr('height', hlight_width).attr('transform', function () {
		    var tmp_translate_y = params.viz.rect_width - hlight_width;
		    var tmp_translate_x = -(params.viz.clust.dim.height + params.viz.cat_room.col + params.viz.uni_margin);
		    return 'translate(' + tmp_translate_x + ',' + tmp_translate_y + ')';
		  });
			};
	
	/***/ },
	/* 105 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function resize_row_viz(params, ini_svg_group) {
		  var delay_info = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];
	
	
		  var delays = {};
		  var duration = params.viz.duration;
		  var svg_group;
	
		  if (delay_info === false) {
		    delays.run_transition = false;
		  } else {
		    delays = delay_info;
		  }
	
		  if (delays.run_transition) {
		    svg_group = ini_svg_group.transition().delay(delays.update).duration(duration);
		  } else {
		    svg_group = ini_svg_group;
		  }
	
		  svg_group.select('.row_cat_outer_container').attr('transform', 'translate(' + params.viz.norm_labels.width.row + ',0)').select('white_bars').attr('width', params.viz.cat_room.row + 'px').attr('height', function () {
		    var inst_height = params.viz.clust.dim.height;
		    return inst_height;
		  });
	
		  var x_offset = params.viz.clust.margin.left + params.viz.clust.dim.width;
		  var y_offset = params.viz.clust.margin.top;
		  svg_group.select('.row_dendro_outer_container').attr('transform', 'translate(' + x_offset + ',' + y_offset + ')');
	
		  // !! tmp resize col dendro
		  x_offset = params.viz.clust.margin.left;
		  y_offset = params.viz.clust.margin.top + params.viz.clust.dim.height;
	
		  svg_group.select(' .col_dendro_outer_container').attr('transform', function () {
		    return 'translate(' + x_offset + ',' + y_offset + ')';
		  });
			};
	
	/***/ },
	/* 106 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function (params, ini_svg_group) {
		  var delay_info = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];
	
	
		  var delays = {};
		  var duration = params.viz.duration;
		  var svg_group;
	
		  var col_nodes = params.network_data.col_nodes;
		  var col_nodes_names = params.network_data.col_nodes_names;
	
		  if (delay_info === false) {
		    delays.run_transition = false;
		  } else {
		    delays = delay_info;
		  }
	
		  if (delays.run_transition) {
		    svg_group = ini_svg_group.transition().delay(delays.update).duration(duration);
	
		    ini_svg_group.selectAll('.col_label_text').data(col_nodes, function (d) {
		      return d.name;
		    }).transition().delay(delays.update).duration(duration).attr('transform', function (d) {
		      var inst_index = _.indexOf(col_nodes_names, d.name);
		      return 'translate(' + params.viz.x_scale(inst_index) + ', 0) rotate(-90)';
		    });
		  } else {
		    svg_group = ini_svg_group;
	
		    ini_svg_group.selectAll('.col_label_text').data(col_nodes, function (d) {
		      return d.name;
		    }).attr('transform', function (d) {
		      var inst_index = _.indexOf(col_nodes_names, d.name);
		      return 'translate(' + params.viz.x_scale(inst_index) + ', 0) rotate(-90)';
		    });
		  }
	
		  // offset click group column label
		  var x_offset_click = params.viz.x_scale.rangeBand() / 2 + params.viz.border_width.x;
	
		  svg_group.select(params.root + ' .col_container').attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.norm_labels.margin.top + ')');
	
		  svg_group.select(params.root + ' .col_container').select('.white_bars').attr('width', 30 * params.viz.clust.dim.width + 'px').attr('height', params.viz.label_background.col);
	
		  svg_group.select(params.root + ' .col_container').select('.col_label_outer_container').attr('transform', 'translate(0,' + params.viz.norm_labels.width.col + ')');
	
		  svg_group.selectAll('.col_label_group').attr('transform', 'translate(' + params.viz.x_scale.rangeBand() / 2 + ',' + x_offset_click + ') rotate(45)');
	
		  svg_group.selectAll('.col_label_group').select('text').attr('y', params.viz.x_scale.rangeBand() * 0.60).attr('dx', 2 * params.viz.border_width.x);
			};
	
	/***/ },
	/* 107 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var utils = __webpack_require__(2);
	
		module.exports = function resize_col_text(params, svg_group) {
		  svg_group.selectAll('.col_label_group').select('text').style('font-size', params.labels.default_fs_col + 'px').text(function (d) {
		    return utils.normal_name(d);
		  });
	
		  svg_group.selectAll('.col_label_group').each(function () {
		    d3.select(this).select('text')[0][0].getBBox();
		  });
		};
	
	/***/ },
	/* 108 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var col_viz_aid_triangle = __webpack_require__(74);
	
		module.exports = function resize_col_triangle(params, ini_svg_group) {
		  var delay_info = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];
	
	
		  // resize column triangle
		  var ini_triangle_group = ini_svg_group.selectAll('.col_label_group').select('path');
	
		  var delays = {};
		  var duration = params.viz.duration;
	
		  if (delay_info === false) {
		    delays.run_transition = false;
		  } else {
		    delays = delay_info;
		  }
	
		  var triangle_group;
		  if (delays.run_transition) {
		    triangle_group = ini_triangle_group.transition().delay(delays.update).duration(duration);
		  } else {
		    triangle_group = ini_triangle_group;
		  }
	
		  triangle_group.attr('d', function () {
		    return col_viz_aid_triangle(params);
		  }).attr('fill', '#eee');
			};
	
	/***/ },
	/* 109 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var utils = __webpack_require__(2);
	
		module.exports = function resize_col_hlight(params, svg_group) {
		  var delay_info = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];
	
	
		  var delays = {};
		  // var duration = params.viz.duration;
	
		  if (delay_info === false) {
		    delays.run_transition = false;
		  } else {
		    delays = delay_info;
		  }
	
		  if (utils.has(params.network_data.col_nodes[0], 'value')) {
	
		    svg_group.selectAll('.col_bars').data(params.network_data.col_nodes, function (d) {
		      return d.name;
		    }).attr('width', function (d) {
	
		      var inst_value = 0;
	
		      if (d.value > 0) {
		        inst_value = params.labels.bar_scale_col(d.value);
		      }
		      return inst_value;
		    })
		    // rotate labels - reduce width if rotating
		    .attr('height', params.viz.rect_width * 0.66);
		  }
			};
	
	/***/ },
	/* 110 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var get_svg_dim = __webpack_require__(19);
		var calc_clust_height = __webpack_require__(22);
		var calc_clust_width = __webpack_require__(21);
		var calc_default_fs = __webpack_require__(31);
		var calc_zoom_switching = __webpack_require__(30);
	
		module.exports = function recalc_params_for_resize(params) {
	
		  // Resetting some visualization parameters
		  params = get_svg_dim(params);
		  params.viz = calc_clust_width(params.viz);
		  params.viz = calc_clust_height(params.viz);
	
		  if (params.sim_mat) {
		    if (params.viz.clust.dim.width <= params.viz.clust.dim.height) {
		      params.viz.clust.dim.height = params.viz.clust.dim.width;
		    } else {
		      params.viz.clust.dim.width = params.viz.clust.dim.height;
		    }
		  }
	
		  params.viz = calc_zoom_switching(params.viz);
	
		  // redefine x_scale and y_scale rangeBands
		  params.viz.x_scale.rangeBands([0, params.viz.clust.dim.width]);
		  params.viz.y_scale.rangeBands([0, params.viz.clust.dim.height]);
	
		  // redefine border width
		  params.viz.border_width.x = params.viz.x_scale.rangeBand() / params.viz.border_fraction;
		  params.viz.border_width.y = params.viz.y_scale.rangeBand() / params.viz.border_fraction;
	
		  params.viz.rect_width = params.viz.x_scale.rangeBand() - params.viz.border_width.x;
		  params.viz.rect_height = params.viz.y_scale.rangeBand() - params.viz.border_width.y;
	
		  // for downsampling
		  if (params.viz.ds != null) {
		    for (var i; i < params.viz.ds.length; i++) {
		      params.viz.ds[i].rect_height = params.viz.ds[i].y_scale.rangeBand() - params.viz.border_width.y;
		    }
		  }
	
		  // recalc downsampled y_scale if necessary
		  if (params.viz.ds_num_levels > 0) {
		    _.each(params.viz.ds, function (inst_ds) {
	
		      // y_scale
		      /////////////////////////
		      inst_ds.y_scale = d3.scale.ordinal().rangeBands([0, params.viz.clust.dim.height]);
		      inst_ds.y_scale.domain(d3.range(inst_ds.num_rows + 1));
	
		      inst_ds.rect_height = inst_ds.y_scale.rangeBand() - params.viz.border_width.y;
		    });
		  }
	
		  // redefine zoom extent
		  params.viz.square_zoom = params.viz.norm_labels.width.col / (params.viz.rect_width / 2);
	
		  // the default font sizes are set here
		  params = calc_default_fs(params);
	
		  return params;
		};
	
	/***/ },
	/* 111 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var draw_up_tile = __webpack_require__(43);
		var draw_dn_tile = __webpack_require__(44);
		var fine_position_tile = __webpack_require__(47);
	
		module.exports = function resize_row_tiles(params, svg_group) {
	
		  var row_nodes_names = params.network_data.row_nodes_names;
	
		  if (params.viz.ds_level === -1) {
	
		    // no downsampling
		    ///////////////////////
	
		    // resize rows
		    svg_group.selectAll('.row').attr('transform', function (d) {
		      var tmp_index = _.indexOf(row_nodes_names, d.name);
		      var inst_y = params.viz.y_scale(tmp_index);
		      return 'translate(0,' + inst_y + ')';
		    });
	
		    // resize tiles
		    svg_group.selectAll('.row').selectAll('.tile').attr('transform', function (d) {
		      return fine_position_tile(params, d);
		    }).attr('width', params.viz.rect_width).attr('height', params.viz.rect_height);
	
		    // resize tile_up
		    svg_group.selectAll('.row').selectAll('.tile_up').attr('d', function () {
		      return draw_up_tile(params);
		    }).attr('transform', function (d) {
		      return fine_position_tile(params, d);
		    });
	
		    // resize tile_dn
		    svg_group.selectAll('.row').selectAll('.tile_dn').attr('d', function () {
		      return draw_dn_tile(params);
		    }).attr('transform', function (d) {
		      return fine_position_tile(params, d);
		    });
		  } else {
	
		    // downsampling
		    /////////////////////////
	
		    var ds_level = params.viz.ds_level;
		    var row_class = '.ds' + String(ds_level) + '_row';
		    var ds_rect_height = params.viz.ds[ds_level].rect_height;
	
		    svg_group.selectAll(row_class).attr('transform', function (d) {
		      var inst_y = params.viz.ds[ds_level].y_scale(d.row_index);
		      return 'translate(0,' + inst_y + ')';
		    });
	
		    // reset ds-tiles
		    svg_group.selectAll(row_class).selectAll('.tile').attr('transform', function (d) {
		      return fine_position_tile(params, d);
		    }).attr('width', params.viz.rect_width).attr('height', ds_rect_height);
		  }
			};
	
	/***/ },
	/* 112 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var calc_val_max = __webpack_require__(23);
	
		module.exports = function resize_label_bars(cgm, svg_group) {
		  var params = cgm.params;
	
		  // // set bar scale
		  // var val_max = Math.abs(_.max( params.network_data.row_nodes, function(d) {
		  //   return Math.abs(d.value);
		  // } ).value) ;
	
		  // params.labels.bar_scale_row = d3.scale
		  //   .linear()
		  //   .domain([0, val_max])
		  //   .range([0, params.viz.norm_labels.width.row ]);
	
		  params = calc_val_max(params);
	
		  svg_group.selectAll('.row_bars')
		  // .transition().delay(delays.update).duration(duration)
		  .attr('width', function (d) {
		    var inst_value = 0;
		    inst_value = params.labels.bar_scale_row(Math.abs(d.value));
		    return inst_value;
		  }).attr('x', function (d) {
		    var inst_value = 0;
		    inst_value = -params.labels.bar_scale_row(Math.abs(d.value));
		    return inst_value;
		  }).attr('height', params.viz.y_scale.rangeBand());
			};
	
	/***/ },
	/* 113 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function position_play_button(params) {
	
		  var clust_transform = d3.select(params.root + ' .clust_container').attr('transform');
	
		  var clust_x = Number(clust_transform.split('(')[1].split(',')[0]);
		  var clust_y = Number(clust_transform.split(',')[1].replace(')', ''));
		  var trans_x = clust_x + params.viz.clust.dim.width / 2;
		  var trans_y = clust_y + params.viz.clust.dim.height / 2;
	
		  d3.select(params.root + ' .play_button').attr('transform', function () {
		    return 'translate(' + trans_x + ',' + trans_y + ')';
		  });
			};
	
	/***/ },
	/* 114 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function position_svg_dendro_slider(cgm, inst_rc) {
	
		  var viz = cgm.params.viz;
		  var tmp_left;
		  var tmp_top;
		  if (inst_rc === 'row') {
	
		    // row dendrogram
		    ///////////////////////
	
		    // keep slider near clustergram
		    var max_room = viz.svg_dim.width - 3 * viz.uni_margin;
	
		    // position close to row dendrogram trapezoids
		    tmp_left = viz.clust.margin.left + viz.clust.dim.width + 5 * viz.dendro_room.row;
	
		    if (tmp_left > max_room) {
		      tmp_left = max_room;
		    }
	
		    tmp_top = viz.clust.margin.top + 3 * viz.uni_margin;
		  } else {
	
		    // column dendrogram
		    ///////////////////////
		    tmp_left = 2 * viz.uni_margin;
		    // tmp_top =  viz.svg_dim.height - 2.5 * viz.uni_margin;
		    tmp_top = viz.clust.margin.top + viz.clust.dim.height + viz.dendro_room.col - 2 * viz.uni_margin;
		  }
	
		  d3.select(cgm.params.root + ' .' + inst_rc + '_slider_group').attr('transform', function () {
		    var inst_translation;
		    if (inst_rc === 'row') {
		      inst_translation = 'translate(' + tmp_left + ',' + tmp_top + ')';
		    } else {
		      inst_translation = 'translate(' + tmp_left + ',' + tmp_top + '), rotate(-90)';
		    }
		    return inst_translation;
		  }).style('opacity', 1);
			};
	
	/***/ },
	/* 115 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function grid_lines_viz(params) {
		  var duration = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];
	
	
		  var delay = 0;
		  if (duration > 0) {
		    delay = 2000;
		  }
	
		  var horz_lines = d3.selectAll(params.root + ' .horz_lines');
		  var vert_lines = d3.selectAll(params.root + ' .vert_lines');
	
		  horz_lines.style('opacity', 0).attr('transform', function (d) {
		    var inst_index = d.row_index;
		    var inst_trans = params.viz.y_scale(inst_index);
		    return 'translate(  0,' + inst_trans + ') rotate(0)';
		  }).transition().duration(duration).delay(delay).style('opacity', 1);
	
		  horz_lines.append('line').attr('x1', 0).attr('x2', params.viz.clust.dim.width).style('stroke-width', function () {
		    var inst_width = params.viz.border_width.y;
		    return inst_width + 'px';
		  });
	
		  vert_lines.style('opacity', 0).attr('transform', function (d) {
		    var inst_index = d.col_index;
		    var inst_trans = params.viz.x_scale(inst_index);
		    return 'translate(' + inst_trans + ') rotate(-90)';
		  }).transition().duration(duration).delay(delay).style('opacity', 1);
	
		  vert_lines.append('line').attr('x1', 0).attr('x2', -params.viz.clust.dim.height).style('stroke-width', function () {
		    var inst_width = params.viz.border_width.x;
		    return inst_width + 'px';
		  });
			};
	
	/***/ },
	/* 116 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var cat_tooltip_text = __webpack_require__(117);
		var d3_tip_custom = __webpack_require__(48);
		var reset_cat_opacity = __webpack_require__(118);
		var ini_cat_opacity = __webpack_require__(119);
		var click_filter_cats = __webpack_require__(120);
		var get_cat_names = __webpack_require__(121);
	
		module.exports = function make_col_cat(cgm) {
	
		  var params = cgm.params;
	
		  // make or reuse outer container
		  if (d3.select(params.root + ' .col_cat_outer_container').empty()) {
		    d3.select(params.root + ' .col_container').append('g').attr('class', 'col_cat_outer_container').attr('transform', function () {
		      var inst_offset = params.viz.norm_labels.width.col + 2;
		      return 'translate(0,' + inst_offset + ')';
		    }).append('g').attr('class', 'col_cat_container');
		  } else {
		    d3.select(params.root + ' .col_container').select('col_cat_outer_container').attr('transform', function () {
		      var inst_offset = params.viz.norm_labels.width.col + 2;
		      return 'translate(0,' + inst_offset + ')';
		    });
		  }
	
		  // remove old col_cat_tips
		  d3.selectAll(params.viz.root_tips + '_col_cat_tip').remove();
	
		  // d3-tooltip
		  var cat_tip = d3_tip_custom().attr('class', function () {
		    var root_tip_selector = params.viz.root_tips.replace('.', '');
		    var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_col_cat_tip';
		    return class_string;
		  }).direction('s').offset([5, 0]).style('display', 'none').html(function (d) {
		    return cat_tooltip_text(params, d, this, 'col');
		  });
	
		  // append groups - each will hold classification rects
		  d3.select(params.root + ' .col_cat_container').selectAll('g').data(params.network_data.col_nodes, function (d) {
		    return d.name;
		  }).enter().append('g').attr('class', 'col_cat_group').attr('transform', function (d) {
		    var inst_index = _.indexOf(params.network_data.col_nodes_names, d.name);
		    // return 'translate(' + params.viz.x_scale(d.col_index) + ',0)';
		    return 'translate(' + params.viz.x_scale(inst_index) + ',0)';
		  });
	
		  d3.select(params.root + ' .col_cat_container').selectAll('.col_cat_group').call(cat_tip);
	
		  // add category rects
		  d3.selectAll(params.root + ' .col_cat_group').each(function () {
	
		    var inst_selection = this;
		    var cat_rect;
	
		    _.each(params.viz.all_cats.col, function (inst_cat) {
	
		      var inst_num = parseInt(inst_cat.split('-')[1], 10);
		      var cat_rect_class = 'col_cat_rect_' + String(inst_num);
	
		      if (d3.select(inst_selection).select('.' + cat_rect_class).empty()) {
		        cat_rect = d3.select(inst_selection).append('rect').attr('class', cat_rect_class).attr('cat', inst_cat).attr('transform', function () {
		          var cat_room = params.viz.cat_room.symbol_width + params.viz.cat_room.separation;
		          var inst_shift = inst_num * cat_room;
		          return 'translate(0,' + inst_shift + ')';
		        }).on('click', function (d) {
	
		          if (d3.select(this).classed('cat_strings')) {
	
		            if (d3.event.shiftKey === true) {
		              click_filter_cats_db(cgm, d, this, 'col');
		            } else {
	
		              var found_names = get_cat_names(params, d, this, 'col');
	
		              $(params.root + ' .dendro_info').modal('toggle');
		              var group_string = found_names.join(', ');
		              d3.select(params.root + ' .dendro_info input').attr('value', group_string);
		            }
		          }
		        });
		      } else {
		        cat_rect = d3.select(inst_selection).select('.' + cat_rect_class);
		      }
	
		      cat_rect.attr('width', params.viz.x_scale.rangeBand()).attr('height', params.viz.cat_room.symbol_width).style('fill', function (d) {
		        var cat_name = d[inst_cat];
		        var inst_color = params.viz.cat_colors.col[inst_cat][cat_name];
		        return inst_color;
		      }).on('mouseover', cat_tip.show).on('mouseout', function () {
		        cat_tip.hide(this);
		        reset_cat_opacity(params);
		        d3.select(this).classed('hovering', false);
	
		        d3.selectAll('.d3-tip').style('display', 'none');
		      });
	
		      ini_cat_opacity(params.viz, 'col', cat_rect, inst_cat);
		    });
		  });
	
		  var click_filter_cats_db = _.debounce(click_filter_cats, 1500);
			};
	
	/***/ },
	/* 117 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var get_cat_title = __webpack_require__(77);
	
		module.exports = function cat_tooltip_text(params, inst_data, inst_selection, inst_rc) {
	
		  d3.selectAll(params.viz.root_tips + '_col_cat_tip').style('display', 'block');
	
		  d3.selectAll(params.viz.root_tips + '_row_cat_tip').style('display', 'block');
	
		  // category index
		  var inst_cat = d3.select(inst_selection).attr('cat');
		  var cat_title = get_cat_title(params.viz, inst_cat, inst_rc);
		  var cat_name = inst_data[inst_cat];
	
		  if (typeof cat_name === 'string') {
		    if (cat_name.indexOf(': ') >= 0) {
		      cat_name = cat_name.split(': ')[1];
		    }
		  }
	
		  var cat_string = cat_title + ': ' + cat_name;
	
		  d3.select(inst_selection).classed('hovering', true);
	
		  setTimeout(highlight_categories, 500);
	
		  return cat_string;
	
		  function highlight_categories() {
	
		    var run_highlighting = false;
	
		    if (d3.select(inst_selection).classed('hovering')) {
	
		      var node_types = [inst_rc];
	
		      if (params.viz.sim_mat) {
		        node_types = ['row', 'col'];
		      }
	
		      _.each(node_types, function (tmp_rc) {
	
		        // only highlight string categories that are not 'false' categories
		        if (typeof cat_name === 'string') {
		          if (cat_name.indexOf('Not ') < 0 && cat_name != 'false') {
		            run_highlighting = true;
		          }
		        }
	
		        if (run_highlighting) {
	
		          d3.selectAll(params.root + ' .' + tmp_rc + '_cat_group').selectAll('rect').style('opacity', function (d) {
	
		            var inst_opacity = d3.select(this).style('opacity');
	
		            if (d3.select(this).classed('cat_strings') && d3.select(this).classed('filtered_cat') === false) {
	
		              var tmp_name;
		              var tmp_cat = d3.select(this).attr('cat');
	
		              if (d[tmp_cat].indexOf(': ') >= 0) {
		                tmp_name = d[tmp_cat].split(': ')[1];
		              } else {
		                tmp_name = d[tmp_cat];
		              }
	
		              if (tmp_cat === inst_cat && tmp_name === cat_name) {
		                inst_opacity = params.viz.cat_colors.active_opacity;
		              } else {
		                inst_opacity = params.viz.cat_colors.opacity / 4;
		              }
		            }
	
		            return inst_opacity;
		          });
		        }
		      });
		    }
		  }
			};
	
	/***/ },
	/* 118 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function reset_cat_opacity(params) {
	
		  _.each(['row', 'col'], function (inst_rc) {
	
		    d3.selectAll(params.root + ' .' + inst_rc + '_cat_group').selectAll('rect').style('opacity', function () {
	
		      var inst_opacity = d3.select(this).style('opacity');
	
		      if (d3.select(this).classed('cat_strings') && d3.select(this).classed('filtered_cat') === false) {
		        inst_opacity = params.viz.cat_colors.opacity;
		      }
	
		      return inst_opacity;
		    });
		  });
			};
	
	/***/ },
	/* 119 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function ini_cat_opacity(viz, inst_rc, cat_rect, inst_cat) {
		  var updating = arguments.length <= 4 || arguments[4] === undefined ? false : arguments[4];
	
	
		  // debugger;
	
		  var super_string = ': ';
		  var inst_type = viz.cat_info[inst_rc][inst_cat].type;
	
		  // set opacity based on string or value cats
		  if (inst_type === 'cat_strings') {
	
		    // optionally have categories transition in
		    if (updating) {
		      cat_rect.classed('cat_strings', true).style('opacity', 0).transition().duration(1000).style('opacity', viz.cat_colors.opacity);
		    } else {
		      // opacity is fixed
		      cat_rect.classed('cat_strings', true).style('opacity', viz.cat_colors.opacity);
		    }
		  } else {
	
		    // opacity varies based on value
		    cat_rect.classed('cat_values', true).style('opacity', function (d) {
	
		      var unprocessed_val = d[inst_cat];
	
		      var cat_value = get_cat_value(unprocessed_val);
	
		      return viz.cat_info[inst_rc][inst_cat].cat_scale(Math.abs(cat_value));
		    }).style('fill', function (d) {
		      var inst_color;
	
		      var cat_value = get_cat_value(d[inst_cat]);
	
		      // get positive and negative colors
		      if (cat_value > 0) {
		        inst_color = viz.cat_value_colors[0];
		      } else {
		        inst_color = viz.cat_value_colors[1];
		      }
	
		      return inst_color;
		    });
		  }
	
		  function get_cat_value(unprocessed_value) {
		    if (typeof unprocessed_value === 'string') {
	
		      if (unprocessed_value.indexOf(super_string) > -1) {
		        unprocessed_value = unprocessed_value.split(super_string)[1];
		      }
		    }
	
		    var cat_value = parseFloat(unprocessed_value);
	
		    return cat_value;
		  }
			};
	
	/***/ },
	/* 120 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var get_cat_names = __webpack_require__(121);
	
		module.exports = function click_filter_cats(cgm, inst_data, inst_selection, inst_rc) {
	
		  var params = cgm.params;
	
		  var inst_cat = d3.select(inst_selection).attr('cat');
		  var cat_name = inst_data[inst_cat];
	
		  var found_names = get_cat_names(params, inst_data, inst_selection, inst_rc);
	
		  var switch_rc = { 'row': 'col', 'col': 'row' };
		  var other_rc = switch_rc[inst_rc];
	
		  var filter_names = {};
		  filter_names[inst_rc] = found_names;
	
		  if (cgm.params.cat_filter[inst_rc] === false) {
	
		    if (cgm.params.dendro_filter.row === false && cgm.params.dendro_filter.col === false && cgm.params.cat_filter[other_rc] === false) {
	
		      var tmp_names = cgm.params.network_data.col_nodes_names;
	
		      // keep a backup of the inst_view
		      var inst_row_nodes = cgm.params.network_data.row_nodes;
		      var inst_col_nodes = cgm.params.network_data.col_nodes;
	
		      // run filtering using found names
		      cgm.filter_viz_using_names(filter_names);
	
		      // overwrite with backup of original nodes
		      cgm.params.inst_nodes.row_nodes = inst_row_nodes;
		      cgm.params.inst_nodes.col_nodes = inst_col_nodes;
	
		      // must set this after filtering has been run
		      cgm.params.cat_filter[inst_rc] = tmp_names;
	
		      highlight_filtered_cat(inst_rc, inst_cat, cat_name);
		    }
		  } else {
	
		    // get backup of names
		    filter_names = cgm.params.cat_filter[inst_rc];
	
		    // reset filter
		    cgm.filter_viz_using_names(filter_names);
		    // must set this after filtering has been run
		    cgm.params.cat_filter[inst_rc] = false;
	
		    // there are no filtered cats
		    d3.selectAll(params.root + ' .' + inst_rc + '_cat_group').selectAll('rect').classed('filtered_cat', false);
		  }
	
		  function highlight_filtered_cat(inst_rc, inst_cat, cat_name) {
	
		    d3.selectAll(params.root + ' .' + inst_rc + '_cat_group').selectAll('rect').style('opacity', function (d) {
	
		      var inst_opacity = d3.select(this).style('opacity');
	
		      if (d3.select(this).classed('cat_strings')) {
	
		        var tmp_name;
		        var tmp_cat = d3.select(this).attr('cat');
	
		        // no need to filter out title
		        tmp_name = d[tmp_cat];
	
		        if (tmp_cat === inst_cat && tmp_name === cat_name) {
		          inst_opacity = 1;
	
		          d3.select(this).classed('filtered_cat', true);
		        }
		        // else {
		        //   inst_opacity = params.viz.cat_colors.opacity/4;
		        // }
		      }
	
		      return inst_opacity;
		    });
		  }
			};
	
	/***/ },
	/* 121 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var utils = __webpack_require__(2);
	
		module.exports = function get_cat_names(params, inst_data, inst_selection, inst_rc) {
	
		  // category index
		  var inst_cat = d3.select(inst_selection).attr('cat');
		  var cat_name = inst_data[inst_cat];
		  var tmp_nodes = params.network_data[inst_rc + '_nodes'];
	
		  var found_nodes = _.filter(tmp_nodes, function (d) {
		    return d[inst_cat] == cat_name;
		  });
	
		  var found_names = utils.pluck(found_nodes, 'name');
	
		  return found_names;
		};
	
	/***/ },
	/* 122 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var cat_tooltip_text = __webpack_require__(117);
		var d3_tip_custom = __webpack_require__(48);
		var reset_cat_opacity = __webpack_require__(118);
		var ini_cat_opacity = __webpack_require__(119);
		var click_filter_cats = __webpack_require__(120);
		var get_cat_names = __webpack_require__(121);
	
		module.exports = function make_row_cat(cgm) {
		  var updating = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
	
	
		  // console.log('make_row_cat')
	
		  var params = cgm.params;
	
		  // make or reuse outer container
		  if (d3.select(params.root + ' .row_cat_outer_container').empty()) {
		    d3.select(params.root + ' .row_container').append('g').attr('class', 'row_cat_outer_container').attr('transform', 'translate(' + params.viz.norm_labels.width.row + ',0)').append('g').attr('class', 'row_cat_container');
		  } else {
		    d3.select(params.root + ' .row_container').select('row_cat_outer_container').attr('transform', 'translate(' + params.viz.norm_labels.width.row + ',0)');
		  }
	
		  // white background
		  if (d3.select(params.root + ' .row_cat_container').select('.white_bars').empty()) {
		    d3.select(params.root + ' .row_cat_container').append('rect').attr('class', 'white_bars').attr('fill', params.viz.background_color).attr('width', params.viz.cat_room.row + 'px').attr('height', function () {
		      var inst_height = params.viz.clust.dim.height;
		      return inst_height;
		    });
		  } else {
		    d3.select(params.root + ' .row_cat_container').select('.white_bars').attr('fill', params.viz.background_color).attr('width', params.viz.cat_room.row + 'px').attr('height', function () {
		      var inst_height = params.viz.clust.dim.height;
		      return inst_height;
		    });
		  }
	
		  // remove old col_cat_tips
		  d3.selectAll(params.viz.root_tips + '_row_cat_tip').remove();
	
		  // d3-tooltip
		  var cat_tip = d3_tip_custom().attr('class', function () {
		    var root_tip_selector = params.viz.root_tips.replace('.', '');
		    var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_row_cat_tip';
		    return class_string;
		  }).direction('e').offset([5, 0]).style('display', 'none').html(function (d) {
		    return cat_tooltip_text(params, d, this, 'row');
		  });
	
		  // groups that hold classification triangle and colorbar rect
		  d3.select(params.root + ' .row_cat_container').selectAll('g').data(params.network_data.row_nodes, function (d) {
		    // console.log('-------------')
		    // console.log(d['cat-0'])
		    // console.log('-------------')
		    return d.name;
		  }).enter().append('g').attr('class', 'row_cat_group').attr('transform', function (d) {
		    var inst_index = _.indexOf(params.network_data.row_nodes_names, d.name);
		    return 'translate(0, ' + params.viz.y_scale(inst_index) + ')';
		  });
	
		  d3.select(params.root + ' .row_cat_container').selectAll('.row_cat_group').call(cat_tip);
	
		  // add row visual-aid triangles (if no downsampling)
		  // if (params.viz.ds_level === -1){
		  // d3.selectAll(params.root+' .row_cat_group')
		  //   .append('path')
		  //   .attr('d', function() {
		  //     var origin_x = params.viz.cat_room.symbol_width - 1;
		  //     var origin_y = 0;
		  //     var mid_x = 1;
		  //     var mid_y = params.viz.y_scale.rangeBand() / 2;
		  //     var final_x = params.viz.cat_room.symbol_width - 1;
		  //     var final_y = params.viz.y_scale.rangeBand();
		  //     var output_string = 'M ' + origin_x + ',' + origin_y + ' L ' +
		  //       mid_x + ',' + mid_y + ', L ' + final_x + ',' + final_y + ' Z';
		  //     return output_string;
		  //   })
		  //   .attr('fill', '#eee')
		  //   .style('opacity', params.viz.triangle_opacity);
		  // }
	
		  var cat_rect;
		  var inst_selection;
	
		  d3.selectAll(params.root + ' .row_cat_group rect').remove();
	
		  if (params.viz.show_categories.row) {
	
		    d3.selectAll(params.root + ' .row_cat_group').each(function () {
	
		      inst_selection = this;
	
		      _.each(params.viz.all_cats.row, function (inst_cat) {
	
		        var inst_num = parseInt(inst_cat.split('-')[1], 10);
		        var cat_rect_class = 'row_cat_rect_' + String(inst_num);
	
		        if (d3.select(inst_selection).select('.' + cat_rect_class).empty()) {
		          cat_rect = d3.select(inst_selection).append('rect').attr('class', cat_rect_class).attr('cat', inst_cat);
		        } else {
		          cat_rect = d3.select(inst_selection).select('.' + cat_rect_class);
		        }
	
		        cat_rect.attr('width', params.viz.cat_room.symbol_width).attr('height', params.viz.y_scale.rangeBand()).style('fill', function (d) {
		          var cat_name = d[inst_cat];
	
		          // if (cat_name.indexOf(': ') >= 0){
		          //   cat_name = cat_name.split(': ')[1];
		          // }
	
		          // console.log(cat_name)
	
		          var inst_color = params.viz.cat_colors.row[inst_cat][cat_name];
	
		          // console.log('inst_color: ' + String(inst_color));
		          return inst_color;
		        }).attr('x', function () {
		          var inst_offset = params.viz.cat_room.symbol_width + params.viz.uni_margin / 2;
		          return inst_offset + 'px';
		        }).attr('transform', function () {
		          var cat_room = params.viz.cat_room.symbol_width + params.viz.cat_room.separation;
		          var inst_shift = inst_num * cat_room;
		          return 'translate(' + inst_shift + ',0)';
		        }).on('click', function (d) {
	
		          if (d3.select(this).classed('cat_strings')) {
	
		            if (d3.event.shiftKey === true) {
		              click_filter_cats_db(cgm, d, this, 'row');
		            } else {
	
		              var found_names = get_cat_names(params, d, this, 'row');
	
		              $(params.root + ' .dendro_info').modal('toggle');
		              var group_string = found_names.join(', ');
		              d3.select(params.root + ' .dendro_info input').attr('value', group_string);
		            }
		          }
		        }).on('mouseover', cat_tip.show).on('mouseout', function () {
		          cat_tip.hide(this);
		          reset_cat_opacity(params);
		          d3.select(this).classed('hovering', false);
	
		          d3.selectAll('.d3-tip').style('display', 'none');
		        });
	
		        ini_cat_opacity(params.viz, 'row', cat_rect, inst_cat, updating);
		      });
		    });
		  }
	
		  var click_filter_cats_db = _.debounce(click_filter_cats, 1500);
			};
	
	/***/ },
	/* 123 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var make_dendro_triangles = __webpack_require__(55);
	
		module.exports = function make_row_dendro(cgm) {
	
		  var params = cgm.params;
	
		  var spillover_width = params.viz.dendro_room.row + params.viz.uni_margin;
	
		  // position row_dendro_outer_container
		  var x_offset = params.viz.clust.margin.left + params.viz.clust.dim.width;
		  var y_offset = params.viz.clust.margin.top;
	
		  // make or reuse outer container
		  if (d3.select(params.root + ' .row_dendro_outer_container').empty()) {
	
		    d3.select(params.root + ' .viz_svg').append('g').attr('class', 'row_dendro_outer_container').attr('transform', 'translate(' + x_offset + ',' + y_offset + ')');
	
		    d3.select(params.root + ' .row_dendro_outer_container').append('rect').classed('row_dendro_spillover', true).attr('fill', params.viz.background_color).attr('width', spillover_width + 'px').attr('height', params.viz.svg_dim.height);
	
		    d3.select(params.root + ' .row_dendro_outer_container').append('g').attr('class', 'row_dendro_container').attr('transform', 'translate(' + params.viz.uni_margin / 2 + ',0)');
		  } else {
		    d3.select(params.root + ' .viz_svg').select('row_dendro_outer_container').attr('transform', 'translate(' + x_offset + ',' + y_offset + ')');
	
		    d3.select(params.root + ' .row_dendro_outer_container').select('.row_dendro_spillover').attr('width', spillover_width + 'px').attr('height', params.viz.svg_dim.height);
		  }
	
		  make_dendro_triangles(cgm, 'row', false);
	
		  if (params.viz.inst_order.col != 'clust') {
		    d3.selectAll(params.root + ' .row_dendro_group').remove();
		  }
			};
	
	/***/ },
	/* 124 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var make_dendro_triangles = __webpack_require__(55);
	
		module.exports = function make_col_dendro(cgm) {
	
		  var params = cgm.params;
	
		  // position col_dendro_outer_container
		  var x_offset = params.viz.clust.margin.left;
		  var y_offset = params.viz.clust.margin.top + params.viz.clust.dim.height;
		  var spillover_height = params.viz.dendro_room.col + params.viz.uni_margin;
	
		  // make or reuse outer container
		  if (d3.select(params.root + ' .col_dendro_outer_container').empty()) {
	
		    d3.select(params.root + ' .viz_svg').append('g').attr('class', 'col_dendro_outer_container').attr('transform', 'translate(' + x_offset + ',' + y_offset + ')');
	
		    d3.select(params.root + ' .col_dendro_outer_container').append('rect').classed('col_dendro_spillover', true).attr('fill', params.viz.background_color).attr('width', params.viz.svg_dim.width).attr('height', spillover_height + 'px');
	
		    d3.select(params.root + ' .col_dendro_outer_container').append('g').attr('class', 'col_dendro_container').attr('transform', 'translate(0,' + params.viz.uni_margin / 2 + ')');
	
		    d3.select(params.root + ' .col_dendro_outer_container').append('rect').classed('col_dendro_spillover_top', true).attr('fill', params.viz.background_color).attr('width', params.viz.svg_dim.width).attr('height', params.viz.svg_dim.height).attr('transform', 'translate(0,' + params.viz.dendro_room.col + ')');
		  } else {
	
		    d3.select(params.root + ' .viz_svg').select('col_dendro_outer_container').attr('transform', 'translate(' + x_offset + ',' + y_offset + ')');
	
		    d3.select(params.root + ' .col_dendro_outer_container').select('.col_dendro_spillover').attr('width', params.viz.svg_dim.width).attr('height', spillover_height + 'px');
		  }
	
		  make_dendro_triangles(cgm, 'col', false);
	
		  if (params.viz.inst_order.row != 'clust') {
		    d3.selectAll(params.root + ' .col_dendro_group').remove();
		  }
			};
	
	/***/ },
	/* 125 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var build_svg_dendro_slider = __webpack_require__(126);
	
		module.exports = function make_svg_dendro_sliders(cgm) {
	
		  build_svg_dendro_slider(cgm, 'row');
		  build_svg_dendro_slider(cgm, 'col');
			};
	
	/***/ },
	/* 126 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var change_groups = __webpack_require__(127);
		var position_svg_dendro_slider = __webpack_require__(114);
	
		module.exports = function build_svg_dendro_slider(cgm, inst_rc) {
	
		  var slider_length = 100;
	
		  var drag = d3.behavior.drag().on("drag", dragging).on('dragend', function () {
		    cgm.params.is_slider_drag = false;
		  });
	
		  var slider_group = d3.select(cgm.params.root + ' .viz_svg').append('g').classed(inst_rc + '_slider_group', true);
	
		  position_svg_dendro_slider(cgm, inst_rc);
	
		  var rect_height = slider_length + 20;
		  var rect_width = 30;
		  slider_group.append('rect').classed(inst_rc + '_slider_background', true).attr('height', rect_height + 'px').attr('width', rect_width + 'px').attr('fill', cgm.params.viz.background_color).attr('transform', function () {
		    var translate_string = 'translate(-10, -5)';
		    return translate_string;
		  }).style('opacity', 0);
	
		  slider_group.append("line").style('stroke-width', slider_length / 7 + 'px').style('stroke', 'black').style('stroke-linecap', 'round').style('opacity', 0.0).attr("y1", 0).attr("y2", function () {
		    return slider_length - 2;
		  }).on('click', click_dendro_slider);
	
		  var offset_triangle = -slider_length / 40;
		  slider_group.append('path').style('fill', 'black').attr('transform', 'translate(' + offset_triangle + ', 0)').attr('d', function () {
	
		    // up triangle
		    var start_x = 0;
		    var start_y = 0;
	
		    var mid_x = 0;
		    var mid_y = slider_length;
	
		    var final_x = slider_length / 10;
		    var final_y = 0;
	
		    var output_string = 'M' + start_x + ',' + start_y + ', L' + mid_x + ', ' + mid_y + ', L' + final_x + ',' + final_y + ' Z';
	
		    return output_string;
		  }).style('opacity', 0.35).on('click', click_dendro_slider);
	
		  var default_opacity = 0.35;
		  var high_opacity = 0.6;
		  slider_group.append('circle').classed(inst_rc + '_group_circle', true).attr('r', slider_length * 0.08).attr('transform', function () {
		    return 'translate(0, ' + slider_length / 2 + ')';
		  }).style('fill', 'blue').style('opacity', default_opacity).on('mouseover', function () {
		    d3.select(this).style('opacity', high_opacity);
		  }).on('mouseout', function () {
		    d3.select(this).style('opacity', default_opacity);
		  }).call(drag);
	
		  function dragging() {
	
		    cgm.params.is_slider_drag = true;
	
		    // d[0] = d3.event.x;
		    var slider_pos = d3.event.y;
	
		    if (slider_pos < 0) {
		      slider_pos = 0;
		    }
	
		    if (slider_pos > slider_length) {
		      slider_pos = slider_length;
		    }
	
		    if (this.nextSibling) {
		      this.parentNode.appendChild(this);
		    }
	
		    slider_pos = d3.round(slider_pos, -1);
	
		    var slider_value = 10 - slider_pos / 10;
	
		    d3.select(this).attr("transform", "translate(0, " + slider_pos + ")");
	
		    change_groups(cgm, inst_rc, slider_value);
		  }
	
		  function click_dendro_slider() {
	
		    var clicked_line_position = d3.mouse(this);
	
		    var rel_pos = d3.round(clicked_line_position[1], -1);
	
		    d3.select(cgm.params.root + ' .' + inst_rc + '_group_circle').attr('transform', 'translate(0, ' + rel_pos + ')');
	
		    var slider_value = 10 - rel_pos / 10;
	
		    change_groups(cgm, inst_rc, slider_value);
		  }
		};
	
	/***/ },
	/* 127 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		// var build_color_groups = require('./build_color_groups');
		var make_dendro_triangles = __webpack_require__(55);
	
		/* Changes the groupings (x- and y-axis color bars).
		 */
		module.exports = function (cgm, inst_rc, inst_index) {
	
		  var params = cgm.params;
	
		  if (inst_rc === 'row') {
		    params.group_level.row = inst_index;
		  } else if (inst_rc === 'col') {
		    params.group_level.col = inst_index;
		  }
	
		  var is_change_group = true;
	
		  make_dendro_triangles(cgm, inst_rc, is_change_group);
			};
	
	/***/ },
	/* 128 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var make_dendro_crop_buttons = __webpack_require__(60);
	
		module.exports = function make_row_dendro_spillover(cgm) {
	
		  var viz = cgm.params.viz;
	
		  // hide spillover from right
		  var tmp_left = viz.clust.margin.left + viz.clust.dim.width + viz.uni_margin + viz.dendro_room.row;
	
		  var r_spill_container = d3.select(viz.viz_svg).append('g').classed('right_spillover_container', true).attr('transform', function () {
		    return 'translate(' + tmp_left + ', 0)';
		  });
	
		  var tmp_top = viz.norm_labels.margin.top + viz.norm_labels.width.col;
	
		  r_spill_container.append('rect').attr('fill', viz.background_color) //!! prog_colors
		  .attr('width', 10 * viz.clust.dim.width).attr('height', viz.svg_dim.height + 'px').attr('class', 'white_bars').attr('class', 'right_spillover').attr('transform', function () {
		    return 'translate( 0,' + tmp_top + ')';
		  });
	
		  var x_offset = 0;
		  var y_offset = viz.clust.margin.top;
		  r_spill_container.append('g').classed('row_dendro_icons_container', true).attr('transform', 'translate(' + x_offset + ',' + y_offset + ')').append('g').classed('row_dendro_icons_group', true);
	
		  make_dendro_crop_buttons(cgm, 'row');
	
		  // hide spillover from top of row dendrogram
		  x_offset = viz.clust.margin.left + viz.clust.dim.width;
		  y_offset = tmp_top;
	
		  var tmp_width = viz.dendro_room.row + viz.uni_margin;
		  var tmp_height = viz.cat_room.col + viz.uni_margin;
		  d3.select(viz.viz_svg).append('rect').attr('fill', viz.background_color).attr('width', tmp_width).attr('height', tmp_height).attr('transform', function () {
		    return 'translate(' + x_offset + ',' + y_offset + ')';
		  }).classed('white_bars', true).classed('dendro_row_spillover', true);
			};
	
	/***/ },
	/* 129 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		/* eslint-disable */
	
		var run_segment = __webpack_require__(130);
		var play_intro = __webpack_require__(131);
		var play_zoom = __webpack_require__(133);
		var play_reset_zoom = __webpack_require__(134);
		var play_reorder_row = __webpack_require__(136);
		var play_reorder_buttons = __webpack_require__(137);
		var play_search = __webpack_require__(139);
		var play_filter = __webpack_require__(140);
		var quick_cluster = __webpack_require__(163);
		var play_groups = __webpack_require__(164);
		var play_categories = __webpack_require__(165);
		var play_conclusion = __webpack_require__(166);
		var toggle_play_button = __webpack_require__(167);
		var play_menu_button = __webpack_require__(168);
	
		module.exports = function play_demo() {
	
		  var cgm = this;
		  var params = cgm.params;
	
		  if (d3.select(params.root + ' .running_demo').empty()) {
	
		    // prevent more than one demo from running at once
		    d3.select(params.root + ' .play_button').classed('running_demo', true);
	
		    toggle_play_button(params, false);
	
		    // prevent user interaction while playing
		    $.blockUI({ css: {
		        border: 'none',
		        padding: '15px',
		        backgroundColor: '#000',
		        '-webkit-border-radius': '10px',
		        '-moz-border-radius': '10px',
		        opacity: 0,
		        color: '#fff',
		        cursor: 'default'
		      } });
	
		    d3.selectAll('.blockUI').style('opacity', 0);
	
		    // intro text
		    var inst_time = 750;
	
		    if (cgm.params.viz.is_expand === false) {
		      inst_time = run_segment(params, inst_time, quick_cluster);
		      inst_time = inst_time - 1500;
		    }
	
		    // clustergram interaction
		    ///////////////////////////////////
		    inst_time = run_segment(params, inst_time, play_intro);
		    inst_time = run_segment(params, inst_time, play_zoom);
		    inst_time = run_segment(cgm, inst_time, play_reset_zoom);
		    inst_time = run_segment(params, inst_time, play_categories);
		    inst_time = run_segment(params, inst_time, play_reorder_row);
	
		    // sidebar interaction
		    ///////////////////////////////////
		    inst_time = run_segment(params, inst_time, play_menu_button);
		    inst_time = run_segment(params, inst_time, play_groups);
		    inst_time = run_segment(params, inst_time, play_reorder_buttons);
		    inst_time = run_segment(params, inst_time, play_search);
		    inst_time = run_segment(cgm, inst_time, play_filter);
	
		    // conclusion
		    ///////////////////////////////////
		    inst_time = run_segment(params, inst_time, quick_cluster);
		    inst_time = run_segment(params, inst_time, play_conclusion);
		  }
			};
	
	/***/ },
	/* 130 */
	/***/ function(module, exports) {
	
		"use strict";
	
		module.exports = function run_segment(segment_data, inst_time, inst_segment) {
		  /* eslint-disable */
	
		  var timer = setTimeout(inst_segment().run, inst_time, segment_data);
	
		  // set up kill demo that will stop setTimeouts
		  //////////////////////////////////////////////////
		  // if (clear_timer){
		  //   clearTimeout(timer);
		  // }
	
		  var inst_duration = inst_segment().get_duration();
		  inst_time = inst_time + inst_duration;
	
		  return inst_time;
			};
	
	/***/ },
	/* 131 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var demo_text = __webpack_require__(132);
	
		module.exports = function play_intro() {
	
		  var speed_up = 1;
	
		  function run(params) {
		    var text_1 = 'Clustergrammer allows users to generate\ninteractive and ' + 'sharable visualizations\nby uploading a matrix';
		    var text_2 = "This demo will quickly overview some\nof Clustergrammer's " + "interactive features";
	
		    setTimeout(demo_text, 0, params, text_1, 4500 / speed_up);
		    setTimeout(demo_text, 4500 / speed_up, params, text_2, 4500 / speed_up);
		  }
	
		  function get_duration() {
		    return 10000 / speed_up;
		  }
	
		  return {
		    run: run,
		    get_duration: get_duration
		  };
			};
	
	/***/ },
	/* 132 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function demo_text(params, text, read_duration) {
	
		  var split_text = text.split('\n');
	
		  if (split_text.length < 3) {
		    split_text.push('');
		  }
	
		  d3.select(params.root + ' .demo_group').style('opacity', 0).transition().duration(250).style('opacity', 1).transition().duration(250).delay(read_duration).style('opacity', 0);
	
		  for (var i = 0; i < split_text.length; i++) {
	
		    var inst_text_num = i + 1;
	
		    // make text box 
		    //////////////////
		    var inst_text_obj = d3.select(params.root + ' .demo_group').select('#text_' + inst_text_num).text(split_text[i]);
		    var bbox = inst_text_obj[0][0].getBBox();
	
		    var box_opacity = 0.9;
	
		    var tmp_fs = Number(d3.select('.demo_group').select('text').style('font-size').replace('px', ''));
		    var shift_height = tmp_fs * 1.3;
	
		    d3.select(params.root + ' .demo_group').select('.rect_' + inst_text_num).style('fill', 'white').attr('width', bbox.width + 20).attr('height', bbox.height).attr('x', -10).attr('y', bbox.y + i * shift_height).style('opacity', box_opacity);
		  }
			};
	
	/***/ },
	/* 133 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var demo_text = __webpack_require__(132);
		var two_translate_zoom = __webpack_require__(80);
	
		module.exports = function play_zoom() {
	
		  function run(cgm) {
	
		    var params = cgm.params;
		    var text = 'Zoom and pan by\nscrolling and dragging';
		    demo_text(params, text, 4000);
	
		    setTimeout(two_translate_zoom, 1500, cgm, 0, 0, 4);
		  }
	
		  function get_duration() {
		    return 4000;
		  }
	
		  return {
		    run: run,
		    get_duration: get_duration
		  };
			};
	
	/***/ },
	/* 134 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var demo_text = __webpack_require__(132);
		var two_translate_zoom = __webpack_require__(80);
		var sim_click = __webpack_require__(135);
	
		module.exports = function play_reset_zoom() {
	
		  function run(cgm) {
	
		    var params = cgm.params;
	
		    var text = 'Reset zoom by double-clicking\n';
		    demo_text(params, text, 4000);
	
		    setTimeout(sim_click, 2000, params, 'double', 300, 300);
		    setTimeout(two_translate_zoom, 2400, cgm, 0, 0, 1);
		  }
	
		  function get_duration() {
		    return 4500;
		  }
	
		  return {
		    run: run,
		    get_duration: get_duration
		  };
			};
	
	/***/ },
	/* 135 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function sim_click(params, single_double, pos_x, pos_y) {
	
		  var click_duration = 200;
	
		  var click_circle = d3.select(params.root + ' .viz_svg').append('circle').attr('cx', pos_x).attr('cy', pos_y).attr('r', 25).style('stroke', 'black').style('stroke-width', '3px').style('fill', '#007f00').style('opacity', 0.5);
	
		  if (single_double === 'double') {
		    click_circle.transition().duration(click_duration).style('opacity', 0.0).transition().duration(50).style('opacity', 0.5).transition().duration(click_duration).style('opacity', 0.0).remove();
		  } else {
		    click_circle.transition().duration(click_duration).style('opacity', 0.0).transition().duration(250).remove();
		  }
			};
	
	/***/ },
	/* 136 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var demo_text = __webpack_require__(132);
		var sim_click = __webpack_require__(135);
	
		module.exports = function play_reorder_row() {
		  /* eslint-disable */
	
		  function run(params) {
	
		    var text = 'Reorder the matrix based on a single\nrow or column by double-clicking a\nlabel';
		    demo_text(params, text, 7000);
	
		    var inst_element = get_row_element(params, 'EGFR');
	
		    var group_trans = d3.select(inst_element).attr('transform');
	
		    var container_trans = d3.select(params.root + ' .clust_container').attr('transform').split(',')[1].replace(')', '');
	
		    var x_trans = params.viz.norm_labels.width.row * 0.9;
	
		    var row_trans = group_trans.split(',')[1].replace(')', '');
		    var y_trans = String(Number(row_trans) + Number(container_trans) + params.viz.rect_height / 2);
	
		    var wait_click = 4000;
		    setTimeout(sim_click, wait_click, params, 'double', x_trans, y_trans);
		    var wait_reorder = wait_click + 300;
		    setTimeout(fire_double_click_row, wait_reorder, params, inst_element);
		  }
	
		  function get_duration() {
		    return 8000;
		  }
	
		  function get_row_element(params, inst_row) {
	
		    var inst_element = d3.selectAll(params.root + ' .row_label_group').filter(function () {
		      var inst_data = this.__data__;
		      return inst_data.name == inst_row;
		    })[0][0];
	
		    return inst_element;
		  }
	
		  function fire_double_click_row(params, inst_element) {
	
		    $(inst_element).d3DblClick();
		  }
	
		  // allows doubleclicking on d3 element
		  jQuery.fn.d3DblClick = function () {
		    this.each(function (i, e) {
		      var evt = document.createEvent("MouseEvents");
		      evt.initMouseEvent("dblclick", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
		      e.dispatchEvent(evt);
		    });
		  };
	
		  return {
		    run: run,
		    get_duration: get_duration
		  };
			};
	
	/***/ },
	/* 137 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var demo_text = __webpack_require__(132);
		var highlight_sidebar_element = __webpack_require__(138);
	
		module.exports = function play_reorder_buttons() {
		  /* eslint-disable */
	
		  function run(params) {
	
		    var text = 'Reorder all rows and columns\nby clicking the reorder\n buttons';
		    demo_text(params, text, 9000);
	
		    setTimeout(highlight_sidebar_element, 3000, params, 'toggle_col_order');
		    setTimeout(click_reorder_button, 3500, params, 'col', 'rank');
	
		    setTimeout(highlight_sidebar_element, 7000, params, 'toggle_row_order');
		    setTimeout(click_reorder_button, 7500, params, 'row', 'rank');
		  }
	
		  function get_duration() {
		    return 11000;
		  }
	
		  function click_reorder_button(params, inst_rc, inst_order) {
		    var inst_button = d3.selectAll('.toggle_' + inst_rc + '_order .btn').filter(function () {
		      return this.__data__ == inst_order;
		    })[0];
	
		    $(inst_button).click();
		  }
	
		  return {
		    run: run,
		    get_duration: get_duration
		  };
			};
	
	/***/ },
	/* 138 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function highlight_sidebar_element(params, highlight_class) {
		  var duration = arguments.length <= 2 || arguments[2] === undefined ? 4000 : arguments[2];
	
	
		  if (highlight_class.indexOf('slider') < 0) {
		    d3.select(params.root + ' .' + highlight_class).style('background', '#007f00').style('box-shadow', '0px 0px 10px 5px #007f00').transition().duration(1).delay(duration).style('background', '#FFFFFF').style('box-shadow', 'none');
		  } else {
		    d3.select(params.root + ' .' + highlight_class).style('box-shadow', '0px 0px 10px 5px #007f00').transition().duration(1).delay(duration).style('box-shadow', 'none');
		  }
			};
	
	/***/ },
	/* 139 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var demo_text = __webpack_require__(132);
		var highlight_sidebar_element = __webpack_require__(138);
		var two_translate_zoom = __webpack_require__(80);
	
		module.exports = function play_search() {
	
		  function run(cgm) {
	
		    var params = cgm.params;
		    var text = 'Search for rows using\nthe search box';
		    demo_text(params, text, 5000);
	
		    var ini_delay = 2500;
		    setTimeout(highlight_sidebar_element, ini_delay, params, 'gene_search_container');
	
		    // manually mimic typing and autocomplete
		    setTimeout(type_out_search, ini_delay + 1000, params, 'E');
		    setTimeout(type_out_search, ini_delay + 1500, params, 'EG');
		    setTimeout(type_out_search, ini_delay + 2000, params, 'EGF');
		    setTimeout(type_out_search, ini_delay + 2500, params, 'EGFR');
	
		    setTimeout(run_search, 5500, params);
	
		    setTimeout(two_translate_zoom, 7500, cgm, 0, 0, 1);
		  }
	
		  function get_duration() {
		    return 10000;
		  }
	
		  function type_out_search(params, inst_string) {
		    $(params.root + ' .gene_search_box').val(inst_string);
		    $(params.root + ' .gene_search_box').autocomplete("search", inst_string);
		  }
	
		  function run_search(params) {
		    $(params.root + ' .submit_gene_button').click();
		    $(params.root + ' .gene_search_box').autocomplete("search", '');
		  }
	
		  return {
		    run: run,
		    get_duration: get_duration
		  };
			};
	
	/***/ },
	/* 140 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var demo_text = __webpack_require__(132);
		var highlight_sidebar_element = __webpack_require__(138);
		var update_viz_with_view = __webpack_require__(141);
	
		module.exports = function play_filter() {
	
		  function run(cgm) {
		    var params = cgm.params;
	
		    var text = 'Filter rows based on sum or\nvariance using the sliders';
		    demo_text(params, text, 4000);
	
		    var filter_type = 'N_row_sum';
	
		    setTimeout(highlight_sidebar_element, 5000, params, 'slider_' + filter_type, 13000);
	
		    text = 'Filter: Top 20 rows by sum';
		    setTimeout(demo_text, 5000, params, text, 4000);
		    setTimeout(run_update, 5300, cgm, filter_type, 20, 1);
	
		    text = 'Filter: Top 10 rows by sum';
		    setTimeout(demo_text, 10000, params, text, 4000);
		    setTimeout(run_update, 10300, cgm, filter_type, 10, 2);
	
		    text = 'Filter: All rows';
		    setTimeout(demo_text, 15000, params, text, 4000);
		    setTimeout(run_update, 15300, cgm, filter_type, 'all', 0);
		  }
	
		  function get_duration() {
		    return 19500;
		  }
	
		  function run_update(cgm, filter_type, filter_value, filter_index) {
	
		    var params = cgm.params;
	
		    var requested_view = {};
		    requested_view[filter_type] = filter_value;
		    update_viz_with_view(cgm, requested_view);
	
		    // quick fix for slider
		    $(params.root + ' .slider_' + filter_type).slider("value", filter_index);
	
		    var unit_name;
		    if (filter_type === 'N_row_sum') {
		      unit_name = 'sum';
		    } else {
		      unit_name = 'variance';
		    }
	
		    d3.select(params.root + ' .title_' + filter_type).text('Top rows ' + unit_name + ': ' + filter_value);
		  }
	
		  return {
		    run: run,
		    get_duration: get_duration
		  };
			};
	
	/***/ },
	/* 141 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var make_network_using_view = __webpack_require__(10);
		var disable_sidebar = __webpack_require__(142);
		var update_viz_with_network = __webpack_require__(143);
	
		module.exports = function update_viz_with_view(cgm, requested_view) {
	
		  disable_sidebar(cgm.params);
	
		  // make new_network_data by filtering the original network data
		  var new_network_data = make_network_using_view(cgm.config, cgm.params, requested_view);
	
		  // reset crop button
		  d3.select(cgm.params.root + ' .crop_button').style('color', '#337ab7').classed('fa-crop', true).classed('fa-undo', false).classed('active_cropping', false);
	
		  // reset dendrogram filtering when updating with a new view
		  // e.g. with the row filter sliders
		  _.each(['row', 'col'], function (inst_rc) {
	
		    // set class to reflect that no filtering was ran
		    d3.select(cgm.params.root + ' .' + inst_rc + '_dendro_icons_group').classed('ran_filter', false);
	
		    // display all crop buttons when cropping has not been done
		    d3.select(cgm.params.root + ' .' + inst_rc + '_dendro_icons_container').style('display', 'block');
		  });
	
		  update_viz_with_network(cgm, new_network_data);
			};
	
	/***/ },
	/* 142 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function disable_sidebar(params) {
	
		  d3.selectAll(params.root + ' .btn').attr('disabled', true);
		  d3.select(params.viz.viz_svg).style('opacity', 0.70);
			};
	
	/***/ },
	/* 143 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var make_params = __webpack_require__(9);
		var define_enter_exit_delays = __webpack_require__(144);
		var enter_exit_update = __webpack_require__(145);
		var initialize_resizing = __webpack_require__(87);
		var make_col_cat = __webpack_require__(116);
		var make_row_cat = __webpack_require__(122);
		var make_row_dendro = __webpack_require__(123);
		var make_col_dendro = __webpack_require__(124);
		var ini_sidebar = __webpack_require__(156);
		var enable_sidebar = __webpack_require__(158);
		var ini_doubleclick = __webpack_require__(97);
		var update_reorder_buttons = __webpack_require__(159);
		var make_row_cat_super_labels = __webpack_require__(86);
		var modify_row_node_cats = __webpack_require__(160);
		var run_zoom = __webpack_require__(89);
		var ds_enter_exit_update = __webpack_require__(162);
		var make_cat_params = __webpack_require__(32);
	
		module.exports = function update_viz_with_network(cgm, new_network_data) {
	
		  // console.log('UPDATE VIZ WITH NETWORK')
	
		  // set runnning_update class, prevents multiple update from running at once
		  d3.select(cgm.params.viz.viz_svg).classed('running_update', true);
	
		  // remove downsampled rows always
		  d3.selectAll(cgm.params.root + ' .ds' + String(cgm.params.viz.ds_level) + '_row').remove();
	
		  // run optional callback function
		  // console.log('before and after matrix_update_callback')
		  // console.log(new_network_data.row_nodes[0]['cat-0'])
		  if (cgm.params.matrix_update_callback != null) {
		    cgm.params.matrix_update_callback();
		  }
		  // console.log(new_network_data.row_nodes[0]['cat-0'])
	
		  var inst_group_level = cgm.params.group_level;
		  var inst_crop_fitler = cgm.params.crop_filter_nodes;
	
		  // make tmp config to make new params
		  var tmp_config = jQuery.extend(true, {}, cgm.config);
	
		  var new_row_cats = null;
	
		  // bring in 'new' category data
		  if (cgm.params.new_row_cats != null) {
		    modify_row_node_cats(cgm.params.new_row_cats, new_network_data.row_nodes);
		    new_row_cats = cgm.params.new_row_cats;
		    cgm.params.new_row_cats = new_row_cats;
		    // do not preserve the updated (row) cats
		    var predefined_cat_colors = true;
		    cgm.params.viz = make_cat_params(cgm.params, cgm.params.viz, predefined_cat_colors);
		  }
	
		  tmp_config.network_data = new_network_data;
		  tmp_config.inst_order = cgm.params.viz.inst_order;
		  tmp_config.input_domain = cgm.params.matrix.opacity_scale.domain()[1];
	
		  update_reorder_buttons(tmp_config, cgm.params);
	
		  // tmp_config.ini_expand = false;
		  tmp_config.ini_view = null;
		  tmp_config.current_col_cat = cgm.params.current_col_cat;
	
		  // disabled, causing problems when cropping
		  // always preserve category colors when updating
		  tmp_config.cat_colors = cgm.params.viz.cat_colors;
	
		  var new_params = make_params(tmp_config);
	
		  // this function is sensitive to further updates, so run here
		  var delays = define_enter_exit_delays(cgm.params, new_params);
	
		  // pass the newly calcluated params back to the cgm object
		  cgm.params = new_params;
	
		  // set up zoom
		  cgm.params.zoom_behavior = d3.behavior.zoom().scaleExtent([1, cgm.params.viz.square_zoom * cgm.params.viz.zoom_ratio.x]).on('zoom', function () {
		    run_zoom(cgm);
		  });
	
		  // have persistent group levels while updating
		  cgm.params.group_level = inst_group_level;
	
		  // have persistent crop_filter_nodes while updating
		  cgm.params.crop_filter_nodes = inst_crop_fitler;
	
		  // only run enter-exit-updates if there is no downsampling
		  if (cgm.params.viz.ds_num_levels === 0) {
		    // new_network_data is necessary
		    enter_exit_update(cgm, new_network_data, delays);
		  } else {
		    ds_enter_exit_update(cgm);
		  }
	
		  // reduce opacity during update
		  d3.select(cgm.params.viz.viz_svg).style('opacity', 0.70);
	
		  make_row_cat(cgm);
		  make_row_cat_super_labels(cgm);
	
		  if (cgm.params.viz.show_categories.col) {
		    make_col_cat(cgm);
		  }
	
		  if (cgm.params.viz.show_dendrogram) {
		    make_row_dendro(cgm);
		    make_col_dendro(cgm);
		  }
	
		  initialize_resizing(cgm);
	
		  d3.select(cgm.params.viz.viz_svg).call(cgm.params.zoom_behavior);
	
		  ini_doubleclick(cgm);
	
		  ini_sidebar(cgm);
	
		  cgm.params.viz.run_trans = true;
	
		  // d3.selectAll(cgm.params.viz.root_tips)
		  //   .style('opacity',0);
	
		  setTimeout(enable_sidebar, 2500, cgm.params);
	
		  // remove all dendro shadows
		  setTimeout(remove_shadows, 50);
		  setTimeout(remove_shadows, 100);
		  setTimeout(remove_shadows, 500);
		  setTimeout(remove_shadows, 1000);
		  setTimeout(remove_shadows, 1500);
	
		  function remove_shadows() {
		    d3.selectAll('.dendro_shadow').remove();
		  }
	
		  function finish_update() {
		    d3.select(cgm.params.viz.viz_svg).transition().duration(250).style('opacity', 1.0);
	
		    setTimeout(finish_update_class, 1000);
		  }
	
		  setTimeout(finish_update, delays.enter);
	
		  function finish_update_class() {
		    d3.select(cgm.params.viz.viz_svg).classed('running_update', false);
		  }
			};
	
	/***/ },
	/* 144 */
	/***/ function(module, exports) {
	
		"use strict";
	
		module.exports = function (old_params, params) {
	
		  // exit, update, enter
	
		  // check if exit or enter or both are required
		  var old_row_nodes = old_params.network_data.row_nodes;
		  var old_col_nodes = old_params.network_data.col_nodes;
		  var old_row = _.map(old_row_nodes, function (d) {
		    return d.name;
		  });
		  var old_col = _.map(old_col_nodes, function (d) {
		    return d.name;
		  });
		  var all_old_nodes = old_row.concat(old_col);
	
		  var row_nodes = params.network_data.row_nodes;
		  var col_nodes = params.network_data.col_nodes;
		  var row = _.map(row_nodes, function (d) {
		    return d.name;
		  });
		  var col = _.map(col_nodes, function (d) {
		    return d.name;
		  });
		  var all_nodes = row.concat(col);
	
		  var exit_nodes = _.difference(all_old_nodes, all_nodes).length;
		  var enter_nodes = _.difference(all_nodes, all_old_nodes).length;
	
		  var delays = {};
	
		  if (exit_nodes > 0) {
		    delays.update = 1000;
		  } else {
		    delays.update = 0;
		  }
	
		  if (enter_nodes > 0) {
		    delays.enter = 1000;
		  } else {
		    delays.enter = 0;
		  }
	
		  delays.enter = delays.enter + delays.update;
	
		  delays.run_transition = true;
	
		  var old_num_links = old_params.network_data.links.length;
		  var new_num_links = params.network_data.links.length;
		  var cutoff_num_links = 0.5 * params.matrix.def_large_matrix;
	
		  if (old_num_links > cutoff_num_links || new_num_links > cutoff_num_links) {
		    delays.run_transition = false;
		    delays.update = 0;
		    delays.enter = 0;
		  }
	
		  return delays;
		};
	
	/***/ },
	/* 145 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var reset_size_after_update = __webpack_require__(146);
		var make_row_label_container = __webpack_require__(49);
		var make_col_label_container = __webpack_require__(67);
		var eeu_existing_row = __webpack_require__(147);
		var exit_components = __webpack_require__(151);
		var draw_gridlines = __webpack_require__(39);
		var enter_row_groups = __webpack_require__(152);
		var resize_containers = __webpack_require__(155);
		var label_constrain_and_trim = __webpack_require__(81);
		var d3_tip_custom = __webpack_require__(48);
	
		module.exports = function enter_exit_update(cgm, network_data, delays) {
	
		  var params = cgm.params;
	
		  // remove old tooltips
		  d3.selectAll(params.viz.root_tips).remove();
	
		  // d3-tooltip - for tiles
		  var tip = d3_tip_custom().attr('class', function () {
		    var root_tip_selector = params.viz.root_tips.replace('.', '');
		    var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_tile_tip';
		    return class_string;
		  }).direction('nw').offset([0, 0]).style('display', 'none').html(function (d) {
		    var inst_value = String(d.value.toFixed(3));
		    var tooltip_string;
	
		    if (params.keep_orig) {
		      var orig_value = String(d.value_orig.toFixed(3));
		      tooltip_string = '<p>' + d.row_name + ' and ' + d.col_name + '</p>' + '<p> normalized value: ' + inst_value + '</p>' + '<div> original value: ' + orig_value + '</div>';
		    } else {
		      tooltip_string = '<p>' + d.row_name + ' and ' + d.col_name + '</p>' + '<div> value: ' + inst_value + '</div>';
		    }
	
		    return tooltip_string;
		  });
	
		  d3.select(params.root + ' .clust_group').call(tip);
	
		  // necessary for repositioning clust, col and col-cat containers
		  resize_containers(params);
	
		  var duration = 1000;
	
		  // make global so that names can be accessed
		  var row_nodes = network_data.row_nodes;
		  var col_nodes = network_data.col_nodes;
		  var links = network_data.links;
	
		  //
		  var tile_data = links;
	
		  // add name to links for object constancy
		  for (var i = 0; i < tile_data.length; i++) {
		    var d = tile_data[i];
		    tile_data[i].name = row_nodes[d.source].name + '_' + col_nodes[d.target].name;
		  }
	
		  // move rows
		  var move_rows = d3.select(params.root + ' .clust_group').selectAll('.row').data(params.matrix.matrix, function (d) {
		    return d.name;
		  });
	
		  if (delays.run_transition) {
		    move_rows.transition().delay(delays.update).duration(duration).attr('transform', function (d) {
		      var tmp_index = d.row_index;
		      return 'translate(0,' + params.viz.y_scale(tmp_index) + ')';
		    });
		  } else {
		    move_rows.attr('transform', function (d) {
		      var tmp_index = d.row_index;
		      return 'translate(0,' + params.viz.y_scale(tmp_index) + ')';
		    });
		  }
	
		  // update existing rows - enter, exit, update tiles in existing row
		  d3.select(params.root + ' .clust_group').selectAll('.row').each(function (d) {
		    // TODO add tip back to arguments
		    var inst_selection = this;
		    eeu_existing_row(params, d, delays, duration, inst_selection, tip);
		  });
	
		  d3.selectAll(params.root + ' .horz_lines').remove();
		  d3.selectAll(params.root + ' .vert_lines').remove();
	
		  // exit
		  ////////////
		  exit_components(params, delays, duration);
	
		  // resize clust components using appropriate delays
		  reset_size_after_update(cgm, duration, delays);
	
		  // enter new elements
		  //////////////////////////
		  enter_row_groups(params, delays, duration, tip);
	
		  // update existing rows
		  make_row_label_container(cgm, duration);
		  make_col_label_container(cgm, duration);
	
		  draw_gridlines(params, delays, duration);
	
		  setTimeout(label_constrain_and_trim, 2000, params);
			};
	
	/***/ },
	/* 146 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var utils = __webpack_require__(2);
		var calc_clust_height = __webpack_require__(22);
		var get_svg_dim = __webpack_require__(19);
		var calc_clust_width = __webpack_require__(21);
		var reset_zoom = __webpack_require__(98);
		var resize_dendro = __webpack_require__(99);
		var resize_super_labels = __webpack_require__(100);
		var resize_spillover = __webpack_require__(101);
		var resize_row_labels = __webpack_require__(103);
		var resize_row_viz = __webpack_require__(105);
		var resize_col_labels = __webpack_require__(106);
		var resize_col_text = __webpack_require__(107);
		var resize_col_triangle = __webpack_require__(108);
		var resize_col_hlight = __webpack_require__(109);
		var resize_label_bars = __webpack_require__(112);
		var calc_default_fs = __webpack_require__(31);
		var calc_zoom_switching = __webpack_require__(30);
		// var show_visible_area = require('../zoom/show_visible_area');
		var ini_zoom_info = __webpack_require__(36);
	
		module.exports = function reset_size_after_update(cgm) {
		  var duration = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];
		  var delays = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2];
	
	
		  if (delays === null) {
		    delays = {};
		    delays.enter = 0;
		    delays.update = 0;
		    delays.run_transition = false;
		  }
	
		  var params = cgm.params;
	
		  var row_nodes = cgm.params.network_data.row_nodes;
	
		  params.zoom_info = ini_zoom_info();
	
		  // // not sure if this is necessary
		  // ////////////////////////////
		  // show_visible_area(params);
		  // // quick fix for column filtering
		  // setTimeout(show_visible_area, 2200, cgm);
	
		  var row_nodes_names = params.network_data.row_nodes_names;
	
		  reset_zoom(params);
	
		  // Resetting some visualization parameters
		  params = get_svg_dim(params);
		  params.viz = calc_clust_width(params.viz);
		  params.viz = calc_clust_height(params.viz);
	
		  if (params.sim_mat) {
		    if (params.viz.clust.dim.width <= params.viz.clust.dim.height) {
		      params.viz.clust.dim.height = params.viz.clust.dim.width;
		    } else {
		      params.viz.clust.dim.width = params.viz.clust.dim.height;
		    }
		  }
	
		  params.viz = calc_zoom_switching(params.viz);
	
		  // redefine x_scale and y_scale rangeBands
		  params.viz.x_scale.rangeBands([0, params.viz.clust.dim.width]);
		  params.viz.y_scale.rangeBands([0, params.viz.clust.dim.height]);
	
		  // redefine zoom extent
		  params.viz.square_zoom = params.viz.norm_labels.width.col / (params.viz.x_scale.rangeBand() / 2);
		  params.zoom_behavior.scaleExtent([1, params.viz.square_zoom * params.viz.zoom_ratio.x]);
	
		  // redefine border width
		  params.viz.border_width.x = params.viz.x_scale.rangeBand() / params.viz.border_fraction;
		  params.viz.border_width.y = params.viz.y_scale.rangeBand() / params.viz.border_fraction;
	
		  params = calc_default_fs(params);
	
		  // resize the svg
		  ///////////////////////
		  var svg_group = d3.select(params.viz.viz_wrapper).select('svg');
	
		  svg_group.select(params.root + ' .grey_background').transition().delay(delays.update).duration(duration).attr('width', params.viz.clust.dim.width).attr('height', params.viz.clust.dim.height);
	
		  resize_row_labels(params, svg_group, delays);
	
		  // do not delay the font size change since this will break the bounding box calc
		  svg_group.selectAll('.row_label_group').select('text').style('font-size', params.labels.default_fs_row + 'px').text(function (d) {
		    return utils.normal_name(d);
		  });
	
		  // change the size of the highlighting rects
		  svg_group.selectAll('.row_label_group').each(function () {
		    var bbox = d3.select(this).select('text')[0][0].getBBox();
		    d3.select(this).select('rect').attr('x', bbox.x).attr('y', 0).attr('width', bbox.width).attr('height', params.viz.y_scale.rangeBand()).style('fill', 'yellow').style('opacity', function (d) {
		      var inst_opacity = 0;
		      // highlight target genes
		      if (d.target === 1) {
		        inst_opacity = 1;
		      }
		      return inst_opacity;
		    });
		  });
	
		  resize_row_viz(params, svg_group, delays);
	
		  if (delays.run_transition) {
	
		    // positioning row text after row text size may have been reduced
		    svg_group.selectAll('.row_label_group').select('text').transition().delay(delays.update).duration(duration).attr('y', params.viz.rect_height * 0.5 + params.labels.default_fs_row * 0.35);
	
		    svg_group.selectAll('.row_cat_group').data(row_nodes, function (d) {
		      return d.name;
		    }).transition().delay(delays.update).duration(duration).attr('transform', function (d) {
		      var inst_index = _.indexOf(row_nodes_names, d.name);
		      return 'translate(0, ' + params.viz.y_scale(inst_index) + ')';
		    });
	
		    svg_group.selectAll('.row_cat_group').select('path').transition().delay(delays.update).duration(duration).attr('d', function () {
		      var origin_x = params.viz.cat_room.symbol_width - 1;
		      var origin_y = 0;
		      var mid_x = 1;
		      var mid_y = params.viz.y_scale.rangeBand() / 2;
		      var final_x = params.viz.cat_room.symbol_width - 1;
		      var final_y = params.viz.y_scale.rangeBand();
		      var output_string = 'M ' + origin_x + ',' + origin_y + ' L ' + mid_x + ',' + mid_y + ', L ' + final_x + ',' + final_y + ' Z';
		      return output_string;
		    });
	
		    svg_group.selectAll('.row_dendro_group').data(row_nodes, function (d) {
		      return d.name;
		    }).transition().delay(delays.update).duration(duration).attr('transform', function (d) {
		      var inst_index = _.indexOf(row_nodes_names, d.name);
		      return 'translate(0, ' + params.viz.y_scale(inst_index) + ')';
		    });
		  } else {
	
		    // positioning row text after row text size may have been reduced
		    svg_group.selectAll('.row_label_group').select('text').attr('y', params.viz.rect_height * 0.5 + params.labels.default_fs_row * 0.35);
	
		    svg_group.selectAll('.row_cat_group').data(row_nodes, function (d) {
		      return d.name;
		    }).attr('transform', function (d) {
		      var inst_index = _.indexOf(row_nodes_names, d.name);
		      return 'translate(0, ' + params.viz.y_scale(inst_index) + ')';
		    });
	
		    svg_group.selectAll('.row_cat_group').select('path').attr('d', function () {
		      var origin_x = params.viz.cat_room.symbol_width - 1;
		      var origin_y = 0;
		      var mid_x = 1;
		      var mid_y = params.viz.y_scale.rangeBand() / 2;
		      var final_x = params.viz.cat_room.symbol_width - 1;
		      var final_y = params.viz.y_scale.rangeBand();
		      var output_string = 'M ' + origin_x + ',' + origin_y + ' L ' + mid_x + ',' + mid_y + ', L ' + final_x + ',' + final_y + ' Z';
		      return output_string;
		    });
	
		    svg_group.selectAll('.row_dendro_group').data(row_nodes, function (d) {
		      return d.name;
		    }).attr('transform', function (d) {
		      var inst_index = _.indexOf(row_nodes_names, d.name);
		      return 'translate(0, ' + params.viz.y_scale(inst_index) + ')';
		    });
		  }
	
		  if (utils.has(params.network_data.row_nodes[0], 'value')) {
	
		    resize_label_bars(cgm, svg_group);
		  }
	
		  // resize col labels
		  ///////////////////////
		  // reduce width of rotated rects
	
		  resize_col_labels(params, svg_group, delays);
		  resize_col_text(params, svg_group);
		  resize_col_triangle(params, svg_group, delays);
	
		  resize_col_hlight(params, svg_group, delays);
	
		  resize_dendro(params, svg_group, delays);
		  resize_super_labels(params, svg_group, delays);
		  resize_spillover(params.viz, svg_group, delays);
	
		  // reset zoom and translate
		  params.zoom_behavior.scale(1).translate([params.viz.clust.margin.left, params.viz.clust.margin.top]);
			};
	
	/***/ },
	/* 147 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var exit_existing_row = __webpack_require__(148);
		var enter_existing_row = __webpack_require__(149);
		var update_split_tiles = __webpack_require__(150);
		var mouseover_tile = __webpack_require__(45);
		var mouseout_tile = __webpack_require__(46);
		var fine_position_tile = __webpack_require__(47);
	
		// TODO add tip back to arguments
		module.exports = function eeu_existing_row(params, ini_inp_row_data, delays, duration, row_selection, tip) {
	
		  var inp_row_data = ini_inp_row_data.row_data;
	
		  // remove zero values from
		  var row_values = _.filter(inp_row_data, function (num) {
		    return num.value != 0;
		  });
	
		  // bind data to tiles
		  var cur_row_tiles = d3.select(row_selection).selectAll('.tile').data(row_values, function (d) {
		    return d.col_name;
		  });
	
		  exit_existing_row(params, delays, cur_row_tiles, inp_row_data, row_selection);
	
		  ///////////////////////////
		  // Update
		  ///////////////////////////
	
		  // update tiles in x direction
		  var update_row_tiles = cur_row_tiles.on('mouseover', function () {
		    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
		      args[_key] = arguments[_key];
		    }
	
		    mouseover_tile(params, this, tip, args);
		  }).on('mouseout', function mouseout() {
		    mouseout_tile(params, this, tip);
		  });
	
		  var col_nodes_names = params.network_data.col_nodes_names;
	
		  if (delays.run_transition) {
	
		    update_row_tiles.transition().delay(delays.update).duration(duration).attr('width', params.viz.rect_width).attr('height', params.viz.rect_height).attr('transform', function (d) {
		      if (_.contains(col_nodes_names, d.col_name)) {
		        return fine_position_tile(params, d);
		      } else {
		        return 'translate(0,0)';
		      }
		    });
		  } else {
		    update_row_tiles.attr('width', params.viz.rect_width).attr('height', params.viz.rect_height).attr('transform', function (d) {
		      if (_.contains(col_nodes_names, d.col_name)) {
		        return fine_position_tile(params, d);
		      } else {
		        return 'translate(0,0)';
		      }
		    });
		  }
	
		  if (params.matrix.tile_type == 'updn') {
		    update_split_tiles(params, inp_row_data, row_selection, delays, duration, cur_row_tiles, tip);
		  }
	
		  enter_existing_row(params, delays, duration, cur_row_tiles, tip);
			};
	
	/***/ },
	/* 148 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function exit_existing_row(params, delays, cur_row_tiles, inp_row_data, row_selection) {
	
		  if (delays.run_transition) {
		    cur_row_tiles.exit().transition().duration(300).attr('fill-opacity', 0).remove();
		  } else {
		    cur_row_tiles.exit().attr('fill-opacity', 0).remove();
		  }
	
		  if (params.matrix.tile_type == 'updn') {
	
		    // value split
		    var row_split_data = _.filter(inp_row_data, function (num) {
		      return num.value_up != 0 || num.value_dn != 0;
		    });
	
		    // tile_up
		    var cur_tiles_up = d3.select(row_selection).selectAll('.tile_up').data(row_split_data, function (d) {
		      return d.col_name;
		    });
	
		    if (delays.run_transition) {
		      cur_tiles_up.exit().transition().duration(300).attr('fill', '0').remove();
		    } else {
		      cur_tiles_up.exit().attr('fill', 0).remove();
		    }
	
		    // tile_dn
		    var cur_tiles_dn = d3.select(row_selection).selectAll('.tile_dn').data(row_split_data, function (d) {
		      return d.col_name;
		    });
	
		    if (delays.run_transition) {
		      cur_tiles_dn.exit().transition().duration(300).attr('fill', 0).remove();
		    } else {
		      cur_tiles_dn.exit().attr('fill', 0).remove();
		    }
		  }
			};
	
	/***/ },
	/* 149 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var mouseover_tile = __webpack_require__(45);
		var mouseout_tile = __webpack_require__(46);
		var fine_position_tile = __webpack_require__(47);
	
		module.exports = function enter_existing_row(params, delays, duration, cur_row_tiles, tip) {
	
		  // enter new tiles
		  var new_tiles = cur_row_tiles.enter().append('rect').attr('class', 'tile row_tile').attr('width', params.viz.rect_width).attr('height', params.viz.rect_height).on('mouseover', function () {
		    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
		      args[_key] = arguments[_key];
		    }
	
		    mouseover_tile(params, this, tip, args);
		  }).on('mouseout', function mouseout() {
		    mouseout_tile(params, this, tip);
		  }).attr('fill-opacity', 0).attr('transform', function (d) {
		    return fine_position_tile(params, d);
		  });
	
		  if (delays.run_transition) {
		    new_tiles.transition().delay(delays.enter).duration(duration).style('fill', function (d) {
		      return d.value > 0 ? params.matrix.tile_colors[0] : params.matrix.tile_colors[1];
		    }).attr('fill-opacity', function (d) {
		      var output_opacity = params.matrix.opacity_scale(Math.abs(d.value));
		      return output_opacity;
		    });
		  } else {
		    new_tiles.style('fill', function (d) {
		      return d.value > 0 ? params.matrix.tile_colors[0] : params.matrix.tile_colors[1];
		    }).attr('fill-opacity', function (d) {
		      var output_opacity = params.matrix.opacity_scale(Math.abs(d.value));
		      return output_opacity;
		    });
		  }
	
		  // remove new tiles if necessary
		  new_tiles.each(function (d) {
		    if (Math.abs(d.value_up) > 0 && Math.abs(d.value_dn) > 0) {
		      d3.select(this).remove();
		    }
		  });
		};
	
	/***/ },
	/* 150 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var draw_up_tile = __webpack_require__(43);
		var draw_dn_tile = __webpack_require__(44);
		var mouseover_tile = __webpack_require__(45);
		var mouseout_tile = __webpack_require__(46);
		var fine_position_tile = __webpack_require__(47);
	
		module.exports = function update_split_tiles(params, inp_row_data, row_selection, delays, duration, cur_row_tiles, tip) {
	
		  // value split
		  var row_split_data = _.filter(inp_row_data, function (num) {
		    return num.value_up != 0 || num.value_dn != 0;
		  });
	
		  // tile_up
		  var cur_tiles_up = d3.select(row_selection).selectAll('.tile_up').data(row_split_data, function (d) {
		    return d.col_name;
		  });
	
		  // update split tiles_up
		  var update_tiles_up = cur_tiles_up.on('mouseover', function () {
		    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
		      args[_key] = arguments[_key];
		    }
	
		    mouseover_tile(params, this, tip, args);
		  }).on('mouseout', function mouseout() {
		    mouseout_tile(params, this, tip);
		  });
	
		  if (delays.run_transition) {
		    update_tiles_up.transition().delay(delays.update).duration(duration).attr('d', function () {
		      return draw_up_tile(params);
		    }).attr('transform', function (d) {
		      return fine_position_tile(params, d);
		    });
		  } else {
		    update_tiles_up.attr('d', function () {
		      return draw_up_tile(params);
		    }).attr('transform', function (d) {
		      return fine_position_tile(params, d);
		    });
		  }
	
		  // tile_dn
		  var cur_tiles_dn = d3.select(row_selection).selectAll('.tile_dn').data(row_split_data, function (d) {
		    return d.col_name;
		  });
	
		  // update split tiles_dn
		  var update_tiles_dn = cur_tiles_dn.on('mouseover', function () {
		    for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
		      args[_key2] = arguments[_key2];
		    }
	
		    mouseover_tile(params, this, tip, args);
		  }).on('mouseout', function mouseout() {
		    mouseout_tile(params, this, tip);
		  });
	
		  if (delays.run_transition) {
		    update_tiles_dn.transition().delay(delays.update).duration(duration).attr('d', function () {
		      return draw_dn_tile(params);
		    }).attr('transform', function (d) {
		      return fine_position_tile(params, d);
		    });
		  } else {
		    update_tiles_dn.attr('d', function () {
		      return draw_dn_tile(params);
		    }).attr('transform', function (d) {
		      return fine_position_tile(params, d);
		    });
		  }
	
		  // remove tiles when splitting is done
		  cur_row_tiles.selectAll('.tile').each(function (d) {
		    if (Math.abs(d.value_up) > 0 && Math.abs(d.value_dn) > 0) {
		      d3.select(this).remove();
		    }
		  });
		};
	
	/***/ },
	/* 151 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function exit_components(params, delays, duration) {
	
		  var row_nodes = params.network_data.row_nodes;
		  var col_nodes = params.network_data.col_nodes;
	
		  // remove entire rows
		  var exiting_rows = d3.select(params.root + ' .clust_group').selectAll('.row').data(params.matrix.matrix, function (d) {
		    return d.name;
		  }).exit();
	
		  if (delays.run_transition) {
		    exiting_rows.transition().duration(duration).style('opacity', 0).remove();
		  } else {
		    exiting_rows.style('opacity', 0).remove();
		  }
	
		  // remove row labels
		  d3.selectAll(params.root + ' .row_label_group').data(row_nodes, function (d) {
		    return d.name;
		  }).exit().transition().duration(duration).style('opacity', 0).remove();
	
		  // remove column labels
		  d3.selectAll(params.root + ' .col_label_group').data(col_nodes, function (d) {
		    return d.name;
		  }).exit().transition().duration(duration).style('opacity', 0).remove();
	
		  // remove row triangles and colorbars
		  d3.selectAll(params.root + ' .row_cat_group').data(row_nodes, function (d) {
		    return d.name;
		  }).exit().transition().duration(duration).style('opacity', 0).remove();
	
		  // remove row triangles and colorbars
		  d3.selectAll(params.root + ' .row_dendro_group').data(row_nodes, function (d) {
		    return d.name;
		  }).exit().transition().duration(duration).style('opacity', 0).remove();
	
		  d3.selectAll(params.root + ' .col_label_text').data(col_nodes, function (d) {
		    return d.name;
		  }).exit().transition().duration(duration).style('opacity', 0).remove();
	
		  d3.selectAll(params.root + ' .horz_lines').data(row_nodes, function (d) {
		    return d.name;
		  }).exit().transition().duration(duration).style('opacity', 0).remove();
	
		  d3.selectAll(params.root + ' .vert_lines').data(col_nodes, function (d) {
		    return d.name;
		  }).exit().transition().duration(duration).style('opacity', 0).remove();
	
		  // remove dendrogram
		  d3.selectAll(params.root + ' .col_cat_group').data(col_nodes, function (d) {
		    return d.name;
		  }).exit().transition().duration(duration).style('opacity', 0).remove();
	
		  d3.selectAll(params.root + ' .col_dendro_group').data(col_nodes, function (d) {
		    return d.name;
		  }).exit().transition().duration(duration).style('opacity', 0).remove();
			};
	
	/***/ },
	/* 152 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var enter_new_rows = __webpack_require__(153);
	
		module.exports = function enter_row_groups(params, delays, duration, tip) {
	
		  // enter new rows
		  var new_row_groups = d3.select(params.root + ' .clust_group').selectAll('.row').data(params.matrix.matrix, function (d) {
		    return d.name;
		  }).enter().append('g').classed('row', true).attr('transform', function (d) {
		    return 'translate(0,' + params.viz.y_scale(d.row_index) + ')';
		  });
	
		  new_row_groups.each(function (d) {
		    enter_new_rows(params, d, delays, duration, tip, this);
		  });
			};
	
	/***/ },
	/* 153 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var enter_split_tiles = __webpack_require__(154);
		var mouseover_tile = __webpack_require__(45);
		var mouseout_tile = __webpack_require__(46);
		var fine_position_tile = __webpack_require__(47);
	
		// make each row in the clustergram
		module.exports = function enter_new_rows(params, ini_inp_row_data, delays, duration, tip, row_selection) {
	
		  var inp_row_data = ini_inp_row_data.row_data;
	
		  // remove zero values to make visualization faster
		  var row_data = _.filter(inp_row_data, function (num) {
		    return num.value !== 0;
		  });
	
		  // update tiles
		  ////////////////////////////////////////////
		  var tile = d3.select(row_selection).selectAll('rect').data(row_data, function (d) {
		    return d.col_name;
		  }).enter().append('rect').attr('class', 'tile row_tile').attr('width', params.viz.rect_width).attr('height', params.viz.rect_height)
		  // switch the color based on up/dn value
		  .style('fill', function (d) {
		    return d.value > 0 ? params.matrix.tile_colors[0] : params.matrix.tile_colors[1];
		  }).on('mouseover', function () {
		    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
		      args[_key] = arguments[_key];
		    }
	
		    mouseover_tile(params, this, tip, args);
		  }).on('mouseout', function mouseout() {
		    mouseout_tile(params, this, tip);
		  });
	
		  tile.style('fill-opacity', 0).transition().delay(delays.enter).duration(duration).style('fill-opacity', function (d) {
		    // calculate output opacity using the opacity scale
		    var output_opacity = params.matrix.opacity_scale(Math.abs(d.value));
		    return output_opacity;
		  });
	
		  tile.attr('transform', function (d) {
		    return fine_position_tile(params, d);
		  });
	
		  if (params.matrix.tile_type == 'updn') {
		    enter_split_tiles(params, inp_row_data, row_selection, tip, delays, duration, tile);
		  }
			};
	
	/***/ },
	/* 154 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var draw_up_tile = __webpack_require__(43);
		var draw_dn_tile = __webpack_require__(44);
		var fine_position_tile = __webpack_require__(47);
	
		module.exports = function enter_split_tiles(params, inp_row_data, row_selection, tip, delays, duration, tile) {
	
		  // value split
		  var row_split_data = _.filter(inp_row_data, function (num) {
		    return num.value_up != 0 || num.value_dn != 0;
		  });
	
		  // tile_up
		  var new_tiles_up = d3.select(row_selection).selectAll('.tile_up').data(row_split_data, function (d) {
		    return d.col_name;
		  }).enter().append('path').attr('class', 'tile_up').attr('d', function () {
		    return draw_up_tile(params);
		  }).attr('transform', function (d) {
		    return fine_position_tile(params, d);
		  }).style('fill', function () {
		    return params.matrix.tile_colors[0];
		  }).on('mouseover', function (p) {
		    // highlight row - set text to active if
		    d3.selectAll(params.root + ' .row_label_group text').classed('active', function (d) {
		      return p.row_name === d.name;
		    });
	
		    d3.selectAll(params.root + ' .col_label_text text').classed('active', function (d) {
		      return p.col_name === d.name;
		    });
		    if (params.matrix.show_tile_tooltips) {
		      tip.show(p);
		    }
		  }).on('mouseout', function () {
		    d3.selectAll(params.root + ' text').classed('active', false);
		    if (params.matrix.show_tile_tooltips) {
		      tip.hide();
		    }
		  });
	
		  new_tiles_up.style('fill-opacity', 0).transition().delay(delays.enter).duration(duration).style('fill-opacity', function (d) {
		    var inst_opacity = 0;
		    if (Math.abs(d.value_dn) > 0) {
		      inst_opacity = params.matrix.opacity_scale(Math.abs(d.value_up));
		    }
		    return inst_opacity;
		  });
	
		  // tile_dn
		  var new_tiles_dn = d3.select(row_selection).selectAll('.tile_dn').data(row_split_data, function (d) {
		    return d.col_name;
		  }).enter().append('path').attr('class', 'tile_dn').attr('d', function () {
		    return draw_dn_tile(params);
		  }).attr('transform', function (d) {
		    return fine_position_tile(params, d);
		  }).style('fill', function () {
		    return params.matrix.tile_colors[1];
		  }).on('mouseover', function (p) {
		    // highlight row - set text to active if
		    d3.selectAll(params.root + ' .row_label_group text').classed('active', function (d) {
		      return p.row_name === d.name;
		    });
	
		    d3.selectAll(params.root + ' .col_label_text text').classed('active', function (d) {
		      return p.col_name === d.name;
		    });
		    if (params.matrix.show_tile_tooltips) {
		      tip.show(p);
		    }
		  }).on('mouseout', function () {
		    d3.selectAll(params.root + ' text').classed('active', false);
		    if (params.matrix.show_tile_tooltips) {
		      tip.hide();
		    }
		  });
	
		  new_tiles_dn.style('fill-opacity', 0).transition().delay(delays.enter).duration(duration).style('fill-opacity', function (d) {
		    var inst_opacity = 0;
		    if (Math.abs(d.value_up) > 0) {
		      inst_opacity = params.matrix.opacity_scale(Math.abs(d.value_dn));
		    }
		    return inst_opacity;
		  });
	
		  // remove tiles when splitting is done
		  tile.each(function (d) {
		    if (Math.abs(d.value_up) > 0 && Math.abs(d.value_dn) > 0) {
		      d3.select(this).remove();
		    }
		  });
			};
	
	/***/ },
	/* 155 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function resize_containers(params) {
	
		  // reposition matrix
		  d3.select(params.root + ' .clust_container').attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.clust.margin.top + ')');
	
		  // reposition col container
		  d3.select(params.root + ' .col_label_outer_container').attr('transform', 'translate(0,' + params.viz.norm_labels.width.col + ')');
	
		  // reposition col_viz container
		  d3.select(params.root + ' .col_cat_outer_container').attr('transform', function () {
		    var inst_offset = params.viz.norm_labels.width.col + 2;
		    return 'translate(0,' + inst_offset + ')';
		  });
			};
	
	/***/ },
	/* 156 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		/* eslint-disable */
	
		var change_groups = __webpack_require__(127);
		var all_reorder = __webpack_require__(79);
		var ini_cat_reorder = __webpack_require__(78);
		var run_row_search = __webpack_require__(157);
	
		module.exports = function ini_sidebar(cgm) {
	
		  var params = cgm.params;
	
		  var input = d3.select(params.root + ' .gene_search_box')[0][0];
		  var awesomplete = new Awesomplete(input, { minChars: 1, maxItems: 15 });
		  var entities = cgm.params.network_data.row_nodes_names;
		  awesomplete.list = entities;
	
		  // position awesomplete list elements above other elements in the page
		  d3.selectAll('.awesomplete ul').style('z-index', 99);
	
		  // submit genes button
		  $(params.root + ' .gene_search_box').keyup(function (e) {
		    if (e.keyCode === 13) {
		      var search_gene = $(params.root + ' .gene_search_box').val();
		      run_row_search(cgm, search_gene, entities);
		    }
		  });
	
		  $(params.root + ' .submit_gene_button').off().click(function () {
		    var search_gene = $(params.root + ' .gene_search_box').val();
		    run_row_search(cgm, search_gene, entities);
		  });
	
		  var reorder_types;
		  if (params.sim_mat) {
		    reorder_types = ['both'];
		  } else {
		    reorder_types = ['row', 'col'];
		  }
	
		  _.each(reorder_types, function (inst_rc) {
	
		    // reorder buttons
		    $(params.root + ' .toggle_' + inst_rc + '_order .btn').off().click(function (evt) {
	
		      var order_id = $(evt.target).attr('name').replace('_row', '').replace('_col', '');
	
		      d3.selectAll(params.root + ' .toggle_' + inst_rc + '_order .btn').classed('active', false);
	
		      d3.select(this).classed('active', true);
	
		      if (inst_rc != 'both') {
		        all_reorder(cgm, order_id, inst_rc);
		      } else {
		        all_reorder(cgm, order_id, 'row');
		        all_reorder(cgm, order_id, 'col');
		      }
		    });
		  });
	
		  ini_cat_reorder(cgm);
	
		  // Opacity Slider
		  //////////////////////////////////////////////////////////////////////
		  if (d3.select(cgm.params.root + ' .opacity_slider').select('#handle-one').empty()) {
	
		    var slider_fun = d3.slider().snap(true).value(1).min(0.1).max(1.9).step(0.1).on('slide', function (evt, value) {
		      run_on_opacity_slide(evt, value);
		    });
	
		    d3.select(cgm.params.root + ' .opacity_slider').call(slider_fun);
		  }
	
		  function run_on_dendro_slide(evt, value, inst_rc) {
		    $("#amount").val("$" + value);
		    var inst_index = value * 10;
		    // var inst_rc;
	
		    if (inst_rc != 'both') {
		      change_groups(cgm, inst_rc, inst_index);
		    } else {
		      change_groups(cgm, 'row', inst_index);
		      change_groups(cgm, 'col', inst_index);
		    }
		  }
	
		  function run_on_opacity_slide(evt, value) {
	
		    var inst_index = 2 - value;
		    var scaled_max = cgm.params.matrix.abs_max_val * inst_index;
	
		    cgm.params.matrix.opacity_scale.domain([0, scaled_max]);
	
		    d3.selectAll(cgm.params.root + ' .tile').style('fill-opacity', function (d) {
		      // calculate output opacity using the opacity scale
		      var output_opacity = cgm.params.matrix.opacity_scale(Math.abs(d.value));
		      return output_opacity;
		    });
		  }
			};
	
	/***/ },
	/* 157 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var two_translate_zoom = __webpack_require__(80);
	
		module.exports = function run_row_search(cgm, search_term, entities) {
	
		  var prop = 'name';
	
		  if (entities.indexOf(search_term) !== -1) {
	
		    // unhighlight
		    d3.selectAll(cgm.params.root + ' .row_label_group').select('rect').style('opacity', 0);
	
		    // calc pan_dy
		    var idx = _.indexOf(entities, search_term);
		    var inst_y_pos = cgm.params.viz.y_scale(idx);
		    var pan_dy = cgm.params.viz.clust.dim.height / 2 - inst_y_pos;
	
		    var inst_zoom = cgm.params.viz.zoom_ratio.x;
	
		    // working on improving zoom behavior
		    ///////////////////////////////////////////////////
		    ///////////////////////////////////////////////////
	
		    // // increase zoom
		    // inst_zoom = 3 * inst_zoom;
	
		    // // move visualization down less
		    // pan_dy = pan_dy - 5;
	
		    two_translate_zoom(cgm, 0, pan_dy, inst_zoom);
	
		    // set y zoom to zoom_switch
		    cgm.params.zoom_info.zoom_y = inst_zoom;
	
		    // highlight
		    d3.selectAll(cgm.params.root + ' .row_label_group').filter(function (d) {
		      return d[prop] === search_term;
		    }).select('rect').style('opacity', 1);
		  }
			};
	
	/***/ },
	/* 158 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function enable_sidebar(params) {
	
		  /* only enable dendrogram sliders if there has been no dendro_filtering */
	
		  // only enable reordering if params.dendro_filter.row === false
		  if (params.dendro_filter.row === false) {
	
		    // orders are switched!
		    if (params.viz.inst_order.col === 'clust') {
		      d3.select(params.root + ' .row_slider_group').style('opacity', 1).style('pointer-events', 'all');
		    }
		  }
	
		  d3.selectAll(params.root + ' .toggle_row_order .btn').attr('disabled', null);
	
		  if (params.dendro_filter.col === false) {
	
		    // orders are switched!
		    if (params.viz.inst_order.row === 'clust') {
		      d3.select(params.root + ' .col_slider_group').style('opacity', 1).style('pointer-events', 'all');
		    }
		  }
	
		  d3.selectAll(params.root + ' .toggle_col_order .btn').attr('disabled', null);
	
		  d3.selectAll(params.root + ' .gene_search_button .btn').attr('disabled', null);
	
		  params.viz.run_trans = false;
			};
	
	/***/ },
	/* 159 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function update_reorder_buttons(tmp_config, params) {
		  _.each(['row', 'col'], function (inst_rc) {
	
		    var other_rc;
		    if (inst_rc === 'row') {
		      other_rc = 'col';
		    } else {
		      other_rc = 'row';
		    }
	
		    d3.selectAll(params.root + ' .toggle_' + other_rc + '_order .btn').filter(function () {
		      return d3.select(this).attr('name') === tmp_config.inst_order[inst_rc];
		    }).classed('active', true);
		  });
		};
	
	/***/ },
	/* 160 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var remove_node_cats = __webpack_require__(161);
		var utils = __webpack_require__(2);
	
		module.exports = function modify_row_node_cats(cat_data, inst_nodes) {
		  var strip_names = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];
	
	
		  // console.log('MODIFY ROW NODE CATS')
		  // console.log('CAT_DATA')
		  // console.log(cat_data)
	
		  var cat_type_num = 0;
		  var inst_index = 0;
		  var inst_cat_title;
		  var inst_cats;
		  var inst_members;
		  var inst_name;
		  var inst_category;
		  var inst_cat_name;
		  var inst_full_cat;
		  var inst_cat_num;
	
		  // loop through row nodes
		  //////////////////////////
		  _.each(inst_nodes, function (inst_node) {
	
		    inst_name = inst_node.name;
	
		    // not sure if this is needed
		    // inst_name = inst_name.toUpperCase();
	
		    if (strip_names === true) {
		      // only consider first part of inst_name
		      ////////////////////////////////////////////
		      // may improve this
		      if (inst_name.indexOf(' ')) {
		        inst_name = inst_name.split(' ')[0];
		      } else if (inst_name.indexOf('_')) {
		        inst_name = inst_name.split('_')[0];
		      }
		    }
	
		    cat_type_num = 0;
	
		    remove_node_cats(inst_node);
	
		    // loop through each category type
		    _.each(cat_data, function (inst_cat_data) {
	
		      inst_cat_title = inst_cat_data.cat_title;
		      inst_cats = inst_cat_data.cats;
	
		      // initialize with no category
		      inst_category = 'false';
		      inst_index = -1;
	
		      inst_cat_num = 0;
	
		      // loop through each category in the category-type
		      _.each(inst_cats, function (inst_cat) {
	
		        inst_cat_name = inst_cat.cat_name;
		        inst_members = inst_cat.members;
	
		        // add category if node is a member
		        if (_.contains(inst_members, inst_name)) {
	
		          inst_category = inst_cat_name;
		          inst_index = inst_cat_num;
		        }
	
		        inst_cat_num = inst_cat_num + 1;
		      });
	
		      if (utils.has(inst_cat_data, 'pval')) {
	
		        var inst_pval = inst_cat_data.pval.toExponential();
		        inst_full_cat = inst_cat_title + ': ' + inst_category + '<p> Pval ' + String(inst_pval) + '</p>';
		      } else {
	
		        if (inst_cat_title.indexOf('cat-') === -1) {
		          inst_full_cat = inst_cat_title + ': ' + inst_category;
		        } else {
		          inst_full_cat = inst_category;
		        }
		      }
	
		      inst_node['cat-' + String(cat_type_num)] = inst_full_cat;
		      inst_node['cat_' + String(cat_type_num) + '_index'] = inst_index;
	
		      cat_type_num = cat_type_num + 1;
		    });
		  });
			};
	
	/***/ },
	/* 161 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function remove_node_cats(inst_node) {
	
		  var all_props = _.keys(inst_node);
	
		  _.each(all_props, function (inst_prop) {
	
		    if (inst_prop.indexOf('cat-') > -1) {
		      delete inst_node[inst_prop];
		    }
	
		    if (inst_prop.indexOf('cat_') > -1) {
		      delete inst_node[inst_prop];
		    }
		  });
			};
	
	/***/ },
	/* 162 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var reset_size_after_update = __webpack_require__(146);
		var make_col_label_container = __webpack_require__(67);
		var show_visible_area = __webpack_require__(70);
		var resize_containers = __webpack_require__(155);
	
		module.exports = function ds_enter_exit_update(cgm) {
	
		  // console.log('======== ds_enter_exit_update ===============');
	
		  // remove row labels, remove non-downsampled rows, and add downsampled rows
		  d3.selectAll(cgm.params.root + ' .row_cat_group').remove();
		  d3.selectAll(cgm.params.root + ' .row_label_group').remove();
		  d3.selectAll(cgm.params.root + ' .row').remove();
	
		  // no need to re-calculate the downsampled layers
		  // calc_downsampled_levels(params);
		  var zooming_stopped = true;
		  var zooming_out = true;
		  var make_all_rows = true;
	
		  // show_visible_area is also run with two_translate_zoom, but at that point
		  // the parameters were not updated and two_translate_zoom if only run
		  // if needed to reset zoom
		  show_visible_area(cgm, zooming_stopped, zooming_out, make_all_rows);
	
		  make_col_label_container(cgm);
	
		  var col_nodes = cgm.params.network_data.col_nodes;
	
		  // remove column labels
		  d3.selectAll(cgm.params.root + ' .col_label_group').data(col_nodes, function (d) {
		    return d.name;
		  }).exit().style('opacity', 0).remove();
	
		  d3.selectAll(cgm.params.root + ' .col_label_text').data(col_nodes, function (d) {
		    return d.name;
		  }).exit().style('opacity', 0).remove();
	
		  d3.selectAll(cgm.params.root + ' .col_cat_group').data(col_nodes, function (d) {
		    return d.name;
		  }).exit().style('opacity', 0).remove();
	
		  d3.selectAll(cgm.params.root + ' .col_dendro_group').data(col_nodes, function (d) {
		    return d.name;
		  }).exit().style('opacity', 0).remove();
	
		  // necessary for repositioning clust, col and col-cat containers
		  resize_containers(cgm.params);
	
		  // seeing if this fixes resizing issue
		  var delays = {};
		  delays.enter = 0;
		  delays.update = 0;
		  delays.run_transition = false;
		  var duration = 0;
		  reset_size_after_update(cgm, duration, delays);
			};
	
	/***/ },
	/* 163 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var sim_click = __webpack_require__(135);
	
		module.exports = function quick_cluster() {
		  /* eslint-disable */
	
		  function run(params) {
	
		    var x_trans = Number(d3.select(params.root + ' .expand_button').attr('x').replace('px', ''));
		    var y_trans = Number(d3.select(params.root + ' .expand_button').attr('y').replace('px', ''));
	
		    var wait_click = 0;
		    var wait_real_click = 400;
		    setTimeout(sim_click, wait_click, params, 'single', x_trans, y_trans);
		    setTimeout(click_menu_button, wait_real_click, params);
	
		    setTimeout(reset_cluster_order, 1500, params);
		  }
	
		  function get_duration() {
		    return 3500;
		  }
	
		  function click_menu_button(params) {
		    $(params.root + ' .expand_button').d3Click();
		  };
	
		  function reset_cluster_order(params) {
		    click_reorder_button(params, 'row', 'clust');
		    click_reorder_button(params, 'col', 'clust');
		  }
	
		  function click_reorder_button(params, inst_rc, inst_order) {
		    var inst_button = d3.selectAll('.toggle_' + inst_rc + '_order .btn').filter(function () {
		      return this.__data__ == inst_order;
		    })[0];
	
		    $(inst_button).click();
		  }
	
		  // allows doubleclicking on d3 element
		  jQuery.fn.d3Click = function () {
		    this.each(function (i, e) {
		      var evt = document.createEvent("MouseEvents");
		      evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
		      e.dispatchEvent(evt);
		    });
		  };
	
		  return {
		    run: run,
		    get_duration: get_duration
		  };
			};
	
	/***/ },
	/* 164 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var demo_text = __webpack_require__(132);
		var highlight_sidebar_element = __webpack_require__(138);
		var change_groups = __webpack_require__(127);
	
		module.exports = function play_groups() {
		  /* eslint-disable */
	
		  function run(params) {
	
		    var text = 'Identify row and column groups\nof varying sizes using ' + ' the\nsliders and dendrogram';
		    demo_text(params, text, 10000);
	
		    setTimeout(highlight_sidebar_element, 3000, params, 'slider_col', 7000);
	
		    setTimeout(change_group_slider, 4000, params, 'row', 3);
		    setTimeout(change_group_slider, 5000, params, 'row', 4);
		    setTimeout(change_group_slider, 6000, params, 'row', 5);
		    setTimeout(change_group_slider, 7000, params, 'row', 6);
		    setTimeout(change_group_slider, 8000, params, 'row', 7);
		    setTimeout(change_group_slider, 9000, params, 'row', 5);
		  }
	
		  function get_duration() {
		    return 11000;
		  }
	
		  function change_group_slider(params, inst_rc, inst_value) {
		    $(cgm.params.root + ' .slider_col').slider("value", inst_value / 10);
		    change_groups(cgm, inst_rc, inst_value);
		  }
	
		  return {
		    run: run,
		    get_duration: get_duration
		  };
			};
	
	/***/ },
	/* 165 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var demo_text = __webpack_require__(132);
		var sim_click = __webpack_require__(135);
	
		module.exports = function play_category() {
		  /* eslint-disable */
	
		  function run(params) {
	
		    var text = 'Row and column categories\ncan be use to reorder\nby double-clicking';
		    demo_text(params, text, 7000);
	
		    var inst_element = d3.selectAll(params.root + ' .col_cat_super').filter(function () {
		      return this.__data__ === 'cat-1';
		    })[0];
	
		    var tmp_pos = d3.select('.col_cat_super').attr('transform');
		    var x_trans = Number(tmp_pos.split('(')[1].split(',')[0].replace(')', '')) + 20;
		    var y_trans = Number(tmp_pos.split(',')[1].replace(')', ''));
	
		    var wait_click = 4000;
		    setTimeout(sim_click, wait_click, params, 'double', x_trans, y_trans);
	
		    var wait_reorder = wait_click + 300;
		    setTimeout(fire_double_click_row, wait_reorder, params, inst_element);
		  }
	
		  function get_duration() {
		    return 8000;
		  }
	
		  function fire_double_click_row(params, inst_element) {
		    $(inst_element).d3DblClick();
		  }
	
		  // allows doubleclicking on d3 element
		  jQuery.fn.d3DblClick = function () {
		    this.each(function (i, e) {
		      var evt = document.createEvent("MouseEvents");
		      evt.initMouseEvent("dblclick", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
		      e.dispatchEvent(evt);
		    });
		  };
		  return {
		    run: run,
		    get_duration: get_duration
		  };
			};
	
	/***/ },
	/* 166 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var demo_text = __webpack_require__(132);
		var toggle_play_button = __webpack_require__(167);
	
		module.exports = function play_conclusion() {
	
		  function run(params) {
		    var text_1 = "Clustergrammer is built with gene\nexpression data in mind" + " and interfaces\nwith several Ma'ayan lab web tools";
		    var text_2 = "The example data being visualized is\ngene expression data" + " obtained from the\nCancer Cell Line Encyclopedia";
		    var text_3 = "For more information please view\nthe help documentation";
	
		    setTimeout(demo_text, 0, params, text_1, 4500);
		    setTimeout(demo_text, 4500, params, text_2, 4500);
		    setTimeout(demo_text, 9000, params, text_3, 4500);
	
		    setTimeout(reset_demo, 14000, params);
		  }
	
		  function reset_demo(params) {
	
		    // prevent more than one demo from running at once 
		    d3.select(params.root + ' .play_button').classed('running_demo', false);
	
		    toggle_play_button(params, true);
		  }
	
		  function get_duration() {
		    return 12000;
		  }
	
		  return {
		    run: run,
		    get_duration: get_duration
		  };
			};
	
	/***/ },
	/* 167 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function toggle_play_button(params, show) {
	
		  if (show === false) {
		    d3.select(params.root + ' .play_button').transition().duration(500).style('opacity', 0);
		  } else {
		    d3.select(params.root + ' .play_button').transition().duration(500).style('opacity', 1);
	
		    $.unblockUI();
		  }
			};
	
	/***/ },
	/* 168 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var demo_text = __webpack_require__(132);
		var sim_click = __webpack_require__(135);
	
		module.exports = function play_menu_button() {
		  /* eslint-disable */
	
		  function run(params) {
	
		    var text = 'View additional controls\nby clicking the menu button';
		    demo_text(params, text, 4000);
	
		    // var inst_element = get_row_element(params, 'EGFR');
	
		    // var group_trans = d3.select(inst_element).attr('transform');
	
		    // var container_trans = d3.select(params.root+' .clust_container')
		    //   .attr('transform')
		    //   .split(',')[1].replace(')','');
	
		    // var x_trans = params.viz.norm_labels.width.row * 0.9;
	
		    // var row_trans = group_trans.split(',')[1].replace(')','');
		    // var y_trans = String(Number(row_trans) + Number(container_trans) + 
		    //   params.viz.rect_height/2);
	
		    var x_trans = Number(d3.select(params.root + ' .expand_button').attr('x').replace('px', ''));
		    var y_trans = Number(d3.select(params.root + ' .expand_button').attr('y').replace('px', ''));
	
		    var wait_click = 3000;
		    var wait_real_click = 3400;
		    setTimeout(sim_click, wait_click, params, 'single', x_trans, y_trans);
		    setTimeout(click_menu_button, wait_real_click, params);
		  }
	
		  function get_duration() {
		    return 5000;
		  }
	
		  function click_menu_button(params) {
		    $(params.root + ' .expand_button').d3Click();
		  };
	
		  function get_row_element(params, inst_row) {
	
		    var inst_element = d3.selectAll(params.root + ' .row_label_group').filter(function () {
		      var inst_data = this.__data__;
		      return inst_data.name == inst_row;
		    })[0][0];
	
		    return inst_element;
		  }
	
		  // allows doubleclicking on d3 element
		  jQuery.fn.d3Click = function () {
		    this.each(function (i, e) {
		      var evt = document.createEvent("MouseEvents");
		      evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
		      e.dispatchEvent(evt);
		    });
		  };
	
		  // allows doubleclicking on d3 element
		  jQuery.fn.d3DblClick = function () {
		    this.each(function (i, e) {
		      var evt = document.createEvent("MouseEvents");
		      evt.initMouseEvent("dblclick", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
		      e.dispatchEvent(evt);
		    });
		  };
		  return {
		    run: run,
		    get_duration: get_duration
		  };
			};
	
	/***/ },
	/* 169 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var make_play_button = __webpack_require__(170);
		var make_demo_text_containers = __webpack_require__(171);
	
		module.exports = function ini_demo() {
	
		  var cgm = this;
		  var params = cgm.params;
	
		  make_play_button(cgm);
	
		  var demo_text_size = 30;
		  make_demo_text_containers(params, demo_text_size);
			};
	
	/***/ },
	/* 170 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var position_play_button = __webpack_require__(113);
	
		module.exports = function make_play_button(cgm) {
	
		  var params = cgm.params;
	
		  if (d3.select(params.root + ' .play_button').empty()) {
	
		    var play_button = d3.select(params.root + ' .viz_svg').append('g').classed('play_button', true).classed('running_demo', false);
	
		    position_play_button(params);
	
		    play_button.append('circle').style('r', 45).style('fill', 'white').style('stroke', 'black').style('stroke-width', '3px').style('opacity', 0.5);
	
		    play_button.append('path').attr('d', function () {
	
		      var tri_w = 40;
		      var tri_h = 22;
		      var tri_offset = 15;
	
		      return 'M-' + tri_offset + ',-' + tri_h + ' l ' + tri_w + ',' + tri_h + ' l -' + tri_w + ',' + tri_h + ' z ';
		    }).style('fill', 'black').style('opacity', 0.5);
	
		    // mouseover behavior
		    play_button.on('mouseover', function () {
		      d3.select(this).select('path').style('fill', 'red').style('opacity', 1);
	
		      d3.select(this).select('circle').style('opacity', 1);
		    }).on('mouseout', function () {
		      d3.select(this).select('path').style('fill', 'black').style('opacity', 0.5);
		      d3.select(this).select('circle').style('opacity', 0.5);
		    }).on('click', function () {
		      // running from anonymous function to keep this defined correctly 
		      cgm.play_demo();
		    });
		  }
			};
	
	/***/ },
	/* 171 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function make_demo_text_containers(params, demo_text_size) {
	
		  if (d3.select(params.root + ' .demo_group').empty()) {
	
		    var clust_transform = d3.select(params.root + ' .clust_container').attr('transform');
		    var clust_x = Number(clust_transform.split('(')[1].split(',')[0]);
		    var clust_y = Number(clust_transform.split(',')[1].replace(')', ''));
	
		    // demo text container 
		    var demo_group = d3.select(params.root + ' .viz_svg').append('g').classed('demo_group', true).attr('transform', function () {
		      var pos_x = clust_x + 20;
		      var pos_y = clust_y + 40;
		      return 'translate(' + pos_x + ',' + pos_y + ')';
		    });
	
		    demo_group.append('rect').classed('rect_1', true);
	
		    demo_group.append('rect').classed('rect_2', true);
	
		    demo_group.append('rect').classed('rect_3', true);
	
		    var shift_height = 1.3 * demo_text_size;
	
		    demo_group.append('text').attr('id', 'text_1').attr('font-size', demo_text_size + 'px').attr('font-weight', 1000).attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif');
	
		    demo_group.append('text').attr('id', 'text_2').attr('font-size', demo_text_size + 'px').attr('font-weight', 1000).attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').attr('transform', function () {
		      return 'translate(0,' + String(shift_height) + ')';
		    });
	
		    demo_group.append('text').attr('id', 'text_3').attr('font-size', demo_text_size + 'px').attr('font-weight', 1000).attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').attr('transform', function () {
		      return 'translate(0,' + String(2 * shift_height) + ')';
		    });
		  }
			};
	
	/***/ },
	/* 172 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var filter_network_using_new_nodes = __webpack_require__(11);
		var update_viz_with_network = __webpack_require__(143);
	
		module.exports = function filter_viz_using_nodes(new_nodes) {
	
		  var new_network_data = filter_network_using_new_nodes(this.config, new_nodes);
		  update_viz_with_network(this, new_network_data);
			};
	
	/***/ },
	/* 173 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var filter_network_using_new_nodes = __webpack_require__(11);
		var update_viz_with_network = __webpack_require__(143);
	
		module.exports = function filter_viz_using_names(names) {
		  var external_cgm = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
	
	
		  // names is an object with row and column names that will be used to filter
		  // the matrix
	
		  var cgm;
		  if (external_cgm === false) {
		    cgm = this;
		  } else {
		    cgm = external_cgm;
		  }
	
		  var params = cgm.params;
		  var new_nodes = {};
		  var found_nodes;
	
		  _.each(['row', 'col'], function (inst_rc) {
	
		    var orig_nodes = params.inst_nodes[inst_rc + '_nodes'];
	
		    if (_.has(names, inst_rc)) {
	
		      if (names[inst_rc].length > 0) {
		        var inst_names = names[inst_rc];
		        found_nodes = $.grep(orig_nodes, function (d) {
		          return $.inArray(d.name, inst_names) > -1;
		        });
		      } else {
	
		        found_nodes = orig_nodes;
		      }
		    } else {
	
		      found_nodes = orig_nodes;
		    }
	
		    new_nodes[inst_rc + '_nodes'] = found_nodes;
		  });
	
		  // keep backup of the nodes for resetting filtering
		  var inst_row_nodes = cgm.params.network_data.row_nodes;
		  var inst_col_nodes = cgm.params.network_data.col_nodes;
	
		  var new_network_data = filter_network_using_new_nodes(cgm.config, new_nodes);
	
		  // takes entire cgm object
		  // last argument tells it to not preserve categoty colors
		  update_viz_with_network(cgm, new_network_data);
	
		  // only keep backup if previous number of nodes were larger than current number
		  // of nodes
		  if (inst_row_nodes.length > cgm.params.inst_nodes.row_nodes.length) {
		    cgm.params.inst_nodes.row_nodes = inst_row_nodes;
		  }
	
		  if (inst_col_nodes.length > cgm.params.inst_nodes.col_nodes.length) {
		    cgm.params.inst_nodes.col_nodes = inst_col_nodes;
		  }
			};
	
	/***/ },
	/* 174 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var make_row_cat = __webpack_require__(122);
		var calc_viz_params = __webpack_require__(15);
		var resize_viz = __webpack_require__(88);
		var modify_row_node_cats = __webpack_require__(160);
	
		module.exports = function update_cats(cgm, cat_data) {
	
		  // Only accessible from the cgm API, cat_data is provided by externally
		  ///////////////////////////////////////////////////////////////////////////
	
		  if (cgm.params.cat_update_callback != null) {
		    cgm.params.cat_update_callback(this);
		  }
	
		  // do not change column category info
		  var col_cat_colors = cgm.params.viz.cat_colors.col;
	
		  modify_row_node_cats(cat_data, cgm.params.network_data.row_nodes, true);
		  // modify the current inst copy of nodes
		  modify_row_node_cats(cat_data, cgm.params.inst_nodes.row_nodes, true);
	
		  // recalculate the visualization parameters using the updated network_data
		  cgm.params = calc_viz_params(cgm.params, false);
	
		  make_row_cat(cgm, true);
		  resize_viz(cgm);
	
		  cgm.params.new_row_cats = cat_data;
	
		  cgm.params.viz.cat_colors.col = col_cat_colors;
			};
	
	/***/ },
	/* 175 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var make_row_cat = __webpack_require__(122);
		var calc_viz_params = __webpack_require__(15);
		var resize_viz = __webpack_require__(88);
		var modify_row_node_cats = __webpack_require__(160);
		var generate_cat_data = __webpack_require__(176);
	
		module.exports = function reset_cats() {
		  var run_resize_viz = arguments.length <= 0 || arguments[0] === undefined ? true : arguments[0];
	
	
		  // console.log('RESET CATS')
	
		  var cgm = this;
	
		  var cat_data = generate_cat_data(cgm);
	
		  // do not change column category info
		  var col_cat_colors = cgm.params.viz.cat_colors.col;
	
		  modify_row_node_cats(cat_data, cgm.params.network_data.row_nodes);
		  // modify the current inst copy of nodes
		  modify_row_node_cats(cat_data, cgm.params.inst_nodes.row_nodes);
	
		  cgm.params.new_row_cats = cat_data;
		  cgm.params.viz.cat_colors.col = col_cat_colors;
	
		  if (run_resize_viz) {
	
		    // resize visualizatino
		    ////////////////////////////
		    // recalculate the visualization parameters using the updated network_data
		    var predefine_cat_colors = true;
		    cgm.params = calc_viz_params(cgm.params, predefine_cat_colors);
	
		    make_row_cat(cgm, true);
		    resize_viz(cgm);
		  }
			};
	
	/***/ },
	/* 176 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function generate_cat_data(cgm) {
	
		  // only row category resetting is supported currently
	
		  // get row_nodes from config, since this is has the original network
		  var row_nodes = cgm.config.network_data.row_nodes;
		  var title_sep = ': ';
	
		  // contains all the category information stored as an array of
		  // cat_type
		  var cat_data = [];
		  var cat_type;
		  var cat_info;
		  var found_cat_title;
		  var found_cat_name;
		  var cat_name;
	
		  // console.log('generate_cat_data')
		  // console.log(cgm.params.viz.cat_names.row)
	
		  // get current list of cateories
		  var check_node = row_nodes[0];
		  var node_keys = _.keys(check_node);
		  var current_cats = {};
		  var tmp_cat;
		  var tmp_title;
		  var cat_index;
		  _.each(node_keys, function (inst_prop) {
	
		    if (inst_prop.indexOf('cat-') >= 0) {
	
		      // generate titles from cat info
		      tmp_cat = check_node[inst_prop];
	
		      cat_index = parseInt(inst_prop.split('cat-')[1], 10);
	
		      // use given title
		      if (tmp_cat.indexOf(title_sep) >= 0) {
		        tmp_title = tmp_cat.split(title_sep)[0];
		      } else {
		        tmp_title = inst_prop;
		      }
	
		      // current_cats.push(tmp_title);
	
		      current_cats[cat_index] = tmp_title;
		    }
		  });
	
		  // console.log('current_cats')
		  // console.log(current_cats)
	
		  // initialize cat_data with categories in the correct order
		  var all_index = _.keys(current_cats).sort();
	
		  var inst_data;
		  _.each(all_index, function (inst_index) {
	
		    inst_data = {};
		    inst_data.cat_title = current_cats[inst_index];
		    inst_data.cats = [];
	
		    cat_data.push(inst_data);
		  });
	
		  // // initialize cat_data (keep original order)
		  // var found_title;
		  // _.each(cgm.params.viz.cat_names.row, function(inst_title){
	
		  //   found_title = false;
	
		  //   console.log('inst_title -> ' + String(inst_title))
	
		  //   if (current_cats.indexOf(inst_title) >= 0){
		  //     found_title = true;
		  //   }
	
		  //   // only track cats that are found in the incoming nodes
		  //   if (found_title){
		  //     var inst_data = {};
		  //     inst_data.cat_title = inst_title;
		  //     inst_data.cats = [];
		  //     cat_data.push(inst_data);
		  //   }
	
		  // });
	
		  // console.log('cat_data after cross checking with current cats')
		  // console.log(cat_data)
		  // console.log('-------------------------\n')
	
		  _.each(row_nodes, function (inst_node) {
	
		    var all_props = _.keys(inst_node);
	
		    _.each(all_props, function (inst_prop) {
	
		      if (inst_prop.indexOf('cat-') > -1) {
	
		        cat_name = inst_node[inst_prop];
	
		        cat_index = parseInt(inst_prop.split('cat-')[1], 10);
	
		        // default title and name
		        var cat_title = inst_prop;
		        cat_name = inst_node[inst_prop];
		        var cat_string = inst_node[inst_prop];
		        var cat_row_name = inst_node.name;
	
		        // console.log('cat_string: '+String(cat_string))
		        // found actual title
		        if (cat_string.indexOf(title_sep) > -1) {
		          cat_title = cat_string.split(title_sep)[0];
		          cat_name = cat_string.split(title_sep)[1];
		        } else {
		          // cat_title = 'Category-'+String(parseInt(inst_prop.split('-')[1]) + 1)
		          cat_title = inst_prop;
		          cat_name = cat_string;
		        }
	
		        // console.log('cat_index -> ' + String(cat_index))
		        // console.log('cat_name '+cat_name)
		        // console.log('cat_title ' + cat_title)
		        // console.log('--------')
	
		        // cat_data is empty
		        if (cat_data.length === 0) {
	
		          add_new_cat_type(cat_title, cat_name, cat_row_name);
	
		          // cat_data is not empty
		        } else {
	
		          // look for cat_title in cat_data
		          found_cat_title = false;
		          _.each(cat_data, function (inst_cat_type) {
	
		            // console.log('inst_cat_data title ' + inst_cat_type.cat_title)
	
		            // check each cat_type object for a matching title
		            if (cat_title === inst_cat_type.cat_title) {
		              found_cat_title = true;
	
		              // check if cat_name is in cats
		              found_cat_name = false;
		              _.each(inst_cat_type.cats, function (inst_cat_obj) {
	
		                // found category name, add cat_row_name to members
		                if (cat_name === inst_cat_obj.cat_name) {
		                  found_cat_name = true;
	
		                  // add cat_row_name to members
		                  inst_cat_obj.members.push(cat_row_name);
		                }
		              });
	
		              // did not find cat name in cat_type - add cat_info for new
		              // category
		              if (found_cat_name === false) {
		                cat_info = {};
		                cat_info.cat_name = cat_name;
		                cat_info.members = [];
		                cat_info.members.push(cat_row_name);
		                inst_cat_type.cats.push(cat_info);
		              }
		            }
		          });
	
		          // did not find category type, initialize category type object
		          if (found_cat_title === false) {
	
		            // console.log('did not find cat_title: ' + String(cat_title))
		            // add_new_cat_type(cat_title, cat_name, cat_row_name);
	
		          }
		        }
		      }
		    });
		  });
	
		  function add_new_cat_type(cat_title, cat_name, cat_row_name) {
	
		    // initialize cat_type object to push to cat_data
		    cat_type = {};
		    cat_type.cat_title = cat_title;
		    cat_type.cats = [];
	
		    // initialize cat_info (e.g. 'true' category has members [...])
		    cat_info = {};
		    cat_info.cat_name = cat_name;
		    cat_info.members = [];
		    cat_info.members.push(cat_row_name);
	
		    cat_type.cats.push(cat_info);
	
		    cat_data.push(cat_type);
		  }
	
		  // console.log('RETURNING CAT DATA')
		  // console.log(cat_data)
	
		  return cat_data;
		};
	
	/***/ },
	/* 177 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var update_viz_with_view = __webpack_require__(141);
		var reset_other_filter_sliders = __webpack_require__(178);
	
		module.exports = function external_update_view(filter_type, inst_state) {
	
		  // add something to control slider position
		  /////////////////////////////////////////////
	
		  var cgm = this;
	
		  var requested_view = {};
		  requested_view[filter_type] = inst_state;
		  update_viz_with_view(this, requested_view);
	
		  reset_other_filter_sliders(cgm, filter_type, inst_state);
		};
	
	/***/ },
	/* 178 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var make_filter_title = __webpack_require__(179);
	
		module.exports = function reset_other_filter_sliders(cgm, filter_type, inst_state) {
	
		  var params = cgm.params;
		  var inst_rc;
		  var reset_rc;
	
		  d3.select(params.root + ' .slider_' + filter_type).attr('current_state', inst_state);
	
		  _.each(_.keys(params.viz.possible_filters), function (reset_filter) {
	
		    if (filter_type.indexOf('row') > -1) {
		      inst_rc = 'row';
		    } else if (filter_type.indexOf('col') > -1) {
		      inst_rc = 'col';
		    } else {
		      inst_rc = 'neither';
		    }
	
		    if (reset_filter.indexOf('row') > -1) {
		      reset_rc = 'row';
		    } else if (reset_filter.indexOf('col') > -1) {
		      reset_rc = 'col';
		    } else {
		      reset_rc = 'neither';
		    }
	
		    if (filter_type != reset_filter && inst_rc != 'neither') {
	
		      if (inst_rc == reset_rc) {
	
		        var tmp_title = make_filter_title(params, reset_filter);
	
		        cgm.slider_functions[reset_filter].value(0);
	
		        d3.select(params.root + ' .title_' + reset_filter).text(tmp_title.text + tmp_title.state);
	
		        d3.select(params.root + ' .slider_' + reset_filter).attr('current_state', tmp_title.state);
		      }
		    }
		  });
	
		  var filter_title = make_filter_title(params, filter_type);
	
		  d3.select(params.root + ' .title_' + filter_type).text(filter_title.text + inst_state + filter_title.suffix);
			};
	
	/***/ },
	/* 179 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var get_filter_default_state = __webpack_require__(5);
	
		module.exports = function make_filter_title(params, filter_type) {
	
		  var filter_title = {};
		  var title = {};
		  var type = {};
	
		  filter_title.state = get_filter_default_state(params.viz.filter_data, filter_type);
	
		  type.top = filter_type.split('_')[0];
		  type.node = filter_type.split('_')[1];
		  type.measure = filter_type.split('_')[2];
	
		  if (type.node === 'row') {
		    title.node = 'rows';
		  } else {
		    title.node = 'columns';
		  }
	
		  if (type.top === 'N') {
		    // filter_title.suffix = ' '+title.node;
		    filter_title.suffix = '';
		  }
	
		  if (type.top === 'pct') {
		    filter_title.suffix = '%';
		  }
	
		  if (type.measure == 'sum') {
		    title.measure = 'sum';
		  } else if (type.measure == 'var') {
		    title.measure = 'variance';
		  }
	
		  if (type.measure === 'sum') {
		    filter_title.text = 'Top ' + title.node + ' ' + title.measure + ': ';
		  }
	
		  if (type.measure === 'var') {
		    filter_title.text = 'Top ' + title.node + ' ' + title.measure + ': ';
		  }
	
		  // Enrichr specific rules 
		  if (_.keys(params.viz.possible_filters).indexOf('enr_score_type') > -1) {
		    if (type.node === 'col') {
		      filter_title.text = 'Top Enriched Terms: ';
		      filter_title.suffix = '';
		    }
		  }
	
		  return filter_title;
		};
	
	/***/ },
	/* 180 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var file_saver = __webpack_require__(181);
		var make_matrix_string = __webpack_require__(182);
	
		module.exports = function save_matrix() {
	
		  var saveAs = file_saver();
	
		  var params = this.params;
	
		  var matrix_string = make_matrix_string(params);
	
		  var blob = new Blob([matrix_string], { type: 'text/plain;charset=utf-8' });
		  saveAs(blob, 'clustergrammer.txt');
			};
	
	/***/ },
	/* 181 */
	/***/ function(module, exports) {
	
		"use strict";
	
		module.exports = function file_saver() {
		  /* eslint-disable */
		  /* FileSaver.js
		   * A saveAs() FileSaver implementation.
		   * 2013-01-23
		   * 
		   * By Eli Grey, http://eligrey.com
		   * License: X11/MIT
		   *   See LICENSE.md
		   */
	
		  /*global self */
		  /*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
		    plusplus: true */
	
		  /*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
	
		  var saveAs = saveAs || navigator.msSaveBlob && navigator.msSaveBlob.bind(navigator) || function (view) {
		    "use strict";
	
		    var doc = view.document
		    // only get URL when necessary in case BlobBuilder.js hasn't overridden it yet
		    ,
		        get_URL = function get_URL() {
		      return view.URL || view.webkitURL || view;
		    },
		        URL = view.URL || view.webkitURL || view,
		        save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a"),
		        can_use_save_link = "download" in save_link,
		        click = function click(node) {
		      var event = doc.createEvent("MouseEvents");
		      event.initMouseEvent("click", true, false, view, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
		      node.dispatchEvent(event);
		    },
		        webkit_req_fs = view.webkitRequestFileSystem,
		        req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem,
		        throw_outside = function throw_outside(ex) {
		      (view.setImmediate || view.setTimeout)(function () {
		        throw ex;
		      }, 0);
		    },
		        force_saveable_type = "application/octet-stream",
		        fs_min_size = 0,
		        deletion_queue = [],
		        process_deletion_queue = function process_deletion_queue() {
		      var i = deletion_queue.length;
		      while (i--) {
		        var file = deletion_queue[i];
		        if (typeof file === "string") {
		          // file is an object URL
		          URL.revokeObjectURL(file);
		        } else {
		          // file is a File
		          file.remove();
		        }
		      }
		      deletion_queue.length = 0; // clear queue
		    },
		        dispatch = function dispatch(filesaver, event_types, event) {
		      event_types = [].concat(event_types);
		      var i = event_types.length;
		      while (i--) {
		        var listener = filesaver["on" + event_types[i]];
		        if (typeof listener === "function") {
		          try {
		            listener.call(filesaver, event || filesaver);
		          } catch (ex) {
		            throw_outside(ex);
		          }
		        }
		      }
		    },
		        FileSaver = function FileSaver(blob, name) {
		      // First try a.download, then web filesystem, then object URLs
		      var filesaver = this,
		          type = blob.type,
		          blob_changed = false,
		          object_url,
		          target_view,
		          get_object_url = function get_object_url() {
		        var object_url = get_URL().createObjectURL(blob);
		        deletion_queue.push(object_url);
		        return object_url;
		      },
		          dispatch_all = function dispatch_all() {
		        dispatch(filesaver, "writestart progress write writeend".split(" "));
		      }
		      // on any filesys errors revert to saving with object URLs
		      ,
		          fs_error = function fs_error() {
		        // don't create more object URLs than needed
		        if (blob_changed || !object_url) {
		          object_url = get_object_url(blob);
		        }
		        if (target_view) {
		          target_view.location.href = object_url;
		        }
		        filesaver.readyState = filesaver.DONE;
		        dispatch_all();
		      },
		          abortable = function abortable(func) {
		        return function () {
		          if (filesaver.readyState !== filesaver.DONE) {
		            return func.apply(this, arguments);
		          }
		        };
		      },
		          create_if_not_found = { create: true, exclusive: false },
		          slice;
		      filesaver.readyState = filesaver.INIT;
		      if (!name) {
		        name = "download";
		      }
		      if (can_use_save_link) {
		        object_url = get_object_url(blob);
		        save_link.href = object_url;
		        save_link.download = name;
		        click(save_link);
		        filesaver.readyState = filesaver.DONE;
		        dispatch_all();
		        return;
		      }
		      // Object and web filesystem URLs have a problem saving in Google Chrome when
		      // viewed in a tab, so I force save with application/octet-stream
		      // http://code.google.com/p/chromium/issues/detail?id=91158
		      if (view.chrome && type && type !== force_saveable_type) {
		        slice = blob.slice || blob.webkitSlice;
		        blob = slice.call(blob, 0, blob.size, force_saveable_type);
		        blob_changed = true;
		      }
		      // Since I can't be sure that the guessed media type will trigger a download
		      // in WebKit, I append .download to the filename.
		      // https://bugs.webkit.org/show_bug.cgi?id=65440
		      if (webkit_req_fs && name !== "download") {
		        name += ".download";
		      }
		      if (type === force_saveable_type || webkit_req_fs) {
		        target_view = view;
		      } else {
		        target_view = view.open();
		      }
		      if (!req_fs) {
		        fs_error();
		        return;
		      }
		      fs_min_size += blob.size;
		      req_fs(view.TEMPORARY, fs_min_size, abortable(function (fs) {
		        fs.root.getDirectory("saved", create_if_not_found, abortable(function (dir) {
		          var save = function save() {
		            dir.getFile(name, create_if_not_found, abortable(function (file) {
		              file.createWriter(abortable(function (writer) {
		                writer.onwriteend = function (event) {
		                  target_view.location.href = file.toURL();
		                  deletion_queue.push(file);
		                  filesaver.readyState = filesaver.DONE;
		                  dispatch(filesaver, "writeend", event);
		                };
		                writer.onerror = function () {
		                  var error = writer.error;
		                  if (error.code !== error.ABORT_ERR) {
		                    fs_error();
		                  }
		                };
		                "writestart progress write abort".split(" ").forEach(function (event) {
		                  writer["on" + event] = filesaver["on" + event];
		                });
		                writer.write(blob);
		                filesaver.abort = function () {
		                  writer.abort();
		                  filesaver.readyState = filesaver.DONE;
		                };
		                filesaver.readyState = filesaver.WRITING;
		              }), fs_error);
		            }), fs_error);
		          };
		          dir.getFile(name, { create: false }, abortable(function (file) {
		            // delete file if it already exists
		            file.remove();
		            save();
		          }), abortable(function (ex) {
		            if (ex.code === ex.NOT_FOUND_ERR) {
		              save();
		            } else {
		              fs_error();
		            }
		          }));
		        }), fs_error);
		      }), fs_error);
		    },
		        FS_proto = FileSaver.prototype,
		        saveAs = function saveAs(blob, name) {
		      return new FileSaver(blob, name);
		    };
		    FS_proto.abort = function () {
		      var filesaver = this;
		      filesaver.readyState = filesaver.DONE;
		      dispatch(filesaver, "abort");
		    };
		    FS_proto.readyState = FS_proto.INIT = 0;
		    FS_proto.WRITING = 1;
		    FS_proto.DONE = 2;
	
		    FS_proto.error = FS_proto.onwritestart = FS_proto.onprogress = FS_proto.onwrite = FS_proto.onabort = FS_proto.onerror = FS_proto.onwriteend = null;
	
		    view.addEventListener("unload", process_deletion_queue, false);
		    return saveAs;
		  }(self);
	
		  return saveAs;
			};
	
	/***/ },
	/* 182 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var make_full_name = __webpack_require__(183);
	
		module.exports = function make_matrix_string(params) {
	
		  var inst_matrix = params.matrix;
	
		  // get order indexes
		  var order_indexes = {};
		  var inst_name;
		  _.each(['row', 'col'], function (tmp_rc) {
	
		    var inst_rc;
		    // row/col names are reversed in saved orders
		    if (tmp_rc === 'row') {
		      inst_rc = 'col';
		    } else {
		      inst_rc = 'row';
		    }
	
		    // use tmp_rc
		    inst_name = params.inst_order[tmp_rc];
	
		    // use tmp_rc
		    order_indexes[inst_rc] = inst_matrix.orders[inst_name + '_' + tmp_rc];
		  });
	
		  var matrix_string = '\t';
		  var row_nodes = params.network_data.row_nodes;
		  var col_nodes = params.network_data.col_nodes;
	
		  // alternate column entry
		  for (var c_i = 0; c_i < order_indexes.col.length; c_i++) {
	
		    var inst_index = order_indexes.col[c_i];
	
		    var inst_col = col_nodes[inst_index];
		    var col_name = make_full_name(params, inst_col, 'col');
	
		    if (c_i < order_indexes.col.length - 1) {
		      matrix_string = matrix_string + col_name + '\t';
		    } else {
		      matrix_string = matrix_string + col_name;
		    }
		  }
	
		  var row_data;
		  matrix_string = matrix_string + '\n';
	
		  _.each(order_indexes.row, function (inst_index) {
	
		    // row names
		    row_data = inst_matrix.matrix[inst_index].row_data;
	
		    // var row_name = inst_matrix.matrix[inst_index].name;
		    var inst_row = row_nodes[inst_index];
	
		    // var row_name = inst_row.name;
		    var row_name = make_full_name(params, inst_row, 'row');
	
		    matrix_string = matrix_string + row_name + '\t';
	
		    // alternate data entry
		    for (var r_i = 0; r_i < order_indexes.col.length; r_i++) {
	
		      // get the order
		      var col_index = order_indexes.col[r_i];
	
		      if (r_i < order_indexes.col.length - 1) {
		        matrix_string = matrix_string + String(row_data[col_index].value) + '\t';
		      } else {
		        matrix_string = matrix_string + String(row_data[col_index].value);
		      }
		    }
	
		    matrix_string = matrix_string + '\n';
		  });
	
		  return matrix_string;
			};
	
	/***/ },
	/* 183 */
	/***/ function(module, exports) {
	
		"use strict";
	
		module.exports = function make_full_name(params, inst_node, inst_rc) {
	
		  var cat_name;
		  var inst_name = inst_node.name;
		  var num_cats = params.viz.all_cats[inst_rc].length;
	
		  // make tuple if necessary
		  if (num_cats > 0) {
	
		    inst_name = "('" + inst_name + "'";
	
		    for (var cat_index = 0; cat_index < num_cats; cat_index++) {
		      cat_name = 'cat-' + String(cat_index);
	
		      inst_name = inst_name + ", '" + String(inst_node[cat_name]) + "'";
		    }
	
		    inst_name = inst_name + ')';
		  } else {
	
		    // always make names strings
		    inst_name = String(inst_name);
		  }
	
		  return inst_name;
		};
	
	/***/ },
	/* 184 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var deactivate_cropping = __webpack_require__(185);
	
		module.exports = function brush_crop_matrix() {
	
		  // get rows/cols from brush-extent
		  // works for differnt brushing directions (e.g. start end sites)
	
		  var cgm = this;
		  var params = cgm.params;
	
		  var clust_width = params.viz.clust.dim.width;
		  var clust_height = params.viz.clust.dim.height;
	
		  var x = d3.scale.linear().domain([0, clust_width]).range([0, clust_width]);
		  var y = d3.scale.linear().domain([0, clust_height]).range([0, clust_height]);
	
		  // make brush group
		  d3.select(params.root + ' .clust_container').append('g').classed('brush_group', true);
	
		  cgm.params.is_cropping = true;
	
		  var brush = d3.svg.brush().x(x).y(y).on("brushend", brushend);
	
		  d3.select(params.root + ' .brush_group').call(brush);
	
		  function brushend() {
	
		    // do not display dendro crop buttons when cropping with brushing
		    d3.select(cgm.params.root + ' .col_dendro_icons_container').style('display', 'none');
		    d3.select(cgm.params.root + ' .row_dendro_icons_container').style('display', 'none');
	
		    var brushing_extent = brush.extent();
		    var brush_start = brushing_extent[0];
		    var brush_end = brushing_extent[1];
	
		    var x_start = brush_start[0];
		    var x_end = brush_end[0];
	
		    var y_start = brush_start[1];
		    var y_end = brush_end[1];
	
		    if (x_start != x_end && y_start != y_end) {
	
		      setTimeout(deactivate_cropping, 500, cgm);
	
		      // find cropped nodes
		      var found_nodes = find_cropped_nodes(x_start, x_end, y_start, y_end, brush_start, brush_end);
	
		      cgm.filter_viz_using_names(found_nodes);
	
		      d3.select(params.root + ' .crop_button').style('color', '#337ab7').classed('fa-crop', false).classed('fa-undo', true);
		    }
		  }
	
		  function find_cropped_nodes(x_start, x_end, y_start, y_end, brush_start, brush_end) {
	
		    // reverse if necessary (depending on how brushing was done)
		    if (x_start > x_end) {
		      x_start = brush_end[0];
		      x_end = brush_start[0];
		    }
	
		    if (y_start > y_end) {
		      y_start = brush_end[1];
		      y_end = brush_start[1];
		    }
	
		    // add room to brushing
		    y_start = y_start - params.viz.rect_height;
		    x_start = x_start - params.viz.rect_width;
	
		    var found_nodes = {};
		    found_nodes.row = [];
		    found_nodes.col = [];
	
		    // d3.selectAll(params.root+' .row_label_group')
		    //   .each(function(inst_row){
	
		    //     // there is already bound data on the rows
		    //     var inst_trans = d3.select(this)
		    //       .attr('transform');
	
		    //     var y_trans = Number(inst_trans.split(',')[1].split(')')[0]);
	
		    //     if (y_trans > y_start && y_trans < y_end){
	
		    //       found_nodes.row.push(inst_row.name);
	
		    //     }
	
		    //   });
	
		    _.each(params.matrix.matrix, function (row_data) {
		      var y_trans = params.viz.y_scale(row_data.row_index);
	
		      if (y_trans > y_start && y_trans < y_end) {
		        found_nodes.row.push(row_data.name);
		      }
		    });
	
		    d3.selectAll(params.root + ' .col_label_text').each(function (inst_col) {
	
		      // there is already bound data on the cols
		      var inst_trans = d3.select(this).attr('transform');
	
		      var x_trans = Number(inst_trans.split(',')[0].split('(')[1]);
	
		      if (x_trans > x_start && x_trans < x_end) {
	
		        found_nodes.col.push(inst_col.name);
		      }
		    });
	
		    return found_nodes;
		  }
	
		  d3.selectAll(params.root + ' .extent').style('opacity', 0.2).style('fill', 'black');
			};
	
	/***/ },
	/* 185 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function deactivate_cropping(cgm) {
	
		  d3.select(cgm.params.root + ' .brush_group').transition().style('opacity', 0).remove();
	
		  cgm.params.is_cropping = false;
			};
	
	/***/ },
	/* 186 */
	/***/ function(module, exports, __webpack_require__) {
	
		var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;'use strict';
	
		var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
	
		/*
		    D3.js Slider
		    Inspired by jQuery UI Slider
		    Copyright (c) 2013, Bjorn Sandvik - http://blog.thematicmapping.org
		    BSD license: http://opensource.org/licenses/BSD-3-Clause
		*/
		(function (root, factory) {
		  if (true) {
		    // AMD. Register as an anonymous module.
		    !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(187)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		  } else if ((typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object') {
		    if (process.browser) {
		      // Browserify. Import css too using cssify.
		      require('./d3.slider.css');
		    }
		    // Node. Does not work with strict CommonJS, but
		    // only CommonJS-like environments that support module.exports,
		    // like Node.
		    module.exports = factory(require('d3'));
		  } else {
		    // Browser globals (root is window)
		    root.d3.slider = factory(root.d3);
		  }
		})(undefined, function (d3) {
		  return function module() {
		    "use strict";
	
		    // Public variables width default settings
	
		    var min = 0,
		        max = 100,
		        step = 0.01,
		        animate = false,
		        orientation = "horizontal",
		        axis = false,
		        margin = 50,
		        value,
		        active = 1,
		        snap = false,
		        scale;
	
		    // Private variables
		    var axisScale,
		        dispatch = d3.dispatch("slide", "slideend"),
		        formatPercent = d3.format(".2%"),
		        tickFormat = d3.format(".0"),
		        handle1,
		        handle2 = null,
		        divRange,
		        sliderLength;
	
		    function slider(selection) {
		      selection.each(function () {
	
		        // Create scale if not defined by user
		        if (!scale) {
		          scale = d3.scale.linear().domain([min, max]);
		        }
	
		        // Start value
		        value = value || scale.domain()[0];
	
		        // DIV container
		        var div = d3.select(this).classed("d3-slider d3-slider-" + orientation, true);
	
		        var drag = d3.behavior.drag();
		        drag.on('dragend', function () {
		          dispatch.slideend(d3.event, value);
		        });
	
		        // Slider handle
		        //if range slider, create two
		        // var divRange;
	
		        if (toType(value) == "array" && value.length == 2) {
		          handle1 = div.append("a").classed("d3-slider-handle", true).attr("xlink:href", "#").attr('id', "handle-one").on("click", stopPropagation).call(drag);
		          handle2 = div.append("a").classed("d3-slider-handle", true).attr('id', "handle-two").attr("xlink:href", "#").on("click", stopPropagation).call(drag);
		        } else {
		          handle1 = div.append("a").classed("d3-slider-handle", true).attr("xlink:href", "#").attr('id', "handle-one").on("click", stopPropagation).call(drag);
		        }
	
		        // Horizontal slider
		        if (orientation === "horizontal") {
	
		          div.on("click", onClickHorizontal);
	
		          if (toType(value) == "array" && value.length == 2) {
		            divRange = d3.select(this).append('div').classed("d3-slider-range", true);
	
		            handle1.style("left", formatPercent(scale(value[0])));
		            divRange.style("left", formatPercent(scale(value[0])));
		            drag.on("drag", onDragHorizontal);
	
		            var width = 100 - parseFloat(formatPercent(scale(value[1])));
		            handle2.style("left", formatPercent(scale(value[1])));
		            divRange.style("right", width + "%");
		            drag.on("drag", onDragHorizontal);
		          } else {
		            handle1.style("left", formatPercent(scale(value)));
		            drag.on("drag", onDragHorizontal);
		          }
	
		          sliderLength = parseInt(div.style("width"), 10);
		        } else {
		          // Vertical
	
		          div.on("click", onClickVertical);
		          drag.on("drag", onDragVertical);
		          if (toType(value) == "array" && value.length == 2) {
		            divRange = d3.select(this).append('div').classed("d3-slider-range-vertical", true);
	
		            handle1.style("bottom", formatPercent(scale(value[0])));
		            divRange.style("bottom", formatPercent(scale(value[0])));
		            drag.on("drag", onDragVertical);
	
		            var top = 100 - parseFloat(formatPercent(scale(value[1])));
		            handle2.style("bottom", formatPercent(scale(value[1])));
		            divRange.style("top", top + "%");
		            drag.on("drag", onDragVertical);
		          } else {
		            handle1.style("bottom", formatPercent(scale(value)));
		            drag.on("drag", onDragVertical);
		          }
	
		          sliderLength = parseInt(div.style("height"), 10);
		        }
	
		        if (axis) {
		          createAxis(div);
		        }
	
		        function createAxis(dom) {
	
		          // Create axis if not defined by user
		          if (typeof axis === "boolean") {
	
		            axis = d3.svg.axis().ticks(Math.round(sliderLength / 100)).tickFormat(tickFormat).orient(orientation === "horizontal" ? "bottom" : "right");
		          }
	
		          // Copy slider scale to move from percentages to pixels
		          axisScale = scale.ticks ? scale.copy().range([0, sliderLength]) : scale.copy().rangePoints([0, sliderLength], 0.5);
		          axis.scale(axisScale);
	
		          // Create SVG axis container
		          var svg = dom.append("svg").classed("d3-slider-axis d3-slider-axis-" + axis.orient(), true).on("click", stopPropagation);
	
		          var g = svg.append("g");
	
		          // Horizontal axis
		          if (orientation === "horizontal") {
	
		            svg.style("margin-left", -margin + "px");
	
		            svg.attr({
		              width: sliderLength + margin * 2,
		              height: margin
		            });
	
		            if (axis.orient() === "top") {
		              svg.style("top", -margin + "px");
		              g.attr("transform", "translate(" + margin + "," + margin + ")");
		            } else {
		              // bottom
		              g.attr("transform", "translate(" + margin + ",0)");
		            }
		          } else {
		            // Vertical
	
		            svg.style("top", -margin + "px");
	
		            svg.attr({
		              width: margin,
		              height: sliderLength + margin * 2
		            });
	
		            if (axis.orient() === "left") {
		              svg.style("left", -margin + "px");
		              g.attr("transform", "translate(" + margin + "," + margin + ")");
		            } else {
		              // right
		              g.attr("transform", "translate(" + 0 + "," + margin + ")");
		            }
		          }
	
		          g.call(axis);
		        }
	
		        function onClickHorizontal() {
		          if (toType(value) != "array") {
		            var pos = Math.max(0, Math.min(sliderLength, d3.event.offsetX || d3.event.layerX));
		            moveHandle(scale.invert ? stepValue(scale.invert(pos / sliderLength)) : nearestTick(pos / sliderLength));
		          }
		        }
	
		        function onClickVertical() {
		          if (toType(value) != "array") {
		            var pos = sliderLength - Math.max(0, Math.min(sliderLength, d3.event.offsetY || d3.event.layerY));
		            moveHandle(scale.invert ? stepValue(scale.invert(pos / sliderLength)) : nearestTick(pos / sliderLength));
		          }
		        }
	
		        function onDragHorizontal() {
		          if (d3.event.sourceEvent.target.id === "handle-one") {
		            active = 1;
		          } else if (d3.event.sourceEvent.target.id == "handle-two") {
		            active = 2;
		          }
		          var pos = Math.max(0, Math.min(sliderLength, d3.event.x));
		          moveHandle(scale.invert ? stepValue(scale.invert(pos / sliderLength)) : nearestTick(pos / sliderLength));
		        }
	
		        function onDragVertical() {
		          if (d3.event.sourceEvent.target.id === "handle-one") {
		            active = 1;
		          } else if (d3.event.sourceEvent.target.id == "handle-two") {
		            active = 2;
		          }
		          var pos = sliderLength - Math.max(0, Math.min(sliderLength, d3.event.y));
		          moveHandle(scale.invert ? stepValue(scale.invert(pos / sliderLength)) : nearestTick(pos / sliderLength));
		        }
	
		        function stopPropagation() {
		          d3.event.stopPropagation();
		        }
		      });
		    }
	
		    // Move slider handle on click/drag
		    function moveHandle(newValue) {
		      var currentValue = toType(value) == "array" && value.length == 2 ? value[active - 1] : value,
		          oldPos = formatPercent(scale(stepValue(currentValue))),
		          newPos = formatPercent(scale(stepValue(newValue))),
		          position = orientation === "horizontal" ? "left" : "bottom";
		      if (oldPos !== newPos) {
	
		        if (toType(value) == "array" && value.length == 2) {
		          value[active - 1] = newValue;
		          if (d3.event) {
		            dispatch.slide(d3.event, value);
		          };
		        } else {
		          if (d3.event) {
		            dispatch.slide(d3.event.sourceEvent || d3.event, value = newValue);
		          };
		        }
	
		        if (value[0] >= value[1]) return;
		        if (active === 1) {
		          if (toType(value) == "array" && value.length == 2) {
		            position === "left" ? divRange.style("left", newPos) : divRange.style("bottom", newPos);
		          }
	
		          if (animate) {
		            handle1.transition().styleTween(position, function () {
		              return d3.interpolate(oldPos, newPos);
		            }).duration(typeof animate === "number" ? animate : 250);
		          } else {
		            handle1.style(position, newPos);
		          }
		        } else {
	
		          var width = 100 - parseFloat(newPos);
		          var top = 100 - parseFloat(newPos);
	
		          position === "left" ? divRange.style("right", width + "%") : divRange.style("top", top + "%");
	
		          if (animate) {
		            handle2.transition().styleTween(position, function () {
		              return d3.interpolate(oldPos, newPos);
		            }).duration(typeof animate === "number" ? animate : 250);
		          } else {
		            handle2.style(position, newPos);
		          }
		        }
		      }
		    }
	
		    // Calculate nearest step value
		    function stepValue(val) {
	
		      if (val === scale.domain()[0] || val === scale.domain()[1]) {
		        return val;
		      }
	
		      var alignValue = val;
		      if (snap) {
		        alignValue = nearestTick(scale(val));
		      } else {
		        var valModStep = (val - scale.domain()[0]) % step;
		        alignValue = val - valModStep;
	
		        if (Math.abs(valModStep) * 2 >= step) {
		          alignValue += valModStep > 0 ? step : -step;
		        }
		      };
	
		      return alignValue;
		    }
	
		    // Find the nearest tick
		    function nearestTick(pos) {
		      var ticks = scale.ticks ? scale.ticks() : scale.domain();
		      var dist = ticks.map(function (d) {
		        return pos - scale(d);
		      });
		      var i = -1,
		          index = 0,
		          r = scale.ticks ? scale.range()[1] : scale.rangeExtent()[1];
		      do {
		        i++;
		        if (Math.abs(dist[i]) < r) {
		          r = Math.abs(dist[i]);
		          index = i;
		        };
		      } while (dist[i] > 0 && i < dist.length - 1);
	
		      return ticks[index];
		    };
	
		    // Return the type of an object
		    function toType(v) {
		      return {}.toString.call(v).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
		    };
	
		    // Getter/setter functions
		    slider.min = function (_) {
		      if (!arguments.length) return min;
		      min = _;
		      return slider;
		    };
	
		    slider.max = function (_) {
		      if (!arguments.length) return max;
		      max = _;
		      return slider;
		    };
	
		    slider.step = function (_) {
		      if (!arguments.length) return step;
		      step = _;
		      return slider;
		    };
	
		    slider.animate = function (_) {
		      if (!arguments.length) return animate;
		      animate = _;
		      return slider;
		    };
	
		    slider.orientation = function (_) {
		      if (!arguments.length) return orientation;
		      orientation = _;
		      return slider;
		    };
	
		    slider.axis = function (_) {
		      if (!arguments.length) return axis;
		      axis = _;
		      return slider;
		    };
	
		    slider.margin = function (_) {
		      if (!arguments.length) return margin;
		      margin = _;
		      return slider;
		    };
	
		    slider.value = function (_) {
		      if (!arguments.length) return value;
		      if (value) {
		        moveHandle(stepValue(_));
		      };
		      value = _;
		      return slider;
		    };
	
		    slider.snap = function (_) {
		      if (!arguments.length) return snap;
		      snap = _;
		      return slider;
		    };
	
		    slider.scale = function (_) {
		      if (!arguments.length) return scale;
		      scale = _;
		      return slider;
		    };
	
		    d3.rebind(slider, dispatch, "on");
	
		    return slider;
		  };
		});
	
	/***/ },
	/* 187 */
	/***/ function(module, exports) {
	
		module.exports = __webpack_require__(4);
	
	/***/ },
	/* 188 */
	/***/ function(module, exports, __webpack_require__) {
	
		/* WEBPACK VAR INJECTION */(function(module) {"use strict";
	
		var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
	
		/**
		 * Simple, lightweight, usable local autocomplete library for modern browsers
		 * Because there weren’t enough autocomplete scripts in the world? Because I’m completely insane and have NIH syndrome? Probably both. :P
		 * @author Lea Verou http://leaverou.github.io/awesomplete
		 * MIT license
		 */
	
		(function () {
	
			var _ = function _(input, o) {
				var me = this;
	
				// Setup
	
				this.input = $(input);
				this.input.setAttribute("autocomplete", "off");
				this.input.setAttribute("aria-autocomplete", "list");
	
				o = o || {};
	
				configure(this, {
					minChars: 2,
					maxItems: 10,
					autoFirst: false,
					data: _.DATA,
					filter: _.FILTER_CONTAINS,
					sort: _.SORT_BYLENGTH,
					item: _.ITEM,
					replace: _.REPLACE
				}, o);
	
				this.index = -1;
	
				// Create necessary elements
	
				this.container = $.create("div", {
					className: "awesomplete",
					around: input
				});
	
				this.ul = $.create("ul", {
					hidden: "hidden",
					inside: this.container
				});
	
				this.status = $.create("span", {
					className: "visually-hidden",
					role: "status",
					"aria-live": "assertive",
					"aria-relevant": "additions",
					inside: this.container
				});
	
				// Bind events
	
				$.bind(this.input, {
					"input": this.evaluate.bind(this),
					"blur": this.close.bind(this, { reason: "blur" }),
					"keydown": function keydown(evt) {
						var c = evt.keyCode;
	
						// If the dropdown `ul` is in view, then act on keydown for the following keys:
						// Enter / Esc / Up / Down
						if (me.opened) {
							if (c === 13 && me.selected) {
								// Enter
								evt.preventDefault();
								me.select();
							} else if (c === 27) {
								// Esc
								me.close({ reason: "esc" });
							} else if (c === 38 || c === 40) {
								// Down/Up arrow
								evt.preventDefault();
								me[c === 38 ? "previous" : "next"]();
							}
						}
					}
				});
	
				$.bind(this.input.form, { "submit": this.close.bind(this, { reason: "submit" }) });
	
				$.bind(this.ul, { "mousedown": function mousedown(evt) {
						var li = evt.target;
	
						if (li !== this) {
	
							while (li && !/li/i.test(li.nodeName)) {
								li = li.parentNode;
							}
	
							if (li && evt.button === 0) {
								// Only select on left click
								evt.preventDefault();
								me.select(li, evt.target);
							}
						}
					} });
	
				if (this.input.hasAttribute("list")) {
					this.list = "#" + this.input.getAttribute("list");
					this.input.removeAttribute("list");
				} else {
					this.list = this.input.getAttribute("data-list") || o.list || [];
				}
	
				_.all.push(this);
			};
	
			_.prototype = {
				set list(list) {
					if (Array.isArray(list)) {
						this._list = list;
					} else if (typeof list === "string" && list.indexOf(",") > -1) {
						this._list = list.split(/\s*,\s*/);
					} else {
						// Element or CSS selector
						list = $(list);
	
						if (list && list.children) {
							var items = [];
							slice.apply(list.children).forEach(function (el) {
								if (!el.disabled) {
									var text = el.textContent.trim();
									var value = el.value || text;
									var label = el.label || text;
									if (value !== "") {
										items.push({ label: label, value: value });
									}
								}
							});
							this._list = items;
						}
					}
	
					if (document.activeElement === this.input) {
						this.evaluate();
					}
				},
	
				get selected() {
					return this.index > -1;
				},
	
				get opened() {
					return !this.ul.hasAttribute("hidden");
				},
	
				close: function close(o) {
					if (!this.opened) {
						return;
					}
	
					this.ul.setAttribute("hidden", "");
					this.index = -1;
	
					$.fire(this.input, "awesomplete-close", o || {});
				},
	
				open: function open() {
					this.ul.removeAttribute("hidden");
	
					if (this.autoFirst && this.index === -1) {
						this.goto(0);
					}
	
					$.fire(this.input, "awesomplete-open");
				},
	
				next: function next() {
					var count = this.ul.children.length;
	
					this.goto(this.index < count - 1 ? this.index + 1 : -1);
				},
	
				previous: function previous() {
					var count = this.ul.children.length;
	
					this.goto(this.selected ? this.index - 1 : count - 1);
				},
	
				// Should not be used, highlights specific item without any checks!
				goto: function goto(i) {
					var lis = this.ul.children;
	
					if (this.selected) {
						lis[this.index].setAttribute("aria-selected", "false");
					}
	
					this.index = i;
	
					if (i > -1 && lis.length > 0) {
						lis[i].setAttribute("aria-selected", "true");
						this.status.textContent = lis[i].textContent;
	
						$.fire(this.input, "awesomplete-highlight", {
							text: this.suggestions[this.index]
						});
					}
				},
	
				select: function select(selected, origin) {
					if (selected) {
						this.index = $.siblingIndex(selected);
					} else {
						selected = this.ul.children[this.index];
					}
	
					if (selected) {
						var suggestion = this.suggestions[this.index];
	
						var allowed = $.fire(this.input, "awesomplete-select", {
							text: suggestion,
							origin: origin || selected
						});
	
						if (allowed) {
							this.replace(suggestion);
							this.close({ reason: "select" });
							$.fire(this.input, "awesomplete-selectcomplete", {
								text: suggestion
							});
						}
					}
				},
	
				evaluate: function evaluate() {
					var me = this;
					var value = this.input.value;
	
					if (value.length >= this.minChars && this._list.length > 0) {
						this.index = -1;
						// Populate list with options that match
						this.ul.innerHTML = "";
	
						this.suggestions = this._list.map(function (item) {
							return new Suggestion(me.data(item, value));
						}).filter(function (item) {
							return me.filter(item, value);
						}).sort(this.sort).slice(0, this.maxItems);
	
						this.suggestions.forEach(function (text) {
							me.ul.appendChild(me.item(text, value));
						});
	
						if (this.ul.children.length === 0) {
							this.close({ reason: "nomatches" });
						} else {
							this.open();
						}
					} else {
						this.close({ reason: "nomatches" });
					}
				}
			};
	
			// Static methods/properties
	
			_.all = [];
	
			_.FILTER_CONTAINS = function (text, input) {
				return RegExp($.regExpEscape(input.trim()), "i").test(text);
			};
	
			_.FILTER_STARTSWITH = function (text, input) {
				return RegExp("^" + $.regExpEscape(input.trim()), "i").test(text);
			};
	
			_.SORT_BYLENGTH = function (a, b) {
				if (a.length !== b.length) {
					return a.length - b.length;
				}
	
				return a < b ? -1 : 1;
			};
	
			_.ITEM = function (text, input) {
				var html = input === '' ? text : text.replace(RegExp($.regExpEscape(input.trim()), "gi"), "<mark>$&</mark>");
				return $.create("li", {
					innerHTML: html,
					"aria-selected": "false"
				});
			};
	
			_.REPLACE = function (text) {
				this.input.value = text.value;
			};
	
			_.DATA = function (item /*, input*/) {
				return item;
			};
	
			// Private functions
	
			function Suggestion(data) {
				var o = Array.isArray(data) ? { label: data[0], value: data[1] } : (typeof data === "undefined" ? "undefined" : _typeof(data)) === "object" && "label" in data && "value" in data ? data : { label: data, value: data };
	
				this.label = o.label || o.value;
				this.value = o.value;
			}
			Object.defineProperty(Suggestion.prototype = Object.create(String.prototype), "length", {
				get: function get() {
					return this.label.length;
				}
			});
			Suggestion.prototype.toString = Suggestion.prototype.valueOf = function () {
				return "" + this.label;
			};
	
			function configure(instance, properties, o) {
				for (var i in properties) {
					var initial = properties[i],
					    attrValue = instance.input.getAttribute("data-" + i.toLowerCase());
	
					if (typeof initial === "number") {
						instance[i] = parseInt(attrValue);
					} else if (initial === false) {
						// Boolean options must be false by default anyway
						instance[i] = attrValue !== null;
					} else if (initial instanceof Function) {
						instance[i] = null;
					} else {
						instance[i] = attrValue;
					}
	
					if (!instance[i] && instance[i] !== 0) {
						instance[i] = i in o ? o[i] : initial;
					}
				}
			}
	
			// Helpers
	
			var slice = Array.prototype.slice;
	
			function $(expr, con) {
				return typeof expr === "string" ? (con || document).querySelector(expr) : expr || null;
			}
	
			function $$(expr, con) {
				return slice.call((con || document).querySelectorAll(expr));
			}
	
			$.create = function (tag, o) {
				var element = document.createElement(tag);
	
				for (var i in o) {
					var val = o[i];
	
					if (i === "inside") {
						$(val).appendChild(element);
					} else if (i === "around") {
						var ref = $(val);
						ref.parentNode.insertBefore(element, ref);
						element.appendChild(ref);
					} else if (i in element) {
						element[i] = val;
					} else {
						element.setAttribute(i, val);
					}
				}
	
				return element;
			};
	
			$.bind = function (element, o) {
				if (element) {
					for (var event in o) {
						var callback = o[event];
	
						event.split(/\s+/).forEach(function (event) {
							element.addEventListener(event, callback);
						});
					}
				}
			};
	
			$.fire = function (target, type, properties) {
				var evt = document.createEvent("HTMLEvents");
	
				evt.initEvent(type, true, true);
	
				for (var j in properties) {
					evt[j] = properties[j];
				}
	
				return target.dispatchEvent(evt);
			};
	
			$.regExpEscape = function (s) {
				return s.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&");
			};
	
			$.siblingIndex = function (el) {
				/* eslint-disable no-cond-assign */
				for (var i = 0; el = el.previousElementSibling; i++) {}
				return i;
			};
	
			// Initialization
	
			function init() {
				$$("input.awesomplete").forEach(function (input) {
					new _(input);
				});
			}
	
			// Are we in a browser? Check for Document constructor
			if (typeof Document !== "undefined") {
				// DOM already loaded?
				if (document.readyState !== "loading") {
					init();
				} else {
					// Wait for it
					document.addEventListener("DOMContentLoaded", init);
				}
			}
	
			_.$ = $;
			_.$$ = $$;
	
			// Make sure to export Awesomplete on self when in a browser
			if (typeof self !== "undefined") {
				self.Awesomplete = _;
			}
	
			// Expose Awesomplete as a CJS module
			if (( false ? "undefined" : _typeof(module)) === "object" && module.exports) {
				module.exports = _;
			}
	
			return _;
			})();
		/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(189)(module)))
	
	/***/ },
	/* 189 */
	/***/ function(module, exports) {
	
		"use strict";
	
		module.exports = function (module) {
			if (!module.webpackPolyfill) {
				module.deprecate = function () {};
				module.paths = [];
				// module.parent = undefined by default
				module.children = [];
				module.webpackPolyfill = 1;
			}
			return module;
			};
	
	/***/ },
	/* 190 */
	/***/ function(module, exports, __webpack_require__) {
	
		// style-loader: Adds some css to the DOM by adding a <style> tag
	
		// load the styles
		var content = __webpack_require__(191);
		if(typeof content === 'string') content = [[module.id, content, '']];
		// add the styles to the DOM
		var update = __webpack_require__(193)(content, {});
		if(content.locals) module.exports = content.locals;
		// Hot Module Replacement
		if(false) {
			// When the styles change, update the <style> tags
			if(!content.locals) {
				module.hot.accept("!!./../../node_modules/css-loader/index.js!./d3.slider.css", function() {
					var newContent = require("!!./../../node_modules/css-loader/index.js!./d3.slider.css");
					if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
					update(newContent);
				});
			}
			// When the module is disposed, remove the <style> tags
			module.hot.dispose(function() { update(); });
		}
	
	/***/ },
	/* 191 */
	/***/ function(module, exports, __webpack_require__) {
	
		exports = module.exports = __webpack_require__(192)();
		// imports
	
	
		// module
		exports.push([module.id, ".d3-slider {\n    position: relative;\n    font-family: Verdana,Arial,sans-serif;\n    font-size: 1.1em;\n    border: 1px solid #aaaaaa;\n    z-index: 2;\n}\n\n.d3-slider-horizontal {\n    height: .8em;\n}  \n\n.d3-slider-range {\n  background:#2980b9;\n  left:0px;\n  right:0px;\n  height: 0.8em;\n  position: absolute;\n}\n\n.d3-slider-range-vertical {\n  background:#2980b9;\n  left:0px;\n  right:0px;\n  position: absolute;\n  top:0;\n}\n\n.d3-slider-vertical {\n    width: .8em;\n    height: 100px;\n}      \n\n.d3-slider-handle {\n    position: absolute;\n    width: 1.2em;\n    height: 1.2em;\n    border: 1px solid #d3d3d3;\n    border-radius: 4px;\n    background: #eee;\n    background: linear-gradient(to bottom, #eee 0%, #ddd 100%);\n    z-index: 3;\n}\n\n.d3-slider-handle:hover {\n    border: 1px solid #999999;\n}\n\n.d3-slider-horizontal .d3-slider-handle {\n    top: -.3em;\n    margin-left: -.6em;\n}\n\n.d3-slider-axis {\n    position: relative;\n    z-index: 1;    \n}\n\n.d3-slider-axis-bottom {\n    top: .8em;\n}\n\n.d3-slider-axis-right {\n    left: .8em;\n}\n\n.d3-slider-axis path {\n    stroke-width: 0;\n    fill: none;\n}\n\n.d3-slider-axis line {\n    fill: none;\n    stroke: #aaa;\n    shape-rendering: crispEdges;\n}\n\n.d3-slider-axis text {\n    font-size: 11px;\n}\n\n.d3-slider-vertical .d3-slider-handle {\n    left: -.25em;\n    margin-left: 0;\n    margin-bottom: -.6em;      \n}", ""]);
	
		// exports
	
	
	/***/ },
	/* 192 */
	/***/ function(module, exports) {
	
		"use strict";
	
		/*
			MIT License http://www.opensource.org/licenses/mit-license.php
			Author Tobias Koppers @sokra
		*/
		// css base code, injected by the css-loader
		module.exports = function () {
			var list = [];
	
			// return the list of modules as css string
			list.toString = function toString() {
				var result = [];
				for (var i = 0; i < this.length; i++) {
					var item = this[i];
					if (item[2]) {
						result.push("@media " + item[2] + "{" + item[1] + "}");
					} else {
						result.push(item[1]);
					}
				}
				return result.join("");
			};
	
			// import a list of modules into the list
			list.i = function (modules, mediaQuery) {
				if (typeof modules === "string") modules = [[null, modules, ""]];
				var alreadyImportedModules = {};
				for (var i = 0; i < this.length; i++) {
					var id = this[i][0];
					if (typeof id === "number") alreadyImportedModules[id] = true;
				}
				for (i = 0; i < modules.length; i++) {
					var item = modules[i];
					// skip already imported module
					// this implementation is not 100% perfect for weird media query combinations
					//  when a module is imported multiple times with different media queries.
					//  I hope this will never occur (Hey this way we have smaller bundles)
					if (typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {
						if (mediaQuery && !item[2]) {
							item[2] = mediaQuery;
						} else if (mediaQuery) {
							item[2] = "(" + item[2] + ") and (" + mediaQuery + ")";
						}
						list.push(item);
					}
				}
			};
			return list;
		};
	
	/***/ },
	/* 193 */
	/***/ function(module, exports, __webpack_require__) {
	
		/*
			MIT License http://www.opensource.org/licenses/mit-license.php
			Author Tobias Koppers @sokra
		*/
		var stylesInDom = {},
			memoize = function(fn) {
				var memo;
				return function () {
					if (typeof memo === "undefined") memo = fn.apply(this, arguments);
					return memo;
				};
			},
			isOldIE = memoize(function() {
				return /msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase());
			}),
			getHeadElement = memoize(function () {
				return document.head || document.getElementsByTagName("head")[0];
			}),
			singletonElement = null,
			singletonCounter = 0,
			styleElementsInsertedAtTop = [];
	
		module.exports = function(list, options) {
			if(false) {
				if(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
			}
	
			options = options || {};
			// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
			// tags it will allow on a page
			if (typeof options.singleton === "undefined") options.singleton = isOldIE();
	
			// By default, add <style> tags to the bottom of <head>.
			if (typeof options.insertAt === "undefined") options.insertAt = "bottom";
	
			var styles = listToStyles(list);
			addStylesToDom(styles, options);
	
			return function update(newList) {
				var mayRemove = [];
				for(var i = 0; i < styles.length; i++) {
					var item = styles[i];
					var domStyle = stylesInDom[item.id];
					domStyle.refs--;
					mayRemove.push(domStyle);
				}
				if(newList) {
					var newStyles = listToStyles(newList);
					addStylesToDom(newStyles, options);
				}
				for(var i = 0; i < mayRemove.length; i++) {
					var domStyle = mayRemove[i];
					if(domStyle.refs === 0) {
						for(var j = 0; j < domStyle.parts.length; j++)
							domStyle.parts[j]();
						delete stylesInDom[domStyle.id];
					}
				}
			};
		}
	
		function addStylesToDom(styles, options) {
			for(var i = 0; i < styles.length; i++) {
				var item = styles[i];
				var domStyle = stylesInDom[item.id];
				if(domStyle) {
					domStyle.refs++;
					for(var j = 0; j < domStyle.parts.length; j++) {
						domStyle.parts[j](item.parts[j]);
					}
					for(; j < item.parts.length; j++) {
						domStyle.parts.push(addStyle(item.parts[j], options));
					}
				} else {
					var parts = [];
					for(var j = 0; j < item.parts.length; j++) {
						parts.push(addStyle(item.parts[j], options));
					}
					stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
				}
			}
		}
	
		function listToStyles(list) {
			var styles = [];
			var newStyles = {};
			for(var i = 0; i < list.length; i++) {
				var item = list[i];
				var id = item[0];
				var css = item[1];
				var media = item[2];
				var sourceMap = item[3];
				var part = {css: css, media: media, sourceMap: sourceMap};
				if(!newStyles[id])
					styles.push(newStyles[id] = {id: id, parts: [part]});
				else
					newStyles[id].parts.push(part);
			}
			return styles;
		}
	
		function insertStyleElement(options, styleElement) {
			var head = getHeadElement();
			var lastStyleElementInsertedAtTop = styleElementsInsertedAtTop[styleElementsInsertedAtTop.length - 1];
			if (options.insertAt === "top") {
				if(!lastStyleElementInsertedAtTop) {
					head.insertBefore(styleElement, head.firstChild);
				} else if(lastStyleElementInsertedAtTop.nextSibling) {
					head.insertBefore(styleElement, lastStyleElementInsertedAtTop.nextSibling);
				} else {
					head.appendChild(styleElement);
				}
				styleElementsInsertedAtTop.push(styleElement);
			} else if (options.insertAt === "bottom") {
				head.appendChild(styleElement);
			} else {
				throw new Error("Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'.");
			}
		}
	
		function removeStyleElement(styleElement) {
			styleElement.parentNode.removeChild(styleElement);
			var idx = styleElementsInsertedAtTop.indexOf(styleElement);
			if(idx >= 0) {
				styleElementsInsertedAtTop.splice(idx, 1);
			}
		}
	
		function createStyleElement(options) {
			var styleElement = document.createElement("style");
			styleElement.type = "text/css";
			insertStyleElement(options, styleElement);
			return styleElement;
		}
	
		function createLinkElement(options) {
			var linkElement = document.createElement("link");
			linkElement.rel = "stylesheet";
			insertStyleElement(options, linkElement);
			return linkElement;
		}
	
		function addStyle(obj, options) {
			var styleElement, update, remove;
	
			if (options.singleton) {
				var styleIndex = singletonCounter++;
				styleElement = singletonElement || (singletonElement = createStyleElement(options));
				update = applyToSingletonTag.bind(null, styleElement, styleIndex, false);
				remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true);
			} else if(obj.sourceMap &&
				typeof URL === "function" &&
				typeof URL.createObjectURL === "function" &&
				typeof URL.revokeObjectURL === "function" &&
				typeof Blob === "function" &&
				typeof btoa === "function") {
				styleElement = createLinkElement(options);
				update = updateLink.bind(null, styleElement);
				remove = function() {
					removeStyleElement(styleElement);
					if(styleElement.href)
						URL.revokeObjectURL(styleElement.href);
				};
			} else {
				styleElement = createStyleElement(options);
				update = applyToTag.bind(null, styleElement);
				remove = function() {
					removeStyleElement(styleElement);
				};
			}
	
			update(obj);
	
			return function updateStyle(newObj) {
				if(newObj) {
					if(newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap)
						return;
					update(obj = newObj);
				} else {
					remove();
				}
			};
		}
	
		var replaceText = (function () {
			var textStore = [];
	
			return function (index, replacement) {
				textStore[index] = replacement;
				return textStore.filter(Boolean).join('\n');
			};
		})();
	
		function applyToSingletonTag(styleElement, index, remove, obj) {
			var css = remove ? "" : obj.css;
	
			if (styleElement.styleSheet) {
				styleElement.styleSheet.cssText = replaceText(index, css);
			} else {
				var cssNode = document.createTextNode(css);
				var childNodes = styleElement.childNodes;
				if (childNodes[index]) styleElement.removeChild(childNodes[index]);
				if (childNodes.length) {
					styleElement.insertBefore(cssNode, childNodes[index]);
				} else {
					styleElement.appendChild(cssNode);
				}
			}
		}
	
		function applyToTag(styleElement, obj) {
			var css = obj.css;
			var media = obj.media;
	
			if(media) {
				styleElement.setAttribute("media", media)
			}
	
			if(styleElement.styleSheet) {
				styleElement.styleSheet.cssText = css;
			} else {
				while(styleElement.firstChild) {
					styleElement.removeChild(styleElement.firstChild);
				}
				styleElement.appendChild(document.createTextNode(css));
			}
		}
	
		function updateLink(linkElement, obj) {
			var css = obj.css;
			var sourceMap = obj.sourceMap;
	
			if(sourceMap) {
				// http://stackoverflow.com/a/26603875
				css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */";
			}
	
			var blob = new Blob([css], { type: "text/css" });
	
			var oldSrc = linkElement.href;
	
			linkElement.href = URL.createObjectURL(blob);
	
			if(oldSrc)
				URL.revokeObjectURL(oldSrc);
		}
	
	
	/***/ },
	/* 194 */
	/***/ function(module, exports, __webpack_require__) {
	
		// style-loader: Adds some css to the DOM by adding a <style> tag
	
		// load the styles
		var content = __webpack_require__(195);
		if(typeof content === 'string') content = [[module.id, content, '']];
		// add the styles to the DOM
		var update = __webpack_require__(193)(content, {});
		if(content.locals) module.exports = content.locals;
		// Hot Module Replacement
		if(false) {
			// When the styles change, update the <style> tags
			if(!content.locals) {
				module.hot.accept("!!./../css-loader/index.js!./awesomplete.css", function() {
					var newContent = require("!!./../css-loader/index.js!./awesomplete.css");
					if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
					update(newContent);
				});
			}
			// When the module is disposed, remove the <style> tags
			module.hot.dispose(function() { update(); });
		}
	
	/***/ },
	/* 195 */
	/***/ function(module, exports, __webpack_require__) {
	
		exports = module.exports = __webpack_require__(192)();
		// imports
	
	
		// module
		exports.push([module.id, "[hidden] { display: none; }\n\n.visually-hidden {\n\tposition: absolute;\n\tclip: rect(0, 0, 0, 0);\n}\n\ndiv.awesomplete {\n\tdisplay: inline-block;\n\tposition: relative;\n}\n\ndiv.awesomplete > input {\n\tdisplay: block;\n}\n\ndiv.awesomplete > ul {\n\tposition: absolute;\n\tleft: 0;\n\tz-index: 1;\n\tmin-width: 100%;\n\tbox-sizing: border-box;\n\tlist-style: none;\n\tpadding: 0;\n\tborder-radius: .3em;\n\tmargin: .2em 0 0;\n\tbackground: hsla(0,0%,100%,.9);\n\tbackground: linear-gradient(to bottom right, white, hsla(0,0%,100%,.8));\n\tborder: 1px solid rgba(0,0,0,.3);\n\tbox-shadow: .05em .2em .6em rgba(0,0,0,.2);\n\ttext-shadow: none;\n}\n\ndiv.awesomplete > ul[hidden],\ndiv.awesomplete > ul:empty {\n\tdisplay: none;\n}\n\n@supports (transform: scale(0)) {\n\tdiv.awesomplete > ul {\n\t\ttransition: .3s cubic-bezier(.4,.2,.5,1.4);\n\t\ttransform-origin: 1.43em -.43em;\n\t}\n\t\n\tdiv.awesomplete > ul[hidden],\n\tdiv.awesomplete > ul:empty {\n\t\topacity: 0;\n\t\ttransform: scale(0);\n\t\tdisplay: block;\n\t\ttransition-timing-function: ease;\n\t}\n}\n\n\t/* Pointer */\n\tdiv.awesomplete > ul:before {\n\t\tcontent: \"\";\n\t\tposition: absolute;\n\t\ttop: -.43em;\n\t\tleft: 1em;\n\t\twidth: 0; height: 0;\n\t\tpadding: .4em;\n\t\tbackground: white;\n\t\tborder: inherit;\n\t\tborder-right: 0;\n\t\tborder-bottom: 0;\n\t\t-webkit-transform: rotate(45deg);\n\t\ttransform: rotate(45deg);\n\t}\n\n\tdiv.awesomplete > ul > li {\n\t\tposition: relative;\n\t\tpadding: .2em .5em;\n\t\tcursor: pointer;\n\t}\n\t\n\tdiv.awesomplete > ul > li:hover {\n\t\tbackground: hsl(200, 40%, 80%);\n\t\tcolor: black;\n\t}\n\t\n\tdiv.awesomplete > ul > li[aria-selected=\"true\"] {\n\t\tbackground: hsl(205, 40%, 40%);\n\t\tcolor: white;\n\t}\n\t\n\t\tdiv.awesomplete mark {\n\t\t\tbackground: hsl(65, 100%, 50%);\n\t\t}\n\t\t\n\t\tdiv.awesomplete li:hover mark {\n\t\t\tbackground: hsl(68, 100%, 41%);\n\t\t}\n\t\t\n\t\tdiv.awesomplete li[aria-selected=\"true\"] mark {\n\t\t\tbackground: hsl(86, 100%, 21%);\n\t\t\tcolor: inherit;\n\t\t}", ""]);
	
		// exports
	
	
	/***/ },
	/* 196 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var ini_sidebar = __webpack_require__(156);
		var set_up_filters = __webpack_require__(197);
		var set_up_search = __webpack_require__(202);
		var set_up_reorder = __webpack_require__(203);
		var set_sidebar_ini_view = __webpack_require__(204);
		var make_icons = __webpack_require__(205);
		var make_modals = __webpack_require__(207);
		var set_up_opacity_slider = __webpack_require__(209);
	
		/* Represents sidebar with controls.
		 */
		module.exports = function sidebar(cgm) {
	
		  var params = cgm.params;
	
		  var sidebar = d3.select(params.root + ' .sidebar_wrapper');
	
		  // console.log('is_expand ',params.viz.is_expand)
	
		  if (params.viz.is_expand) {
		    sidebar.style('display', 'none');
		  }
	
		  sidebar.append('div').classed('title_section', true);
	
		  if (params.sidebar.title != null) {
		    sidebar.select('.title_section').append('h4')
		    // .style('margin-left', params.sidebar.title_margin_left+'px')
		    .style('margin-left', '20px').style('margin-top', '5px').style('margin-bottom', '0px').text(params.sidebar.title);
		  }
	
		  sidebar.append('div').style('padding-right', '2px').classed('about_section', true);
	
		  if (params.sidebar.about != null) {
	
		    sidebar.select('.about_section').append('h5').classed('sidebar_text', true).style('margin-left', '7px').style('margin-top', '5px').style('margin-bottom', '2px').style('text-align', 'justify').html(params.sidebar.about);
		  }
	
		  sidebar.append('div').classed('icons_section', true).style('text-align', 'center');
	
		  if (cgm.params.make_modals) {
		    make_modals(params);
		  }
	
		  if (params.sidebar.icons) {
		    make_icons(cgm, sidebar);
		  }
	
		  set_up_reorder(params, sidebar);
	
		  set_up_search(sidebar, params);
	
		  set_up_opacity_slider(sidebar);
	
		  var possible_filter_names = _.keys(params.viz.possible_filters);
	
		  if (possible_filter_names.indexOf('enr_score_type') > -1) {
		    possible_filter_names.sort(function (a, b) {
		      return a.toLowerCase().localeCompare(b.toLowerCase());
		    });
		  }
	
		  cgm.slider_functions = {};
	
		  _.each(possible_filter_names, function (inst_filter) {
		    set_up_filters(cgm, inst_filter);
		  });
	
		  ini_sidebar(cgm);
	
		  // when initializing the visualization using a view
		  if (params.ini_view !== null) {
	
		    set_sidebar_ini_view(params);
	
		    params.ini_view = null;
		  }
			};
	
	/***/ },
	/* 197 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var make_slider_filter = __webpack_require__(198);
		var make_button_filter = __webpack_require__(201);
	
		module.exports = function set_up_filters(cgm, filter_type) {
	
		  var params = cgm.params;
	
		  var div_filters = d3.select(params.root + ' .sidebar_wrapper').append('div').classed('div_filters', true).style('padding-left', '10px').style('padding-right', '10px');
	
		  if (params.viz.possible_filters[filter_type] == 'numerical') {
		    make_slider_filter(cgm, filter_type, div_filters);
		  } else if (params.viz.possible_filters[filter_type] == 'categorical') {
		    make_button_filter(cgm, filter_type, div_filters);
		  }
			};
	
	/***/ },
	/* 198 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var make_filter_title = __webpack_require__(179);
		var run_filter_slider = __webpack_require__(199);
		var get_filter_default_state = __webpack_require__(5);
		var get_subset_views = __webpack_require__(12);
	
		d3.slider = __webpack_require__(186);
	
		module.exports = function make_slider_filter(cgm, filter_type, div_filters) {
	
		  var params = cgm.params;
		  var inst_view = {};
	
		  var possible_filters = _.keys(params.viz.possible_filters);
	
		  _.each(possible_filters, function (tmp_filter) {
		    if (tmp_filter != filter_type) {
		      var default_state = get_filter_default_state(params.viz.filter_data, tmp_filter);
		      inst_view[tmp_filter] = default_state;
		    }
		  });
	
		  var filter_title = make_filter_title(params, filter_type);
	
		  div_filters.append('div').classed('title_' + filter_type, true).classed('sidebar_text', true).classed('slider_description', true).style('margin-top', '5px').style('margin-bottom', '3px').text(filter_title.text + filter_title.state + filter_title.suffix);
	
		  div_filters.append('div').classed('slider_' + filter_type, true).classed('slider', true).attr('current_state', filter_title.state);
	
		  var views = params.network_data.views;
	
		  var available_views = get_subset_views(params, views, inst_view);
	
		  // sort available views by filter_type value
		  available_views = available_views.sort(function (a, b) {
		    return b[filter_type] - a[filter_type];
		  });
	
		  var inst_max = available_views.length - 1;
	
		  var ini_value = 0;
		  // change the starting position of the slider if necessary
		  if (params.requested_view !== null && filter_type in params.requested_view) {
	
		    var inst_filter_value = params.requested_view[filter_type];
	
		    if (inst_filter_value != 'all') {
	
		      var found_value = available_views.map(function (e) {
		        return e[filter_type];
		      }).indexOf(inst_filter_value);
	
		      if (found_value > 0) {
		        ini_value = found_value;
		      }
		    }
		  }
	
		  // Filter Slider
		  //////////////////////////////////////////////////////////////////////
		  var slide_filter_fun = d3.slider().value(ini_value).min(0).max(inst_max).step(1).on('slide', function (evt, value) {
		    run_filter_slider_db(cgm, filter_type, available_views, value);
		  }).on('slideend', function (evt, value) {
		    run_filter_slider_db(cgm, filter_type, available_views, value);
		  });
	
		  // save slider function in order to reset value later
		  cgm.slider_functions[filter_type] = slide_filter_fun;
	
		  d3.select(cgm.params.root + ' .slider_' + filter_type).call(slide_filter_fun);
	
		  //////////////////////////////////////////////////////////////////////
	
		  var run_filter_slider_db = _.debounce(run_filter_slider, 800);
			};
	
	/***/ },
	/* 199 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var update_viz_with_view = __webpack_require__(141);
		var reset_other_filter_sliders = __webpack_require__(178);
		var get_current_orders = __webpack_require__(200);
		var make_requested_view = __webpack_require__(14);
	
		module.exports = function run_filter_slider(cgm, filter_type, available_views, inst_index) {
	
		  // only update if not running update
		  if (d3.select(cgm.params.viz.viz_svg).classed('running_update') === false) {
	
		    var params = cgm.params;
	
		    // get value
		    var inst_state = available_views[inst_index][filter_type];
	
		    reset_other_filter_sliders(cgm, filter_type, inst_state);
	
		    params = get_current_orders(params);
	
		    var requested_view = {};
		    requested_view[filter_type] = inst_state;
	
		    requested_view = make_requested_view(params, requested_view);
	
		    if (_.has(available_views[0], 'enr_score_type')) {
		      var enr_state = d3.select(params.root + ' .toggle_enr_score_type').attr('current_state');
	
		      requested_view.enr_score_type = enr_state;
		    }
	
		    update_viz_with_view(cgm, requested_view);
		  }
			};
	
	/***/ },
	/* 200 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function get_current_orders(params) {
	
		  // get current orders 
		  var other_rc;
		  _.each(['row', 'col'], function (inst_rc) {
	
		    if (inst_rc === 'row') {
		      other_rc = 'col';
		    } else {
		      other_rc = 'row';
		    }
	
		    if (d3.select(params.root + ' .toggle_' + other_rc + '_order .active').empty() === false) {
	
		      params.viz.inst_order[inst_rc] = d3.select(params.root + ' .toggle_' + other_rc + '_order').select('.active').attr('name');
		    } else {
	
		      // default to cluster ordering 
		      params.viz.inst_order[inst_rc] = 'clust';
		    }
		  });
	
		  return params;
		};
	
	/***/ },
	/* 201 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		// var update_network = require('../network/update_network');
		var make_requested_view = __webpack_require__(14);
	
		module.exports = function make_button_filter(config, params, filter_type, div_filters) {
	
		  /*
		  Enrichr specific code
		  */
	
		  var buttons = div_filters.append('div').classed('categorical_filter', true).classed('toggle_' + filter_type, true).classed('btn-group-vertical', true).style('width', '100%').style('margin-top', '10px').attr('current_state', 'combined_score');
	
		  var filter_options = params.viz.filter_data[filter_type];
	
		  var button_dict = {
		    'combined_score': 'Combined Score',
		    'pval': 'P-Value',
		    'zscore': 'Z-score'
		  };
	
		  buttons.selectAll('button').data(filter_options).enter().append('button').attr('type', 'button').classed('btn', true).classed('btn-primary', true).classed('.filter_button', true).classed('active', function (d) {
		    var is_active = false;
		    if (d == 'combined_score') {
		      is_active = true;
		    }
		    return is_active;
		  }).attr('name', function (d) {
		    return d;
		  }).html(function (d) {
		    return button_dict[d];
		  });
	
		  $(params.root + ' .categorical_filter .btn').off().click(function () {
	
		    d3.selectAll(params.root + ' .categorical_filter .btn').classed('active', false);
	
		    d3.select(this).classed('active', true);
	
		    var inst_state = d3.select(this).attr('name');
	
		    var requested_view = { 'enr_score_type': inst_state };
	
		    make_requested_view(params, requested_view);
	
		    d3.select(params.root + ' .toggle_enr_score_type').attr('current_state', inst_state);
		  });
			};
	
	/***/ },
	/* 202 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function set_up_search(sidebar, params) {
	
		  var search_container = sidebar.append('div')
		  // .classed('row',true)
		  .classed('gene_search_container', true).style('padding-left', '10px').style('padding-right', '10px').style('margin-top', '10px');
	
		  search_container.append('input').classed('form-control', true).classed('gene_search_box', true).classed('sidebar_text', true).attr('type', 'text').attr('placeholder', params.sidebar.row_search.placeholder).style('height', params.sidebar.row_search.box.height + 'px').style('margin-top', '10px');
	
		  search_container.append('div').classed('gene_search_button', true).style('margin-top', '5px').attr('data-toggle', 'buttons').append('button').classed('sidebar_text', true).html('Search').attr('type', 'button').classed('btn', true).classed('btn-primary', true).classed('submit_gene_button', true).style('width', '100%').style('font-size', '14px');
			};
	
	/***/ },
	/* 203 */
	/***/ function(module, exports) {
	
		'use strict';
	
		// var get_cat_title = require('../categories/get_cat_title');
	
		module.exports = function set_up_reorder(params, sidebar) {
	
		  var button_dict;
		  var tmp_orders;
		  var rc_dict = { 'row': 'Row', 'col': 'Column', 'both': '' };
		  var is_active;
		  var inst_reorder;
		  // var all_cats;
		  // var inst_order_label;
	
		  var reorder_section = sidebar.append('div').style('padding-left', '10px').style('padding-right', '10px').classed('reorder_section', true);
	
		  var reorder_types;
		  if (params.sim_mat) {
		    reorder_types = ['both'];
		  } else {
		    reorder_types = ['row', 'col'];
		  }
	
		  _.each(reorder_types, function (inst_rc) {
	
		    button_dict = {
		      'clust': 'Cluster',
		      'rank': 'Rank by Sum',
		      'rankvar': 'Rank by Variance',
		      'ini': 'Initial Order',
		      'alpha': 'Alphabetically'
		    };
	
		    var other_rc;
		    if (inst_rc === 'row') {
		      other_rc = 'col';
		    } else {
		      other_rc = 'row';
		    }
	
		    tmp_orders = Object.keys(params.matrix.orders);
	
		    var possible_orders = [];
	
		    _.each(tmp_orders, function (inst_name) {
	
		      if (inst_name.indexOf(other_rc) > -1) {
		        inst_name = inst_name.replace('_row', '').replace('_col', '');
	
		        if (inst_name.indexOf('cat_') < 0) {
		          possible_orders.push(inst_name);
		        }
		      }
		    });
	
		    // specific to Enrichr
		    if (_.keys(params.viz.filter_data).indexOf('enr_score_type') > -1) {
		      possible_orders = ['clust', 'rank'];
		    }
	
		    possible_orders = _.uniq(possible_orders);
	
		    possible_orders = possible_orders.sort();
	
		    var reorder_text;
		    if (inst_rc != 'both') {
		      reorder_text = ' Order';
		    } else {
		      reorder_text = 'Reorder Matrix';
		    }
	
		    reorder_section.append('div').classed('sidebar_button_text', true).style('clear', 'both').style('margin-top', '10px').html(rc_dict[inst_rc] + reorder_text);
	
		    inst_reorder = reorder_section.append('div').classed('btn-group-vertical', true).style('width', '100%').classed('toggle_' + inst_rc + '_order', true).attr('role', 'group');
	
		    inst_reorder.selectAll('.button').data(possible_orders).enter().append('button').attr('type', 'button').classed('btn', true).classed('btn-primary', true).classed('sidebar_button_text', true).classed('active', function (d) {
		      is_active = false;
		      if (d == params.viz.inst_order[other_rc]) {
		        is_active = true;
		      }
		      return is_active;
		    }).attr('name', function (d) {
		      return d;
		    }).html(function (d) {
		      return button_dict[d];
		    });
		  });
			};
	
	/***/ },
	/* 204 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var make_filter_title = __webpack_require__(179);
	
		module.exports = function set_sidebar_ini_view(params) {
	
		  _.each(_.keys(params.ini_view), function (inst_filter) {
	
		    // initialize filter slider using ini_view
		    var inst_value = params.ini_view[inst_filter];
	
		    var filter_type = params.viz.possible_filters[inst_filter];
	
		    if (filter_type === 'numerical') {
	
		      if (inst_value != 'all') {
		        inst_value = parseInt(inst_value, 10);
		      }
	
		      if (params.viz.filter_data[inst_filter].indexOf(inst_value) <= -1) {
		        inst_value = 'all';
		      }
	
		      var filter_title = make_filter_title(params, inst_filter);
	
		      d3.select(params.root + ' .title_' + inst_filter).text(filter_title.text + inst_value + filter_title.suffix);
	
		      d3.select(params.root + ' .slider_' + inst_filter).attr('current_state', inst_value);
		    } else {
	
		      // set up button initialization
	
		    }
		  });
			};
	
	/***/ },
	/* 205 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var file_saver = __webpack_require__(181);
		var two_translate_zoom = __webpack_require__(80);
		var deactivate_cropping = __webpack_require__(185);
		var save_svg_png = __webpack_require__(206);
	
		module.exports = function make_icons(cgm, sidebar) {
	
		  var params = cgm.params;
		  // var saveSvgAsPng = save_svg_png();
		  var saveAs = file_saver();
	
		  var row = sidebar.select('.icons_section').style('margin-top', '7px').style('margin-left', '5%');
	
		  var width_pct = '22%';
		  var padding_left = '0px';
		  var padding_right = '0px';
	
		  row.append('div').classed('clust_icon', true).style('float', 'left').style('width', width_pct).style('padding-left', padding_left).style('padding-right', padding_right).append('i').classed('fa', true).classed('fa-share-alt', true).classed('icon_buttons', true).style('font-size', '25px').on('click', function () {
		    $(params.root + ' .share_info').modal('toggle');
		    $('.share_url').val(window.location.href);
		  }).classed('sidebar_tooltip', true).append('span').classed('sidebar_tooltip_text', true).html('Share').style('left', '0%');
	
		  row.append('div').classed('clust_icon', true).style('float', 'left').style('width', width_pct).style('padding-left', padding_left).style('padding-right', padding_right).append('i').classed('fa', true).classed('fa-camera', true).classed('icon_buttons', true).style('font-size', '25px').on('click', function () {
	
		    $(params.root + ' .picture_info').modal('toggle');
		  }).classed('sidebar_tooltip', true).append('span').classed('sidebar_tooltip_text', true).html('Take snapshot').style('left', '-100%');
	
		  row.append('div').classed('clust_icon', true).style('float', 'left').style('width', width_pct).style('padding-left', padding_left).style('padding-right', padding_right).append('i').classed('fa', true).classed('fa fa-cloud-download', true).classed('icon_buttons', true).style('font-size', '25px').on('click', function () {
	
		    cgm.save_matrix();
		  }).classed('sidebar_tooltip', true).append('span').classed('sidebar_tooltip_text', true).html('Download matrix').style('left', '-200%');
	
		  row.append('div').classed('clust_icon', true).style('float', 'left').style('width', width_pct).style('padding-left', padding_left).style('padding-right', '-5px').append('i').classed('fa', true).classed('fa-crop', true).classed('crop_button', true).classed('icon_buttons', true).style('font-size', '25px').on('click', function () {
	
		    // do nothing if dendro filtering has been done
		    if (cgm.params.dendro_filter.row === false && cgm.params.dendro_filter.col === false) {
	
		      var is_crop = d3.select(this).classed('fa-crop');
	
		      var is_undo = d3.select(this).classed('fa-undo');
	
		      // press crop button (can be active/incative)
		      if (is_crop) {
	
		        // keep list of names to return to state
		        cgm.params.crop_filter_nodes = {};
		        cgm.params.crop_filter_nodes.row_nodes = cgm.params.network_data.row_nodes;
		        cgm.params.crop_filter_nodes.col_nodes = cgm.params.network_data.col_nodes;
	
		        cgm.brush_crop_matrix();
	
		        if (d3.select(this).classed('active_cropping') === false) {
	
		          // set active_cropping (button turns red)
		          d3.select(this).classed('active_cropping', true).style('color', 'red');
		        } else {
		          // deactivate cropping (button turns blue)
		          d3.select(this).classed('active_cropping', false).style('color', '#337ab7');
	
		          deactivate_cropping(cgm);
		        }
		      }
	
		      // press undo button
		      if (is_undo) {
	
		        d3.select(params.root + ' .crop_button').style('color', '#337ab7').classed('fa-crop', true).classed('fa-undo', false);
	
		        // cgm.filter_viz_using_names(cgm.params.crop_filter_nodes);
		        cgm.filter_viz_using_nodes(cgm.params.crop_filter_nodes);
	
		        // show dendro crop buttons after brush-cropping has been undone
		        d3.select(cgm.params.root + ' .col_dendro_icons_container').style('display', 'block');
		        d3.select(cgm.params.root + ' .row_dendro_icons_container').style('display', 'block');
		      }
	
		      two_translate_zoom(cgm, 0, 0, 1);
		    }
		  }).classed('sidebar_tooltip', true).append('span').classed('sidebar_tooltip_text', true).html('Crop matrix').style('left', '-400%');
	
		  // save svg: example from: http://bl.ocks.org/pgiraud/8955139#profile.json
		  ////////////////////////////////////////////////////////////////////////////
		  function save_clust_svg() {
	
		    d3.select(params.root + ' .expand_button').style('opacity', 0);
	
		    var html = d3.select(params.root + " svg").attr("title", "test2").attr("version", 1.1).attr("xmlns", "http://www.w3.org/2000/svg").node().parentNode.innerHTML;
	
		    var blob = new Blob([html], { type: "image/svg+xml" });
	
		    saveAs(blob, "clustergrammer.svg");
	
		    d3.select(params.root + ' .expand_button').style('opacity', 0.4);
		  }
	
		  d3.select(params.root + ' .download_buttons').append('p').append('a').html('Download SVG').on('click', function () {
		    save_clust_svg();
		  });
	
		  var svg_id = 'svg_' + params.root.replace('#', '');
	
		  // save as PNG
		  /////////////////////////////////////////
		  d3.select(params.root + ' .download_buttons').append('p').append('a').html('Download PNG').on('click', function () {
		    d3.select(params.root + ' .expand_button').style('opacity', 0);
		    // saveSvgAsPng(document.getElementById(svg_id), "clustergrammer.png");
		    save_svg_png.saveSvgAsPng(document.getElementById(svg_id), "clustergrammer.png");
		    d3.select(params.root + ' .expand_button').style('opacity', 0.4);
		  });
			};
	
	/***/ },
	/* 206 */
	/***/ function(module, exports, __webpack_require__) {
	
		var __WEBPACK_AMD_DEFINE_RESULT__;'use strict';
	
		(function () {
		  var out$ = typeof exports != 'undefined' && exports || "function" != 'undefined' && {} || this;
	
		  var doctype = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [<!ENTITY nbsp "&#160;">]>';
	
		  function isElement(obj) {
		    return obj instanceof HTMLElement || obj instanceof SVGElement;
		  }
	
		  function requireDomNode(el) {
		    if (!isElement(el)) {
		      throw new Error('an HTMLElement or SVGElement is required; got ' + el);
		    }
		  }
	
		  function isExternal(url) {
		    return url && url.lastIndexOf('http', 0) == 0 && url.lastIndexOf(window.location.host) == -1;
		  }
	
		  function inlineImages(el, callback) {
		    requireDomNode(el);
	
		    var images = el.querySelectorAll('image'),
		        left = images.length,
		        checkDone = function checkDone() {
		      if (left === 0) {
		        callback();
		      }
		    };
	
		    checkDone();
		    for (var i = 0; i < images.length; i++) {
		      (function (image) {
		        var href = image.getAttributeNS("http://www.w3.org/1999/xlink", "href");
		        if (href) {
		          if (isExternal(href.value)) {
		            console.warn("Cannot render embedded images linking to external hosts: " + href.value);
		            return;
		          }
		        }
		        var canvas = document.createElement('canvas');
		        var ctx = canvas.getContext('2d');
		        var img = new Image();
		        img.crossOrigin = "anonymous";
		        href = href || image.getAttribute('href');
		        if (href) {
		          img.src = href;
		          img.onload = function () {
		            canvas.width = img.width;
		            canvas.height = img.height;
		            ctx.drawImage(img, 0, 0);
		            image.setAttributeNS("http://www.w3.org/1999/xlink", "href", canvas.toDataURL('image/png'));
		            left--;
		            checkDone();
		          };
		          img.onerror = function () {
		            console.log("Could not load " + href);
		            left--;
		            checkDone();
		          };
		        } else {
		          left--;
		          checkDone();
		        }
		      })(images[i]);
		    }
		  }
	
		  function styles(el, options, cssLoadedCallback) {
		    var selectorRemap = options.selectorRemap;
		    var modifyStyle = options.modifyStyle;
		    var css = "";
		    // each font that has extranl link is saved into queue, and processed
		    // asynchronously
		    var fontsQueue = [];
		    var sheets = document.styleSheets;
		    for (var i = 0; i < sheets.length; i++) {
		      try {
		        var rules = sheets[i].cssRules;
		      } catch (e) {
		        console.warn("Stylesheet could not be loaded: " + sheets[i].href);
		        continue;
		      }
	
		      if (rules != null) {
		        for (var j = 0, match; j < rules.length; j++, match = null) {
		          var rule = rules[j];
		          if (typeof rule.style != "undefined") {
		            var selectorText;
	
		            try {
		              selectorText = rule.selectorText;
		            } catch (err) {
		              console.warn('The following CSS rule has an invalid selector: "' + rule + '"', err);
		            }
	
		            try {
		              if (selectorText) {
		                match = el.querySelector(selectorText);
		              }
		            } catch (err) {
		              console.warn('Invalid CSS selector "' + selectorText + '"', err);
		            }
	
		            if (match) {
		              var selector = selectorRemap ? selectorRemap(rule.selectorText) : rule.selectorText;
		              var cssText = modifyStyle ? modifyStyle(rule.style.cssText) : rule.style.cssText;
		              css += selector + " { " + cssText + " }\n";
		            } else if (rule.cssText.match(/^@font-face/)) {
		              // below we are trying to find matches to external link. E.g.
		              // @font-face {
		              //   // ...
		              //   src: local('Abel'), url(https://fonts.gstatic.com/s/abel/v6/UzN-iejR1VoXU2Oc-7LsbvesZW2xOQ-xsNqO47m55DA.woff2);
		              // }
		              //
		              // This regex will save extrnal link into first capture group
		              var fontUrlRegexp = /url\(["']?(.+?)["']?\)/;
		              // TODO: This needs to be changed to support multiple url declarations per font.
		              var fontUrlMatch = rule.cssText.match(fontUrlRegexp);
	
		              var externalFontUrl = fontUrlMatch && fontUrlMatch[1] || '';
		              var fontUrlIsDataURI = externalFontUrl.match(/^data:/);
		              if (fontUrlIsDataURI) {
		                // We should ignore data uri - they are already embedded
		                externalFontUrl = '';
		              }
	
		              if (externalFontUrl) {
		                // okay, we are lucky. We can fetch this font later
		                fontsQueue.push({
		                  text: rule.cssText,
		                  // Pass url regex, so that once font is downladed, we can run `replace()` on it
		                  fontUrlRegexp: fontUrlRegexp,
		                  format: getFontMimeTypeFromUrl(externalFontUrl),
		                  url: externalFontUrl
		                });
		              } else {
		                // otherwise, use previous logic
		                css += rule.cssText + '\n';
		              }
		            }
		          }
		        }
		      }
		    }
	
		    // Now all css is processed, it's time to handle scheduled fonts
		    processFontQueue(fontsQueue);
	
		    function getFontMimeTypeFromUrl(fontUrl) {
		      var supportedFormats = {
		        'woff2': 'font/woff2',
		        'woff': 'font/woff',
		        'otf': 'application/x-font-opentype',
		        'ttf': 'application/x-font-ttf',
		        'eot': 'application/vnd.ms-fontobject',
		        'sfnt': 'application/font-sfnt',
		        'svg': 'image/svg+xml'
		      };
		      var extensions = Object.keys(supportedFormats);
		      for (var i = 0; i < extensions.length; ++i) {
		        var extension = extensions[i];
		        // TODO: This is not bullet proof, it needs to handle edge cases...
		        if (fontUrl.indexOf('.' + extension) > 0) {
		          return supportedFormats[extension];
		        }
		      }
	
		      // If you see this error message, you probably need to update code above.
		      console.error('Unknown font format for ' + fontUrl + '; Fonts may not be working correctly');
		      return 'application/octet-stream';
		    }
	
		    function processFontQueue(queue) {
		      if (queue.length > 0) {
		        // load fonts one by one until we have anything in the queue:
		        var font = queue.pop();
		        processNext(font);
		      } else {
		        // no more fonts to load.
		        cssLoadedCallback(css);
		      }
	
		      function processNext(font) {
		        // TODO: This could benefit from caching.
		        var oReq = new XMLHttpRequest();
		        oReq.addEventListener('load', fontLoaded);
		        oReq.addEventListener('error', transferFailed);
		        oReq.addEventListener('abort', transferFailed);
		        oReq.open('GET', font.url);
		        oReq.responseType = 'arraybuffer';
		        oReq.send();
	
		        function fontLoaded() {
		          // TODO: it may be also worth to wait until fonts are fully loaded before
		          // attempting to rasterize them. (e.g. use https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet )
		          var fontBits = oReq.response;
		          var fontInBase64 = arrayBufferToBase64(fontBits);
		          updateFontStyle(font, fontInBase64);
		        }
	
		        function transferFailed(e) {
		          console.warn('Failed to load font from: ' + font.url);
		          console.warn(e);
		          css += font.text + '\n';
		          processFontQueue();
		        }
	
		        function updateFontStyle(font, fontInBase64) {
		          var dataUrl = 'url("data:' + font.format + ';base64,' + fontInBase64 + '")';
		          css += font.text.replace(font.fontUrlRegexp, dataUrl) + '\n';
	
		          // schedule next font download on next tick.
		          setTimeout(function () {
		            processFontQueue(queue);
		          }, 0);
		        }
		      }
		    }
	
		    function arrayBufferToBase64(buffer) {
		      var binary = '';
		      var bytes = new Uint8Array(buffer);
		      var len = bytes.byteLength;
	
		      for (var i = 0; i < len; i++) {
		        binary += String.fromCharCode(bytes[i]);
		      }
	
		      return window.btoa(binary);
		    }
		  }
	
		  function getDimension(el, clone, dim) {
		    var v = el.viewBox && el.viewBox.baseVal && el.viewBox.baseVal[dim] || clone.getAttribute(dim) !== null && !clone.getAttribute(dim).match(/%$/) && parseInt(clone.getAttribute(dim)) || el.getBoundingClientRect()[dim] || parseInt(clone.style[dim]) || parseInt(window.getComputedStyle(el).getPropertyValue(dim));
		    return typeof v === 'undefined' || v === null || isNaN(parseFloat(v)) ? 0 : v;
		  }
	
		  function reEncode(data) {
		    data = encodeURIComponent(data);
		    data = data.replace(/%([0-9A-F]{2})/g, function (match, p1) {
		      var c = String.fromCharCode('0x' + p1);
		      return c === '%' ? '%25' : c;
		    });
		    return decodeURIComponent(data);
		  }
	
		  out$.prepareSvg = function (el, options, cb) {
		    requireDomNode(el);
	
		    options = options || {};
		    options.scale = options.scale || 1;
		    options.responsive = options.responsive || false;
		    var xmlns = "http://www.w3.org/2000/xmlns/";
	
		    inlineImages(el, function () {
		      var outer = document.createElement("div");
		      var clone = el.cloneNode(true);
		      var width, height;
		      if (el.tagName == 'svg') {
		        width = options.width || getDimension(el, clone, 'width');
		        height = options.height || getDimension(el, clone, 'height');
		      } else if (el.getBBox) {
		        var box = el.getBBox();
		        width = box.x + box.width;
		        height = box.y + box.height;
		        clone.setAttribute('transform', clone.getAttribute('transform').replace(/translate\(.*?\)/, ''));
	
		        var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
		        svg.appendChild(clone);
		        clone = svg;
		      } else {
		        console.error('Attempted to render non-SVG element', el);
		        return;
		      }
	
		      clone.setAttribute("version", "1.1");
		      if (!clone.getAttribute('xmlns')) {
		        clone.setAttributeNS(xmlns, "xmlns", "http://www.w3.org/2000/svg");
		      }
		      if (!clone.getAttribute('xmlns:xlink')) {
		        clone.setAttributeNS(xmlns, "xmlns:xlink", "http://www.w3.org/1999/xlink");
		      }
	
		      if (options.responsive) {
		        clone.removeAttribute('width');
		        clone.removeAttribute('height');
		        clone.setAttribute('preserveAspectRatio', 'xMinYMin meet');
		      } else {
		        clone.setAttribute("width", width * options.scale);
		        clone.setAttribute("height", height * options.scale);
		      }
	
		      clone.setAttribute("viewBox", [options.left || 0, options.top || 0, width, height].join(" "));
	
		      var fos = clone.querySelectorAll('foreignObject > *');
		      for (var i = 0; i < fos.length; i++) {
		        if (!fos[i].getAttribute('xmlns')) {
		          fos[i].setAttributeNS(xmlns, "xmlns", "http://www.w3.org/1999/xhtml");
		        }
		      }
	
		      outer.appendChild(clone);
	
		      // In case of custom fonts we need to fetch font first, and then inline
		      // its url into data-uri format (encode as base64). That's why style
		      // processing is done asynchonously. Once all inlining is finshed
		      // cssLoadedCallback() is called.
		      styles(el, options, cssLoadedCallback);
	
		      function cssLoadedCallback(css) {
		        // here all fonts are inlined, so that we can render them properly.
		        var s = document.createElement('style');
		        s.setAttribute('type', 'text/css');
		        s.innerHTML = "<![CDATA[\n" + css + "\n]]>";
		        var defs = document.createElement('defs');
		        defs.appendChild(s);
		        clone.insertBefore(defs, clone.firstChild);
	
		        if (cb) {
		          var outHtml = outer.innerHTML;
		          outHtml = outHtml.replace(/NS\d+:href/gi, 'xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href');
		          cb(outHtml, width, height);
		        }
		      }
		    });
		  };
	
		  out$.svgAsDataUri = function (el, options, cb) {
		    out$.prepareSvg(el, options, function (svg) {
		      var uri = 'data:image/svg+xml;base64,' + window.btoa(reEncode(doctype + svg));
		      if (cb) {
		        cb(uri);
		      }
		    });
		  };
	
		  out$.svgAsPngUri = function (el, options, cb) {
		    requireDomNode(el);
	
		    options = options || {};
		    options.encoderType = options.encoderType || 'image/png';
		    options.encoderOptions = options.encoderOptions || 0.8;
	
		    var convertToPng = function convertToPng(src, w, h) {
		      var canvas = document.createElement('canvas');
		      var context = canvas.getContext('2d');
		      canvas.width = w;
		      canvas.height = h;
	
		      if (options.canvg) {
		        options.canvg(canvas, src);
		      } else {
		        context.drawImage(src, 0, 0);
		      }
	
		      if (options.backgroundColor) {
		        context.globalCompositeOperation = 'destination-over';
		        context.fillStyle = options.backgroundColor;
		        context.fillRect(0, 0, canvas.width, canvas.height);
		      }
	
		      var png;
		      try {
		        png = canvas.toDataURL(options.encoderType, options.encoderOptions);
		      } catch (e) {
		        if (typeof SecurityError !== 'undefined' && e instanceof SecurityError || e.name == "SecurityError") {
		          console.error("Rendered SVG images cannot be downloaded in this browser.");
		          return;
		        } else {
		          throw e;
		        }
		      }
		      cb(png);
		    };
	
		    if (options.canvg) {
		      out$.prepareSvg(el, options, convertToPng);
		    } else {
		      out$.svgAsDataUri(el, options, function (uri) {
		        var image = new Image();
	
		        image.onload = function () {
		          convertToPng(image, image.width, image.height);
		        };
	
		        image.onerror = function () {
		          console.error('There was an error loading the data URI as an image on the following SVG\n', window.atob(uri.slice(26)), '\n', "Open the following link to see browser's diagnosis\n", uri);
		        };
	
		        image.src = uri;
		      });
		    }
		  };
	
		  out$.download = function (name, uri) {
		    if (navigator.msSaveOrOpenBlob) {
		      navigator.msSaveOrOpenBlob(uriToBlob(uri), name);
		    } else {
		      var saveLink = document.createElement('a');
		      var downloadSupported = 'download' in saveLink;
		      if (downloadSupported) {
		        saveLink.download = name;
		        saveLink.href = uri;
		        saveLink.style.display = 'none';
		        document.body.appendChild(saveLink);
		        saveLink.click();
		        document.body.removeChild(saveLink);
		      } else {
		        window.open(uri, '_temp', 'menubar=no,toolbar=no,status=no');
		      }
		    }
		  };
	
		  function uriToBlob(uri) {
		    var byteString = window.atob(uri.split(',')[1]);
		    var mimeString = uri.split(',')[0].split(':')[1].split(';')[0];
		    var buffer = new ArrayBuffer(byteString.length);
		    var intArray = new Uint8Array(buffer);
		    for (var i = 0; i < byteString.length; i++) {
		      intArray[i] = byteString.charCodeAt(i);
		    }
		    return new Blob([buffer], { type: mimeString });
		  }
	
		  out$.saveSvg = function (el, name, options) {
		    requireDomNode(el);
	
		    options = options || {};
		    out$.svgAsDataUri(el, options, function (uri) {
		      out$.download(name, uri);
		    });
		  };
	
		  out$.saveSvgAsPng = function (el, name, options) {
		    requireDomNode(el);
	
		    options = options || {};
		    out$.svgAsPngUri(el, options, function (uri) {
		      out$.download(name, uri);
		    });
		  };
	
		  // if define is defined create as an AMD module
		  if (true) {
		    !(__WEBPACK_AMD_DEFINE_RESULT__ = function () {
		      return out$;
		    }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		  }
			})();
	
	/***/ },
	/* 207 */
	/***/ function(module, exports, __webpack_require__) {
	
		'use strict';
	
		var make_modal_skeleton = __webpack_require__(208);
	
		module.exports = function ini_modals(params) {
	
		  // share modal
		  ///////////////////////////////////////
		  var share_modal = make_modal_skeleton(params, 'share_info');
	
		  share_modal.header.append('a').attr('target', '_blank').attr('href', '/clustergrammer/');
	
		  share_modal.header.append('h4').classed('modal-title', true).html('Share the visualization using the current URL:');
	
		  share_modal.body.append('input').classed('bootstrap_highlight', true).classed('share_url', true);
	
		  // picture modal
		  ///////////////////////////////////////
		  var screenshot_modal = make_modal_skeleton(params, 'picture_info');
	
		  screenshot_modal.header.append('h4').classed('modal-title', true).html('Save a snapshot of the visualization');
	
		  screenshot_modal.body.append('div').classed('download_buttons', true);
	
		  // dendro modal
		  ///////////////////////////////////////
		  var dendro_modal = make_modal_skeleton(params, 'dendro_info');
	
		  dendro_modal.header.append('h4').classed('modal-title', true).html('Cluster Information');
	
		  dendro_modal.body.append('g').classed('cluster_info_container', true);
	
		  dendro_modal.body.append('div').classed('dendro_text', true).append('input').classed('bootstrap_highlight', true).classed('current_names', true).style('width', '100%');
			};
	
	/***/ },
	/* 208 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function make_modal_skeleton(params, modal_class) {
	
		  var modal_skeleton = {};
	
		  var modal = d3.select(params.root).append('div').classed('modal', true).classed('fade', true).classed(modal_class, true).attr('role', 'dialog');
	
		  var modal_dialog = modal.append('div').classed('modal-dialog', true);
	
		  var modal_content = modal_dialog.append('div').classed('modal-content', true);
	
		  modal_skeleton.header = modal_content.append('div').classed('modal-header', true);
	
		  modal_skeleton.header.append('button').attr('type', 'button').classed('close', true).attr('data-dismiss', 'modal').html('&times;');
	
		  modal_skeleton.body = modal_content.append('div').classed('modal-body', true);
	
		  return modal_skeleton;
			};
	
	/***/ },
	/* 209 */
	/***/ function(module, exports) {
	
		'use strict';
	
		module.exports = function set_up_opacity_slider(sidebar) {
	
		  var slider_container = sidebar.append('div').classed('opacity_slider_container', true).style('margin-top', '5px').style('padding-left', '10px').style('padding-right', '10px');
	
		  slider_container.append('div').classed('sidebar_text', true).classed('opacity_slider_text', true).style('margin-bottom', '3px').text('Opacity Slider');
	
		  slider_container.append('div').classed('slider', true).classed('opacity_slider', true);
			};
	
	/***/ }
	/******/ ]);
	//# sourceMappingURL=clustergrammer.node.js.map

/***/ },
/* 6 */
/***/ function(module, exports) {

	function ini_hzome(root_id){
	
	  // save gene data to global variable
	  gene_data = {};
	
	  function get_mouseover(root_tip, gene_symbol){
	
	    // not sure if this is necessary
	    if ( d3.select(root_tip + '_row_tip').classed(gene_symbol) ){
	     get_request(root_tip, gene_symbol);
	    }
	
	  }
	
	  function get_request(root_tip, ini_gene_symbol){
	
	    var gene_symbol;
	    if (ini_gene_symbol.indexOf(' ') > 0){
	      gene_symbol = ini_gene_symbol.split(' ')[0];
	    } else if (ini_gene_symbol.indexOf('_') > 0){
	      gene_symbol = ini_gene_symbol.split('_')[0];
	    }
	    else {
	      gene_symbol = ini_gene_symbol;
	    }
	
	    var base_url = 'https://amp.pharm.mssm.edu/Harmonizome/api/1.0/gene/';
	    var url = base_url + gene_symbol;
	
	    $.get(url, function(data) {
	
	      data = JSON.parse(data);
	
	      // save data for repeated use
	      gene_data[gene_symbol] = {}
	      gene_data[gene_symbol].name = data.name;
	      gene_data[gene_symbol].description = data.description;
	
	      set_tooltip(data, root_tip, ini_gene_symbol);
	
	      return data;
	
	    });
	  }
	
	  function set_tooltip(data, root_tip, gene_symbol){
	
	    if (data.name != undefined){
	
	      d3.selectAll(root_tip + '_row_tip')
	        .html(function(){
	            var sym_name = gene_symbol + ': ' + data.name;
	            var full_html = '<p>' + sym_name + '</p>' +  '<p>' +
	              data.description + '</p>';
	            return full_html;
	        });
	    }
	  }
	
	
	  function gene_info(root_tip, gene_info){
	
	    var gene_symbol = gene_info.name;
	
	    if (_.has(gene_data, gene_symbol)){
	      var inst_data = gene_data[gene_symbol];
	      set_tooltip(inst_data, root_tip, gene_symbol);
	    } else{
	      setTimeout(get_mouseover, 250, root_tip, gene_symbol);
	    }
	
	  }
	
	  hzome = {}
	
	  hzome.gene_info = gene_info;
	  hzome.gene_data = gene_data;
	  hzome.get_mouseover = get_mouseover;
	  hzome.get_request = get_request;
	
	  return hzome;
	
	}
	
	module.exports = ini_hzome;

/***/ },
/* 7 */
/***/ function(module, exports) {

	function Enrichrgram(inst_cgm){
	
	  var inst_root = inst_cgm.params.root;
	
	  function enrichr_icon(){
	
	    var low_opacity = 0.7;
	    var high_opacity = 1.0;
	    var icon_size = 42;
	    var d3_tip_custom = inst_cgm.d3_tip_custom();
	
	    // var enrichr_description = 'Perform enrichment analysis on your gene-list <br>'+
	    //                           'using Enrichr to find biological information that is unique to your list.'
	    var enrichr_description = 'Perform enrichment analysis, using Enrichr, to find biological <br>'+
	                              'information specific to your set (or subset) of genes. <br><br>' +
	                              'Select a subset of genes for analysis by cropping the matrix using: the brush-cropping tool in the sidebar, or the crop buttons on the dendrogram.'
	    // d3-tooltip
	    var enr_tip = d3_tip_custom()
	      .attr('class', function(){
	        var root_tip_selector = inst_cgm.params.viz.root_tips.replace('.','');
	        var class_string = root_tip_selector + '_enr_tip d3-tip';
	        return class_string;
	      })
	      .direction('se')
	      .style('display', 'none')
	      .offset([-10,-5])
	      .html(function(d){
	        return enrichr_description;
	      });
	
	    var enr_logo = d3.select(inst_root+' .viz_svg').append("svg:image")
	     .attr('x', 50)
	     .attr('y', 2)
	     .attr('width', icon_size)
	     .attr('height', icon_size)
	     .attr("xlink:href", "https://amp.pharm.mssm.edu/Enrichr/images/enrichr-icon.png")
	     .style('opacity', low_opacity)
	     .classed('enrichr_logo', true)
	     .attr('id', function(){
	      var inst_id = 'enrichr_menu_button_' + inst_cgm.params.root.replace('#','');
	      return inst_id;
	     })
	     .on('click', function(){
	       toggle_enrichr_menu();
	     })
	     .on('mouseover', function(){
	
	      var is_showing = d3.select(inst_cgm.params.root+' .enrichr_menu')
	                         .classed('showing');
	
	      if (is_showing === false){
	        // show tooltip
	        d3.selectAll( inst_cgm.params.viz.root_tips + '_enr_tip')
	          .style('opacity', 1)
	          .style('display', 'block');
	
	         enr_tip.show();
	      }
	
	     })
	     .on('mouseout', function(){
	
	      // hide tooltip
	      d3.selectAll( inst_cgm.params.viz.root_tips + '_enr_tip')
	        .style('opacity', 0)
	        .style('display', 'block');
	
	       enr_tip.hide();
	     })
	     .call(enr_tip);
	
	    var enr_menu = d3.select(inst_cgm.params.root+' .viz_svg')
	      .append('g')
	      .classed('showing', false)
	      .classed('enrichr_menu', true)
	      .attr('transform', 'translate(85,40)')
	      .style('display', 'none');
	
	    enr_menu
	      .append('rect')
	      .classed('enr_menu_background', true)
	      .style('width', 475)
	      .style('height', 500)
	      .style('opacity', 0.95)
	      .style('fill', 'white')
	      .style('stroke', '#A3A3A3')
	      .style('stroke-width', '3px');
	
	    enr_menu
	      .append('text')
	      .attr('transform', 'translate(20,30)')
	      .attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif')
	      .style('font-size','18px')
	      .style('font-weight', 800)
	      .style('cursor', 'default')
	      .text('Choose Enrichr Library');
	
	    // clear results button
	    enr_menu
	      .append('text')
	      .classed('enr_menu_clear', true)
	      .attr('transform', 'translate(345, 30)')
	      .attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif')
	      .style('font-size','18px')
	      .style('font-weight', 800)
	      .style('cursor', 'default')
	      .text('Clear Results')
	      .style('fill', 'red')
	      .style('opacity', 0.75)
	      .style('display', 'none')
	      .on('click', function(){
	
	
	        // reset enrichr menu
	        toggle_enrichr_menu();
	
	        // clear enrichr results and run resizing
	        clear_enrichr_results(true);
	
	      })
	
	    var lib_section = enr_menu
	      .append('g')
	      .attr('transform', 'translate(20,60)')
	      .style('width', 460)
	      .style('height', 370)
	      .classed('enr_lib_section','true');
	
	    var possible_libraries = [
	      'ChEA_2016',
	      'KEA_2015',
	      'ENCODE_TF_ChIP-seq_2015',
	      'ENCODE_Histone_Modifications_2015',
	      'Disease_Perturbations_from_GEO_up',
	      'Disease_Perturbations_from_GEO_down',
	      'GO_Molecular_Function_2015',
	      'GO_Biological_Process_2015',
	      'GO_Cellular_Component_2015',
	      'Reactome_2016',
	      'KEGG_2016',
	      'MGI_Mammalian_Phenotype_Level_4',
	      'LINCS_L1000_Chem_Pert_up',
	      'LINCS_L1000_Chem_Pert_down',
	      ];
	
	    var vertical_space = 30;
	
	    enr_menu
	      .append('rect')
	      .classed('enr_menu_line', true)
	      .attr('height', '2px')
	      .attr('width', '435px')
	      .style('stroke-width', '3px')
	      .style('opacity', 0.3)
	      .style('fill','black')
	      .attr('transform', 'translate(20, 465)');
	
	    var enr_export_container = enr_menu
	      .append('g')
	      .classed('enr_export_container', true)
	      .attr('transform', 'translate(20, 487)');
	
	    enr_export_container
	      .append('text')
	      .style('font-size','16px')
	      .attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif')
	      .style('cursor', 'default')
	      .text('Export gene list to ');
	
	    enr_export_container
	      .append('text')
	      .style('font-size','16px')
	      .attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif')
	      .style('cursor', 'default')
	      .text('Enrichr')
	      .style('fill','#337ab7')
	      .attr('transform', 'translate(135, 0)')
	      .on('click', function(){
	
	        // get gene list and send to Enrichr
	        var gene_list = inst_cgm.params.network_data.row_nodes_names.join('\n');
	
	        var enrichr_info = {list: gene_list, description: 'Clustergrammer gene list' , popup: true};
	
	        // defined globally - will improve
	        enrich(enrichr_info);
	
	      })
	
	    var lib_groups = lib_section
	      .selectAll('g')
	      .data(possible_libraries)
	      .enter()
	      .append('g')
	      .attr('transform', function(d,i){
	        var vert =  i*vertical_space
	        var transform_string = 'translate(0,'+ vert+')';
	        return transform_string;
	      })
	
	    lib_groups
	      .append('circle')
	      .attr('cx', 10)
	      .attr('cy', -6)
	      .attr('r', 7)
	      .style('stroke', '#A3A3A3')
	      .style('stroke-width', '2px')
	      .style('fill','white')
	
	    lib_groups
	      .append('text')
	      .attr('transform', 'translate(25,0)')
	      .style('font-size','16px')
	      .attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif')
	      .style('cursor', 'default')
	      .text(function(d){
	        return d.replace(/_/g, ' ');
	      });
	
	    lib_groups
	      .on('click', function(d){
	
	        d3.select(inst_cgm.params.root+' .enr_lib_section')
	          .selectAll('g')
	          .select('circle')
	          .style('fill','white');
	
	        // indicate that library was selected
	        d3.select(this)
	          .select('circle')
	          .style('fill','red')
	
	        // turn on clear sign
	        d3.select(inst_cgm.params.root+' .enr_menu_clear')
	          .transition()
	          .delay(1000)
	          .style('display', 'block');
	
	        // request enrichment results from Enrichr
	        enr_obj.enrichr_rows(d, update_viz_callback, 10);
	
	        make_enr_wait_circle();
	        animate_wait();
	
	        setTimeout(toggle_enrichr_menu, 500);
	      })
	
	  }
	
	  function clear_enrichr_results(run_resize_viz){
	
	    d3.select(inst_cgm.params.root+ ' .enr_menu_clear')
	      .style('display', 'none');
	
	    // unselect library
	    d3.select(inst_cgm.params.root+' .enr_lib_section')
	      .selectAll('g')
	      .select('circle')
	      .style('fill','white');
	
	    // clear categories
	    inst_cgm.reset_cats(run_resize_viz);
	
	    // remove title and bars
	    d3.select(inst_cgm.params.root+' .enr_title').remove();
	    d3.selectAll(inst_cgm.params.root+' .enrichr_bars').remove();
	
	  }
	
	  function toggle_enrichr_menu(){
	
	    var enr_menu = d3.select(inst_cgm.params.root+' .enrichr_menu');
	
	    if (enr_menu.classed('showing') === false){
	
	      // show menu
	      ///////////////////////
	      enr_menu
	        .classed('showing', true)
	        .style('display', 'block');
	
	      d3.select(inst_cgm.params.root+' .enrichr_menu')
	        .style('opacity',0)
	        .transition()
	        .style('opacity',1)
	
	      d3.selectAll('.row_cat_super').style('display','none');
	
	      // hide tooltip
	      d3.selectAll( inst_cgm.params.viz.root_tips + '_enr_tip')
	        .style('opacity', 0)
	        .style('display', 'none');
	
	    } else {
	
	      // hide menu
	      ///////////////////////
	      setTimeout(function(){enr_menu.style('display', 'none');}, 1000)
	
	      d3.select(inst_cgm.params.root+' .enrichr_menu')
	        .classed('showing', false)
	        .style('opacity',1)
	        .transition()
	        .style('opacity',0)
	
	      d3.selectAll('.row_cat_super').style('display','block');
	    }
	
	  }
	
	  function get_enr_with_list(ini_gene_list, library, callback_function){
	
	    // clean gene list
	    var gene_list = []
	    _.each(ini_gene_list, function(gene_symbol){
	      if (gene_symbol.indexOf(' ') > 0){
	        gene_symbol = gene_symbol.split(' ')[0];
	      } else if (gene_symbol.indexOf('_') > 0){
	        gene_symbol = gene_symbol.split('_')[0];
	      }
	      gene_list.push(gene_symbol)
	    })
	
	    enr_obj.library = library;
	    enr_obj.gene_list = gene_list;
	
	    enr_obj.post_list(gene_list, function(){
	
	      if (typeof callback_function != 'undefined'){
	        enr_obj.get_enr(library, callback_function);
	      } else {
	        enr_obj.get_enr(library);
	      }
	
	    });
	  }
	
	  function post_list(gene_list, callback_function){
	
	    var gene_list_string = gene_list.join('\n');
	
	    var form = new FormData();
	    var response;
	
	    form.append("list", gene_list_string);
	
	    form.append("description", "clustergrammer");
	
	    var settings = {
	     "async": true,
	     "crossDomain": true,
	     "url": "https://amp.pharm.mssm.edu/Enrichr/addList",
	     "method": "POST",
	     "processData": false,
	     "contentType": false,
	     "mimeType": "multipart/form-data",
	     "data": form
	    }
	
	    if (typeof callback_function === 'undefined'){
	      callback_function = confirm_save;
	    }
	
	    $.ajax(settings)
	     .done(function(response){
	      response = JSON.parse(response);
	      enr_obj.user_list_id = response.userListId;
	
	      // make get request
	      setTimeout(callback_function, 500, response);
	      // callback_function(response);
	     });
	  }
	
	  function confirm_save(response){
	    console.log('saved user_list_id '+String(enr_obj.user_list_id));
	  }
	
	  function get_enr(library, callback_function){
	
	    if (enr_obj.user_list_id !== null){
	      var form = new FormData();
	
	      var base_url = 'https://amp.pharm.mssm.edu/Enrichr/enrich?';
	      var library_string = 'backgroundType=' + String(library);
	      var list_id_string = 'userListId=' + String(enr_obj.user_list_id);
	
	      var full_url = base_url + library_string + '&' + list_id_string;
	
	      // get request
	      var settings = {
	       "async": true,
	       "crossDomain": true,
	       "url": full_url,
	       "method": "GET",
	       "processData": false,
	       "contentType": false,
	       "mimeType": "multipart/form-data",
	       "data": form
	      }
	
	      $.ajax(settings)
	        .done(function (response, textStatus, jqXHR) {
	
	          response = JSON.parse(response);
	          enr_obj.enr_data = response;
	
	          // parse enr_data to cat_data format
	          /////////////////////////////////////
	          // enr_obj.cat_data = enr_obj.enr_data
	          enr_obj.enr_data_to_cats();
	
	          if (typeof callback_function != 'undefined'){
	            callback_function(enr_obj);
	          }
	          d3.select(inst_cgm.params.root+' .enr_wait_circle').remove();
	
	        })
	        .fail(function( jqXHR, textStatus, errorThrown ){
	
	          enr_obj.get_tries = enr_obj.get_tries + 1;
	
	          if (enr_obj.get_tries < 2){
	            // enr_obj.get_enr(library, callback_function);
	            setTimeout( enr_obj.get_enr, 500, library_string, callback_function )
	          } else {
	            console.log('did not get response from Enrichr - need to remove wait circle')
	            d3.select(inst_cgm.params.root+' .enr_wait_circle').remove();
	          }
	
	        });
	
	    } else {
	      console.log('no user_list_id defined')
	    }
	  }
	
	  function enrichr_rows(library, callback_function, num_terms){
	
	    // set up a variable number of terms
	
	    enr_obj.library = library;
	    var gene_list = inst_cgm.params.network_data.row_nodes_names;
	    enr_obj.get_enr_with_list(gene_list, library, callback_function)
	
	  }
	
	  function enr_data_to_cats(){
	
	    var library_name = _.keys(this.enr_data)[0];
	
	    var enr_terms = this.enr_data[library_name];
	
	    // keep the top 10 enriched terms
	    enr_terms = enr_terms.slice(0,10);
	
	    cat_data = []
	
	    _.each(enr_terms, function(inst_term){
	
	      inst_data = {};
	      inst_data['cat_title'] = inst_term[1];
	      inst_data['cats'] = [];
	      inst_data['pval'] = inst_term[2];
	
	      // keep the combined score
	      inst_data['combined_score'] = inst_term[4]
	
	      cat_details = {};
	      cat_details.cat_name = 'true';
	      cat_details.members = inst_term[5]
	
	      // there are only two categories for Enrichr: true/false
	      inst_data['cats'].push(cat_details)
	
	      cat_data.push(inst_data);
	    });
	
	    this.cat_data = cat_data;
	
	  }
	
	  function animate_wait() {
	
	    var repeat_time = 700;
	    var max_opacity = 0.8;
	    var min_opacity = 0.2
	
	    d3.select(inst_cgm.params.root+' .enr_wait_circle')
	      .transition()
	      .ease('linear')
	      .style('opacity', min_opacity)
	      .transition()
	      .ease('linear')
	      .duration(repeat_time)
	      .style('opacity', max_opacity)
	      .transition()
	      .ease('linear')
	      .duration(repeat_time)
	      .style('opacity', min_opacity)
	      .each("end", animate_wait);
	  }
	
	  function update_viz_callback(enr_obj){
	
	    inst_cgm.update_cats(enr_obj.cat_data);
	
	    d3.select(inst_cgm.params.root+' .enr_title').remove();
	
	    var enr_title = d3.select(inst_cgm.params.root+' .viz_svg')
	      .append('g')
	      .classed('enr_title', true)
	      .attr('transform', function(){
	
	        var trans = d3.select(inst_cgm.params.root+' .row_cat_label_container')
	                      .attr('transform').split('(')[1].split(')')[0];
	        x_offset = Number(trans.split(',')[0]) - 10;
	
	        return 'translate('+ String(x_offset)+', 0)';
	
	      });
	
	    enr_title
	      .append('rect')
	      .attr('width', inst_cgm.params.viz.cat_room.row)
	      .attr('height', 25)
	      .attr('fill', 'white');
	
	    var library_string = enr_obj.library.substring(0,40);
	    enr_title
	      .append('text')
	      .attr('transform', 'translate(0, 17)')
	      .text(library_string.replace(/_/g, ' '))
	      .style('font-size', '15px')
	      .attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif');
	
	    var extra_y_room = 1.25;
	    var unit_length = extra_y_room * inst_cgm.params.viz.cat_room.symbol_width;
	    var bar_width = unit_length * 0.9;
	
	    // Enrichr bars
	    ///////////////////////////////
	
	    d3.selectAll(inst_cgm.params.root+' .enrichr_bars').remove();
	
	    var bar_height = inst_cgm.params.viz.clust.margin.top - 35;
	    var max_score = enr_obj.cat_data[0].combined_score;
	    var bar_scale = d3.scale.linear()
	                      .domain([0, max_score])
	                      .range([0, bar_height]);
	
	    d3.select(inst_cgm.params.root+' .row_cat_label_bar_container')
	      .selectAll()
	      .data(inst_cgm.params.viz.all_cats.row)
	      .enter()
	      .append('rect')
	      .classed('enrichr_bars', true)
	      .style('height', bar_width +'px')
	      .style('fill', 'red')
	      .style('width', function(d){
	
	        var enr_index = d.split('-')[1];
	        var inst_comb_score = enr_obj.cat_data[enr_index].combined_score;
	        var bar_lenth = bar_scale(inst_comb_score);
	        var bar_length_string = bar_lenth + 'px'
	        return bar_length_string;
	      })
	      .style('opacity', 0.4)
	      .attr('transform', function(d){
	        var inst_y = unit_length * (parseInt( d.split('-')[1], 10 ) -0.75 );
	        return 'translate(0,'+inst_y+')';
	      })
	
	  }
	
	  function make_enr_wait_circle(){
	    var pos_x = 72;
	    var pos_y = 25;
	
	     var click_circle = d3.select(inst_cgm.params.root+' .viz_svg')
	        .append('circle')
	        .classed('enr_wait_circle', true)
	        .attr('cx',pos_x)
	        .attr('cy',pos_y)
	        .attr('r',23)
	        .style('stroke','#666666')
	        .style('stroke-width','3px')
	        .style('fill','white')
	        .style('fill-opacity',0)
	        .style('opacity', 0);
	  }
	
	  // example of how to check gene list
	  // http://amp.pharm.mssm.edu/Enrichr/view?userListId=1284420
	
	  var enr_obj = {};
	  enr_obj.user_list_id = null;
	  enr_obj.enr_data = null;
	  enr_obj.cat_data = null;
	  enr_obj.get_tries = 0;
	  enr_obj.library = null;
	  enr_obj.gene_list = null;
	
	  enr_obj.enrichr_icon = enrichr_icon;
	  enr_obj.post_list = post_list;
	  enr_obj.get_enr = get_enr;
	  enr_obj.get_enr_with_list = get_enr_with_list;
	  enr_obj.enrichr_rows = enrichr_rows;
	  enr_obj.enr_data_to_cats = enr_data_to_cats;
	  enr_obj.update_viz_callback = update_viz_callback;
	  enr_obj.clear_enrichr_results = clear_enrichr_results;
	
	  return enr_obj;
	
	}
	
	module.exports = Enrichrgram;

/***/ },
/* 8 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__.p + "f2c72c12e473db657b6f061871c24289.png";

/***/ },
/* 9 */
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag
	
	// load the styles
	var content = __webpack_require__(10);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(12)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!../node_modules/css-loader/index.js!./custom.css", function() {
				var newContent = require("!!../node_modules/css-loader/index.js!./custom.css");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },
/* 10 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(11)();
	// imports
	
	
	// module
	exports.push([module.id, "* {\n  -webkit-box-sizing: border-box;\n}\n\nbody{\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n  line-height: 1.428;\n  color: #333;\n  background-color: #fff;\n}\n\n/*.clust_icon{\n  float:left;\n  width: 33.3333333%;\n  padding-left: 15px;\n  padding-right: 15px;\n}*/\n\n.viz_medium_text{\n  width:99%;\n  margin-left: 5px;\n  margin-top: 3px;\n  margin-bottom: 3px;\n  color:#333;\n  text-align: justify;\n  font-size: 14px;\n  font-weight: 300;\n  padding-left: 0px;\n}\n\n.viz_large_text{\n  width:99%;\n  margin: 0 auto;\n  margin-top: 6px;\n  margin-bottom: 3px;\n  color:#333;\n  text-align: justify;\n  font-size: 16px;\n  font-weight: 300;\n  padding-left: 0px;\n}\n\n/* need to move d3-tip into stypes */\n.d3-tip {\n  line-height: 1.25;\n  font-weight: bold;\n  padding: 12px;\n  background: rgba(0, 0, 0, 0.8);\n  color: #fff;\n  border-radius: 2px;\n  max-width: 500px;\n}\n\n/* Style northward tooltips differently */\n.d3-tip.n:after {\n  margin: -1px 0 0 0;\n  top: 100%;\n  left: 0;\n}\n\n.noselect {\n    -webkit-touch-callout: none;\n    -webkit-user-select: none;\n    -khtml-user-select: none;\n    -moz-user-select: none;\n    -ms-user-select: none;\n    user-select: none;\n}\n\n\n.icon_buttons{\n  color: #337ab7;\n}\n\n.sidebar_text{\n  font-weight: 300;\n  font-size: 12px;\n  line-height: 1.1;\n}\n\n.sidebar_button_text{\n  font-size: 13px;\n  font-weight: 300;\n}\n\n.btn{\n  padding-top:2px;\n  padding-bottom:2px;\n}\n\n.toggle_row_order{\n  position: relative;\n  display: inline-block;\n  vertical-align: middle;\n}\n\n.modal-backdrop{\n  display: none;\n}\n\n.modal-backdrop.fade{\n  display: none;\n}\n\n.modal-backdrop.in{\n  display: none;\n}\n\n/* sidebar tooltips */\n.sidebar_tooltip {\n    position: relative;\n    display: inline-block;\n}\n\n.sidebar_tooltip .sidebar_tooltip_text {\n    visibility: hidden;\n    width: 120px;\n    background: rgba(0, 0, 0, 1);\n    /*opacity: 0.95;*/\n    color: #fff;\n    text-align: center;\n    border-radius: 6px;\n    padding: 5px 0;\n\n    position: absolute;\n    z-index: 1000;\n    top:100%;\n    /*left:-400%;*/\n    font-size: 15px;\n    /*margin-left: 60px;*/\n    font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n    font-size: 13px;\n    font-weight: bold;\n}\n\n.sidebar_tooltip:hover .sidebar_tooltip_text {\n    visibility: visible;\n}", ""]);
	
	// exports


/***/ },
/* 11 */
/***/ function(module, exports) {

	/*
		MIT License http://www.opensource.org/licenses/mit-license.php
		Author Tobias Koppers @sokra
	*/
	// css base code, injected by the css-loader
	module.exports = function() {
		var list = [];
	
		// return the list of modules as css string
		list.toString = function toString() {
			var result = [];
			for(var i = 0; i < this.length; i++) {
				var item = this[i];
				if(item[2]) {
					result.push("@media " + item[2] + "{" + item[1] + "}");
				} else {
					result.push(item[1]);
				}
			}
			return result.join("");
		};
	
		// import a list of modules into the list
		list.i = function(modules, mediaQuery) {
			if(typeof modules === "string")
				modules = [[null, modules, ""]];
			var alreadyImportedModules = {};
			for(var i = 0; i < this.length; i++) {
				var id = this[i][0];
				if(typeof id === "number")
					alreadyImportedModules[id] = true;
			}
			for(i = 0; i < modules.length; i++) {
				var item = modules[i];
				// skip already imported module
				// this implementation is not 100% perfect for weird media query combinations
				//  when a module is imported multiple times with different media queries.
				//  I hope this will never occur (Hey this way we have smaller bundles)
				if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {
					if(mediaQuery && !item[2]) {
						item[2] = mediaQuery;
					} else if(mediaQuery) {
						item[2] = "(" + item[2] + ") and (" + mediaQuery + ")";
					}
					list.push(item);
				}
			}
		};
		return list;
	};


/***/ },
/* 12 */
/***/ function(module, exports, __webpack_require__) {

	/*
		MIT License http://www.opensource.org/licenses/mit-license.php
		Author Tobias Koppers @sokra
	*/
	var stylesInDom = {},
		memoize = function(fn) {
			var memo;
			return function () {
				if (typeof memo === "undefined") memo = fn.apply(this, arguments);
				return memo;
			};
		},
		isOldIE = memoize(function() {
			return /msie [6-9]\b/.test(self.navigator.userAgent.toLowerCase());
		}),
		getHeadElement = memoize(function () {
			return document.head || document.getElementsByTagName("head")[0];
		}),
		singletonElement = null,
		singletonCounter = 0,
		styleElementsInsertedAtTop = [];
	
	module.exports = function(list, options) {
		if(false) {
			if(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
		}
	
		options = options || {};
		// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
		// tags it will allow on a page
		if (typeof options.singleton === "undefined") options.singleton = isOldIE();
	
		// By default, add <style> tags to the bottom of <head>.
		if (typeof options.insertAt === "undefined") options.insertAt = "bottom";
	
		var styles = listToStyles(list);
		addStylesToDom(styles, options);
	
		return function update(newList) {
			var mayRemove = [];
			for(var i = 0; i < styles.length; i++) {
				var item = styles[i];
				var domStyle = stylesInDom[item.id];
				domStyle.refs--;
				mayRemove.push(domStyle);
			}
			if(newList) {
				var newStyles = listToStyles(newList);
				addStylesToDom(newStyles, options);
			}
			for(var i = 0; i < mayRemove.length; i++) {
				var domStyle = mayRemove[i];
				if(domStyle.refs === 0) {
					for(var j = 0; j < domStyle.parts.length; j++)
						domStyle.parts[j]();
					delete stylesInDom[domStyle.id];
				}
			}
		};
	}
	
	function addStylesToDom(styles, options) {
		for(var i = 0; i < styles.length; i++) {
			var item = styles[i];
			var domStyle = stylesInDom[item.id];
			if(domStyle) {
				domStyle.refs++;
				for(var j = 0; j < domStyle.parts.length; j++) {
					domStyle.parts[j](item.parts[j]);
				}
				for(; j < item.parts.length; j++) {
					domStyle.parts.push(addStyle(item.parts[j], options));
				}
			} else {
				var parts = [];
				for(var j = 0; j < item.parts.length; j++) {
					parts.push(addStyle(item.parts[j], options));
				}
				stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
			}
		}
	}
	
	function listToStyles(list) {
		var styles = [];
		var newStyles = {};
		for(var i = 0; i < list.length; i++) {
			var item = list[i];
			var id = item[0];
			var css = item[1];
			var media = item[2];
			var sourceMap = item[3];
			var part = {css: css, media: media, sourceMap: sourceMap};
			if(!newStyles[id])
				styles.push(newStyles[id] = {id: id, parts: [part]});
			else
				newStyles[id].parts.push(part);
		}
		return styles;
	}
	
	function insertStyleElement(options, styleElement) {
		var head = getHeadElement();
		var lastStyleElementInsertedAtTop = styleElementsInsertedAtTop[styleElementsInsertedAtTop.length - 1];
		if (options.insertAt === "top") {
			if(!lastStyleElementInsertedAtTop) {
				head.insertBefore(styleElement, head.firstChild);
			} else if(lastStyleElementInsertedAtTop.nextSibling) {
				head.insertBefore(styleElement, lastStyleElementInsertedAtTop.nextSibling);
			} else {
				head.appendChild(styleElement);
			}
			styleElementsInsertedAtTop.push(styleElement);
		} else if (options.insertAt === "bottom") {
			head.appendChild(styleElement);
		} else {
			throw new Error("Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'.");
		}
	}
	
	function removeStyleElement(styleElement) {
		styleElement.parentNode.removeChild(styleElement);
		var idx = styleElementsInsertedAtTop.indexOf(styleElement);
		if(idx >= 0) {
			styleElementsInsertedAtTop.splice(idx, 1);
		}
	}
	
	function createStyleElement(options) {
		var styleElement = document.createElement("style");
		styleElement.type = "text/css";
		insertStyleElement(options, styleElement);
		return styleElement;
	}
	
	function createLinkElement(options) {
		var linkElement = document.createElement("link");
		linkElement.rel = "stylesheet";
		insertStyleElement(options, linkElement);
		return linkElement;
	}
	
	function addStyle(obj, options) {
		var styleElement, update, remove;
	
		if (options.singleton) {
			var styleIndex = singletonCounter++;
			styleElement = singletonElement || (singletonElement = createStyleElement(options));
			update = applyToSingletonTag.bind(null, styleElement, styleIndex, false);
			remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true);
		} else if(obj.sourceMap &&
			typeof URL === "function" &&
			typeof URL.createObjectURL === "function" &&
			typeof URL.revokeObjectURL === "function" &&
			typeof Blob === "function" &&
			typeof btoa === "function") {
			styleElement = createLinkElement(options);
			update = updateLink.bind(null, styleElement);
			remove = function() {
				removeStyleElement(styleElement);
				if(styleElement.href)
					URL.revokeObjectURL(styleElement.href);
			};
		} else {
			styleElement = createStyleElement(options);
			update = applyToTag.bind(null, styleElement);
			remove = function() {
				removeStyleElement(styleElement);
			};
		}
	
		update(obj);
	
		return function updateStyle(newObj) {
			if(newObj) {
				if(newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap)
					return;
				update(obj = newObj);
			} else {
				remove();
			}
		};
	}
	
	var replaceText = (function () {
		var textStore = [];
	
		return function (index, replacement) {
			textStore[index] = replacement;
			return textStore.filter(Boolean).join('\n');
		};
	})();
	
	function applyToSingletonTag(styleElement, index, remove, obj) {
		var css = remove ? "" : obj.css;
	
		if (styleElement.styleSheet) {
			styleElement.styleSheet.cssText = replaceText(index, css);
		} else {
			var cssNode = document.createTextNode(css);
			var childNodes = styleElement.childNodes;
			if (childNodes[index]) styleElement.removeChild(childNodes[index]);
			if (childNodes.length) {
				styleElement.insertBefore(cssNode, childNodes[index]);
			} else {
				styleElement.appendChild(cssNode);
			}
		}
	}
	
	function applyToTag(styleElement, obj) {
		var css = obj.css;
		var media = obj.media;
	
		if(media) {
			styleElement.setAttribute("media", media)
		}
	
		if(styleElement.styleSheet) {
			styleElement.styleSheet.cssText = css;
		} else {
			while(styleElement.firstChild) {
				styleElement.removeChild(styleElement.firstChild);
			}
			styleElement.appendChild(document.createTextNode(css));
		}
	}
	
	function updateLink(linkElement, obj) {
		var css = obj.css;
		var sourceMap = obj.sourceMap;
	
		if(sourceMap) {
			// http://stackoverflow.com/a/26603875
			css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */";
		}
	
		var blob = new Blob([css], { type: "text/css" });
	
		var oldSrc = linkElement.href;
	
		linkElement.href = URL.createObjectURL(blob);
	
		if(oldSrc)
			URL.revokeObjectURL(oldSrc);
	}


/***/ },
/* 13 */
/***/ function(module, exports) {

	module.exports = {
		"name": "clustergrammer_widget",
		"version": "1.10.0",
		"description": "clustergrammer_widget",
		"author": "Nicolas Fernandez",
		"license": "MIT",
		"main": "src/index.js",
		"repository": {
			"type": "git",
			"url": "https://github.com/maayanlab/clustergrammer_widget.git"
		},
		"keywords": [
			"jupyter",
			"widgets",
			"ipython",
			"ipywidgets"
		],
		"scripts": {
			"prepublish": "webpack",
			"test": "echo \"Error: no test specified\" && exit 1"
		},
		"devDependencies": {
			"css-loader": "^0.25.0",
			"file-loader": "^0.10.0",
			"json-loader": "^0.5.4",
			"webpack": "^1.12.14"
		},
		"dependencies": {
			"clustergrammer": "v1.16.0",
			"d3": "^3.5.8",
			"jupyter-js-widgets": "^1.1.1",
			"underscore": "^1.8.3"
		}
	};

/***/ }
/******/ ])});;
//# sourceMappingURL=index.js.map