<commit_before>const { Transaction, script, address } = require('bitcoinjs-lib')
const request = require('request')
const secp256k1 = require('secp256k1')
const { sha2, ripemd160 } = require('./hash.js')
const { byte, concat } = require('./util.js')

const DEV = process.env.NODE_ENV === 'development'
const EXODUS_ADDRESS = '1EaV33reN8XWWUfs5jkbGMD399vie5KQc4'
const MINIMUM_AMOUNT = DEV ? 60000 : 1000000 // min satoshis to send to exodus
const ATOMS_PER_BTC = 2000
const MINIMUM_OUTPUT = 1000

function getAddress (pub) {
  let pubkeyHash = ripemd160(sha2(pub))

  // NOTE: isn't this just an expensive way to base58check encode?
  let outputScript = script.pubKeyHashOutput(pubkeyHash)
  return address.fromOutputScript(outputScript)
}

function bciRequest (method, url, data, cb) {
  return request({
    method,
    url: `https://blockchain.info/${url}`,
    qs: { cors: true },
    form: data
  }, (err, res, body) => {
    if (err) return cb(err)
    if (res.statusCode !== 200) {
      return cb(Error(body || res.statusCode), body)
    }
    try {
      body = JSON.parse(body)
    } catch (err) {}
    cb(null, body)
  })
}

// fetch all utxos for this address
function fetchUtxos (address, cb) {
  bciRequest('GET', `unspent?active=${address}`, null, (err, res) => {
    // when there are no outputs for this address,
    // blockchain API gives error 500 with this message:
    if (err && res === 'No free outputs to spend') {
      return cb(null, { utxos: [], amount: 0 })
    }
    if (err) return cb(err)
    let amount = 0
    for (let utxo of res.unspent_outputs) {
      amount += utxo.value
    }
    cb(null, { utxos: res.unspent_outputs, amount })
  })
}

function waitForPayment (address, cb) {
  const done = (err, res) => {
    clearInterval(interval)
    cb(err, res)
  }
  const checkForUnspent = () => {
    fetchUtxos(address, (err, res) => {
      if (err) return done(err)
      if (res.amount < MINIMUM_AMOUNT) return
      done(null, res)
    })
  }
  // poll once every 6 seconds
  let interval = setInterval(checkForUnspent, 6000)
  checkForUnspent()
  return interval
}

function pushTx (txHex, cb) {
  bciRequest('POST', 'pushtx', { tx: txHex }, cb)
}

function createFinalTx (wallet, inputs, feeRate) {
  let inputAmount = 0
  for (let input of inputs) inputAmount += input.value
  inputs = {
    utxos: inputs,
    amount: inputAmount
  }

  if (inputs.amount < MINIMUM_AMOUNT) {
    throw Error(`Intermediate tx is smaller than minimum.
      minimum=${MINIMUM_AMOUNT}
      actual=${inputs.amount}`)
  }
  if (!feeRate || feeRate < 0) {
    throw Error(`Must specify a transaction fee rate`)
  }

  let tx = new Transaction()

  // add inputs from intermediate tx
  for (let output of inputs.utxos) {
    let txid = Buffer(output.tx_hash, 'hex')
    tx.addInput(txid, output.tx_output_n)
  }

  // pay to exodus address, spendable by Cosmos developers
  let payToExodus = address.toOutputScript(EXODUS_ADDRESS)
  tx.addOutput(payToExodus, inputs.amount)

  // output to specify user's Cosmos address
  let cosmosAddress = Buffer(wallet.addresses.cosmos, 'hex')
  let specifyCosmosAddress = script.pubKeyHashOutput(cosmosAddress)
  tx.addOutput(specifyCosmosAddress, MINIMUM_OUTPUT)

  // deduct fee from exodus output
  let feeAmount = tx.byteLength() * feeRate
  if ((tx.outs[0].value - feeAmount) < MINIMUM_OUTPUT) {
    throw Error(`Not enough coins given to pay fee.
      tx length=${tx.byteLength()}
      fee rate=${feeRate} satoshi/byte
      fee amount=${feeAmount} satoshis
      output amount=${tx.outs[0].value} satoshis`)
  }
  tx.outs[0].value -= feeAmount

  // sign inputs
  let privKey = wallet.privateKeys.bitcoin
  let pubKey = wallet.publicKeys.bitcoin
  let sigHashType = Transaction.SIGHASH_ALL
  for (let i = 0; i < tx.ins.length; i++) {
    let input = tx.ins[i] // tx input
    let prevOut = inputs.utxos[i] // utxo associated w/ this input
    let scriptPubKey = Buffer(prevOut.script, 'hex') // utxo's script
    let sigHash = tx.hashForSignature(i, scriptPubKey, sigHashType)
    let signature = sign(privKey, sigHash)
    signature = concat(signature, byte(sigHashType)) // append sighash type byte
    input.script = script.pubKeyHashInput(signature, pubKey)
  }

  let paidAmount = inputs.amount
  let atomAmount = (tx.outs[0].value * ATOMS_PER_BTC) / 1e8
  return { tx, paidAmount, feeAmount, atomAmount }
}

function sign (privKey, sigHash) {
  let { signature } = secp256k1.sign(sigHash, privKey)
  signature = secp256k1.signatureNormalize(signature) // enforce low-S
  return secp256k1.signatureExport(signature) // convert to DER encoding
}

function fetchFundraiserStats (cb) {
  bciRequest('GET', `multiaddr?active=${EXODUS_ADDRESS}`, null, (err, res) => {
    if (err) return cb(err)
    let recentTxs = res.txs
      .filter((tx) => tx.result > 0) // only show received txs
      .map((tx) => ({
        hash: tx.hash,
        donated: tx.result,
        claimed: tx.result * ATOMS_PER_BTC / 1e8,
        time: tx.time
      }))
    cb(null, {
      amountDonated: res.addresses[0].total_received,
      amountClaimed: res.addresses[0].total_received * ATOMS_PER_BTC / 1e8,
      txCount: res.addresses[0].n_tx,
      recentTxs
    })
  })
}

function fetchFeeRate (cb) {
  request({
    url: 'https://bitcoinfees.21.co/api/v1/fees/recommended',
    json: true
  }, (err, res, body) => {
    if (err || res.statusCode !== 200) {
      return cb(err || Error(res.statusCode), body)
    }
    if (body.halfHourFee > 500) {
      return cb(Error('Very high fee rate, aborting'))
    }
    cb(null, body.halfHourFee)
  })
}

module.exports = {
  getAddress,
  fetchUtxos,
  pushTx,
  waitForPayment,
  createFinalTx,
  fetchFundraiserStats,
  fetchFeeRate,
  MINIMUM_AMOUNT,
  ATOMS_PER_BTC
}
<commit_msg>cleanup Bitcoin.getAddress<commit_after>const bs58check = require('bs58check')
const { Transaction, script, address } = require('bitcoinjs-lib')
const request = require('request')
const secp256k1 = require('secp256k1')
const { sha2, ripemd160 } = require('./hash.js')
const { byte, concat } = require('./util.js')

const DEV = process.env.NODE_ENV === 'development'
const EXODUS_ADDRESS = '1EaV33reN8XWWUfs5jkbGMD399vie5KQc4'
const MINIMUM_AMOUNT = DEV ? 60000 : 1000000 // min satoshis to send to exodus
const ATOMS_PER_BTC = 2000
const MINIMUM_OUTPUT = 1000

function getAddress (pub) {
  let pubkeyHash = ripemd160(sha2(pub))
  let payload = concat(byte(0x00), pubkeyHash)
  return bs58check.encode(payload)
}

function bciRequest (method, url, data, cb) {
  return request({
    method,
    url: `https://blockchain.info/${url}`,
    qs: { cors: true },
    form: data
  }, (err, res, body) => {
    if (err) return cb(err)
    if (res.statusCode !== 200) {
      return cb(Error(body || res.statusCode), body)
    }
    try {
      body = JSON.parse(body)
    } catch (err) {}
    cb(null, body)
  })
}

// fetch all utxos for this address
function fetchUtxos (address, cb) {
  bciRequest('GET', `unspent?active=${address}`, null, (err, res) => {
    // when there are no outputs for this address,
    // blockchain API gives error 500 with this message:
    if (err && res === 'No free outputs to spend') {
      return cb(null, { utxos: [], amount: 0 })
    }
    if (err) return cb(err)
    let amount = 0
    for (let utxo of res.unspent_outputs) {
      amount += utxo.value
    }
    cb(null, { utxos: res.unspent_outputs, amount })
  })
}

function waitForPayment (address, cb) {
  const done = (err, res) => {
    clearInterval(interval)
    cb(err, res)
  }
  const checkForUnspent = () => {
    fetchUtxos(address, (err, res) => {
      if (err) return done(err)
      if (res.amount < MINIMUM_AMOUNT) return
      done(null, res)
    })
  }
  // poll once every 6 seconds
  let interval = setInterval(checkForUnspent, 6000)
  checkForUnspent()
  return interval
}

function pushTx (txHex, cb) {
  bciRequest('POST', 'pushtx', { tx: txHex }, cb)
}

