<commit_before>#!/usr/bin/env node

import path from 'path';
import commander from 'commander';
import requireCwd from 'req-cwd';

commander
  .usage('[options] <tasks runner>')
  .option('-f, --file, <file>', 'tasks file path, tasks.js by default', 'tasks.js')
  .option('-p, --preset, <preset>', 'tasks preset')
  .parse(process.argv);

let tasks = null;

if (commander.preset) {
  try {
    tasks = requireCwd(commander.preset);
  } catch (e) {
    console.error(`Unable to find "${commander.preset}" preset, please check it again`);
    process.exit(1);
  }
} else {
  try {
    tasks = require(path.resolve(commander.file));
  } catch (e) {
    console.error(`Unable to find "${commander.file}" file, please check it again`);
    process.exit(1);
  }
}

const getAvailableTasksRunnersMessage = () => {
  return `Available tasks runners: "${Object.keys(tasks).join('", "')}"`;
};

if (commander.args.length === 0) {
  console.log('Tasks runner is required');
  console.log(getAvailableTasksRunnersMessage());
  process.exit(0);
}

if (commander.args.length > 1) {
  console.error('Starting only a single tasks runner is supported');
  console.error('You should consider using of composition of tasks runners');
  process.exit(1);
}

const tasksRunnerName = commander.args[0];
const tasksRunner = tasks[tasksRunnerName];

if (typeof tasksRunner === 'undefined') {
  console.error(`Unable to find tasks runner "${tasksRunnerName}"`);
  console.error(getAvailableTasksRunnersMessage());
  process.exit(1);
}

tasksRunner().catch(() => {
  process.exit(1);
});
<commit_msg>:heavy_plus_sign: pass additional arguments to tasks runner<commit_after>#!/usr/bin/env node

import path from 'path';
import commander from 'commander';
import requireCwd from 'req-cwd';

commander
  .usage('[options] <tasks runner> [arguments]')
  .option('-f, --file, <file>', 'tasks file path, tasks.js by default', 'tasks.js')
  .option('-p, --preset, <preset>', 'tasks preset')
  .parse(process.argv);

let tasks = null;

if (commander.preset) {
  try {
    tasks = requireCwd(commander.preset);
  } catch (e) {
    console.error(`Unable to find "${commander.preset}" preset, please check it again`);
    process.exit(1);
  }
} else {
  try {
    tasks = require(path.resolve(commander.file));
  } catch (e) {
    console.error(`Unable to find "${commander.file}" file, please check it again`);
    process.exit(1);
  }
}

const getAvailableTasksRunnersMessage = () => {
  return `Available tasks runners: "${Object.keys(tasks).join('", "')}"`;
};

if (commander.args.length === 0) {
  console.log('Tasks runner is required');
  console.log(getAvailableTasksRunnersMessage());
  process.exit(0);
}

const tasksRunnerName = commander.args[0];
const tasksRunner = tasks[tasksRunnerName];

if (typeof tasksRunner === 'undefined') {
  console.error(`Unable to find tasks runner "${tasksRunnerName}"`);
  console.error(getAvailableTasksRunnersMessage());
  process.exit(1);
}

const tasksRunnerArgs = commander.args.slice(1);

tasksRunner(...tasksRunnerArgs).catch(() => {
  process.exit(1);
});
<|endoftext|>


<commit_before>(function (root, factory) {
  if (typeof define === "function" && define.amd) {
    define(["prhone-log"], function () {
      return factory();
    });
  } else if (typeof module === "object" && module.exports) {
    module.exports = factory();
  } else {
    root.PrhoneLog = factory();
  }
}(this, function () {

  /**
   * Simple extend object. Receives many objects.
   * @param  {Object} obj - The object to extend.
   * @return {Object} - `obj` extended.
   */
  var extend = function (obj) {
    obj = obj || {};
    var exts = Array.prototype.slice.call(arguments, 1);
    for (var k=0; k<exts.length; k++) {
      for (var i in exts[k]) {
        if (exts[k].hasOwnProperty(i)) {
          obj[i] = exts[k][i];
        }
      }
    }
    return obj;
  };

  /**
   * Log levels. Each level is a log method.
   * @type {Array}
   */
  const levels = [
    {
      name: 'DEBUG',
      scale: 4,
      method: 'debug',
      'console': 'debug'
    },
    {
      name: 'INFO',
      scale: 3,
      method: 'info',
      'console': 'info'
    },
    {
      name: 'WARN',
      scale: 2,
      method: 'warn',
      'console': 'warn'
    },
    {
      name: 'ERROR',
      scale: 1,
      method: 'error',
      'console': 'error'
    }
  ];

  /**
   * The logger class.
   * @param {String} namespace - A namespace to identify the logger.
   * @param {Object} [settings] - An optional configuration to overwrite defaults.
   */
  var Log = function (namespace, settings) {
    this.namespace = namespace;
    this.history = [];
    this.settings = extend({}, Log.defaults, settings);
  };

  /**
   * Default config.
   * @type {Object}
   */
  Log.defaults = {
    history: true,  // Keep a record of all messages.
    scale: 4,  // Scale to display messages.
    throwErrors: false,  // Throw errors in methods scale 1 or below.
    display: true,  // Display messages in console.
    displayTime: false,  // Display the time in messages.
    displayLevel: true,  // Display the level in messages.
    displayNamespace: true  // Display the namespace in messages.
  };

  /**
   * Add a new method level.
   * @param {Object} level - Level description.
   * @param {String} level.name - Level name.
   * @param {Number} [level.scale] - Number scale. Default to 0.
   * @param {String} [level.method] - The method logger. Default to 'log'.
   * @param {String} [level.console] - The console method used to display. Default 'log'.
   */
  Log.addLevel = function (level) {

    if (!level || typeof level !== 'object') {
      throw new Error('The first parameter must be an object describing the level');
    }
    if (typeof level.name !== 'string') {
      throw new Error('The level object must have a name property');
    }

    level = extend({
      name: null,
      scale: 0,
      method: 'log',
      'console': 'log'
    }, level);

    this.prototype[level.method] = function () {
      this._exec(level, arguments);
    };
  };

  /**
   * Record a log in logger history if configured.
   * @private
   * @param  {Date} date - Date of log.
   * @param  {Object} level - Reference to the level definition.
   * @param  {String} text - The raw message.
   * @param  {String} msg - The parsed message.
   */
  Log.prototype._record = function (date, level, text, msg) {
    if (this.settings.history) {
      this.history.push({
        date: date.getTime(),
        level: level,
        text: text,
        msg: msg
      });
    }
  };

  /**
   * Create the log message with the logger configuration.
   * @private
   * @param  {Date} date - Date of log.
   * @param  {Object} level - Reference to the level definition.
   * @param  {String} text - The raw message.
   * @return {String} - The parsed message.
   */
  Log.prototype._msg = function (date, level, text) {

    var dtime = '';
    var dlevel = '';
    var dnamespace = '';

    if (this.settings.displayTime) {
      var hh = date.getHours() < 10 ? '0' + date.getHours() : date.getHours();
      var mm = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes();
      var ss = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
      var ms = date.getMilliseconds() < 10 ?
        '00' + date.getMilliseconds() :
        date.getMilliseconds() < 100 ?
          '0' + date.getMilliseconds() :
          date.getMilliseconds();
      dtime = hh + ':' + mm + ':' + ss + '.' + ms + ' ';
    }

    if (this.settings.displayLevel) {
      dlevel = level.name + ' ';
    }

    if (this.settings.displayNamespace) {
      dnamespace = this.namespace + ' ';
    }

    var dmsg = (dtime + dlevel + dnamespace).trim();
    dmsg = dmsg.length ? dmsg + ': ' + text : text;

    return dmsg;
  };

  /**
   * Log the message in the console.
   * @private
   * @param  {Object} level - Reference to the level definition.
   * @param  {String} msg - The parsed message.
   */
  Log.prototype._log = function (level, msg) {
    if (this.settings.display) {
      if (console && console.log) {
        if (console[level.console] && typeof console[level.console] === 'function') {
          console[level.console](msg);
        } else {
          console.log(msg);
        }
      }
    }
  };

  /**
   * Log method definition.
   * @private
   * @param  {Object} level - Reference to the level definition.
   * @param  {Array} args - The arguments received by the log method.
   */
  Log.prototype._exec = function (level, args) {

    var date = new Date();
    var text = '';

    args = Array.prototype.slice.call(args, 0);
    for (var i=0; i<args.length; i++) {
      if (typeof args[i] === 'object') {
        text += ' '+ JSON.stringify(args[i]);
      } else {
        text += ' '+ args[i];
      }
    }
    text = text.trim();

    var msg = this._msg(date, level, text);

    this._record(date, level, text, msg);

    if (this.settings.throwErrors && level.scale <= 1) {
      throw new Error(msg);
    }

    if (level.scale <= this.settings.scale) {
      this._log(level, msg);
    }
  };

  // Initialize default levels.
  for (var l=0; l<levels.length; l++) {
    Log.addLevel(levels[l]);
  }

  return Log;
}));
<commit_msg>feat: Log.LEVEL object and .setLevel method<commit_after>(function (root, factory) {
  if (typeof define === "function" && define.amd) {
    define(["prhone-log"], function () {
      return factory();
    });
  } else if (typeof module === "object" && module.exports) {
    module.exports = factory();
  } else {
    root.PrhoneLog = factory();
  }
}(this, function () {

  /**
   * Simple extend object. Receives many objects.
   * @param  {Object} obj - The object to extend.
   * @return {Object} - `obj` extended.
   */
  var extend = function (obj) {
    obj = obj || {};
    var exts = Array.prototype.slice.call(arguments, 1);
    for (var k=0; k<exts.length; k++) {
      for (var i in exts[k]) {
        if (exts[k].hasOwnProperty(i)) {
          obj[i] = exts[k][i];
        }
      }
    }
    return obj;
  };

  /**
   * Log levels. Each level is a log method.
   * @type {Array}
   */
  const levels = [
    {
      name: 'DEBUG',
      scale: 4,
      method: 'debug',
      'console': 'debug'
    },
    {
      name: 'INFO',
      scale: 3,
      method: 'info',
      'console': 'info'
    },
    {
      name: 'WARN',
      scale: 2,
      method: 'warn',
      'console': 'warn'
    },
    {
      name: 'ERROR',
      scale: 1,
      method: 'error',
      'console': 'error'
    }
  ];

  /**
   * The logger class.
   * @param {String} namespace - A namespace to identify the logger.
   * @param {Object} [settings] - An optional configuration to overwrite defaults.
   */
  var Log = function (namespace, settings) {
    this.namespace = namespace;
    this.history = [];
    this.settings = extend({}, Log.defaults, settings);
  };

  /**
   * Default config.
   * @type {Object}
   */
  Log.defaults = {
    history: true,  // Keep a record of all messages.
    scale: 4,  // Scale to display messages.
    throwErrors: false,  // Throw errors in methods scale 1 or below.
    display: true,  // Display messages in console.
    displayTime: false,  // Display the time in messages.
    displayLevel: true,  // Display the level in messages.
    displayNamespace: true  // Display the namespace in messages.
  };

  /**
   * All registered levels.
   * @type {Object}
   */
  Log.LEVEL = {};

  /**
   * Add a new method level.
   * @param {Object} level - Level description.
   * @param {String} level.name - Level name.
   * @param {Number} [level.scale] - Number scale. Default to 0.
   * @param {String} [level.method] - The method logger. Default to 'log'.
   * @param {String} [level.console] - The console method used to display. Default 'log'.
   */
   Log.addLevel = Log.prototype.addLevel = function (level) {

    if (!level || typeof level !== 'object') {
      throw new Error('The first parameter must be an object describing the level');
    }
    if (typeof level.name !== 'string' && !level.name.length) {
      throw new Error('The level object must have a name property');
    }

    level = extend({
      name: null,
      scale: 0,
      method: 'log',
      'console': 'log'
    }, level);

    if (this.LEVEL[level.name]) {
      throw new Error('The level name "'+ level.name +'" already exists');
    }

    this.LEVEL[level.name] = level;

    this.prototype[level.method] = function () {
      this._exec(level, arguments);
    };
  };

  /**
   * Set an specific level as the scale of messages to display.
   * @param {Number|Object} level - The number scale to set or the reference to the
   * level object to set.
   */
  Log.setLevel = Log.prototype.setLevel = function (level) {
    if (typeof level === 'object' && Log.LEVEL[level.name]) {
      this.settings.scale = level.scale;
    } else {
      this.settings.scale = level;
    }
  };

  /**
   * Record a log in logger history if configured.
   * @private
   * @param  {Date} date - Date of log.
   * @param  {Object} level - Reference to the level definition.
   * @param  {String} text - The raw message.
   * @param  {String} msg - The parsed message.
   */
  Log.prototype._record = function (date, level, text, msg) {
    if (this.settings.history) {
      this.history.push({
        date: date.getTime(),
        level: level,
        text: text,
        msg: msg
      });
    }
  };

  /**
   * Create the log message with the logger configuration.
   * @private
   * @param  {Date} date - Date of log.
   * @param  {Object} level - Reference to the level definition.
   * @param  {String} text - The raw message.
   * @return {String} - The parsed message.
   */
  Log.prototype._msg = function (date, level, text) {

    var dtime = '';
    var dlevel = '';
    var dnamespace = '';

    if (this.settings.displayTime) {
      var hh = date.getHours() < 10 ? '0' + date.getHours() : date.getHours();
      var mm = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes();
      var ss = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
      var ms = date.getMilliseconds() < 10 ?
        '00' + date.getMilliseconds() :
        date.getMilliseconds() < 100 ?
          '0' + date.getMilliseconds() :
          date.getMilliseconds();
      dtime = hh + ':' + mm + ':' + ss + '.' + ms + ' ';
    }

    if (this.settings.displayLevel) {
      dlevel = level.name + ' ';
    }

    if (this.settings.displayNamespace) {
      dnamespace = this.namespace + ' ';
    }

    var dmsg = (dtime + dlevel + dnamespace).trim();
    dmsg = dmsg.length ? dmsg + ': ' + text : text;

    return dmsg;
  };

  /**
   * Log the message in the console.
   * @private
   * @param  {Object} level - Reference to the level definition.
   * @param  {String} msg - The parsed message.
   */
  Log.prototype._log = function (level, msg) {
    if (this.settings.display) {
      if (console && console.log) {
        if (console[level.console] && typeof console[level.console] === 'function') {
          console[level.console](msg);
        } else {
          console.log(msg);
        }
      }
    }
  };

  /**
   * Log method definition.
   * @private
   * @param  {Object} level - Reference to the level definition.
   * @param  {Array} args - The arguments received by the log method.
   */
  Log.prototype._exec = function (level, args) {

    var date = new Date();
    var text = '';

    args = Array.prototype.slice.call(args, 0);
    for (var i=0; i<args.length; i++) {
      if (typeof args[i] === 'object') {
        text += ' '+ JSON.stringify(args[i]);
      } else {
        text += ' '+ args[i];
      }
    }
    text = text.trim();

    var msg = this._msg(date, level, text);

    this._record(date, level, text, msg);

    if (this.settings.throwErrors && level.scale <= 1) {
      throw new Error(msg);
    }

    if (level.scale <= this.settings.scale) {
      this._log(level, msg);
    }
  };

  // Initialize default levels.
  for (var l=0; l<levels.length; l++) {
    Log.addLevel(levels[l]);
  }

  return Log;
}));
<|endoftext|>


