<commit_before>var d3 = require('d3')
  , EventEmitter = require('events').EventEmitter
  , util = require('util')
  , defaults = {
    depth: 20, // indentation depth
    height: 36, // height of each row
    accessors: {
      id: 'id',
      label: 'label',
      icon: 'icon',
      color: 'color'
    }
  }
  , styles = window.getComputedStyle(document.documentElement, '')
  , prefix = Array.prototype.slice.call(styles).join('').match(/-(moz|webkit|ms)-/)[0]
  , resize = require('./lib/resize')

/**
 * Create a new d3 tree with the given config.
 */
var Tree = function (options) {
  if (!options) {
    throw new Error('options are required')
  }
  if (!options.stream) {
    throw new Error('options.stream is required')
  }

  this.options = defaults
  for (var p in options) {
    if (p === 'accessors') {
      for (var pp in options.accessors) {
        this.options.accessors[pp] = options.accessors[pp]
      }
    } else {
      this.options[p] = options[p]
    }
  }

  this.resizer = resize(prefix)

  this.tree = d3.layout.tree()
                       .nodeSize([0, this.options.depth])
}

util.inherits(Tree, EventEmitter)

Tree.prototype.render = function () {
  var self = this

  this.el = d3.select(document.createElement('div'))
              .attr('class', 'tree-container')

  this.node = this.el.append('div')
                       .attr('class', 'tree')
                       .append('ul')
                         .selectAll('li.node')

  this._nodeData = []
  this.options.stream.on('data', function (n) {
    var p = (function (nodes) {
      for (var i = nodes.length - 1; i >= 0; i--) {
        if (nodes[i].id === n.parentId) {
          return nodes[i]
        }
      }
    })(self._nodeData)

    self._nodeData.push(n)
    if (p) {
      n.parent = p
      if (p == self._nodeData[0]) {
        // if parent is the root, then push unto children so it's visible
        (p.children || (p.children = [])).push(n)
        self.draw()
      } else {
        // push to _children so it's hidden, no need to draw
        (p._children || (p._children = [])).push(n)
      }
    } else {
      // root, draw it.
      self.draw()
    }
  })
  .on('end', self.draw.bind(self))

  return this
}

Tree.prototype.resize = function () {
  var box = this.el.select('div.tree').node().parentNode.getBoundingClientRect()
  this.resizer.height(this.options.height)
  this.node.call(this.resizer)
}

Tree.prototype.draw = function (source) {
  var self = this

  this.node = this.node.data(this.tree.nodes(this._nodeData[0]), function (d) {
    return d[self.options.accessors.id]
  })

  var enter = this.node.enter().append('li')
      .attr('class', 'node')
      .on('click', this._onSelect.bind(this))
      .style(prefix + 'transform', function (d) {
        return 'translate(0px,' + (source ? source._y : d.y) + 'px)'
      })
      .style('opacity', 1e-6)

  // Add the node contents
  var contents = enter.append('div')
                        .attr('class', 'node-contents')
                        .attr('style', function (d) {
                          return prefix + 'transform:' + 'translate(' + (d.parent ? d.parent._x : 0) + 'px,0px)'
                        })

  // Add the toggler
  contents.append('div')
          .attr('class', 'toggler')
            .append('svg')
              .append('use')
                .attr('xlink:href', '#icon-collapsed')

  // icon to represent the node tpye
  contents.append('svg')
          .attr('class', 'icon')
            .append('use')

  contents.append('div')
         .attr('class', 'label')

  // Now the indicator light
  enter.append('div')
          .attr('class', 'indicator')

  // Update the color if it changed
  this.node.selectAll('div.indicator')
      .attr('class', function (d) {
        return 'indicator ' + d[self.options.accessors.color]
      })

  // The icon maybe changed
  this.node.selectAll('svg.icon')
           .attr('class', function (d) {
             return 'icon ' + d[self.options.accessors.color]
           })
           .selectAll('use')
            .attr('xlink:href', function (d) {
              return '#icon-' + d[self.options.accessors.icon]
            })

  // change the state of the toggle icon by adjusting its class
  this.node.selectAll('.toggler')
           .attr('class', function (d) {
             return 'toggler ' + (d._children ? 'collapsed' : d.children ? 'expanded' : 'leaf')
           })

  // Perhaps the name changed
  this.node.selectAll('div.label')
            .text(function (d) {
              return d[self.options.accessors.label]
            })

  // if we are manipulating a single node, we may have to adjust selected properties
  if (source) {
    this.node.classed('selected', function (d) {
      return d.selected
    })
  }

  // If this node has been removed, let's remove it.
  var exit = this.node.exit()
  exit.selectAll('div.node-contents')
      .style(prefix + 'transform', function (d) {
        return 'translate(' + d.parent._x + 'px,0px)'
      })

  exit.style(prefix + 'transform', function (d) {
        return 'translate(0px,' + source._y + 'px)'
      })
      .style('opacity', 1e-6)
      .transition()
      .duration(300) // copied in css
      .remove()

  // Now resize things
  this.resize()
}

Tree.prototype.select = function (id, opt) {
  opt = opt || {}
  var d = null
  this._nodeData.some(function (_d) {
    return _d.id == id && (d = _d, true)
  })

  if (d) {
    this._onSelect(d, null, opt)
  }
}

/*
 * Returns the currently selected d3 selection. This is the d3 object that contains
 * the currently selected node. The underlying dom node can be accessed by invoking
 * .node() on the selection.
 *
 * e.g.
 *    tree.getSelected().node()
 */
Tree.prototype.getSelected = function () {
  if (!this._selected) {
    return
  }

  var self = this
  return this.node.filter(function (d) {
    return d == self._selected
  })
}

Tree.prototype._onSelect = function (d, i, opt) {
  opt = opt || {}

  if (!opt.silent) {
    this.emit('select', d)
  }

  // tree_.selected stores a previously selected node
  if (this._selected) {
    // delete the selected field from that node
    delete this._selected.selected
  }
  d.selected = true
  this._selected = d

  if (i === 0) {
    // The root node should just be redrawn. No need to check ancestors or toggle since it's always expanded
    this.draw(d)
    return
  }

  // Make sure all ancestors are visible
  ;(function e (node) {
    if (node._children) {
      node.children = node._children
      node._children = null
    }
    if (node.parent) {
      e(node.parent)
    }
  })(d.parent)

  this.toggle(d)
}

Tree.prototype.editable = function () {
  var t = this.el.select('.tree')
  t.classed('editable', !t.classed('editable'))
}

/*
 * Toggle all isn't necessary the best name, because it doesn't toggle the root node,
 * since the first children are always visible
 */
Tree.prototype._toggleAll = function (fn) {
  for (var i = 1; i < this._nodeData.length; i++) {
    var d = this._nodeData[i]
    fn(d)
  }
  this.draw(this._nodeData[0])
}

Tree.prototype.expandAll = function () {
  this._toggleAll(function (d) {
    if (d._children) {
      d.children = d._children
      d._children = null
    }
  })
}

Tree.prototype.collapseAll = function () {
  this._toggleAll(function (d) {
    if (d.children) {
      d._children = d.children
      d.children = null
    }
  })
}

Tree.prototype.toggle = function (d) {
  if (d.children) {
    d._children = d.children
    d.children = null
  } else {
    d.children = d._children
    d._children = null
  }
  this.draw(d)
  if (d3.event) {
    d3.event.stopPropagation()
  }
}

module.exports = Tree
<commit_msg>Adds tree.get(id) to get node data.<commit_after>var d3 = require('d3')
  , EventEmitter = require('events').EventEmitter
  , util = require('util')
  , defaults = {
    depth: 20, // indentation depth
    height: 36, // height of each row
    accessors: {
      id: 'id',
      label: 'label',
      icon: 'icon',
      color: 'color'
    }
  }
  , styles = window.getComputedStyle(document.documentElement, '')
  , prefix = Array.prototype.slice.call(styles).join('').match(/-(moz|webkit|ms)-/)[0]
  , resize = require('./lib/resize')

/**
 * Create a new d3 tree with the given config.
 */
var Tree = function (options) {
  if (!options) {
    throw new Error('options are required')
  }
  if (!options.stream) {
    throw new Error('options.stream is required')
  }

  this.options = defaults
  for (var p in options) {
    if (p === 'accessors') {
      for (var pp in options.accessors) {
        this.options.accessors[pp] = options.accessors[pp]
      }
    } else {
      this.options[p] = options[p]
    }
  }

  this.resizer = resize(prefix)

  this.tree = d3.layout.tree()
                       .nodeSize([0, this.options.depth])
}

util.inherits(Tree, EventEmitter)

Tree.prototype.render = function () {
  var self = this

  this.el = d3.select(document.createElement('div'))
              .attr('class', 'tree-container')

  this.node = this.el.append('div')
                       .attr('class', 'tree')
                       .append('ul')
                         .selectAll('li.node')

  this._nodeData = []
  this.options.stream.on('data', function (n) {
    var p = (function (nodes) {
      for (var i = nodes.length - 1; i >= 0; i--) {
        if (nodes[i].id === n.parentId) {
          return nodes[i]
        }
      }
    })(self._nodeData)

    self._nodeData.push(n)
    if (p) {
      n.parent = p
      if (p == self._nodeData[0]) {
        // if parent is the root, then push unto children so it's visible
        (p.children || (p.children = [])).push(n)
        self.draw()
      } else {
        // push to _children so it's hidden, no need to draw
        (p._children || (p._children = [])).push(n)
      }
    } else {
      // root, draw it.
      self.draw()
    }
  })
  .on('end', self.draw.bind(self))

  return this
}

Tree.prototype.resize = function () {
  var box = this.el.select('div.tree').node().parentNode.getBoundingClientRect()
  this.resizer.height(this.options.height)
  this.node.call(this.resizer)
}

