<commit_before>/**
 * Copyright (c) 2012 Andreas Madsen
 * MIT License
 */

(function () {
  "use strict";

  var util = require('util');
  var events = require('events');
  var Stream = require('stream');

  /**
   * This constructor will simply relay data
   * by purpose this do not support .end or .close
   */
  function RelayStream() {
    Stream.apply(this, arguments);
    this.writable = true;
    this.readable = true;

    this.store = [];
    this.paused = false;
  }
  util.inherits(RelayStream, Stream);
  exports.RelayStream = RelayStream;

  // support pause and resume
  RelayStream.prototype.resume = function () {
    while (this.store.length !== 0) {
      this.emit('data', this.store.shift());
    }
    this.paused = false;
  };
  RelayStream.prototype.pause = function () {
    this.paused = true;
  };

  // write message by emitting data event
  RelayStream.prototype.write = function (chunk) {
    if (this.paused) {
      this.store.push(chunk);
      return false;
    }
    this.emit('data', chunk);
    return true;
  };

  // close will be ignored
  RelayStream.prototype.close = function () {};

  // end function will only write chunk message
  RelayStream.prototype.end = function (chunk) {
    if (chunk !== undefined) this.wirte(chunk);
  };

  /**
   * This constructor will create a I/O line stream
   * from a writable and readable stream
   */
  function LineStream(writeStream, readStream) {
    var self = this;
    this.writeStream = writeStream;
    this.readStream = readStream;

    // save data in this buffer
    this.buffer = "";

    // new data from stream will be handled by this
    this.readStream.on('data', function (chunk) {
      self.buffer += chunk;

      // go through the buffer and isolate each message by a linebreak
      var i, start = 0;
      while ((i = self.buffer.indexOf('\n', start)) >= 0) {

        // parse line as JSON and emit line
        self.emit('message', JSON.parse(self.buffer.slice(start, i)));
        start = i + 1;
      }
      self.buffer = self.buffer.slice(start);
    });
  }
  util.inherits(LineStream, events.EventEmitter);
  exports.LineStream = LineStream;

  // flush buffer, usful when the process restart
  LineStream.prototype.flush = function () {
    this.buffer = "";
  };

  // send message by JSON stringify the message and add a linebreak
  LineStream.prototype.send = function (message) {
    this.writeStream.write(JSON.stringify(message) + '\n');
  };

})();
<commit_msg>[fix] resume streams when opening IPC<commit_after>/**
 * Copyright (c) 2012 Andreas Madsen
 * MIT License
 */

(function () {
  "use strict";

  var util = require('util');
  var events = require('events');
  var Stream = require('stream');

  /**
   * This constructor will simply relay data
   * by purpose this do not support .end or .close
   */
  function RelayStream() {
    Stream.apply(this, arguments);
    this.writable = true;
    this.readable = true;

    this.store = [];
    this.paused = false;
  }
  util.inherits(RelayStream, Stream);
  exports.RelayStream = RelayStream;

  // support pause and resume
  RelayStream.prototype.resume = function () {
    while (this.store.length !== 0) {
      this.emit('data', this.store.shift());
    }
    this.paused = false;
  };
  RelayStream.prototype.pause = function () {
    this.paused = true;
  };

  // write message by emitting data event
  RelayStream.prototype.write = function (chunk) {
    if (this.paused) {
      this.store.push(chunk);
      return false;
    }
    this.emit('data', chunk);
    return true;
  };

  // close will be ignored
  RelayStream.prototype.close = function () {};

  // end function will only write chunk message
  RelayStream.prototype.end = function (chunk) {
    if (chunk !== undefined) this.wirte(chunk);
  };

  /**
   * This constructor will create a I/O line stream
   * from a writable and readable stream
   */
  function LineStream(writeStream, readStream) {
    var self = this;
    this.writeStream = writeStream;
    this.readStream = readStream;

    // resume streams
    this.writeStream.resume();
    this.readStream.resume();

    // save data in this buffer
    this.buffer = "";

    // new data from stream will be handled by this
    this.readStream.on('data', function (chunk) {
      self.buffer += chunk;

      // go through the buffer and isolate each message by a linebreak
      var i, start = 0;
      while ((i = self.buffer.indexOf('\n', start)) >= 0) {

        // parse line as JSON and emit line
        self.emit('message', JSON.parse(self.buffer.slice(start, i)));
        start = i + 1;
      }
      self.buffer = self.buffer.slice(start);
    });
  }
  util.inherits(LineStream, events.EventEmitter);
  exports.LineStream = LineStream;

  // flush buffer, usful when the process restart
  LineStream.prototype.flush = function () {
    this.buffer = "";
  };

  // send message by JSON stringify the message and add a linebreak
  LineStream.prototype.send = function (message) {
    this.writeStream.write(JSON.stringify(message) + '\n');
  };

})();
<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash');
var assert = require('assert');
var GetOpt = require('node-getopt');
var S = require('string');

/*
 * Create and return a new branch object for the task tree.
 */
var createBranch = function(name) {
  return {
    name: name,
    children: [],
    __isBranch: true
  };
};

/*
 * The task tree object.
 */
var taskTree = createBranch('root');

/*
 * Is object a branch?
 */
var isBranch = exports.isBranch = function(obj) {
  return obj.__isBranch;
};

/*
 * Is object a task?
 */
var isTask = exports.isTask = function(obj) {
  return obj.__isTask;
};

/*
 * Is object either a branch or a task?
 */
var isBranchOrTask = function(obj) {
  return isBranch(obj) || isTask(obj);
};

/*
 * Is object an argv object?
 */
var isArgv = exports.isArgv = function(obj) {
  return Array.isArray(obj);
};

/*
 * Return name of branch or task.
 */
var getName = exports.getName = function(obj) {
  if (isBranch(obj)) {
    return obj.name;
  } else if (isTask(obj)) {
    if (obj.path.length < 1) {
      assert(false);
    }
    return obj.path[0];
  } else {
    assert(false);
  }
};

/*
 * Standard compare function to apply to either branch or task.
 */
var compareBranchOrTask = function(x, y) {
  var xName = getName(x);
  var yName = getName(y);

  if (typeof xName !== 'string' || xName.length < 1) {
    assert(false);
  }
  if (typeof yName !== 'string' || yName.length < 1) {
    assert(false);
  }

  if (xName === yName) {
    return 0;
  } else if (xName < yName) {
    return -1;
  } else if (xName > yName) {
    return 1;
  } else {
    assert(false);
  }
};

/*
 * Search a branch's children for a branch or task with a given name.
 */
var findChild = function(branch, name) {
  return _.find(branch.children, function(child) {
    return getName(child) === name;
  });
};

/*
 * Check if branch contains a child with a name/path.
 */
var branchContainsChild = function(branch, obj) {
  var names = _.map(branch.children, getName);
  var name = getName(obj);
  return _.contains(names, name);
};

/*
 * Add a task or branch to an existing branch.
 */
var addChild = function(branch, child) {
  // Validate.
  if (!isBranch(branch)) {
    assert(false);
  }
  if (!isBranchOrTask(child)) {
    assert(false);
  }

  // Branch already contains a child with the same name.
  if (branchContainsChild(branch, child)) {
    assert(false);
  }

  // Add child and then sort children.
  branch.children.push(child);
  branch.children.sort(compareBranchOrTask);
};

/*
 * Add a task to the root of the task tree.
 */
var addTask = function(task) {

  // Validate input.
  if (!isTask(task)) {
    throw new TypeError('Invalid task: ' + task);
  }
  if (task.path.length === 0) {
    throw new TypeError('Invalid task path: ' + task) ;
  }

  // Recursive function for placing task in task tree.
  var rec = function(node, path) {

    // Validate.
    if (!isBranch(node)) {
      assert(false);
    }
    if (path.length === 0) {
      assert(false);
    }

    // Partition head and tail.
    var hd = path[0];
    var tl = path.slice(1);

    // Find a child of node that matches path.
    var cursor = _.find(node.children, function(obj) {
      return getName(obj) === hd;
    });

    // Conflicting tasks exist in task tree.
    if (cursor && isTask(cursor)) {
      assert(false);
    }

    // Continue.
    if (tl.length === 0) {

      // We are at the end of the path.
      task.path = [hd];

      if (cursor) {

        addChild(cursor, task);

      } else {

        addChild(node, task);

      }

      return;

    } else {

      // We are NOT at the end of the path.
      if (!cursor) {

        cursor = createBranch(hd);
        addChild(node, cursor);

      }

      return rec(cursor, tl);

    }

  };

  // Kick off recursive function for placing task in task tree.
  rec(taskTree, task.path);

};

/*
 * Clear the task tree.
 */
var clearTasks = exports.clearTasks = function() {
  throw new Error('Not implemented.');
};

/*
 * Blueprint that every task will be cloned from.
 */
var blueprint = {
  path: [],
  description: null,
  allowArgv: false,
  options: [],
  func: null,
  __isTask: true
};

/*
 * Pretty print object in a nicer way.
 */
var pp = function(obj) {
  return JSON.stringify(obj);
};

/*
 * Validation function for a task.
 */
var invariant = function(task) {

  // Validate __isTask.
  if (!isTask(task)) {
    throw new TypeError('Invalid task: ' + pp(task));
  }

  // Validate path.
  if (!Array.isArray(task.path)) {
    throw new TypeError('Invalid task path: ' + pp(task));
  }
  if (task.path.length === 0) {
    throw new TypeError('Empty task path: ' + pp(task));
  }
  task.path.forEach(function(atom) {
    if (typeof atom !== 'string') {
      throw new TypeError('Invalid task path: ' + pp(task));
    }
  });

  // Validate description.
  if (typeof task.description !== 'string' || task.description.length === 0) {
    throw new TypeError('Invalid task description: ' + pp(task));
  }

  // Validate allowArgv.
  if (typeof task.allowArgv !== 'boolean') {
    throw new TypeError('Invalid task allowArgv: ' + pp(task));
  }

  // @todo: validate options.

  // Validate function.
  if (typeof task.func !== 'function') {
    throw new TypeError('Invalid task function: ' + pp(task));
  }
  if (task.func.length > 1) {
    throw new TypeError('Wrong number of arguments in task function: ' +
      task.func.toString());
  }

};

/*
 * Take blueprint and clone it to produce a new object reference.
 */
var cloneBlueprint = function() {
  return _.cloneDeep(blueprint);
};

/*
 * Add needed default stuff to a build task.
 */
var decorate = function(task) {
  var helpOption = _.find(task.options, function(option) {
    return option[1] === 'khelp';
  });

  if (!helpOption) {
    task.options.push(['', 'khelp', 'Display usage and options.']);
  }
};

/*
 * Add new task to the task tree.
 */
var registerTask = exports.registerTask = function(handler) {
  if (typeof handler !== 'function') {
    throw new TypeError('Invalid task registration handler: ' + handler);
  }

  var task = cloneBlueprint();
  if (handler.length === 1) {

    handler(task);
    invariant(task);
    decorate(task);
    addTask(task);

  } else if (handler.length === 2) {

    var timeout = setTimeout(function() {
      throw new Error('Task registration done callback was not called: ' +
        task.path);
    }, 2 * 60 * 1000);

    handler(task, function() {
      clearTimeout(timeout);
      invariant(task);
      decorate(task);
      addTask(task);
    });

  } else {

    throw new TypeError('Invalid task registration handler: ' +
      handler.toString());

  }

};

/*
 * Shortcut alias.
 */
exports.add = registerTask;

/*
 * Return the task tree.
 */