function createFinalTx (wallet, inputs, feeRate) {
  let inputAmount = 0
  for (let input of inputs) inputAmount += input.value
  inputs = {
    utxos: inputs,
    amount: inputAmount
  }

  if (inputs.amount < MINIMUM_AMOUNT) {
    throw Error(`Intermediate tx is smaller than minimum.
      minimum=${MINIMUM_AMOUNT}
      actual=${inputs.amount}`)
  }
  if (!feeRate || feeRate < 0) {
    throw Error(`Must specify a transaction fee rate`)
  }

  let tx = new Transaction()

  // add inputs from intermediate tx
  for (let output of inputs.utxos) {
    let txid = Buffer(output.tx_hash, 'hex')
    tx.addInput(txid, output.tx_output_n)
  }

  // pay to exodus address, spendable by Cosmos developers
  let payToExodus = address.toOutputScript(EXODUS_ADDRESS)
  tx.addOutput(payToExodus, inputs.amount)

  // output to specify user's Cosmos address
  let cosmosAddress = Buffer(wallet.addresses.cosmos, 'hex')
  let specifyCosmosAddress = script.pubKeyHashOutput(cosmosAddress)
  tx.addOutput(specifyCosmosAddress, MINIMUM_OUTPUT)

  // deduct fee from exodus output
  let feeAmount = tx.byteLength() * feeRate
  if ((tx.outs[0].value - feeAmount) < MINIMUM_OUTPUT) {
    throw Error(`Not enough coins given to pay fee.
      tx length=${tx.byteLength()}
      fee rate=${feeRate} satoshi/byte
      fee amount=${feeAmount} satoshis
      output amount=${tx.outs[0].value} satoshis`)
  }
  tx.outs[0].value -= feeAmount

  // sign inputs
  let privKey = wallet.privateKeys.bitcoin
  let pubKey = wallet.publicKeys.bitcoin
  let sigHashType = Transaction.SIGHASH_ALL
  for (let i = 0; i < tx.ins.length; i++) {
    let input = tx.ins[i] // tx input
    let prevOut = inputs.utxos[i] // utxo associated w/ this input
    let scriptPubKey = Buffer(prevOut.script, 'hex') // utxo's script
    let sigHash = tx.hashForSignature(i, scriptPubKey, sigHashType)
    let signature = sign(privKey, sigHash)
    signature = concat(signature, byte(sigHashType)) // append sighash type byte
    input.script = script.pubKeyHashInput(signature, pubKey)
  }

  let paidAmount = inputs.amount
  let atomAmount = (tx.outs[0].value * ATOMS_PER_BTC) / 1e8
  return { tx, paidAmount, feeAmount, atomAmount }
}

function sign (privKey, sigHash) {
  let { signature } = secp256k1.sign(sigHash, privKey)
  signature = secp256k1.signatureNormalize(signature) // enforce low-S
  return secp256k1.signatureExport(signature) // convert to DER encoding
}

function fetchFundraiserStats (cb) {
  bciRequest('GET', `multiaddr?active=${EXODUS_ADDRESS}`, null, (err, res) => {
    if (err) return cb(err)
    let recentTxs = res.txs
      .filter((tx) => tx.result > 0) // only show received txs
      .map((tx) => ({
        hash: tx.hash,
        donated: tx.result,
        claimed: tx.result * ATOMS_PER_BTC / 1e8,
        time: tx.time
      }))
    cb(null, {
      amountDonated: res.addresses[0].total_received,
      amountClaimed: res.addresses[0].total_received * ATOMS_PER_BTC / 1e8,
      txCount: res.addresses[0].n_tx,
      recentTxs
    })
  })
}

function fetchFeeRate (cb) {
  request({
    url: 'https://bitcoinfees.21.co/api/v1/fees/recommended',
    json: true
  }, (err, res, body) => {
    if (err || res.statusCode !== 200) {
      return cb(err || Error(res.statusCode), body)
    }
    if (body.halfHourFee > 500) {
      return cb(Error('Very high fee rate, aborting'))
    }
    cb(null, body.halfHourFee)
  })
}

module.exports = {
  getAddress,
  fetchUtxos,
  pushTx,
  waitForPayment,
  createFinalTx,
  fetchFundraiserStats,
  fetchFeeRate,
  MINIMUM_AMOUNT,
  ATOMS_PER_BTC
}
<|endoftext|>


<commit_before>(function(global, _) {

  var Miso = global.Miso || {};

  /**
  * This is a generic collection of dataset-building utilities
  * that are used by Miso.Dataset and Miso.DataView.
  */
  Miso.Builder = {

    /**
    * Detects the type of a column based on some input data.
    * Parameters:
    *   column - the Miso.Column object
    *   data - an array of data to be scanned for type detection
    * Returns:
    *   input column but typed.
    */
    detectColumnType : function(column, data) {

      // compute the type by assembling a sample of computed types
      // and then squashing it to create a unique subset.
      var type = _.inject(data.slice(0, 5), function(memo, value) {

        var t = Miso.typeOf(value);

        if (value !== "" && memo.indexOf(t) === -1 && !_.isNull(value)) {
          memo.push(t);
        }
        return memo;
      }, []);

      // if we only have one type in our sample, save it as the type
      if (type.length === 1) {
        column.type = type[0];
      } else {
        //empty column or mixed type
        column.type = 'mixed';
      }

      return column;
    },

    /**
    * Detects the types of all columns in a dataset.
    * Parameters:
    *   dataset - the dataset to test the columns of
    *   parsedData - the data to check the type of
    */
    detectColumnTypes : function(dataset, parsedData) {

      _.each(parsedData, function(data, columnName) {

        var column = dataset.column( columnName );

        // check if the column already has a type defined
        if ( column.type ) {
          column.force = true;
          return;
        } else {
          Miso.Builder.detectColumnType(column, data);
        }

      }, this);
    },

    /**
    * Used by internal importers to cache the rows
    * in quick lookup tables for any id based operations.
    * also used by views to cache the new rows they get
    * as a result of whatever filter created them.
    */
    cacheRows : function(dataset) {

      Miso.Builder.clearRowCache(dataset);

      // cache the row id positions in both directions.
      // iterate over the _id column and grab the row ids
      _.each(dataset._columns[dataset._columnPositionByName._id].data, function(id, index) {
        dataset._rowPositionById[id] = index;
        dataset._rowIdByPosition.push(id);
      }, dataset);

      // cache the total number of rows. There should be same
      // number in each column's data
      var rowLengths = _.uniq( _.map(dataset._columns, function(column) {
        return column.data.length;
      }));

      if (rowLengths.length > 1) {
        throw new Error("Row lengths need to be the same. Empty values should be set to null." +
          _.map(dataset._columns, function(c) { return c.data + "|||" ; }));
      } else {
        dataset.length = rowLengths[0];
      }
    },

    /**
    * Clears the row cache objects of a dataset
    * Parameters:
    *   dataset - Miso.Dataset instance.
    */
    clearRowCache : function(dataset) {
      dataset._rowPositionById = {};
      dataset._rowIdByPosition = [];
    },

    /**
    * Caches the column positions by name
    * Parameters:
    *   dataset - Miso.Dataset instance.
    */
    cacheColumns : function(dataset) {
      dataset._columnPositionByName = {};
      _.each(dataset._columns, function(column, i) {
        dataset._columnPositionByName[column.name] = i;
      });
    }
  };
}(this, _));<commit_msg>Fixing Array.indexOf missing in IE.<commit_after>(function(global, _) {

  var Miso = global.Miso || {};

  /**
  * This is a generic collection of dataset-building utilities
  * that are used by Miso.Dataset and Miso.DataView.
  */
  Miso.Builder = {

    /**
    * Detects the type of a column based on some input data.
    * Parameters:
    *   column - the Miso.Column object
    *   data - an array of data to be scanned for type detection
    * Returns:
    *   input column but typed.
    */
    detectColumnType : function(column, data) {

      // compute the type by assembling a sample of computed types
      // and then squashing it to create a unique subset.
      var type = _.inject(data.slice(0, 5), function(memo, value) {

        var t = Miso.typeOf(value);

        if (value !== "" && memo.indexOf(t) === -1 && !_.isNull(value)) {
          memo.push(t);
        }
        return memo;
      }, []);

      // if we only have one type in our sample, save it as the type
      if (type.length === 1) {
        column.type = type[0];
      } else {
        //empty column or mixed type
        column.type = 'mixed';
      }

      return column;
    },

    /**
    * Detects the types of all columns in a dataset.
    * Parameters:
    *   dataset - the dataset to test the columns of
    *   parsedData - the data to check the type of
    */
    detectColumnTypes : function(dataset, parsedData) {

      _.each(parsedData, function(data, columnName) {

        var column = dataset.column( columnName );

        // check if the column already has a type defined
        if ( column.type ) {
          column.force = true;
          return;
        } else {
          Miso.Builder.detectColumnType(column, data);
        }

      }, this);
    },

    /**
    * Used by internal importers to cache the rows
    * in quick lookup tables for any id based operations.
    * also used by views to cache the new rows they get
    * as a result of whatever filter created them.
    */
    cacheRows : function(dataset) {

      Miso.Builder.clearRowCache(dataset);

      // cache the row id positions in both directions.
      // iterate over the _id column and grab the row ids
      _.each(dataset._columns[dataset._columnPositionByName._id].data, function(id, index) {
        dataset._rowPositionById[id] = index;
        dataset._rowIdByPosition.push(id);
      }, dataset);

      // cache the total number of rows. There should be same
      // number in each column's data
      var rowLengths = _.uniq( _.map(dataset._columns, function(column) {
        return column.data.length;
      }));

      if (rowLengths.length > 1) {
        throw new Error("Row lengths need to be the same. Empty values should be set to null." +
          _.map(dataset._columns, function(c) { return c.data + "|||" ; }));
      } else {
        dataset.length = rowLengths[0];
      }
    },

    /**
    * Clears the row cache objects of a dataset
    * Parameters:
    *   dataset - Miso.Dataset instance.
    */
    clearRowCache : function(dataset) {
      dataset._rowPositionById = {};
      dataset._rowIdByPosition = [];
    },

    /**
    * Caches the column positions by name
    * Parameters:
    *   dataset - Miso.Dataset instance.
    */
    cacheColumns : function(dataset) {
      dataset._columnPositionByName = {};
      _.each(dataset._columns, function(column, i) {
        dataset._columnPositionByName[column.name] = i;
      });
    }
  };

  // fix lack of IE indexOf. Again.
  if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(obj, start) {
     for (var i = (start || 0), j = this.length; i < j; i++) {
         if (this[i] === obj) { return i; }
     }
     return -1;
    }
  }

}(this, _));<|endoftext|>