Tree.prototype.draw = function (source) {
  var self = this

  this.node = this.node.data(this.tree.nodes(this._nodeData[0]), function (d) {
    return d[self.options.accessors.id]
  })

  var enter = this.node.enter().append('li')
      .attr('class', 'node')
      .on('click', this._onSelect.bind(this))
      .style(prefix + 'transform', function (d) {
        return 'translate(0px,' + (source ? source._y : d.y) + 'px)'
      })
      .style('opacity', 1e-6)

  // Add the node contents
  var contents = enter.append('div')
                        .attr('class', 'node-contents')
                        .attr('style', function (d) {
                          return prefix + 'transform:' + 'translate(' + (d.parent ? d.parent._x : 0) + 'px,0px)'
                        })

  // Add the toggler
  contents.append('div')
          .attr('class', 'toggler')
            .append('svg')
              .append('use')
                .attr('xlink:href', '#icon-collapsed')

  // icon to represent the node tpye
  contents.append('svg')
          .attr('class', 'icon')
            .append('use')

  contents.append('div')
         .attr('class', 'label')

  // Now the indicator light
  enter.append('div')
          .attr('class', 'indicator')

  // Update the color if it changed
  this.node.selectAll('div.indicator')
      .attr('class', function (d) {
        return 'indicator ' + d[self.options.accessors.color]
      })

  // The icon maybe changed
  this.node.selectAll('svg.icon')
           .attr('class', function (d) {
             return 'icon ' + d[self.options.accessors.color]
           })
           .selectAll('use')
            .attr('xlink:href', function (d) {
              return '#icon-' + d[self.options.accessors.icon]
            })

  // change the state of the toggle icon by adjusting its class
  this.node.selectAll('.toggler')
           .attr('class', function (d) {
             return 'toggler ' + (d._children ? 'collapsed' : d.children ? 'expanded' : 'leaf')
           })

  // Perhaps the name changed
  this.node.selectAll('div.label')
            .text(function (d) {
              return d[self.options.accessors.label]
            })

  // if we are manipulating a single node, we may have to adjust selected properties
  if (source) {
    this.node.classed('selected', function (d) {
      return d.selected
    })
  }

  // If this node has been removed, let's remove it.
  var exit = this.node.exit()
  exit.selectAll('div.node-contents')
      .style(prefix + 'transform', function (d) {
        return 'translate(' + d.parent._x + 'px,0px)'
      })

  exit.style(prefix + 'transform', function (d) {
        return 'translate(0px,' + source._y + 'px)'
      })
      .style('opacity', 1e-6)
      .transition()
      .duration(300) // copied in css
      .remove()

  // Now resize things
  this.resize()
}

Tree.prototype.select = function (id, opt) {
  opt = opt || {}
  var d = this.get(id)

  if (d) {
    this._onSelect(d, null, opt)
  }
}

/*
 * Returns a node object. This searches all the underlying data, not
 * just the visible nodes
 */
Tree.prototype.get = function (id) {
  var node = null
  this._nodeData.some(function (d) {
    return d.id == id && (node = d, true)
  })
  return node
}

/*
 * Returns the currently selected d3 selection. This is the d3 object that contains
 * the currently selected node. The underlying dom node can be accessed by invoking
 * .node() on the selection.
 *
 * e.g.
 *    tree.getSelected().node()
 */
Tree.prototype.getSelected = function () {
  if (!this._selected) {
    return
  }

  var self = this
  return this.node.filter(function (d) {
    return d == self._selected
  })
}

Tree.prototype._onSelect = function (d, i, opt) {
  opt = opt || {}

  if (!opt.silent) {
    this.emit('select', d)
  }

  // tree_.selected stores a previously selected node
  if (this._selected) {
    // delete the selected field from that node
    delete this._selected.selected
  }
  d.selected = true
  this._selected = d

  if (i === 0) {
    // The root node should just be redrawn. No need to check ancestors or toggle since it's always expanded
    this.draw(d)
    return
  }

  // Make sure all ancestors are visible
  ;(function e (node) {
    if (node._children) {
      node.children = node._children
      node._children = null
    }
    if (node.parent) {
      e(node.parent)
    }
  })(d.parent)

  this.toggle(d)
}

Tree.prototype.editable = function () {
  var t = this.el.select('.tree')
  t.classed('editable', !t.classed('editable'))
}

/*
 * Toggle all isn't necessary the best name, because it doesn't toggle the root node,
 * since the first children are always visible
 */
Tree.prototype._toggleAll = function (fn) {
  for (var i = 1; i < this._nodeData.length; i++) {
    var d = this._nodeData[i]
    fn(d)
  }
  this.draw(this._nodeData[0])
}

Tree.prototype.expandAll = function () {
  this._toggleAll(function (d) {
    if (d._children) {
      d.children = d._children
      d._children = null
    }
  })
}

Tree.prototype.collapseAll = function () {
  this._toggleAll(function (d) {
    if (d.children) {
      d._children = d.children
      d.children = null
    }
  })
}

Tree.prototype.toggle = function (d) {
  if (d.children) {
    d._children = d.children
    d.children = null
  } else {
    d.children = d._children
    d._children = null
  }
  this.draw(d)
  if (d3.event) {
    d3.event.stopPropagation()
  }
}

module.exports = Tree
<|endoftext|>


<commit_before>/*!
 * read-yaml <https://github.com/jonschlinkert/read-yaml>
 *
 * Copyright (c) 2014, 2017, Jon Schlinkert.
 * Released under the MIT License.
 */
'use strict';

var fs = require('fs');
var tryit = require('tryit');
var YAML = require('js-yaml');
var xtend = require('xtend');

/**
 * Expose `read`
 */

module.exports = readYaml;

/**
 * Read YAML file asynchronously and parse content as JSON
 *
 * **Example:**
 *
 * ```js
 * var readYaml = require('read-yaml');
 * readYaml('config.yml', function(err, data) {
 *   if (err) throw err;
 *   console.log(data);
 * });
 * ```
 *
 * @param {String} `fp` Path of the file to read.
 * @param {Object|String} `options` to pass to [js-yaml]
 * @param {Function} `cb` Callback function
 * @return {Object} JSON
 * @api public
 */

function readYaml(fp, options, cb) {
  if (cb === undefined) {
    cb = options;
    options = {};
  }

  fs.readFile(fp, options, function (err, buf) {
    if (err) {
      cb(err);
      return;
    }

    options = createYamlOptions(options, fp);
    var data;

    tryit(function() {
      data = YAML.safeLoad(buf, options);
    }, function(err) {
      if (err) {
        cb(err);
        return;
      }
      cb(null, data);
    });
  });
}

/**
 * Read YAML file synchronously and parse content as JSON
 *
 * **Example:**
 *
 * ```js
 * var read = require('read-yaml');
 * var config = read.sync('config.yml');
 * ```
 *
 * @param {String} `fp` Path of the file to read.
 * @param {Object|String} `options` to pass to [js-yaml]
 * @return {Object} JSON
 * @api public
 */

readYaml.sync = function readYamlSync(fp, options) {
  var str = fs.readFileSync(fp, options);
  options = createYamlOptions(options, fp);
  return YAML.safeLoad(str, options);
};

/**
 * Util to normalize options for js-yaml
 *
 * @api private
 */

function createYamlOptions (options, fp) {
  if (typeof options === 'string') {
    return {filename: fp};
  }
  return xtend(options, {filename: fp});
}
<commit_msg>simplify<commit_after>/*!
 * read-yaml <https://github.com/jonschlinkert/read-yaml>
 *
 * Copyright (c) 2014, 2017, Jon Schlinkert.
 * Released under the MIT License.
 */
'use strict';

var fs = require('fs');
var yaml = require('js-yaml');
var extend = require('extend-shallow');

/**
 * Read yaml file asynchronously and parse content as JSON.
 *
 * ```js
 * var readYaml = require('read-yaml');
 * readYaml('config.yml', function(err, data) {
 *   if (err) throw err;
 *   console.log(data);
 * });
 * ```
 * @param {String} `filepath` Path of the file to read.
 * @param {Object|String} `options` to pass to [js-yaml][]
 * @param {Function} `cb` Callback function `
 * @api public
 */

function readYaml(filepath, options, cb) {
  if (typeof options === 'function') {
    cb = options;
    options = {};
  }

  var opts = extend({}, options, {filename: filepath});

  fs.readFile(filepath, options, function(err, buf) {
    if (err) {
      cb(err);
      return;
    }

    var data;

    try {
      data = yaml.safeLoad(buf, opts);
    } catch (err) {
      cb(err);
      return;
    }

    cb(null, data);
  });
}

/**
 * Read yaml file synchronously and parse content as JSON.
 *
 * ```js
 * var read = require('read-yaml');
 * var config = read.sync('config.yml');
 * ```
 * @param {String} `filepath` Path of the file to read.
 * @param {Object|String} `options` to pass to [js-yaml][].
 * @return {Object} JSON
 * @api public
 */

readYaml.sync = function readYamlSync(filepath, options) {
  var str = fs.readFileSync(filepath, options);
  var opts = extend({}, options, {filename: filepath});
  return yaml.safeLoad(str, opts);
};

/**
 * Expose `readYaml`
 */

module.exports = readYaml;
<|endoftext|>


<commit_before>'use strict';

var through = require('through2'),
    gutil = require('gulp-util'),
    merge = require('merge'),
    debugServer = require('node-inspector/lib/debug-server'),
    Config = require('node-inspector/lib/config'),
    packageJson = require('node-inspector/package.json');

var PluginError = gutil.PluginError;
var config = new Config([]);
var DebugServer = debugServer.DebugServer;
var log = gutil.log, colors = gutil.colors;

var PLUGIN_NAME = 'gulp-node-inspector';

var nodeInspector = function(opt) {

  var options = merge(config, opt);

  var start = function(file, enc, cb) {

    log(PLUGIN_NAME, 'is using node-inspector v' + packageJson.version);

    var debugServer = new DebugServer(options);

    debugServer.on('error', function(err) {

      if (err.code === 'EADDRINUSE') {
        log(colors.red('There is another process already listening at this address.\n' +
          'Change "webPort": {port} to use a different port.'));
      }

      return cb(new PluginError(PLUGIN_NAME, 'Cannot start the server at ' + config.webHost + ':' + config.webPort + '. Error: ' + (err.message || err)));
    });

    debugServer.on('listening', function() {
      log(colors.green('Visit', this.address().url, 'to start debugging.'));
    });

    debugServer.on('close', function() {
      cb(null, file);
    });

    debugServer.start(config);
  }

  return through.obj(start);
};

module.exports = nodeInspector;<commit_msg>throwing an exception might be a better idea<commit_after>'use strict';

var through = require('through2'),
    gutil = require('gulp-util'),
    merge = require('merge'),
    debugServer = require('node-inspector/lib/debug-server'),
    Config = require('node-inspector/lib/config'),
    packageJson = require('node-inspector/package.json');

var PluginError = gutil.PluginError;
var config = new Config([]);
var DebugServer = debugServer.DebugServer;
var log = gutil.log, colors = gutil.colors;

var PLUGIN_NAME = 'gulp-node-inspector';

var nodeInspector = function(opt) {

  var options = merge(config, opt);

  var start = function(file, enc, cb) {

    log(PLUGIN_NAME, 'is using node-inspector v' + packageJson.version);

    var debugServer = new DebugServer(options);

    debugServer.on('error', function(err) {

      if (err.code === 'EADDRINUSE') {
        log(colors.red('There is another process already listening at this address.\n' +
          'Change "webPort": {port} to use a different port.'));
      }

      throw new PluginError(PLUGIN_NAME, 'Cannot start the server at ' + config.webHost + ':' + config.webPort + '. Error: ' + (err.message || err));
    });

    debugServer.on('listening', function() {
      log(colors.green('Visit', this.address().url, 'to start debugging.'));
    });

    debugServer.on('close', function() {
      cb(null, file);
    });

    debugServer.start(config);
  }

  return through.obj(start);
};

module.exports = nodeInspector;<|endoftext|>