var getTaskTree = exports.getTaskTree = function() {
  return taskTree;
};

/*
 * Search a task tree using a given argv, return the found task and
 * slice the used portion from the argv.
 */
var find = exports.find = function(tree, argv) {

  // Optional argument handling.
  if (argv === undefined && isArgv(tree)) {
    argv = tree;
    tree = getTaskTree();
  }

  // Validate.
  if (!isBranch(tree)) {
    throw new TypeError('Expected a branch: ' + tree);
  }
  if (!isArgv(argv)) {
    throw new TypeError('Invalid argv object: ' + pp(argv));
  }

  // Recursive function for searching the task tree.
  var rec = function(node, argv) {

    if (argv.length === 0) {

      // Reached end of argv path, so return current node.
      node.argv = argv;
      return node;

    } else if (isTask(node)) {

      // A task has been found along the argv path, so return it.
      node.argv = argv;
      return node;

    } else if (isBranch(node)) {

      // Get the head of the argv path.
      var hd = argv[0];

      // Find a child of node branch that matches hd.
      var child = findChild(node, hd);

      if (child) {

        // Update the argv path and then recurse with child that was found.
        return rec(child, argv.slice(1));

      } else {

        // No matching child was found, it's a dead search so return null.
        return null;

      }

    } else {

      // This should never happen.
      assert(false);

    }

  };

  // Kick off the recursive function with the task tree.
  return rec(tree, argv);
};

var getHelpMessage = function(task) {
  return 'Usage: ' + getName(task) + ' [OPTION]\n' +
    '\n' +
    '[[OPTIONS]]\n';
};

/*
 * Run a task's function.
 */
var run = exports.run = function(task, callback) {

  // Validate.
  if (!isTask(task)) {
    throw new TypeError('Invalid task object: ' + pp(task));
  }
  if (!isArgv(task.argv)) {
    throw new TypeError('Invalid argv object: ' + pp(task.argv));
  }
  if (typeof callback !== 'function') {
    throw new TypeError('Invalid callback function: ' + pp(callback));
  }

  // Parse cli options.
  var parser = new GetOpt(task.options);
  var argv = parser.parse(task.argv);

  // Display task help message instead of running.
  if (argv.options.khelp) {
    parser.setHelp(getHelpMessage(task));
    console.log(parser.getHelp());
    return process.exit(1);
  }

  // Build context for task function.
  var context = {
    argv: argv.argv,
    options: argv.options,
    task: task
  };

  // Enforce task.allowArgv.
  if (!task.allowArg && context.argv.length > 0) {
    var helpMessage = '\nInvalid argument: ' + context.argv[0] + '\n\n' +
      getHelpMessage(task);
    parser.setHelp(helpMessage);
    console.log(parser.getHelp());
    return process.exit(1);
  }

  // Find out if task function is asynchronous.
  var isAsync = task.func.length === 1;
  if (task.func.length > 1) {
    // This should never happen.
    assert(false);
  }

  if (isAsync) {

    // Treat task function as asynchronous.
    task.func.apply(context, [callback]);

  } else {

    // Treat task function as synchronous.
    task.func.apply(context, []);
    callback();

  }

};

/*
 * Return string representation of task tree.
 */
var getMenu = exports.getMenu = function(branch) {

  // Validate.
  if (!isBranch(branch)) {
    throw new TypeError('Invalid branch: ' + pp(branch));
  }

  var tabSpacing = 4;

  var header = '--- Command Menu ---\n';

  // Recursively build list of lines.
  var lines = [];
  var rec = function(node, depth) {
    if (isTask(node)) {
      lines.push({
        depth: depth,
        name: getName(node),
        description: node.description
      });
    } else if (isBranch(node)) {
      lines.push({
        depth: depth,
        name: getName(node)
      });
      node.children.forEach(function(child) {
        rec(child, depth + 1);
      });
    } else {
      assert(false);
    }
  };
  branch.children.forEach(function(child) {
    rec(child, 0);
  });

  lines = _.map(lines, function(line) {
    var depthPrefix = S(' ').repeat(tabSpacing * line.depth).s;
    var name = depthPrefix + line.name;
    return {
      name: name,
      description: line.description
    };
  });

  var widths = _.map(lines, function(line) {
    return line.name.length;
  });
  var maxWidth = _.max(widths);

  lines = _.map(lines, function(line) {
    var name = S(line.name).padRight(maxWidth).s;
    if (line.description) {
      return [name, line.description].join(S(' ').repeat(tabSpacing).s);
    } else {
      return name;
    }
  });

  lines.unshift(header);
  lines.push('');
  return lines.join('\n');

};

/*
 * Display menu from branch's reference point, and then exit(1).
 */
var showMenu = exports.showMenu = function(branch) {
  // Display menu.
  console.log(getMenu(branch));
  // Exit the process.
  process.exit(1);
};
<commit_msg>Fixing small bug where variable had a typo.<commit_after>'use strict';

var _ = require('lodash');
var assert = require('assert');
var GetOpt = require('node-getopt');
var S = require('string');

/*
 * Create and return a new branch object for the task tree.
 */
var createBranch = function(name) {
  return {
    name: name,
    children: [],
    __isBranch: true
  };
};

/*
 * The task tree object.
 */
var taskTree = createBranch('root');

/*
 * Is object a branch?
 */
var isBranch = exports.isBranch = function(obj) {
  return obj.__isBranch;
};

/*
 * Is object a task?
 */
var isTask = exports.isTask = function(obj) {
  return obj.__isTask;
};

/*
 * Is object either a branch or a task?
 */
var isBranchOrTask = function(obj) {
  return isBranch(obj) || isTask(obj);
};

/*
 * Is object an argv object?
 */
var isArgv = exports.isArgv = function(obj) {
  return Array.isArray(obj);
};

/*
 * Return name of branch or task.
 */
var getName = exports.getName = function(obj) {
  if (isBranch(obj)) {
    return obj.name;
  } else if (isTask(obj)) {
    if (obj.path.length < 1) {
      assert(false);
    }
    return obj.path[0];
  } else {
    assert(false);
  }
};

/*
 * Standard compare function to apply to either branch or task.
 */
var compareBranchOrTask = function(x, y) {
  var xName = getName(x);
  var yName = getName(y);

  if (typeof xName !== 'string' || xName.length < 1) {
    assert(false);
  }
  if (typeof yName !== 'string' || yName.length < 1) {
    assert(false);
  }

  if (xName === yName) {
    return 0;
  } else if (xName < yName) {
    return -1;
  } else if (xName > yName) {
    return 1;
  } else {
    assert(false);
  }
};

/*
 * Search a branch's children for a branch or task with a given name.
 */
var findChild = function(branch, name) {
  return _.find(branch.children, function(child) {
    return getName(child) === name;
  });
};

/*
 * Check if branch contains a child with a name/path.
 */
var branchContainsChild = function(branch, obj) {
  var names = _.map(branch.children, getName);
  var name = getName(obj);
  return _.contains(names, name);
};

/*
 * Add a task or branch to an existing branch.
 */
var addChild = function(branch, child) {
  // Validate.
  if (!isBranch(branch)) {
    assert(false);
  }
  if (!isBranchOrTask(child)) {
    assert(false);
  }

  // Branch already contains a child with the same name.
  if (branchContainsChild(branch, child)) {
    assert(false);
  }

  // Add child and then sort children.
  branch.children.push(child);
  branch.children.sort(compareBranchOrTask);
};

/*
 * Add a task to the root of the task tree.
 */
var addTask = function(task) {

  // Validate input.
  if (!isTask(task)) {
    throw new TypeError('Invalid task: ' + task);
  }
  if (task.path.length === 0) {
    throw new TypeError('Invalid task path: ' + task) ;
  }

  // Recursive function for placing task in task tree.
  var rec = function(node, path) {

    // Validate.
    if (!isBranch(node)) {
      assert(false);
    }
    if (path.length === 0) {
      assert(false);
    }

    // Partition head and tail.
    var hd = path[0];
    var tl = path.slice(1);

    // Find a child of node that matches path.
    var cursor = _.find(node.children, function(obj) {
      return getName(obj) === hd;
    });

    // Conflicting tasks exist in task tree.
    if (cursor && isTask(cursor)) {
      assert(false);
    }

    // Continue.
    if (tl.length === 0) {

      // We are at the end of the path.
      task.path = [hd];

      if (cursor) {

        addChild(cursor, task);

      } else {

        addChild(node, task);

      }

      return;

    } else {

      // We are NOT at the end of the path.
      if (!cursor) {

        cursor = createBranch(hd);
        addChild(node, cursor);

      }

      return rec(cursor, tl);

    }

  };

  // Kick off recursive function for placing task in task tree.
  rec(taskTree, task.path);

};

/*
 * Clear the task tree.
 */
var clearTasks = exports.clearTasks = function() {
  throw new Error('Not implemented.');
};

/*
 * Blueprint that every task will be cloned from.
 */
var blueprint = {
  path: [],
  description: null,
  allowArgv: false,
  options: [],
  func: null,
  __isTask: true
};

/*
 * Pretty print object in a nicer way.
 */
var pp = function(obj) {
  return JSON.stringify(obj);
};

/*
 * Validation function for a task.
 */
var invariant = function(task) {

  // Validate __isTask.
  if (!isTask(task)) {
    throw new TypeError('Invalid task: ' + pp(task));
  }

  // Validate path.
  if (!Array.isArray(task.path)) {
    throw new TypeError('Invalid task path: ' + pp(task));
  }
  if (task.path.length === 0) {
    throw new TypeError('Empty task path: ' + pp(task));
  }
  task.path.forEach(function(atom) {
    if (typeof atom !== 'string') {
      throw new TypeError('Invalid task path: ' + pp(task));
    }
  });

  // Validate description.
  if (typeof task.description !== 'string' || task.description.length === 0) {
    throw new TypeError('Invalid task description: ' + pp(task));
  }

  // Validate allowArgv.
  if (typeof task.allowArgv !== 'boolean') {
    throw new TypeError('Invalid task allowArgv: ' + pp(task));
  }

  // @todo: validate options.

  // Validate function.
  if (typeof task.func !== 'function') {
    throw new TypeError('Invalid task function: ' + pp(task));
  }
  if (task.func.length > 1) {
    throw new TypeError('Wrong number of arguments in task function: ' +
      task.func.toString());
  }

};

/*
 * Take blueprint and clone it to produce a new object reference.
 */
var cloneBlueprint = function() {
  return _.cloneDeep(blueprint);
};

/*
 * Add needed default stuff to a build task.
 */
var decorate = function(task) {
  var helpOption = _.find(task.options, function(option) {
    return option[1] === 'khelp';
  });

  if (!helpOption) {
    task.options.push(['', 'khelp', 'Display usage and options.']);
  }
};

/*
 * Add new task to the task tree.
 */
var registerTask = exports.registerTask = function(handler) {
  if (typeof handler !== 'function') {
    throw new TypeError('Invalid task registration handler: ' + handler);
  }

  var task = cloneBlueprint();
  if (handler.length === 1) {

    handler(task);
    invariant(task);
    decorate(task);
    addTask(task);

  } else if (handler.length === 2) {

    var timeout = setTimeout(function() {
      throw new Error('Task registration done callback was not called: ' +
        task.path);
    }, 2 * 60 * 1000);

    handler(task, function() {
      clearTimeout(timeout);
      invariant(task);
      decorate(task);
      addTask(task);
    });

  } else {

    throw new TypeError('Invalid task registration handler: ' +
      handler.toString());

  }

};

/*
 * Shortcut alias.
 */
exports.add = registerTask;