<commit_before>const treeBuilder = {

  create(root, siblings, opts) {

      var kx = function(d) {
        return d.x - 20;
      };
      var ky = function(d) {
        return d.y - 10;
      };
      //this place the text x axis adjust this to center align the text
      var tx = function(d) {
        return d.x + opts.textOffset.x;
      };
      //this place the text y axis adjust this to center align the text
      var ty = function(d) {
        return d.y + opts.textOffset.y;
      };

      //make an SVG
      var svg = d3.select(opts.target)
        .append('svg')
        .attr('width', opts.width + opts.margin.left + opts.margin.right)
        .attr('height', opts.height + opts.margin.top + opts.margin.bottom)
        .append('g')
        .attr('transform', 'translate(' + opts.margin.left + ',' + opts.margin.top + ')');

      //This maps the siblings together mapping uses the ID using the blue line

      // Compute the layout.
      var tree = d3.layout.tree()
        .size([opts.width, opts.height]);
      var nodes = tree.nodes(root);
      var links = tree.links(nodes);

      // Create the link lines.
      svg.selectAll('.link')
        .data(links)
        .enter()
        .append('path')
        .attr('class', opts.styles.linage)
        .attr('d', this._elbow);

      var nodes = svg.selectAll('.node')
        .data(nodes)
        .enter();

      var allNodes = this._flatten(root);
      this._linkSiblings(allNodes, siblings);

      //First draw sibling line with blue line
      svg.selectAll('.sibling')
        .data(siblings)
        .enter()
        .append('path')
        .attr('class', 'sibling')
        .attr('d', this._siblingLine);

      // Create the node rectangles.
      nodes.append('rect')
        .attr('class', 'node')
        .attr('height', 20)
        .attr('width', 40)
        .attr('id', function(d) {
          return d.id;
        })
        .attr('display', function(d) {
          if (d.hidden) {
            return 'none';
          } else {
            return '';
          };
        })
        .attr('x', kx)
        .attr('y', ky);

      // Create the node text label.
      nodes.append('text')
        .text(function(d) {
          return d.name;
        })
        .attr('x', tx)
        .attr('y', ty);
    },

    _flatten: function(root) {
      var n = [];
      var i = 0;

      function recurse(node) {
        if (node.children) {
          node.children.forEach(recurse);
        }
        if (!node.id) {
          node.id = ++i;
        }
        n.push(node);
      }
      recurse(root);
      return n;
    },

    _elbow: function(d, i) {
      if (d.target.noParent) {
        return 'M0,0L0,0';
      }
      var ny = d.target.y + (d.source.y - d.target.y) * 0.50;

      var linedata = [{
        x: d.target.x,
        y: d.target.y
      }, {
        x: d.target.x,
        y: ny
      }, {
        x: d.source.x,
        y: d.source.y
      }];

      var fun = d3.svg.line()
        .x(function(d) {
          return d.x;
        })
        .y(function(d) {
          return d.y;
        })
        .interpolate('step-after');
      return fun(linedata);
    },

    _linkSiblings: function(allNodes, siblings) {

      _.forEach(siblings, function(d) {
        var start = allNodes.filter(function(v) {
          return d.source.id == v.id;
        });
        var end = allNodes.filter(function(v) {
          return d.target.id == v.id;
        });
        d.source.x = start[0].x;
        d.source.y = start[0].y;
        d.target.x = end[0].x;
        d.target.y = end[0].y;
      });

    },

    _siblingLine: function(d, i) {

      var ny = d.target.y + (d.source.y - d.target.y) * 0.50;

      var linedata = [{
        x: d.source.x,
        y: d.source.y
      }, {
        x: d.target.x,
        y: ny
      }, {
        x: d.target.x,
        y: d.target.y
      }];

      var fun = d3.svg.line()
        .x(function(d) {
          return d.x;
        })
        .y(function(d) {
          return d.y;
        })
        .interpolate('step-after');
      return fun(linedata);
    }

};

export default treeBuilder;
<commit_msg>feat: Use class in data<commit_after>const treeBuilder = {

  create(root, siblings, opts) {

      var kx = function(d) {
        return d.x - 20;
      };
      var ky = function(d) {
        return d.y - 10;
      };
      //this place the text x axis adjust this to center align the text
      var tx = function(d) {
        return d.x + opts.textOffset.x;
      };
      //this place the text y axis adjust this to center align the text
      var ty = function(d) {
        return d.y + opts.textOffset.y;
      };

      //make an SVG
      var svg = d3.select(opts.target)
        .append('svg')
        .attr('width', opts.width + opts.margin.left + opts.margin.right)
        .attr('height', opts.height + opts.margin.top + opts.margin.bottom)
        .append('g')
        .attr('transform', 'translate(' + opts.margin.left + ',' + opts.margin.top + ')');

      // Compute the layout.
      var tree = d3.layout.tree()
        .size([opts.width, opts.height]);
      var nodes = tree.nodes(root);

      // Since root node is hidden, readjust height.
      var root_offset = nodes[1].y;
      _.forEach(nodes, function(n) {
        n.y = n.y - root_offset / 2;
      });

      var links = tree.links(nodes);

      // Create the link lines.
      svg.selectAll('.link')
        .data(links)
        .enter()
        .append('path')
        .attr('class', opts.styles.linage)
        .attr('d', this._elbow);

      var nodes = svg.selectAll('.node')
        .data(nodes)
        .enter();

      var allNodes = this._flatten(root);
      this._linkSiblings(allNodes, siblings);

      //First draw sibling line with blue line
      svg.selectAll('.sibling')
        .data(siblings)
        .enter()
        .append('path')
        .attr('class', opts.styles.marriage)
        .attr('d', this._siblingLine);

      // Create the node rectangles.
      nodes.append('rect')
        .attr('class', function(d) {
          if (d.class) {
            return d.class;
          } else {
            return opts.styles.node;
          }
        })
        .attr('height', 20)
        .attr('width', 40)
        .attr('id', function(d) {
          return d.id;
        })
        .attr('display', function(d) {
          if (d.hidden) {
            return 'none';
          } else {
            return '';
          };
        })
        .attr('x', kx)
        .attr('y', ky);

      // Create the node text label.
      nodes.append('text')
        .text(function(d) {
          return d.name;
        })
        .attr('x', tx)
        .attr('y', ty);
    },

    _flatten: function(root) {
      var n = [];
      var i = 0;

      function recurse(node) {
        if (node.children) {
          node.children.forEach(recurse);
        }
        if (!node.id) {
          node.id = ++i;
        }
        n.push(node);
      }
      recurse(root);
      return n;
    },

    _elbow: function(d, i) {
      if (d.target.noParent) {
        return 'M0,0L0,0';
      }
      var ny = d.target.y + (d.source.y - d.target.y) * 0.50;

      var linedata = [{
        x: d.target.x,
        y: d.target.y
      }, {
        x: d.target.x,
        y: ny
      }, {
        x: d.source.x,
        y: d.source.y
      }];

      var fun = d3.svg.line()
        .x(function(d) {
          return d.x;
        })
        .y(function(d) {
          return d.y;
        })
        .interpolate('step-after');
      return fun(linedata);
    },

    _linkSiblings: function(allNodes, siblings) {

      _.forEach(siblings, function(d) {
        var start = allNodes.filter(function(v) {
          return d.source.id == v.id;
        });
        var end = allNodes.filter(function(v) {
          return d.target.id == v.id;
        });
        d.source.x = start[0].x;
        d.source.y = start[0].y;
        d.target.x = end[0].x;
        d.target.y = end[0].y;
      });

    },

    _siblingLine: function(d, i) {

      var ny = d.target.y + (d.source.y - d.target.y) * 0.50;

      var linedata = [{
        x: d.source.x,
        y: d.source.y
      }, {
        x: d.target.x,
        y: ny
      }, {
        x: d.target.x,
        y: d.target.y
      }];

      var fun = d3.svg.line()
        .x(function(d) {
          return d.x;
        })
        .y(function(d) {
          return d.y;
        })
        .interpolate('step-after');
      return fun(linedata);
    }

};

export default treeBuilder;
<|endoftext|>


<commit_before>import * as PhaserObjects from './phaserObjects';

/** Sprite with text added as a child.
 * @extends Phaser.Group
 */
export class TextSprite extends PhaserObjects.Group {
    /**
     * @param {Object} game - Current game instance.
     * @param {string} key - The image to create a sprite with.
     * @param {number} x - The x coordinate on screen where the textSprite will be placed.
     * @param {number} y - The y coordinate on screen where the textSprite will be placed.
     */
    constructor(game, x, y, key) {
        super(game);

        this.game = game;
        game.add.existing(this);

        this.sprite = new PhaserObjects.Sprite(game, x, y, key);
        this.add(this.sprite);

        this.width = this.sprite.width;
        this.height = this.sprite.height;
    }

    /**
     * @param {string} label - The text to place on top of the sprite.
     * @param {Object} style - The style properties to be set on the Text.
     */
    setText(label, style) {
        if (this.text) {
            this.text.destroy();
        }

        if (this.version === 3) {
            this.text = this.game.add.text(0, 0, label, style);
            this.text.setOrigin(0.5, 0.5);
        } else {
            this.text = this.game.add.text(this.width / 2, this.height / 2, label, style);
            this.text.anchor.set(0.5, 0.5);
        }

        this.add(this.text);

        return this;
    }

    setOrigin(x, y) {
        this.sprite.setOrigin(x, y);
        this.text.x = this.sprite.width / 2;
        this.text.y = this.sprite.height / 2;

        return this;
    }
}

/** Phaser Group containing a button with text anchored in the button's center.
 * @extends Phaser.Group
 */
export class TextButton extends PhaserObjects.Group {
    /**
     * @param {Object} game - Current game instance.
     * @param {string} image - The image to create a sprite with.
     * @param {number} x - The x coordinate on screen where the textSprite will be placed.
     * @param {number} y - The y coordinate on screen where the textSprite will be placed.
     * @param {Object} callback - Callback to use when the button is clicked.
     * @param {Object} callbackContext - The context the callback is called in.
     * @param {number} overKey -
     * @param {number} outKey -
     * @param {number} downKey -
     * @param {number} upKey -
     */
    constructor(game, x, y, key, callback, callbackContext, overKey, outKey, downKey, upKey) {
        super(game);

        this.game = game;
        game.add.existing(this);

        this.button = new PhaserObjects.Button(
            game,
            x,
            y,
            key,
            callback,
            callbackContext,
            overKey,
            outKey,
            downKey,
            upKey,
        );
        this.add(this.button);

        this.width = this.button.width;
        this.height = this.button.height;
    }

