<commit_before>var step = require("step"),
outcome = require("outcome"),
request = require("request"),
fs = require("fs"),
mkdirp = require("mkdirp"),
path = require("path"),
child_process = require("child_process"),
exec = child_process.exec,
spawn = child_process.spawn,
sprintf = require("sprintf").sprintf,
ncp = require("ncp").ncp,
sardines = require("sardines");

/**
 */

exports.compile = function(args, next) {

	var on = outcome.error(next);

	args.input = require.resolve(args.input);

	step(

		/**
		 * 1. download node
		 */

		function() {
			downloadNode(args.runtime, this);
		},

		/**
		 * 2. build the script into ONE file
		 */

		on.success(function(node) {
			console.log("making application bundle with %s", args.input);
			this.node = node;

			sardines({ entries: [args.input], platform: "node" }, this);
		}),

		on.success(function(content) {
			console.log("writing application bundle: \n\n%s\n\n", content);
			fs.writeFile(this.nexePath = path.join(this.node.dir, "lib", "nexe.js"), content, "utf8", this);
		}),

		/**
		 * 4. monkeypatch the node entry
		 */

		on.success(function() {
			console.log("monkey patching node.js file");
			monkeyPatchNodejs(this.node, this);
		}),

		/**
		 * 5. bundle it all together
		 */

		on.success(function() {
			console.log("building node.js");
			this.node.make(this);
		}),

		/**
		 * 6. copy the executable
		 */

		on.success(function() {
			console.log("copying binary to output directory to %s", args.output);

			mkdirp(path.dirname(args.output), this);
		}),

		/**
		 */

		function() {
			ncp(this.node.releasePath, args.output, this);
		},

		/**
		 */

		next

	);
};

/**
 */

function downloadNode(version, next) {

	var tmpPath = path.join("/tmp/nexe", "node-v" + version + ".tar.gz"),
	srcDr       = tmpPath.replace(/\.tar.gz$/, "");

	try {

		mkdirp.sync(path.dirname(tmpPath));

	//an error will usually occur when the dir already exists.
	} catch(e) { }

	step(

		/**
		 * download
		 */

		function() {

			//zip exists?
			if(fs.existsSync(tmpPath) || fs.existsSync(srcDr)) return this();

			console.log("downloading node %s", version);

			var output = fs.createWriteStream(tmpPath, { "flags": "w+" }),
			req = request("http://nodejs.org/dist/v" + version + "/node-v" + version + ".tar.gz").pipe(output);

			output.on("close", this);
		},

		/**
		 * untar
		 */

		function() {

			//source dir exists?
			if(fs.existsSync(srcDr)) return this();

			console.log("unzipping node source");

			//TODO - use native zlib library for this
			exec(sprintf("tar -xf '%s'", tmpPath), { cwd: path.dirname(tmpPath) }, this);
		},

		/**
		 * cleanup the node.js file
		 */

		function() {
			fs.unlink(tmpfile, this);
		},

		/**
		 * return make script
		 */

		function() {
			next(null, {

				//the directory to the node.js file
				dir: srcDr,

				releasePath: path.join(srcDr, "out/Release/node"),

				//makes node.js
				make: function(next) {
					var proc = exec(sprintf("cd %s; ./configure; make; ", srcDr));
					proc.stdout._events = {}; //remove stdout & stdin capture
					proc.stdin._events = {};
					proc.stdout.on("data", function(chunk) {
						process.stdout.write(chunk);
					});
					proc.stderr.on("data", function(chunk) {
						process.stdout.write(chunk);
					});

					proc.on("exit", next);
				}
			});
		}
	);
}

/**
 */