/*
 * Return the task tree.
 */
var getTaskTree = exports.getTaskTree = function() {
  return taskTree;
};

/*
 * Search a task tree using a given argv, return the found task and
 * slice the used portion from the argv.
 */
var find = exports.find = function(tree, argv) {

  // Optional argument handling.
  if (argv === undefined && isArgv(tree)) {
    argv = tree;
    tree = getTaskTree();
  }

  // Validate.
  if (!isBranch(tree)) {
    throw new TypeError('Expected a branch: ' + tree);
  }
  if (!isArgv(argv)) {
    throw new TypeError('Invalid argv object: ' + pp(argv));
  }

  // Recursive function for searching the task tree.
  var rec = function(node, argv) {

    if (argv.length === 0) {

      // Reached end of argv path, so return current node.
      node.argv = argv;
      return node;

    } else if (isTask(node)) {

      // A task has been found along the argv path, so return it.
      node.argv = argv;
      return node;

    } else if (isBranch(node)) {

      // Get the head of the argv path.
      var hd = argv[0];

      // Find a child of node branch that matches hd.
      var child = findChild(node, hd);

      if (child) {

        // Update the argv path and then recurse with child that was found.
        return rec(child, argv.slice(1));

      } else {

        // No matching child was found, it's a dead search so return null.
        return null;

      }

    } else {

      // This should never happen.
      assert(false);

    }

  };

  // Kick off the recursive function with the task tree.
  return rec(tree, argv);
};

var getHelpMessage = function(task) {
  return 'Usage: ' + getName(task) + ' [OPTION]\n' +
    '\n' +
    '[[OPTIONS]]\n';
};

/*
 * Run a task's function.
 */
var run = exports.run = function(task, callback) {

  // Validate.
  if (!isTask(task)) {
    throw new TypeError('Invalid task object: ' + pp(task));
  }
  if (!isArgv(task.argv)) {
    throw new TypeError('Invalid argv object: ' + pp(task.argv));
  }
  if (typeof callback !== 'function') {
    throw new TypeError('Invalid callback function: ' + pp(callback));
  }

  // Parse cli options.
  var parser = new GetOpt(task.options);
  var argv = parser.parse(task.argv);

  // Display task help message instead of running.
  if (argv.options.khelp) {
    parser.setHelp(getHelpMessage(task));
    console.log(parser.getHelp());
    return process.exit(1);
  }

  // Build context for task function.
  var context = {
    argv: argv.argv,
    options: argv.options,
    task: task
  };

  // Enforce task.allowArgv.
  if (!task.allowArgv && context.argv.length > 0) {
    var helpMessage = '\nInvalid argument: ' + context.argv[0] + '\n\n' +
      getHelpMessage(task);
    parser.setHelp(helpMessage);
    console.log(parser.getHelp());
    return process.exit(1);
  }

  // Find out if task function is asynchronous.
  var isAsync = task.func.length === 1;
  if (task.func.length > 1) {
    // This should never happen.
    assert(false);
  }

  if (isAsync) {

    // Treat task function as asynchronous.
    task.func.apply(context, [callback]);

  } else {

    // Treat task function as synchronous.
    task.func.apply(context, []);
    callback();

  }

};

/*
 * Return string representation of task tree.
 */
var getMenu = exports.getMenu = function(branch) {

  // Validate.
  if (!isBranch(branch)) {
    throw new TypeError('Invalid branch: ' + pp(branch));
  }

  var tabSpacing = 4;

  var header = '--- Command Menu ---\n';

  // Recursively build list of lines.
  var lines = [];
  var rec = function(node, depth) {
    if (isTask(node)) {
      lines.push({
        depth: depth,
        name: getName(node),
        description: node.description
      });
    } else if (isBranch(node)) {
      lines.push({
        depth: depth,
        name: getName(node)
      });
      node.children.forEach(function(child) {
        rec(child, depth + 1);
      });
    } else {
      assert(false);
    }
  };
  branch.children.forEach(function(child) {
    rec(child, 0);
  });

  lines = _.map(lines, function(line) {
    var depthPrefix = S(' ').repeat(tabSpacing * line.depth).s;
    var name = depthPrefix + line.name;
    return {
      name: name,
      description: line.description
    };
  });

  var widths = _.map(lines, function(line) {
    return line.name.length;
  });
  var maxWidth = _.max(widths);

  lines = _.map(lines, function(line) {
    var name = S(line.name).padRight(maxWidth).s;
    if (line.description) {
      return [name, line.description].join(S(' ').repeat(tabSpacing).s);
    } else {
      return name;
    }
  });

  lines.unshift(header);
  lines.push('');
  return lines.join('\n');

};

/*
 * Display menu from branch's reference point, and then exit(1).
 */
var showMenu = exports.showMenu = function(branch) {
  // Display menu.
  console.log(getMenu(branch));
  // Exit the process.
  process.exit(1);
};
<|endoftext|>


<commit_before>/*
 * crude-entity
 * An awesome project description
 * https://github.com/thanpolas/crude-entity
 *
 * Copyright (c) 2014 Thanasis Polychronakis
 * Licensed under the MIT license.
 */

/**
 * @fileOverview crude-entity Base.
 */

var __ = require('lodash');

var crude = require('crude');

/**
 * The Entity Crude Controller
 *
 * @param {string} route The route to use.
 * @param {Entity} Entity An entity Ctor.
 * @contructor
 * @extends {crude}
 */
var CrudCtrl = module.exports = crude.extend(function(route, Entity) {
  this.route = route;
  this.Entity = Entity;
  this.entity = new Entity();
  this.setOptions();
});

/**
 * Set options.
 *
 * @param {Object=} optOptions User defined options.
 */
CrudCtrl.prototype.setOptions = function(optOptions) {
  var userOpts = {};
  if (__.isObject(optOptions)) {
    userOpts = optOptions;
  }

  /** @type {Object} define default options */
  this.opts = __.defaults(userOpts, {
    // entity "create" method to use.
    entityCreate: 'create',

    // entity "read" method to use.
    entityRead: 'read',

    // entity "readLimit" method to use.
    entityReadLimit: 'readLimit',

    // entity "readOne" method to use.
    entityReadOne: 'readOne',

    // entity "update" method to use.
    entityUpdate: 'update',

    // entity "count" method to use.
    entityCount: 'count',
  });
};

<commit_msg>work on crude-entity module<commit_after>/*
 * crude-entity
 * An awesome project description
 * https://github.com/thanpolas/crude-entity
 *
 * Copyright (c) 2014 Thanasis Polychronakis
 * Licensed under the MIT license.
 */

/**
 * @fileOverview crude-entity Base.
 */

var __ = require('lodash');

var crude = require('crude');

/**
 * The Entity Crude Controller
 *
 * @param {string} route The route to use.
 * @param {Entity} Entity An entity Ctor.
 * @contructor
 * @extends {crude}
 */
var CrudCtrl = module.exports = crude.extend(function(route, Entity) {
  this.route = route;
  this.Entity = Entity;
  this.entity = new Entity();

  /** @type {Object} Overwrite controller. */
  this.controller = {
    create: this.entity[this.opts.entityCreate],
    read: this.entity[this.opts.entityRead],
    readLimit: this.entity[this.opts.entityReadLimit],
    readOne: this.entity[this.opts.entityReadOne],
    update: this.entity[this.opts.entityUpdate],
    count: this.entity[this.opts.entityCount],
  };

  this.setOptions.use(this._setOptionsEntity.bind(this));
});

/**
 * Set options.
 *
 * @param {Object=} optOptions User defined options.
 */
CrudCtrl.prototype._setOptionsEntity = function(optOptions) {
  var userOpts = {};
  if (__.isObject(optOptions)) {
    userOpts = optOptions;
  }

  /** @type {Object} define default options */
  this.opts = __.defaults(userOpts, {
    // entity "create" method to use.
    entityCreate: 'create',

    // entity "read" method to use.
    entityRead: 'read',

    // entity "readLimit" method to use.
    entityReadLimit: 'readLimit',

    // entity "readOne" method to use.
    entityReadOne: 'readOne',

    // entity "update" method to use.
    entityUpdate: 'update',

    // entity "count" method to use.
    entityCount: 'count',
  });
};

<|endoftext|>


<commit_before>var crypto = require('crypto');
var util = require('util');
var Stream = require('stream').Stream

function CryptoStream(opts, cipher) {
  this._key = opts.key;
  this._cipher = cipher;
  this.inputEncoding = opts.inputEncoding;
  this.outputEncoding = opts.outputEncoding;
  this.readable = this.writable = true
}

util.inherits(CryptoStream, Stream);
exports.CryptoStream = CryptoStream;

CryptoStream.prototype.write = function(data) {
  this.emit("data", this._cipher.update(data, this.inputEncoding, this.outputEncoding));
  return true
}

CryptoStream.prototype.end = function(data) {
  if (data) this.write(data)
  this.emit("data", this._cipher.final(this.outputEncoding))
  this.emit("end");
}

function coearseOpts (opts) {
  return 'string' == typeof opts ? {key: opts, algorithm: 'aes-256-cbc'} : opts
}
var EncryptStream = function(opts) {
  opts = coearseOpts(opts)
  EncryptStream.super_.call(this, opts, crypto.createDecipher(opts.algorithm, opts.key));
}

util.inherits(EncryptStream, CryptoStream);
exports.EncryptStream = EncryptStream;

var DecryptStream = function(opts) {
  opts = coearseOpts(opts)
  DecryptStream.super_.call(this, opts, crypto.createDecipher(opts.algorithm, opts.key));
}

util.inherits(DecryptStream, CryptoStream);
exports.DecryptStream = DecryptStream;
<commit_msg>cryptostream: in EncryptStream use createCipher<commit_after>var crypto = require('crypto');
var util = require('util');
var Stream = require('stream').Stream

function CryptoStream(opts, cipher) {
  this._key = opts.key;
  this._cipher = cipher;
  this.inputEncoding = opts.inputEncoding;
  this.outputEncoding = opts.outputEncoding;
  this.readable = this.writable = true
}

util.inherits(CryptoStream, Stream);
exports.CryptoStream = CryptoStream;

CryptoStream.prototype.write = function(data) {
  this.emit("data", this._cipher.update(data, this.inputEncoding, this.outputEncoding));
  return true
}

CryptoStream.prototype.end = function(data) {
  if (data) this.write(data)
  this.emit("data", this._cipher.final(this.outputEncoding))
  this.emit("end");
}

function coearseOpts (opts) {
  return 'string' == typeof opts ? {key: opts, algorithm: 'aes-256-cbc'} : opts
}
var EncryptStream = function(opts) {
  opts = coearseOpts(opts)
  EncryptStream.super_.call(this, opts, crypto.createCipher(opts.algorithm, opts.key));
}

util.inherits(EncryptStream, CryptoStream);
exports.EncryptStream = EncryptStream;

var DecryptStream = function(opts) {
  opts = coearseOpts(opts)
  DecryptStream.super_.call(this, opts, crypto.createDecipher(opts.algorithm, opts.key));
}

util.inherits(DecryptStream, CryptoStream);
exports.DecryptStream = DecryptStream;
<|endoftext|>


<commit_before>"use strict";

module.exports = onbar;

var util = require("util"),
    barsUtil = require("../util/bars"),
    stoch = require("../indicators/stoch"),
    ema = require("../indicators/ema"),
    orderUtil = require("../util/order");