    /**
     * @param {string} label - The text to place on top of the sprite.
     * @param {Object} style - The style properties to be set on the Text.
     */
    setText(label, style) {
        if (this.text) {
            this.text.destroy();
        }

        if (this.version === 3) {
            this.text = this.game.add.text(0, 0, label, style);
            this.text.setOrigin(0.5, 0.5);
        } else {
            this.text = this.game.add.text(this.width / 2, this.height / 2, label, style);
            this.text.anchor.set(0.5, 0.5);
        }

        this.add(this.text);

        return this;
    }

    setOrigin(x, y) {
        this.button.setOrigin(x, y);
        this.text.x = this.button.width / 2;
        this.text.y = this.button.height / 2;

        return this;
    }

    /** Adds an adjustment to the text on down/up events. */
    eventTextYAdjustment(number) {
        let upAdjustment;

        const sign = Math.sign(number);

        if (sign === 1) {
            upAdjustment = -Math.abs(number);
        } else if (sign === -1) {
            upAdjustment = Math.abs(number);
        }

        this.button.addDownEvent(() => { this.text.y += number; });
        this.button.addUpEvent(() => { this.text.y += upAdjustment; });

        return this;
    }
}
<commit_msg>Simplify TextSprite and TextButton. Handle case where Out event occurs without Up event<commit_after>import * as PhaserObjects from './phaserObjects';

/** Group with some added functionality for text overlays.
 * @extends Phaser.Group
 */
class TextGroup extends PhaserObjects.Group {
    /**
     * @param {string} label - The text to place on top of the sprite.
     * @param {Object} style - The style properties to be set on the Text.
     */
    setText(label, style) {
        if (this.text) {
            this.text.destroy();
        }

        if (this.version === 3) {
            this.text = this.game.add.text(0, 0, label, style);
            this.text.setOrigin(0.5, 0.5);
        } else {
            this.text = this.game.add.text(this.width / 2, this.height / 2, label, style);
            this.text.anchor.set(0.5, 0.5);
        }

        this.add(this.text);

        return this;
    }

    /** When setOrigin is called, align the text as well. */
    setOrigin(x, y) {
        this.sprite.setOrigin(x, y);
        this.text.x = this.sprite.width / 2;
        this.text.y = this.sprite.height / 2;

        return this;
    }
}

/** Sprite with text added as a child.
 * @extends Phaser.Group
 */
export class TextSprite extends TextGroup {
    /**
     * @param {Object} game - Current game instance.
     * @param {string} key - The image to create a sprite with.
     * @param {number} x - The x coordinate on screen where the textSprite will be placed.
     * @param {number} y - The y coordinate on screen where the textSprite will be placed.
     */
    constructor(game, x, y, key) {
        super(game);

        this.game = game;
        game.add.existing(this);

        this.sprite = new PhaserObjects.Sprite(game, x, y, key);
        this.add(this.sprite);

        this.width = this.sprite.width;
        this.height = this.sprite.height;
    }
}

/** Phaser Group containing a button with text anchored in the button's center.
 * @extends Phaser.Group
 */
export class TextButton extends TextGroup {
    /**
     * @param {Object} game - Current game instance.
     * @param {string} image - The image to create a sprite with.
     * @param {number} x - The x coordinate on screen where the textSprite will be placed.
     * @param {number} y - The y coordinate on screen where the textSprite will be placed.
     * @param {Object} callback - Callback to use when the button is clicked.
     * @param {Object} callbackContext - The context the callback is called in.
     * @param {number} overKey - The frame to switch to when an over event is triggered.
     * @param {number} outKey - The frame to switch to when an out event is triggered.
     * @param {number} downKey - The frame to switch to when a down event is triggered.
     * @param {number} upKey - The frame to switch to when an up event is triggered.
     */
    constructor(game, x, y, key, callback, callbackContext, overKey, outKey, downKey, upKey) {
        super(game);

        this.game = game;
        game.add.existing(this);

        this.button = new PhaserObjects.Button(
            game,
            x,
            y,
            key,
            callback,
            callbackContext,
            overKey,
            outKey,
            downKey,
            upKey,
        );
        this.add(this.button);

        this.width = this.button.width;
        this.height = this.button.height;
    }

    /** Adds an adjustment to the text on down/up events. */
    eventTextYAdjustment(number) {
        const startY = this.text.y;

        this.button.addDownEvent(() => { this.text.y += number; });
        this.button.addUpEvent(() => { this.text.y = startY; });

        // A pointerout event should reset the text position too.
        this.button.addOutEvent(() => { this.text.y = startY; });

        return this;
    }
}
<|endoftext|>


<commit_before>/*jslint evil: false, bitwise:false, strict: true, undef: true, white:true, onevar:false, browser:true, plusplus:false */
/*global jQuery, Capture:true, window */
/**
 *  Capture.js
 *  v1.0.0
 *  Copyright 2011 Adam Craven
 *  Freely distributable under the MIT License.
 *  https://github.com/AdmCrvn/Capture
 */
(function ($) {
    "use strict";

    var bind = Function.prototype.bind;
    var slice = Array.prototype.slice;
    var toString = Object.prototype.toString;
    var UNDEFINED;

    // All properties with prefix of 'on' are treated as event delegates
    var eventMethodPrefix = /^on(.+)/;

    /**
     *  Native ECMAScript 5 bind if supported or passes to jQuery proxy.
     *  @param  {function}  fn    Function to bind.
     *  @param  {object}  scope Scope in which to bind the function.
     */
    function bindScope(fn, scope) {
        if (bind && fn.bind === bind) {
            return bind.apply(fn, slice.call(arguments, 1));
        }
        return $.proxy(fn, scope);
    }

    /**
     *  Validates the view when captured, checking for basic errors
     */
    function validate(element, view) {
        if (!view) {
            throw new Error('Capture.js; No view passed. You must attach a view object or constructor. e.g. $("el").capture(view)');
        }

        if (toString.call(view) !== '[object Object]') {
            throw new Error('Capture.js; Invalid view type. The view must be an object or a constructor.');
        }

        if (element.length === 0 || !element.each) {
            throw new Error('Capture.js; No element found. You must attach the view to an element.');
        }
    }

    /**
     *  Adds listeners to the view.
     *  By default all methods that have the valid prefix 'on', their selectors will be bound
     *
     *  @example view controller method the function will bind event delegates with
     *    onclick : {
     *      '.selector' : function(e) {
     *
     *      }
     *    }
     */
    function addEventListeners(view) {
        var eventHolder;
        var eventType;
        var method;
        var selector;
        var listenerElement = view.element;
        var handlerFn;

        // Loop through all methods looking for event delegates
        for (method in view) {
            if (view.hasOwnProperty(method) && method.match(eventMethodPrefix) && typeof view[method] === "object") {
                eventHolder = view[method];
                // e.g. click
                eventType = method.match(eventMethodPrefix)[1];

                for (selector in eventHolder) {
                    if (eventHolder.hasOwnProperty(selector)) {
                        handlerFn = eventHolder[selector];
                        // If the selector is the same as the listenerElement
                        // Or using special 'element' property
                        if (listenerElement.is(selector) || handlerFn === eventHolder.element) {
                            // Attach event to current element
                            listenerElement.bind(eventType, bindScope(handlerFn, view));
                        } else {
                            // Bind event delegate to the element. Setting the context to the view
                            listenerElement.delegate(selector, eventType, bindScope(handlerFn, view));
                        }
                    }
                }
            }
        }
    }

    /**
     *  Connect the view controller and element together
     *
     *  @param {Object} element         Element to attach view unto.
     *  @param {Object} View            View to capture.
     *  @param {Any}    [optionalArgs]  One or more extra arguments that are passed to the view.init.
     *
     *  @returns {object} New instance of an initalised view controller
     */
    function connectView(element, view, optionalArgs) {
        view.element = element;

        if (view.init && view.hasOwnProperty('init')) {
            if (optionalArgs) {
                view.init.apply(view, optionalArgs);
            } else {
                view.init.call(view);
            }
        }

        addEventListeners(view);

        return view;
    }

    if (typeof Capture !== "undefined") {
        throw new Error('Capture is already defined');
    }

    /**
     * View Controller base constructor.
     * When an object is wrapped with Capture.view, it inherits methods directly
     * from this constructor
     * @constructor
     */
    function ViewBaseClass() {}

    ViewBaseClass.prototype = {
        // Remove all event handlers
        removeEventListeners : function () {
            this.element.unbind();
            this.element.undelegate();
        },
        // Reattach all event listners
        reattachEventListeners : function () {
            this.removeEventListeners();
            addEventListeners(this);
        }
    };

    /**
     *  Capture attaches a view to an element via event delegates.
     *
     *  @param {String/Object}   element Element to attach view unto.
     *  @param {Object/Function} View    To be instantiated as a capture view.
     *  @param {AnyType}         [1..*]  One or more extra arguments that are passed to the view.init.
     *
     *  @returns {object}    Instantiated view
     *
     *  @example
     *   Capture('#gallery', view)
     */
    window.Capture = function (element, view) {
        // If wrapped by Capture.view, it will be a function.
        view = (typeof view === "function") ? view() : view;

        element = $(element);

        validate(element, view);

        return connectView(element.eq(0), view, (arguments.length > 2) ? slice.call(arguments, 2) : UNDEFINED);
    };

    /**
     *  This wraps the view until called by capture.
     *  It instantiates the view controller and sets inheritance to view base class.
     *
     *  @param {Object/Function} View    To be instantiated as a capture view
     *
     *  @returns {function} The view to be initalised by capture
     */
    Capture.view = function (View) {
        return function () {
            // If a constructor has been passed
            var view = (typeof View === "function") ? new View() : View;

            // Deep copy view into instance of ViewBaseClass
            return $.extend(true, new ViewBaseClass(), view);
        };
    };

    /**
     *  jQuery method to capture a view on the existing element.
     *  Doesn't return an error if element doesn't exist, as per jQuery philosophy.
     *
     *  @param  {object}  view  The View to be initialised from on the element
     *  @param {AnyType}         [1..*]  One or more extra arguments that are passed to the view.init.
     *
     *  @returns {object}    Instantiated view
     *
     *  @example
     *  $('#element').capture(view)
     */
    $.fn.capture = function (view) {
        if (this.length === 0 || !this.each) {
            return;
        }
        return window.Capture.apply(null, [this].concat(slice.call(arguments, 0)));
    };

})(jQuery);
<commit_msg>Error checking happens at the start.<commit_after>/*jslint evil: false, bitwise:false, strict: true, undef: true, white:true, onevar:false, browser:true, plusplus:false */
/*global jQuery, Capture:true, window */
/**
 *  Capture.js
 *  v1.0.0
 *  Copyright 2011 Adam Craven
 *  Freely distributable under the MIT License.
 *  https://github.com/AdmCrvn/Capture
 */