<commit_before>"use strict";

var __slice = [].slice;
/*
function die () {
  console.log.apply(console, __slice.call(arguments, 0));
  process.exit(1);
}

function say () { console.log.apply(console, __slice.call(arguments, 0)) }
*/
function extend (object) {
  __slice.call(arguments, 1).forEach(function (append) {
    for (var key in append) if (append.hasOwnProperty(key)) {
      object[key] = append[key];
    }
  });
  return object;
}

function factory () {
  var options = { context: {} };
  __slice.call(arguments, 0).forEach(function (opts) {
    var context = extend({}, options.context, opts.context || {});
    extend(options, opts).context = context;
  });

  return function cadence () {
    var vargs = __slice.call(arguments, 0)
      , steps = []
      , firstSteps = []
      , timer
      , callback
      , called
      , count
      , exitCode = 0
      , methods = { step: async }
      , abended
      , key
      , arg
      , context = {}
      ;

    firstSteps = vargs;

    if (firstSteps.every(function (object) { return typeof object == "object" })) {
      return factory.apply(null, [ options ].concat(firstSteps));
    }

    firstSteps = firstSteps.map(function (step) { return parameterize(step, context) });

    function execute () {
      var vargs = __slice.call(arguments, 0), callbacks = [], callback = exceptional;
      if (vargs.length) {
        callback = vargs.pop();
        callbacks = [{ results: [vargs] }];
      }
      steps = firstSteps.slice(0);
      abended = false;
      invoke(steps, 0, Object.create(options.context), callbacks, callback);
    }

    function exceptional (error) { if (error) throw error }

    // Set and reset a thirty second timeout between assertions.
    function timeout () {
      if (timer) clearTimeout(timer);
      if (options.timeout) timer = setTimeout(function () { callback(new Error("Timeout")) }, options.timeout);
    }

    // **TODO**: To support renentrancy, you need to make this a stack, shift
    // the invocation sturcture onto an array of invocations before calling the
    // step, then shift it off when you're done. I am imagining that this will
    // permit the immediate invocation of a sub-cadence, which may be necessary
    // to support notions like recusive descent of a directory tree.
    var invocation;

    // We give this function to the caller to build control flow. In the
    // debugger, I often want to step into a function that takes a step
    // callback, so I'm often stepping into this function, only to step right
    // back out again. Step out is a two finger chord in the Chrome debugger,
    // but step over is a single function key, so I want to have the option to
    // step over the body of this function, instead of having to find the
    // control key when I'm in it. That is the only reason for the separate
    // async function.

    //
    function async () { return _async.apply(null, arguments) }

    function _async() {
      var vargs = __slice.call(arguments, 0), i = -1, step, original;

      // The caller as invoked the async function directly as an explicit early
      // return to exit the entire cadence.
      if (vargs.length && (vargs[0] == null || vargs[0] instanceof Error)) {
        invocation.count = Number.MAX_VALUE;
        invocation.callback.apply(null, vargs);
        return;
      }

      // If we're called with a single object argument, we merge the given
      // object into the cadence context.
      if (vargs.length == 1 && typeof vargs[0] == "object" && vargs[0] && !Array.isArray(vargs[0])) {
        extend(invocation.context, vargs[0]);
        return;
      }

      // If our first argument is a function, we check to see if it is a jump
      // instruction. If the function is a member of the current cadence, we
      // will inovke that function with the results of this step.

      // Search for the function in the current cadence.
      if (vargs.length == 1 && typeof vargs[0] == "function") {
        original = vargs[0].original || vargs[0];
        for (i = invocation.arguments[0].length - 1; step = invocation.arguments[0][i]; i--) {
          if (original === step || original === step.original) break;
        }
      }

      // If we find the function in the current cadence, we set the index of
      // next step function to execute; then remove the function argument and
      // procede.
      if (~i) {
        invocation.arguments[1] = i;
        vargs.shift();
      }

      var fixup;
      if (fixup = (vargs[0] === async)) {
        vargs.shift();
      }
      if (!isNaN(parseFloat(vargs[0])) && isFinite(vargs[0])) {
        var arity = parseInt(vargs.shift(), 10);
      }
      if (Array.isArray(vargs[0]) && vargs[0].length == 0) {
        var arrayed = !! vargs.shift();
      }
      if (vargs.length && vargs.every(function (arg) { return typeof arg == "function" })) {
        var cadence = vargs.splice(0, vargs.length);
      }

      // If we have no arguments, or else if every argument is a string, then
      // we've been asked to build a callback, otherwise, this is a sub-cadence.

      //
      if (cadence && !fixup) {
        return createCadence(invocation, arity, cadence, arrayed);
      } else {
        if (vargs.length) throw new Error("invalid arguments");
        if (arrayed) {
          return createArray(invocation, arity, cadence);
        } else {
          return createScalar(invocation, arity, cadence);
        }
      }
    }

    function createCadence (invocation, arity, cadence, arrayed) {
      var callback = { results: [], run: ! arrayed, cadence: cadence, arrayed: arrayed }, index = 0;
      if (arity) callback.arity = arity;
      invocation.callbacks.push(callback);
      return function () {
        var vargs = __slice.call(arguments);
        runSubCadence(invocation, callback, index++, [{ results: [vargs] }]);
      }
    }

    function createArray (invocation, arity, cadence) {
      var callback = { results: [], cadence: cadence }, index = 0;
      if (arity) callback.arity = arity;
      callback.arrayed = true;
      invocation.callbacks.push(callback);
      return function () {
        var vargs = __slice.call(arguments);
        if (callback.built) throw new Error("already zero to many");
        if (Array.isArray(vargs[0])) {
          index = -1;
          callback.built = true;
        }
        return createCallback(invocation, callback, index++);
      }
    }

    function createScalar (invocation, arity, cadence) {
      var callback = { results: [], cadence: cadence };
      if (arity) callback.arity = arity;
      invocation.callbacks.push(callback);
      return createCallback(invocation, callback, 0);
    }

    function createCallback (invocation, callback, index) {
      if (-1 < index) invocation.count++;
      return function (error) {
        var vargs = __slice.call(arguments, 1);
        if (error) {
          thrown(invocation, error);
        } else {
          if (index < 0) callback.results.push(vargs);
          else callback.results[index] = vargs;
          if (callback.cadence) {
            invocation.count++;
            var subtext = Object.create(invocation.context);
            var steps = callback.cadence.slice(0).map(function (step) { return parameterize(step, subtext) });
            invoke(steps, 0, subtext, [{ results: [callback.results[index]] }], function (error, result) {
              if (error) {
                thrown(invocation, error);
              } else {
                callback.results[index] = __slice.call(arguments, 1);
              }
              if (-1 < index && ++invocation.called == invocation.count) {
                invoke.apply(null, invocation.arguments);
              }
            });
          }
          // Indicates that the function has completed, so we need create
          // the callbacks for parallel cadences now, the next increment of
          // the called counter, which may be the last.
          if (vargs[0] == invoke) {
            invocation.callbacks.filter(function (callback) { return callback.run }).forEach(function (callback) {
              runSubCadence(invocation, callback, 0, []);
            });
          }
        }
        if (index > -1 && ++invocation.called == invocation.count) {
          invoke.apply(null, invocation.arguments);
        }
      }
    }

    function runSubCadence (invocation, callback, index, vargs) {
      delete callback.run;
      var subtext = Object.create(invocation.context);
      steps = callback.cadence.map(function (step) { return parameterize(step, subtext) });
      invocation.count++;
      invoke(steps, 0, subtext, vargs, function (error) {
        var vargs = __slice.call(arguments, 1);
        if (error) {
          thrown(invocation, error);
        } else {
          callback.results[index] = vargs;
        }
        if (++invocation.called == invocation.count) {
          invoke.apply(null, invocation.arguments);
        }
      });
    }

    function parameterize (step, context) {
      var $ = /^function\s*[^(]*\(([^)]*)\)/.exec(step.toString());
      if (!$) throw new Error("bad function");
      if (step.name) {
        context[step.name] = function () { async(step).apply(null, [ null ].concat(__slice.call(arguments, 0))) }
        context[step.name].original = step;
      }
      step.parameters = $[1].split(/\s*,\s*/);
      if (!step.parameters[0].trim()) step.parameters.shift();
      return step;
    }

    // Test if a program name matches one of our special names. We support
    // Streamline.js by also accepting a function whose name has been mangled in a
    // Streamline.js fashion.

    //
    function named (proc, name) {
      return proc.name == name || (proc.name && !proc.name.indexOf(name + '__'));
    }

    function thrown (invocation, error) {
      var steps = invocation.arguments[0]
        , next = steps[invocation.index + 1]
        ;
      if (next && /^errors?$/.test(next.parameters[0])) {
        invocation.context.errors.push(error);
      } else {
        if (timer) clearTimeout(timer);
        abended = true;
        invocation.callback(error);
      }
    }

    // Parallel arrays make the most sense, really. If the paralleled function
    // is better off returning a map, it can be shimmed.
    function contextualize (step, callbacks, context, ephemeral) {
      var $, names, name, value, index, vargs = [], arg, callback, arity;

      names = step.parameters.slice(0);
      if (~(index = names.indexOf('step')) || ~(index = names.indexOf(options.alias))) {
        names.length = index;
      }

      if (step.name == '_') {
        names.length = 0;
      }

      if (!names.length) return;

      arg = 0;
      while (callbacks.length) {
        callback = callbacks.shift();
        if (callback.arrayed) {
          callback.results = callback.results.filter(function (vargs) { return vargs.length });
        }
        if ('arity' in callback) {
          arity = callback.arity;
        } else {
          arity = callback.arrayed ? 1 : 0;
          callback.results.forEach(function (result) {
            arity = Math.max(arity, result.length);
          });
        }
        for (index = 0; index < arity; index++) {
          vargs.push({ values: [],
                       arrayed: ('arrayed' in callback) ? callback.arrayed : callback.results.length > 1 });
        }
        callback.results.forEach(function (result) {
          for (var i = 0; i < arity; i++) {
            vargs[arg + i].values.push(result[i]);
          }
        });
        arg += arity;
      }

      while (names.length) {
        name = names.shift();
        if ($ = /^\$vargs(?:\$(\d+))?$/.exec(name)) {
          ephemeral[name] = vargs.splice(0, vargs.length - (+($[1] || 0)))
                                 .map(function (varg) {
                                    return varg.arrayed ? varg.values : varg.values.shift()
                                 });
        } else {
          if (vargs.length) {
            value = vargs.shift();
            value = value.arrayed ? value.values : value.values.shift();
          } else {
            break;
          }
          (name[0] == '$' ? ephemeral : context)[name] = value;
        }
      }
    }

    function invoke (steps, index, context, callbacks, callback) {
      var arg
        , args = []
        , match
        , parameter, parameters
        , i, I
        , calledback
        , step, key, next
        , leaked
        , result
        , value
        , names
        , result
        , hold
        , ephemeral = {}
        ;

      if (abended) return;

      timeout();

      invocation = { callbacks: [], count: 0 , called: 0, context: context,
                     index: index, callback: callback };
      invocation.arguments = [ steps, index + 1, context, invocation.callbacks, callback ]

      if (steps[index] && /^errors?$/.test(steps[index].parameters[0]) && !context.errors.length) {
        invoke(steps, index + 1, context, callbacks, callback);
      } else {
        // No callbacks means that we use the function return value, if any.
        if (callbacks.length == 1) {
          if (callbacks[0].results[0][0] === invoke) {
            callbacks[0].results[0].shift()
          }
          if (!callbacks[0].results[0].length) {
            callbacks.shift();
          }
        } else {
          callbacks = callbacks.filter(function (callback) {
            return !callback.results.length || callback.results[0][0] !== invoke
          });
        }

        if (steps.length == index) {
          callback.apply(null, [ null ].concat(callbacks.length == 1 ? callbacks[0].results[0] : []));
          return;
        }

        // Get the next step.
        step = steps[index];

        // Filter out the return value, if there are callbacks left, then
        // `contextualize` will process them.
        if (callbacks.length) {
          contextualize(step, callbacks, context, ephemeral);
        }

        // Give our creator a chance to inspect the step, possibly wrap it.
        Object.keys(options.wrap || {})
          .filter(function (name) { return named(step, name) && name })
          .map(function (name) { return options.wrap[name] })
          .forEach(function (wrapper) {
            var parameters = step.parameters, original = step.original || step;
            step = wrapper(step)
            step.parameters = parameters;
            step.original = original;
          });

        step.parameters.forEach(function (parameter) {
          if (parameter == options.alias) {
            parameter = 'step';
          }
          if (parameter == "error") {
            arg = context.errors[0];
          } else if ((arg = context[parameter]) === void(0)) {
            if ((arg = ephemeral[parameter]) === void(0)) arg = methods[parameter];
          }
          args.push(arg);
        });

        context.errors = [];

        try {
          hold = async();
          result = step.apply(null, args);
          hold.apply(null, [ null, invoke ].concat(result === void(0) ? [] : [ result ]));
        } catch (error) {
          thrown(invocation, error);
          invocation.count++;  // Don't trigger, we do it ourselves next.
          hold.apply(null, [ null, invoke ]);
          invoke.apply(null, invocation.arguments);
        }
      }
    }

    return execute;
  }
}