var SETUP = {
    instruments: {
        "EUR_USD": true,
        "USD_JPY": true,
        "GBP_USD": true,
        "EUR_GBP": true,
        "EUR_JPY": true,
        "USD_CAD": true,
        "AUD_USD": true,
        "GBP_JPY": true
    },

    granularity: "M5",
    count: 100,
    units: 100
};

function onbar(bar) {
    var instruments = SETUP.instruments,
        granularity = SETUP.granularity,
        count = SETUP.count,
        units = SETUP.units,
        instrument = bar.instrument;

    if (!instruments[instrument] || bar.granularity !== granularity) {
        return;
    }

    util.log(bar.time, instrument, bar.granularity, bar.volume);

    barsUtil.getHistBars({
        instrument: instrument,
        granularity: granularity,
        count: count + 1
    }, function (err, bars) {
        var closes,
            lastClose,
            highs,
            lows,
            slowStoch,
            fastStoch,
            lastSlow,
            lastFast,
            emaSeries,
            lastEma,
            side;

        if (err) {
            util.log(err);
            return;
        }

        bars.splice(0, 1); // remove first element, because it is incomplete
        bars = bars.reverse(); // we need oldest-0 / newest-last

        closes = bars.map(function (x) {
            return x.closeMid;
        });
        lastClose = closes.slice(-1)[0];

        highs = bars.map(function (x) {
            return x.highMid;
        });

        lows = bars.map(function (x) {
            return x.lowMid;
        });

        slowStoch = stoch(closes, highs, lows, 21, 4);
        fastStoch = stoch(closes, highs, lows, 5, 2);
        lastSlow = slowStoch.d.slice(-1)[0];
        lastFast = fastStoch.k.slice(-1)[0];

        util.log("Hist Bars loaded for", instrument,
            "slow", lastSlow.toFixed(2), "fast", lastFast.toFixed(2));

        if (lastSlow < 20 && lastFast > 80) {
            side = "sell";
        }
        if (lastSlow > 80 && lastFast < 20) {
            side = "buy";
        }

        if (!side) {
            return;
        }

        emaSeries = ema(closes, 20);
        lastEma = emaSeries.slice(-1)[0];

        util.log("Testing with EMA", instrument, side,
            "close", lastClose.toFixed(2), "ema", lastEma.toFixed(2));

        if ((side === "sell" && lastClose < lastEma) ||
            (side === "buy" && lastClose > lastEma)) {

            orderUtil.fillOrder({
                instrument: instrument,
                type: "market",
                side: side,
                units: units,
                trailingStop: 20
            }, function (orderErr, trade) {
                if (!orderErr) {
                    util.log(trade.time, instrument, side, trade.price);
                } else {
                    util.log(orderErr);
                }
            });
        }
    });
}
<commit_msg>fix(onbar): fix fillOrder call<commit_after>"use strict";

module.exports = onbar;

var util = require("util"),
    config = require("../util/config"),
    barsUtil = require("../util/bars"),
    stoch = require("../indicators/stoch"),
    ema = require("../indicators/ema"),
    orderUtil = require("../util/order");

var SETUP = {
    instruments: {
        "EUR_USD": true,
        "USD_JPY": true,
        "GBP_USD": true,
        "EUR_GBP": true,
        "EUR_JPY": true,
        "USD_CAD": true,
        "AUD_USD": true,
        "GBP_JPY": true
    },

    granularity: "M5",
    count: 100,
    units: 100
};

function onbar(bar) {
    var instruments = SETUP.instruments,
        granularity = SETUP.granularity,
        count = SETUP.count,
        units = SETUP.units,
        instrument = bar.instrument,
        pip = config.pips[instrument];

    if (!instruments[instrument] || bar.granularity !== granularity) {
        return;
    }

    util.log(bar.time, instrument, bar.granularity, bar.volume);

    barsUtil.getHistBars({
        instrument: instrument,
        granularity: granularity,
        count: count + 1
    }, function (err, bars) {
        var closes,
            lastClose,
            highs,
            lows,
            slowStoch,
            fastStoch,
            lastSlow,
            lastFast,
            emaSeries,
            lastEma,
            side;

        if (err) {
            util.log(err);
            return;
        }

        bars.splice(0, 1); // remove first element, because it is incomplete
        bars = bars.reverse(); // we need oldest-0 / newest-last

        closes = bars.map(function (x) {
            return x.mid.c;
        });
        lastClose = closes.slice(-1)[0];

        highs = bars.map(function (x) {
            return x.mid.h;
        });

        lows = bars.map(function (x) {
            return x.mid.l;
        });

        slowStoch = stoch(closes, highs, lows, 21, 4);
        fastStoch = stoch(closes, highs, lows, 5, 2);
        lastSlow = slowStoch.d.slice(-1)[0];
        lastFast = fastStoch.k.slice(-1)[0];

        util.log("Hist Bars loaded for", instrument,
            "slow", lastSlow.toFixed(2), "fast", lastFast.toFixed(2));

        if (lastSlow < 20 && lastFast > 80) {
            side = "sell";
        }
        if (lastSlow > 80 && lastFast < 20) {
            side = "buy";
        }

        if (!side) {
            return;
        }

        emaSeries = ema(closes, 20);
        lastEma = emaSeries.slice(-1)[0];

        util.log("Testing with EMA", instrument, side,
            "close", lastClose.toFixed(2), "ema", lastEma.toFixed(2));

        if ((side === "sell" && lastClose < lastEma) ||
            (side === "buy" && lastClose > lastEma)) {

            orderUtil.fillOrder({
                instrument: instrument,
                type: "MARKET",
                side: side,
                units: side === "buy" ? units : -units,
                trailingStopLossOnFill: {
                    distance: (20 * pip).toPrecision(2)
                }

            }, function (orderErr) {
                if (orderErr) {
                    util.log(orderErr);
                }
            });
        }
    });
}
<|endoftext|>


<commit_before>function star_click(e) {
  var starlink = $(this);
  var csrf_token = $("meta[name='csrf-token']").attr('content');
  starlink.addClass('fa-spin');
  $.ajax('/star/' + $(this).data('id'), {
    type: 'POST',
    data: {
      csrf_token: csrf_token
    },
    dataType: 'json',
    complete: function() {
      starlink.removeClass('fa-spin');
      // TODO: Show error
    },
    success: function(data) {
      console.log(data);
      if (data.is_starred === true) {
        starlink.removeClass('fa-star-o').addClass('fa-star');
      } else {
        starlink.removeClass('fa-star').addClass('fa-star-o');
      };
    }
  });
  e.preventDefault();
  return false;
};

$(function() {
  var handleGroupClick = function(){
    // replaces the group with individual stickies when clicked
    $('#stickie-area').on('click', 'li.grouped', function(e){
      e.preventDefault();
      var group = $(this);
      $($.map(group.children(), function(node){
        return "
" +
                 "" + $(node).html() + " \

";
        }).join(""))
      .insertBefore(group);
      $(group).remove();
      $(".pstar").off().click(star_click);
    });
  };
  handleGroupClick();
  $(".pstar").off().click(star_click);
});
<commit_msg>Are DOM updates faster if we don't work with text?<commit_after>function star_click(e) {
  var starlink = $(this);
  var csrf_token = $("meta[name='csrf-token']").attr('content');
  starlink.addClass('fa-spin');
  $.ajax('/star/' + $(this).data('id'), {
    type: 'POST',
    data: {
      csrf_token: csrf_token
    },
    dataType: 'json',
    complete: function() {
      starlink.removeClass('fa-spin');
      // TODO: Show error
    },
    success: function(data) {
      if (data.is_starred === true) {
        starlink.removeClass('fa-star-o').addClass('fa-star');
      } else {
        starlink.removeClass('fa-star').addClass('fa-star-o');
      };
    }
  });
  e.preventDefault();
  return false;
};

$(function() {
  var outerTemplate = document.createElement('li');
  outerTemplate.setAttribute('class', 'col-xs-12 col-md-3 col-sm-4 animated shake');
  var innerTemplate = document.createElement('a');
  innerTemplate.setAttribute('class', 'stickie');
  innerTemplate.setAttribute('rel', 'bookmark');

  var handleGroupClick = function(){
    // replaces the group with individual stickies when clicked
    $('#stickie-area').on('click', 'li.grouped', function(e){
      e.preventDefault();
      var group = this, parent=group.parentNode;

      for (var i = 0; i < group.children.length; i++) {
        var node = group.children[i];
        outer = outerTemplate.cloneNode(false);
        inner = innerTemplate.cloneNode(false);
        inner.setAttribute('href', node.getAttribute('data-href'));
        while (node.firstChild) {
          inner.appendChild(node.firstChild);
        }
        outer.appendChild(inner);
        parent.insertBefore(outer, group);
      }

      parent.removeChild(group);
      $(".pstar").off().click(star_click);
    });
  };
  handleGroupClick();
  $(".pstar").off().click(star_click);
});
<|endoftext|>