(function ($) {
    "use strict";

    if (typeof Capture !== "undefined") {
        throw new Error('Capture is already defined');
    }

    var bind = Function.prototype.bind;
    var slice = Array.prototype.slice;
    var toString = Object.prototype.toString;
    var UNDEFINED;

    // All properties with prefix of 'on' are treated as event delegates
    var eventMethodPrefix = /^on(.+)/;

    /**
     *  Native ECMAScript 5 bind if supported or passes to jQuery proxy.
     *  @param  {function}  fn    Function to bind.
     *  @param  {object}  scope Scope in which to bind the function.
     */
    function bindScope(fn, scope) {
        if (bind && fn.bind === bind) {
            return bind.apply(fn, slice.call(arguments, 1));
        }
        return $.proxy(fn, scope);
    }

    /**
     *  Validates the view when captured, checking for basic errors
     */
    function validate(element, view) {
        if (!view) {
            throw new Error('Capture.js; No view passed. You must attach a view object or constructor. e.g. $("el").capture(view)');
        }

        if (toString.call(view) !== '[object Object]') {
            throw new Error('Capture.js; Invalid view type. The view must be an object or a constructor.');
        }

        if (element.length === 0 || !element.each) {
            throw new Error('Capture.js; No element found. You must attach the view to an element.');
        }
    }

    /**
     *  Adds listeners to the view.
     *  By default all methods that have the valid prefix 'on', their selectors will be bound
     *
     *  @example view controller method the function will bind event delegates with
     *    onclick : {
     *      '.selector' : function(e) {
     *
     *      }
     *    }
     */
    function addEventListeners(view) {
        var eventHolder;
        var eventType;
        var method;
        var selector;
        var listenerElement = view.element;
        var handlerFn;

        // Loop through all methods looking for event delegates
        for (method in view) {
            if (view.hasOwnProperty(method) && method.match(eventMethodPrefix) && typeof view[method] === "object") {
                eventHolder = view[method];
                // e.g. click
                eventType = method.match(eventMethodPrefix)[1];

                for (selector in eventHolder) {
                    if (eventHolder.hasOwnProperty(selector)) {
                        handlerFn = eventHolder[selector];
                        // If the selector is the same as the listenerElement
                        // Or using special 'element' property
                        if (listenerElement.is(selector) || handlerFn === eventHolder.element) {
                            // Attach event to current element
                            listenerElement.bind(eventType, bindScope(handlerFn, view));
                        } else {
                            // Bind event delegate to the element. Setting the context to the view
                            listenerElement.delegate(selector, eventType, bindScope(handlerFn, view));
                        }
                    }
                }
            }
        }
    }

    /**
     *  Connect the view controller and element together
     *
     *  @param {Object} element         Element to attach view unto.
     *  @param {Object} View            View to capture.
     *  @param {Any}    [optionalArgs]  One or more extra arguments that are passed to the view.init.
     *
     *  @returns {object} New instance of an initalised view controller
     */
    function connectView(element, view, optionalArgs) {
        view.element = element;

        if (view.init && view.hasOwnProperty('init')) {
            if (optionalArgs) {
                view.init.apply(view, optionalArgs);
            } else {
                view.init.call(view);
            }
        }

        addEventListeners(view);

        return view;
    }

    /**
     * View Controller base constructor.
     * When an object is wrapped with Capture.view, it inherits methods directly
     * from this constructor
     * @constructor
     */
    function ViewBaseClass() {}

    ViewBaseClass.prototype = {
        // Remove all event handlers
        removeEventListeners : function () {
            this.element.unbind();
            this.element.undelegate();
        },
        // Reattach all event listners
        reattachEventListeners : function () {
            this.removeEventListeners();
            addEventListeners(this);
        }
    };

    /**
     *  Capture attaches a view to an element via event delegates.
     *
     *  @param {String/Object}   element Element to attach view unto.
     *  @param {Object/Function} View    To be instantiated as a capture view.
     *  @param {AnyType}         [1..*]  One or more extra arguments that are passed to the view.init.
     *
     *  @returns {object}    Instantiated view
     *
     *  @example
     *   Capture('#gallery', view)
     */
    window.Capture = function (element, view) {
        // If wrapped by Capture.view, it will be a function.
        view = (typeof view === "function") ? view() : view;

        element = $(element);

        validate(element, view);

        return connectView(element.eq(0), view, (arguments.length > 2) ? slice.call(arguments, 2) : UNDEFINED);
    };

    /**
     *  This wraps the view until called by capture.
     *  It instantiates the view controller and sets inheritance to view base class.
     *
     *  @param {Object/Function} View    To be instantiated as a capture view
     *
     *  @returns {function} The view to be initalised by capture
     */
    Capture.view = function (View) {
        return function () {
            // If a constructor has been passed, instantiate it now
            var view = (typeof View === "function") ? new View() : View;

            // Deep copy view into instance of ViewBaseClass
            return $.extend(true, new ViewBaseClass(), view);
        };
    };

    /**
     *  jQuery method to capture a view on the existing element.
     *  Doesn't return an error if element doesn't exist, as per jQuery philosophy.
     *
     *  @param  {object}  view  The View to be initialised from on the element
     *  @param {AnyType}         [1..*]  One or more extra arguments that are passed to the view.init.
     *
     *  @returns {object}    Instantiated view
     *
     *  @example
     *  $('#element').capture(view)
     */
    $.fn.capture = function (view) {
        if (this.length === 0 || !this.each) {
            return;
        }
        return window.Capture.apply(null, [this].concat(slice.call(arguments, 0)));
    };

})(jQuery);
<|endoftext|>