function monkeyPatchNodejs(node, next) {

	var nodejsPath = path.join(node.dir, "src", "node.js"),
	nodegypPath    = path.join(node.dir, "node.gyp"),
	on = outcome.error(next);

	step(

		/**
		 * read the node.js file
		 */

		function() {
			fs.readFile(nodejsPath, "utf8", this);
		},

		/**
		 * inject nexe as _eval IF it hasn't already been injected
		 */

		on.success(function(content) {

			//nexe already injected?
			if(~content.indexOf('nexe')) return this();

			fs.writeFile(nodejsPath,
			content.replace(/\(function\(process\) \{/,'(function(process){ \n process._eval = \'require("nexe");\'; '),
			"utf8",
			this);
		}),

		/**
		 * next, find node.gyp and add nexe as a native lib file
		 */

		on.success(function() {
			fs.readFile(nodegypPath, "utf8", this);
		}),

		/**
		 * finally, monkeypatch node.gyp
		 */

		on.success(function(content) {

			//nexe already included as dep?
			if(~content.indexOf('lib/nexe.js')) return this();

			fs.writeFile(nodegypPath,
			content.replace("'lib/fs.js',", "'lib/fs.js', 'lib/nexe.js', "),
			"utf8",
			this);
		}),

		/**
		 */

		next
	);
}
<commit_msg>Rewrite configure/make spawning<commit_after>var step = require("step"),
outcome = require("outcome"),
request = require("request"),
fs = require("fs"),
mkdirp = require("mkdirp"),
path = require("path"),
child_process = require("child_process"),
exec = child_process.exec,
spawn = child_process.spawn,
sprintf = require("sprintf").sprintf,
ncp = require("ncp").ncp,
sardines = require("sardines");

/**
 */

exports.compile = function(args, next) {

	var on = outcome.error(next);

	args.input = require.resolve(args.input);

	step(

		/**
		 * 1. download node
		 */

		function() {
			downloadNode(args.runtime, this);
		},

		/**
		 * 2. build the script into ONE file
		 */

		on.success(function(node) {
			console.log("making application bundle with %s", args.input);
			this.node = node;

			sardines({ entries: [args.input], platform: "node" }, this);
		}),

		on.success(function(content) {
			console.log("writing application bundle: \n\n%s\n\n", content);
			fs.writeFile(this.nexePath = path.join(this.node.dir, "lib", "nexe.js"), content, "utf8", this);
		}),

		/**
		 * 4. monkeypatch the node entry
		 */

		on.success(function() {
			console.log("monkey patching node.js file");
			monkeyPatchNodejs(this.node, this);
		}),

		/**
		 * 5. bundle it all together
		 */

		on.success(function() {
			console.log("building node.js");
			this.node.make(this);
		}),

		/**
		 * 6. copy the executable
		 */

		on.success(function() {
			console.log("copying binary to output directory to %s", args.output);

			mkdirp(path.dirname(args.output), this);
		}),

		/**
		 */

		function() {
			ncp(this.node.releasePath, args.output, this);
		},

		/**
		 */

		next

	);
};

/**
 */

function downloadNode(version, next) {

	var tmpPath = path.join("/tmp/nexe", "node-v" + version + ".tar.gz"),
	srcDr       = tmpPath.replace(/\.tar.gz$/, "");

	try {

		mkdirp.sync(path.dirname(tmpPath));

	//an error will usually occur when the dir already exists.
	} catch(e) { }

	step(

		/**
		 * download
		 */

		function() {

			//zip exists?
			if(fs.existsSync(tmpPath) || fs.existsSync(srcDr)) return this();

			console.log("downloading node %s", version);

			var output = fs.createWriteStream(tmpPath, { "flags": "w+" }),
			req = request("http://nodejs.org/dist/v" + version + "/node-v" + version + ".tar.gz").pipe(output);

			output.on("close", this);
		},

		/**
		 * untar
		 */

		function() {

			//source dir exists?
			if(fs.existsSync(srcDr)) return this();

			console.log("unzipping node source");

			//TODO - use native zlib library for this
			exec(sprintf("tar -xf '%s'", tmpPath), { cwd: path.dirname(tmpPath) }, this);
		},

		/**
		 * cleanup the node.js file
		 */

		function() {
			fs.unlink(tmpfile, this);
		},

		/**
		 * return make script
		 */

		function() {
			next(null, {

				//the directory to the node.js file
				dir: srcDr,

				releasePath: path.join(srcDr, "out/Release/node"),

				//makes node.js
				make: function(next) {
					var configure = spawn('./configure', [], { cwd: srcDr });
					configure.stdout.on('data', function(data) {
						process.stdout.write(data.toString());
					});
					configure.stderr.on('data', function(data) {
						process.stderr.write(data.toString());
					});
					configure.on('close', function() {
						var make = spawn('make', [], { cwd: srcDr });
						make.stdout.on('data', function(data) {
							process.stdout.write(data.toString());
						});
						make.stderr.on('data', function(data) {
							process.stderr.write(data.toString());
						});
						make.on('close', next);
					});
				}
			});
		}
	);
}

/**
 */

function monkeyPatchNodejs(node, next) {

	var nodejsPath = path.join(node.dir, "src", "node.js"),
	nodegypPath    = path.join(node.dir, "node.gyp"),
	on = outcome.error(next);

	step(

		/**
		 * read the node.js file
		 */

		function() {
			fs.readFile(nodejsPath, "utf8", this);
		},

		/**
		 * inject nexe as _eval IF it hasn't already been injected
		 */

		on.success(function(content) {

			//nexe already injected?
			if(~content.indexOf('nexe')) return this();

			fs.writeFile(nodejsPath,
			content.replace(/\(function\(process\) \{/,'(function(process){ \n process._eval = \'require("nexe");\'; '),
			"utf8",
			this);
		}),

		/**
		 * next, find node.gyp and add nexe as a native lib file
		 */

		on.success(function() {
			fs.readFile(nodegypPath, "utf8", this);
		}),

		/**
		 * finally, monkeypatch node.gyp
		 */

		on.success(function(content) {

			//nexe already included as dep?
			if(~content.indexOf('lib/nexe.js')) return this();

			fs.writeFile(nodegypPath,
			content.replace("'lib/fs.js',", "'lib/fs.js', 'lib/nexe.js', "),
			"utf8",
			this);
		}),

		/**
		 */

		next
	);
}
<|endoftext|>


<commit_before>/**
* 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('yuidoc');
    var json = (new Y.YUIDoc(options)).run();

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

var YUI = require('yui3').YUI,
    path = require('path');

var Y = YUI({
    modules: {
        help: {
            fullpath: path.join(__dirname, 'help.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')
        },
        utils: {
            fullpath: path.join(__dirname, 'utils.js')
        },
        docview: {
            fullpath: path.join(__dirname, 'docview.js')
        }
    },
    logExclude: {
        yui: true,
        get: true,
        loader: true,
        files: true
    }
}).useSync('docparser', 'yuidoc', 'utils', 'doc-builder', 'docview', 'files', 'help');

module.exports = Y;
<commit_msg>Added version support for CLI<commit_after>/**
* 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('yuidoc');
    var json = (new Y.YUIDoc(options)).run();

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

var YUI = require('yui3').YUI,
    path = require('path');

var Y = YUI({
    modules: {
        help: {
            fullpath: path.join(__dirname, 'help.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')
        },
        utils: {
            fullpath: path.join(__dirname, 'utils.js')
        },
        docview: {
            fullpath: path.join(__dirname, 'docview.js')
        }
    },
    logExclude: {
        yui: true,
        get: true,
        loader: true,
        files: true
    }
}).useSync('docparser', 'yuidoc', 'utils', 'doc-builder', 'docview', 'files', 'help');

Y.packageInfo = Y.Files.getJSON(path.join(__dirname, '../', 'package.json'));

module.exports = Y;
<|endoftext|>


<commit_before>'use strict';

/**
 * @file Helper for pdf2htmlEX file processing
 * For more information about Pdf2htmlex :
 * https://github.com/coolwanglu/pdf2htmlEX.git
 */

var fs = require('fs');
var async = require('async');
var shellExec = require('child_process').exec;
var crypto = require('crypto');
var config = require('../config/configuration.js');

/**
 * Extract the content in html of the specified pdf
 *
 * @param {string} path Path of the specified file
 * @param {string} document to hydrate
 * @param {function} cb Callback, first parameter, is the error if any, then the processed data
 */
module.exports = function(path, document, cb) {

  async.waterfall([

    function(cb) {
      var outFile = crypto.randomBytes(20).toString('hex');

      var options = [
        '--printing 0', // Disable printing optimization, only for display
        '-l 7', // Generate 7 pages at most
        ' --data-dir ' + __dirname + '/../config/pdf2htmlEX',
      ];
      shellExec('pdf2htmlEX ' + options.join(' ') + ' --dest-dir /tmp ' + path + ' ' + outFile + ' --hdpi ' + config.quality + ' --vdpi ' + config.quality, function(err) {
        cb(err, '/tmp/' + outFile);
      });
    },
    function(outPath, cb) {
      fs.readFile(outPath, function(err, data) {
        cb(err, outPath, data);
      });
    },
    function(outPath, data, cb) {
      document.datas.html = data.toString();
      document.document_type = "document";
      cb(null, outPath);
    },
    function(outPath, cb) {
      fs.unlink(outPath, cb);
    },
  ], function(err) {
    cb(err, document);
  });
};
<commit_msg>add timemout<commit_after>'use strict';

/**
 * @file Helper for pdf2htmlEX file processing
 * For more information about Pdf2htmlex :
 * https://github.com/coolwanglu/pdf2htmlEX.git
 */

var fs = require('fs');
var async = require('async');
var shellExec = require('child_process').exec;
var crypto = require('crypto');
var config = require('../config/configuration.js');

/**
 * Extract the content in html of the specified pdf
 *
 * @param {string} path Path of the specified file
 * @param {string} document to hydrate
 * @param {function} cb Callback, first parameter, is the error if any, then the processed data
 */
module.exports = function(path, document, cb) {

  async.waterfall([

    function(cb) {
      var outFile = crypto.randomBytes(20).toString('hex');

      var options = [
        '--printing 0', // Disable printing optimization, only for display
        '-l 7', // Generate 7 pages at most
        ' --data-dir ' + __dirname + '/../config/pdf2htmlEX',
      ];
      shellExec('pdf2htmlEX ' + options.join(' ') + ' --dest-dir /tmp ' + path + ' ' + outFile + ' --hdpi ' + config.quality + ' --vdpi ' + config.quality, {timeout: 300000}, function(err) {
        cb(err, '/tmp/' + outFile);
      });
    },
    function(outPath, cb) {
      fs.readFile(outPath, function(err, data) {
        cb(err, outPath, data);
      });
    },
    function(outPath, data, cb) {
      document.datas.html = data.toString();
      document.document_type = "document";
      cb(null, outPath);
    },
    function(outPath, cb) {
      fs.unlink(outPath, cb);
    },
  ], function(err) {
    cb(err, document);
  });
};
<|endoftext|>


<commit_before>var possibleTriads  = require('./triads')
  , combi           = require('./combinatorics');

module.exports = exports = function infer(notes, enharmonics) {
  var triads, chords = [];

  if (enharmonics) {
    notes = notes.map(function(note) {
      return [note].concat(note.enharmonics());
    });

    // Flatten it
    notes = [].concat.apply([], notes);

    chords = combi.k_combinations(notes, 4).map(function(notecombi) {
      return infer(notecombi);
    });

    return [].concat.apply([], chords);
  }

  triads = possibleTriads(notes);
  triads.forEach(function(triad) {
    var indexes = triad.notes.map(function(n) { return n.toString() });
    var chromas = triad.notes.map(function(n) { return n.chroma() });
    var root = triad.notes[0], extensions = [];

    var exts = notes.filter(function(note) {
      return indexes.indexOf(note.toString()) === -1;
    });

    for (var i = 0, length = exts.length; i < length; i++) {
      var ext = exts[i];
      var interval = root.interval(ext);
      if (chromas.indexOf(ext.chroma()) !== -1 ||
          Math.abs(interval.qualityValue()) > 2) return;

      interval = interval.direction() === 'down' ?  interval.invert() : interval;
      var q = interval.quality();
      var num = interval.number();

      if (num === 2 || num === 4)
        interval.coord[0]++;
      else if (num === 3 && triad.type.indexOf('sus') !== -1)
        return; // No thirds in sus chords
      else if (q === 'A' && num !== 2 && num !== 4)
        return;
      else if (q === 'd' && num !== 4 && num !== 7)
        return;
      else if (q === 'dd' || q === 'AA')
        return;

      extensions.push(interval);
    }

    // Sort descending
    extensions.sort(function(a, b) { return b.number() - a.number(); });

    chords.push({
      root: root.name().toUpperCase() + root.accidental(),
      type: triad.type,
      exts: extensions
    });
  });

  return chords;
}
<commit_msg>Only dim chords can have diminished sevenths<commit_after>var possibleTriads  = require('./triads')
  , combi           = require('./combinatorics');

module.exports = exports = function infer(notes, enharmonics) {
  var triads, chords = [];

  if (enharmonics) {
    notes = notes.map(function(note) {
      return [note].concat(note.enharmonics());
    });

    // Flatten it
    notes = [].concat.apply([], notes);

    chords = combi.k_combinations(notes, 4).map(function(notecombi) {
      return infer(notecombi);
    });

    return [].concat.apply([], chords);
  }

  triads = possibleTriads(notes);
  triads.forEach(function(triad) {
    var indexes = triad.notes.map(function(n) { return n.toString() });
    var chromas = triad.notes.map(function(n) { return n.chroma() });
    var root = triad.notes[0], extensions = [];

    var exts = notes.filter(function(note) {
      return indexes.indexOf(note.toString()) === -1;
    });

    for (var i = 0, length = exts.length; i < length; i++) {
      var ext = exts[i];
      var interval = root.interval(ext);
      if (chromas.indexOf(ext.chroma()) !== -1 ||
          Math.abs(interval.qualityValue()) > 2) return;

      interval = interval.direction() === 'down' ?  interval.invert() : interval;
      var q = interval.quality();
      var num = interval.number();

      if (num === 2 || num === 4)
        interval.coord[0]++;
      else if (num === 3 && triad.type.indexOf('sus') !== -1)
        return; // No thirds in sus chords
      else if (q === 'A' && num !== 2 && num !== 4)
        return;
      else if (q === 'd' && num !== 4 && !(num === 7 && triad.type === 'dim'))
        return;
      else if (q === 'dd' || q === 'AA')
        return;

      extensions.push(interval);
    }

    // Sort descending
    extensions.sort(function(a, b) { return b.number() - a.number(); });

    chords.push({
      root: root.name().toUpperCase() + root.accidental(),
      type: triad.type,
      exts: extensions
    });
  });

  return chords;
}
<|endoftext|>


<commit_before>"use strict";

var Keyboard = require("game-keyboard");
var keyMap = require("game-keyboard/key_map").US;
var keyboard = new Keyboard(keyMap);
var Mouse = require("./mouse");

function Input(config, canvas) {
	this.config = config;
	this.mouse = new Mouse(canvas);
	this.lastButtonState = {};
	this.delayedButtonUpdates = {};
}
Input.prototype.button = function(name) {
	var input = this.config.buttons[name];
	if (input === undefined) {
		console.error("No such button: " + name);
		return false;
	}
	for (var i = 0; i < input.length; i++) {
		var physicalInput = input[i];
		var device = physicalInput.device;
		if (device === "keyboard") {
			var key = physicalInput.key;
			if (keyboard.isPressed(key)) {
				return true;
			}
		}
		if (device === "mouse") {
			var button = physicalInput.button;
			if (this.mouse.isPressed(button)) {
				return true;
			}
		}
		if (device === "mouse") {
			var button = physicalInput.button;
			if (this.mouse.isPressed(button)) {
				return true;
			}
		}
		if (device === "touch") {
			for (var j = 0; j < this.mouse.touches.length; j++) {
				var t = this.mouse.touches[j];
				if (t.x >= physicalInput.x && t.x < physicalInput.x + physicalInput.width && t.y >= physicalInput.y && t.y < physicalInput.y + physicalInput.height) {
					return true;
				}
			}
		}
	}
	return false;
};
Input.prototype.buttonPressed = function(name) {
	var current = this.button(name);
	var last = this.lastButtonState[name];
	if (last === undefined) {
		last = true;
	}
	this.delayedButtonUpdates[name] = current;
	return current && !last;
};
Input.prototype.buttonReleased = function(name) {
	var current = this.button(name);
	var last = this.lastButtonState[name];
	if (last === undefined) {
		last = false;
	}
	this.delayedButtonUpdates[name] = current;
	return !current && last;
};
Input.prototype.processUpdates = function() {
	Object.keys(this.delayedButtonUpdates).forEach(function(name) {
		this.lastButtonState[name] = this.delayedButtonUpdates[name];
		delete this.delayedButtonUpdates[name];
	}.bind(this));
};

module.exports = Input;
<commit_msg>Add Input.axis()<commit_after>"use strict";

var Keyboard = require("game-keyboard");
var keyMap = require("game-keyboard/key_map").US;
var keyboard = new Keyboard(keyMap);
var Mouse = require("./mouse");

function Input(config, canvas) {
	this.config = config;
	this.mouse = new Mouse(canvas);
	this.lastButtonState = {};
	this.delayedButtonUpdates = {};
}
Input.prototype.axis = function(name) {
	var input = this.config.axes[name];
	if (input === undefined) {
		console.error("No such axis: " + name);
		return false;
	}
	for (var i = 0; i < input.length; i++) {
		var physicalInput = input[i];
		var device = physicalInput.device;
		if (device === "mouse") {
			if (physicalInput.axis === "x") {
				return this.mouse.x;
			}
			if (physicalInput.axis === "y") {
				return this.mouse.y;
			}
		}
	}
};
Input.prototype.button = function(name) {
	var input = this.config.buttons[name];
	if (input === undefined) {
		console.error("No such button: " + name);
		return false;
	}
	for (var i = 0; i < input.length; i++) {
		var physicalInput = input[i];
		var device = physicalInput.device;
		if (device === "keyboard") {
			var key = physicalInput.key;
			if (keyboard.isPressed(key)) {
				return true;
			}
		}
		if (device === "mouse") {
			var button = physicalInput.button;
			if (this.mouse.isPressed(button)) {
				return true;
			}
		}
		if (device === "mouse") {
			var button = physicalInput.button;
			if (this.mouse.isPressed(button)) {
				return true;
			}
		}
		if (device === "touch") {
			for (var j = 0; j < this.mouse.touches.length; j++) {
				var t = this.mouse.touches[j];
				if (t.x >= physicalInput.x && t.x < physicalInput.x + physicalInput.width && t.y >= physicalInput.y && t.y < physicalInput.y + physicalInput.height) {
					return true;
				}
			}
		}
	}
	return false;
};
Input.prototype.buttonPressed = function(name) {
	var current = this.button(name);
	var last = this.lastButtonState[name];
	if (last === undefined) {
		last = true;
	}
	this.delayedButtonUpdates[name] = current;
	return current && !last;
};
Input.prototype.buttonReleased = function(name) {
	var current = this.button(name);
	var last = this.lastButtonState[name];
	if (last === undefined) {
		last = false;
	}
	this.delayedButtonUpdates[name] = current;
	return !current && last;
};
Input.prototype.processUpdates = function() {
	Object.keys(this.delayedButtonUpdates).forEach(function(name) {
		this.lastButtonState[name] = this.delayedButtonUpdates[name];
		delete this.delayedButtonUpdates[name];
	}.bind(this));
};

module.exports = Input;
<|endoftext|>


<commit_before>const React = require('react-native');

const {
  Dimensions,
  StyleSheet,
  Component,
  View,
  ScrollView,
  TouchableWithoutFeedback,
  Text
} = React;

const window = Dimensions.get('window');

const styles = StyleSheet.create({
  scrollView: {
    height: 120,
    width: 198 //TODO: this needs to be dynamic
  },
  container: {
    position: 'absolute',
    borderColor: '#BDBDC1',
    borderWidth: 2 / window.scale,
    borderTopColor: 'transparent',
  }
})

class Items extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    const { items, positionX, positionY, show, onPress, width, height } = this.props;

    if (!show) {
      return null;
    }

    const renderedItems = React.Children.map(items, (item) => {

      return (
        <TouchableWithoutFeedback onPress={() => onPress(item.props.children, item.props.value) }>
          {item}
        </TouchableWithoutFeedback>
      );
    });

    return (
      <View style={[styles.container, { top: positionY, left: positionX }]}>
        <ScrollView
          style={{ width: width - 2, height: height * 3 }}
          automaticallyAdjustContentInsets={false}
          bounces={false}>
          {renderedItems}
        </ScrollView>
      </View>
    );
  }
}

Items.propTypes = {
  positionX: React.PropTypes.number,
  positionY: React.PropTypes.number,
  show: React.PropTypes.bool,
  onPress: React.PropTypes.func
};

Items.defaultProps = {
  width: 0,
  height: 0,
  positionX: 0,
  positionY: 0,
  show: false,
  onPress: () => {}
};

module.exports = Items;
<commit_msg>Add containing view<commit_after>const React = require('react-native');

const {
  Dimensions,
  StyleSheet,
  Component,
  View,
  ScrollView,
  TouchableWithoutFeedback,
  Text
} = React;

const window = Dimensions.get('window');

const styles = StyleSheet.create({
  scrollView: {
    height: 120,
    width: 198 //TODO: this needs to be dynamic
  },
  container: {
    position: 'absolute',
    borderColor: '#BDBDC1',
    borderWidth: 2 / window.scale,
    borderTopColor: 'transparent',
  }
})

class Items extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    const { items, positionX, positionY, show, onPress, width, height } = this.props;

    if (!show) {
      return null;
    }

    const renderedItems = React.Children.map(items, (item) => {

      return (
        <TouchableWithoutFeedback onPress={() => onPress(item.props.children, item.props.value) }>
          <View>
            {item}
          </View>
        </TouchableWithoutFeedback>
      );
    });

    return (
      <View style={[styles.container, { top: positionY, left: positionX }]}>
        <ScrollView
          style={{ width: width - 2, height: height * 3 }}
          automaticallyAdjustContentInsets={false}
          bounces={false}>
          {renderedItems}
        </ScrollView>
      </View>
    );
  }
}