<commit_before>require([
    'hammerjs',
    'jquery',
    'wf-js-uicomponents/scroll_list/ScrollList',
    'wf-js-uicomponents/scroll_bar/ScrollBar',
    'wf-js-uicomponents/layouts/ItemSizeCollection',
    'wf-js-uicomponents/awesome_map/BoundaryInterceptor',
    'wf-js-uicomponents/awesome_map/ScaleInterceptor',
    'wf-js-uicomponents/awesome_map/SwipeInterceptor',
    'wf-js-common/DeviceInfo',
    'wf-js-common/BrowserInfo',
    'wf-js-common/Url',
    'wf-js-common/DOMUtil',
    'wf-js-common/console',
    'hammerjs.fakemultitouch',
    'hammerjs.showtouches'
], function(
    Hammer,
    $,
    ScrollList,
    ScrollBar,
    ItemSizeCollection,
    BoundaryInterceptor,
    ScaleInterceptor,
    SwipeInterceptor,
    DeviceInfo,
    BrowserInfo,
    Url,
    DOMUtil,
    console
) {
    'use strict';

    //---------------------------------------------------------
    // Initialize ViewerComponent
    //---------------------------------------------------------

    function generateItemSizes(length) {
        // NOTE: Interested in retina canvas performance?
        // See: http://www.scirra.com/forum/retina-ios-performance-problem-fix-please-test_topic58742.html
        var tallItem = { height: 1022, width: 766 };
        var wideItem = { height: 766, width: 1022 };
        var result = [];
        for (var i = 0; i < length; i++) {
            var item = (i % 2 === 0) ? tallItem : wideItem;
            result.push(item);
        }

        return result;
    }

    function createPage(container, pageIndex, scale, width, height) {
        var pixelRatio = DeviceInfo.devicePixelRatio;

        // Create the canvas element.
        var canvas = document.createElement('canvas');
        canvas.style.position = 'absolute';

        // NOTE: Account for retina displays! (Incl setting ctx.scale below.)
        canvas.height = height * pixelRatio;
        canvas.width = width * pixelRatio;
        canvas.style.height = height + 'px';
        canvas.style.width = width + 'px';

        // Initialize the drawing context.
        var ctx = canvas.getContext('2d');
        ctx.scale(pixelRatio, pixelRatio);
        ctx.fillStyle = '#fff';
        ctx.fillRect(0, 0, width, height);

        // Render the page label.
        ctx.fillStyle = '#333';
        ctx.font = 'bold 20px sans-serif';
        ctx.textBaseline = 'top';
        ctx.textAlign = 'center';
        ctx.fillText('Page ' + (pageIndex + 1), width / 2, 5);

        // Render the canvas checkerboard.
        var checkerboardMargin = 30;
        var checkerboardSquareCount = 10;
        var exactCheckerboardHeight = height - checkerboardMargin * 2;
        var exactCheckerboardWidth = width - checkerboardMargin * 2;
        var excessCheckerboardHeight = exactCheckerboardHeight % checkerboardSquareCount;
        var excessCheckerboardWidth = exactCheckerboardWidth % checkerboardSquareCount;
        var squareHeight = (exactCheckerboardHeight - excessCheckerboardHeight) / checkerboardSquareCount;
        var squareWidth = (exactCheckerboardWidth - excessCheckerboardWidth) / checkerboardSquareCount;
        var patternLeft = checkerboardMargin + (excessCheckerboardWidth / 2);
        var patternTop = checkerboardMargin + (excessCheckerboardHeight / 2);
        var patternHeight = squareHeight * checkerboardSquareCount;
        var patternWidth = squareWidth * checkerboardSquareCount;

        var patternCanvas = document.createElement('canvas');
        patternCanvas.height = squareHeight * 2;
        patternCanvas.width = squareWidth * 2;

        // Draw if we have non-zero dimensions to draw.
        if (squareWidth && squareHeight) {
            var patternCtx = patternCanvas.getContext('2d');
            patternCtx.fillStyle = (pageIndex % 2 === 0) ? '#69c' : '#c96';
            patternCtx.fillRect(0, 0, squareWidth, squareHeight);
            patternCtx.fillRect(squareWidth, squareHeight, squareWidth, squareHeight);

            var pattern = ctx.createPattern(patternCanvas, 'repeat');
            ctx.fillStyle = pattern;
            ctx.translate(patternLeft, patternTop);
            ctx.fillRect(0, 0, patternWidth, patternHeight);
        }

        // Append to the container.
        container.appendChild(canvas);
    }

    function updateZoomPercentage() {
        if (!scrollList) {
            return;
        }
        $('#zoomTo').val(Math.floor(scrollList.getScale() * 100));
    }

    var url = new Url(window.location);
    var urlParams = url.getParams();
    var scrollMode = urlParams.scroll || (DeviceInfo.desktop ? 'flow' : 'peek');
    var fitMode = urlParams.fit || 'auto';
    var totalPages = +urlParams.totalPages || 100;
    var minNumberOfVirtualItems = scrollMode === 'flow' ? (DeviceInfo.desktop ? 15 : 9) : (DeviceInfo.desktop ? 5 : 3);

    var itemSizeCollection = new ItemSizeCollection({
        maxWidth: 1022,
        maxHeight: 1022,
        items: generateItemSizes(totalPages)
    });

    var scrollList = window.scrollList = new ScrollList($('#document')[0], itemSizeCollection, {
        gap: 2,
        mode: scrollMode,
        fit: fitMode,
        minNumberOfVirtualItems: minNumberOfVirtualItems,
        padding: 1,
        scaleLimits: { minimum: 0.25, maximum: 3 }
    });

    // If on desktop, instantiate a scrollBar
    if (DeviceInfo.desktop) {
        var parent = document.getElementById('scrollbar-parent');
        var scrollbarOptions = {};
        scrollbarOptions.scrollbarId = 'scrollbar';
        scrollbarOptions.scrollbarContainerId = 'scrollbar-container';
        window.scrollBar = new ScrollBar(scrollList, parent, scrollbarOptions);
    }

    scrollList.onContentRequested(function(sender, args) {
        var itemIndex = args.itemIndex;
        console.log('content requested for', itemIndex);
        createPage(args.placeholder.contentContainer, itemIndex,
            args.scaleToFit, args.width, args.height);
    });

    scrollList.onContentRemoved(function(sender, args) {
        console.log('content removed for', args.itemIndex);
    });

    scrollList.onCurrentItemChanged(function(sender, args) {
        console.log('current item changed to', args.itemIndex);
        $('#page').val(args.itemIndex + 1);
        updateZoomPercentage();
    });

    scrollList.onInteraction(function(sender, args) {
        console.log(args.event.type, args);
    });

    scrollList.onInteractionStarted(function(/*sender*/) {
        console.log('interaction started');
    });

    scrollList.onInteractionFinished(function(/*sender*/) {
        console.log('interaction finished');
    });

    scrollList.onPlaceholderRendered(function(sender, args) {
        console.log('placeholder rendered for', args.itemIndex);
        // BEWARE: Doing big stuff here can interrupt swipe animations!
        args.placeholder.contentContainer.style.backgroundColor = '#fff';
    });

    scrollList.onScaleChanged(function(sender, args) {
        console.log('scale changed to', args.scale);
        updateZoomPercentage();
    });

    scrollList.onScrollPositionChanged(function(sender, args) {
        console.log('scroll position changed to', args.x, args.y);
    });

    scrollList.onItemsInserted(function(sender, args) {
        totalPages += args.count;
        $('#totalPages').val(totalPages);
    });

    scrollList.render();

    //---------------------------------------------------------
    // Hammer touch simulation
    //---------------------------------------------------------

    if (BrowserInfo.getBrowser() !== 'MSIE') {
        Hammer.plugins.showTouches();
        Hammer.plugins.fakeMultitouch();
    }

    //---------------------------------------------------------
    // UI control wiring
    //---------------------------------------------------------

    $(function() {

        $(window).on('resize', function() { console.log('resize'); });
        $(window).on('orientationchange', function() { console.log('orientationchange'); });
        $(window).on('scroll', function() { console.log('scroll'); });

        DOMUtil.dismissIOS7VirtualKeyboardOnOrientationChange();
        DOMUtil.preventIOS7WindowScroll();

        $('#scrollMode').val(scrollMode).change(function() {
            window.location = url.addParam('scroll', this.value).toString();
        });

        $('#fitMode').val(fitMode).change(function() {
            window.location = url.addParam('fit', this.value).toString();
        });

        $('#zoomToScale').submit(function() {
            var scale = parseInt(this.elements.zoomTo.value, 10) / 100;
            scrollList.zoomTo({ scale: scale });
            $(':focus').blur();
            return false;
        });

        $('#toggle-disabled').click(function() {
            if ($(this).is(':checked')) {
                scrollList.disable();
            }
            else {
                scrollList.enable();
            }
        });

        $('#jumpToPage').submit(function() {
            scrollList.scrollTo({
                index: this.elements.page.value - 1
            });
            $(':focus').blur();
            return false;
        });

        $('#totalPages').val(totalPages).change(function() {
            window.location = url.addParam('totalPages', this.value).toString();
        });

        // Hide iOS browser chrome
        $('body').scrollTop(0);
    });
});
<commit_msg>Add KeyNavigator instantiation to the scrollList demo<commit_after>require([
    'hammerjs',
    'jquery',
    'wf-js-uicomponents/scroll_list/ScrollList',
    'wf-js-uicomponents/scroll_bar/ScrollBar',
    'wf-js-uicomponents/scroll_list/KeyNavigator',
    'wf-js-uicomponents/layouts/ItemSizeCollection',
    'wf-js-uicomponents/awesome_map/BoundaryInterceptor',
    'wf-js-uicomponents/awesome_map/ScaleInterceptor',
    'wf-js-uicomponents/awesome_map/SwipeInterceptor',
    'wf-js-common/DeviceInfo',
    'wf-js-common/BrowserInfo',
    'wf-js-common/Url',
    'wf-js-common/DOMUtil',
    'wf-js-common/console',
    'hammerjs.fakemultitouch',
    'hammerjs.showtouches'
], function(
    Hammer,
    $,
    ScrollList,
    ScrollBar,
    KeyNavigator,
    ItemSizeCollection,
    BoundaryInterceptor,
    ScaleInterceptor,
    SwipeInterceptor,
    DeviceInfo,
    BrowserInfo,
    Url,
    DOMUtil,
    console
) {
    'use strict';

    //---------------------------------------------------------
    // Initialize ViewerComponent
    //---------------------------------------------------------

    function generateItemSizes(length) {
        // NOTE: Interested in retina canvas performance?
        // See: http://www.scirra.com/forum/retina-ios-performance-problem-fix-please-test_topic58742.html
        var tallItem = { height: 1022, width: 766 };
        var wideItem = { height: 766, width: 1022 };
        var result = [];
        for (var i = 0; i < length; i++) {
            var item = (i % 2 === 0) ? tallItem : wideItem;
            result.push(item);
        }

        return result;
    }

    function createPage(container, pageIndex, scale, width, height) {
        var pixelRatio = DeviceInfo.devicePixelRatio;

        // Create the canvas element.
        var canvas = document.createElement('canvas');
        canvas.style.position = 'absolute';

        // NOTE: Account for retina displays! (Incl setting ctx.scale below.)
        canvas.height = height * pixelRatio;
        canvas.width = width * pixelRatio;
        canvas.style.height = height + 'px';
        canvas.style.width = width + 'px';

        // Initialize the drawing context.
        var ctx = canvas.getContext('2d');
        ctx.scale(pixelRatio, pixelRatio);
        ctx.fillStyle = '#fff';
        ctx.fillRect(0, 0, width, height);

        // Render the page label.
        ctx.fillStyle = '#333';
        ctx.font = 'bold 20px sans-serif';
        ctx.textBaseline = 'top';
        ctx.textAlign = 'center';
        ctx.fillText('Page ' + (pageIndex + 1), width / 2, 5);

        // Render the canvas checkerboard.
        var checkerboardMargin = 30;
        var checkerboardSquareCount = 10;
        var exactCheckerboardHeight = height - checkerboardMargin * 2;
        var exactCheckerboardWidth = width - checkerboardMargin * 2;
        var excessCheckerboardHeight = exactCheckerboardHeight % checkerboardSquareCount;
        var excessCheckerboardWidth = exactCheckerboardWidth % checkerboardSquareCount;
        var squareHeight = (exactCheckerboardHeight - excessCheckerboardHeight) / checkerboardSquareCount;
        var squareWidth = (exactCheckerboardWidth - excessCheckerboardWidth) / checkerboardSquareCount;
        var patternLeft = checkerboardMargin + (excessCheckerboardWidth / 2);
        var patternTop = checkerboardMargin + (excessCheckerboardHeight / 2);
        var patternHeight = squareHeight * checkerboardSquareCount;
        var patternWidth = squareWidth * checkerboardSquareCount;

        var patternCanvas = document.createElement('canvas');
        patternCanvas.height = squareHeight * 2;
        patternCanvas.width = squareWidth * 2;

        // Draw if we have non-zero dimensions to draw.
        if (squareWidth && squareHeight) {
            var patternCtx = patternCanvas.getContext('2d');
            patternCtx.fillStyle = (pageIndex % 2 === 0) ? '#69c' : '#c96';
            patternCtx.fillRect(0, 0, squareWidth, squareHeight);
            patternCtx.fillRect(squareWidth, squareHeight, squareWidth, squareHeight);

            var pattern = ctx.createPattern(patternCanvas, 'repeat');
            ctx.fillStyle = pattern;
            ctx.translate(patternLeft, patternTop);
            ctx.fillRect(0, 0, patternWidth, patternHeight);
        }

        // Append to the container.
        container.appendChild(canvas);
    }

    function updateZoomPercentage() {
        if (!scrollList) {
            return;
        }
        $('#zoomTo').val(Math.floor(scrollList.getScale() * 100));
    }

    var url = new Url(window.location);
    var urlParams = url.getParams();
    var scrollMode = urlParams.scroll || (DeviceInfo.desktop ? 'flow' : 'peek');
    var fitMode = urlParams.fit || 'auto';
    var totalPages = +urlParams.totalPages || 100;
    var minNumberOfVirtualItems = scrollMode === 'flow' ? (DeviceInfo.desktop ? 15 : 9) : (DeviceInfo.desktop ? 5 : 3);

    var itemSizeCollection = new ItemSizeCollection({
        maxWidth: 1022,
        maxHeight: 1022,
        items: generateItemSizes(totalPages)
    });

    var scrollList = window.scrollList = new ScrollList($('#document')[0], itemSizeCollection, {
        gap: 2,
        mode: scrollMode,
        fit: fitMode,
        minNumberOfVirtualItems: minNumberOfVirtualItems,
        padding: 1,
        scaleLimits: { minimum: 0.25, maximum: 3 }
    });

    // Instantiate a KeyNavigator
    window._keyNavigator = new KeyNavigator(scrollList);

    // If on desktop, instantiate a scrollBar
    if (DeviceInfo.desktop) {
        var parent = document.getElementById('scrollbar-parent');
        var scrollbarOptions = {};
        scrollbarOptions.scrollbarId = 'scrollbar';
        scrollbarOptions.scrollbarContainerId = 'scrollbar-container';
        window.scrollBar = new ScrollBar(scrollList, parent, scrollbarOptions);
    }

    scrollList.onContentRequested(function(sender, args) {
        var itemIndex = args.itemIndex;
        console.log('content requested for', itemIndex);
        createPage(args.placeholder.contentContainer, itemIndex,
            args.scaleToFit, args.width, args.height);
    });

    scrollList.onContentRemoved(function(sender, args) {
        console.log('content removed for', args.itemIndex);
    });

    scrollList.onCurrentItemChanged(function(sender, args) {
        console.log('current item changed to', args.itemIndex);
        $('#page').val(args.itemIndex + 1);
        updateZoomPercentage();
    });

    scrollList.onInteraction(function(sender, args) {
        console.log(args.event.type, args);
    });

    scrollList.onInteractionStarted(function(/*sender*/) {
        console.log('interaction started');
    });

    scrollList.onInteractionFinished(function(/*sender*/) {
        console.log('interaction finished');
    });

    scrollList.onPlaceholderRendered(function(sender, args) {
        console.log('placeholder rendered for', args.itemIndex);
        // BEWARE: Doing big stuff here can interrupt swipe animations!
        args.placeholder.contentContainer.style.backgroundColor = '#fff';
    });

    scrollList.onScaleChanged(function(sender, args) {
        console.log('scale changed to', args.scale);
        updateZoomPercentage();
    });

    scrollList.onScrollPositionChanged(function(sender, args) {
        console.log('scroll position changed to', args.x, args.y);
    });

    scrollList.onItemsInserted(function(sender, args) {
        totalPages += args.count;
        $('#totalPages').val(totalPages);
    });

    scrollList.render();

    //---------------------------------------------------------
    // Hammer touch simulation
    //---------------------------------------------------------

    if (BrowserInfo.getBrowser() !== 'MSIE') {
        Hammer.plugins.showTouches();
        Hammer.plugins.fakeMultitouch();
    }

    //---------------------------------------------------------
    // UI control wiring
    //---------------------------------------------------------

    $(function() {

        $(window).on('resize', function() { console.log('resize'); });
        $(window).on('orientationchange', function() { console.log('orientationchange'); });
        $(window).on('scroll', function() { console.log('scroll'); });

        DOMUtil.dismissIOS7VirtualKeyboardOnOrientationChange();
        DOMUtil.preventIOS7WindowScroll();

        $('#scrollMode').val(scrollMode).change(function() {
            window.location = url.addParam('scroll', this.value).toString();
        });

        $('#fitMode').val(fitMode).change(function() {
            window.location = url.addParam('fit', this.value).toString();
        });

        $('#zoomToScale').submit(function() {
            var scale = parseInt(this.elements.zoomTo.value, 10) / 100;
            scrollList.zoomTo({ scale: scale });
            $(':focus').blur();
            return false;
        });

        $('#toggle-disabled').click(function() {
            if ($(this).is(':checked')) {
                scrollList.disable();
            }
            else {
                scrollList.enable();
            }
        });

        $('#jumpToPage').submit(function() {
            scrollList.scrollTo({
                index: this.elements.page.value - 1
            });
            $(':focus').blur();
            return false;
        });

        $('#totalPages').val(totalPages).change(function() {
            window.location = url.addParam('totalPages', this.value).toString();
        });

        // Hide iOS browser chrome
        $('body').scrollTop(0);
    });
});
<|endoftext|>