<commit_before>// entry point
;(function() {

    var root = this;

    var cdb = root.cdb = {};

    cdb.VERSION = "3.11.29";
    cdb.DEBUG = false;

    cdb.CARTOCSS_VERSIONS = {
      '2.0.0': '',
      '2.1.0': ''
    };

    cdb.CARTOCSS_DEFAULT_VERSION = '2.1.1';

    cdb.CDB_HOST = {
      'http': 'api.cartocdn.com',
      'https': 'cartocdn.global.ssl.fastly.net'
    };

    root.cdb.config = {};
    root.cdb.core = {};
    root.cdb.image = {};
    root.cdb.geo = {};
    root.cdb.geo.ui = {};
    root.cdb.geo.geocoder = {};
    root.cdb.ui = {};
    root.cdb.ui.common = {};
    root.cdb.vis = {};
    root.cdb.decorators = {};
    /**
     * global variables
     */
    root.JST = root.JST || {};
    root.cartodb = cdb;

    cdb.files = [
        "../vendor/jquery.min.js",
        "../vendor/underscore-min.js",
        "../vendor/json2.js",
        "../vendor/backbone.js",

        "../vendor/leaflet.js",
        "../vendor/wax.cartodb.js",
        "../vendor/GeoJSON.js", //geojson gmaps lib

        "../vendor/jscrollpane.js",
        "../vendor/mousewheel.js",
        "../vendor/mwheelIntent.js",
        "../vendor/spin.js",
        "../vendor/lzma.js",

        'core/decorator.js',
        'core/config.js',
        'core/log.js',
        'core/profiler.js',
        'core/template.js',
        'core/model.js',
        'core/view.js',
        'core/image.js',

        'geo/geocoder.js',
        'geo/geometry.js',
        'geo/map.js',
        'geo/ui/text.js',
        'geo/ui/annotation.js',
        'geo/ui/image.js',
        'geo/ui/share.js',
        'geo/ui/zoom.js',
        'geo/ui/zoom_info.js',
        'geo/ui/legend.js',
        'geo/ui/switcher.js',
        'geo/ui/infowindow.js',
        'geo/ui/header.js',
        'geo/ui/search.js',
        'geo/ui/layer_selector.js',
        'geo/ui/mobile.js',
        'geo/ui/tiles_loader.js',
        'geo/ui/infobox.js',
        'geo/ui/tooltip.js',
        'geo/ui/fullscreen.js',

        'geo/layer_definition.js',
        'geo/common.js',

        'geo/leaflet/leaflet_base.js',
        'geo/leaflet/leaflet_plainlayer.js',
        'geo/leaflet/leaflet_tiledlayer.js',
        'geo/leaflet/leaflet_gmaps_tiledlayer.js',
        'geo/leaflet/leaflet_wmslayer.js',
        'geo/leaflet/leaflet_cartodb_layergroup.js',
        'geo/leaflet/leaflet_cartodb_layer.js',
        'geo/leaflet/leaflet.js',

        'geo/gmaps/gmaps_base.js',
        'geo/gmaps/gmaps_baselayer.js',
        'geo/gmaps/gmaps_plainlayer.js',
        'geo/gmaps/gmaps_tiledlayer.js',
        'geo/gmaps/gmaps_cartodb_layergroup.js',
        'geo/gmaps/gmaps_cartodb_layer.js',
        'geo/gmaps/gmaps.js',

        'ui/common/dialog.js',
        'ui/common/share.js',
        'ui/common/notification.js',
        'ui/common/table.js',
        'ui/common/dropdown.js',

        'vis/vis.js',
        'vis/overlays.js',
        'vis/layers.js',

        // PUBLIC API
        'api/layers.js',
        'api/sql.js',
        'api/vis.js'
    ];

    cdb.init = function(ready) {
      // define a simple class
      var Class = cdb.Class = function() {};
      _.extend(Class.prototype, Backbone.Events);

      cdb._loadJST();
      root.cdb.god = new Backbone.Model();

      ready && ready();
    };

    /**
     * load all the javascript files. For testing, do not use in production
     */
    cdb.load = function(prefix, ready) {
        var c = 0;

        var next = function() {
            var script = document.createElement('script');
            script.src = prefix + cdb.files[c];
            document.body.appendChild(script);
            ++c;
            if(c == cdb.files.length) {
                if(ready) {
                    script.onload = ready;
                }
            } else {
                script.onload = next;
            }
        };

        next();

    };
})();
<commit_msg>moved to the bottom to extend from map<commit_after>// entry point
;(function() {

    var root = this;

    var cdb = root.cdb = {};

    cdb.VERSION = "3.11.29";
    cdb.DEBUG = false;

    cdb.CARTOCSS_VERSIONS = {
      '2.0.0': '',
      '2.1.0': ''
    };

    cdb.CARTOCSS_DEFAULT_VERSION = '2.1.1';

    cdb.CDB_HOST = {
      'http': 'api.cartocdn.com',
      'https': 'cartocdn.global.ssl.fastly.net'
    };

    root.cdb.config = {};
    root.cdb.core = {};
    root.cdb.image = {};
    root.cdb.geo = {};
    root.cdb.geo.ui = {};
    root.cdb.geo.geocoder = {};
    root.cdb.ui = {};
    root.cdb.ui.common = {};
    root.cdb.vis = {};
    root.cdb.decorators = {};
    /**
     * global variables
     */
    root.JST = root.JST || {};
    root.cartodb = cdb;

    cdb.files = [
        "../vendor/jquery.min.js",
        "../vendor/underscore-min.js",
        "../vendor/json2.js",
        "../vendor/backbone.js",

        "../vendor/leaflet.js",
        "../vendor/wax.cartodb.js",
        "../vendor/GeoJSON.js", //geojson gmaps lib

        "../vendor/jscrollpane.js",
        "../vendor/mousewheel.js",
        "../vendor/mwheelIntent.js",
        "../vendor/spin.js",
        "../vendor/lzma.js",

        'core/decorator.js',
        'core/config.js',
        'core/log.js',
        'core/profiler.js',
        'core/template.js',
        'core/model.js',
        'core/view.js',

        'geo/geocoder.js',
        'geo/geometry.js',
        'geo/map.js',
        'geo/ui/text.js',
        'geo/ui/annotation.js',
        'geo/ui/image.js',
        'geo/ui/share.js',
        'geo/ui/zoom.js',
        'geo/ui/zoom_info.js',
        'geo/ui/legend.js',
        'geo/ui/switcher.js',
        'geo/ui/infowindow.js',
        'geo/ui/header.js',
        'geo/ui/search.js',
        'geo/ui/layer_selector.js',
        'geo/ui/mobile.js',
        'geo/ui/tiles_loader.js',
        'geo/ui/infobox.js',
        'geo/ui/tooltip.js',
        'geo/ui/fullscreen.js',

        'geo/layer_definition.js',
        'geo/common.js',
        'core/image.js',

        'geo/leaflet/leaflet_base.js',
        'geo/leaflet/leaflet_plainlayer.js',
        'geo/leaflet/leaflet_tiledlayer.js',
        'geo/leaflet/leaflet_gmaps_tiledlayer.js',
        'geo/leaflet/leaflet_wmslayer.js',
        'geo/leaflet/leaflet_cartodb_layergroup.js',
        'geo/leaflet/leaflet_cartodb_layer.js',
        'geo/leaflet/leaflet.js',

        'geo/gmaps/gmaps_base.js',
        'geo/gmaps/gmaps_baselayer.js',
        'geo/gmaps/gmaps_plainlayer.js',
        'geo/gmaps/gmaps_tiledlayer.js',
        'geo/gmaps/gmaps_cartodb_layergroup.js',
        'geo/gmaps/gmaps_cartodb_layer.js',
        'geo/gmaps/gmaps.js',

        'ui/common/dialog.js',
        'ui/common/share.js',
        'ui/common/notification.js',
        'ui/common/table.js',
        'ui/common/dropdown.js',

        'vis/vis.js',
        'vis/overlays.js',
        'vis/layers.js',

        // PUBLIC API
        'api/layers.js',
        'api/sql.js',
        'api/vis.js'
    ];

    cdb.init = function(ready) {
      // define a simple class
      var Class = cdb.Class = function() {};
      _.extend(Class.prototype, Backbone.Events);

      cdb._loadJST();
      root.cdb.god = new Backbone.Model();

      ready && ready();
    };

    /**
     * load all the javascript files. For testing, do not use in production
     */
    cdb.load = function(prefix, ready) {
        var c = 0;

        var next = function() {
            var script = document.createElement('script');
            script.src = prefix + cdb.files[c];
            document.body.appendChild(script);
            ++c;
            if(c == cdb.files.length) {
                if(ready) {
                    script.onload = ready;
                }
            } else {
                script.onload = next;
            }
        };

        next();

    };
})();
<|endoftext|>