Items.propTypes = {
  positionX: React.PropTypes.number,
  positionY: React.PropTypes.number,
  show: React.PropTypes.bool,
  onPress: React.PropTypes.func
};

Items.defaultProps = {
  width: 0,
  height: 0,
  positionX: 0,
  positionY: 0,
  show: false,
  onPress: () => {}
};

module.exports = Items;
<|endoftext|>


<commit_before>/*
 * jitsu.js: Top-level include for the jitsu module.
 *
 * (C) 2010, Nodejitsu Inc.
 *
 */

var path = require('path'),
    util = require('util'),
    colors = require('colors'),
    flatiron = require('flatiron');

var jitsu = module.exports = flatiron.app;

//
// Setup `jitsu` to use `pkginfo` to expose version
//
require('pkginfo')(module, 'name', 'version');

//
// Configure jitsu to use `flatiron.plugins.cli`
//
jitsu.use(flatiron.plugins.cli, {
  version: true,
  usage: require('./jitsu/usage'),
  source: path.join(__dirname, 'jitsu', 'commands'),
  argv: {
    version: {
      alias: 'v',
      description: 'print jitsu version and exit',
      string: true
    },
    localconf: {
      description: 'search for .jitsuconf file in ./ and then parent directories',
      string: true
    },
    jitsuconf: {
      alias: 'j',
      description: 'specify file to load configuration from',
      string: true
    },
    noanalyze: {
      description: 'skip require-analyzer: do not attempt to dynamically detect dependencies',
      boolean: true
    },
    colors: {
      description: '--no-colors will disable output coloring',
      default: true,
      boolean: true
    },
    confirm: {
      alias: 'c',
      description: 'prevents jitsu from asking before overwriting/removing things',
      default: false,
      boolean: true
    },
    release: {
      alias: 'r',
      description: 'specify release version number or semantic increment (build, patch, minor, major)',
      string: true
    },
    raw: {
      description: 'jitsu will only output line-delimited raw JSON (useful for piping)',
      boolean: true
    }
  }
});

jitsu.options.log = {
  console: {
    raw: jitsu.argv.raw
  }
};

//
// Setup config, users, command aliases and prompt settings
//
jitsu.prompt.properties = flatiron.common.mixin(
  jitsu.prompt.properties,
  require('./jitsu/properties')
);
jitsu.prompt.override   = jitsu.argv;
require('./jitsu/config');
require('./jitsu/alias');
require('./jitsu/commands');

//
// Setup other jitsu settings.
//
jitsu.started  = false;
jitsu.common   = require('./jitsu/common');
jitsu.package  = require('./jitsu/package');
jitsu.logFile  = new (require('./jitsu/common/logfile').LogFile)(path.join(process.env.HOME, '.jitsulog'));

//
// Hoist `jitsu.api` from `nodejitsu-api` module.
//
jitsu.api               = {};
jitsu.api.Client        = require('nodejitsu-api').Client;
jitsu.api.Apps          = require('nodejitsu-api').Apps;
jitsu.api.Databases     = require('nodejitsu-api').Databases;
jitsu.api.Logs          = require('nodejitsu-api').Logs;
jitsu.api.Snapshots     = require('nodejitsu-api').Snapshots;
jitsu.api.Users         = require('nodejitsu-api').Users;
jitsu.api.Tokens        = require('nodejitsu-api').Tokens;

//
// ### function welcome ()
// Print welcome message.
//
jitsu.welcome = function () {
  //
  // If a user is logged in, show username
  //
  var username = jitsu.config.get('username') || '';
  jitsu.log.info('Welcome to ' + 'Nodejitsu'.grey + ' ' + username.magenta);
  jitsu.log.info('jitsu v' + jitsu.version + ', node ' + process.version);
  jitsu.log.info('It worked if it ends with ' + 'Nodejitsu'.grey + ' ok'.green.bold);
};

//
// ### function start (command, callback)
// #### @command {string} Command to execute once started
// #### @callback {function} Continuation to pass control to when complete.
// Starts the jitsu CLI and runs the specified command.
//
jitsu.start = function (callback) {
  //
  // Check for --no-colors/--colors option, without hitting the config file
  // yet
  //
  var useColors = (typeof jitsu.argv.colors == 'undefined' || jitsu.argv.colors);

  useColors || (colors.mode = "none");

  //
  // whoami command should not output anything but username
  //
  if (jitsu.argv._[0] === "whoami") {
    console.log(jitsu.config.get('username') || '');
    return;
  }

  jitsu.init(function (err) {
    if (err) {
      jitsu.welcome();
      jitsu.showError(jitsu.argv._.join(' '), err);
      return callback(err);
    }

    jitsu.common.checkVersion(function (err) {
      if (err) {
        return callback();
      }

      var minor, username;

      //
      // --no-colors option turns off output coloring, and so does setting
      // colors: false in ~/.jitsuconf (see
      // https://github.com/nodejitsu/jitsu/issues/101 )
      //
      if ( !jitsu.config.get('colors') || !useColors ) {
        colors.mode = "none";
        jitsu.log.get('default').stripColors = true;
        jitsu.log.get('default').transports.console.colorize = false;
      }

      jitsu.welcome();

      minor = process.version.split('.')[1];

      if (parseInt(minor, 10) % 2) {
        jitsu.log.warn('You are using unstable version of node.js. You may experience problems.');
      }

      username = jitsu.config.get('username');
      if (!username && jitsu.config.get('requiresAuth').indexOf(jitsu.argv._[0]) !== -1) {
        return jitsu.commands.users.login(function (err) {
          if (err) {
            jitsu.showError(jitsu.argv._.join(' '), err);
            return callback(err);
          }

          var username = jitsu.config.get('username');
          jitsu.log.info('Successfully configured user ' + username.magenta);
          return jitsu.exec(jitsu.argv._, callback);
        });
      }
      return jitsu.exec(jitsu.argv._, callback);
    });
  });
};

//
// ### function exec (command, callback)
// #### @command {string} Command to execute
// #### @callback {function} Continuation to pass control to when complete.
// Runs the specified command in the jitsu CLI.
//
jitsu.exec = function (command, callback) {
  function execCommand (err) {
    if (err) {
      return callback(err);
    }

    //
    // Remark: This is a temporary fix for aliasing init=>install,
    // was having a few issues with the alias command on the install resource
    //
    if (command[0] === 'init') {
      command[0] = 'install';
    }

    // Alias db to databases
    if (command[0] === 'db' || command[0] === 'dbs' || command[0] === 'database') {
      command[0] = 'databases';
    }

    // Allow `jitsu logs` as a shortcut for `jitsu logs app`
    if (command[0] === 'logs' && command.length === 1) {
      command[1] = 'app';
    }

    // Allow `jitsu host` as a shortcut for `jitsu config set remoteHost`
    if (command[0] === 'host' && command.length === 2) {
      command[3] = command[1];
      command[0] = 'config';
      command[1] = 'set';
      command[2] = 'remoteHost';
    }

    jitsu.log.info('Executing command ' + command.join(' ').magenta);
    jitsu.router.dispatch('on', command.join(' '), jitsu.log, function (err, shallow) {
      if (err) {
        jitsu.showError(command.join(' '), err, shallow);
        return callback(err);
      }

      //
      // TODO (indexzero): Something here
      //
      callback();
    });
  }

  return !jitsu.started ? jitsu.setup(execCommand) : execCommand();
};

//
// ### function setup (callback)
// #### @callback {function} Continuation to pass control to when complete.
// Sets up the instances of the Resource clients for jitsu.
// there is no io here, yet this function is ASYNC.
//
jitsu.setup = function (callback) {
  if (jitsu.started === true) {
    return callback();
  }

  var rejectUnauthorized = jitsu.config.get('rejectUnauthorized');
  if (typeof rejectUnauthorized === 'undefined') {
    jitsu.config.set('rejectUnauthorized', false);
  }

  var userAgent = jitsu.config.get('headers:user-agent');
  if (!userAgent) {
    jitsu.config.set('headers:user-agent', 'jitsu/' + jitsu.version);
  }

  ['Users', 'Apps', 'Snapshots', 'Databases', 'Logs', 'Tokens'].forEach(function (key) {
    var k = key.toLowerCase();
    jitsu[k] = new jitsu.api[key](jitsu.config);
    jitsu[k].on('debug::request',  debug);
    jitsu[k].on('debug::response', debug);
    function debug (data) {
      if (jitsu.argv.debug || jitsu.config.get('debug')) {
        if (data.headers && data.headers['Authorization']) {
          data = JSON.parse(JSON.stringify(data));
          data.headers['Authorization'] = Array(data.headers['Authorization'].length).join('*');
        }

        util.inspect(data, false, null, true).split('\n').forEach(jitsu.log.debug);
      }
    };
  });

  jitsu.started = true;
  callback();
};