module.exports = factory();
<commit_msg>Remove underscore to indicate zero arity.<commit_after>"use strict";

var __slice = [].slice;
/*
function die () {
  console.log.apply(console, __slice.call(arguments, 0));
  process.exit(1);
}

function say () { console.log.apply(console, __slice.call(arguments, 0)) }
*/
function extend (object) {
  __slice.call(arguments, 1).forEach(function (append) {
    for (var key in append) if (append.hasOwnProperty(key)) {
      object[key] = append[key];
    }
  });
  return object;
}

function factory () {
  var options = { context: {} };
  __slice.call(arguments, 0).forEach(function (opts) {
    var context = extend({}, options.context, opts.context || {});
    extend(options, opts).context = context;
  });

  return function cadence () {
    var vargs = __slice.call(arguments, 0)
      , steps = []
      , firstSteps = []
      , timer
      , callback
      , called
      , count
      , exitCode = 0
      , methods = { step: async }
      , abended
      , key
      , arg
      , context = {}
      ;

    firstSteps = vargs;

    if (firstSteps.every(function (object) { return typeof object == "object" })) {
      return factory.apply(null, [ options ].concat(firstSteps));
    }

    firstSteps = firstSteps.map(function (step) { return parameterize(step, context) });

    function execute () {
      var vargs = __slice.call(arguments, 0), callbacks = [], callback = exceptional;
      if (vargs.length) {
        callback = vargs.pop();
        callbacks = [{ results: [vargs] }];
      }
      steps = firstSteps.slice(0);
      abended = false;
      invoke(steps, 0, Object.create(options.context), callbacks, callback);
    }

    function exceptional (error) { if (error) throw error }

    // Set and reset a thirty second timeout between assertions.
    function timeout () {
      if (timer) clearTimeout(timer);
      if (options.timeout) timer = setTimeout(function () { callback(new Error("Timeout")) }, options.timeout);
    }

    // **TODO**: To support renentrancy, you need to make this a stack, shift
    // the invocation sturcture onto an array of invocations before calling the
    // step, then shift it off when you're done. I am imagining that this will
    // permit the immediate invocation of a sub-cadence, which may be necessary
    // to support notions like recusive descent of a directory tree.
    var invocation;

    // We give this function to the caller to build control flow. In the
    // debugger, I often want to step into a function that takes a step
    // callback, so I'm often stepping into this function, only to step right
    // back out again. Step out is a two finger chord in the Chrome debugger,
    // but step over is a single function key, so I want to have the option to
    // step over the body of this function, instead of having to find the
    // control key when I'm in it. That is the only reason for the separate
    // async function.

    //
    function async () { return _async.apply(null, arguments) }

    function _async() {
      var vargs = __slice.call(arguments, 0), i = -1, step, original;

      // The caller as invoked the async function directly as an explicit early
      // return to exit the entire cadence.
      if (vargs.length && (vargs[0] == null || vargs[0] instanceof Error)) {
        invocation.count = Number.MAX_VALUE;
        invocation.callback.apply(null, vargs);
        return;
      }

      // If we're called with a single object argument, we merge the given
      // object into the cadence context.
      if (vargs.length == 1 && typeof vargs[0] == "object" && vargs[0] && !Array.isArray(vargs[0])) {
        extend(invocation.context, vargs[0]);
        return;
      }

      // If our first argument is a function, we check to see if it is a jump
      // instruction. If the function is a member of the current cadence, we
      // will inovke that function with the results of this step.

      // Search for the function in the current cadence.
      if (vargs.length == 1 && typeof vargs[0] == "function") {
        original = vargs[0].original || vargs[0];
        for (i = invocation.arguments[0].length - 1; step = invocation.arguments[0][i]; i--) {
          if (original === step || original === step.original) break;
        }
      }

      // If we find the function in the current cadence, we set the index of
      // next step function to execute; then remove the function argument and
      // procede.
      if (~i) {
        invocation.arguments[1] = i;
        vargs.shift();
      }

      var fixup;
      if (fixup = (vargs[0] === async)) {
        vargs.shift();
      }
      if (!isNaN(parseFloat(vargs[0])) && isFinite(vargs[0])) {
        var arity = parseInt(vargs.shift(), 10);
      }
      if (Array.isArray(vargs[0]) && vargs[0].length == 0) {
        var arrayed = !! vargs.shift();
      }
      if (vargs.length && vargs.every(function (arg) { return typeof arg == "function" })) {
        var cadence = vargs.splice(0, vargs.length);
      }

      // If we have no arguments, or else if every argument is a string, then
      // we've been asked to build a callback, otherwise, this is a sub-cadence.

      //
      if (cadence && !fixup) {
        return createCadence(invocation, arity, cadence, arrayed);
      } else {
        if (vargs.length) throw new Error("invalid arguments");
        if (arrayed) {
          return createArray(invocation, arity, cadence);
        } else {
          return createScalar(invocation, arity, cadence);
        }
      }
    }

    function createCadence (invocation, arity, cadence, arrayed) {
      var callback = { results: [], run: ! arrayed, cadence: cadence, arrayed: arrayed }, index = 0;
      if (arity) callback.arity = arity;
      invocation.callbacks.push(callback);
      return function () {
        var vargs = __slice.call(arguments);
        runSubCadence(invocation, callback, index++, [{ results: [vargs] }]);
      }
    }

    function createArray (invocation, arity, cadence) {
      var callback = { results: [], cadence: cadence }, index = 0;
      if (arity) callback.arity = arity;
      callback.arrayed = true;
      invocation.callbacks.push(callback);
      return function () {
        var vargs = __slice.call(arguments);
        if (callback.built) throw new Error("already zero to many");
        if (Array.isArray(vargs[0])) {
          index = -1;
          callback.built = true;
        }
        return createCallback(invocation, callback, index++);
      }
    }

    function createScalar (invocation, arity, cadence) {
      var callback = { results: [], cadence: cadence };
      if (arity) callback.arity = arity;
      invocation.callbacks.push(callback);
      return createCallback(invocation, callback, 0);
    }

    function createCallback (invocation, callback, index) {
      if (-1 < index) invocation.count++;
      return function (error) {
        var vargs = __slice.call(arguments, 1);
        if (error) {
          thrown(invocation, error);
        } else {
          if (index < 0) callback.results.push(vargs);
          else callback.results[index] = vargs;
          if (callback.cadence) {
            invocation.count++;
            var subtext = Object.create(invocation.context);
            var steps = callback.cadence.slice(0).map(function (step) { return parameterize(step, subtext) });
            invoke(steps, 0, subtext, [{ results: [callback.results[index]] }], function (error, result) {
              if (error) {
                thrown(invocation, error);
              } else {
                callback.results[index] = __slice.call(arguments, 1);
              }
              if (-1 < index && ++invocation.called == invocation.count) {
                invoke.apply(null, invocation.arguments);
              }
            });
          }
          // Indicates that the function has completed, so we need create
          // the callbacks for parallel cadences now, the next increment of
          // the called counter, which may be the last.
          if (vargs[0] == invoke) {
            invocation.callbacks.filter(function (callback) { return callback.run }).forEach(function (callback) {
              runSubCadence(invocation, callback, 0, []);
            });
          }
        }
        if (index > -1 && ++invocation.called == invocation.count) {
          invoke.apply(null, invocation.arguments);
        }
      }
    }

    function runSubCadence (invocation, callback, index, vargs) {
      delete callback.run;
      var subtext = Object.create(invocation.context);
      steps = callback.cadence.map(function (step) { return parameterize(step, subtext) });
      invocation.count++;
      invoke(steps, 0, subtext, vargs, function (error) {
        var vargs = __slice.call(arguments, 1);
        if (error) {
          thrown(invocation, error);
        } else {
          callback.results[index] = vargs;
        }
        if (++invocation.called == invocation.count) {
          invoke.apply(null, invocation.arguments);
        }
      });
    }

    function parameterize (step, context) {
      var $ = /^function\s*[^(]*\(([^)]*)\)/.exec(step.toString());
      if (!$) throw new Error("bad function");
      if (step.name) {
        context[step.name] = function () { async(step).apply(null, [ null ].concat(__slice.call(arguments, 0))) }
        context[step.name].original = step;
      }
      step.parameters = $[1].split(/\s*,\s*/);
      if (!step.parameters[0].trim()) step.parameters.shift();
      return step;
    }

    // Test if a program name matches one of our special names. We support
    // Streamline.js by also accepting a function whose name has been mangled in a
    // Streamline.js fashion.

    //
    function named (proc, name) {
      return proc.name == name || (proc.name && !proc.name.indexOf(name + '__'));
    }

    function thrown (invocation, error) {
      var steps = invocation.arguments[0]
        , next = steps[invocation.index + 1]
        ;
      if (next && /^errors?$/.test(next.parameters[0])) {
        invocation.context.errors.push(error);
      } else {
        if (timer) clearTimeout(timer);
        abended = true;
        invocation.callback(error);
      }
    }

    // Parallel arrays make the most sense, really. If the paralleled function
    // is better off returning a map, it can be shimmed.
    function contextualize (step, callbacks, context, ephemeral) {
      var $, names, name, value, index, vargs = [], arg, callback, arity;

      names = step.parameters.slice(0);
      if (~(index = names.indexOf('step')) || ~(index = names.indexOf(options.alias))) {
        names.length = index;
      }

      if (!names.length) return;

      arg = 0;
      while (callbacks.length) {
        callback = callbacks.shift();
        if (callback.arrayed) {
          callback.results = callback.results.filter(function (vargs) { return vargs.length });
        }
        if ('arity' in callback) {
          arity = callback.arity;
        } else {
          arity = callback.arrayed ? 1 : 0;
          callback.results.forEach(function (result) {
            arity = Math.max(arity, result.length);
          });
        }
        for (index = 0; index < arity; index++) {
          vargs.push({ values: [],
                       arrayed: ('arrayed' in callback) ? callback.arrayed : callback.results.length > 1 });
        }
        callback.results.forEach(function (result) {
          for (var i = 0; i < arity; i++) {
            vargs[arg + i].values.push(result[i]);
          }
        });
        arg += arity;
      }

      while (names.length) {
        name = names.shift();
        if ($ = /^\$vargs(?:\$(\d+))?$/.exec(name)) {
          ephemeral[name] = vargs.splice(0, vargs.length - (+($[1] || 0)))
                                 .map(function (varg) {
                                    return varg.arrayed ? varg.values : varg.values.shift()
                                 });
        } else {
          if (vargs.length) {
            value = vargs.shift();
            value = value.arrayed ? value.values : value.values.shift();
          } else {
            break;
          }
          (name[0] == '$' ? ephemeral : context)[name] = value;
        }
      }
    }

    function invoke (steps, index, context, callbacks, callback) {
      var arg
        , args = []
        , match
        , parameter, parameters
        , i, I
        , calledback
        , step, key, next
        , leaked
        , result
        , value
        , names
        , result
        , hold
        , ephemeral = {}
        ;

      if (abended) return;

      timeout();

      invocation = { callbacks: [], count: 0 , called: 0, context: context,
                     index: index, callback: callback };
      invocation.arguments = [ steps, index + 1, context, invocation.callbacks, callback ]

      if (steps[index] && /^errors?$/.test(steps[index].parameters[0]) && !context.errors.length) {
        invoke(steps, index + 1, context, callbacks, callback);
      } else {
        // No callbacks means that we use the function return value, if any.
        if (callbacks.length == 1) {
          if (callbacks[0].results[0][0] === invoke) {
            callbacks[0].results[0].shift()
          }
          if (!callbacks[0].results[0].length) {
            callbacks.shift();
          }
        } else {
          callbacks = callbacks.filter(function (callback) {
            return !callback.results.length || callback.results[0][0] !== invoke
          });
        }

        if (steps.length == index) {
          callback.apply(null, [ null ].concat(callbacks.length == 1 ? callbacks[0].results[0] : []));
          return;
        }

        // Get the next step.
        step = steps[index];

        // Filter out the return value, if there are callbacks left, then
        // `contextualize` will process them.
        if (callbacks.length) {
          contextualize(step, callbacks, context, ephemeral);
        }

        // Give our creator a chance to inspect the step, possibly wrap it.
        Object.keys(options.wrap || {})
          .filter(function (name) { return named(step, name) && name })
          .map(function (name) { return options.wrap[name] })
          .forEach(function (wrapper) {
            var parameters = step.parameters, original = step.original || step;
            step = wrapper(step)
            step.parameters = parameters;
            step.original = original;
          });

        step.parameters.forEach(function (parameter) {
          if (parameter == options.alias) {
            parameter = 'step';
          }
          if (parameter == "error") {
            arg = context.errors[0];
          } else if ((arg = context[parameter]) === void(0)) {
            if ((arg = ephemeral[parameter]) === void(0)) arg = methods[parameter];
          }
          args.push(arg);
        });

        context.errors = [];

        try {
          hold = async();
          result = step.apply(null, args);
          hold.apply(null, [ null, invoke ].concat(result === void(0) ? [] : [ result ]));
        } catch (error) {
          thrown(invocation, error);
          invocation.count++;  // Don't trigger, we do it ourselves next.
          hold.apply(null, [ null, invoke ]);
          invoke.apply(null, invocation.arguments);
        }
      }
    }

    return execute;
  }
}