<commit_before>/*    Copyright 2016 Firewalla LLC
 *
 *    This program is free software: you can redistribute it and/or  modify
 *    it under the terms of the GNU Affero General Public License, version 3,
 *    as published by the Free Software Foundation.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
'use strict';

let log = require('../net2/logger.js')(__filename);

let util = require('util');

let Sensor = require('./Sensor.js').Sensor;

let redis = require("redis");
let rclient = redis.createClient();
let pubClient = redis.createClient();

const PolicyManager2 = require('../alarm/PolicyManager2.js')
const pm2 = new PolicyManager2()

const ExceptionManager = require('../alarm/ExceptionManager.js')
const em = new ExceptionManager()

const HostTool = require('../net2/HostTool.js')
const hostTool = new HostTool()

let Promise = require('bluebird');
Promise.promisifyAll(redis.RedisClient.prototype);
Promise.promisifyAll(redis.Multi.prototype);

let async = require('asyncawait/async');
let await = require('asyncawait/await');

let fConfig = require('../net2/config.js').getConfig();

class OldDataCleanSensor extends Sensor {
  constructor() {
    super();
  }

  getExpiredDate(type) {
    let expireInterval = (this.config[type] && this.config[type].expires) || 0;
    let minInterval = 8 * 60 * 60;
    expireInterval = Math.max(expireInterval, minInterval);

    return Date.now() / 1000 - expireInterval;
  }

  getCount(type) {
    let count = (this.config[type] && this.config[type].count) || 10000;
    return count;
  }

  cleanByExpireDate(key, expireDate) {
    return rclient.zremrangebyscoreAsync(key, "-inf", expireDate)
      .then((count) => {
        if(count > 0) {
          log.info(util.format("%d entries in %s are cleaned by expired date", count, key));
        }
      });
  }

  cleanToCount(key, leftOverCount) {
    return rclient.zremrangebyrankAsync(key, 0, -1 * leftOverCount)
      .then((count) => {
        if(count > 0) {
          log.info(util.format("%d entries in %s are cleaned by count", count, key));
        }
      });
  }

  getKeys(keyPattern) {
    return rclient.keysAsync(keyPattern);
  }

  // clean by expired time and count
  regularClean(type, keyPattern, ignorePatterns) {

    return async(() => {
      let keys = await (this.getKeys(keyPattern));

      if(ignorePatterns) {
        keys = keys.filter((x) => {
          return ignorePatterns.filter((p) => x.match(p)).length === 0
        });
      }

      keys.forEach((key) => {
        await (this.cleanByExpireDate(key, this.getExpiredDate(type)));
        await (this.cleanToCount(key, this.getCount(type)));
      })

    })();

  }

  cleanAlarm() {
    // TODO
  }

  cleanPolicy() {
    // TODO
  }

  cleanException() {
    // TODO
  }

  cleanSumFlow() {

  }

  cleanHourlyFlow() {

  }

  cleanAggrFlow() {

  }

  cleanHourlyStats() {
    // FIXME: not well coded here, deprecated code
      rclient.keys("stats:hour*",(err,keys)=> {
        let expireDate = Date.now() / 1000 - 60 * 60 * 24 * 30 * 6;
        for (let j in keys) {
          rclient.zscan(keys[j],0,(err,data)=>{
            if (data && data.length==2) {
              let array = data[1];
              for (let i=0;i<array.length;i++) {
                if (array[i]<expireDate) {
                  rclient.zrem(keys[j],array[i]);
                }
                i += Number(1);
              }
            }
          });
        }
      });

    return Promise.resolve();
  }

  cleanUserAgents() {
    // FIXME: not well coded here, deprecated code
      let MAX_AGENT_STORED = 150;
      rclient.keys("host:user_agent:*", (err, keys) => {
        for (let j in keys) {
          rclient.scard(keys[j], (err, count) => {
//                    log.info(keys[j]," count ", count);
            if (count > MAX_AGENT_STORED) {
              log.info(keys[j], " pop count ", count - MAX_AGENT_STORED);
              for (let i = 0; i < count - MAX_AGENT_STORED; i++) {
                rclient.spop(keys[j], (err) => {
                  if (err) {
                    log.info(keys[j], " count ", count - MAX_AGENT_STORED, err);
                  }
                });
              }
            }
          });
        }
      });

      return Promise.resolve();
  }

  cleanHostData(type, keyPattern, defaultExpireInterval) {
    let expireInterval = (this.config[type] && this.config[type].expires) ||
      defaultExpireInterval;

    let expireDate = Date.now() / 1000 - expireInterval;

    return this.getKeys(keyPattern)
      .then((keys) => {
        return Promise.all(
          keys.map((key) => {
            return rclient.hgetallAsync(key)
              .then((data) => {
                if (data &&  data.lastActiveTimestamp) {
                  if (data.lastActiveTimestamp < expireDate) {
                    log.info(key,"Deleting due to timeout ", expireDate, data);
                    return rclient.delAsync(key);
                  } else {
                    return Promise.resolve();
                  }
                } else {
                  return Promise.resolve();
                }
              })
          })
        ).then(() => {
          // log.info("CleanHostData on", keys, "is completed", {});
        })
      });
  }

  cleanDuplicatedPolicy() {
    return async(() => {

      const policies = await (pm2.loadActivePolicysAsync(1000))

      let toBeDeleted = []

      for(let i = 0; i < policies.length; i++) {
        let p = policies[i]
        for(let j = i+1; j< policies.length; j++) {
          let p2 = policies[j]
          if(p && p2 && p.isEqualToPolicy(p2)) {
            toBeDeleted.push(p)
            break
          }
        }
      }

      for(let k in toBeDeleted) {
        let p = toBeDeleted[k]
        await (pm2.deletePolicy(p.pid))
      }
    })()
  }

  cleanDuplicatedException() {
    return async(() => {
      const exceptions = await (em.loadExceptionsAsync())

      let toBeDeleted = []

      for(let i = 0; i < exceptions.length; i++) {
        let e = exceptions[i]
        for(let j = i+1; j< exceptions.length; j++) {
          let e2 = exceptions[j]
          if(e && e2 && e.isEqualToException(e2)) {
            toBeDeleted.push(e)
            break
          }
        }
      }

      for(let k in toBeDeleted) {
        let e = toBeDeleted[k]
        await (em.deleteException(e.eid))
      }
    })()
  }

  cleanInvalidMACAddress() {
    return async(() => {
      const macs = await (hostTool.getAllMACs())
      const invalidMACs = macs.filter((m) => {
        return m.match(/[a-f]+/) != null
      })
      invalidMACs.forEach((m) => {
        await (hostTool.deleteMac(m))
      })
    })()
  }

  oneTimeJob() {
    return async(() => {
      await (this.cleanDuplicatedPolicy())
      await (this.cleanDuplicatedException())
      await (this.cleanInvalidMACAddress())
    })()
  }

  scheduledJob() {
    return async(() => {
      log.info("Start cleaning old data in redis")

      await (this.regularClean("conn", "flow:conn:*"));
      await (this.regularClean("ssl", "flow:ssl:*"));
      await (this.regularClean("http", "flow:http:*"));
      await (this.regularClean("notice", "notice:*"));
      await (this.regularClean("intel", "intel:*", [/^intel:ip/]));
      await (this.regularClean("software", "software:*"));
      await (this.regularClean("monitor", "monitor:flow:*"));
      await (this.regularClean("alarm", "alarm:ip4:*"));
      await (this.cleanHourlyStats());
      await (this.cleanUserAgents());
      await (this.cleanHostData("host:ip4", "host:ip4:*", 60*60*24*30));
      await (this.cleanHostData("host:ip6", "host:ip6:*", 60*60*24*30));
      await (this.cleanHostData("host:mac", "host:mac:*", 60*60*24*365));
      log.info("scheduledJob is executed successfully");
    })();
  }

  listen() {
    pubClient.on("message", (channel, message) => {
      if(channel === "OldDataCleanSensor" && message === "Start") {
        this.scheduledJob();
      }
    });
    pubClient.subscribe("OldDataCleanSensor");
    log.info("Listen on channel FlowDataCleanSensor");
  }

  // could be disabled in the future when all policy blockin rule is migrated to general policy rules
  hostPolicyMigration() {
    return async(() => {
      const keys = await (rclient.keysAsync("policy:mac:*"))
      if(keys) {
        keys.forEach((key) => {
          const blockin = await (rclient.hgetAsync(key, "blockin"))
          if(blockin) {
            const mac = key.replace("policy:mac:", "")
            const rule = await (pm2.findPolicy(mac, "mac"))
            if(!rule) {
              log.info(`Migrating blockin policy for host ${mac} to policyRule`)
              const newRule = pm2.createPolicy({
                target: mac,
                type: "mac"
              })
              const result = await (pm2.checkAndSaveAsync(newRule))
              if(result) {
                await (rclient.hsetAsync(key, "blockin", false))
                log.info("Migrated successfully")
              } else {
                log.error("Failed to migrate")
              }
            }
          }
        })
      }
    })().catch((err) => {
      log.error("Failed to migrate host policy rules:", err, {})
    })
  }

  run() {
    super.run();

    this.listen();

    this.hostPolicyMigration()

    setTimeout(() => {
      this.scheduledJob();
      this.oneTimeJob()
      setInterval(() => {
        this.scheduledJob();
      }, 1000 * 60 * 60); // cleanup every hour
    }, 1000 * 60 * 5); // first time in 5 mins
  }
}

module.exports = OldDataCleanSensor;
<commit_msg>bug fix<commit_after>/*    Copyright 2016 Firewalla LLC
 *
 *    This program is free software: you can redistribute it and/or  modify
 *    it under the terms of the GNU Affero General Public License, version 3,
 *    as published by the Free Software Foundation.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
'use strict';

let log = require('../net2/logger.js')(__filename);

let util = require('util');

let Sensor = require('./Sensor.js').Sensor;

let redis = require("redis");
let rclient = redis.createClient();
let pubClient = redis.createClient();

const PolicyManager2 = require('../alarm/PolicyManager2.js')
const pm2 = new PolicyManager2()

const ExceptionManager = require('../alarm/ExceptionManager.js')
const em = new ExceptionManager()

const HostTool = require('../net2/HostTool.js')
const hostTool = new HostTool()

let Promise = require('bluebird');
Promise.promisifyAll(redis.RedisClient.prototype);
Promise.promisifyAll(redis.Multi.prototype);

let async = require('asyncawait/async');
let await = require('asyncawait/await');

let fConfig = require('../net2/config.js').getConfig();

class OldDataCleanSensor extends Sensor {
  constructor() {
    super();
  }

  getExpiredDate(type) {
    let expireInterval = (this.config[type] && this.config[type].expires) || 0;
    let minInterval = 8 * 60 * 60;
    expireInterval = Math.max(expireInterval, minInterval);

    return Date.now() / 1000 - expireInterval;
  }

  getCount(type) {
    let count = (this.config[type] && this.config[type].count) || 10000;
    return count;
  }

  cleanByExpireDate(key, expireDate) {
    return rclient.zremrangebyscoreAsync(key, "-inf", expireDate)
      .then((count) => {
        if(count > 0) {
          log.info(util.format("%d entries in %s are cleaned by expired date", count, key));
        }
      });
  }

  cleanToCount(key, leftOverCount) {
    return rclient.zremrangebyrankAsync(key, 0, -1 * leftOverCount)
      .then((count) => {
        if(count > 0) {
          log.info(util.format("%d entries in %s are cleaned by count", count, key));
        }
      });
  }

  getKeys(keyPattern) {
    return rclient.keysAsync(keyPattern);
  }

  // clean by expired time and count
  regularClean(type, keyPattern, ignorePatterns) {

    return async(() => {
      let keys = await (this.getKeys(keyPattern));

      if(ignorePatterns) {
        keys = keys.filter((x) => {
          return ignorePatterns.filter((p) => x.match(p)).length === 0
        });
      }

      keys.forEach((key) => {
        await (this.cleanByExpireDate(key, this.getExpiredDate(type)));
        await (this.cleanToCount(key, this.getCount(type)));
      })

    })();

  }

  cleanAlarm() {
    // TODO
  }

  cleanPolicy() {
    // TODO
  }

  cleanException() {
    // TODO
  }

  cleanSumFlow() {

  }

  cleanHourlyFlow() {

  }

  cleanAggrFlow() {

  }

  cleanHourlyStats() {
    // FIXME: not well coded here, deprecated code
      rclient.keys("stats:hour*",(err,keys)=> {
        let expireDate = Date.now() / 1000 - 60 * 60 * 24 * 30 * 6;
        for (let j in keys) {
          rclient.zscan(keys[j],0,(err,data)=>{
            if (data && data.length==2) {
              let array = data[1];
              for (let i=0;i<array.length;i++) {
                if (array[i]<expireDate) {
                  rclient.zrem(keys[j],array[i]);
                }
                i += Number(1);
              }
            }
          });
        }
      });

    return Promise.resolve();
  }

  cleanUserAgents() {
    // FIXME: not well coded here, deprecated code
      let MAX_AGENT_STORED = 150;
      rclient.keys("host:user_agent:*", (err, keys) => {
        for (let j in keys) {
          rclient.scard(keys[j], (err, count) => {
//                    log.info(keys[j]," count ", count);
            if (count > MAX_AGENT_STORED) {
              log.info(keys[j], " pop count ", count - MAX_AGENT_STORED);
              for (let i = 0; i < count - MAX_AGENT_STORED; i++) {
                rclient.spop(keys[j], (err) => {
                  if (err) {
                    log.info(keys[j], " count ", count - MAX_AGENT_STORED, err);
                  }
                });
              }
            }
          });
        }
      });

      return Promise.resolve();
  }

  cleanHostData(type, keyPattern, defaultExpireInterval) {
    let expireInterval = (this.config[type] && this.config[type].expires) ||
      defaultExpireInterval;

    let expireDate = Date.now() / 1000 - expireInterval;

    return this.getKeys(keyPattern)
      .then((keys) => {
        return Promise.all(
          keys.map((key) => {
            return rclient.hgetallAsync(key)
              .then((data) => {
                if (data &&  data.lastActiveTimestamp) {
                  if (data.lastActiveTimestamp < expireDate) {
                    log.info(key,"Deleting due to timeout ", expireDate, data);
                    return rclient.delAsync(key);
                  } else {
                    return Promise.resolve();
                  }
                } else {
                  return Promise.resolve();
                }
              })
          })
        ).then(() => {
          // log.info("CleanHostData on", keys, "is completed", {});
        })
      });
  }

  cleanDuplicatedPolicy() {
    return async(() => {

      const policies = await (pm2.loadActivePolicysAsync(1000))

      let toBeDeleted = []

      for(let i = 0; i < policies.length; i++) {
        let p = policies[i]
        for(let j = i+1; j< policies.length; j++) {
          let p2 = policies[j]
          if(p && p2 && p.isEqualToPolicy(p2)) {
            toBeDeleted.push(p)
            break
          }
        }
      }

      for(let k in toBeDeleted) {
        let p = toBeDeleted[k]
        await (pm2.deletePolicy(p.pid))
      }
    })()
  }

  cleanDuplicatedException() {
    return async(() => {
      const exceptions = await (em.loadExceptionsAsync())

      let toBeDeleted = []

      for(let i = 0; i < exceptions.length; i++) {
        let e = exceptions[i]
        for(let j = i+1; j< exceptions.length; j++) {
          let e2 = exceptions[j]
          if(e && e2 && e.isEqualToException(e2)) {
            toBeDeleted.push(e)
            break
          }
        }
      }

      for(let k in toBeDeleted) {
        let e = toBeDeleted[k]
        await (em.deleteException(e.eid))
      }
    })()
  }

  cleanInvalidMACAddress() {
    return async(() => {
      const macs = await (hostTool.getAllMACs())
      const invalidMACs = macs.filter((m) => {
        return m.match(/[a-f]+/) != null
      })
      invalidMACs.forEach((m) => {
        await (hostTool.deleteMac(m))
      })
    })()
  }

  oneTimeJob() {
    return async(() => {
      await (this.cleanDuplicatedPolicy())
      await (this.cleanDuplicatedException())
      await (this.cleanInvalidMACAddress())
    })()
  }

  scheduledJob() {
    return async(() => {
      log.info("Start cleaning old data in redis")

      await (this.regularClean("conn", "flow:conn:*"));
      await (this.regularClean("ssl", "flow:ssl:*"));
      await (this.regularClean("http", "flow:http:*"));
      await (this.regularClean("notice", "notice:*"));
      await (this.regularClean("intel", "intel:*", [/^intel:ip/]));
      await (this.regularClean("software", "software:*"));
      await (this.regularClean("monitor", "monitor:flow:*"));
      await (this.regularClean("alarm", "alarm:ip4:*"));
      await (this.cleanHourlyStats());
      await (this.cleanUserAgents());
      await (this.cleanHostData("host:ip4", "host:ip4:*", 60*60*24*30));
      await (this.cleanHostData("host:ip6", "host:ip6:*", 60*60*24*30));
      await (this.cleanHostData("host:mac", "host:mac:*", 60*60*24*365));
      log.info("scheduledJob is executed successfully");
    })();
  }

  listen() {
    pubClient.on("message", (channel, message) => {
      if(channel === "OldDataCleanSensor" && message === "Start") {
        this.scheduledJob();
      }
    });
    pubClient.subscribe("OldDataCleanSensor");
    log.info("Listen on channel FlowDataCleanSensor");
  }

  // could be disabled in the future when all policy blockin rule is migrated to general policy rules
  hostPolicyMigration() {
    return async(() => {
      const keys = await (rclient.keysAsync("policy:mac:*"))
      if(keys) {
        keys.forEach((key) => {
          const blockin = await (rclient.hgetAsync(key, "blockin"))
          if(blockin) {
            const mac = key.replace("policy:mac:", "")
            const rule = await (pm2.findPolicy(mac, "mac"))
            if(!rule) {
              log.info(`Migrating blockin policy for host ${mac} to policyRule`)
              const hostInfo = await (hostTool.getMACEntry(mac))
              const newRule = pm2.createPolicy({
                target: mac,
                type: "mac",
                target_name: hostInfo.name || hostInfo.bname || hostInfo.ipv4Addr,
                target_ip: hostInfo.ipv4Addr // target_name and target ip are necessary for old app display
              })
              const result = await (pm2.checkAndSaveAsync(newRule))
              if(result) {
                await (rclient.hsetAsync(key, "blockin", false))
                log.info("Migrated successfully")
              } else {
                log.error("Failed to migrate")
              }
            }
          }
        })
      }
    })().catch((err) => {
      log.error("Failed to migrate host policy rules:", err, {})
    })
  }

  run() {
    super.run();

    this.listen();

    this.hostPolicyMigration()

    setTimeout(() => {
      this.scheduledJob();
      this.oneTimeJob()
      setInterval(() => {
        this.scheduledJob();
      }, 1000 * 60 * 60); // cleanup every hour
    }, 1000 * 60 * 5); // first time in 5 mins
  }
}

module.exports = OldDataCleanSensor;
<|endoftext|>


<commit_before>const Wasm = require('./wasmAgent')

module.exports = class Test extends Wasm {
  /**
   * Runs the core VM with a given environment and imports
   */
  async run (message, kernel, imports) {
    const responses = this.responses = {}
    /**
     * Builds a import map with an array of given interfaces
     */
    async function buildImports (kernelApi, kernel, imports) {
      const importMap = {}
      for (const Import of imports) {
        const response = responses[Import.name] = {}
        const newIterface = new Import(kernelApi, message, response)
        importMap[Import.name] = newIterface.exports
        // initailize the import
        await newIterface.initialize()
      }
      return importMap
    }

    let instance
    const interfaceApi = this.api = {
      /**
       * adds an aync operation to the operations queue
       */
      pushOpsQueue: (promise, callbackIndex, intefaceCallback) => {
        this._opsQueue = Promise.all([this._opsQueue, promise]).then(values => {
          const result = intefaceCallback(values.pop())
          instance.exports.callback.get(callbackIndex)(result)
        })
      },
      memory: () => {
        return instance.exports.memory.buffer
      },
      kernel: kernel
    }

    const initializedImports = await buildImports(interfaceApi, kernel, imports)
    this.instance = instance = WebAssembly.Instance(this._module, initializedImports)

    if (instance.exports.main) {
      instance.exports.main()
    }
    await this.onDone()
    return responses
  }
}
<commit_msg>remove debugging interface<commit_after><|endoftext|>