//
// ### function showError (command, err, shallow, skip)
// #### @command {string} Command which has errored.
// #### @err {Error} Error received for the command.
// #### @shallow {boolean} Value indicating if a deep stack should be displayed
// #### @skip {boolean} Value indicating if this error should be forcibly suppressed.
// Displays the `err` to the user for the `command` supplied.
//
jitsu.showError = function (command, err, shallow, skip) {
  var username,
      display,
      errors,
      stack;

  //
  // ### function unknownError(message, stack)
  // Displays an unknown error by dumping the call `stack`
  // and a given `message`.
  //
  function unknownError(message, stack) {
    jitsu.log.error(message);
    stack.split('\n').forEach(function (line) {
      jitsu.log.error(line);
    })
  }

  //
  // ### function solenoidError(display)
  // Displays a "solenoid" error.
  //
  function solenoidError(display) {
    jitsu.log.error('Error starting application. This could be a user error.');
    display.solenoid.split('\n').forEach(function (line) {
      jitsu.log.error(line);
    });
  }

  //
  // ### function appError(display)
  // Displays an "application" error.
  //
  function appError(display) {
    if (display.output) {
      jitsu.log.error('Error output from application. This is usually a user error.');
      display.output.split('\n').forEach(function (line) {
        jitsu.log.error(line);
      })
    }

    return !display.solenoid
      ? unknownError(display.message, display.stack)
      : solenoidError(display);
  }

  if (err.statusCode === 403) {
    //jitsu.log.error('403 ' + err.result.error);
  }
  else if (err.statusCode === 503) {
    if (err.result && err.result.message) {
      jitsu.log.error(err.result.message);
    }
    else {
      jitsu.log.error('The Nodejitsu cloud is currently at capacity.  Please try again later.');
    }
  }
  else if (!skip) {
    jitsu.log.error('Error running command ' + command.magenta);
    if (!jitsu.config.get('nolog')) {
      jitsu.logFile.log(err);
    }

    if (err.result) {
      if (err.result.message) {
        jitsu.log.error(err.result.message);
      }

      if (err.result.error && typeof err.result.error == 'string') {
        if (~err.result.error.indexOf('matching versions')) {
          jitsu.log.error(err.result.error);
          jitsu.log.error("Do not use a specific engine version, try a generic one (eg: 0.8.x or 0.10.x)");
        }
        else if (~err.result.error.indexOf('npm exited')) {
          jitsu.log.error(err.result.error);
        } else {
          jitsu.log.error(err.result.error);
        }
      }

      if (err.result.errors && Array.isArray(err.result.errors)) {
        errors = {
          connection: err.result.errors.filter(function (err) {
            return err.blame === 'connection';
          }),
          application: err.result.errors.filter(function (err) {
            return err.blame === 'application';
          }),
          solenoid: err.result.errors.filter(function (err) {
            return err.blame === 'solenoid';
          })
        };

        if (errors.application.length) {
          return appError(errors.application[0]);
        }
        else if (errors.solenoid.length) {
          return solenoidError(errors.solenoid[0])
        }

        return errors.connection.length
          ? unknownError('Error contacting drone(s):', errors.connection[0].stack)
          : unknownError('Error returned from Nodejitsu:', err.result.errors[0].stack);
      }
      else if (err.result.stack) {
        return unknownError('Error returned from Nodejitsu:', err.result.stack);
      }
    }
    else {
      if (err.stack && !shallow) {
        if (err.message && err.message === 'socket hang up' && err.code && err.code === 'ECONNRESET') {
          jitsu.log.info('The nodejitsu api reset the connection');
          jitsu.log.help('This error may be due to the application or the drone server');
        } else if (err.message && err.message === 'ETIMEDOUT'){
          jitsu.log.info(
            'jitsu\'s client request timed out before the server ' +
            'could respond. Please increase your client timeout');
          jitsu.log.help('(Example: `jitsu config set timeout 480000`)');
          jitsu.log.help('This error may be due to network connection problems');
        } else {
          err.stack.split('\n').forEach(function (trace) {
            jitsu.log.error(trace);
          });
        }

        return;
      }
    }

    if (err.message) {
      jitsu.log.error(err.message);
    }
  }

  jitsu.log.help("For help with this error contact Nodejitsu Support:");
  jitsu.log.help("  webchat: <http://webchat.nodejitsu.com/>");
  jitsu.log.help("      irc: <irc://chat.freenode.net/#nodejitsu>");
  jitsu.log.help("    email: <support@nodejitsu.com>");
  jitsu.log.help("");
  jitsu.log.help("  Copy and paste this output to a gist (http://gist.github.com/)");
  jitsu.log.info('Nodejitsu '.grey + 'not ok'.red.bold);
};
<commit_msg>[fix] Remove unnecessary else if<commit_after>/*
 * jitsu.js: Top-level include for the jitsu module.
 *
 * (C) 2010, Nodejitsu Inc.
 *
 */

var path = require('path'),
    util = require('util'),
    colors = require('colors'),
    flatiron = require('flatiron');

var jitsu = module.exports = flatiron.app;

//
// Setup `jitsu` to use `pkginfo` to expose version
//
require('pkginfo')(module, 'name', 'version');

//
// Configure jitsu to use `flatiron.plugins.cli`
//
jitsu.use(flatiron.plugins.cli, {
  version: true,
  usage: require('./jitsu/usage'),
  source: path.join(__dirname, 'jitsu', 'commands'),
  argv: {
    version: {
      alias: 'v',
      description: 'print jitsu version and exit',
      string: true
    },
    localconf: {
      description: 'search for .jitsuconf file in ./ and then parent directories',
      string: true
    },
    jitsuconf: {
      alias: 'j',
      description: 'specify file to load configuration from',
      string: true
    },
    noanalyze: {
      description: 'skip require-analyzer: do not attempt to dynamically detect dependencies',
      boolean: true
    },
    colors: {
      description: '--no-colors will disable output coloring',
      default: true,
      boolean: true
    },
    confirm: {
      alias: 'c',
      description: 'prevents jitsu from asking before overwriting/removing things',
      default: false,
      boolean: true
    },
    release: {
      alias: 'r',
      description: 'specify release version number or semantic increment (build, patch, minor, major)',
      string: true
    },
    raw: {
      description: 'jitsu will only output line-delimited raw JSON (useful for piping)',
      boolean: true
    }
  }
});

jitsu.options.log = {
  console: {
    raw: jitsu.argv.raw
  }
};

//
// Setup config, users, command aliases and prompt settings
//
jitsu.prompt.properties = flatiron.common.mixin(
  jitsu.prompt.properties,
  require('./jitsu/properties')
);
jitsu.prompt.override   = jitsu.argv;
require('./jitsu/config');
require('./jitsu/alias');
require('./jitsu/commands');

//
// Setup other jitsu settings.
//
jitsu.started  = false;
jitsu.common   = require('./jitsu/common');
jitsu.package  = require('./jitsu/package');
jitsu.logFile  = new (require('./jitsu/common/logfile').LogFile)(path.join(process.env.HOME, '.jitsulog'));

//
// Hoist `jitsu.api` from `nodejitsu-api` module.
//
jitsu.api               = {};
jitsu.api.Client        = require('nodejitsu-api').Client;
jitsu.api.Apps          = require('nodejitsu-api').Apps;
jitsu.api.Databases     = require('nodejitsu-api').Databases;
jitsu.api.Logs          = require('nodejitsu-api').Logs;
jitsu.api.Snapshots     = require('nodejitsu-api').Snapshots;
jitsu.api.Users         = require('nodejitsu-api').Users;
jitsu.api.Tokens        = require('nodejitsu-api').Tokens;

//
// ### function welcome ()
// Print welcome message.
//
jitsu.welcome = function () {
  //
  // If a user is logged in, show username
  //
  var username = jitsu.config.get('username') || '';
  jitsu.log.info('Welcome to ' + 'Nodejitsu'.grey + ' ' + username.magenta);
  jitsu.log.info('jitsu v' + jitsu.version + ', node ' + process.version);
  jitsu.log.info('It worked if it ends with ' + 'Nodejitsu'.grey + ' ok'.green.bold);
};

//
// ### function start (command, callback)
// #### @command {string} Command to execute once started
// #### @callback {function} Continuation to pass control to when complete.
// Starts the jitsu CLI and runs the specified command.
//
jitsu.start = function (callback) {
  //
  // Check for --no-colors/--colors option, without hitting the config file
  // yet
  //
  var useColors = (typeof jitsu.argv.colors == 'undefined' || jitsu.argv.colors);

  useColors || (colors.mode = "none");

  //
  // whoami command should not output anything but username
  //
  if (jitsu.argv._[0] === "whoami") {
    console.log(jitsu.config.get('username') || '');
    return;
  }

  jitsu.init(function (err) {
    if (err) {
      jitsu.welcome();
      jitsu.showError(jitsu.argv._.join(' '), err);
      return callback(err);
    }

    jitsu.common.checkVersion(function (err) {
      if (err) {
        return callback();
      }

      var minor, username;

      //
      // --no-colors option turns off output coloring, and so does setting
      // colors: false in ~/.jitsuconf (see
      // https://github.com/nodejitsu/jitsu/issues/101 )
      //
      if ( !jitsu.config.get('colors') || !useColors ) {
        colors.mode = "none";
        jitsu.log.get('default').stripColors = true;
        jitsu.log.get('default').transports.console.colorize = false;
      }

      jitsu.welcome();

      minor = process.version.split('.')[1];

      if (parseInt(minor, 10) % 2) {
        jitsu.log.warn('You are using unstable version of node.js. You may experience problems.');
      }

      username = jitsu.config.get('username');
      if (!username && jitsu.config.get('requiresAuth').indexOf(jitsu.argv._[0]) !== -1) {
        return jitsu.commands.users.login(function (err) {
          if (err) {
            jitsu.showError(jitsu.argv._.join(' '), err);
            return callback(err);
          }

          var username = jitsu.config.get('username');
          jitsu.log.info('Successfully configured user ' + username.magenta);
          return jitsu.exec(jitsu.argv._, callback);
        });
      }
      return jitsu.exec(jitsu.argv._, callback);
    });
  });
};

//
// ### function exec (command, callback)
// #### @command {string} Command to execute
// #### @callback {function} Continuation to pass control to when complete.
// Runs the specified command in the jitsu CLI.
//
jitsu.exec = function (command, callback) {
  function execCommand (err) {
    if (err) {
      return callback(err);
    }

    //
    // Remark: This is a temporary fix for aliasing init=>install,
    // was having a few issues with the alias command on the install resource
    //
    if (command[0] === 'init') {
      command[0] = 'install';
    }

    // Alias db to databases
    if (command[0] === 'db' || command[0] === 'dbs' || command[0] === 'database') {
      command[0] = 'databases';
    }

    // Allow `jitsu logs` as a shortcut for `jitsu logs app`
    if (command[0] === 'logs' && command.length === 1) {
      command[1] = 'app';
    }

    // Allow `jitsu host` as a shortcut for `jitsu config set remoteHost`
    if (command[0] === 'host' && command.length === 2) {
      command[3] = command[1];
      command[0] = 'config';
      command[1] = 'set';
      command[2] = 'remoteHost';
    }

    jitsu.log.info('Executing command ' + command.join(' ').magenta);
    jitsu.router.dispatch('on', command.join(' '), jitsu.log, function (err, shallow) {
      if (err) {
        jitsu.showError(command.join(' '), err, shallow);
        return callback(err);
      }

      //
      // TODO (indexzero): Something here
      //
      callback();
    });
  }

  return !jitsu.started ? jitsu.setup(execCommand) : execCommand();
};

//
// ### function setup (callback)
// #### @callback {function} Continuation to pass control to when complete.
// Sets up the instances of the Resource clients for jitsu.
// there is no io here, yet this function is ASYNC.
//
jitsu.setup = function (callback) {
  if (jitsu.started === true) {
    return callback();
  }

  var rejectUnauthorized = jitsu.config.get('rejectUnauthorized');
  if (typeof rejectUnauthorized === 'undefined') {
    jitsu.config.set('rejectUnauthorized', false);
  }

  var userAgent = jitsu.config.get('headers:user-agent');
  if (!userAgent) {
    jitsu.config.set('headers:user-agent', 'jitsu/' + jitsu.version);
  }

  ['Users', 'Apps', 'Snapshots', 'Databases', 'Logs', 'Tokens'].forEach(function (key) {
    var k = key.toLowerCase();
    jitsu[k] = new jitsu.api[key](jitsu.config);
    jitsu[k].on('debug::request',  debug);
    jitsu[k].on('debug::response', debug);
    function debug (data) {
      if (jitsu.argv.debug || jitsu.config.get('debug')) {
        if (data.headers && data.headers['Authorization']) {
          data = JSON.parse(JSON.stringify(data));
          data.headers['Authorization'] = Array(data.headers['Authorization'].length).join('*');
        }

        util.inspect(data, false, null, true).split('\n').forEach(jitsu.log.debug);
      }
    };
  });

  jitsu.started = true;
  callback();
};