<commit_before>var _ = require('lodash');
var inflection = require('inflection');

module.exports = function Deserializer (data, serverRelations) {

  var clientRelations = data.data.relationships;
  var result = data.data.attributes || {};
  if (_.isPlainObject(clientRelations)) {
    _.each(clientRelations, function (clientRelation, clientRelationName) {
      var serverRelation = serverRelations[clientRelationName];

      if (_.isPlainObject(serverRelation)) {
        var relationType = null;
        var relationValue = null;
        var fkSuffix = null;
        var fk = null;
        if (_.isArray(clientRelation.data)) {
          relationType = _.result(_.find(clientRelation.data, 'type'), 'type');
          relationValue = _.map(clientRelation.data, function (val) {
            return val.id;
          });
          fkSuffix = 'Ids';
        } else {
          relationType = clientRelation.data.type;
          relationValue = clientRelation.data.id;
          fkSuffix = 'Id';
        }

        relationType = inflection.singularize(relationType);

        if (relationType === serverRelation.model) {
          if (serverRelation.foreignKey) {
            fk = serverRelation.foreignKey;
          } else {

            relationType = inflection.camelize(relationType, true);
            fk = relationType + fkSuffix;
          }
          result[fk] = relationValue;
        }
      }
    });
  }

  return result;

};
<commit_msg>Fix error if relation empty<commit_after>var _ = require('lodash');
var inflection = require('inflection');

module.exports = function Deserializer (data, serverRelations) {

  var clientRelations = data.data.relationships;
  var result = data.data.attributes || {};
  if (_.isPlainObject(clientRelations)) {
    _.each(clientRelations, function (clientRelation, clientRelationName) {
      var serverRelation = serverRelations[clientRelationName];

      if (_.isPlainObject(serverRelation)) {
        var relationType = null;
        var relationValue = null;
        var fkSuffix = null;
        var fk = null;
        if (_.isArray(clientRelation.data)) {
          if (_.isEmpty(clientRelation.data)) {
            return;
          }
          relationType = _.result(_.find(clientRelation.data, 'type'), 'type');
          relationValue = _.map(clientRelation.data, function (val) {
            return val.id;
          });
          fkSuffix = 'Ids';
        } else {
          if (clientRelation.data === null) {
            return;
          }
          relationType = clientRelation.data.type;
          relationValue = clientRelation.data.id;
          fkSuffix = 'Id';
        }

        relationType = inflection.singularize(relationType);

        if (relationType === serverRelation.model) {
          if (serverRelation.foreignKey) {
            fk = serverRelation.foreignKey;
          } else {

            relationType = inflection.camelize(relationType, true);
            fk = relationType + fkSuffix;
          }
          result[fk] = relationValue;
        }
      }
    });
  }

  return result;

};
<|endoftext|>


<commit_before>'use strict';

let EPGPCharacter = require('./models/character');
let EPGPItem = require('./models/item');
let EPGPRaid = require('./models/raid');
let characterService = require('../character/service');
let guildService = require('../guild/service');
let _ = require('lodash');
let ItemString = require('wow-itemstring');
let moment = require('moment-timezone');

function getEPGP(guildId, characterName) {
  return new Promise((resolve, reject) => {
    characterService
      .getCharacters(guildId, characterName)
      .then((character) => {
        if(!character) {
          reject({error: {message: `Unable to find character: ${character}`}});
        }

        EPGPCharacter
          .find({characterId: character._id})
          .exec()
          .then((epgpData) => {
            resolve(epgpData);
          }, (err) => {
            reject({error: {message: err}});
          });
      }, (err) => {
        reject({error: {message: err}});
      });
  });
}

function getLoot(guildId, raidDate) {
  return new Promise((resolve, reject) => {
    let LATEST = 'latest';
    let populateItemPromises = [];
    let raids = [];
    let raidIndex = 0;

    getRaids(guildId)
      .then((raidData) => {
        let query = null;
        raids = raidData;

        if (raids.length === 0) {
          return reject({error: {message: 'No raids have been uploaded yet.'}});
        }

        let raidId = raids[0]._id;

        if (raidDate !== LATEST) {
          raidIndex = _.findIndex(raids, {raidDate: moment(raidDate, 'YYYY-MM-DD').format('MM-DD-YYYY')});

          if (raidIndex === -1) {
            return reject({error: {message: 'Unable to find loot for the requested raid.'}});
          }

          raidId = raids[raidIndex]._id;
        }

        return EPGPItem
          .find({raidId: raidId})
          .populate({
            path: 'characterId',
            select: 'name'
          })
          .populate({
            path: 'itemId',
            select: 'item' // 'name context level itemLevel stats quality icon isWeapon weaponInfo itemClass inventoryType'
          })
          .exec();
      }, (err) => {
        reject({error: {message: err}});
      })
      .then((items) => {
        if (raidIndex === -1) {
          return Promise.reject();
        }

        _.forEach(items, (item) => {

          populateItemPromises.push(
            new Promise((resolve, reject) => {
              new ItemString()
                .populate(item.itemId.item)
                .then((itemObj) => {

                  resolve({
                    characterId: item.characterId,
                    cost: item.cost,
                    raidId: item.raidId,
                    timestamp: item.timestamp,
                    itemId: {
                      itemClass: itemObj.getClass(),
                      context: itemObj.getContext(),
                      icon: itemObj.getIcon(),
                      id: itemObj.getId(),
                      inventoryType: itemObj.getInventoryType(),
                      isItemSet: itemObj.isItemSet(),
                      isWeapon: itemObj.isWeapon(),
                      itemLevel: itemObj.getItemLevel(),
                      itemSet: itemObj.getItemSet(),
                      itemString: itemObj._itemString,
                      level: itemObj.getLevel(),
                      name: itemObj.getName(),
                      quality: itemObj.getQuality(),
                      stats: itemObj.getStats(),
                      weaponInfo: itemObj.getWeaponInfo()
                    }
                  });
                }, (err) => {
                  reject({error: {message: err}});
                });
            })
          );
        });

        return Promise.all(populateItemPromises);
      }, (err) => {
        reject({error: {message: err}});
      })
      .then((items) => {
        if (raidIndex === -1) {
          reject({error: {message: 'Unable to determine raid index'}});
        }

        resolve({
          nextRaidDate: (raidIndex === 0) ? null : items.nextRaidDate = moment(raids[raidIndex - 1].raidDate, 'MM-DD-YYYY').format('YYYY-MM-DD'),
          prevRaidDate: (raidIndex === raids.length - 1) ? null : items.nextRaidDate = moment(raids[raidIndex + 1].raidDate, 'MM-DD-YYYY').format('YYYY-MM-DD'),
          raidDate: moment(raids[raidIndex].raidDate, 'MM-DD-YYYY').format('YYYY-MM-DD'),
          items: items
        });
      }, (err) => {
        reject({error: {message: err}});
      });
  });
}

function getMembersEPGP(guildId, ranks) {
  return new Promise((resolve, reject) => {
    characterService
      .getCharacters(guildId)
      .then((character) => {

        let populate = {
          path: 'characterId',
          select: 'name rank thumbnail level gender race class items spec'
        };

        if (ranks) {
          let parsed = ranks.split(',');

          populate.match = {
            rank: { $in: parsed },
            isDeleted: false
          }
        }

        return EPGPCharacter
          .find()
          .populate(populate)
          .exec();
      }, (err) => {
        reject({error: {message: err}});
      })
      .then((epgpData) => {
        resolve(
          _.sortBy(
            _.filter(epgpData, (o) => { return o.characterId; }),
            function(item) {
              return [item.characterId.name];
            }
          )
        );
      }, (err) => {
        reject({error: {message: err}});
      });
  });
}