<commit_before>
(function () {

  window.choppedjs = {};

  function extend(){
    for(var i=1; i<arguments.length; i++)
    for(var key in arguments[i])
      if(arguments[i].hasOwnProperty(key))
        arguments[0][key] = arguments[i][key];
    return arguments[0];
  }

  choppedjs.onEvent = function (eventType, handler, timeout, config) {
    var defaults = {
      name: 'unnamed',
      immediate: false
    };
    this.options = extend({}, defaults, config);
    this.eventType = eventType;
    this.timeout = timeout;
    this.handler = handler;
    this.isExecuteTime = this.options.immediate;
    this.interval = '';
    var _this = this;
    init();

    function init() {
      //reset the execute determiner
      $(window)[_this.eventType](function () {
        _this.isExecuteTime = true;
      });

      //execute the handler based on the timeout user passed
      _this.interval = setInterval(function () {
        if (_this.isExecuteTime) {
          try {
            handler();
          } catch (err) {
            console.log(err);
          }
          //turn off the exec time until user scroll again
          _this.isExecuteTime = false;
        }
      }, _this.timeout);
    }

  };

  choppedjs.onScroll = function (handler, timeout, options) {
    return new choppedjs.onEvent('scroll', handler, timeout, options);
  };

  choppedjs.onResize = function (handler, timeout, options) {
    return new choppedjs.onEvent('resize', handler, timeout, options);
  };

}());
<commit_msg>mosemove event added<commit_after>
(function () {

  window.choppedjs = {};

  function extend(){
    for(var i=1; i<arguments.length; i++)
    for(var key in arguments[i])
      if(arguments[i].hasOwnProperty(key))
        arguments[0][key] = arguments[i][key];
    return arguments[0];
  }

  choppedjs.onEvent = function (eventType, handler, timeout, config) {
    var defaults = {
      name: 'unnamed',
      immediate: true
    };
    this.options = extend({}, defaults, config);
    this.eventType = eventType;
    this.timeout = timeout;
    this.handler = handler;
    this.isExecuteTime = this.options.immediate;
    this.interval = '';
    var _this = this;
    init();

    function init() {
      //reset the execute determiner
      $(window)[_this.eventType](function () {
        _this.isExecuteTime = true;
      });

      //execute the handler based on the timeout user passed
      _this.interval = setInterval(function () {
        if (_this.isExecuteTime) {
          try {
            handler();
          } catch (err) {
            console.log(err);
          }
          //turn off the exec time until user scroll again
          _this.isExecuteTime = false;
        }
      }, _this.timeout);
    }

  };

  choppedjs.onScroll = function (handler, timeout, options) {
    return new choppedjs.onEvent('scroll', handler, timeout, options);
  };

  choppedjs.onResize = function (handler, timeout, options) {
    return new choppedjs.onEvent('resize', handler, timeout, options);
  };

  choppedjs.onMousemove = function (handler, timeout, options) {
    return new choppedjs.onEvent('mousemove', handler, timeout, options);
  };

}());
<|endoftext|>


<commit_before><commit_msg>Ajuste a index de delivery<commit_after>'use_strict'
var express = require('express');
var controller = require('./delivery.controller');
var router = express.Router();
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: false });

router.post('/', urlencodedParser, controller.postEvento);
module.exports = router;<|endoftext|>


<commit_before>'use strict';

var should = require('should');
var app = require('../../app');
var request = require('supertest');

describe('GET /api/users', function() {

  it('should respond with JSON array', function(done) {
    request(app)
      .get('/api/users/past')
      .expect(200)
      .expect('Content-Type', /json/)
      .end(function(err, res) {
        if (err) return done(err);
        res.body.should.be.instanceof(Array);
        done();
      });
  });
});
<commit_msg>added test to ensure users.past is array<commit_after>'use strict';

var should = require('should');
var app = require('../../app');
var request = require('supertest');

describe('GET /api/users/past', function() {

  it('should respond with JSON array', function(done) {
    request(app)
      .get('/api/users/past')
      .expect(200)
      .expect('Content-Type', /json/)
      .end(function(err, res) {
        if (err) return done(err);
        res.body.should.be.instanceof(Array);
        done();
      });
  });
});
<|endoftext|>