//
// ### function showError (command, err, shallow, skip)
// #### @command {string} Command which has errored.
// #### @err {Error} Error received for the command.
// #### @shallow {boolean} Value indicating if a deep stack should be displayed
// #### @skip {boolean} Value indicating if this error should be forcibly suppressed.
// Displays the `err` to the user for the `command` supplied.
//
jitsu.showError = function (command, err, shallow, skip) {
  var username,
      display,
      errors,
      stack;

  //
  // ### function unknownError(message, stack)
  // Displays an unknown error by dumping the call `stack`
  // and a given `message`.
  //
  function unknownError(message, stack) {
    jitsu.log.error(message);
    stack.split('\n').forEach(function (line) {
      jitsu.log.error(line);
    })
  }

  //
  // ### function solenoidError(display)
  // Displays a "solenoid" error.
  //
  function solenoidError(display) {
    jitsu.log.error('Error starting application. This could be a user error.');
    display.solenoid.split('\n').forEach(function (line) {
      jitsu.log.error(line);
    });
  }

  //
  // ### function appError(display)
  // Displays an "application" error.
  //
  function appError(display) {
    if (display.output) {
      jitsu.log.error('Error output from application. This is usually a user error.');
      display.output.split('\n').forEach(function (line) {
        jitsu.log.error(line);
      })
    }

    return !display.solenoid
      ? unknownError(display.message, display.stack)
      : solenoidError(display);
  }

  if (err.statusCode === 403) {
    //jitsu.log.error('403 ' + err.result.error);
  }
  else if (err.statusCode === 503) {
    if (err.result && err.result.message) {
      jitsu.log.error(err.result.message);
    }
    else {
      jitsu.log.error('The Nodejitsu cloud is currently at capacity.  Please try again later.');
    }
  }
  else if (!skip) {
    jitsu.log.error('Error running command ' + command.magenta);
    if (!jitsu.config.get('nolog')) {
      jitsu.logFile.log(err);
    }

    if (err.result) {
      if (err.result.message) {
        jitsu.log.error(err.result.message);
      }

      if (err.result.error && typeof err.result.error == 'string') {
        if (~err.result.error.indexOf('matching versions')) {
          jitsu.log.error(err.result.error);
          jitsu.log.error("Do not use a specific engine version, try a generic one (eg: 0.8.x or 0.10.x)");
        } else {
          jitsu.log.error(err.result.error);
        }
      }

      if (err.result.errors && Array.isArray(err.result.errors)) {
        errors = {
          connection: err.result.errors.filter(function (err) {
            return err.blame === 'connection';
          }),
          application: err.result.errors.filter(function (err) {
            return err.blame === 'application';
          }),
          solenoid: err.result.errors.filter(function (err) {
            return err.blame === 'solenoid';
          })
        };

        if (errors.application.length) {
          return appError(errors.application[0]);
        }
        else if (errors.solenoid.length) {
          return solenoidError(errors.solenoid[0])
        }

        return errors.connection.length
          ? unknownError('Error contacting drone(s):', errors.connection[0].stack)
          : unknownError('Error returned from Nodejitsu:', err.result.errors[0].stack);
      }
      else if (err.result.stack) {
        return unknownError('Error returned from Nodejitsu:', err.result.stack);
      }
    }
    else {
      if (err.stack && !shallow) {
        if (err.message && err.message === 'socket hang up' && err.code && err.code === 'ECONNRESET') {
          jitsu.log.info('The nodejitsu api reset the connection');
          jitsu.log.help('This error may be due to the application or the drone server');
        } else if (err.message && err.message === 'ETIMEDOUT'){
          jitsu.log.info(
            'jitsu\'s client request timed out before the server ' +
            'could respond. Please increase your client timeout');
          jitsu.log.help('(Example: `jitsu config set timeout 480000`)');
          jitsu.log.help('This error may be due to network connection problems');
        } else {
          err.stack.split('\n').forEach(function (trace) {
            jitsu.log.error(trace);
          });
        }

        return;
      }
    }

    if (err.message) {
      jitsu.log.error(err.message);
    }
  }

  jitsu.log.help("For help with this error contact Nodejitsu Support:");
  jitsu.log.help("  webchat: <http://webchat.nodejitsu.com/>");
  jitsu.log.help("      irc: <irc://chat.freenode.net/#nodejitsu>");
  jitsu.log.help("    email: <support@nodejitsu.com>");
  jitsu.log.help("");
  jitsu.log.help("  Copy and paste this output to a gist (http://gist.github.com/)");
  jitsu.log.info('Nodejitsu '.grey + 'not ok'.red.bold);
};
<|endoftext|>


<commit_before>var Tags = require('./tags'),
    parser = require('./parser'),
    inherit = require('inherit');
/**
 * API
 * @param {Array} plugins
 * @returns {Function}
 */
module.exports = function(plugins) {
    var jsdoc = new JSDoc(plugins);
    return function(str) {
        return jsdoc.parse(str);
    };
};

var JSDoc = inherit({
    __constructor : function(plugins) {
        this._tagParsers = {};
        this._tagBuilders = [];
        this._postprocessors = {};

        plugins.forEach(this._registerPlugin, this);
    },

    _registerPlugin : function(plugin) {
        (typeof plugin === 'string'? require(plugin) : plugin)(this);
        return this;
    },

    registerParser : function(tagType, parseFn) {
        if(Array.isArray(tagType)) {
            tagType.forEach(
                function(tagType) {
                    this.registerParser(tagType, parseFn);
                },
                this);
            return this;
        }

        tagType = escapeKey(tagType);
        this._tagParsers[tagType] = parseFn === Boolean || parseFn === String?
            simpleParsers[parseFn.name] :
            parseFn;
        return this;
    },

    registerBuilder : function(tagType, builderFn) {
        if(typeof tagType === 'function') {
            builderFn = tagType;
            tagType = null;
        }
        else if(Array.isArray(tagType)) {
            tagType.forEach(
                function(tagType) {
                    this.registerBuilder(tagType, builderFn);
                },
                this);
            return this;
        }

        this._tagBuilders.push({ type : tagType, fn : builderFn });
        return this;
    },

    registerPostprocessor : function(jsdocType, postprocessorFn) {
        if(Array.isArray(jsdocType)) {
            jsdocType.forEach(
                function(jsdocType) {
                    this.registerPostprocessor(jsdocType, postprocessorFn);
                },
                this);
            return this;
        }

        if(arguments.length === 1) {
            postprocessorFn = jsdocType;
            jsdocType = '';
        }

        jsdocType = escapeKey(jsdocType);
        (this._postprocessors[jsdocType] || (this._postprocessors[jsdocType] = [])).push(postprocessorFn);
        return this;
    },

    parse : function(source) {
        var sourceTree = parser(source),
            rootJsdocNode = { jsdocType : 'root' },
            ctx = {},
            _this = this,
            errors = [];

        sourceTree.iterate(
            function(astNode, jsdocNode) {
                var accJsdocNode = jsdocNode;
                astNode.comments.forEach(function(commentAstNode) {
                    var iterationErrors = [];
                    accJsdocNode = _this._onIterate(ctx, commentAstNode, astNode, jsdocNode, iterationErrors);
                    errors = errors.concat(iterationErrors.map(function(e) {
                        return _this._buildError(e, source, commentAstNode);
                    }));
                });

                return accJsdocNode;
            },
            rootJsdocNode);

        this._postprocess(rootJsdocNode, ctx, errors);

        if(errors.length) throw Error(errors.join('\n\n\n'));

        return rootJsdocNode;
    },

    _onIterate : function(ctx, commentAstNode, astNode, jsdocNode, errors) {
        var accJsdocNode = jsdocNode,
            parentJsdocNode = jsdocNode,
            tags = new Tags(this._parseJSDocComment(commentAstNode.value, errors));

        this._tagBuilders.forEach(function(tagBuilder) {
            if(!tagBuilder.type) {
                // TODO: get rid of copy-paste
                try {
                    var res = tagBuilder.fn.call(ctx, tags, accJsdocNode, parentJsdocNode, astNode);
                    typeof res !== 'undefined' && (accJsdocNode = res);
                } catch(e) {
                    errors.push(e);
                }
                return;
            }

            tags.getTagsByType(tagBuilder.type).forEach(function(tag) {
                // TODO: get rid of copy-paste
                try {
                    var res = tagBuilder.fn.call(ctx, tag, accJsdocNode, parentJsdocNode, astNode);
                    typeof res !== 'undefined' && (accJsdocNode = res);
                } catch(e) {
                    errors.push(e);
                }
            });
        });

        return accJsdocNode;
    },

    _parseJSDocComment : function(comment, errors) {
        var tags = [],
            lines = comment.replace(/^(\s*\*)?[\s\n]*|[\s\n]*$/g, '').split('\n'),
            tag = { type : '', comment : '' };

        lines.forEach(function(line, i) {
            var matches = line.match(/^(?:\*|\s)*@(\w+)(?:\s+(.+?)\s*)?$/);
            if(matches) {
                tag.type && tags.push(this._parseTagComment(tag, errors));
                tag.type = matches[1];
                tag.comment = matches[2] || '';
            } else {
                i || (tag.type = 'description');
                tag.comment += (tag.comment? '\n' : '') + line.replace(/^\s*\*\s?|\s*$/g, '');
            }
        }, this);

        tags.push(this._parseTagComment(tag, errors));

        return tags;
    },

    _parseTagComment : function(tag, errors) {
        var parse = this._tagParsers[escapeKey(tag.type)],
            comment = tag.comment.replace(/\n*$/g, ''),
            res;

        if(parse) {
            try {
                res = parse(comment);
            } catch(e) {
                errors.push(e);
            }
        } else {
            errors.push(Error('Unsupported tag: ' + tag.type));
        }

        res || (res = { content : comment });
        res.type = tag.type;

        return res;
    },

    iterate : function(jsdocNode, cb, ctx) {
        function iterate(jsdocNode) {
            if(!jsdocNode) return;

            jsdocNode.jsdocType && cb.call(ctx, jsdocNode);

            for(var i in jsdocNode) {
                if(jsdocNode.hasOwnProperty(i)) {
                    var prop = jsdocNode[i];
                    if(prop && typeof prop === 'object') {
                        Array.isArray(prop)?
                            prop.forEach(iterate) :
                            iterate(prop);
                    }
                }
            }
        }

        iterate(jsdocNode);
    },

    _postprocess : function(rootJsdocNode, ctx, errors) {
        var _this = this,
            processedJsdocNodes = [],
            postprocessCb = function(jsdocNode) {
                _this.iterate(jsdocNode, function(jsdocNode) {
                    if(!jsdocNode._postprocessed) {
                        jsdocNode._postprocessed = true;
                        processedJsdocNodes.push(jsdocNode);
                        try {
                           _this._postprocessByType(jsdocNode.jsdocType, jsdocNode, ctx, postprocessCb);
                        } catch(e) {
                            errors.push(e);
                        }

                        try {
                            _this._postprocessByType('', jsdocNode, ctx, postprocessCb);
                        } catch(e) {
                            errors.push(e);
                        }
                    }
                });
            };

        postprocessCb(rootJsdocNode);

        processedJsdocNodes.forEach(function(jsdocNode) {
            delete jsdocNode._postprocessed;
        });
    },

    _postprocessByType : function(jsdocType, jsdocNode, ctx, postprocessCb) {
        var postprocessors = this._postprocessors[escapeKey(jsdocType)];
        postprocessors && postprocessors.forEach(function(fn) {
            fn.call(ctx, jsdocNode, postprocessCb);
        });
    },

    _buildError : function(e, source, commentAstNode) {
        var loc = commentAstNode.loc,
            msg = 'Error: "' + e.message + '" while processing jsdoc comments started at line ' + loc.start.line;

        return Error(
            msg + '\n' +
            new Array(msg.length + 1).join('-') + '\n' +
            source.split('\n').slice(loc.start.line - 1, loc.end.line + 3).join('\n') + '\n' +
            e.stack);
    }
});

var simpleParsers = {
        String : function(comment) {
            return { content : comment.trim() };
        },
        Boolean : function(comment) {
            return {};
        }
    };

function escapeKey(tagType) {
    return '_' + tagType;
}
<commit_msg>Current jsdoc node isn't properly changed during iteration by comment nodes (close #77)<commit_after>var Tags = require('./tags'),
    parser = require('./parser'),
    inherit = require('inherit');
/**
 * API
 * @param {Array} plugins
 * @returns {Function}
 */
module.exports = function(plugins) {
    var jsdoc = new JSDoc(plugins);
    return function(str) {
        return jsdoc.parse(str);
    };
};