module.exports = factory();
<|endoftext|>


<commit_before>var http = require('http');
var https = require('https');
var through = require('through');
var parseArgs = require('./lib/parse_args.js');
var insert = require('./lib/insert');
var nextTick = typeof setImmediate !== 'undefined'
    ? setImmediate
    : process.nextTick
;

module.exports = function (opts, cb) {
    if (typeof opts === 'function') {
        cb = opts;
        opts = {};
    }
    if (!opts) opts = {};
    if (typeof opts === 'object' && opts.listen) opts = { server: opts };

    var ssl = Boolean(opts.key && opts.cert);
    var connectionEvent = ssl ? 'secureConnection' : 'connection';

    var server = opts.server || (ssl
        ? https.createServer(opts)
        : http.createServer()
    );
    server.on(connectionEvent, function (stream) {
        var src = stream._bouncyStream = through();
        src.pause();
        stream.pipe(src);
    });

    server.on('upgrade', onrequest);
    server.on('request', onrequest);
    return server;

    function onrequest (req, res) {
        var src = req.connection._bouncyStream;
        var bounce = function (dst) {
            var args = {};
            if (!dst || typeof dst.pipe !== 'function') {
                args = parseArgs(arguments);
                dst = args.stream;
            }
            if (!dst) dst = through();

            function destroy () {
                src.destroy();
                dst.destroy();
            }
            src.on('error', destroy);
            dst.on('error', destroy);

            var s = args.headers || args.method || args.path
                ? src.pipe(insert(args))
                : src
            ;
            s.pipe(dst).pipe(req.connection);

            nextTick(function () { src.resume() });
            return dst;
        };

        if (cb.length === 2) cb(req, bounce)
        else cb(req, res, bounce)
    }
};
<commit_msg>all tests now pass on 0.8 with stealthBuffer() hack<commit_after>var http = require('http');
var https = require('https');
var through = require('through');
var parseArgs = require('./lib/parse_args.js');
var insert = require('./lib/insert');
var nextTick = typeof setImmediate !== 'undefined'
    ? setImmediate
    : process.nextTick
;

module.exports = function (opts, cb) {
    if (typeof opts === 'function') {
        cb = opts;
        opts = {};
    }
    if (!opts) opts = {};
    if (typeof opts === 'object' && opts.listen) opts = { server: opts };

    var ssl = Boolean(opts.key && opts.cert);
    var connectionEvent = ssl ? 'secureConnection' : 'connection';

    var server = opts.server || (ssl
        ? https.createServer(opts)
        : http.createServer()
    );
    server.on(connectionEvent, function (stream) {
        var buffer = [];
        var src = stream._bouncyStream = stealthBuffer();
        stream.pipe(src);
    });

    server.on('upgrade', onrequest);
    server.on('request', onrequest);
    return server;

    function onrequest (req, res) {
        var src = req.connection._bouncyStream;
        var bounce = function (dst) {
            var args = {};
            if (!dst || typeof dst.pipe !== 'function') {
                args = parseArgs(arguments);
                dst = args.stream;
            }
            if (!dst) dst = through();

            function destroy () {
                src.destroy();
                dst.destroy();
            }
            src.on('error', destroy);
            dst.on('error', destroy);

            var s = args.headers || args.method || args.path
                ? src.pipe(insert(args))
                : src
            ;
            s.pipe(dst).pipe(req.connection);

            nextTick(function () { src._resume() });
            return dst;
        };

        if (cb.length === 2) cb(req, bounce)
        else cb(req, res, bounce)
    }
};

function stealthBuffer () {
    // the raw_ok test doesn't pass without this shim
    // instead of just using through()

    var tr = through(write, end);
    var buffer = [];
    tr._resume = function () {
        buffer.forEach(tr.queue.bind(tr));
        buffer = undefined;
    };
    return tr;

    function write (buf) {
        if (buffer) buffer.push(buf)
        else this.queue(buf)
    }
    function end () {
        if (buffer) buffer.push(null)
        else this.queue(null)
    }
}
<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict';

function exec (command) {
  return require('child_process').execSync(command).toString();
}

function luckyCommit (desiredString) {
  if (!/^[0-9a-f]{1,40}$/.test(desiredString)) {
    throw new TypeError('Invalid input provided. (If an input is provided, it must be a hex string.)');
  }
  const lastCommit = exec('git cat-file commit head');
  const previousDate = exec('git --no-pager show -s --oneline --format="%cd" head');
  const previousMessage = exec('git --no-pager show -s --oneline --format="%B" head').slice(0, -2);
  let currentStr = lastCommit;
  let counter = 0;
  let whitespace = '';
  do {
    whitespace = (++counter).toString(2).replace(/0/g, ' ').replace(/1/g, '\t');
    const strWithNewMessage = lastCommit.slice(0, -1) + whitespace + '\n';
    currentStr = 'commit ' + strWithNewMessage.length + '\u0000' + strWithNewMessage;
  } while (!require('crypto').createHash('sha1').update(currentStr).digest('hex').startsWith(desiredString))
  exec('GIT_COMMITTER_DATE="' + previousDate + '" git commit --amend --cleanup=verbatim -m \'' + previousMessage.replace(/'/g, "'\"'\"'") + whitespace + "'");
}

luckyCommit(process.argv[2] || '0000000');
<commit_msg>Use \x00 instead of \u0000 for null character	    	  	  				 		  		     	<commit_after>#!/usr/bin/env node
'use strict';

function exec (command) {
  return require('child_process').execSync(command).toString();
}

function luckyCommit (desiredString) {
  if (!/^[0-9a-f]{1,40}$/.test(desiredString)) {
    throw new TypeError('Invalid input provided. (If an input is provided, it must be a hex string.)');
  }
  const lastCommit = exec('git cat-file commit head');
  const previousDate = exec('git --no-pager show -s --oneline --format="%cd" head');
  const previousMessage = exec('git --no-pager show -s --oneline --format="%B" head').slice(0, -2);
  let currentStr = lastCommit;
  let counter = 0;
  let whitespace = '';
  do {
    whitespace = (++counter).toString(2).replace(/0/g, ' ').replace(/1/g, '\t');
    const strWithNewMessage = lastCommit.slice(0, -1) + whitespace + '\n';
    currentStr = 'commit ' + strWithNewMessage.length + '\x00' + strWithNewMessage;
  } while (!require('crypto').createHash('sha1').update(currentStr).digest('hex').startsWith(desiredString))
  exec('GIT_COMMITTER_DATE="' + previousDate + '" git commit --amend --cleanup=verbatim -m \'' + previousMessage.replace(/'/g, "'\"'\"'") + whitespace + "'");
}