<commit_before>/*
Copyright (c) 2011, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://yuilibrary.com/license/
*/
/**
Module creates the YUI instance with the required modules, uses them and exports the **Y** to be used
by the _CLI class_ or by extenders: `require('yuidocjs');`
You can use it like this:

    var options = {
        paths: [ './lib' ],
        outdir: './out'
    };

    var Y = require('yuidocjs');
    var json = (new Y.YUIDoc(options)).run();

@class Main
@exports {YUI} Y A YUI instance
@module yuidoc
*/

var YUI = require('yui').YUI,
    path = require('path'),
    fs = require('graceful-fs'),
    metaPath = path.join(__dirname, '../', 'package.json');

/*
process.on('uncaughtException', function(msg) {
    var inst = YUI(),
        meta = JSON.parse(fs.readFileSync(metaPath));

    console.log(msg);

    inst.applyConfig({
        debug: true,
        useColor: Y.config.useColor
    });
    inst.log('--------------------------------------------------------------------------', 'error');
    inst.log('An uncaught YUIDoc error has occurred, stack trace given below', 'error');
    inst.log('--------------------------------------------------------------------------', 'error');
    inst.log(msg.stack || msg.message || msg, 'error');
    inst.log('--------------------------------------------------------------------------', 'error');
    inst.log('Node.js version: ' + process.version, 'error');
    inst.log('YUI version: ' + YUI.version, 'error');
    inst.log('YUIDoc version: ' + meta.version, 'error');
    inst.log('Please file all tickets here: ' + meta.bugs.url, 'error');
    inst.log('--------------------------------------------------------------------------', 'error');

    process.exit(1);
});
*/

var Y = YUI({
    modules: {
        help: {
            fullpath: path.join(__dirname, 'help.js')
        },
        options: {
            fullpath: path.join(__dirname, 'options.js')
        },
        docparser: {
            fullpath: path.join(__dirname, 'docparser.js'),
            requires: ['base-base', 'json-stringify']
        },
        yuidoc: {
            fullpath: path.join(__dirname, 'yuidoc.js')
        },
        'doc-builder': {
            fullpath: path.join(__dirname, 'builder.js'),
            requires: ['parallel', 'handlebars']
        },
        utils: {
            fullpath: path.join(__dirname, 'utils.js')
        },
        files: {
            fullpath: path.join(__dirname, 'files.js')
        },
        docview: {
            fullpath: path.join(__dirname, 'docview.js')
        },
        server: {
            fullpath: path.join(__dirname, 'server.js')
        },
        project: {
            fullpath: path.join(__dirname, 'project.js')
        },
        microtemplate: {
        	fullpath: path.join(__dirname, 'microtemplate.js')
        }
    },
    logExclude: {
        yui: true,
        get: true,
        files: true,
        loader: true
    },
    useSync: true
}).use('utils', 'microtemplate', 'docparser', 'yuidoc', 'doc-builder', 'docview', 'files', 'help', 'options', 'server', 'project');

Y.packageInfo = Y.Files.getJSON(metaPath);

module.exports = Y;
<commit_msg>console.log Á¦°Å<commit_after>/*
Copyright (c) 2011, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://yuilibrary.com/license/
*/
/**
Module creates the YUI instance with the required modules, uses them and exports the **Y** to be used
by the _CLI class_ or by extenders: `require('yuidocjs');`
You can use it like this:

    var options = {
        paths: [ './lib' ],
        outdir: './out'
    };

    var Y = require('yuidocjs');
    var json = (new Y.YUIDoc(options)).run();

@class Main
@exports {YUI} Y A YUI instance
@module yuidoc
*/

var YUI = require('yui').YUI,
    path = require('path'),
    fs = require('graceful-fs'),
    metaPath = path.join(__dirname, '../', 'package.json');

/*
process.on('uncaughtException', function(msg) {
    var inst = YUI(),
        meta = JSON.parse(fs.readFileSync(metaPath));

    inst.applyConfig({
        debug: true,
        useColor: Y.config.useColor
    });
    inst.log('--------------------------------------------------------------------------', 'error');
    inst.log('An uncaught YUIDoc error has occurred, stack trace given below', 'error');
    inst.log('--------------------------------------------------------------------------', 'error');
    inst.log(msg.stack || msg.message || msg, 'error');
    inst.log('--------------------------------------------------------------------------', 'error');
    inst.log('Node.js version: ' + process.version, 'error');
    inst.log('YUI version: ' + YUI.version, 'error');
    inst.log('YUIDoc version: ' + meta.version, 'error');
    inst.log('Please file all tickets here: ' + meta.bugs.url, 'error');
    inst.log('--------------------------------------------------------------------------', 'error');

    process.exit(1);
});
*/

var Y = YUI({
    modules: {
        help: {
            fullpath: path.join(__dirname, 'help.js')
        },
        options: {
            fullpath: path.join(__dirname, 'options.js')
        },
        docparser: {
            fullpath: path.join(__dirname, 'docparser.js'),
            requires: ['base-base', 'json-stringify']
        },
        yuidoc: {
            fullpath: path.join(__dirname, 'yuidoc.js')
        },
        'doc-builder': {
            fullpath: path.join(__dirname, 'builder.js'),
            requires: ['parallel', 'handlebars']
        },
        utils: {
            fullpath: path.join(__dirname, 'utils.js')
        },
        files: {
            fullpath: path.join(__dirname, 'files.js')
        },
        docview: {
            fullpath: path.join(__dirname, 'docview.js')
        },
        server: {
            fullpath: path.join(__dirname, 'server.js')
        },
        project: {
            fullpath: path.join(__dirname, 'project.js')
        },
        microtemplate: {
        	fullpath: path.join(__dirname, 'microtemplate.js')
        }
    },
    logExclude: {
        yui: true,
        get: true,
        files: true,
        loader: true
    },
    useSync: true
}).use('utils', 'microtemplate', 'docparser', 'yuidoc', 'doc-builder', 'docview', 'files', 'help', 'options', 'server', 'project');

Y.packageInfo = Y.Files.getJSON(metaPath);

module.exports = Y;
<|endoftext|>


<commit_before>'use strict';

var fs = require('fs');
var express = require('express');
var bodyParser = require('body-parser');