function getRaid(guildName, raidDate) {
  return new Promise((resolve, reject) => {
    guildService
      .getGuild(guildName)
      .then((guild) => {
        if(!guild) {
          reject({error: {message: `Unable to find guild: ${guildName}`}});
        }

        return EPGPRaid
          .findOne({raidDate: raidDate})
          .exec();
      })
      .then((raid) => {
        resolve(raid);
      }, (err) => {
        reject({error: {message: err}});
      });
  });
};

function getRaids(guildId) {
  return EPGPRaid
          .find()
          .sort('-raidDate')
          .exec();
};

function getRaidersEPGP(guildId) {
  return new Promise((resolve, reject) => {
    characterService
      .getCharacters(guildId)
      .then((characters) => {

        return EPGPCharacter
          .find()
          .populate({
            path: 'characterId',
            select: 'name rank thumbnail level gender race class items spec',
            match: {
              rank: { $in: [0, 1, 4, 5] },
              isDeleted: false
            }
          })
          .exec();
      }, (err) => {
        reject({error: {message: err}});
      })
      .then((epgpData) => {
        resolve(
          _.sortBy(
            _.filter(epgpData, (o) => { return o.characterId; }),
            function(item) {
              return [item.characterId.name];
            }
          )
        );
      }, (err) => {
        reject({error: {message: err}});
      });
  });
}

function updateGuildConfig(epgpData) {
  return new Promise((resolve, reject) => {
    resolve(epgpData);
  });
}

module.exports = {
  getEPGP: getEPGP,
  getLoot: getLoot,
  getMembersEPGP: getMembersEPGP,
  getRaid: getRaid,
  getRaidersEPGP: getRaidersEPGP,
  updateGuildConfig: updateGuildConfig
};
<commit_msg>revert<commit_after>'use strict';

let EPGPCharacter = require('./models/character');
let EPGPItem = require('./models/item');
let EPGPRaid = require('./models/raid');
let characterService = require('../character/service');
let guildService = require('../guild/service');
let _ = require('lodash');
let ItemString = require('wow-itemstring');

function getEPGP(guildId, characterName) {
  return new Promise((resolve, reject) => {
    characterService
      .getCharacters(guildId, characterName)
      .then((character) => {
        if(!character) {
          reject({error: {message: `Unable to find character: ${character}`}});
        }

        EPGPCharacter
          .find({characterId: character._id})
          .exec()
          .then((epgpData) => {
            resolve(epgpData);
          }, (err) => {
            reject({error: {message: err}});
          });
      }, (err) => {
        reject({error: {message: err}});
      });
  });
}

function getLoot(guildId, raidDate) {
  return new Promise((resolve, reject) => {
    let LATEST = 'latest';
    let populateItemPromises = [];
    let raids = [];
    let raidIndex = 0;

    getRaids(guildId)
      .then((raidData) => {
        let query = null;
        raids = raidData;

        if (raids.length === 0) {
          return reject({error: {message: 'No raids have been uploaded yet.'}});
        }

        let raidId = raids[0]._id;

        if (raidDate !== LATEST) {
          raidIndex = _.findIndex(raids, {raidDate: raidDate});

          if (raidIndex === -1) {
            return reject({error: {message: 'Unable to find loot for the requested raid.'}});
          }

          raidId = raids[raidIndex]._id;
        }

        return EPGPItem
          .find({raidId: raidId})
          .populate({
            path: 'characterId',
            select: 'name'
          })
          .populate({
            path: 'itemId',
            select: 'item' // 'name context level itemLevel stats quality icon isWeapon weaponInfo itemClass inventoryType'
          })
          .exec();
      }, (err) => {
        reject({error: {message: err}});
      })
      .then((items) => {
        if (raidIndex === -1) {
          return Promise.reject();
        }

        _.forEach(items, (item) => {

          populateItemPromises.push(
            new Promise((resolve, reject) => {
              new ItemString()
                .populate(item.itemId.item)
                .then((itemObj) => {

                  resolve({
                    characterId: item.characterId,
                    cost: item.cost,
                    raidId: item.raidId,
                    timestamp: item.timestamp,
                    itemId: {
                      itemClass: itemObj.getClass(),
                      context: itemObj.getContext(),
                      icon: itemObj.getIcon(),
                      id: itemObj.getId(),
                      inventoryType: itemObj.getInventoryType(),
                      isItemSet: itemObj.isItemSet(),
                      isWeapon: itemObj.isWeapon(),
                      itemLevel: itemObj.getItemLevel(),
                      itemSet: itemObj.getItemSet(),
                      itemString: itemObj._itemString,
                      level: itemObj.getLevel(),
                      name: itemObj.getName(),
                      quality: itemObj.getQuality(),
                      stats: itemObj.getStats(),
                      weaponInfo: itemObj.getWeaponInfo()
                    }
                  });
                }, (err) => {
                  reject({error: {message: err}});
                });
            })
          );
        });

        return Promise.all(populateItemPromises);
      }, (err) => {
        reject({error: {message: err}});
      })
      .then((items) => {
        if (raidIndex === -1) {
          reject({error: {message: 'Unable to determine raid index'}});
        }

        resolve({
          nextRaidDate: (raidIndex === 0) ? null : items.nextRaidDate = raids[raidIndex - 1].raidDate,
          prevRaidDate: (raidIndex === raids.length - 1) ? null : items.nextRaidDate = raids[raidIndex + 1].raidDate,
          raidDate: raids[raidIndex].raidDate,
          items: items
        });
      }, (err) => {
        reject({error: {message: err}});
      });
  });
}

function getMembersEPGP(guildId, ranks) {
  return new Promise((resolve, reject) => {
    characterService
      .getCharacters(guildId)
      .then((character) => {

        let populate = {
          path: 'characterId',
          select: 'name rank thumbnail level gender race class items spec'
        };

        if (ranks) {
          let parsed = ranks.split(',');

          populate.match = {
            rank: { $in: parsed },
            isDeleted: false
          }
        }

        return EPGPCharacter
          .find()
          .populate(populate)
          .exec();
      }, (err) => {
        reject({error: {message: err}});
      })
      .then((epgpData) => {
        resolve(
          _.sortBy(
            _.filter(epgpData, (o) => { return o.characterId; }),
            function(item) {
              return [item.characterId.name];
            }
          )
        );
      }, (err) => {
        reject({error: {message: err}});
      });
  });
}

function getRaid(guildName, raidDate) {
  return new Promise((resolve, reject) => {
    guildService
      .getGuild(guildName)
      .then((guild) => {
        if(!guild) {
          reject({error: {message: `Unable to find guild: ${guildName}`}});
        }

        return EPGPRaid
          .findOne({raidDate: raidDate})
          .exec();
      })
      .then((raid) => {
        resolve(raid);
      }, (err) => {
        reject({error: {message: err}});
      });
  });
};

function getRaids(guildId) {
  return EPGPRaid
          .find()
          .sort('-raidDate')
          .exec();
};

function getRaidersEPGP(guildId) {
  return new Promise((resolve, reject) => {
    characterService
      .getCharacters(guildId)
      .then((characters) => {

        return EPGPCharacter
          .find()
          .populate({
            path: 'characterId',
            select: 'name rank thumbnail level gender race class items spec',
            match: {
              rank: { $in: [0, 1, 4, 5] },
              isDeleted: false
            }
          })
          .exec();
      }, (err) => {
        reject({error: {message: err}});
      })
      .then((epgpData) => {
        resolve(
          _.sortBy(
            _.filter(epgpData, (o) => { return o.characterId; }),
            function(item) {
              return [item.characterId.name];
            }
          )
        );
      }, (err) => {
        reject({error: {message: err}});
      });
  });
}

function updateGuildConfig(epgpData) {
  return new Promise((resolve, reject) => {
    resolve(epgpData);
  });
}

module.exports = {
  getEPGP: getEPGP,
  getLoot: getLoot,
  getMembersEPGP: getMembersEPGP,
  getRaid: getRaid,
  getRaidersEPGP: getRaidersEPGP,
  updateGuildConfig: updateGuildConfig
};
<|endoftext|>


<commit_before>var EventEmitter = require('events').EventEmitter
  , util = require('util')
  , es = require('event-stream')
  ;

var gitHooks = require('./hooks');

function DefaultFrame (stream, emitter) {
  var result;
}

function make (op, length, next) {
  var result = es.through(write);
  var params = {op: op};
  var pending = length;
  var data;
  function finisher (r) {
    if (--pending == 0) {
      next( );
    }
  }
  var hook = gitHooks('dummy', params, finisher);
  hook.name = op;
  hook.stream = result;
  hook.params = params;
  function value (chunk) {
    if (chunk) {
      data = chunk;
    }
    return data;
  }
  hook.value = value;
  if (gitHooks.isHook(op)) {
    params.arguments = arguments;
    function finish (r) {
      if (r) { return result.end(params.lines); };
      return result.end( );
    }
    // missing params.lines
    hook = gitHooks(op, params, finish);
  }
  function write (chunk) {
    this.emit('data', hook.value(chunk));
  }
  return hook;
}

function Stream (emitters, opts) {

  var s = es.through(writer, end);
  // var s = es.through(write, end);
  function writer (chunk) {
    // console.log('should event emit', chunk, arguments);
    function next ( ) {
      console.log('NEXT', arguments);
    }
    var chain = [ ];
    // chunk.stream.write(chunk.value(chunk.params));
    emitters.emit(chunk.name, chunk, next);
    this.emit('data', chunk);
  }
  /*
  function write (op, fetch, consume) {
    var params = {op: op};
    var result = es.through( );
    var chain = [ ];
    var hook = gitHooks('dummy', params, finisher);
    // take an incoming operation, like 'user', return a stream performing that
    // operation.
    var cancelled = false;
    function preventDefault ( ) {
      console.log("CANCELED");
      cancelled = true;
      result.end(null);
    }
    hook.preventDefault = preventDefault;
    function finisher (r) {
      if (!r) {
        cancelled = true;
      }
    };
    var handlers = emitters.listeners(op).length;
    var map = es.map(function (data, next) {
      var trigger = function trigger ( ) {
        // --handlers;
        console.log("LEFT", handlers);
        if (--handlers == 0) {
          result.emit('data', data);
          next(null, data);
        }
      }
      emitters.emit(op, hook, trigger);
      if (handlers == 0) {
        next(null, hook.value( ));
      }

    });

    chain.push(map);
    if (fetch) {
      var map = es.map(function (data, next) {
        next(null, fetch(data));
      });
      chain.push(map);
    }
    if (consume && fetch) {
      es.pipeline(result, chain, es.writeArray( function (err, body) {
        consume(err, body);
        result.end( );
      }));
    }

    this.emit('data', hook);
  }
  */
  function end ( ) {
    // when done
    // this.emit('data', '');
    this.end( );
  }

  function process (thing, cb) {
    // s.write(thing, cb);
    var handlers = emitters.listeners(thing).length;
    // function make (op, length, next) {
    var ev = make(thing, handlers, next);

    ev.stream.on('data', function (data) {
      console.log('LOG', 'data', data);
    });
    ev.stream.on('end', function (data) {
      console.log("END");
      if (data) {
        ev.value(data);
      }
      next( );
    });
    function next ( ) {
      cb(ev.value( ));
    }
    s.write(ev);
    return ev;
    // s.once('data', function (res
    // s.write(thing, fetch, consume);

  }

  s.process = process;

  return s;
}