luckyCommit(process.argv[2] || '0000000');
<|endoftext|>


<commit_before>'use strict';

var path = require('path');
var util = require('util');
var defaults = require('object.defaults');
var delegate = require('delegate-properties');
var extend = require('extend-shallow');
var pascal = require('pascalcase');
var lazy = require('lazy-cache')(require);

/**
 * Lazily required module dependencies
 */

lazy('through2', 'through');
lazy('template-config', 'config');
lazy('parser-front-matter', 'matter');
lazy('vinyl-fs', 'vfs');
lazy('vinyl', 'Vinyl');
lazy('to-vinyl');
lazy('dest');

/**
 * Extend `Assemble`
 */

// var Boilerplate = lazy('boilerplate');
// var Generate = lazy('generate');
// var Scaffold = lazy('scaffold');
var Composer = require('composer');
var Template = require('template');
// var Snippet = lazy('snippet');

/**
 * Create an instance of `Assemble` with the given `options`.
 *
 * ```js
 * var Assemble = require('assemble');
 * var app = new Assemble();
 * ```
 *
 * @param {Object} `options`
 * @api public
 */

function Assemble(options) {
  if (!(this instanceof Assemble)) {
    return new Assemble(options);
  }
  Template.apply(this, arguments);
  Composer.call(this, 'assemble');
}

Template.extend(Assemble);
extend(Assemble.prototype, Composer.prototype);

/**
 * Default configuration
 */

delegate(Assemble.prototype, {
  constructor: Assemble,

  defaultConfig: function() {
    this.mixin('config', lazy.config(this));

    var exts = ['hbs', 'html', 'md'];
    this.engine(exts, require('engine-handlebars'));

    this.onLoad(/\.(hbs|md|html)$/, function (view, next) {
      lazy.matter.parse(view, next);
    });

    this.preLayout(/./, function (view, next) {
      if (/\.(hbs|md|html)$/.test(view.path)) {
        if (!view.layout) view.layout = view.locals.layout;
        if (!view.layout) view.layout = view.data.layout;
      } else {
        view.layout = null;
      }
      next();
    });

    this.preRender(/\.(hbs|md|html)$/, function (view, next) {
      extend(view.data, view.parsePath())
    });

    this.create('partials', {
      viewType: ['partial'],
      renameKey: function (fp) {
        return path.basename(fp, path.extname(fp));
      }
    });

    this.create('layouts', {
      viewType: ['layout'],
      renameKey: function (fp) {
        return path.basename(fp, path.extname(fp));
      }
    });

    this.create('pages', {
      renameKey: function (fp) {
        return fp;
      }
    });

    this.loaded = true;
  },

  // boilerplate: function (name, config) {
  //   this.boilerplates[name] = new Boilerplate(config);
  //   return this;
  // },

  // scaffold: function (name, config) {
  //   this.scaffolds[name] = new Scaffold(config);
  //   return this;
  // },

  // snippet: function (name, config) {
  //   this.snippets[name] = new Snippet(config);
  //   return this;
  // },

  /**
   * Glob patterns or filepaths to source files.
   *
   * ```js
   * app.src('src/*.hbs', {layout: 'default'});
   * ```
   *
   * @param {String|Array} `glob` Glob patterns or file paths to source files.
   * @param {Object} `options` Options or locals to merge into the context and/or pass to `src` plugins
   * @api public
   */

  src: function (glob, options) {
    if (!this.loaded) this.defaultConfig();
    this.files(glob, options);
    var stream = this.toStream('files');
    process.nextTick(function () {
      stream.end();
    });
    return stream;
  },

  /**
   * Specify a destination for processed files.
   *
   * ```js
   * app.dest('dist/');
   * ```
   *
   * @param {String|Function} `dest` File path or rename function.
   * @param {Object} `options` Options and locals to pass to `dest` plugins
   * @api public
   */

  dest: function (/*dest, options*/) {
    return lazy.dest.apply(lazy.dest, arguments);
  },

  task: function (name) {
    var task = Composer.prototype.task;
    if (!this.loaded) this.defaultConfig();
    var key = 'task_' + name;
    this.create(key, {
      renameKey: function (fp) {
        return fp;
      }
    });
    return task.apply(this, arguments);
  },

  /**
   * Copy files with the given glob `patterns` to the specified `destDir`.
   *
   * ```js
   * app.task('assets', function() {
   *   app.copy('assets/**', 'dist/');
   * });
   * ```
   *
   * @param {String|Array} `patterns` Glob patterns of files to copy.
   * @param  {String|Function} `destDir` Desination directory.
   * @return {Stream} Stream, to continue processing if necessary.
   * @api public
   */

  copy: function(patterns, destDir, opts) {
    return lazy.vfs.src(patterns, opts)
      .pipe(lazy.vfs.dest(destDir, opts));
  },

  /**
   * Push a view collection into a vinyl stream.
   *
   * @param {String} `plural`
   * @param {Object} `locals`
   * @return {Stream}
   * @api public
   */

  toStream: function (plural, locals) {
    var views = this.views[plural] || {};
    return lazy.through.obj(function (file, enc, cb) {
      this.push(file);
      return cb();
    }, function (cb) {
      Object.keys(views).forEach(function (key) {
        var view = views[key];
        var file = lazy.toVinyl(view);
        this.push(file);
      }.bind(this));
      cb();
    });
  },

  taskName: function () {
    var task = this.session.get('task');
    return (task ? 'task_' + task.name : 'file');
  },

  /**
   * Render a vinyl file.
   *
   * @param  {Object} file
   * @param  {Function} cb Callback
   * @return {Object}
   * @api public
   */

  renderFile: function (locals) {
    var File = this.get(pascal(this.taskName()));
    var self = this;

    return lazy.through.obj(function (file, enc, cb) {
      if (typeof locals === 'function') {
        cb = locals;
        locals = {};
      }

      self.render(new File(file), locals, function (err, res) {
        if (err) return cb(err);
        res.contents = new Buffer(res.content);
        file = new lazy.Vinyl(res);
        cb(null, file);
      });
    });
  }
});

/**
 * Static method for allowing other classes to inherit
 * both prototype and static methods from `Assemble`.
 *
 * ```js
 * function MyApp(options) {...}
 * Assemble.extend(MyApp);
 * ```
 *
 * @param  {Object} `Ctor` Constructor function to extend with `Assemble`
 * @return {undefined}
 * @api public
 */

Assemble.extend = function(Ctor) {
  util.inherits(Ctor, Assemble);
  delegate(Ctor, Assemble);
};

/**
 * Expose an instance of `Assemble`
 */

module.exports = new Assemble();

/**
 * Allow users to instantiate `Assemble`.
 */

module.exports.Assemble = Assemble;
<commit_msg>using session-cache to pick the correct view collection<commit_after>'use strict';

var path = require('path');
var util = require('util');
var defaults = require('object.defaults');
var delegate = require('delegate-properties');
var extend = require('extend-shallow');
var pascal = require('pascalcase');
var lazy = require('lazy-cache')(require);

/**
 * Lazily required module dependencies
 */

lazy('through2', 'through');
lazy('template-config', 'config');
lazy('parser-front-matter', 'matter');
lazy('vinyl-fs', 'vfs');
lazy('vinyl', 'Vinyl');
lazy('to-vinyl');
lazy('dest');

/**
 * Extend `Assemble`
 */

// var Boilerplate = lazy('boilerplate');
// var Generate = lazy('generate');
// var Scaffold = lazy('scaffold');
var Composer = require('composer');
var Template = require('template');
// var Snippet = lazy('snippet');

/**
 * Create an instance of `Assemble` with the given `options`.
 *
 * ```js
 * var Assemble = require('assemble');
 * var app = new Assemble();
 * ```
 *
 * @param {Object} `options`
 * @api public
 */

function Assemble(options) {
  if (!(this instanceof Assemble)) {
    return new Assemble(options);
  }
  Template.apply(this, arguments);
  Composer.call(this, 'assemble');
}

Template.extend(Assemble);
extend(Assemble.prototype, Composer.prototype);

/**
 * Default configuration
 */

delegate(Assemble.prototype, {
  constructor: Assemble,

  defaultConfig: function() {
    this.mixin('config', lazy.config(this));

    var exts = ['hbs', 'html', 'md'];
    this.engine(exts, require('engine-handlebars'));

    this.onLoad(/\.(hbs|md|html)$/, function (view, next) {
      lazy.matter.parse(view, next);
    });

    this.preLayout(/./, function (view, next) {
      if (/\.(hbs|md|html)$/.test(view.path)) {
        if (!view.layout) view.layout = view.locals.layout;
        if (!view.layout) view.layout = view.data.layout;
      } else {
        view.layout = null;
      }
      next();
    });

    this.preRender(/\.(hbs|md|html)$/, function (view, next) {
      extend(view.data, view.parsePath())
    });

    this.create('partials', {
      viewType: ['partial'],
      renameKey: function (fp) {
        return path.basename(fp, path.extname(fp));
      }
    });

    this.create('layouts', {
      viewType: ['layout'],
      renameKey: function (fp) {
        return path.basename(fp, path.extname(fp));
      }
    });

    this.create('pages', {
      renameKey: function (fp) {
        return fp;
      }
    });

    this.loaded = true;
  },

  // boilerplate: function (name, config) {
  //   this.boilerplates[name] = new Boilerplate(config);
  //   return this;
  // },

  // scaffold: function (name, config) {
  //   this.scaffolds[name] = new Scaffold(config);
  //   return this;
  // },

  // snippet: function (name, config) {
  //   this.snippets[name] = new Snippet(config);
  //   return this;
  // },

  /**
   * Glob patterns or filepaths to source files.
   *
   * ```js
   * app.src('src/*.hbs', {layout: 'default'});
   * ```
   *
   * @param {String|Array} `glob` Glob patterns or file paths to source files.
   * @param {Object} `options` Options or locals to merge into the context and/or pass to `src` plugins
   * @api public
   */

  src: function (glob, options) {
    if (!this.loaded) this.defaultConfig();
    var name = this.taskName();
    // TODO: should template use camelcase?
    this[name](glob, options);
    var stream = this.toStream(name);
    process.nextTick(function () {
      stream.end();
    });
    return stream;
  },

  /**
   * Specify a destination for processed files.
   *
   * ```js
   * app.dest('dist/');
   * ```
   *
   * @param {String|Function} `dest` File path or rename function.
   * @param {Object} `options` Options and locals to pass to `dest` plugins
   * @api public
   */

  dest: function (/*dest, options*/) {
    return lazy.dest.apply(lazy.dest, arguments);
  },

  task: function (name) {
    var task = Composer.prototype.task;
    if (!this.loaded) this.defaultConfig();
    var key = 'task_' + name;
    this.create(key, {
      renameKey: function (fp) {
        return fp;
      }
    });
    return task.apply(this, arguments);
  },

  /**
   * Copy files with the given glob `patterns` to the specified `destDir`.
   *
   * ```js
   * app.task('assets', function() {
   *   app.copy('assets/**', 'dist/');
   * });
   * ```
   *
   * @param {String|Array} `patterns` Glob patterns of files to copy.
   * @param  {String|Function} `destDir` Desination directory.
   * @return {Stream} Stream, to continue processing if necessary.
   * @api public
   */

  copy: function(patterns, destDir, opts) {
    return lazy.vfs.src(patterns, opts)
      .pipe(lazy.vfs.dest(destDir, opts));
  },

  /**
   * Push a view collection into a vinyl stream.
   *
   * @param {String} `plural`
   * @param {Object} `locals`
   * @return {Stream}
   * @api public
   */

  toStream: function (plural, locals) {
    if (!this.views.hasOwnProperty(plural)) {
      plural = this.inflections[plural];
    }
    var views = this.views[plural] || {};
    return lazy.through.obj(function (file, enc, cb) {
      this.push(file);
      return cb();
    }, function (cb) {
      Object.keys(views).forEach(function (key) {
        var view = views[key];
        var file = lazy.toVinyl(view);
        this.push(file);
      }.bind(this));
      cb();
    });
  },

  taskName: function () {
    var task = this.session.get('task');
    return (task ? 'task_' + task.name : 'file');
  },

  /**
   * Render a vinyl file.
   *
   * @param  {Object} file
   * @param  {Function} cb Callback
   * @return {Object}
   * @api public
   */

  renderFile: function (locals) {
    var name = this.taskName();
    // TODO: update template to use pascalcase
    name = name[0].toUpperCase() + name.slice(1);
    var File = this.get(name);
    var self = this;

    return lazy.through.obj(function (file, enc, cb) {
      if (typeof locals === 'function') {
        cb = locals;
        locals = {};
      }

      self.render(new File(file), locals, function (err, res) {
        if (err) return cb(err);
        res.contents = new Buffer(res.content);
        file = new lazy.Vinyl(res);
        cb(null, file);
      });
    });
  }
});