var JSDoc = inherit({
    __constructor : function(plugins) {
        this._tagParsers = {};
        this._tagBuilders = [];
        this._postprocessors = {};

        plugins.forEach(this._registerPlugin, this);
    },

    _registerPlugin : function(plugin) {
        (typeof plugin === 'string'? require(plugin) : plugin)(this);
        return this;
    },

    registerParser : function(tagType, parseFn) {
        if(Array.isArray(tagType)) {
            tagType.forEach(
                function(tagType) {
                    this.registerParser(tagType, parseFn);
                },
                this);
            return this;
        }

        tagType = escapeKey(tagType);
        this._tagParsers[tagType] = parseFn === Boolean || parseFn === String?
            simpleParsers[parseFn.name] :
            parseFn;
        return this;
    },

    registerBuilder : function(tagType, builderFn) {
        if(typeof tagType === 'function') {
            builderFn = tagType;
            tagType = null;
        }
        else if(Array.isArray(tagType)) {
            tagType.forEach(
                function(tagType) {
                    this.registerBuilder(tagType, builderFn);
                },
                this);
            return this;
        }

        this._tagBuilders.push({ type : tagType, fn : builderFn });
        return this;
    },

    registerPostprocessor : function(jsdocType, postprocessorFn) {
        if(Array.isArray(jsdocType)) {
            jsdocType.forEach(
                function(jsdocType) {
                    this.registerPostprocessor(jsdocType, postprocessorFn);
                },
                this);
            return this;
        }

        if(arguments.length === 1) {
            postprocessorFn = jsdocType;
            jsdocType = '';
        }

        jsdocType = escapeKey(jsdocType);
        (this._postprocessors[jsdocType] || (this._postprocessors[jsdocType] = [])).push(postprocessorFn);
        return this;
    },

    parse : function(source) {
        var sourceTree = parser(source),
            rootJsdocNode = { jsdocType : 'root' },
            ctx = {},
            _this = this,
            errors = [];

        sourceTree.iterate(
            function(astNode, jsdocNode) {
                var accJsdocNode = jsdocNode;
                astNode.comments.forEach(function(commentAstNode) {
                    var iterationErrors = [];
                    accJsdocNode = _this._onIterate(ctx, commentAstNode, astNode, accJsdocNode, iterationErrors);
                    errors = errors.concat(iterationErrors.map(function(e) {
                        return _this._buildError(e, source, commentAstNode);
                    }));
                });

                return accJsdocNode;
            },
            rootJsdocNode);

        this._postprocess(rootJsdocNode, ctx, errors);

        if(errors.length) throw Error(errors.join('\n\n\n'));

        return rootJsdocNode;
    },

    _onIterate : function(ctx, commentAstNode, astNode, jsdocNode, errors) {
        var accJsdocNode = jsdocNode,
            parentJsdocNode = jsdocNode,
            tags = new Tags(this._parseJSDocComment(commentAstNode.value, errors));

        this._tagBuilders.forEach(function(tagBuilder) {
            if(!tagBuilder.type) {
                // TODO: get rid of copy-paste
                try {
                    var res = tagBuilder.fn.call(ctx, tags, accJsdocNode, parentJsdocNode, astNode);
                    typeof res !== 'undefined' && (accJsdocNode = res);
                } catch(e) {
                    errors.push(e);
                }
                return;
            }

            tags.getTagsByType(tagBuilder.type).forEach(function(tag) {
                // TODO: get rid of copy-paste
                try {
                    var res = tagBuilder.fn.call(ctx, tag, accJsdocNode, parentJsdocNode, astNode);
                    typeof res !== 'undefined' && (accJsdocNode = res);
                } catch(e) {
                    errors.push(e);
                }
            });
        });

        return accJsdocNode;
    },

    _parseJSDocComment : function(comment, errors) {
        var tags = [],
            lines = comment.replace(/^(\s*\*)?[\s\n]*|[\s\n]*$/g, '').split('\n'),
            tag = { type : '', comment : '' };

        lines.forEach(function(line, i) {
            var matches = line.match(/^(?:\*|\s)*@(\w+)(?:\s+(.+?)\s*)?$/);
            if(matches) {
                tag.type && tags.push(this._parseTagComment(tag, errors));
                tag.type = matches[1];
                tag.comment = matches[2] || '';
            } else {
                i || (tag.type = 'description');
                tag.comment += (tag.comment? '\n' : '') + line.replace(/^\s*\*\s?|\s*$/g, '');
            }
        }, this);

        tags.push(this._parseTagComment(tag, errors));

        return tags;
    },

    _parseTagComment : function(tag, errors) {
        var parse = this._tagParsers[escapeKey(tag.type)],
            comment = tag.comment.replace(/\n*$/g, ''),
            res;

        if(parse) {
            try {
                res = parse(comment);
            } catch(e) {
                errors.push(e);
            }
        } else {
            errors.push(Error('Unsupported tag: ' + tag.type));
        }

        res || (res = { content : comment });
        res.type = tag.type;

        return res;
    },

    iterate : function(jsdocNode, cb, ctx) {
        function iterate(jsdocNode) {
            if(!jsdocNode) return;

            jsdocNode.jsdocType && cb.call(ctx, jsdocNode);

            for(var i in jsdocNode) {
                if(jsdocNode.hasOwnProperty(i)) {
                    var prop = jsdocNode[i];
                    if(prop && typeof prop === 'object') {
                        Array.isArray(prop)?
                            prop.forEach(iterate) :
                            iterate(prop);
                    }
                }
            }
        }

        iterate(jsdocNode);
    },

    _postprocess : function(rootJsdocNode, ctx, errors) {
        var _this = this,
            processedJsdocNodes = [],
            postprocessCb = function(jsdocNode) {
                _this.iterate(jsdocNode, function(jsdocNode) {
                    if(!jsdocNode._postprocessed) {
                        jsdocNode._postprocessed = true;
                        processedJsdocNodes.push(jsdocNode);
                        try {
                           _this._postprocessByType(jsdocNode.jsdocType, jsdocNode, ctx, postprocessCb);
                        } catch(e) {
                            errors.push(e);
                        }

                        try {
                            _this._postprocessByType('', jsdocNode, ctx, postprocessCb);
                        } catch(e) {
                            errors.push(e);
                        }
                    }
                });
            };

        postprocessCb(rootJsdocNode);

        processedJsdocNodes.forEach(function(jsdocNode) {
            delete jsdocNode._postprocessed;
        });
    },

    _postprocessByType : function(jsdocType, jsdocNode, ctx, postprocessCb) {
        var postprocessors = this._postprocessors[escapeKey(jsdocType)];
        postprocessors && postprocessors.forEach(function(fn) {
            fn.call(ctx, jsdocNode, postprocessCb);
        });
    },

    _buildError : function(e, source, commentAstNode) {
        var loc = commentAstNode.loc,
            msg = 'Error: "' + e.message + '" while processing jsdoc comments started at line ' + loc.start.line;

        return Error(
            msg + '\n' +
            new Array(msg.length + 1).join('-') + '\n' +
            source.split('\n').slice(loc.start.line - 1, loc.end.line + 3).join('\n') + '\n' +
            e.stack);
    }
});

var simpleParsers = {
        String : function(comment) {
            return { content : comment.trim() };
        },
        Boolean : function(comment) {
            return {};
        }
    };

function escapeKey(tagType) {
    return '_' + tagType;
}
<|endoftext|>


<commit_before>
/**
 * juice
 * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

var juice = function (html,options) {
  var $ = utils.cheerio(html);
  return juiceDocument($,options).html();
};

module.exports = juice;

/**
 * Module dependencies.
 */

var utils = require('./utils')
  , Selector = require('./selector')
  , Property = require('./property')
  , packageJson = require('../package')
  , fs = require('fs')
  , path = require('path')
  , assert = require('assert')
  , styleSelector = new Selector('<style attribute>', [1, 0, 0, 0])
  , importantSelector = new Selector('<!important>', [2, 0, 0, 0]);

/**
 * Package version
 */

juice.version = packageJson.version;

/**
 * Export Selector.
 */

juice.Selector = Selector;

/**
 * Export Property.
 */

juice.Property = Property;

/**
 * Export utils.
 */

juice.utils = require('./utils');

juice.ignoredPseudos = ['hover', 'active', 'focus', 'visited', 'link'];
juice.widthElements = ['TABLE', 'TD', 'IMG'];
juice.tableElements = ['TABLE', 'TD', 'TH', 'TR', 'TD', 'CAPTION', 'COLGROUP', 'COL', 'THEAD', 'TBODY', 'TFOOT'];
juice.styleToAttribute = {
  'background-color': 'bgcolor',
  'background-image': 'background',
  'text-align': 'align',
  'vertical-align': 'valign'
};

juice.juiceDocument = juiceDocument;
juice.juiceResources = juiceResources;
juice.juiceFile = juiceFile;
juice.inlineDocument = inlineDocument;
juice.inlineContent = inlineContent;