module.exports = function(config, app){
	var resources = {
		db: require('./api/utils/db.js')(config.db)
	};

	// TODO: if DB does not exist, set it up!

	// add middleware
	app.use(config.root + '/api', bodyParser.urlencoded());
	app.use(config.root + '/api', bodyParser.json());
	app.use(config.root + '/api', require('res-error'));
	app.use(config.root + '/api', require('./api/middleware/auth.js')(config.auth, resources));

	// add the endpoints
	fs.readdirSync(__dirname + '/api/endpoints/').forEach(function(file){
	  if(file.indexOf('.js') === (file.length - 3))
	    require(__dirname + '/api/endpoints/' + file)(config, app, resources);
	});

	// TODO: redirect the root

	// TODO: serve angular links

	// TODO: serve components

	// TODO: inject components & dependencies

	// serve static files
	app.use(config.root + '/app', express.static(__dirname + '/app'));
	app.use(config.root + '/files', express.static(__dirname + '/files'));

};
<commit_msg>redirect root<commit_after>'use strict';

var fs = require('fs');
var express = require('express');
var bodyParser = require('body-parser');

module.exports = function(config, app){
	var resources = {
		db: require('./api/utils/db.js')(config.db)
	};

	// TODO: if DB does not exist, set it up!

	// add middleware
	app.use(config.root + '/api', bodyParser.urlencoded());
	app.use(config.root + '/api', bodyParser.json());
	app.use(config.root + '/api', require('res-error'));
	app.use(config.root + '/api', require('./api/middleware/auth.js')(config.auth, resources));

	// add the endpoints
	fs.readdirSync(__dirname + '/api/endpoints/').forEach(function(file){
	  if(file.indexOf('.js') === (file.length - 3))
	    require(__dirname + '/api/endpoints/' + file)(config, app, resources);
	});

	// redirect the root
	app.get(config.root, function(req, res){
		res.set('Location', config.root + '/app');
		res.send(302);
	})

	// TODO: serve angular links

	// TODO: serve components

	// TODO: inject components & dependencies

	// serve static files
	app.use(config.root + '/app', express.static(__dirname + '/app'));
	app.use(config.root + '/files', express.static(__dirname + '/files'));

};
<|endoftext|>


<commit_before>var _ = require('underscore'),
    seq = require('seq'),
    Canvas = require('canvas'),
    passError = require('./util/passError'),
    urlTools = require('assetgraph/lib/util/urlTools'),
    packers = require('./packers');

require('bufferjs');

function getCanvasImageFromImageAsset(imageAsset, cb) {
    var canvasImage = new Canvas.Image();
    canvasImage.onerror = function (err) {
        process.nextTick(function () {
            err.message += ' (' + imageAsset.toString() + ')';
            cb(err);
        });
    };
    canvasImage.onload = function () {
        process.nextTick(function () {
            cb(null, canvasImage);
        });
    };
    canvasImage.src = imageAsset.rawSrc;
}

function calculateSpritePadding(paddingStr) {
    if (paddingStr) {
        // Strip units ('px' assumed)
        var tokens = [];
        paddingStr.split(/\s+/).forEach(function (token) {
            var num = parseInt(token.replace(/[a-z]+$/, ''), 10);
            if (!isNaN(num)) {
                tokens.push(num);
            }
        });
        if (tokens.length === 4) {
            return tokens;
        } else if (tokens.length === 3) {
            return [tokens[0], tokens[1], tokens[2], tokens[1]]; // T, L+R, B
        } else if (tokens.length === 2) {
            return [tokens[0], tokens[1], tokens[0], tokens[1]]; // T+B, L+R
        } else if (tokens.length === 1) {
            return [tokens[0], tokens[0], tokens[0], tokens[0]];
        }
    }
    return [0, 0, 0, 0];
}

module.exports = function () {
    return function spriteBackgroundImages(assetGraph, cb) {
        // Waiting for https://github.com/LearnBoost/node-canvas/issues/52
        var cairoVersion = Canvas.cairoVersion.split(".").map(function (str) {return parseInt(str, 10);});
        if (cairoVersion[0] < 1 || cairoVersion[1] < 10) {
            console.warn("assetgraph-sprite: Cannot create sprites due to missing canvas.getContext('2d').drawImage() support. Please compile node-canvas with Cairo version 1.10.0 or above.");
            return cb();
        }

        var assets = assetGraph.constructor.assets, // Hack
            relations = assetGraph.constructor.relations, // Hack
            spriteGroups = {};
        assetGraph.findRelations({type: 'CssImage'}).forEach(function (relation) {
            var spriteInfo = assets.Css.extractInfoFromRule(relation.cssRule, assets.Css.vendorPrefix + '-sprite-'),
                asset = relation.to;
            if (spriteInfo.group) {
                var spriteGroup = spriteGroups[spriteInfo.group];
                if (!spriteGroup) {
                    spriteGroup = spriteGroups[spriteInfo.group] = {
                        imageInfosById: {}
                    };
                }
                var imageInfo = spriteGroup.imageInfosById[asset.id],
                    padding = calculateSpritePadding(spriteInfo.padding);
                if (!imageInfo) {
                    imageInfo = spriteGroup.imageInfosById[asset.id] = {
                        padding: padding,
                        asset: asset,
                        incomingRelations: [relation]
                    };
                } else {
                    imageInfo.incomingRelations.push(relation);
                    for (var i = 0 ; i < 4 ; i += 1) {
                        imageInfo.padding[i] = Math.max(padding[i], imageInfo.padding[i]);
                    }
                }
            }
        });

        assetGraph.findAssets({type: 'Css'}).forEach(function (cssAsset) {
            assets.Css.eachRuleInParseTree(cssAsset.parseTree, function (cssRule) {
                if ((assets.Css.vendorPrefix + '-sprite-selector-for-group') in cssRule.style) {
                    var spriteInfo = assets.Css.extractInfoFromRule(cssRule, assets.Css.vendorPrefix + '-sprite-'),
                        spriteGroupName = spriteInfo.selectorForGroup;
                    if (spriteGroupName in spriteGroups) {
                        if (spriteGroups[spriteGroupName].placeHolder) {
                            console.warn("assetgraph-sprite: Multiple definitions of " + spriteGroupName + " sprite");
                        }
                        spriteGroups[spriteGroupName].placeHolder = _.extend(spriteInfo, {
                            asset: cssAsset,
                            cssRule: cssRule
                        });
                    }
                }
            });
        });

        seq(Object.keys(spriteGroups))
            .seqEach(function (spriteGroupName) {
                var callback = this,
                    spriteGroup = spriteGroups[spriteGroupName],
                    imageInfos = _.values(spriteGroup.imageInfosById),
                    spriteInfo = spriteGroup.placeHolder ? spriteGroup.placeHolder : {};

                seq(imageInfos)
                    .parMap(function (imageInfo) {
                        getCanvasImageFromImageAsset(imageInfo.asset, this);
                    })
                    .seqEach(function (canvasImage, i) {
                        _.extend(imageInfos[i], {
                            canvasImage: canvasImage,
                            width: canvasImage.width,
                            height: canvasImage.height
                        });
                        this();
                    })
                    .seq(function () {
                        var packerName = {
                            'jim-scott': 'jimScott',
                            horizontal: 'horizontal',
                            vertical: 'vertical'
                        }[spriteInfo.packer] || 'tryAll';
                        var packingData = packers[packerName].pack(imageInfos),
                            canvas = new Canvas(packingData.width, packingData.height),
                            ctx = canvas.getContext('2d');
                        imageInfos = packingData.imageInfos;
                        if ('backgroundColor' in spriteInfo) {
                            ctx.fillStyle = spriteInfo.imageBackgroundColor;
                            ctx.fillRect(0, 0, canvas.width, canvas.height);
                        }
                        imageInfos.forEach(function (imageInfo) {
                            ctx.drawImage(imageInfo.canvasImage, imageInfo.x, imageInfo.y, imageInfo.width, imageInfo.height);
                        });
                        canvas.toBuffer(this);
                    })
                    .seq(function (spriteBuffer) {
                        var spriteAsset = new assets.Png({
                            rawSrc: spriteBuffer
                        });
                        spriteAsset.url = urlTools.resolveUrl(assetGraph.root, spriteAsset.id + spriteAsset.defaultExtension);
                        assetGraph.addAsset(spriteAsset);
                        if (spriteGroup.placeHolder) {
                            var cssRule = spriteGroup.placeHolder.cssRule,
                                relation = new relations.CssImage({
                                    cssRule: cssRule,
                                    propertyName: 'background-image',
                                    from: spriteGroup.placeHolder.asset,
                                    to: spriteAsset
                                });
                            cssRule.style.setProperty('background-image', 'url(...)', spriteGroup.placeHolder.important && 'important');
                            // I can't see why the ordering of CssImage relations should be significant...
                            assetGraph.addRelation(relation, 'last');
                            relation.refreshHref();
                            ['selector-for-group', 'packer', 'image-format', 'background-color', 'important'].forEach(function (propertyName) {
                                 spriteGroup.placeHolder.cssRule.style.removeProperty(assets.Css.vendorPrefix + '-sprite-' + propertyName);
                            });
                        }
                        imageInfos.forEach(function (imageInfo) {
                            imageInfo.incomingRelations.forEach(function (incomingRelation) {
                                incomingRelation.from.markDirty();
                                var relationSpriteInfo = assets.Css.extractInfoFromRule(incomingRelation.cssRule, assets.Css.vendorPrefix + '-sprite-');
                                incomingRelation.cssRule.style.setProperty('background-position',
                                                                           (imageInfo.x ? (-imageInfo.x) + "px " : "0 ") +
                                                                           (imageInfo.y ? -imageInfo.y + "px" : "0"),
                                                                           relationSpriteInfo.important && 'important');
                                ['group', 'padding', 'no-group-selector', 'important'].forEach(function (propertyName) {
                                    incomingRelation.cssRule.style.removeProperty(assets.Css.vendorPrefix + '-sprite-' + propertyName);
                                });
                                if (relationSpriteInfo.noGroupSelector) {
                                    // The user specified that this selector needs its own background-image/background
                                    // property pointing at the sprite rather than relying on the Html elements also being
                                    // matched by the sprite group's "main" selector, which would have been preferable.
                                    var relation = new relations.CssImage({
                                        cssRule: incomingRelation.cssRule,
                                        propertyName: incomingRelation.propertyName,
                                        from: incomingRelation.from,
                                        to: spriteAsset
                                    });
                                    assetGraph.addRelation(relation, 'before', incomingRelation);
                                    relation.refreshHref();
                                    assetGraph.removeRelation(incomingRelation);
                                } else {
                                    incomingRelation.detach();
                                }

                                // Remove the original image if it has become an orphan:
                                if (!assetGraph.findRelations({to: incomingRelation.to}).length) {
                                    assetGraph.removeAsset(incomingRelation.to);
                                }
                            });
                        });
                        callback();
                    })
                    ['catch'](callback);
            })
            .seq(function () {
                cb();
            })
            ['catch'](cb);
    };
};
<commit_msg>Fixed -one-sprite-background-color.<commit_after>var _ = require('underscore'),
    seq = require('seq'),
    Canvas = require('canvas'),
    passError = require('./util/passError'),
    urlTools = require('assetgraph/lib/util/urlTools'),
    packers = require('./packers');