/**
 * Static method for allowing other classes to inherit
 * both prototype and static methods from `Assemble`.
 *
 * ```js
 * function MyApp(options) {...}
 * Assemble.extend(MyApp);
 * ```
 *
 * @param  {Object} `Ctor` Constructor function to extend with `Assemble`
 * @return {undefined}
 * @api public
 */

Assemble.extend = function(Ctor) {
  util.inherits(Ctor, Assemble);
  delegate(Ctor, Assemble);
};

/**
 * Expose an instance of `Assemble`
 */

module.exports = new Assemble();

/**
 * Allow users to instantiate `Assemble`.
 */

module.exports.Assemble = Assemble;
<|endoftext|>


<commit_before>var varstruct = require('varstruct')
var Blake2s = require('blake2s')
var ecc = require('eccjs')
var k256 = ecc.curves.k256
var pull = require('pull-stream')
var assert = require('assert')

var b2s = varstruct.buffer(32)
var signature = varstruct.buffer(64)

var type = varstruct.varbuf(varstruct.bound(varstruct.byte, 0, 32))

var UnsignedMessage = varstruct({
  previous  : b2s,
  author    : b2s,
  sequence  : varstruct.varint,
  type      : type,
  message   : varstruct.varbuf(varstruct.byte)
})

var Message = varstruct({
  previous  : b2s,
  author    : b2s,
  sequence  : varstruct.varint,
  type      : type,
  message   : varstruct.varbuf(varstruct.byte),
  signature : signature
})

var zeros = new Buffer(32)
zeros.fill(0)

function bsum (value) {
  return new Blake2s().update(value).digest()
}

function validate(msg, keys) {
  msg = Buffer.isBuffer(msg) ? message.decode(msg) : msg
  process.assert(bsum(keys.public).toString('hex') === msg.author.toString('hex'), 'same author')
  return ecc.verify(k256, keys, msg.signature, bsum(unsigned_message.encode(msg)))
}

function signMessage(msg, keys) {
  msg.signature = ecc.sign(k256, keys, bsum(UnsignedMessage.encode(msg)))
  return msg
}

function Feed (keys) {
  var feed = [], id = keys ? bsum(keys.public) : null

  function append (type, buffer, cb) {
    var last = feed[feed.length - 1]
    var msg = signMessage({
      previous: last ? bsum(Message.encode(last)) : zeros,
      author  : bsum(keys.public),
      type    : type,
      sequence: feed.length,
      message : buffer
    }, keys)
    feed.push(msg)
    cb(null, msg.sequence, bsum(Message.encode(msg)))
  }

  //if we have the private key, write an initial message.
  if(keys)
    append(new Buffer('INIT'), keys.public, function () {})

  var prev = zeros, seq = 0
  var f
  return f = {
    id: id,
    feed: feed,
    append: append,
    createReadStream: function (opts) {
      if(opts && !isNaN(opts.gt))
        return pull.values(feed.slice(opts.gt + 1))
      return pull.values(feed)
    },
    createWriteStream: function (cb) {
      return pull(pull.map(function (msg) {
          if(!keys) {
            keys = {public: msg.message}
            f.id = id = bsum(keys.public)
          } else
            seq ++

          assert.deepEqual(msg.author, id, 'unexpected author')
          assert.deepEqual(msg.previous, prev, 'messages out of order')
          assert.equal(msg.sequence, seq, 'sequence number is incorrect')

          var hash = bsum(UnsignedMessage.encode(msg))

          if(!ecc.verify(k256, keys, msg.signature, hash))
            throw new Error('message was not validated by:' + id)

          feed.push(msg)
          prev = bsum(Message.encode(msg))

          return true
        }),
        pull.drain(null, function (err) {
          cb(err, seq, prev)
        })
      )
    }
  }
}

//verify the signature, but not the sequence number or prev
Feed.verify = function (msg, keys) {
  var public = keys.public || keys
  var hash = bsum(UnsignedMessage.encode(msg))
  if(!ecc.verify(k256, keys, msg.signature, hash))
    throw new Error('message was not validated by:' + bsum(public))
  return true
}

module.exports = Feed
<commit_msg>scan the db for verify before allowing a write or external read<commit_after>var varstruct = require('varstruct')
var Blake2s = require('blake2s')
var ecc = require('eccjs')
var k256 = ecc.curves.k256
var pull = require('pull-stream')
var assert = require('assert')
var delayed = require('pull-delayed-sink')
var b2s = varstruct.buffer(32)
var signature = varstruct.buffer(64)

var type = varstruct.varbuf(varstruct.bound(varstruct.byte, 0, 32))

var UnsignedMessage = varstruct({
  previous  : b2s,
  author    : b2s,
  sequence  : varstruct.varint,
  type      : type,
  message   : varstruct.varbuf(varstruct.byte)
})

var Message = varstruct({
  previous  : b2s,
  author    : b2s,
  sequence  : varstruct.varint,
  type      : type,
  message   : varstruct.varbuf(varstruct.byte),
  signature : signature
})

var INIT = new Buffer('INIT')

var zeros = new Buffer(32)
zeros.fill(0)

function bsum (value) {
  return new Blake2s().update(value).digest()
}

function validate(msg, keys) {
  msg = Buffer.isBuffer(msg) ? message.decode(msg) : msg
  process.assert(bsum(keys.public).toString('hex') === msg.author.toString('hex'), 'same author')
  return ecc.verify(k256, keys, msg.signature, bsum(unsigned_message.encode(msg)))
}

function signMessage(msg, keys) {
  msg.signature = ecc.sign(k256, keys, bsum(UnsignedMessage.encode(msg)))
  return msg
}

function Feed (db, keys) {
  if('function' !== typeof db.put)
    throw new Error('db instance must be first argument')

  var feed = [], id = keys ? bsum(keys.public) : null, onVerify = [], state = 'created'
  var ready = false, verifying = false

  function append (type, buffer, cb) {
    var last = feed[feed.length - 1]
    var msg = signMessage({
      previous: last ? bsum(Message.encode(last)) : zeros,
      author  : bsum(keys.public),
      type    : type,
      sequence: feed.length,
      message : buffer
    }, keys)
    feed.push(msg)
    cb(null, msg.sequence, bsum(Message.encode(msg)))
  }

  var prev = zeros, seq = 0
  var f
  return f = {
    id: id,
    feed: feed,
    append: function _append (type, message, cb) {
      if(!ready)
        f.verify(function (err) {
          if(err) return cb(err)
          append(type, message, cb)
        })
      else
        append(type, message, cb)
    },
    createReadStream: function (opts) {
      //defer until verified!
      var deferred = pull.defer()
      function createSource () {
        return  opts && !isNaN(opts.gt)
          ? pull.values(feed.slice(opts.gt + 1))
          : pull.values(feed)
      }
      if(state !== 'ready') {
        f.verify(function () { deferred.resolve(createSource()) })
        return deferred
      }
      else
        return createSource()
    },
    //to make this work async,
    //defer any appending until a verification scan is complete
    //and ignore any records that you already have.
    createWriteStream: function (cb) {
      //don't read until verified.
      function createSink() {
        return pull(pull.map(function (msg) {
            if(!keys) {
              keys = {public: msg.message}
              f.id = id = bsum(keys.public)
            } else
              seq ++

            assert.deepEqual(msg.author, id, 'unexpected author')
            assert.deepEqual(msg.previous, prev, 'messages out of order')
            assert.equal(msg.sequence, seq, 'sequence number is incorrect')

            var hash = bsum(UnsignedMessage.encode(msg))

            if(!ecc.verify(k256, keys, msg.signature, hash))
              throw new Error('message was not validated by:' + id)

            feed.push(msg)
            prev = bsum(Message.encode(msg))

            return true
          }),
          pull.drain(null, function (err) {
            cb(err, seq, prev)
          })
        )
      }
      if(!ready) {
        var d = delayed()
        f.verify(function (err) {
          d.start(createSink())
        })
        return d
      }
      else
        return createSink()
    },
    verify: function (_cb) {
      //verify from the start of the database,
      //if empty and we have the private key,
      //write the initial message.
      if(ready) return _cb(null, seq, prev)
      onVerify.push(_cb)
      if(verifying) return
      verifying = true

      function cb (err, seq, hash) {
        if(!err) ready = true
        verifying = false
        while(onVerify.length)
          onVerify.shift()(err, seq, hash)
      }

      pull(
        pull.values(feed),
        pull.map(function (msg) {
          //just copied this from above, tidy up later.
          if(!keys) {
            keys = {public: msg.message}
            f.id = id = bsum(keys.public)
          } else
            seq ++

          assert.deepEqual(msg.author, id, 'unexpected author')
          assert.deepEqual(msg.previous, prev, 'messages out of order')
          assert.equal(msg.sequence, seq, 'sequence number is incorrect')

          var hash = bsum(UnsignedMessage.encode(msg))

          if(!ecc.verify(k256, keys, msg.signature, hash))
            throw new Error('message was not validated by:' + id)

          feed.push(msg)
          prev = bsum(Message.encode(msg))

          return true
        }),
        pull.drain(null, function (err) {
          //if there where no records in the database...
          if(err) return cb(err)
          else if(seq === 0 && keys && keys.private)
            return append(INIT, keys.public, function (err, _seq, _hash) {
              seq = _seq; hash = _hash
              cb(err, _seq, _hash)
            })
          else
            cb(null, seq, prev)
        })
      )

    }
  }
}