module.exports = function init (opts) {
  // var emitter = new EventEmitter;
  // var emit = emitter.emit;
  var ev = new Events(opts);
  return ev;
};

function Events (opts) {
  EventEmitter.call(this);
  this.stream = Stream(this, opts);
}
util.inherits(Events, EventEmitter);
Events.prototype.user = function user (name, cb) {
  console.log('user', name);
  var hook = this.stream.process('user', function (result) {
    console.log('process user', arguments);
    cb(result);
  });
  var body = hook.params;
  params.args = [name];
  hook.stream.write.apply(hook.stream, params.args);
  hook.stream.end( );

}

if (!module.parent) {
  console.log('MAIN');
  var ev = module.exports( );
  ev.on('user', function (hook, next) {
    console.log('every user request', hook.value( ));
    hook.stream.pipe(es.writeArray( function (err, result) {
      console.log('found result', result);
      return next( );
    }));
  });
  ev.user('bewest', function fetch (value) {
    console.log('modify value here', value);
  });
}
<commit_msg>very sloppy kind of works<commit_after>var EventEmitter = require('events').EventEmitter
  , util = require('util')
  , es = require('event-stream')
  ;

var gitHooks = require('./hooks');

function DefaultFrame (stream, emitter) {
  var result;
}

function make (op, length, next) {
  var result = es.through(write);
  var params = {op: op};
  var pending = length;
  var data;
  function finisher (r) {
    console.log('PENDING', pending, 'left');
    if (--pending == 0) {
      next( );
    }
  }
  var hook = gitHooks('dummy', params, finisher);
  hook.name = op;
  hook.stream = result;
  hook.params = params;
  function value (chunk) {
    if (chunk) {
      data = chunk;
    }
    return data;
  }
  hook.value = value;
  if (gitHooks.isHook(op)) {
    params.arguments = arguments;
    function finish (r) {
      if (r) { return result.end(params.lines); };
      return result.end( );
    }
    // missing params.lines
    hook = gitHooks(op, params, finish);
  }
  function write (chunk) {
    this.emit('data', hook.value(chunk));
  }
  return hook;
}

function Stream (emitters, opts) {

  var s = es.through(writer, end);
  // var s = es.through(write, end);
  function writer (chunk) {
    // console.log('should event emit', chunk, arguments);
    function next ( ) {
      console.log('NEXT', arguments);
    }
    var chain = [ ];
    // chunk.stream.write(chunk.value(chunk.params));
    this.emit('data', chunk);
  }
  /*
  function write (op, fetch, consume) {
    var params = {op: op};
    var result = es.through( );
    var chain = [ ];
    var hook = gitHooks('dummy', params, finisher);
    // take an incoming operation, like 'user', return a stream performing that
    // operation.
    var cancelled = false;
    function preventDefault ( ) {
      console.log("CANCELED");
      cancelled = true;
      result.end(null);
    }
    hook.preventDefault = preventDefault;
    function finisher (r) {
      if (!r) {
        cancelled = true;
      }
    };
    var handlers = emitters.listeners(op).length;
    var map = es.map(function (data, next) {
      var trigger = function trigger ( ) {
        // --handlers;
        console.log("LEFT", handlers);
        if (--handlers == 0) {
          result.emit('data', data);
          next(null, data);
        }
      }
      emitters.emit(op, hook, trigger);
      if (handlers == 0) {
        next(null, hook.value( ));
      }

    });

    chain.push(map);
    if (fetch) {
      var map = es.map(function (data, next) {
        next(null, fetch(data));
      });
      chain.push(map);
    }
    if (consume && fetch) {
      es.pipeline(result, chain, es.writeArray( function (err, body) {
        consume(err, body);
        result.end( );
      }));
    }

    this.emit('data', hook);
  }
  */
  function end ( ) {
    // when done
    // this.emit('data', '');
    this.end( );
  }

  function process (thing, cb) {
    // s.write(thing, cb);
    var handlers = emitters.listeners(thing).length;
    // function make (op, length, next) {
    var ev = make(thing, handlers, next);

    ev.stream.on('data', function (data) {
      console.log('LOG', 'data', data);
    });
    ev.stream.on('end', function (data) {
      console.log("END");
      if (data) {
        ev.value(data);
      }
      next( );
    });
    function next ( ) {
      cb(ev.value( ));
    }
    s.write(ev);
    return ev;
    // s.once('data', function (res
    // s.write(thing, fetch, consume);

  }

  s.process = process;

  return s;
}

module.exports = function init (opts) {
  // var emitter = new EventEmitter;
  // var emit = emitter.emit;
  var ev = new Events(opts);
  return ev;
};

function Events (opts) {
  EventEmitter.call(this);
  this.stream = Stream(this, opts);
}
util.inherits(Events, EventEmitter);
Events.prototype.user = function user (name, cb) {
  console.log('user', name);
  var hook = this.stream.process('user', function (result) {
    console.log('process user', arguments);
    cb(result);
  });
  var map = es.map(function each (data, n) {
    data.name = data.args.pop( );
    n(null, hook.value(data));
  });
  var chain = [ map ];
  hook.stream = es.pipeline(hook.stream, map);
  var body = hook.params;
  body.args = [name];
  hook.value(body);
  var handlers = this.listeners('user').length;
  var pending = handlers;
  function onEvents ( ) {
    console.log('finished events', pending);
    if (--pending == 0) {
      hook.stream.write.apply(hook.stream, hook.value( ));
      hook.stream.end( );
    }
  }
  this.emit(hook.name, hook, onEvents);

}

if (!module.parent) {
  console.log('MAIN');
  var ev = module.exports( );
  ev.on('user', function (hook, next) {
    console.log('every user request', hook.value( ), next);
    hook.stream = es.pipeline(hook.stream, es.map(function (data, N) {
      console.log(data);
      data.name = data.name.toUpperCase( );
      N(null, data);
    }));
    return next( );
  });
  ev.on('user', function (hook, next) {
    console.log('every user request 2', hook.value( ), next);
    hook.stream = es.pipeline(hook.stream, es.map(function (data, N) {
      console.log(data);
      data.name = data.name.toUpperCase( );
      data.profile = 'http://logins/' + data.name.toLowerCase( );
      N(null, data);
    }));
    return next( );
  });
  ev.user('bewest', function fetch (value) {
    console.log('USER returned value', value);
  });
}
<|endoftext|>


<commit_before>import Component from '@ember/component';
import { inject as service } from '@ember/service';
import { computed } from '@ember/object';
import { task } from 'ember-concurrency';
import messageFromAdapterError from 'nomad-ui/utils/message-from-adapter-error';
import localStorageProperty from 'nomad-ui/utils/properties/local-storage';

export default Component.extend({
  store: service(),
  config: service(),

  job: null,
  onSubmit() {},
  context: computed({
    get() {
      return this.get('_context');
    },
    set(key, value) {
      const allowedValues = ['new', 'edit'];
      if (!allowedValues.includes(value)) {
        throw new Error(`context must be one of: ${allowedValues.join(', ')}`);
      }
      this.set('_context', value);
      return value;
    },
  }),

  _context: null,
  parseError: null,
  planError: null,
  runError: null,

  planOutput: null,

  showPlanMessage: localStorageProperty('nomadMessageJobPlan', true),
  showEditorMessage: localStorageProperty('nomadMessageJobEditor', true),

  stage: computed('planOutput', function() {
    return this.get('planOutput') ? 'plan' : 'editor';
  }),

  plan: task(function*() {
    this.reset();

    try {
      yield this.get('job').parse();
    } catch (err) {
      const error = messageFromAdapterError(err) || 'Could not parse input';
      this.set('parseError', error);
      this.scrollToError();
      return;
    }

    try {
      yield this.get('job').plan();
      const plan = this.get('store').peekRecord('job-plan', this.get('job.id'));
      this.set('planOutput', plan);
    } catch (err) {
      const error = messageFromAdapterError(err) || 'Could not plan job';
      this.set('planError', error);
      this.scrollToError();
    }
  }).drop(),

  submit: task(function*() {
    try {
      if (this.get('context') === 'new') {
        yield this.get('job').run();
      } else {
        yield this.get('job').update();
      }

      const id = this.get('job.plainId');
      const namespace = this.get('job.namespace.name') || 'default';

      this.reset();

      // Treat the job as ephemeral and only provide ID parts.
      this.get('onSubmit')(id, namespace);
    } catch (err) {
      const error = messageFromAdapterError(err) || 'Could not submit job';
      this.set('runError', error);
      this.set('planOutput', null);
      this.scrollToError();
    }
  }),

  reset() {
    this.set('planOutput', null);
    this.set('planError', null);
    this.set('parseError', null);
    this.set('runError', null);
  },

  scrollToError() {
    if (!this.get('config.isTest')) {
      window.scrollTo(0, 0);
    }
  },
});
<commit_msg>fixup-job-editor<commit_after>import Component from '@ember/component';
import { assert } from '@ember/debug';
import { inject as service } from '@ember/service';
import { computed } from '@ember/object';
import { task } from 'ember-concurrency';
import messageFromAdapterError from 'nomad-ui/utils/message-from-adapter-error';
import localStorageProperty from 'nomad-ui/utils/properties/local-storage';

export default Component.extend({
  store: service(),
  config: service(),

  job: null,
  onSubmit() {},
  context: computed({
    get() {
      return this.get('_context');
    },
    set(key, value) {
      const allowedValues = ['new', 'edit'];

      assert(`context must be one of: ${allowedValues.join(', ')}`, allowedValues.includes(value));

      this.set('_context', value);
      return value;
    },
  }),

  _context: null,
  parseError: null,
  planError: null,
  runError: null,

  planOutput: null,

  showPlanMessage: localStorageProperty('nomadMessageJobPlan', true),
  showEditorMessage: localStorageProperty('nomadMessageJobEditor', true),

  stage: computed('planOutput', function() {
    return this.get('planOutput') ? 'plan' : 'editor';
  }),

  plan: task(function*() {
    this.reset();

    try {
      yield this.get('job').parse();
    } catch (err) {
      const error = messageFromAdapterError(err) || 'Could not parse input';
      this.set('parseError', error);
      this.scrollToError();
      return;
    }

    try {
      yield this.get('job').plan();
      const plan = this.get('store').peekRecord('job-plan', this.get('job.id'));
      this.set('planOutput', plan);
    } catch (err) {
      const error = messageFromAdapterError(err) || 'Could not plan job';
      this.set('planError', error);
      this.scrollToError();
    }
  }).drop(),

  submit: task(function*() {
    try {
      if (this.get('context') === 'new') {
        yield this.get('job').run();
      } else {
        yield this.get('job').update();
      }

      const id = this.get('job.plainId');
      const namespace = this.get('job.namespace.name') || 'default';

      this.reset();

      // Treat the job as ephemeral and only provide ID parts.
      this.get('onSubmit')(id, namespace);
    } catch (err) {
      const error = messageFromAdapterError(err) || 'Could not submit job';
      this.set('runError', error);
      this.set('planOutput', null);
      this.scrollToError();
    }
  }),

  reset() {
    this.set('planOutput', null);
    this.set('planError', null);
    this.set('parseError', null);
    this.set('runError', null);
  },

  scrollToError() {
    if (!this.get('config.isTest')) {
      window.scrollTo(0, 0);
    }
  },
});
<|endoftext|>