require('bufferjs');

function getCanvasImageFromImageAsset(imageAsset, cb) {
    var canvasImage = new Canvas.Image();
    canvasImage.onerror = function (err) {
        process.nextTick(function () {
            err.message += ' (' + imageAsset.toString() + ')';
            cb(err);
        });
    };
    canvasImage.onload = function () {
        process.nextTick(function () {
            cb(null, canvasImage);
        });
    };
    canvasImage.src = imageAsset.rawSrc;
}

function calculateSpritePadding(paddingStr) {
    if (paddingStr) {
        // Strip units ('px' assumed)
        var tokens = [];
        paddingStr.split(/\s+/).forEach(function (token) {
            var num = parseInt(token.replace(/[a-z]+$/, ''), 10);
            if (!isNaN(num)) {
                tokens.push(num);
            }
        });
        if (tokens.length === 4) {
            return tokens;
        } else if (tokens.length === 3) {
            return [tokens[0], tokens[1], tokens[2], tokens[1]]; // T, L+R, B
        } else if (tokens.length === 2) {
            return [tokens[0], tokens[1], tokens[0], tokens[1]]; // T+B, L+R
        } else if (tokens.length === 1) {
            return [tokens[0], tokens[0], tokens[0], tokens[0]];
        }
    }
    return [0, 0, 0, 0];
}

module.exports = function () {
    return function spriteBackgroundImages(assetGraph, cb) {
        // Waiting for https://github.com/LearnBoost/node-canvas/issues/52
        var cairoVersion = Canvas.cairoVersion.split(".").map(function (str) {return parseInt(str, 10);});
        if (cairoVersion[0] < 1 || cairoVersion[1] < 10) {
            console.warn("assetgraph-sprite: Cannot create sprites due to missing canvas.getContext('2d').drawImage() support. Please compile node-canvas with Cairo version 1.10.0 or above.");
            return cb();
        }

        var assets = assetGraph.constructor.assets, // Hack
            relations = assetGraph.constructor.relations, // Hack
            spriteGroups = {};
        assetGraph.findRelations({type: 'CssImage'}).forEach(function (relation) {
            var spriteInfo = assets.Css.extractInfoFromRule(relation.cssRule, assets.Css.vendorPrefix + '-sprite-'),
                asset = relation.to;
            if (spriteInfo.group) {
                var spriteGroup = spriteGroups[spriteInfo.group];
                if (!spriteGroup) {
                    spriteGroup = spriteGroups[spriteInfo.group] = {
                        imageInfosById: {}
                    };
                }
                var imageInfo = spriteGroup.imageInfosById[asset.id],
                    padding = calculateSpritePadding(spriteInfo.padding);
                if (!imageInfo) {
                    imageInfo = spriteGroup.imageInfosById[asset.id] = {
                        padding: padding,
                        asset: asset,
                        incomingRelations: [relation]
                    };
                } else {
                    imageInfo.incomingRelations.push(relation);
                    for (var i = 0 ; i < 4 ; i += 1) {
                        imageInfo.padding[i] = Math.max(padding[i], imageInfo.padding[i]);
                    }
                }
            }
        });

        assetGraph.findAssets({type: 'Css'}).forEach(function (cssAsset) {
            assets.Css.eachRuleInParseTree(cssAsset.parseTree, function (cssRule) {
                if ((assets.Css.vendorPrefix + '-sprite-selector-for-group') in cssRule.style) {
                    var spriteInfo = assets.Css.extractInfoFromRule(cssRule, assets.Css.vendorPrefix + '-sprite-'),
                        spriteGroupName = spriteInfo.selectorForGroup;
                    if (spriteGroupName in spriteGroups) {
                        if (spriteGroups[spriteGroupName].placeHolder) {
                            console.warn("assetgraph-sprite: Multiple definitions of " + spriteGroupName + " sprite");
                        }
                        spriteGroups[spriteGroupName].placeHolder = _.extend(spriteInfo, {
                            asset: cssAsset,
                            cssRule: cssRule
                        });
                    }
                }
            });
        });

        seq(Object.keys(spriteGroups))
            .seqEach(function (spriteGroupName) {
                var callback = this,
                    spriteGroup = spriteGroups[spriteGroupName],
                    imageInfos = _.values(spriteGroup.imageInfosById),
                    spriteInfo = spriteGroup.placeHolder ? spriteGroup.placeHolder : {};

                seq(imageInfos)
                    .parMap(function (imageInfo) {
                        getCanvasImageFromImageAsset(imageInfo.asset, this);
                    })
                    .seqEach(function (canvasImage, i) {
                        _.extend(imageInfos[i], {
                            canvasImage: canvasImage,
                            width: canvasImage.width,
                            height: canvasImage.height
                        });
                        this();
                    })
                    .seq(function () {
                        var packerName = {
                            'jim-scott': 'jimScott',
                            horizontal: 'horizontal',
                            vertical: 'vertical'
                        }[spriteInfo.packer] || 'tryAll';
                        var packingData = packers[packerName].pack(imageInfos),
                            canvas = new Canvas(packingData.width, packingData.height),
                            ctx = canvas.getContext('2d');
                        imageInfos = packingData.imageInfos;
                        if ('backgroundColor' in spriteInfo) {
                            ctx.fillStyle = spriteInfo.backgroundColor;
                            ctx.fillRect(0, 0, canvas.width, canvas.height);
                        }
                        imageInfos.forEach(function (imageInfo) {
                            ctx.drawImage(imageInfo.canvasImage, imageInfo.x, imageInfo.y, imageInfo.width, imageInfo.height);
                        });
                        canvas.toBuffer(this);
                    })
                    .seq(function (spriteBuffer) {
                        var spriteAsset = new assets.Png({
                            rawSrc: spriteBuffer
                        });
                        spriteAsset.url = urlTools.resolveUrl(assetGraph.root, spriteAsset.id + spriteAsset.defaultExtension);
                        assetGraph.addAsset(spriteAsset);
                        if (spriteGroup.placeHolder) {
                            var cssRule = spriteGroup.placeHolder.cssRule,
                                relation = new relations.CssImage({
                                    cssRule: cssRule,
                                    propertyName: 'background-image',
                                    from: spriteGroup.placeHolder.asset,
                                    to: spriteAsset
                                });
                            cssRule.style.setProperty('background-image', 'url(...)', spriteGroup.placeHolder.important && 'important');
                            // I can't see why the ordering of CssImage relations should be significant...
                            assetGraph.addRelation(relation, 'last');
                            relation.refreshHref();
                            ['selector-for-group', 'packer', 'image-format', 'background-color', 'important'].forEach(function (propertyName) {
                                 spriteGroup.placeHolder.cssRule.style.removeProperty(assets.Css.vendorPrefix + '-sprite-' + propertyName);
                            });
                        }
                        imageInfos.forEach(function (imageInfo) {
                            imageInfo.incomingRelations.forEach(function (incomingRelation) {
                                incomingRelation.from.markDirty();
                                var relationSpriteInfo = assets.Css.extractInfoFromRule(incomingRelation.cssRule, assets.Css.vendorPrefix + '-sprite-');
                                incomingRelation.cssRule.style.setProperty('background-position',
                                                                           (imageInfo.x ? (-imageInfo.x) + "px " : "0 ") +
                                                                           (imageInfo.y ? -imageInfo.y + "px" : "0"),
                                                                           relationSpriteInfo.important && 'important');
                                ['group', 'padding', 'no-group-selector', 'important'].forEach(function (propertyName) {
                                    incomingRelation.cssRule.style.removeProperty(assets.Css.vendorPrefix + '-sprite-' + propertyName);
                                });
                                if (relationSpriteInfo.noGroupSelector) {
                                    // The user specified that this selector needs its own background-image/background
                                    // property pointing at the sprite rather than relying on the Html elements also being
                                    // matched by the sprite group's "main" selector, which would have been preferable.
                                    var relation = new relations.CssImage({
                                        cssRule: incomingRelation.cssRule,
                                        propertyName: incomingRelation.propertyName,
                                        from: incomingRelation.from,
                                        to: spriteAsset
                                    });
                                    assetGraph.addRelation(relation, 'before', incomingRelation);
                                    relation.refreshHref();
                                    assetGraph.removeRelation(incomingRelation);
                                } else {
                                    incomingRelation.detach();
                                }

                                // Remove the original image if it has become an orphan:
                                if (!assetGraph.findRelations({to: incomingRelation.to}).length) {
                                    assetGraph.removeAsset(incomingRelation.to);
                                }
                            });
                        });
                        callback();
                    })
                    ['catch'](callback);
            })
            .seq(function () {
                cb();
            })
            ['catch'](cb);
    };
};
<|endoftext|>