//verify the signature, but not the sequence number or prev
Feed.verify = function (msg, keys) {
  var public = keys.public || keys
  var hash = bsum(UnsignedMessage.encode(msg))
  if(!ecc.verify(k256, keys, msg.signature, hash))
    throw new Error('message was not validated by:' + bsum(public))
  return true
}

module.exports = Feed
<|endoftext|>


<commit_before>// Internal modules

// NPM modules
var express = require("express");
var morgan = require("morgan");
var cors = require("cors");

// Own modules
var EventSearch = require("facebook-events-by-location-core");

// Create the Express object
var app = express();

// Use morgan for logging
app.use(morgan("combined"));

// Set application properties
app.set("host", process.env.HOST || "0.0.0.0");
app.set("port", process.env.PORT0 || 3000);
app.set("x-powered-by", false);
app.set("etag", false);

// Instantiate CORS whitelist
var whitelist = [],
    enableAll = false;

// Check if FEBL_CORS_WHITELIST exists
if (process.env.FEBL_CORS_WHITELIST) {
    if (process.env.FEBL_CORS_WHITELIST.indexOf(",") > -1) {
        // Add custom whitelisted domains
        whitelist = whitelist.concat(process.env.FEBL_CORS_WHITELIST.split(","))
    } else {
        // Just push the FEBL_CORS_WHITELIST value
        whitelist.push(process.env.FEBL_CORS_WHITELIST);
    }
    // Log CORS whitelist
    console.log("Using CORS whitelist of " + whitelist);
// Otherwise enable all origins
} else {
    enableAll = true;
}

// CORS middleware handler
var corsOptions = {
    origin: function(origin, callback){
        if (whitelist.length > 0) {
            var originIsWhitelisted = whitelist.indexOf(origin) !== -1;
            callback(null, originIsWhitelisted);
        } else if (enableAll) {
            callback(null, true);
        } else {
            callback(null, false);
        }
    }
};

// Main route
app.get("/events", cors(corsOptions), function(req, res) {

    if (!req.query.lat || !req.query.lng) {
        res.status(500).json({message: "Please specify the lat and lng parameters!"});
    } else if (!req.query.accessToken && !process.env.FEBL_ACCESS_TOKEN) {
        res.status(500).json({message: "Please specify an Access Token, either as environment variable odr as accessToken parameter!"});
    } else {

        var options = {};

        // Add latitude
        if (req.query.lat) {
            options.lat = req.query.lat;
        }
        if (req.query.lng) {
            options.lng = req.query.lng;
        }
        if (req.query.distance) {
            options.distance = req.query.distance;
        }
        if (req.query.accessToken) {
            options.accessToken = req.query.accessToken;
        } else {
            options.accessToken = process.env.FEBL_ACCESS_TOKEN || null;
        }
        if (req.query.query) {
            options.query = req.query.query;
        }
        if (req.query.sort) {
            options.sort = req.query.sort;
        }
        if (req.query.version) {
            options.version = req.query.version;
        }
        if (req.query.since) {
            options.since = req.query.since;
        }
        if (req.query.until) {
            options.until = req.query.until;
        }

        // Instantiate EventSearch
        var es = new EventSearch(options);

        // Search and handle results
        es.search().then(function (events) {
            res.json(events);
        }).catch(function (error) {
            res.status(500).json(error);
        });

    }

});

// Health check route
app.get("/health", function(req, res) {
    res.send("OK");
});

// Start Express.js server
var server = app.listen(app.get("port"), app.get("host"), function() {
    console.log("Express server listening on port " + server.address().port + " on " + server.address().address);
});
<commit_msg>Correct typo in warning message<commit_after>// Internal modules

// NPM modules
var express = require("express");
var morgan = require("morgan");
var cors = require("cors");

// Own modules
var EventSearch = require("facebook-events-by-location-core");

// Create the Express object
var app = express();

// Use morgan for logging
app.use(morgan("combined"));

// Set application properties
app.set("host", process.env.HOST || "0.0.0.0");
app.set("port", process.env.PORT0 || 3000);
app.set("x-powered-by", false);
app.set("etag", false);

// Instantiate CORS whitelist
var whitelist = [],
    enableAll = false;

// Check if FEBL_CORS_WHITELIST exists
if (process.env.FEBL_CORS_WHITELIST) {
    if (process.env.FEBL_CORS_WHITELIST.indexOf(",") > -1) {
        // Add custom whitelisted domains
        whitelist = whitelist.concat(process.env.FEBL_CORS_WHITELIST.split(","))
    } else {
        // Just push the FEBL_CORS_WHITELIST value
        whitelist.push(process.env.FEBL_CORS_WHITELIST);
    }
    // Log CORS whitelist
    console.log("Using CORS whitelist of " + whitelist);
// Otherwise enable all origins
} else {
    enableAll = true;
}

// CORS middleware handler
var corsOptions = {
    origin: function(origin, callback){
        if (whitelist.length > 0) {
            var originIsWhitelisted = whitelist.indexOf(origin) !== -1;
            callback(null, originIsWhitelisted);
        } else if (enableAll) {
            callback(null, true);
        } else {
            callback(null, false);
        }
    }
};

// Main route
app.get("/events", cors(corsOptions), function(req, res) {

    if (!req.query.lat || !req.query.lng) {
        res.status(500).json({message: "Please specify the lat and lng parameters!"});
    } else if (!req.query.accessToken && !process.env.FEBL_ACCESS_TOKEN) {
        res.status(500).json({message: "Please specify an Access Token, either as environment variable or as accessToken parameter!"});
    } else {

        var options = {};

        // Add latitude
        if (req.query.lat) {
            options.lat = req.query.lat;
        }
        if (req.query.lng) {
            options.lng = req.query.lng;
        }
        if (req.query.distance) {
            options.distance = req.query.distance;
        }
        if (req.query.accessToken) {
            options.accessToken = req.query.accessToken;
        } else {
            options.accessToken = process.env.FEBL_ACCESS_TOKEN || null;
        }
        if (req.query.query) {
            options.query = req.query.query;
        }
        if (req.query.sort) {
            options.sort = req.query.sort;
        }
        if (req.query.version) {
            options.version = req.query.version;
        }
        if (req.query.since) {
            options.since = req.query.since;
        }
        if (req.query.until) {
            options.until = req.query.until;
        }

        // Instantiate EventSearch
        var es = new EventSearch(options);

        // Search and handle results
        es.search().then(function (events) {
            res.json(events);
        }).catch(function (error) {
            res.status(500).json(error);
        });

    }

});

// Health check route
app.get("/health", function(req, res) {
    res.send("OK");
});

// Start Express.js server
var server = app.listen(app.get("port"), app.get("host"), function() {
    console.log("Express server listening on port " + server.address().port + " on " + server.address().address);
});
<|endoftext|>


<commit_before>var dup = require('dup')
var map = require('map-async')
var cells = require('cell-range')
var round = Math.round
var min = Math.min
var max = Math.max
var abs = Math.abs

module.exports = observer

function observer(field, range, linger) {
  range = (+range|0) || 1
  linger = max((+linger|0) - range, range)

  var shape = field.shape
  var dims = shape.length
  var neighbours = cells(dup(dims, -range), dup(dims, range))

  return function observe(places, callback) {
    if (!Array.isArray(places[0])) places = [places]
    callback = callback || function(){}

    map(places, function(coord, next) {
      coord = coord.slice()
      var i = dims
      while (i--) coord[i] = round(coord[i] / shape[i])

      map(neighbours, function(offset, next) {
        var pos = coord.slice()
        var i = dims
        while (i--) pos[i] += offset[i]
        field.chunk(pos, next)
      }, next)
    }, function(err) {
      if (err) return next(err)

      var closest = Infinity
      var flagged = []
      var distance = 0
      var l = places.length
      var pos
      var i

      var pages = field.index.pages
      for (var p = 0; p < pages.length; p += 1)
      for (var c = 0; c < pages[p].length; c += 1) {
        pos = pages[p][c].position

        for (i = 0; i < l; i += 1) {
          distance = 0
          for (var d = 0; d < dims; d += 1) {
            distance += abs(pos[d] - places[i][d] / shape[d])
          }

          closest = distance < closest
            ? distance
            : closest
        }

        if (closest > range + linger) flagged.push(pos)
      }

      i = flagged.length
      while (i--) field.remove(flagged[i])

      return callback(null)
    })
  }
}
<commit_msg>Fix a very silly bug. Closes #2<commit_after>var dup = require('dup')
var map = require('map-async')
var cells = require('cell-range')
var round = Math.round
var min = Math.min
var max = Math.max
var abs = Math.abs

module.exports = observer

function observer(field, range, linger) {
  range = (+range|0) || 1
  linger = max((+linger|0) - range, range)

  var shape = field.shape
  var dims = shape.length
  var neighbours = cells(dup(dims, -range), dup(dims, range))

  return function observe(places, callback) {
    if (!Array.isArray(places[0])) places = [places]
    callback = callback || function(){}

    map(places, function(coord, next) {
      coord = coord.slice()
      var i = dims
      while (i--) coord[i] = round(coord[i] / shape[i])

      map(neighbours, function(offset, next) {
        var pos = coord.slice()
        var i = dims
        while (i--) pos[i] += offset[i]
        field.chunk(pos, next)
      }, next)
    }, function(err) {
      if (err) return next(err)

      var closest = Infinity
      var flagged = []
      var distance = 0
      var l = places.length
      var pos
      var i

      var pages = field.index.pages
      for (var p = 0; p < pages.length; p += 1)
      for (var c = 0; c < pages[p].length; c += 1) {
        pos = pages[p][c].position
        closest = Infinity

        for (i = 0; i < l; i += 1) {
          distance = 0
          for (var d = 0; d < dims; d += 1) {
            distance += abs(pos[d] - places[i][d] / shape[d])
          }

          closest = distance < closest
            ? distance
            : closest
        }

        if (closest > range + linger) flagged.push(pos)
      }

      i = flagged.length
      while (i--) field.remove(flagged[i])

      return callback(null)
    })
  }
}
<|endoftext|>