function inlineDocument($, css, options) {

  var rules = utils.parseCSS(css)
    , editedElements = [];

  rules.forEach(handleRule);
  editedElements.forEach(inlineElementStyles);

  if (options && options.inlinePseudoElements) {
    editedElements.forEach(inlinePseudoElements);
  }

  if (options && options.applyWidthAttributes) {
    editedElements.forEach(setWidthAttrs);
  }

  if (options && options.applyAttributesTableElements) {
    editedElements.forEach(setAttributesOnTableElements);
  }

  function handleRule(rule) {
    var sel = rule[0]
      , style = rule[1]
      , selector = new Selector(sel)
      , parsedSelector = selector.parsed()
      , pseudoElementType = getPseudoElementType(parsedSelector);

    // skip rule if the selector has any pseudos which are ignored
    for (var i = 0; i < parsedSelector.length; ++i) {
      var subSel = parsedSelector[i];
      if (subSel.pseudos) {
        for (var j = 0; j < subSel.pseudos.length; ++j) {
          var subSelPseudo = subSel.pseudos[j];
          if (juice.ignoredPseudos.indexOf(subSelPseudo.name) >= 0) return;
        }
      }
    }

    if (pseudoElementType) {
      var last = parsedSelector[parsedSelector.length - 1];
      var pseudos = last.pseudos;
      last.pseudos = filterElementPseudos(last.pseudos),
      sel = parsedSelector.toString();
      last.pseudos = pseudos;
    }

    var els;
    try {
      els = $(sel);
    } catch (err) {
      // skip invalid selector
      return;
    }

    els.each(function () {
      var el = this;

      if (pseudoElementType) {
        var pseudoElPropName = "pseudo" + pseudoElementType;
        var pseudoEl = el[pseudoElPropName];
        if (!pseudoEl) {
          pseudoEl = el[pseudoElPropName] = $("<span />");
          pseudoEl.pseudoElementType = pseudoElementType;
          pseudoEl.pseudoElementParent = el;
          el[pseudoElPropName] = pseudoEl;
        }
        el = pseudoEl;
      }

      if (!el.styleProps) {
        el.styleProps = {}

        // if the element has inline styles, fake selector with topmost specificity
        if ($(el).attr('style')) {
          var cssText = '* { ' + $(el).attr('style') + ' } '
          addProps(utils.parseCSS(cssText)[0][1], styleSelector);
        }

        // store reference to an element we need to compile style="" attr for
        editedElements.push(el);
      }

      // go through the properties
      function addProps (style, selector) {
        for (var i = 0, l = style.length; i < l; i++) {
          var name = style[i]
            , value = style[name]
            , sel = style._importants[name] ? importantSelector : selector
            , prop = new Property(name, value, sel)
            , existing = el.styleProps[name];

          if (existing) {
            var winner = existing.compare(prop)
              , loser = prop === winner ? existing : prop

            if (winner === prop) el.styleProps[name] = prop;
          } else {
            el.styleProps[name] = prop;
          }
        }
      }

      addProps(style, selector);
    });
  }

  function inlineElementStyles(el) {
    var props = Object.keys(el.styleProps).map(function(key) {
      return el.styleProps[key];
    });
    // sort properties by their originating selector's specificity so that
    // props like "padding" and "padding-bottom" are resolved as expected.
    props.sort(function(a, b) {
      return a.selector.specificity().join("").localeCompare(
        b.selector.specificity().join(""));
    });
    var string = props
      .filter(function(prop) {
        // Content becomes the innerHTML of pseudo elements, not used as a
        // style property
        return prop.prop !== "content";
      })
      .map(function(prop) {
        return prop.prop + ": " + prop.value.replace(/["]/g, "'") + ";";
      })
      .join(" ");
    if (string) {
      $(el).attr('style', string);
    }
  }

  function inlinePseudoElements(el) {
    if (el.pseudoElementType && el.styleProps.content) {
      el.html(parseContent(el.styleProps.content.value));
      var parent = el.pseudoElementParent;
      if (el.pseudoElementType === "before") {
        $(parent).prepend(el);
      }
      else {
        $(parent).append(el);
      }
    }
  }

  function setWidthAttrs(el) {
    var elName = el.name.toUpperCase();
    if (juice.widthElements.indexOf(elName) > -1) {
      for (var i in el.styleProps) {
        if (el.styleProps[i].prop === 'width' && el.styleProps[i].value.match(/px/)) {
          var pxWidth = el.styleProps[i].value.replace('px', '');
          $(el).attr('width', pxWidth);
          return;
        }
      }
    }
  }

  function setAttributesOnTableElements(el) {
    var elName = el.name.toUpperCase(),
        styleProps = Object.keys(juice.styleToAttribute);

    if (juice.tableElements.indexOf(elName) > -1) {
      for (var i in el.styleProps) {
        if (styleProps.indexOf(el.styleProps[i].prop) > -1) {
          $(el).attr(juice.styleToAttribute[el.styleProps[i].prop], el.styleProps[i].value);
        }
      }
    }
  }
}

function parseContent(content) {
  if (content === "none" || content === "normal") {
    return "";
  }

  // Naive parsing, assume well-formed value
  content = content.slice(1, content.length - 1);
  // Naive unescape, assume no unicode char codes
  content = content.replace(/\\/g, "");
  return content;
}

// Return "before" or "after" if the given selector is a pseudo element (e.g.,
// a::after).
function getPseudoElementType(selector) {
  if (selector.length === 0) {
    return;
  }

  var pseudos = selector[selector.length - 1].pseudos;
  if (!pseudos) {
    return;
  }

  for (var i = 0; i < pseudos.length; i++) {
    if (isPseudoElementName(pseudos[i])) {
      return pseudos[i].name;
    }
  }
}

function isPseudoElementName(pseudo) {
  return pseudo.name === "before" || pseudo.name === "after";
}

function filterElementPseudos(pseudos) {
  return pseudos.filter(function(pseudo) {
    return !isPseudoElementName(pseudo);
  });
}

function juiceDocument($, options) {
  options = getDefaultOptions(options);
  var css = extractCssFromDocument($, options);
  css += "\n" + options.extraCss;
  inlineDocument($, css, options);
  return $;
}

function juiceResources(html, options, callback) {
  options = getDefaultOptions(options);

  var onInline = function(err, html) {
    if(err){
      return callback(err);
    }

    var $ = utils.cheerio(html);
    juiceDocument($, options);
    callback(null, $.html());
  };

  options.webResources.relativeTo = options.webResources.relativeTo || options.url; //legacy support
  utils.inlineExternal(html, options.webResources, onInline);
}

function getDefaultOptions(options) {
  var result = utils.extend({
    extraCss: "",
    applyStyleTags: true,
    removeStyleTags: true,
    preserveMediaQueries: false,
    applyWidthAttributes: false,
    applyAttributesTableElements: false,
    url: ""
  }, options);

  result.webResources = result.webResources || {};

  return result;
}

function juiceFile(filePath, options, callback) {
  // set default options
  fs.readFile(filePath, 'utf8', function(err, content) {
    if (err) return callback(err);
    options = getDefaultOptions(options); // so we can mutate options without guilt
    if(!options.webResources.relativeTo){
      var rel = path.dirname(path.relative(process.cwd(),filePath));
      options.webResources.relativeTo = rel;
    };
    juiceResources(content, options, callback);
  });
}

function inlineContent(html, css, options) {
    var $ = utils.cheerio(html);
    inlineDocument($, css, options);
    return $.html();
}

function getStylesData($, options) {
  var results = [];
  var stylesList = $("style");
  var i, styleDataList, styleData, styleElement;
  stylesList.each(function () {
    styleElement = this;
    styleDataList = styleElement.childNodes;
    if (styleDataList.length !== 1) {
      return;
    }
    styleData = styleDataList[0].data;
    if ( options.applyStyleTags ) results.push( styleData );
    if ( options.removeStyleTags )
    {
      if ( options.preserveMediaQueries )
      {
        var mediaQueries = utils.getMediaQueryText( styleElement.childNodes[0].nodeValue );
        styleElement.childNodes[0].nodeValue = mediaQueries;
      }
      else
      {
        $(styleElement).remove();
      }
    }
  });
  return results;
}

function extractCssFromDocument($, options) {
  var results = getStylesData($, options);
  var css = results.join("\n");
  return css;
}

<commit_msg>Change function name back to setStyleAttrs<commit_after>
/**
 * juice
 * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

var juice = function (html,options) {
  var $ = utils.cheerio(html);
  return juiceDocument($,options).html();
};

module.exports = juice;

/**
 * Module dependencies.
 */

var utils = require('./utils')
  , Selector = require('./selector')
  , Property = require('./property')
  , packageJson = require('../package')
  , fs = require('fs')
  , path = require('path')
  , assert = require('assert')
  , styleSelector = new Selector('<style attribute>', [1, 0, 0, 0])
  , importantSelector = new Selector('<!important>', [2, 0, 0, 0]);

/**
 * Package version
 */

juice.version = packageJson.version;

/**
 * Export Selector.
 */

juice.Selector = Selector;

/**
 * Export Property.
 */

juice.Property = Property;

/**
 * Export utils.
 */

juice.utils = require('./utils');

juice.ignoredPseudos = ['hover', 'active', 'focus', 'visited', 'link'];
juice.widthElements = ['TABLE', 'TD', 'IMG'];
juice.tableElements = ['TABLE', 'TD', 'TH', 'TR', 'TD', 'CAPTION', 'COLGROUP', 'COL', 'THEAD', 'TBODY', 'TFOOT'];
juice.styleToAttribute = {
  'background-color': 'bgcolor',
  'background-image': 'background',
  'text-align': 'align',
  'vertical-align': 'valign'
};

juice.juiceDocument = juiceDocument;
juice.juiceResources = juiceResources;
juice.juiceFile = juiceFile;
juice.inlineDocument = inlineDocument;
juice.inlineContent = inlineContent;

function inlineDocument($, css, options) {

  var rules = utils.parseCSS(css)
    , editedElements = [];

  rules.forEach(handleRule);
  editedElements.forEach(setStyleAttrs);

  if (options && options.inlinePseudoElements) {
    editedElements.forEach(inlinePseudoElements);
  }

  if (options && options.applyWidthAttributes) {
    editedElements.forEach(setWidthAttrs);
  }

  if (options && options.applyAttributesTableElements) {
    editedElements.forEach(setAttributesOnTableElements);
  }

  function handleRule(rule) {
    var sel = rule[0]
      , style = rule[1]
      , selector = new Selector(sel)
      , parsedSelector = selector.parsed()
      , pseudoElementType = getPseudoElementType(parsedSelector);

    // skip rule if the selector has any pseudos which are ignored
    for (var i = 0; i < parsedSelector.length; ++i) {
      var subSel = parsedSelector[i];
      if (subSel.pseudos) {
        for (var j = 0; j < subSel.pseudos.length; ++j) {
          var subSelPseudo = subSel.pseudos[j];
          if (juice.ignoredPseudos.indexOf(subSelPseudo.name) >= 0) return;
        }
      }
    }

    if (pseudoElementType) {
      var last = parsedSelector[parsedSelector.length - 1];
      var pseudos = last.pseudos;
      last.pseudos = filterElementPseudos(last.pseudos),
      sel = parsedSelector.toString();
      last.pseudos = pseudos;
    }

    var els;
    try {
      els = $(sel);
    } catch (err) {
      // skip invalid selector
      return;
    }

    els.each(function () {
      var el = this;

      if (pseudoElementType) {
        var pseudoElPropName = "pseudo" + pseudoElementType;
        var pseudoEl = el[pseudoElPropName];
        if (!pseudoEl) {
          pseudoEl = el[pseudoElPropName] = $("<span />");
          pseudoEl.pseudoElementType = pseudoElementType;
          pseudoEl.pseudoElementParent = el;
          el[pseudoElPropName] = pseudoEl;
        }
        el = pseudoEl;
      }

      if (!el.styleProps) {
        el.styleProps = {}

        // if the element has inline styles, fake selector with topmost specificity
        if ($(el).attr('style')) {
          var cssText = '* { ' + $(el).attr('style') + ' } '
          addProps(utils.parseCSS(cssText)[0][1], styleSelector);
        }

        // store reference to an element we need to compile style="" attr for
        editedElements.push(el);
      }

      // go through the properties
      function addProps (style, selector) {
        for (var i = 0, l = style.length; i < l; i++) {
          var name = style[i]
            , value = style[name]
            , sel = style._importants[name] ? importantSelector : selector
            , prop = new Property(name, value, sel)
            , existing = el.styleProps[name];

          if (existing) {
            var winner = existing.compare(prop)
              , loser = prop === winner ? existing : prop

            if (winner === prop) el.styleProps[name] = prop;
          } else {
            el.styleProps[name] = prop;
          }
        }
      }

      addProps(style, selector);
    });
  }

  function setStyleAttrs(el) {
    var props = Object.keys(el.styleProps).map(function(key) {
      return el.styleProps[key];
    });
    // sort properties by their originating selector's specificity so that
    // props like "padding" and "padding-bottom" are resolved as expected.
    props.sort(function(a, b) {
      return a.selector.specificity().join("").localeCompare(
        b.selector.specificity().join(""));
    });
    var string = props
      .filter(function(prop) {
        // Content becomes the innerHTML of pseudo elements, not used as a
        // style property
        return prop.prop !== "content";
      })
      .map(function(prop) {
        return prop.prop + ": " + prop.value.replace(/["]/g, "'") + ";";
      })
      .join(" ");
    if (string) {
      $(el).attr('style', string);
    }
  }

  function inlinePseudoElements(el) {
    if (el.pseudoElementType && el.styleProps.content) {
      el.html(parseContent(el.styleProps.content.value));
      var parent = el.pseudoElementParent;
      if (el.pseudoElementType === "before") {
        $(parent).prepend(el);
      }
      else {
        $(parent).append(el);
      }
    }
  }

  function setWidthAttrs(el) {
    var elName = el.name.toUpperCase();
    if (juice.widthElements.indexOf(elName) > -1) {
      for (var i in el.styleProps) {
        if (el.styleProps[i].prop === 'width' && el.styleProps[i].value.match(/px/)) {
          var pxWidth = el.styleProps[i].value.replace('px', '');
          $(el).attr('width', pxWidth);
          return;
        }
      }
    }
  }

  function setAttributesOnTableElements(el) {
    var elName = el.name.toUpperCase(),
        styleProps = Object.keys(juice.styleToAttribute);

    if (juice.tableElements.indexOf(elName) > -1) {
      for (var i in el.styleProps) {
        if (styleProps.indexOf(el.styleProps[i].prop) > -1) {
          $(el).attr(juice.styleToAttribute[el.styleProps[i].prop], el.styleProps[i].value);
        }
      }
    }
  }
}

function parseContent(content) {
  if (content === "none" || content === "normal") {
    return "";
  }

  // Naive parsing, assume well-formed value
  content = content.slice(1, content.length - 1);
  // Naive unescape, assume no unicode char codes
  content = content.replace(/\\/g, "");
  return content;
}

// Return "before" or "after" if the given selector is a pseudo element (e.g.,
// a::after).
function getPseudoElementType(selector) {
  if (selector.length === 0) {
    return;
  }

  var pseudos = selector[selector.length - 1].pseudos;
  if (!pseudos) {
    return;
  }

  for (var i = 0; i < pseudos.length; i++) {
    if (isPseudoElementName(pseudos[i])) {
      return pseudos[i].name;
    }
  }
}

function isPseudoElementName(pseudo) {
  return pseudo.name === "before" || pseudo.name === "after";
}

function filterElementPseudos(pseudos) {
  return pseudos.filter(function(pseudo) {
    return !isPseudoElementName(pseudo);
  });
}

function juiceDocument($, options) {
  options = getDefaultOptions(options);
  var css = extractCssFromDocument($, options);
  css += "\n" + options.extraCss;
  inlineDocument($, css, options);
  return $;
}

function juiceResources(html, options, callback) {
  options = getDefaultOptions(options);

  var onInline = function(err, html) {
    if(err){
      return callback(err);
    }

    var $ = utils.cheerio(html);
    juiceDocument($, options);
    callback(null, $.html());
  };

  options.webResources.relativeTo = options.webResources.relativeTo || options.url; //legacy support
  utils.inlineExternal(html, options.webResources, onInline);
}

function getDefaultOptions(options) {
  var result = utils.extend({
    extraCss: "",
    applyStyleTags: true,
    removeStyleTags: true,
    preserveMediaQueries: false,
    applyWidthAttributes: false,
    applyAttributesTableElements: false,
    url: ""
  }, options);

  result.webResources = result.webResources || {};

  return result;
}

function juiceFile(filePath, options, callback) {
  // set default options
  fs.readFile(filePath, 'utf8', function(err, content) {
    if (err) return callback(err);
    options = getDefaultOptions(options); // so we can mutate options without guilt
    if(!options.webResources.relativeTo){
      var rel = path.dirname(path.relative(process.cwd(),filePath));
      options.webResources.relativeTo = rel;
    };
    juiceResources(content, options, callback);
  });
}

function inlineContent(html, css, options) {
    var $ = utils.cheerio(html);
    inlineDocument($, css, options);
    return $.html();
}

function getStylesData($, options) {
  var results = [];
  var stylesList = $("style");
  var i, styleDataList, styleData, styleElement;
  stylesList.each(function () {
    styleElement = this;
    styleDataList = styleElement.childNodes;
    if (styleDataList.length !== 1) {
      return;
    }
    styleData = styleDataList[0].data;
    if ( options.applyStyleTags ) results.push( styleData );
    if ( options.removeStyleTags )
    {
      if ( options.preserveMediaQueries )
      {
        var mediaQueries = utils.getMediaQueryText( styleElement.childNodes[0].nodeValue );
        styleElement.childNodes[0].nodeValue = mediaQueries;
      }
      else
      {
        $(styleElement).remove();
      }
    }
  });
  return results;
}

function extractCssFromDocument($, options) {
  var results = getStylesData($, options);
  var css = results.join("\n");
  return css;
}

<|endoftext|>


<commit_before>var LaterStorage = require("./later-storage"),
    http = require("http");

/**
 * Create Express middleware to accept incoming messages and store them in a
 * queue.
 * @param {LaterStorage} storage
 */
function createMiddleware(storage) {

    /**
     * @param {http.IncomingMessage} req
     * @param {http.ServerResponse} res
     * @param {function} next
     */
    return function(req, res, next) {

    };

}<commit_msg>cleanup deprecated module<commit_after><|endoftext|>


<commit_before>'use strict';

/**
 * Expose Lexer
 */

module.exports = Lexer;

/**
 * URL path lexer
 *
 * @param {String} input
 * @return {Lexer}
 * @api public
 */

function Lexer(input) {
  if (!(this instanceof Lexer)) return new Lexer(input);
  this.pos = 0;
  this.buf = input;
  this.buflen = input.length;
  this.open = '{';
  this.close = '}';
}

/**
 * Next token.
 *
 * @return {Object}
 * @api public
 */

Lexer.prototype.token = function Lexer$token() {
  this._skipNonTokens();

  if (this.pos >= this.buflen) {
    return null;
  }

  var c = this.buf.charCodeAt(this.pos);

  if (c === 0x2F /*'/'*/) {
    return new Token('SLASH', '/', this.pos++);
  } else {
    if (c === 0x23 /*'#'*/) {
      return new Token('HASH', '#', this.pos++);
    } else if (c === 0x3F /*'?'*/) {
      return new Token('QUESTION', '?', this.pos++);
    } else if (c === this.open.charCodeAt()) {
      return this._processPlaceholder(c, this.close.charCodeAt());
    } else if (isLegalChars(c)) {
      return this._processIdentifier();
    }
  }
};

/**
 * Return all tokens.
 *
 * @return {Array}
 * @api public
 */

Lexer.prototype.tokens = function Lexer$tokens() {
  var res = null, tok;
  while ((tok = this.token())) {
    if (!res) res = [];
    res.push(tok);
  }
  return res;
};

Lexer.prototype._skipNonTokens = function Lexer$_skipNonTokens() {
  var c;
  while (this.pos < this.buflen) {
    c = this.buf.charCodeAt(this.pos);
    if (((c ^ 0x20 /*' '*/) &&
          (c ^ 0x0D /*'\r'*/) &&
          (c ^ 0x0A /*'\n'*/) &&
          (c ^ 0x09 /*'\t'*/)) === 0) {
      this.pos++;
    } else {
      break;
    }
  }
};

Lexer.prototype._processPlaceholder = function Lexer$_processPlaceholder(s, e) {
  var endpos = this.pos + 1,
    colonpos = 0,
    depth = 1,
    c, tok;
  while (endpos < this.buflen) {
    c = this.buf.charCodeAt(endpos);
    if (c === s) depth++;
    else if (c === 0x3A /*':'*/) colonpos = endpos;
    else if (c === e) depth--;
    if (depth === 0) break;
    endpos++;
  }
  // broken delimiters
  if (depth) {
    return null;
  }
  tok = new Token(
    'PLACEHOLDER',
    this.buf.substring(this.pos + 1, colonpos || endpos),
    this.pos
  );
  if (colonpos && endpos - colonpos > 1) {
    tok.regexp = this.buf.substring(colonpos + 1, endpos);
  } else {
    tok.regexp = '[^/]+';
  }
  this.pos = endpos + 1;
  return tok;
};

Lexer.prototype._processIdentifier = function Lexer$_processIdentifier() {
  var endpos = this.pos + 1, tok;
  while (endpos < this.buflen &&
         isLegalChars(this.buf.charCodeAt(endpos))) {
    endpos++;
  }
  tok = new Token(
    'IDENTIFIER',
    this.buf.substring(this.pos, endpos),
    this.pos
  );
  this.pos = endpos;
  return tok;
};

Lexer.isLegalChars= isLegalChars;

function isLegalChars(c) {
  return (c >= 0x30 && c <= 0x39) ||  // 0~9
         (c >= 0x41 && c <= 0x5A) ||  // a~z
         (c >= 0x61 && c <= 0x7A) ||  // A~Z
         c === 0x21 || c === 0x24 ||  // !$
         c === 0x26 || c === 0x27 ||  // &'
         c === 0x28 || c === 0x29 ||  // ()
         c === 0x2A || c === 0x2B ||  // *+
         c === 0x2C || c === 0x3B ||  // ,;
         c === 0x3D || c === 0x3A ||  // =:
         c === 0x40 || c === 0x2D ||  // @-
         c === 0x2E || c === 0x7E ||  // .~
         c === 0x5F || c === 0x25;    // _%
}

/**
 * Token
 *
 * @param {String} name
 * @param {String} value
 * @param {Number} pos
 * @param {String} regexp
 * @return {Token}
 * @api private
 */

function Token(name, value, pos, regexp) {
  this.name = name;
  this.value = value;
  this.pos = pos;
  if (regexp !== void 0) this.regexp = regexp;
}
<commit_msg>check depth<commit_after>'use strict';

/**
 * Expose Lexer
 */

module.exports = Lexer;

/**
 * URL path lexer
 *
 * @param {String} input
 * @return {Lexer}
 * @api public
 */

function Lexer(input) {
  if (!(this instanceof Lexer)) return new Lexer(input);
  this.pos = 0;
  this.buf = input;
  this.buflen = input.length;
  this.open = '{';
  this.close = '}';
}

/**
 * Next token.
 *
 * @return {Object}
 * @api public
 */

Lexer.prototype.token = function Lexer$token() {
  this._skipNonTokens();

  if (this.pos >= this.buflen) {
    return null;
  }

  var c = this.buf.charCodeAt(this.pos);

  if (c === 0x2F /*'/'*/) {
    return new Token('SLASH', '/', this.pos++);
  } else {
    if (c === 0x23 /*'#'*/) {
      return new Token('HASH', '#', this.pos++);
    } else if (c === 0x3F /*'?'*/) {
      return new Token('QUESTION', '?', this.pos++);
    } else if (c === this.open.charCodeAt()) {
      return this._processPlaceholder(c, this.close.charCodeAt());
    } else if (isLegalChars(c)) {
      return this._processIdentifier();
    }
  }
};

/**
 * Return all tokens.
 *
 * @return {Array}
 * @api public
 */

Lexer.prototype.tokens = function Lexer$tokens() {
  var res = null, tok;
  while ((tok = this.token())) {
    if (!res) res = [];
    res.push(tok);
  }
  return res;
};

Lexer.prototype._skipNonTokens = function Lexer$_skipNonTokens() {
  var c;
  while (this.pos < this.buflen) {
    c = this.buf.charCodeAt(this.pos);
    if (((c ^ 0x20 /*' '*/) &&
          (c ^ 0x0D /*'\r'*/) &&
          (c ^ 0x0A /*'\n'*/) &&
          (c ^ 0x09 /*'\t'*/)) === 0) {
      this.pos++;
    } else {
      break;
    }
  }
};

Lexer.prototype._processPlaceholder = function Lexer$_processPlaceholder(s, e) {
  var endpos = this.pos + 1,
    colonpos = 0,
    depth = 1,
    c, tok;
  while (endpos < this.buflen) {
    c = this.buf.charCodeAt(endpos);
    if (c === s) depth++;
    else if (depth === 1 && c === 0x3A /*':'*/) colonpos = endpos;
    else if (c === e) depth--;
    if (depth === 0) break;
    endpos++;
  }
  // broken delimiters
  if (depth) {
    return null;
  }
  tok = new Token(
    'PLACEHOLDER',
    this.buf.substring(this.pos + 1, colonpos || endpos),
    this.pos
  );
  if (colonpos && endpos - colonpos > 1) {
    tok.regexp = this.buf.substring(colonpos + 1, endpos);
  } else {
    tok.regexp = '[^/]+';
  }
  this.pos = endpos + 1;
  return tok;
};

Lexer.prototype._processIdentifier = function Lexer$_processIdentifier() {
  var endpos = this.pos + 1, tok;
  while (endpos < this.buflen &&
         isLegalChars(this.buf.charCodeAt(endpos))) {
    endpos++;
  }
  tok = new Token(
    'IDENTIFIER',
    this.buf.substring(this.pos, endpos),
    this.pos
  );
  this.pos = endpos;
  return tok;
};

Lexer.isLegalChars= isLegalChars;

function isLegalChars(c) {
  return (c >= 0x30 && c <= 0x39) ||  // 0~9
         (c >= 0x41 && c <= 0x5A) ||  // a~z
         (c >= 0x61 && c <= 0x7A) ||  // A~Z
         c === 0x21 || c === 0x24 ||  // !$
         c === 0x26 || c === 0x27 ||  // &'
         c === 0x28 || c === 0x29 ||  // ()
         c === 0x2A || c === 0x2B ||  // *+
         c === 0x2C || c === 0x3B ||  // ,;
         c === 0x3D || c === 0x3A ||  // =:
         c === 0x40 || c === 0x2D ||  // @-
         c === 0x2E || c === 0x7E ||  // .~
         c === 0x5F || c === 0x25;    // _%
}

/**
 * Token
 *
 * @param {String} name
 * @param {String} value
 * @param {Number} pos
 * @param {String} regexp
 * @return {Token}
 * @api private
 */

function Token(name, value, pos, regexp) {
  this.name = name;
  this.value = value;
  this.pos = pos;
  if (regexp !== void 0) this.regexp = regexp;
}
<|endoftext|>