<commit_before>export default function(patterns, callback) {
    return function watch(resolve, reject) {
        const chokidar = require('chokidar');

        function call(file) {
            callback(file).catch(reject);
        }

        chokidar
            .watch(patterns, { persistent: true })
            .on('change', call)
            .on('add', call)
            .on('error', reject);

        callback(patterns).catch(reject);
    };
}
<commit_msg>:wrench: don't interrupt watching on errors in callback<commit_after>export default function(patterns, callback) {
    return function watch(resolve, reject) {
        const chokidar = require('chokidar');

        function call(file) {
            callback(file).catch(reject);
        }

        chokidar
            .watch(patterns, { persistent: true })
            .on('change', callback)
            .on('add', callback)
            .on('error', reject);

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


<commit_before>'use strict'

var Transform = require('stream').Transform
  , util = require('util')
  , Segment = require('./segment')
  , Message = require('./message')
  , utils = require('./utils')

// MLP end frames
var FS = String.fromCharCode(0x1c)
  , CR = String.fromCharCode(0x0d)

exports.Message = Message
exports.Segment = Segment
exports.Parser = Parser
exports.utils = utils

/**
 * Constructor
 */
function Parser() {
  var opts = { objectMode: true }
  if (!(this instanceof Parser))
    return new Parser(opts)

  var self = this
  Transform.call(this, opts)

  this._messages = []
  this.current = null
}

util.inherits(Parser, Transform)

/**
 * Transform for parser
 *
 * **NOTE: The stream should have been pipe through `split()` already**
 *
 * @param {Buffer} data The segment as a buffer
 * @param {String} encoding The encoding of the buffer
 * @param {Function} cb function(err, res)
 * @api private
 */
Parser.prototype._transform = function(data, encoding, done) {
  var self = this
  var segment
  try {
    if (this.current) {
      segment = new Segment(data, this.current.delimiters())
    } else {
      segment = new Segment(data)
    }
  }
  catch (e) {
    self.emit('error', e)
    segment = null
    return
  }

  if (segment && segment.parsed) {
    var isHeader = utils.segmentIsHeader(segment)
    if (isHeader && this.current) {
      this.emit('message', this.current)
      var message = new Message()
      message.addSegment(segment)
      this._messages.push(message)
      this.current = message
    } else if (isHeader && !this.current) {
      this.current = new Message()
      this.current.addSegment(segment)
    } else {
      this.current.addSegment(segment)
    }

    /*
      If the message ended with FS+CR, this indicates the end of the message
      and it should be pushed over the transform stream now.
      http://www.hl7standards.com/blog/2007/05/02/hl7-mlp-minimum-layer-protocol-defined/
    */
    if (data.indexOf(FS + CR) !== -1) {
      this.emit('message', this.current)
      this.current = null
    }
  }
  done()
}

Parser.prototype._flush = function(done) {
  var self = this
  if (this.current && this.current.segments.length) {
    this.emit('message', this.current)
    this._messages.push(this.current)
    this.current = null
  }
  this.emit('messages', this._messages)
  done()
}
<commit_msg>parser: optimize transform<commit_after>'use strict'

var Transform = require('stream').Transform
  , util = require('util')
  , Segment = require('./segment')
  , Message = require('./message')
  , utils = require('./utils')

// MLP end frames
var FS = String.fromCharCode(0x1c)
  , CR = String.fromCharCode(0x0d)

exports.Message = Message
exports.Segment = Segment
exports.Parser = Parser
exports.utils = utils

/**
 * Constructor
 */
function Parser() {
  var opts = { objectMode: true }
  if (!(this instanceof Parser))
    return new Parser(opts)

  var self = this
  Transform.call(this, opts)

  this._messages = []
  this.current = null
}

util.inherits(Parser, Transform)

Parser.prototype._tryParseSegment = function _tryParseSegment(data, delims) {
  var self = this
  try {
    return new Segment(data, delims)
  } catch (err) {
    self.emit('error', err)
    return null
  }
}

/**
 * Transform for parser
 *
 * **NOTE: The stream should have been pipe through `split()` already**
 *
 * @param {Buffer} data The segment as a buffer
 * @param {String} encoding The encoding of the buffer
 * @param {Function} cb function(err, res)
 * @api private
 */
Parser.prototype._transform = function(data, encoding, done) {
  var self = this
  var delims = this.current
    ? this.current.delimiters()
    : null
  var segment = this._tryParseSegment(data, delims)

  if (!segment) return

  if (segment && segment.parsed) {
    var isHeader = utils.segmentIsHeader(segment)
    if (isHeader && this.current) {
      this.emit('message', this.current)
      var message = new Message()
      message.addSegment(segment)
      this._messages.push(message)
      this.current = message
    } else if (isHeader && !this.current) {
      this.current = new Message()
      this.current.addSegment(segment)
    } else {
      this.current.addSegment(segment)
    }

    /*
      If the message ended with FS+CR, this indicates the end of the message
      and it should be pushed over the transform stream now.
      http://www.hl7standards.com/blog/2007/05/02/hl7-mlp-minimum-layer-protocol-defined/
    */
    if (data.indexOf(FS + CR) !== -1) {
      this.emit('message', this.current)
      this.current = null
    }
  }
  done()
}

Parser.prototype._flush = function(done) {
  var self = this
  if (this.current && this.current.segments.length) {
    this.emit('message', this.current)
    this._messages.push(this.current)
    this.current = null
  }
  this.emit('messages', this._messages)
  done()
}
<|endoftext|>


<commit_before>'use strict';

var server = require('http').createServer();
var WebSocketServer = require('ws').Server;
var webSocketServer = new WebSocketServer({ server: server });
var express = require('express');
var _ = require('lodash');
var app = express();
var PORT = 80;
var playerManager = require('./player_manager')();
var messageHandler = require('./message_handler')();

app.use(express.static('app'));

webSocketServer.on('connection', function connection(socket) {
  var playerId = playerManager.createPlayer(socket);
  socket.send(JSON.stringify({type: 'login', playerId: playerId}));
  var otherPlayers = playerManager.getOtherPlayers(playerId);
  _.each(otherPlayers, function (player) {
    socket.send(JSON.stringify({type: 'newPlayer', playerId: player.id, position: player.position}));
    player.socket.send(JSON.stringify({type: 'newPlayer', playerId: playerId}));
  });

  socket.on('message', function incoming(message) {
    message = JSON.parse(message);
    messageHandler[message.type](message);
  });

  socket.on('close', function incoming(code, message) {
    playerManager.deletePlayer(playerId);
    _.each(playerManager.players, function (player) {
      player.socket.send(JSON.stringify({type: 'deletePlayer', playerId: playerId}));
    });
  });
});

server.on('request', app);
server.listen(PORT, function () {
  console.log('Grupica debilizma up and running!');
});<commit_msg>heroku port<commit_after>'use strict';

var server = require('http').createServer();
var WebSocketServer = require('ws').Server;
var webSocketServer = new WebSocketServer({ server: server });
var express = require('express');
var _ = require('lodash');
var app = express();
var PORT = process.env.PORT || 8080;
var playerManager = require('./player_manager')();
var messageHandler = require('./message_handler')();

app.use(express.static('app'));

webSocketServer.on('connection', function connection(socket) {
  var playerId = playerManager.createPlayer(socket);
  socket.send(JSON.stringify({type: 'login', playerId: playerId}));
  var otherPlayers = playerManager.getOtherPlayers(playerId);
  _.each(otherPlayers, function (player) {
    socket.send(JSON.stringify({type: 'newPlayer', playerId: player.id, position: player.position}));
    player.socket.send(JSON.stringify({type: 'newPlayer', playerId: playerId}));
  });

  socket.on('message', function incoming(message) {
    message = JSON.parse(message);
    messageHandler[message.type](message);
  });

  socket.on('close', function incoming(code, message) {
    playerManager.deletePlayer(playerId);
    _.each(playerManager.players, function (player) {
      player.socket.send(JSON.stringify({type: 'deletePlayer', playerId: playerId}));
    });
  });
});

server.on('request', app);
server.listen(PORT, function () {
  console.log('Grupica debilizma up and running!');
});<|endoftext|>


<commit_before>var _ = require('lodash'),
    HtmlDiff = require('./HtmlDiff'),
    modifyHtmlAccordingToOptions = require('./utils/modify'),
    defaults = require('./utils/defaults'),
    handleMasks = require('./utils/mask');

/**
 * Tokenizes the given HTML
 * @param {String} html
 * @returns {Array}
 */
HtmlDiff.prototype.tokenize = function (html) {
    html = modifyHtmlAccordingToOptions(html, this.options);

    return _.filter(html.split(/({{.+?}}(?!})|[{}\(\)=:;,<>"'\[\]\/]|\s+)/));
};

/**
 * @class HtmlDiffer
 * @constructor
 * @param {Object}   [options]
 * @param {String[]} [options.ignoreAttributes]
 * @param {String[]} [options.compareAttributesAsJSON]
 * @param {Boolean}  [options.ignoreWhitespaces=true]
 * @param {Boolean}  [options.ignoreComments=true]
 * @param {Boolean}  [options.ignoreEndTags=false]
 * @param {Boolean}  [options.ignoreDuplicateAttributes=false]
 */
var HtmlDiffer = function (options) {
    options = defaults(options);

    this.options = options;
};

/**
 * Returns the diff between two given chunks of HTML
 * @class HtmlDiffer
 * @method
 * @param {String} html1
 * @param {String} html2
 * @returns {Diff}
 */
HtmlDiffer.prototype.diffHtml = function (html1, html2) {
    var htmlDiffer = new HtmlDiff(this.options),
        diff = htmlDiffer.diff(html1, html2);

    return handleMasks(diff);
};

/**
 * Compares two given chunks of HTML
 * @class HtmlDiffer
 * @method
 * @param {String} html1
 * @param {String} html2
 * @returns {Boolean}
 */
HtmlDiffer.prototype.isEqual = function (html1, html2) {
    var diff = this.diffHtml(html1, html2);

    return (diff.length === 1 && !diff[0].added && !diff[0].removed);
};

var htmlDiffer = new HtmlDiffer();

module.exports = {
    HtmlDiffer: HtmlDiffer,
    diffHtml: htmlDiffer.diffHtml.bind(htmlDiffer),
    isEqual: htmlDiffer.isEqual.bind(htmlDiffer)
};
<commit_msg>Update tokenization of the input<commit_after>var _ = require('lodash'),
    HtmlDiff = require('./HtmlDiff'),
    modifyHtmlAccordingToOptions = require('./utils/modify'),
    defaults = require('./utils/defaults'),
    handleMasks = require('./utils/mask');

/**
 * Tokenizes the given HTML
 * @param {String} html
 * @returns {Array}
 */
HtmlDiff.prototype.tokenize = function (html) {
    html = modifyHtmlAccordingToOptions(html, this.options);

    return _.filter(html.split(/({{.+?}}(?!})|[{}\(\)\[\]#\*`=:;,<>"'\/]|\s+)/));
};

/**
 * @class HtmlDiffer
 * @constructor
 * @param {Object}   [options]
 * @param {String[]} [options.ignoreAttributes]
 * @param {String[]} [options.compareAttributesAsJSON]
 * @param {Boolean}  [options.ignoreWhitespaces=true]
 * @param {Boolean}  [options.ignoreComments=true]
 * @param {Boolean}  [options.ignoreEndTags=false]
 * @param {Boolean}  [options.ignoreDuplicateAttributes=false]
 */
var HtmlDiffer = function (options) {
    options = defaults(options);

    this.options = options;
};

/**
 * Returns the diff between two given chunks of HTML
 * @class HtmlDiffer
 * @method
 * @param {String} html1
 * @param {String} html2
 * @returns {Diff}
 */
HtmlDiffer.prototype.diffHtml = function (html1, html2) {
    var htmlDiffer = new HtmlDiff(this.options),
        diff = htmlDiffer.diff(html1, html2);

    return handleMasks(diff);
};

/**
 * Compares two given chunks of HTML
 * @class HtmlDiffer
 * @method
 * @param {String} html1
 * @param {String} html2
 * @returns {Boolean}
 */
HtmlDiffer.prototype.isEqual = function (html1, html2) {
    var diff = this.diffHtml(html1, html2);

    return (diff.length === 1 && !diff[0].added && !diff[0].removed);
};

var htmlDiffer = new HtmlDiffer();

module.exports = {
    HtmlDiffer: HtmlDiffer,
    diffHtml: htmlDiffer.diffHtml.bind(htmlDiffer),
    isEqual: htmlDiffer.isEqual.bind(htmlDiffer)
};
<|endoftext|>


<commit_before>'use strict';

/**
 * Takes some variable and asks `{}.toString()` what it thinks it is.
 * @param {*} value Anything
 * @example
 * type({})           // 'object'
 * type([])           // 'array'
 * type(1)            // 'number'
 * type(false)        // 'boolean'
 * type(Infinity)     // 'number'
 * type(null)         // 'null'
 * type(new Date())   // 'date'
 * type(/foo/)        // 'regexp'
 * type('type')       // 'string'
 * type(global)       // 'global'
 * @api private
 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString
 * @returns {string}
 */
function type(value) {
  if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {
    return 'buffer';
  }
  return Object.prototype.toString.call(value)
    .replace(/^\[.+\s(.+?)\]$/, '$1')
    .toLowerCase();
}

/**
 * @static .isArray()
 */
var isArray = Array.isArray;

/**
 * @static .keys()
 */
var keys = Object.keys;

/**
 * @summary Return a new Thing that has the keys in sorted order. Recursively.
 * @description
 * - has already been seen, return string `'[Circular]'`
 * - is `undefined`, return string `'[undefined]'`
 * - is `null`, return value `'[null]'`
 * - is some other primitive, return the value
 * - is not a primitive or an `Array`, `Object`, or `Function`, return the value of the Thing's `toString()` method
 * - is a non-empty `Array`, `Object`, or `Function`, return the result of calling this function again.
 * - is an empty `Array`, `Object`, or `Function`, return the result of calling `emptyRepresentation()`
 *
 * @param {*} value Thing to inspect.  May or may not have properties.
 * @param {Array} [stack=[]] Stack of seen values
 * @return {(Object|Array|Function|string|undefined)}
 * @see {@link exports.stringify}
 * @api private
 */

 function canonicalize(value, stack) {
  var canonicalizedObj,
    withStack = function withStack(value, fn) {
      stack.push(value);
      fn();
      stack.pop();
    };

  stack = stack || [];

  if (~stack.indexOf(value)) return '[Circular]';

  switch(type(value)) {
    case 'undefined':
    case 'buffer':
    case 'null':
      canonicalizedObj = value;
      break;
    case 'array':
      withStack(value, function () {
        canonicalizedObj = value.map(function (item) {
          return canonicalize(item, stack);
        });
      });
      break;
    case 'function':
      canonicalizedObj = '[Function]';
      break;
    case 'object':
      canonicalizedObj = canonicalizedObj || {};
      withStack(value, function () {
        keys(value).sort().forEach(function (key) {
          canonicalizedObj[key] = canonicalize(value[key], stack);
        });
      });
      break;
    case 'date':
    case 'number':
    case 'regexp':
    case 'boolean':
      canonicalizedObj = value;
      break;
    default:
      canonicalizedObj = value.toString();
  }

  return canonicalizedObj;
}

/**
 * @description
 * like JSON.stringify but more sense.
 * @param {Object}  object
 * @param {Number=} spaces
 * @param {number=} depth
 * @returns {*}
 * @private
 */
function jsonStringify(object, spaces, depth) {
  if(typeof spaces == 'undefined') return _stringify(object);  // primitive types

  depth = depth || 1;
  var space = spaces * depth
    , str = isArray(object) ? '[' : '{'
    , end = isArray(object) ? ']' : '}'
    , length = object.length || keys(object).length
    , repeat = function(s, n) { return new Array(n).join(s); }; // `.repeat()` polyfill

  function _stringify(val) {
    switch (type(val)) {
      case 'null':
      case 'undefined':
        val = '[' + val + ']';
        break;
      case 'array':
      case 'object':
        val = jsonStringify(val, spaces, depth + 1);
        break;
      case 'boolean':
      case 'regexp':
      case 'number':
        val = val === 0 && (1/val) === -Infinity // `-0`
          ? '-0'
          : val.toString();
        break;
      case 'date':
        val = '[Date: ' + val.toISOString() + ']';
        break;
      case 'buffer':
        var json = val.toJSON();
        // Based on the toJSON result
        json = json.data && json.type ? json.data : json;
        val = '[Buffer: ' + jsonStringify(json, 2, depth + 1) + ']';
        break;
      default:
        val = (val == '[Function]' || val == '[Circular]')
          ? val
          : JSON.stringify(val); //string, etc..
    }
    return val;
  }

  for(var i in object) {
    if(!object.hasOwnProperty(i)) continue;        // not my business
    --length;
    str += '\n ' + repeat(' ', space)
      + (isArray(object) ? '' : '"' + i + '": ') // key
      +  _stringify(object[i])                   // value
      + (length ? ',' : '');                     // comma
  }

  return str + (str.length != 1                    // [], {}
    ? '\n' + repeat(' ', --space) + end
    : end);
}

/**
 * @description
 * the exported function
 * @param value
 * @param spaces
 * @returns {*}
 */
module.exports = function(value, spaces) {
  var _type = type(value);

  if (!~['object', 'array', 'function'].indexOf(_type)) {
    if(_type != 'buffer') {
      return jsonStringify(value);
    }
    var json = value.toJSON();
    // Based on the toJSON result
    return jsonStringify(json.data && json.type ? json.data : json, 2);
  }
  return jsonStringify(canonicalize(value), spaces);
};<commit_msg>fix(global): fix global issue<commit_after>'use strict';

/**
 * Takes some variable and asks `{}.toString()` what it thinks it is.
 * @param {*} value Anything
 * @example
 * type({})           // 'object'
 * type([])           // 'array'
 * type(1)            // 'number'
 * type(false)        // 'boolean'
 * type(Infinity)     // 'number'
 * type(null)         // 'null'
 * type(new Date())   // 'date'
 * type(/foo/)        // 'regexp'
 * type('type')       // 'string'
 * type(global)       // 'global'
 * @api private
 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString
 * @returns {string}
 */
function type(value) {
  if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {
    return 'buffer';
  }
  return Object.prototype.toString.call(value)
    .replace(/^\[.+\s(.+?)\]$/, '$1')
    .toLowerCase();
}

/**
 * @static .isArray()
 */
var isArray = Array.isArray;

/**
 * @static .keys()
 */
var keys = Object.keys;

/**
 * @summary Return a new Thing that has the keys in sorted order. Recursively.
 * @description
 * - has already been seen, return string `'[Circular]'`
 * - is `undefined`, return string `'[undefined]'`
 * - is `null`, return value `'[null]'`
 * - is some other primitive, return the value
 * - is not a primitive or an `Array`, `Object`, or `Function`, return the value of the Thing's `toString()` method
 * - is a non-empty `Array`, `Object`, or `Function`, return the result of calling this function again.
 * - is an empty `Array`, `Object`, or `Function`, return the result of calling `emptyRepresentation()`
 *
 * @param {*} value Thing to inspect.  May or may not have properties.
 * @param {Array} [stack=[]] Stack of seen values
 * @return {(Object|Array|Function|string|undefined)}
 * @see {@link exports.stringify}
 * @api private
 */

 function canonicalize(value, stack) {
  var canonicalizedObj,
    withStack = function withStack(value, fn) {
      stack.push(value);
      fn();
      stack.pop();
    };

  stack = stack || [];

  if (~stack.indexOf(value)) return '[Circular]';
  switch(type(value)) {
    case 'undefined':
    case 'buffer':
    case 'null':
      canonicalizedObj = value;
      break;
    case 'array':
      withStack(value, function () {
        canonicalizedObj = value.map(function (item) {
          return canonicalize(item, stack);
        });
      });
      break;
    case 'function':
      canonicalizedObj = '[Function]';
      break;
    case 'global':
      canonicalizedObj = '[object global]';
      break;
    case 'object':
      canonicalizedObj = canonicalizedObj || {};
      withStack(value, function () {
        keys(value).sort().forEach(function (key) {
          canonicalizedObj[key] = canonicalize(value[key], stack);
        });
      });
      break;
    case 'date':
    case 'number':
    case 'regexp':
    case 'boolean':
      canonicalizedObj = value;
      break;
    default:
      canonicalizedObj = value.toString();
  }

  return canonicalizedObj;
}

/**
 * @description
 * like JSON.stringify but more sense.
 * @param {Object}  object
 * @param {Number=} spaces
 * @param {number=} depth
 * @returns {*}
 * @private
 */
function jsonStringify(object, spaces, depth) {
  if(typeof spaces == 'undefined') return _stringify(object);  // primitive types

  depth = depth || 1;
  var space = spaces * depth
    , str = isArray(object) ? '[' : '{'
    , end = isArray(object) ? ']' : '}'
    , length = object.length || keys(object).length
    , repeat = function(s, n) { return new Array(n).join(s); }; // `.repeat()` polyfill

  function _stringify(val) {
    switch (type(val)) {
      case 'null':
      case 'undefined':
        val = '[' + val + ']';
        break;
      case 'array':
      case 'object':
        val = jsonStringify(val, spaces, depth + 1);
        break;
      case 'boolean':
      case 'regexp':
      case 'number':
        val = val === 0 && (1/val) === -Infinity // `-0`
          ? '-0'
          : val.toString();
        break;
      case 'date':
        val = '[Date: ' + val.toISOString() + ']';
        break;
      case 'buffer':
        var json = val.toJSON();
        // Based on the toJSON result
        json = json.data && json.type ? json.data : json;
        val = '[Buffer: ' + jsonStringify(json, 2, depth + 1) + ']';
        break;
      default:
        val = ~['[Function]', '[Circular]', '[object global]'].indexOf(val)
          ? val
          : JSON.stringify(val); //string, etc..
    }
    return val;
  }

  for(var i in object) {
    if(!object.hasOwnProperty(i)) continue;        // not my business
    --length;
    str += '\n ' + repeat(' ', space)
      + (isArray(object) ? '' : '"' + i + '": ') // key
      +  _stringify(object[i])                   // value
      + (length ? ',' : '');                     // comma
  }

  return str + (str.length != 1                    // [], {}
    ? '\n' + repeat(' ', --space) + end
    : end);
}

/**
 * @description
 * the exported function
 * @param value
 * @param spaces
 * @returns {*}
 */
module.exports = function(value, spaces) {
  var _type = type(value);

  if (!~['object', 'array', 'function'].indexOf(_type)) {
    if(_type != 'buffer') {
      return jsonStringify(value);
    }
    var json = value.toJSON();
    // Based on the toJSON result
    return jsonStringify(json.data && json.type ? json.data : json, 2);
  }
  return jsonStringify(canonicalize(value), spaces);
};<|endoftext|>


<commit_before>#!/usr/bin/env node

/**
 * Module dependencies.
 */

var async = require('async');
var express = require('express');
var http = require('http');
var weIo = require('./socket.io');
var _ = require('lodash');
var wePassport = require('./passport/index.js');
var pluginManager = require('./pluginManager');
var localization = require('./localization');
var exec = require('child_process').exec;

var we = {};

we.hooks = require('./hooks');
we.events = require('./events');

we.url = require('./url');

// project path
we.projectPath = process.cwd();

// - Configure Logger
we.log = require('./log')(we.projectPath);

we.acl = require('./acl');

// start and load db
we.db = require('./database/index.js');

we.sanitizer = require('./sanitizer');

we.loaders = require('./loaders.js');
we.router = require('./router.js');
we.config = require('./staticConfig')(we.projectPath);

// client side config generator
we.getAppBootstrapConfig = require('./staticConfig/getAppBootstrapConfig.js');

we.pluginPaths = [];
we.pluginNames = [];
// load plugin configs
we.pluginConfigs = require('./pluginManager/loadPluginConfig.js')();
we.plugins = pluginManager.plugins;

// save plugin paths and names in a array
for ( var pluginName in we.plugins ) {
  we.pluginNames.push(pluginName);
  if (we.plugins[pluginName].pluginPath) {
    we.pluginPaths.push(we.plugins[pluginName].pluginPath);
  }
}

if (we.env != 'prod') {
  var pluginNames = Object.keys(we.plugins);
  we.log.info( pluginNames.length +' plugins loaded:', pluginNames.join() )
}

we.antiSpam = require('./antiSpam');

we.term = require('./term');

we.childProcesses = [];

we.db.models = {};
we.db.modelsConfigs = {};

we.controllers = {};
var weExpress = require('./express');
// we.js classes
we.class = require('./class/index.js');
// save a reference to we.js object
we.class.Plugin.prototype.we = we;

we.email = require('./email');

// enviroment config prod | dev | test
we.env = require('./env.js');

we.getRouter = function() {
  return express.Router();
}

we.bootstrapStarted = false;

/**
 * Bootstrap and initialize the app
 *
 */
we.bootstrap = function bootstrap(configOnRun, cb) {
  if (we.bootstrapStarted) throw new Error('We.js already did bootstrap');
  we.bootstrapStarted = true;

  if (!cb) {
    cb = configOnRun;
    configOnRun = null;
  }

  if (configOnRun) _.merge(we.config, configOnRun);

  async.series([
    function loadPluginFeatures(next) {
      for (var pluginName in we.plugins) {
        // run all plugins loadFeatures function
        we.plugins[pluginName].loadFeatures(we);
      }

      we.events.emit('we:after:load:plugins', we);

      next();
    },

    function checkRequirements(next) {
      exec('gm version', function (error, stdout, stderr) {
        if (error) {
          return next('Requirement GraphicsMagick not found or not instaled, see: https://github.com/aheckmann/gm');
        }

        return next();
      });
    },

    function loadModels(next) {
      we.loaders.loadModels(we, function(err, models) {
        if (err) return next(err);
        _.merge(we.db.modelsConfigs, models);
        next();
      })
    },

    function instantiateModels(next) {
      we.hooks.trigger('we:models:after:instance', we, function(err) {
        for ( var modelName in we.db.modelsConfigs) {
          we.db.models[modelName] = we.db.define(
            modelName,
            we.db.modelsConfigs[modelName].definition,
            we.db.modelsConfigs[modelName].options
          );
        }

        we.db.setModelAllJoins();

        we.hooks.trigger('we:models:set:joins', we, function afterSetJoins(err) {
            we.db.syncAllModels(we.config.database, next);
        });
      });
    },

    function initACL(next) {
      we.acl.init(we, next);
    },

    function loadControllers(next) {
      we.loaders.loadControllers(we, function(err, controllers) {
        if (err) return next(err);
        _.merge(we.controllers, controllers);

        we.events.emit('we:after:load:controllers', we);
        next();
      })
    },

    function initExpressPassport(next) {
      we.express = weExpress(we);
      // - Passports configs
      wePassport.configureAndSetStrategies(we);

      we.events.emit('we:after:load:passport', we);

      // admin page loader
      we.express.get('/admin', function adminPage(req ,res , next) {
        var we = req.getWe();

        res.locals.isAdmin = true;

        we.acl.can('can_administer', req.user, null, function(err, can) {
          if (err) return res.serverError();

          if (!can) return res.forbidden();

          res.locals.template = 'home/index';
          res.view();
        })
      });

      next();
    },

    function initI18n(next) {
      localization(we);
      we.events.emit('we:after:init:i18n', we);
      next();
    },

    function createDefaultFolders(next) {
      we.hooks.trigger('we:create:default:folders', we, function() {
        next();
      });
    },

    function startGrunt(next) {
      if (we.env === 'dev') {
        var runTask = require('./grunt/initTaskAsSubProcess.js');
        runTask('default', we);
      }
      next();
    },

    function loadEmailTemplates(next) {
      we.email.init(we);

      we.loaders.loadEmailTemplates(we, function(err, templates) {
        if (err) return next(err);

        we.email.templates = templates;

        next();
      });
    },

    function mergeRoutes(next) {
      we.routes = {};
      // merge plugin routes
      for ( var plugin in we.plugins) {
        _.merge(we.routes, we.plugins[plugin].routes);
      }
      // merge project routes
       _.merge(we.routes, we.config.routes);
      next();
    },

    function bindRoutes(next) {
      // bind dinamic url
      we.express.get('*', we.url.middleware);

      for( var route in we.routes) {
        we.router.bindRoute(we, route, we.routes[route] );
      }
      next();
    }
  ], function bootstrapDone(err) {
    if (err) {
      console.error('Error on we.js bootstrap: ', err);
      return cb(err);
    }

    we.events.emit('we:bootstrap:done', we);

    we.log.debug('We.js bootstrap done');
    return cb(null, we);
  });
}

we.startServer = function startExpressServer(cb) {
  /**
   * Get port from environment and store in Express.
   */

  var port = normalizePort(we.config.port);
  we.express.set('port', port);

  /**
   * Create HTTP server.
   */

  var server = http.createServer(we.express);

  weIo.load(we, server);

  /**
   * Listen on provided port, on all network interfaces.
   */

  // catch 404 and forward to error handler
  we.express.use(function(req, res, next) {
    we.log.debug('Route not found:', req.path);
    // var err = new Error('Not Found');
    // err.status = 404;
    return res.notFound();
  });

  server.listen(port);
  server.on('error', onError);
  server.on('listening', onListening);

  /**
   * Normalize a port into a number, string, or false.
   */

  function normalizePort(val) {
    var port = parseInt(val, 10);

    if (isNaN(port)) {
      // named pipe
      return val;
    }

    if (port >= 0) {
      // port number
      return port;
    }

    return false;
  }

  /**
   * Event listener for HTTP server "error" event.
   */

  function onError(error) {
    if (error.syscall !== 'listen') {
      throw error;
    }

    var bind = typeof port === 'string'
      ? 'Pipe ' + port
      : 'Port ' + port;

    // handle specific listen errors with friendly messages
    switch (error.code) {
      case 'EACCES':
        console.error(bind + ' requires elevated privileges');
        process.exit(1);
        break;
      case 'EADDRINUSE':
        console.error(bind + ' is already in use');
        process.exit(1);
        break;
      default:
        throw error;
    }
  }

  /**
   * Event listener for HTTP server "listening" event.
   */

  function onListening() {
    var addr = server.address();
    var bind = typeof addr === 'string'
      ? 'pipe ' + addr
      : 'port ' + addr.port;
    we.log.info('Listening on ' + bind);
  }

  // save the current server
  we.http = server;

  // express error handlers
  // development error handler
  // will print stacktrace
  we.express.use(function onExpressError(err, req, res, next) {
    we.log.error('Error on:', req.path, err);

    res.serverError();
  });

  cb(null, we);
}

/**
 * Bootstrap and Start we.js server
 *
 * @param  {Object}   cfgs configs (optional)
 * @param  {Function} cb   callback
 */
we.go = function go(cfgs, cb) {
  if (!cb) {
    cb = cfgs;
    cfgs = {};
  }

  we.bootstrap(cfgs, function(err, we) {
    we.startServer(cb);
  });
}

/**
 * Turn off process function
 *
 * @param  {Function} cb callback
 */
we.exit = function exit(cb) {

  we.db.defaultConnection.close();

  cb();
}

module.exports = we;
<commit_msg>add console.trace in bootstrap error<commit_after>#!/usr/bin/env node

/**
 * Module dependencies.
 */

var async = require('async');
var express = require('express');
var http = require('http');
var weIo = require('./socket.io');
var _ = require('lodash');
var wePassport = require('./passport/index.js');
var pluginManager = require('./pluginManager');
var localization = require('./localization');
var exec = require('child_process').exec;

var we = {};

we.hooks = require('./hooks');
we.events = require('./events');

we.url = require('./url');

// project path
we.projectPath = process.cwd();

// - Configure Logger
we.log = require('./log')(we.projectPath);

we.acl = require('./acl');

// start and load db
we.db = require('./database/index.js');

we.sanitizer = require('./sanitizer');

we.loaders = require('./loaders.js');
we.router = require('./router.js');
we.config = require('./staticConfig')(we.projectPath);

// client side config generator
we.getAppBootstrapConfig = require('./staticConfig/getAppBootstrapConfig.js');

we.pluginPaths = [];
we.pluginNames = [];
// load plugin configs
we.pluginConfigs = require('./pluginManager/loadPluginConfig.js')();
we.plugins = pluginManager.plugins;

// save plugin paths and names in a array
for ( var pluginName in we.plugins ) {
  we.pluginNames.push(pluginName);
  if (we.plugins[pluginName].pluginPath) {
    we.pluginPaths.push(we.plugins[pluginName].pluginPath);
  }
}

if (we.env != 'prod') {
  var pluginNames = Object.keys(we.plugins);
  we.log.info( pluginNames.length +' plugins loaded:', pluginNames.join() )
}

we.antiSpam = require('./antiSpam');

we.term = require('./term');

we.childProcesses = [];

we.db.models = {};
we.db.modelsConfigs = {};

we.controllers = {};
var weExpress = require('./express');
// we.js classes
we.class = require('./class/index.js');
// save a reference to we.js object
we.class.Plugin.prototype.we = we;

we.email = require('./email');

// enviroment config prod | dev | test
we.env = require('./env.js');

we.getRouter = function() {
  return express.Router();
}

we.bootstrapStarted = false;

/**
 * Bootstrap and initialize the app
 *
 */
we.bootstrap = function bootstrap(configOnRun, cb) {
  if (we.bootstrapStarted) throw new Error('We.js already did bootstrap');
  we.bootstrapStarted = true;

  if (!cb) {
    cb = configOnRun;
    configOnRun = null;
  }

  if (configOnRun) _.merge(we.config, configOnRun);

  async.series([
    function loadPluginFeatures(next) {
      for (var pluginName in we.plugins) {
        // run all plugins loadFeatures function
        we.plugins[pluginName].loadFeatures(we);
      }

      we.events.emit('we:after:load:plugins', we);

      next();
    },

    function checkRequirements(next) {
      exec('gm version', function (error, stdout, stderr) {
        if (error) {
          return next('Requirement GraphicsMagick not found or not instaled, see: https://github.com/aheckmann/gm');
        }

        return next();
      });
    },

    function loadModels(next) {
      we.loaders.loadModels(we, function(err, models) {
        if (err) return next(err);
        _.merge(we.db.modelsConfigs, models);
        next();
      })
    },

    function instantiateModels(next) {
      we.hooks.trigger('we:models:after:instance', we, function(err) {
        for ( var modelName in we.db.modelsConfigs) {
          we.db.models[modelName] = we.db.define(
            modelName,
            we.db.modelsConfigs[modelName].definition,
            we.db.modelsConfigs[modelName].options
          );
        }

        we.db.setModelAllJoins();

        we.hooks.trigger('we:models:set:joins', we, function afterSetJoins(err) {
            we.db.syncAllModels(we.config.database, next);
        });
      });
    },

    function initACL(next) {
      we.acl.init(we, next);
    },

    function loadControllers(next) {
      we.loaders.loadControllers(we, function(err, controllers) {
        if (err) return next(err);
        _.merge(we.controllers, controllers);

        we.events.emit('we:after:load:controllers', we);
        next();
      })
    },

    function initExpressPassport(next) {
      we.express = weExpress(we);
      // - Passports configs
      wePassport.configureAndSetStrategies(we);

      we.events.emit('we:after:load:passport', we);

      // admin page loader
      we.express.get('/admin', function adminPage(req ,res , next) {
        var we = req.getWe();

        res.locals.isAdmin = true;

        we.acl.can('can_administer', req.user, null, function(err, can) {
          if (err) return res.serverError();

          if (!can) return res.forbidden();

          res.locals.template = 'home/index';
          res.view();
        })
      });

      next();
    },

    function initI18n(next) {
      localization(we);
      we.events.emit('we:after:init:i18n', we);
      next();
    },

    function createDefaultFolders(next) {
      we.hooks.trigger('we:create:default:folders', we, function() {
        next();
      });
    },

    function startGrunt(next) {
      if (we.env === 'dev') {
        var runTask = require('./grunt/initTaskAsSubProcess.js');
        runTask('default', we);
      }
      next();
    },

    function loadEmailTemplates(next) {
      we.email.init(we);

      we.loaders.loadEmailTemplates(we, function(err, templates) {
        if (err) return next(err);

        we.email.templates = templates;

        next();
      });
    },

    function mergeRoutes(next) {
      we.routes = {};
      // merge plugin routes
      for ( var plugin in we.plugins) {
        _.merge(we.routes, we.plugins[plugin].routes);
      }
      // merge project routes
       _.merge(we.routes, we.config.routes);
      next();
    },

    function bindRoutes(next) {
      // bind dinamic url
      we.express.get('*', we.url.middleware);

      for( var route in we.routes) {
        we.router.bindRoute(we, route, we.routes[route] );
      }
      next();
    }
  ], function bootstrapDone(err) {
    if (err) {
      console.error('Error on we.js bootstrap: ', err);
      console.trace();
      return cb(err);
    }

    we.events.emit('we:bootstrap:done', we);

    we.log.debug('We.js bootstrap done');
    return cb(null, we);
  });
}

we.startServer = function startExpressServer(cb) {
  /**
   * Get port from environment and store in Express.
   */

  var port = normalizePort(we.config.port);
  we.express.set('port', port);

  /**
   * Create HTTP server.
   */

  var server = http.createServer(we.express);

  weIo.load(we, server);

  /**
   * Listen on provided port, on all network interfaces.
   */

  // catch 404 and forward to error handler
  we.express.use(function(req, res, next) {
    we.log.debug('Route not found:', req.path);
    // var err = new Error('Not Found');
    // err.status = 404;
    return res.notFound();
  });

  server.listen(port);
  server.on('error', onError);
  server.on('listening', onListening);

  /**
   * Normalize a port into a number, string, or false.
   */

  function normalizePort(val) {
    var port = parseInt(val, 10);

    if (isNaN(port)) {
      // named pipe
      return val;
    }

    if (port >= 0) {
      // port number
      return port;
    }

    return false;
  }

  /**
   * Event listener for HTTP server "error" event.
   */

  function onError(error) {
    if (error.syscall !== 'listen') {
      throw error;
    }

    var bind = typeof port === 'string'
      ? 'Pipe ' + port
      : 'Port ' + port;

    // handle specific listen errors with friendly messages
    switch (error.code) {
      case 'EACCES':
        console.error(bind + ' requires elevated privileges');
        process.exit(1);
        break;
      case 'EADDRINUSE':
        console.error(bind + ' is already in use');
        process.exit(1);
        break;
      default:
        throw error;
    }
  }

  /**
   * Event listener for HTTP server "listening" event.
   */

  function onListening() {
    var addr = server.address();
    var bind = typeof addr === 'string'
      ? 'pipe ' + addr
      : 'port ' + addr.port;
    we.log.info('Listening on ' + bind);
  }

  // save the current server
  we.http = server;

  // express error handlers
  // development error handler
  // will print stacktrace
  we.express.use(function onExpressError(err, req, res, next) {
    we.log.error('Error on:', req.path, err);

    res.serverError();
  });

  cb(null, we);
}

/**
 * Bootstrap and Start we.js server
 *
 * @param  {Object}   cfgs configs (optional)
 * @param  {Function} cb   callback
 */
we.go = function go(cfgs, cb) {
  if (!cb) {
    cb = cfgs;
    cfgs = {};
  }

  we.bootstrap(cfgs, function(err, we) {
    we.startServer(cb);
  });
}

/**
 * Turn off process function
 *
 * @param  {Function} cb callback
 */
we.exit = function exit(cb) {

  we.db.defaultConnection.close();

  cb();
}

module.exports = we;
<|endoftext|>


<commit_before>var
  hooks = require('./config/hooks');

module.exports = function SocketioProtocol () {
  this.config = {};
  this.protocol = 'socketio';
  this.isDummy = false;
  this.io = null;
  this.context = null;

  this.init = function (config, context, isDummy) {
    if (!config) {
      throw new Error('plugin-socketio: A configuration parameter is required');
    }

    if (!config.port) {
      /*eslint no-console: 0*/
      this.isDummy = true;
      console.error(new Error('plugin-socketio: the \'port\' attribute, with the port to listen to, is required'));
      return false;
    }

    this.isDummy = isDummy;
    this.config = config;
    this.context = context;

    if (this.isDummy) {
      return this;
    }

    this.io = require('socket.io')(this.config.port);
    this.io.set('origins', '*:*');

    this.io.on('connection', socket => {
      this.newConnection(socket);
    });

    this.io.on('error', err => {
      /*eslint no-console: 0*/
      console.error('Unable to connect: ', err, '\nFalling back to dummy-mode.');
      this.isDummy = true;
    });

    return this;
  };

  this.hooks = hooks;

  this.broadcast = function (data) {
    if (this.isDummy) {
      return false;
    }

    this.io.to(data.channel).emit(data.channel, data.payload);
  };

  this.notify = function (data) {
    if (this.isDummy) {
      return false;
    }

    if (this.io.sockets.connected[data.id]) {
      this.io.sockets.connected[data.id].emit(data.channel, data.payload);
    }
  }

  this.joinChannel = function (data) {
    if (this.isDummy) {
      return false;
    }

    if (this.io.sockets.connected[data.id]) {
      this.io.sockets.connected[data.id].join(data.channel);
    }
  };

  this.leaveChannel = function (data) {
    if (this.isDummy) {
      return false;
    }

    if (this.io.sockets.connected[data.id]) {
      this.io.sockets.connected[data.id].leave(data.channel);
    }
  };

  this.newConnection = function (socket) {
    if (this.isDummy) {
      return false;
    }

    this.context.getRouter().newConnection(this.protocol, socket.id)
      .then(connection => {
        socket.on(this.config.room, data => {
          var requestObject = new this.context.RequestObject(data, {}, this.protocol);

          this.context.getRouter().execute(requestObject, connection)
            .then(responseObject => {
              this.io.to(socket.id).emit(requestObject.requestId, responseObject.toJson());
            })
            .catch(error => {
              this.io.to(socket.id).emit(requestObject.requestId, error.toJson());
            });
        });

        socket.on('disconnect', () => {
          this.context.getRouter().removeConnection(connection);
        });

        socket.on('error', () => {
          this.context.getRouter().removeConnection(connection);
        });
      })
      .catch(err => {
        /*eslint no-console: 0*/
        console.error('Unable to declare new connection: ', err);
      });
  };
};
<commit_msg>fixed eslint error<commit_after>var
  hooks = require('./config/hooks');

module.exports = function SocketioProtocol () {
  this.config = {};
  this.protocol = 'socketio';
  this.isDummy = false;
  this.io = null;
  this.context = null;

  this.init = function (config, context, isDummy) {
    if (!config) {
      throw new Error('plugin-socketio: A configuration parameter is required');
    }

    if (!config.port) {
      /*eslint no-console: 0*/
      this.isDummy = true;
      console.error(new Error('plugin-socketio: the \'port\' attribute, with the port to listen to, is required'));
      return false;
    }

    this.isDummy = isDummy;
    this.config = config;
    this.context = context;

    if (this.isDummy) {
      return this;
    }

    this.io = require('socket.io')(this.config.port);
    this.io.set('origins', '*:*');

    this.io.on('connection', socket => {
      this.newConnection(socket);
    });

    this.io.on('error', err => {
      /*eslint no-console: 0*/
      console.error('Unable to connect: ', err, '\nFalling back to dummy-mode.');
      this.isDummy = true;
    });

    return this;
  };

  this.hooks = hooks;

  this.broadcast = function (data) {
    if (this.isDummy) {
      return false;
    }

    this.io.to(data.channel).emit(data.channel, data.payload);
  };

  this.notify = function (data) {
    if (this.isDummy) {
      return false;
    }

    if (this.io.sockets.connected[data.id]) {
      this.io.sockets.connected[data.id].emit(data.channel, data.payload);
    }
  };

  this.joinChannel = function (data) {
    if (this.isDummy) {
      return false;
    }

    if (this.io.sockets.connected[data.id]) {
      this.io.sockets.connected[data.id].join(data.channel);
    }
  };

  this.leaveChannel = function (data) {
    if (this.isDummy) {
      return false;
    }

    if (this.io.sockets.connected[data.id]) {
      this.io.sockets.connected[data.id].leave(data.channel);
    }
  };

  this.newConnection = function (socket) {
    if (this.isDummy) {
      return false;
    }

    this.context.getRouter().newConnection(this.protocol, socket.id)
      .then(connection => {
        socket.on(this.config.room, data => {
          var requestObject = new this.context.RequestObject(data, {}, this.protocol);

          this.context.getRouter().execute(requestObject, connection)
            .then(responseObject => {
              this.io.to(socket.id).emit(requestObject.requestId, responseObject.toJson());
            })
            .catch(error => {
              this.io.to(socket.id).emit(requestObject.requestId, error.toJson());
            });
        });

        socket.on('disconnect', () => {
          this.context.getRouter().removeConnection(connection);
        });

        socket.on('error', () => {
          this.context.getRouter().removeConnection(connection);
        });
      })
      .catch(err => {
        /*eslint no-console: 0*/
        console.error('Unable to declare new connection: ', err);
      });
  };
};
<|endoftext|>