<commit_before>jQuery.namespace('Meatazine.view.ui.editor');
(function (ns) {
  var localFile = new Meatazine.filesystem.FileReferrence(),
      args = null,
      callback = null,
      canvas = null,
      value = null,
      scale = 1,
      uploader = null,
      url = '',
      x = 0,
      y = 0;
  ns.ImageEditor = ns.AbstractEditor.extend({
    drawImage : function () {
      var source = canvas.data('image'),
          context = canvas[0].getContext('2d'),
          sourceWidth = canvas[0].width / scale,
          sourceHeight = canvas[0].height / scale,
          sourceX = (source.width - sourceWidth >> 1) - x / scale,
          sourceY = (source.height - sourceHeight >> 1) - y / scale,
          destWidth = 0,
          destHeight = 0,
          destX = sourceX < 0 ? Math.abs(sourceX) / sourceWidth * canvas[0].width : 0,
          destY = sourceY < 0 ? Math.abs(sourceY) / sourceHeight * canvas[0].height : 0;
      if (sourceX < 0) {
        sourceWidth += sourceX;
        sourceX = 0;
      }
      if (sourceX + sourceWidth > source.width) {
        sourceWidth = source.width - sourceX;
      }
      if (sourceY < 0) {
        sourceHeight += sourceY;
        sourceY = 0;
      }
      if (sourceY + sourceHeight > source.height) {
        sourceHeight = source.height - sourceY;
      }
      destWidth = sourceWidth * scale;
      destHeight = sourceHeight * scale;
      context.clearRect(0, 0, canvas[0].width, canvas[0].height);
      context.drawImage(source, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight);
    },
    getSourceImageUrl: function (url) {
      if ((/\/source\//i).test(url)) {
        return url;
      }
      return url.substr(0, url.lastIndexOf('/')) + '/source' + url.substr(url.lastIndexOf('/'));
    },
    getTarget: function () {
      return image;
    },
    initButtons: function () {
      ns.AbstractEditor.prototype.initButtons.call(this);
      this.buttons.find('.scale input').on('change', {self: this}, this.scale_changeHandler);
      this.buttons.find("[data-type='upload']").on('click', this.uploadButton_clickHandker);
    },
    initScaleRange: function () {
      scale = image.data('scale');
      var scaleMin = scale < 0.5 ? scale : 0.5,
          scaleMax = scale > 1.5 ? scale : 1.5,
          scaleRanger = this.buttons.find('[data-type="scale"]');
      scaleRanger
        .find('input').attr('max', scaleMax).attr('min', scaleMin).val(scale).end()
        .find('span').text(Math.round(scale * 10000) / 100 + '%');
    },
    initUploader: function () {
      // 因为input必须change才能触发事件，所以有必要移除已经之前的标签
      if (uploader != null) {
        uploader.remove();
        uploader.off();
      }
      uploader = $('<input type="file" multiple="multiple" accept="image/*" class="uploader" />');
      uploader
        .on("change", {self: this}, this.uploader_selectHandler)
        .appendTo(this.buttons.first());
    },
    saveCanvas: function () {
      if (canvas == null) {
        return;
      }
      var name = url.substr(url.lastIndexOf('/') + 1),
          content = atob(canvas[0].toDataURL('image/jpeg').split(',')[1]);
      localFile.on('complete:save', this.canvas_savedHandler, this);
      localFile.save(name, '', content, 'image/jpeg');
    },
    setCanvasScale: function (value) {
      scale = value;
      this.drawImage();
    },
    setTarget: function (value) {
      if (canvas != null) {
        this.saveCanvas();
        callback = arguments.callee;
        args = value;
        return;
      }
      image = $(value);
      url = image.attr('src');
      this.initScaleRange();
      this.initUploader();
      GUI.contextButtons.showButtons(this.buttons);
    },
    startEdit: function () {
      canvas = $('<canvas>');
      var self = this,
          sourceUrl = this.getSourceImageUrl(image.attr('src')),
          loader = new Image();
      canvas[0].width = image.width();
      canvas[0].height = image.height();
      loader.onload = function () {
        self.drawImage();
      }
      canvas
        .data('image', loader)
        .on('mousedown', function (event) {
          var currentX = x,
              currentY = y,
              startX = event.pageX,
              startY = event.pageY;
          $(this).on('mousemove', function (event) {
            offsetX = event.pageX - startX;
            offsetY = event.pageY - startY;
            x = currentX + offsetX;
            y = currentY + offsetY;
            self.drawImage();
            event.stopPropagation();
          });
          $('body').one('mouseup', function (event) {
            canvas.off('mousemove');
          });
        })
        .on('mouseup', function (event) {
          $(this).off('mousemove');
        });
      loader.src = sourceUrl;
      image.replaceWith(canvas);
      _gaq.push(['_trackEvent', 'image', 'edit-start']);
    },
    stopEdit: function () {
      image.data({
        scale: scale,
        x: x,
        y: y,
      })
      this.saveCanvas();
      _gaq.push(['_trackEvent', 'image', 'edit-stop']);
    },
    canvas_clickHandler: function (event) {
      GUI.contextButtons.showButtons(this.buttons);
    },
    canvas_savedHandler: function (url) {
      image.attr('src', url).data('scale', scale);
      canvas.replaceWith(image);
      canvas[0].getContext('2d').clearRect(0, 0, canvas[0].width, canvas[0].height);
      canvas.off();
      canvas = null;
      localFile.off('complete:save', null, this);
      if (callback != null) {
        callback.call(this, args);
      }
    },
    scale_changeHandler: function (event) {
      var self = event.data.self,
          value = $(event.target).val();
      self.buttons.find('.scale span').text(Math.round(value * 10000) / 100 + '%');
      self.setCanvasScale(value);
      _gaq.push(['_trackEvent', 'image', 'resize']);
    },
    uploadButton_clickHandker: function (event) {
      uploader.click();
      _gaq.push(['_trackEvent', 'image', 'upload']);
      event.stopPropagation();
    },
    uploader_selectHandler: function (event) {
      var self = event.data.self;
      self.trigger('select:image', uploader[0].files);
      self.buttons.find('[data-type="edit"]').prop('disabled', false);
    },
  });
})(Meatazine.view.ui.editor);<commit_msg>修复ImageEditor缺失image变量导致的bug<commit_after>jQuery.namespace('Meatazine.view.ui.editor');
(function (ns) {
  var localFile = new Meatazine.filesystem.FileReferrence(),
      args = null,
      callback = null,
      canvas = null,
      value = null,
      scale = 1,
      image = null,
      uploader = null,
      url = '',
      x = 0,
      y = 0;
  ns.ImageEditor = ns.AbstractEditor.extend({
    drawImage : function () {
      var source = canvas.data('image'),
          context = canvas[0].getContext('2d'),
          sourceWidth = canvas[0].width / scale,
          sourceHeight = canvas[0].height / scale,
          sourceX = (source.width - sourceWidth >> 1) - x / scale,
          sourceY = (source.height - sourceHeight >> 1) - y / scale,
          destWidth = 0,
          destHeight = 0,
          destX = sourceX < 0 ? Math.abs(sourceX) / sourceWidth * canvas[0].width : 0,
          destY = sourceY < 0 ? Math.abs(sourceY) / sourceHeight * canvas[0].height : 0;
      if (sourceX < 0) {
        sourceWidth += sourceX;
        sourceX = 0;
      }
      if (sourceX + sourceWidth > source.width) {
        sourceWidth = source.width - sourceX;
      }
      if (sourceY < 0) {
        sourceHeight += sourceY;
        sourceY = 0;
      }
      if (sourceY + sourceHeight > source.height) {
        sourceHeight = source.height - sourceY;
      }
      destWidth = sourceWidth * scale;
      destHeight = sourceHeight * scale;
      context.clearRect(0, 0, canvas[0].width, canvas[0].height);
      context.drawImage(source, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight);
    },
    getSourceImageUrl: function (url) {
      if ((/\/source\//i).test(url)) {
        return url;
      }
      return url.substr(0, url.lastIndexOf('/')) + '/source' + url.substr(url.lastIndexOf('/'));
    },
    getTarget: function () {
      return image;
    },
    initButtons: function () {
      ns.AbstractEditor.prototype.initButtons.call(this);
      this.buttons.find('.scale input').on('change', {self: this}, this.scale_changeHandler);
      this.buttons.find("[data-type='upload']").on('click', this.uploadButton_clickHandker);
    },
    initScaleRange: function () {
      scale = image.data('scale');
      var scaleMin = scale < 0.5 ? scale : 0.5,
          scaleMax = scale > 1.5 ? scale : 1.5,
          scaleRanger = this.buttons.find('[data-type="scale"]');
      scaleRanger
        .find('input').attr('max', scaleMax).attr('min', scaleMin).val(scale).end()
        .find('span').text(Math.round(scale * 10000) / 100 + '%');
    },
    initUploader: function () {
      // 因为input必须change才能触发事件，所以有必要移除已经之前的标签
      if (uploader != null) {
        uploader.remove();
        uploader.off();
      }
      uploader = $('<input type="file" multiple="multiple" accept="image/*" class="uploader" />');
      uploader
        .on("change", {self: this}, this.uploader_selectHandler)
        .appendTo(this.buttons.first());
    },
    saveCanvas: function () {
      if (canvas == null) {
        return;
      }
      var name = url.substr(url.lastIndexOf('/') + 1),
          content = atob(canvas[0].toDataURL('image/jpeg').split(',')[1]);
      localFile.on('complete:save', this.canvas_savedHandler, this);
      localFile.save(name, '', content, 'image/jpeg');
    },
    setCanvasScale: function (value) {
      scale = value;
      this.drawImage();
    },
    setTarget: function (value) {
      GUI.contextButtons.showButtons(this.buttons);
      if (image != null && image.is(value)) {
        return;
      }
      if (canvas != null) {
        this.saveCanvas();
        callback = arguments.callee;
        args = value;
        return;
      }
      image = $(value);
      url = image.attr('src');
      this.initScaleRange();
      this.initUploader();
    },
    startEdit: function () {
      canvas = $('<canvas>');
      var self = this,
          sourceUrl = this.getSourceImageUrl(image.attr('src')),
          loader = new Image();
      canvas[0].width = image.width();
      canvas[0].height = image.height();
      loader.onload = function () {
        self.drawImage();
      }
      canvas
        .data('image', loader)
        .on('mousedown', function (event) {
          var currentX = x,
              currentY = y,
              startX = event.pageX,
              startY = event.pageY;
          $(this).on('mousemove', function (event) {
            offsetX = event.pageX - startX;
            offsetY = event.pageY - startY;
            x = currentX + offsetX;
            y = currentY + offsetY;
            self.drawImage();
            event.stopPropagation();
          });
          $('body').one('mouseup', function (event) {
            canvas.off('mousemove');
          });
        })
        .on('mouseup', function (event) {
          $(this).off('mousemove');
        });
      loader.src = sourceUrl;
      image.replaceWith(canvas);
      _gaq.push(['_trackEvent', 'image', 'edit-start']);
    },
    stopEdit: function () {
      image.data({
        scale: scale,
        x: x,
        y: y,
      })
      this.saveCanvas();
      _gaq.push(['_trackEvent', 'image', 'edit-stop']);
    },
    canvas_clickHandler: function (event) {
      GUI.contextButtons.showButtons(this.buttons);
    },
    canvas_savedHandler: function (url) {
      image.attr('src', url).data('scale', scale);
      canvas.replaceWith(image);
      canvas[0].getContext('2d').clearRect(0, 0, canvas[0].width, canvas[0].height);
      canvas.off();
      canvas = null;
      localFile.off('complete:save', null, this);
      if (callback != null) {
        callback.call(this, args);
      }
    },
    scale_changeHandler: function (event) {
      var self = event.data.self,
          value = $(event.target).val();
      self.buttons.find('.scale span').text(Math.round(value * 10000) / 100 + '%');
      self.setCanvasScale(value);
      _gaq.push(['_trackEvent', 'image', 'resize']);
    },
    uploadButton_clickHandker: function (event) {
      uploader.click();
      _gaq.push(['_trackEvent', 'image', 'upload']);
      event.stopPropagation();
    },
    uploader_selectHandler: function (event) {
      var self = event.data.self;
      self.trigger('select:image', uploader[0].files);
      self.buttons.find('[data-type="edit"]').prop('disabled', false);
    },
  });
})(Meatazine.view.ui.editor);<|endoftext|>


<commit_before>(function ($) {
	$._dup_ajax = $.ajax;
	$._mocked = new Array();

	$.mockAjax = function(params) {
		$._mocked.push(params);
	}

	$.ajax = function() {
		var args = arguments[0];
		for(i in $._mocked) {
			if (args.url == $._mocked[i].url)
				return args.success($._mocked[i].content);
		};

		return $._dup_ajax.apply($, arguments);
	};
})(jQuery);<commit_msg>even if there's no success method, we return the content<commit_after>(function ($) {
	$._dup_ajax = $.ajax;
	$._mocked = new Array();

	$.mockAjax = function(params) {
		$._mocked.push(params);
	}

	$.ajax = function() {
		var args = arguments[0];
		for(i in $._mocked) {
			if (args.url == $._mocked[i].url)
				if (args.success != undefined)
					return args.success($._mocked[i].content);
				else
					return $._mocked[i].content;
		};

		return $._dup_ajax.apply($, arguments);
	};
})(jQuery);<|endoftext|>


<commit_before>/*jslint node: true, nomen: true, white: true, unparam: true, todo: true*/
/*!
 * Sitegear3
 * Copyright(c) 2014 Ben New, Sitegear.org
 * MIT Licensed
 */

(function (_, path, fs, http, https, connect, express, templateObject, mediator, prepareView, notFound, internalServerError, defaults) {
	"use strict";

	// Expose the application factory method and its "public methods"
	module.exports = function (settings) {
		var app = express();
		app.init();
		app.settings = templateObject(_.merge({}, app.settings, defaults, settings || {}), 'mustache');
		app.server = {};
		app.components = {};

		return _.extend(app, {
			routing: function (routes) {
				_.each(routes, function (route) {
					var urlPath = route.path,
						method = route.method || 'get',
						component = app.component(route.component || 'default'),
						actionName = route.action || 'index';
					if (!component.hasOwnProperty(actionName) || !_.isFunction(component[actionName])) {
						throw new Error('Unknown action "' + actionName + '" specified for route at URL "' + urlPath + '"');
					}
					app._router.route(method, urlPath, component[actionName]);
				});
				// TODO Allow these to be overridden
				return app
					.use(prepareView(app))
					.use(app.router)
					.use(notFound())
					.use(internalServerError());
			},

			connect: function (adapter) {
				app.data = mediator(adapter);
				return app;
			},

			start: function (port, callback) {
				if (!_.isNumber(port)) {
					callback = port;
					port = 80;
				}
				callback = callback || _.noop;
				app.server.http = http.createServer(app).listen(port, function () {
					console.log('Listening on port ' + port);
					callback();
				});
				return app;
			},

			startSecure: function (options, port, callback) {
				if (!_.isNumber(port)) {
					callback = port;
					port = 443;
				}
				callback = callback || _.noop;
				if (_.isString(options)) {
					fs.readFile(options, function (error, data) {
						app.startSecure({ pfx: data }, port, callback);
					});
				} else {
					app.server.https = https.createServer(options, app).listen(port, function () {
						console.log('Listening with SSL on port ' + port);
						callback();
					});
				}
				return app;
			},

			stop: function (callback) {
				var next = function () {
					if (_.isPlainObject(app.server) && _.size(app.server) > 0) {
						var key = _.keys(app.server)[0];
						console.log('Closing ' + key + ' port');
						app.server[key].close(function () {
							delete app.server[key];
							next();
						});
					} else {
						delete app.server;
						process.nextTick(callback);
					}
				};
				next();
				return app;
			},

			component: function (name) {
				if (!app.components.hasOwnProperty(name)) {
					var factory = require('sitegear3-component-' + name);
					app.components[name] = factory(app);
				}
				return app.components[name];
			}
		});
	};
}(require('lodash'), require('path'), require('fs'), require('http'), require('https'), require('connect'), require('express'), require('template-object'), require('./mediator'), require('./middleware/prepareView'), require('./middleware/notFound'), require('./middleware/internalServerError'), require('./defaults.json')));
<commit_msg>Remove TODO.<commit_after>/*jslint node: true, nomen: true, white: true, unparam: true*/
/*!
 * Sitegear3
 * Copyright(c) 2014 Ben New, Sitegear.org
 * MIT Licensed
 */

(function (_, path, fs, http, https, connect, express, templateObject, mediator, prepareView, notFound, internalServerError, defaults) {
	"use strict";

	// Expose the application factory method and its "public methods"
	module.exports = function (settings) {
		var app = express();
		app.init();
		app.settings = templateObject(_.merge({}, app.settings, defaults, settings || {}), 'mustache');
		app.server = {};
		app.components = {};

		return _.extend(app, {
			routing: function (routes) {
				_.each(routes, function (route) {
					var urlPath = route.path,
						method = route.method || 'get',
						component = app.component(route.component || 'default'),
						actionName = route.action || 'index';
					if (!component.hasOwnProperty(actionName) || !_.isFunction(component[actionName])) {
						throw new Error('Unknown action "' + actionName + '" specified for route at URL "' + urlPath + '"');
					}
					app._router.route(method, urlPath, component[actionName]);
				});
				return app
					.use(prepareView(app))
					.use(app.router)
					.use(notFound())
					.use(internalServerError());
			},

			connect: function (adapter) {
				app.data = mediator(adapter);
				return app;
			},

			start: function (port, callback) {
				if (!_.isNumber(port)) {
					callback = port;
					port = 80;
				}
				callback = callback || _.noop;
				app.server.http = http.createServer(app).listen(port, function () {
					console.log('Listening on port ' + port);
					callback();
				});
				return app;
			},

			startSecure: function (options, port, callback) {
				if (!_.isNumber(port)) {
					callback = port;
					port = 443;
				}
				callback = callback || _.noop;
				if (_.isString(options)) {
					fs.readFile(options, function (error, data) {
						app.startSecure({ pfx: data }, port, callback);
					});
				} else {
					app.server.https = https.createServer(options, app).listen(port, function () {
						console.log('Listening with SSL on port ' + port);
						callback();
					});
				}
				return app;
			},

			stop: function (callback) {
				var next = function () {
					if (_.isPlainObject(app.server) && _.size(app.server) > 0) {
						var key = _.keys(app.server)[0];
						console.log('Closing ' + key + ' port');
						app.server[key].close(function () {
							delete app.server[key];
							next();
						});
					} else {
						delete app.server;
						process.nextTick(callback);
					}
				};
				next();
				return app;
			},

			component: function (name) {
				if (!app.components.hasOwnProperty(name)) {
					var factory = require('sitegear3-component-' + name);
					app.components[name] = factory(app);
				}
				return app.components[name];
			}
		});
	};
}(require('lodash'), require('path'), require('fs'), require('http'), require('https'), require('connect'), require('express'), require('template-object'), require('./mediator'), require('./middleware/prepareView'), require('./middleware/notFound'), require('./middleware/internalServerError'), require('./defaults.json')));
<|endoftext|>


<commit_before>let fs      = require('fs'),
    path    = require('path'),
    util    = require('util'),
    Sandbox = require("sandbox");

// With following assume, [data] folder will place all data files
// +- data
//   |- cases          * all use cases to be running
//     |- 1.in         * input file for case 1
//     |- 1.out        * expect output for case 1
//   |- source.js      * the source code of solution
//   |- result.json    * the result (score and outputs)

let defaultTimeout = 2000,
    datadir        = process.env.BASEDATA || '/data',
    casedir        = datadir + '/cases',
    caseInPostfix  = '.in',
    caseOutPostfix = '.out',
    final          = {score: 0, count: 0, results: [], timestamp: new Date().getTime()};

function formatDate(date) {
    let hours       = date.getHours(),
        minutes     = date.getMinutes(),
        seconds     = date.getSeconds(),
        millisecond = date.getMilliseconds();
    return `[${hours}:${minutes}:${seconds}.${millisecond}]`;
}

try {
    // clean old result
    fs.writeFileSync(datadir + '/result.json', JSON.stringify(final), 'utf8');

    let source = fs.readFileSync(datadir + '/source.js', 'utf8'),
        cases  = (files => files.map(file => path.join(casedir, file))
            .filter(file => path.extname(file) === caseInPostfix && fs.statSync(file).isFile())
            .map(file => {
                let caseId = path.basename(file, caseInPostfix);
                return {
                    id    : parseInt(caseId, 10),
                    input : readFileContent(file),
                    expect: readExpectFile(caseId)
                };
            })
            .sort((cs1, cs2) => cs1.id - cs2.id))(fs.readdirSync(casedir));

    runCaseAsync(cases, source, () => {
        process.stdout.write(`${formatDate(new Date())} calc final score, write result to file\n`);
        final.score = final.count * final.count;
        fs.writeFileSync(datadir + '/result.json', JSON.stringify(final), 'utf8');
    });
} catch (any) {
    process.stderr.write(`${formatDate(new Date())} Internal error: ${any} \n`);
    return;
}

function runCaseAsync(cases, source, next) {
    let cs   = cases.shift(),
        csId = cs.id;
    process.stdout.write(`${formatDate(new Date())} run case [id: ${csId}], left ${cases.length} in pending\n`);
    new Sandbox({timeout: defaultTimeout})
        .run(source + '; __proc__("' + cs.input.replace(/\n/g, '\\n') + '");',
            output => {
                output.id    = csId;
                let expected = cs.expect,
                    actual   = output.result;
                process.stdout.write(`${formatDate(new Date())} comparing expected and actual for case [id: ${csId}]: \n`);
                process.stdout.write(`${formatDate(new Date())} expected=${expected}\n`);
                process.stdout.write(`${formatDate(new Date())} actual  =${actual}\n`);
                // first compare all original output
                if (expected !== actual) {
                    // second deep trim all blank and newline
                    expected = deepTrim(expected);
                    actual   = deepTrim(actual);

                    if (expected !== actual) {
                        // third wrap data if result is string
                        expected = util.inspect(cs.expect);
                        actual   = output.result;

                        if (expected !== actual) {
                            // fourth deep trim again
                            expected = deepTrim(expected);
                            actual   = deepTrim(actual);
                        }
                    }
                }
                if (expected === actual) {
                    output.passed = true;
                    final.count += 1;
                }
                final.results[csId - 1] = output;

                if (cases.length > 0) {
                    runCaseAsync(cases, source, next);
                } else {
                    next();
                }
            });
}

function readFileContent(file) {
    return fs.readFileSync(file, 'utf8');
}

function readExpectFile(caseId) {
    return readFileContent(path.join(casedir, caseId + caseOutPostfix));
}

function deepTrim(realString) {
    realString       = realString.trim();
    let resultString = '', lastChar = '';
    for (let i = 0; i < realString.length; i++) {
        let currentChar = realString[i];
        if ((lastChar === ' ' || lastChar === '\u00A0') &&
            (currentChar === ' ' || currentChar === '\u00A0')) {
            continue;
        }
        resultString += currentChar;
        lastChar = currentChar;
    }
    return resultString;
}<commit_msg>fix timeout option is not applied into execution<commit_after>let fs      = require('fs'),
    path    = require('path'),
    util    = require('util'),
    Sandbox = require("sandbox");

// With following assume, [data] folder will place all data files
// +- data
//   |- cases          * all use cases to be running
//     |- 1.in         * input file for case 1
//     |- 1.out        * expect output for case 1
//   |- source.js      * the source code of solution
//   |- result.json    * the result (score and outputs)

let defaultTimeout = 2000,
    datadir        = process.env.BASEDATA || '/data',
    casedir        = datadir + '/cases',
    caseInPostfix  = '.in',
    caseOutPostfix = '.out',
    final          = {score: 0, count: 0, results: [], timestamp: new Date().getTime()};

function formatDate(date) {
    let hours       = date.getHours(),
        minutes     = date.getMinutes(),
        seconds     = date.getSeconds(),
        millisecond = date.getMilliseconds();
    return `[${hours}:${minutes}:${seconds}.${millisecond}]`;
}

try {
    // clean old result
    fs.writeFileSync(datadir + '/result.json', JSON.stringify(final), 'utf8');

    let source = fs.readFileSync(datadir + '/source.js', 'utf8'),
        cases  = (files => files.map(file => path.join(casedir, file))
            .filter(file => path.extname(file) === caseInPostfix && fs.statSync(file).isFile())
            .map(file => {
                let caseId = path.basename(file, caseInPostfix);
                return {
                    id    : parseInt(caseId, 10),
                    input : readFileContent(file),
                    expect: readExpectFile(caseId)
                };
            })
            .sort((cs1, cs2) => cs1.id - cs2.id))(fs.readdirSync(casedir));

    runCaseAsync(cases, source, () => {
        process.stdout.write(`${formatDate(new Date())} calc final score, write result to file\n`);
        final.score = final.count * final.count;
        fs.writeFileSync(datadir + '/result.json', JSON.stringify(final), 'utf8');
    });
} catch (any) {
    process.stderr.write(`${formatDate(new Date())} Internal error: ${any} \n`);
    return;
}

function runCaseAsync(cases, source, next) {
    let cs   = cases.shift(),
        csId = cs.id;
    process.stdout.write(`${formatDate(new Date())} run case [id: ${csId}], left ${cases.length} in pending\n`);
    let sb     = new Sandbox();
    sb.timeout = defaultTimeout;
    sb.run(source + '; __proc__("' + cs.input.replace(/\n/g, '\\n') + '");',
        output => {
            output.id    = csId;
            let expected = cs.expect,
                actual   = output.result;
            process.stdout.write(`${formatDate(new Date())} comparing expected and actual for case [id: ${csId}]: \n`);
            process.stdout.write(`${formatDate(new Date())} expected=${expected}\n`);
            process.stdout.write(`${formatDate(new Date())} actual  =${actual}\n`);
            // first compare all original output
            if (expected !== actual) {
                // second deep trim all blank and newline
                expected = deepTrim(expected);
                actual   = deepTrim(actual);

                if (expected !== actual) {
                    // third wrap data if result is string
                    expected = util.inspect(cs.expect);
                    actual   = output.result;

                    if (expected !== actual) {
                        // fourth deep trim again
                        expected = deepTrim(expected);
                        actual   = deepTrim(actual);
                    }
                }
            }
            if (expected === actual) {
                output.passed = true;
                final.count += 1;
            }
            final.results[csId - 1] = output;

            if (cases.length > 0) {
                runCaseAsync(cases, source, next);
            } else {
                next();
            }
        });
}

function readFileContent(file) {
    return fs.readFileSync(file, 'utf8');
}

function readExpectFile(caseId) {
    return readFileContent(path.join(casedir, caseId + caseOutPostfix));
}

function deepTrim(realString) {
    realString       = realString.trim();
    let resultString = '', lastChar = '';
    for (let i = 0; i < realString.length; i++) {
        let currentChar = realString[i];
        if ((lastChar === ' ' || lastChar === '\u00A0') &&
            (currentChar === ' ' || currentChar === '\u00A0')) {
            continue;
        }
        resultString += currentChar;
        lastChar = currentChar;
    }
    return resultString;
}<|endoftext|>


<commit_before>"use strict";

var generic_document_app      = require('./generic_document'),
    _                         = require('underscore');

module.exports = function () {

  var opts = {
    model_name:            'Person',
    template_dir:          'person',
    template_object_name:  'person',
    template_objects_name: 'people',
    url_root:              '/persons',
  };

  var app = generic_document_app(opts);

  app.routes.get = _.reject(
    app.routes.get,
    function (route) { return route.path === '/:id(*)'; }
  );

  app.get(
    '/new',
    function(req,res) {
        var Person = req.popit.model( opts.model_name );
        res.locals[opts.template_object_name] = new Person();
        res.render( opts.template_dir + '/new.html' );
    }
  );

  app.get(
    '/:id(*)',
    function (req, res, next) {
      res
        .locals[opts.template_object_name]
        .find_memberships()
        .populate('organization_id')
        .populate('post_id')
        .exec(function(err, memberships) {
          res.locals.memberships = memberships;
          next(err);
        });
    },
    function(req,res) {
      res.render( opts.template_dir + '/view.html' );
    }
  );

  return app;
};
<commit_msg>Populate persons party before rendering template<commit_after>"use strict";

var generic_document_app      = require('./generic_document'),
    _                         = require('underscore');

module.exports = function () {

  var opts = {
    model_name:            'Person',
    template_dir:          'person',
    template_object_name:  'person',
    template_objects_name: 'people',
    url_root:              '/persons',
  };

  var app = generic_document_app(opts);

  app.routes.get = _.reject(
    app.routes.get,
    function (route) { return route.path === '/:id(*)'; }
  );

  app.get(
    '/new',
    function(req,res) {
        var Person = req.popit.model( opts.model_name );
        res.locals[opts.template_object_name] = new Person();
        res.render( opts.template_dir + '/new.html' );
    }
  );

  app.get(
    '/:id(*)',
    function (req, res, next) {
      res
        .locals[opts.template_object_name]
        .find_memberships()
        .populate('organization_id')
        .populate('post_id')
        .exec(function(err, memberships) {
          res.locals.memberships = memberships;
          next(err);
        });
    },
    function (req, res, next) {
      // Find the primary party for this person.
      var Membership = req.popit.model('Membership');
      Membership.findOne({person_id: req.param('id'), _primary: true})
        .populate('organization_id')
        .exec(function(err, membership) {
          if (err) {
            return next(err);
          }
          if (membership) {
            res.locals[opts.template_object_name].party = membership.organization_id.name;
          }
          next();
        });
    },
    function(req,res) {
      res.render( opts.template_dir + '/view.html' );
    }
  );

  return app;
};
<|endoftext|>


<commit_before>var Subscriber, AtomJshint;
var cp = require('child_process');
var _ = require('underscore-plus');
var JSHINT_Worker = null;

var Subscriber = require('emissary').Subscriber;
var fs = require('fs');
var path = require('path');

module.exports = AtomJshint = (function(){
  JSHINT_Worker = cp.fork(__dirname + '/worker.js');
  process.on('exit', function() {
    JSHINT_Worker.kill();
  });
  var $ = require('atom').$;
  function AtomJsHint(){
    atom.workspace.eachEditor((function(self) {
      return function(editor) {
        return self.handleEvents(editor);
      };
    })(this));
    this.subscribe(atom.workspaceView, 'pane-container:active-pane-item-changed', function(event,editor){
      this.run(editor);
    }.bind(this));
    this.config = {globals:{},options:{}};
    this.loadConfig();
  }
  Subscriber.includeInto(AtomJsHint);

  AtomJsHint.prototype.destroy = function(){
    return this.unsubscribe();
  };

  AtomJsHint.prototype.handleEvents = function(editor) {
    var buffer = editor.getBuffer();
    var listenFor = [];
    if( atom.config.get('atom-jshint.hintOnModify') ){ listenFor.push('contents-modified'); }
    if( atom.config.get('atom-jshint.hintOnSave') ) { listenFor.push('saved'); }

    this.subscribe(buffer, listenFor.join(' '), (function(self) {
      return _.debounce(function() {
        self.run(editor);
      },50);
    })(this));
    this.subscribe(buffer, 'destroyed', (function(self) {
      return function() {
        return self.unsubscribe(buffer);
      };
    })(this));
  };

  AtomJsHint.prototype.run = function(editor){
    var self = this;
    var text = this.getContents();
    if( !text ) {
      this.resetState(editor);
      return;
    }

    var cb = function (jsHintErrors) {
      JSHINT_Worker.removeListener('message', cb);
      if(jsHintErrors.length === 0) {
        self.resetState(editor);
      }
      if( editor.cursors[0] ){
        self.updateStatus(jsHintErrors, editor.cursors[0].getBufferRow());
      }
      self.updateGutter(jsHintErrors);
      self.updatePane(jsHintErrors);
      self.subscribe(atom.workspaceView, 'cursor:moved', function () {
        if( editor.cursors[0] ){
          self.updateStatus(jsHintErrors, editor.cursors[0].getBufferRow());
        }
      });
      self.subscribe(editor, 'scroll-top-changed', function () {
        self.updateGutter(jsHintErrors);
      });
    };
    JSHINT_Worker.on('message', cb);

    JSHINT_Worker.send({
      method: 'run',
      text:text,
      options: this.config.options,
      config: this.config.globals
    });
  };

  AtomJsHint.prototype.resetState = function(editor){
    this.updateStatus(false);
    this.updateGutter([]);
    this.updatePane([]);
    atom.workspaceView.off('cursor:moved');
    this.unsubscribe(editor);
  };

  AtomJsHint.prototype.updatePane = function(errors){
    $('#jshint-status-pane').remove();
    if( !errors || !atom.config.get('atom-jshint.showErrorPanel') ) return;
    var html = $('
');
    errors.forEach(function(error){
      html.append('Line: ' + error.line + ' Char:' + error.character + ' ' + error.reason);
      html.append('
');
    });
    atom.workspaceView.prependToBottom(html);
  };

  AtomJsHint.prototype.updateGutter = function(errors){
    atom.workspaceView.eachEditorView(function(editorView){
      if (editorView.active) {
        var gutter = editorView.gutter;
        gutter.removeClassFromAllLines('atom-jshint-error');
        errors.forEach(function(error){
          gutter.addClassToLine(error.line - 1, 'atom-jshint-error');
        });
      }
    });
  };

  AtomJsHint.prototype.updateStatus = function(errors, row){
    var status = document.getElementById('jshint-status');
    var msg = '';
    if( status ) status.parentElement.removeChild(status);
    if( !errors ) return;
    if (row >= 0) {
      var lineErrors = errors.filter(function (error) {
        return error.line === row + 1;
      });
      if (lineErrors.length > 0) {
        msg = 'Error: ' + lineErrors[0].line + ':' + lineErrors[0].character + ' ' + lineErrors[0].reason;
      } else {
        msg = errors.length > 0 ? errors.length + ' JSHint error' + (errors.length>1?'s':'') : '';
      }
      atom.workspaceView.statusBar.appendLeft('' + msg + '');
    }
  };

  AtomJsHint.prototype.getContents = function(){
    if( !atom.workspace.activePaneItem ) return false;
    var grammar = atom.workspace.activePaneItem.getGrammar();
    if (!grammar || grammar.name !== 'JavaScript') return false;
    var text = atom.workspace.activePaneItem.getText();
    if( !text ) return false;
    return text;
  };

  AtomJsHint.prototype.loadConfig = function(){
    if( fs.existsSync(atom.project.path + '/package.json') ){
      var packageJson = require(atom.project.path + '/package.json');
      if( packageJson.jshintConfig ) {
        return this.setConfig(packageJson.jshintConfig);
      }
    }
    var workingPath = atom.project.path || '';
    var dirs = workingPath.split(path.sep);
    while ( dirs.length >= 1 ) {
      var configPath = path.join(dirs.join(path.sep), '/.jshintrc');
      if( fs.existsSync(configPath) ){
        var configFile = fs.readFileSync(configPath, 'UTF8');
        var conf = {};
        try {
          conf = JSON.parse(configFile);
        } catch(e){
          console.error('error parsing config file');
        }
        return this.setConfig(conf);
      }
      dirs.pop();
    }
  };

  AtomJsHint.prototype.setConfig = function(conf){
    var config = {globals:{},options:{}};
    config.globals = conf.globals || {};
    if( conf.global ) { delete conf.globals; }
    config.options = conf;
    this.config = config;
  };

  return AtomJsHint;

})();
<commit_msg>Load config on demand by searching the tree for the closest .jshintrc to the open file<commit_after>var Subscriber, AtomJshint;
var cp = require('child_process');
var _ = require('underscore-plus');
var JSHINT_Worker = null;

var Subscriber = require('emissary').Subscriber;
var fs = require('fs');
var path = require('path');

module.exports = AtomJshint = (function(){
  JSHINT_Worker = cp.fork(__dirname + '/worker.js');
  process.on('exit', function() {
    JSHINT_Worker.kill();
  });
  var $ = require('atom').$;
  function AtomJsHint(){
    this.configs = {};
    this.npmConfig = this.loadNpmConfig();
    atom.workspace.eachEditor((function(self) {
      return function(editor) {
        return self.handleEvents(editor);
      };
    })(this));
    this.subscribe(atom.workspaceView, 'pane-container:active-pane-item-changed', function(event,editor){
      this.run(editor);
    }.bind(this));
  }
  Subscriber.includeInto(AtomJsHint);

  AtomJsHint.prototype.destroy = function(){
    return this.unsubscribe();
  };

  AtomJsHint.prototype.handleEvents = function(editor) {
    var buffer = editor.getBuffer();
    var listenFor = [];
    if( atom.config.get('atom-jshint.hintOnModify') ){ listenFor.push('contents-modified'); }
    if( atom.config.get('atom-jshint.hintOnSave') ) { listenFor.push('saved'); }

    this.subscribe(buffer, listenFor.join(' '), (function(self) {
      return _.debounce(function() {
        self.run(editor);
      },50);
    })(this));
    this.subscribe(buffer, 'destroyed', (function(self) {
      return function() {
        return self.unsubscribe(buffer);
      };
    })(this));
  };

  AtomJsHint.prototype.run = function(editor){
    var self = this;
    var text = this.getContents();
    if( !text ) {
      this.resetState(editor);
      return;
    }

    var cb = function (jsHintErrors) {
      JSHINT_Worker.removeListener('message', cb);
      if(jsHintErrors.length === 0) {
        self.resetState(editor);
      }
      if( editor.cursors[0] ){
        self.updateStatus(jsHintErrors, editor.cursors[0].getBufferRow());
      }
      self.updateGutter(jsHintErrors);
      self.updatePane(jsHintErrors);
      self.subscribe(atom.workspaceView, 'cursor:moved', function () {
        if( editor.cursors[0] ){
          self.updateStatus(jsHintErrors, editor.cursors[0].getBufferRow());
        }
      });
      self.subscribe(editor, 'scroll-top-changed', function () {
        self.updateGutter(jsHintErrors);
      });
    };
    JSHINT_Worker.on('message', cb);

    var config = this.loadConfig(editor.getPath());

    JSHINT_Worker.send({
      method: 'run',
      text:text,
      options: config.options,
      config: config.globals
    });
  };

  AtomJsHint.prototype.resetState = function(editor){
    this.updateStatus(false);
    this.updateGutter([]);
    this.updatePane([]);
    atom.workspaceView.off('cursor:moved');
    this.unsubscribe(editor);
  };

  AtomJsHint.prototype.updatePane = function(errors){
    $('#jshint-status-pane').remove();
    if( !errors || !atom.config.get('atom-jshint.showErrorPanel') ) return;
    var html = $('
');
    errors.forEach(function(error){
      html.append('Line: ' + error.line + ' Char:' + error.character + ' ' + error.reason);
      html.append('
');
    });
    atom.workspaceView.prependToBottom(html);
  };

  AtomJsHint.prototype.updateGutter = function(errors){
    atom.workspaceView.eachEditorView(function(editorView){
      if (editorView.active) {
        var gutter = editorView.gutter;
        gutter.removeClassFromAllLines('atom-jshint-error');
        errors.forEach(function(error){
          gutter.addClassToLine(error.line - 1, 'atom-jshint-error');
        });
      }
    });
  };

  AtomJsHint.prototype.updateStatus = function(errors, row){
    var status = document.getElementById('jshint-status');
    var msg = '';
    if( status ) status.parentElement.removeChild(status);
    if( !errors ) return;
    if (row >= 0) {
      var lineErrors = errors.filter(function (error) {
        return error.line === row + 1;
      });
      if (lineErrors.length > 0) {
        msg = 'Error: ' + lineErrors[0].line + ':' + lineErrors[0].character + ' ' + lineErrors[0].reason;
      } else {
        msg = errors.length > 0 ? errors.length + ' JSHint error' + (errors.length>1?'s':'') : '';
      }
      atom.workspaceView.statusBar.appendLeft('' + msg + '');
    }
  };

  AtomJsHint.prototype.getContents = function(){
    if( !atom.workspace.activePaneItem ) return false;
    var grammar = atom.workspace.activePaneItem.getGrammar();
    if (!grammar || grammar.name !== 'JavaScript') return false;
    var text = atom.workspace.activePaneItem.getText();
    if( !text ) return false;
    return text;
  };

  AtomJsHint.prototype.loadNpmConfig = function(){
    if( fs.existsSync(atom.project.path + '/package.json') ){
      var packageJson = require(atom.project.path + '/package.json');
      if( packageJson.jshintConfig ) {
        return this.getConfigMessage(packageJson.jshintConfig);
      }
    }
  };

  AtomJsHint.prototype.loadConfig = function(filePath){
    if (this.npmConfig) {
      return this.npmConfig;
    }
    var workingPath = filePath || '';
    var dirs = workingPath.split(path.sep);
    dirs.pop();
    var fileDir = dirs.join(path.sep);
    while ( dirs.length >= 1 ) {
      var dir = dirs.join(path.sep);
      if (this.configs[dir]){
        this.configs[fileDir] = this.configs[dir];
        return this.configs[dir];
      }
      var configPath = path.join(dir, '/.jshintrc');
      if( fs.existsSync(configPath) ){
        var configFile = fs.readFileSync(configPath, 'UTF8');
        var conf = {};
        try {
          conf = JSON.parse(configFile);
        } catch(e){
          console.error('error parsing config file');
        }
        var configMessage = this.getConfigMessage(conf);
        this.configs[fileDir] = configMessage;
        this.configs[dir] = configMessage;
        return configMessage;
      }
      dirs.pop();
    }
  };

  AtomJsHint.prototype.getConfigMessage = function(conf){
    var config = {globals:{},options:{}};
    config.globals = conf.globals || {};
    if( conf.globals ) { delete conf.globals; }
    config.options = conf;
    return config;
  };

  return AtomJsHint;

})();
<|endoftext|>


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

var express = require('express');
var app = express();
var speak = require('./controllers/speak');
var listen = require('./controllers/listen');
var joke = require('./controllers/joke');
var sentences = require('./data/sentences');

// setup API and client
app.use('/', express.static(__dirname + '/public'));

var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
	extended: true
}));

app.get('/api/ping', function (req, res) {
	res.send(speak.isSpeaking());
});

app.listen(3000, function () {
  console.log('MrRobot has started on port 3000');
});

// start listening
listen({

	joke: joke,

	fun: function () {
		speak.say('Comme ma bite');
	}

});

setTimeout(function() {
	// say startup fun
	speak.say(sentences.getStartup());
}, 6000);
<commit_msg>pouet<commit_after>#!/usr/bin/env node
'use strict';

var express = require('express');
var app = express();
var speak = require('./controllers/speak');
var listen = require('./controllers/listen');
var joke = require('./controllers/joke');
var sentences = require('./data/sentences');

// setup API and client
app.use('/', express.static(__dirname + '/public'));

var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
	extended: true
}));

app.get('/api/ping', function (req, res) {
	res.send(speak.isSpeaking());
});

app.listen(3000, function () {
  console.log('MrRobot has started on port 3000');
});

// start listening
listen({

	joke: joke,

	fun: function () {
		speak.say('Comme ma bite');
	}

});

setTimeout(function() {
	// say startup fun
	speak.say(sentences.getStartup());
}, 10000);
<|endoftext|>


<commit_before>'use strict';

const { resolve } = require('path');
const commander = require('commander');
const { checkInstallPath, generateNewApp } = require('@strapi/generate-new');
const promptUser = require('./utils/prompt-user');
const packageJson = require('./package.json');

const program = new commander.Command(packageJson.name);

const databaseOptions = [
  'dbclient',
  'dbhost',
  'dbport',
  'dbname',
  'dbusername',
  'dbpassword',
  'dbssl',
  'dbfile',
];

program
  .version(packageJson.version)
  .arguments('[directory]')
  .option('--no-run', 'Do not start the application after it is created')
  .option('--use-npm', 'Force usage of npm instead of yarn to create the project')
  .option('--debug', 'Display database connection error')
  .option('--quickstart', 'Quickstart app creation')
  .option('--dbclient <dbclient>', 'Database client')
  .option('--dbhost <dbhost>', 'Database host')
  .option('--dbport <dbport>', 'Database port')
  .option('--dbname <dbname>', 'Database name')
  .option('--dbusername <dbusername>', 'Database username')
  .option('--dbpassword <dbpassword>', 'Database password')
  .option('--dbssl <dbssl>', 'Database SSL')
  .option('--dbfile <dbfile>', 'Database file path for sqlite')
  .option('--dbforce', 'Overwrite database content if any')
  .option('--template <templateurl>', 'Specify a Strapi template')
  .description('create a new application')
  .action(directory => {
    initProject(directory, program);
  })
  .parse(process.argv);

function generateApp(projectName, options) {
  if (!projectName) {
    console.error('Please specify the <directory> of your project when using --quickstart');
    process.exit(1);
  }

  return generateNewApp(projectName, options).then(() => {
    if (process.platform === 'win32') {
      process.exit(0);
    }
  });
}

async function initProject(projectName, program) {
  if (projectName) await checkInstallPath(resolve(projectName));

  const hasDatabaseOptions = databaseOptions.some(opt => program[opt]);

  if (program.quickstart && hasDatabaseOptions) {
    console.error(
      `The quickstart option is incompatible with the following options: ${databaseOptions.join(
        ', '
      )}`
    );
    process.exit(1);
  }

  if (hasDatabaseOptions) {
    program.quickstart = false; // Will disable the quickstart question because != 'undefined'
  }

  if (program.quickstart) {
    return generateApp(projectName, program);
  }

  const prompt = await promptUser(projectName, program);

  const directory = prompt.directory || projectName;
  checkInstallPath(resolve(directory));

  const options = {
    template: program.template,
    quickstart: prompt.quick || program.quickstart,
  };

  const generateStrapiAppOptions = {
    ...program,
    ...options,
  };

  return generateApp(directory, generateStrapiAppOptions);
}
<commit_msg>fix: added missing await<commit_after>'use strict';

const { resolve } = require('path');
const commander = require('commander');
const { checkInstallPath, generateNewApp } = require('@strapi/generate-new');
const promptUser = require('./utils/prompt-user');
const packageJson = require('./package.json');

const program = new commander.Command(packageJson.name);

const databaseOptions = [
  'dbclient',
  'dbhost',
  'dbport',
  'dbname',
  'dbusername',
  'dbpassword',
  'dbssl',
  'dbfile',
];

program
  .version(packageJson.version)
  .arguments('[directory]')
  .option('--no-run', 'Do not start the application after it is created')
  .option('--use-npm', 'Force usage of npm instead of yarn to create the project')
  .option('--debug', 'Display database connection error')
  .option('--quickstart', 'Quickstart app creation')
  .option('--dbclient <dbclient>', 'Database client')
  .option('--dbhost <dbhost>', 'Database host')
  .option('--dbport <dbport>', 'Database port')
  .option('--dbname <dbname>', 'Database name')
  .option('--dbusername <dbusername>', 'Database username')
  .option('--dbpassword <dbpassword>', 'Database password')
  .option('--dbssl <dbssl>', 'Database SSL')
  .option('--dbfile <dbfile>', 'Database file path for sqlite')
  .option('--dbforce', 'Overwrite database content if any')
  .option('--template <templateurl>', 'Specify a Strapi template')
  .description('create a new application')
  .action(directory => {
    initProject(directory, program);
  })
  .parse(process.argv);

function generateApp(projectName, options) {
  if (!projectName) {
    console.error('Please specify the <directory> of your project when using --quickstart');
    process.exit(1);
  }

  return generateNewApp(projectName, options).then(() => {
    if (process.platform === 'win32') {
      process.exit(0);
    }
  });
}

async function initProject(projectName, program) {
  if (projectName) {
    await checkInstallPath(resolve(projectName));
  }

  const hasDatabaseOptions = databaseOptions.some(opt => program[opt]);

  if (program.quickstart && hasDatabaseOptions) {
    console.error(
      `The quickstart option is incompatible with the following options: ${databaseOptions.join(
        ', '
      )}`
    );
    process.exit(1);
  }

  if (hasDatabaseOptions) {
    program.quickstart = false; // Will disable the quickstart question because != 'undefined'
  }

  if (program.quickstart) {
    return generateApp(projectName, program);
  }

  const prompt = await promptUser(projectName, program);

  const directory = prompt.directory || projectName;
  await checkInstallPath(resolve(directory));

  const options = {
    template: program.template,
    quickstart: prompt.quick || program.quickstart,
  };

  const generateStrapiAppOptions = {
    ...program,
    ...options,
  };

  return generateApp(directory, generateStrapiAppOptions);
}
<|endoftext|>


<commit_before>// # bionode-bwa
// > A Node.js wrapper for the Burrow-Wheeler Aligner (BWA).
// >
// > doi: [?](?)
// > author: [Bruno Vieira](http://bmpvieira.com)
// > email: <mail@bmpvieira.com>
// > license: [MIT](https://raw.githubusercontent.com/bionode/bionode-bwa/master/LICENSE)
//
// ---
//
// ## Usage
// This module can be used in Node.js as described further below, or as a command line tool.
// Check https://github.com/lh3/bwa for a list of parameters that can be passed to bwa.
// Examples:
//
//     $ npm install -g bionode-bwa
//
//     # bionode-bwa [operation] [arguments...]
//     $ bionode-bwa mem reference.fasta.gz reads.fastq.gz alignment.sam SRR1509835.bwa

var fs = require('fs')
var zlib = require('zlib')
var path = require('path')
var spawn = require('child_process').spawn
var through = require('through2')
var split = require('split')
var debug = require('debug')('bionode-bwa')

module.exports = exports = BWA

// ## BWA
// Takes a BWA operation and returns a Stream that accepts arguments for it.
// For example, for ```mem```, arguments can be a string of space separated filenames
// like ```reference.fasta reads.fastq alignment.sam``` or an array with filenames or variables
// ```[referenceFasta, 'reads.fastq', outputPath]```.
// If the output for sam is omitted, the current directory will be used.
//
//     var bwa = require('bionode-bwa')
//     var mem = bwa('mem')
//     mem('ref.fasta.gz, reads.fastq.gz')
//     .on('data', console.log)
//     => { operation: 'mem',
//          status: 'processing',
//          reference: 'reference.fasta.gz',
//          progress: { total: 11355, current: 0, percent: 0 },
//          sequences: [ 'reads.fastq.gz' ],
//          sam: 'reads.sam' }
//        [...]
//        { operation: 'mem',
//          status: 'finished',
//          reference: 'reference.fasta.gz',
//          progress: { total: 11355, current: 11355, percent: 100 },
//          sequences: [ 'reads.fastq.gz' ],
//          sam: 'reads.sam' }
//
// A callback style can also be used:
//
//     var mem = bwa('mem -x pacbio')
//     mem([ref, reads, alignment], function(err, data) {
//       console.log(data)
//     })
//     => { operation: 'mem',
//          status: 'finished',
//          reference: 'reference.fasta.gz',
//          progress: { total: 11355, current: 11355, percent: 100 },
//          sequences: [ 'reads.fastq.gz' ],
//          sam: 'alignment.sam' }
//
// Or pipes, for example, from a file with just a list of string like ```reference.fasta reads.fastq alignment.sam``` .
//
//     var split = require('split')
//     var mem = bwa() // when operation is omitted, 'mem' is used as default
//     fs.createReadStream('filenamesList.txt')
//     .pipe(split())
//     .pipe(mem())
//     .on('data', console.log)

function BWA(args) {
  var args = args || 'mem'
  var bwaPath = path.join(__dirname, '../bwa/bwa')

  return bwaStream

  function bwaStream(params, callback) {
    var stream = through.obj(transform)
    if (params) { stream.write(params); stream.end() }
    if (callback) {
      var result
      stream.on('data', function(data) {
        result = data
      })
      stream.on('end', function() {
        callback(null, result)
      })
      stream.on('error', callback)
    }
    return stream

    function transform(obj, enc, next) {
      var self = this

      if (typeof obj === 'string') { obj = obj.split(' ') }

      if (obj[0] === '') { return next() }

      if (obj.length > 4) { self.emit('error', new Error('Too many arguments')); next() }

      var options = args.split(' ')
      var operation = options[0]

      var reference
      var sequences = []
      var sam
      var sai
      obj.forEach(function(filename) {
        var filenameLC = filename.toLowerCase()
        if (filenameLC.match(/\.(fasta|fa$|fa.gz$)/)) { reference = filename }
        else if (filenameLC.match(/\.(fastq|fq$|fq.gz$)/)) { sequences.push(filename) }
        else if (filenameLC.match(/\.(sam)/)) { sam = filename }
        else if (filenameLC.match(/\.(sai)/)) { sai = filename }
      })
      if (!sai && operation === 'aln') { sai =  sequences[0].replace(/\.(fast|fq|fa).*/, '.sai')}
      if (!sam && operation !== 'aln') { sam =  sequences[0].replace(/\.(fast|fq|fa).*/, '.sam')}

      var log = {
        operation: operation,
        status: 'processing',
        reference: reference
      }
      if (['index', 'mem'].indexOf(operation) !== -1) {
        log.progress = { total: 0, current: 0, percent: 0 }
      }

      fs.exists(reference + '.bwt', gotReferenceIndexExists)
      function gotReferenceIndexExists(exists) {
        if (!exists) {
          log.operation = 'index'
          var bwa = spawn(bwaPath, ['index', reference])

          bwa.stderr.on('data', function(data) {
            debug('bwa index', data.toString())
            if (['index', 'mem'].indexOf(operation) !== -1) {
              log.progress = logging('index', log.progress, data)
            }
            self.push(log)
          })

          bwa.on('close', function() {
            log.status = 'finished'
            self.push(log)
            alignSequences(self)
          })
        }
        else { alignSequences(self) }
      }

      function alignSequences(self) {
        var lineCount = through()
        var linesCounter = 0
        sequences.forEach(pipeLineCount)
        function pipeLineCount(sequencePath) {
          var unzip = sequencePath.match(/.gz$/) ? zlib.createGunzip() : through()
          fs.createReadStream(sequencePath)
          .pipe(unzip)
          .pipe(lineCount)
        }

        lineCount
        .pipe(split())
        .on('data', function(data) { linesCounter += 1 })
        .on('end', function() { gotLinesCount(self) })

        function gotLinesCount(self) {
          var sequencesNum = Math.round(linesCounter / 4)
          options.push(reference)
          if (sai && operation !== 'aln') { options.push(sai) }
          if (sequences) { options = options.concat(sequences) }
          if (sai && operation === 'aln') { options.push(sai) }
          debug('bwa align options', options)

          log.operation = operation
          log.sequences = sequences
          if (sam) { log.sam = sam }
          if (sai) { log.sai = sai }
          log.status = 'processing'
          if (['index', 'mem'].indexOf(operation) !== -1) {
            log.progress = { total: sequencesNum, current: 0, percent: 0 }
          }

          var bwa = spawn(bwaPath, options)

          bwa.stderr.on('data', function(data) {
            debug('bwa align', data.toString())
            if (['index', 'mem'].indexOf(operation) !== -1) {
              log.progress = logging(operation, log.progress, data)
            }
            self.push(log)
          })
          var output = operation === 'aln' ? sai : sam
          var outputFile = fs.createWriteStream(output)
          bwa.stdout.on('data', function(data) { outputFile.write(data) })

          bwa.on('close', function(code) {
            if (code) {
              self.emit('error', new Error('Unknown error, check that "'+obj[0]+'" exists'))
            }
            else {
              log.status = 'finished'
              outputFile.end()
              self.push(log)
              next()
            }
          })
        }
      }

      function logging(op, progress, data) {
        var bwaLog = data.toString()
        if (op === 'index') {
          if (bwaLog.indexOf('BWTIncCreate') !== -1) {
            progress.total = Number(bwaLog.split(', ')[0].replace('[BWTIncCreate] textLength=', ''))
          }
          if (bwaLog.indexOf('characters processed') !== -1) {
            progress.current = Number(bwaLog.split(' ')[4])
          }
        }
        else if (op === 'mem') {
          if (bwaLog.indexOf('Processed') !== -1) {
            progress.current = Number(bwaLog.split(' ')[2])
          }
        }
        if (progress.current && progress.total) {
          progress.percent = Math.round(progress.current * 100 / progress.total)
        }
        return progress
      }
    }
  }
}
<commit_msg>Add fna to extension regex for FASTA<commit_after>// # bionode-bwa
// > A Node.js wrapper for the Burrow-Wheeler Aligner (BWA).
// >
// > doi: [?](?)
// > author: [Bruno Vieira](http://bmpvieira.com)
// > email: <mail@bmpvieira.com>
// > license: [MIT](https://raw.githubusercontent.com/bionode/bionode-bwa/master/LICENSE)
//
// ---
//
// ## Usage
// This module can be used in Node.js as described further below, or as a command line tool.
// Check https://github.com/lh3/bwa for a list of parameters that can be passed to bwa.
// Examples:
//
//     $ npm install -g bionode-bwa
//
//     # bionode-bwa [operation] [arguments...]
//     $ bionode-bwa mem reference.fasta.gz reads.fastq.gz alignment.sam SRR1509835.bwa

var fs = require('fs')
var zlib = require('zlib')
var path = require('path')
var spawn = require('child_process').spawn
var through = require('through2')
var split = require('split')
var debug = require('debug')('bionode-bwa')

module.exports = exports = BWA

// ## BWA
// Takes a BWA operation and returns a Stream that accepts arguments for it.
// For example, for ```mem```, arguments can be a string of space separated filenames
// like ```reference.fasta reads.fastq alignment.sam``` or an array with filenames or variables
// ```[referenceFasta, 'reads.fastq', outputPath]```.
// If the output for sam is omitted, the current directory will be used.
//
//     var bwa = require('bionode-bwa')
//     var mem = bwa('mem')
//     mem('ref.fasta.gz, reads.fastq.gz')
//     .on('data', console.log)
//     => { operation: 'mem',
//          status: 'processing',
//          reference: 'reference.fasta.gz',
//          progress: { total: 11355, current: 0, percent: 0 },
//          sequences: [ 'reads.fastq.gz' ],
//          sam: 'reads.sam' }
//        [...]
//        { operation: 'mem',
//          status: 'finished',
//          reference: 'reference.fasta.gz',
//          progress: { total: 11355, current: 11355, percent: 100 },
//          sequences: [ 'reads.fastq.gz' ],
//          sam: 'reads.sam' }
//
// A callback style can also be used:
//
//     var mem = bwa('mem -x pacbio')
//     mem([ref, reads, alignment], function(err, data) {
//       console.log(data)
//     })
//     => { operation: 'mem',
//          status: 'finished',
//          reference: 'reference.fasta.gz',
//          progress: { total: 11355, current: 11355, percent: 100 },
//          sequences: [ 'reads.fastq.gz' ],
//          sam: 'alignment.sam' }
//
// Or pipes, for example, from a file with just a list of string like ```reference.fasta reads.fastq alignment.sam``` .
//
//     var split = require('split')
//     var mem = bwa() // when operation is omitted, 'mem' is used as default
//     fs.createReadStream('filenamesList.txt')
//     .pipe(split())
//     .pipe(mem())
//     .on('data', console.log)

function BWA(args) {
  var args = args || 'mem'
  var bwaPath = path.join(__dirname, '../bwa/bwa')

  return bwaStream

  function bwaStream(params, callback) {
    var stream = through.obj(transform)
    if (params) { stream.write(params); stream.end() }
    if (callback) {
      var result
      stream.on('data', function(data) {
        result = data
      })
      stream.on('end', function() {
        callback(null, result)
      })
      stream.on('error', callback)
    }
    return stream

    function transform(obj, enc, next) {
      var self = this

      if (typeof obj === 'string') { obj = obj.split(' ') }

      if (obj[0] === '') { return next() }

      if (obj.length > 4) { self.emit('error', new Error('Too many arguments')); next() }

      var options = args.split(' ')
      var operation = options[0]

      var reference
      var sequences = []
      var sam
      var sai
      obj.forEach(function(filename) {
        var filenameLC = filename.toLowerCase()
        if (filenameLC.match(/\.(fasta|fa$|fa.gz$|fna$|fna.gz$)/)) { reference = filename }
        else if (filenameLC.match(/\.(fastq|fq$|fq.gz$)/)) { sequences.push(filename) }
        else if (filenameLC.match(/\.(sam)/)) { sam = filename }
        else if (filenameLC.match(/\.(sai)/)) { sai = filename }
      })
      if (!sai && operation === 'aln') { sai =  sequences[0].replace(/\.(fast|fq|fa).*/, '.sai')}
      if (!sam && operation !== 'aln') { sam =  sequences[0].replace(/\.(fast|fq|fa).*/, '.sam')}

      var log = {
        operation: operation,
        status: 'processing',
        reference: reference
      }
      if (['index', 'mem'].indexOf(operation) !== -1) {
        log.progress = { total: 0, current: 0, percent: 0 }
      }

      fs.exists(reference + '.bwt', gotReferenceIndexExists)
      function gotReferenceIndexExists(exists) {
        if (!exists) {
          log.operation = 'index'
          var bwa = spawn(bwaPath, ['index', reference])

          bwa.stderr.on('data', function(data) {
            debug('bwa index', data.toString())
            if (['index', 'mem'].indexOf(operation) !== -1) {
              log.progress = logging('index', log.progress, data)
            }
            self.push(log)
          })

          bwa.on('close', function() {
            log.status = 'finished'
            self.push(log)
            alignSequences(self)
          })
        }
        else { alignSequences(self) }
      }

      function alignSequences(self) {
        var lineCount = through()
        var linesCounter = 0
        sequences.forEach(pipeLineCount)
        function pipeLineCount(sequencePath) {
          var unzip = sequencePath.match(/.gz$/) ? zlib.createGunzip() : through()
          fs.createReadStream(sequencePath)
          .pipe(unzip)
          .pipe(lineCount)
        }

        lineCount
        .pipe(split())
        .on('data', function(data) { linesCounter += 1 })
        .on('end', function() { gotLinesCount(self) })

        function gotLinesCount(self) {
          var sequencesNum = Math.round(linesCounter / 4)
          options.push(reference)
          if (sai && operation !== 'aln') { options.push(sai) }
          if (sequences) { options = options.concat(sequences) }
          if (sai && operation === 'aln') { options.push(sai) }
          debug('bwa align options', options)

          log.operation = operation
          log.sequences = sequences
          if (sam) { log.sam = sam }
          if (sai) { log.sai = sai }
          log.status = 'processing'
          if (['index', 'mem'].indexOf(operation) !== -1) {
            log.progress = { total: sequencesNum, current: 0, percent: 0 }
          }

          var bwa = spawn(bwaPath, options)

          bwa.stderr.on('data', function(data) {
            debug('bwa align', data.toString())
            if (['index', 'mem'].indexOf(operation) !== -1) {
              log.progress = logging(operation, log.progress, data)
            }
            self.push(log)
          })
          var output = operation === 'aln' ? sai : sam
          var outputFile = fs.createWriteStream(output)
          bwa.stdout.on('data', function(data) { outputFile.write(data) })

          bwa.on('close', function(code) {
            if (code) {
              self.emit('error', new Error('Unknown error, check that "'+obj[0]+'" exists'))
            }
            else {
              log.status = 'finished'
              outputFile.end()
              self.push(log)
              next()
            }
          })
        }
      }

      function logging(op, progress, data) {
        var bwaLog = data.toString()
        if (op === 'index') {
          if (bwaLog.indexOf('BWTIncCreate') !== -1) {
            progress.total = Number(bwaLog.split(', ')[0].replace('[BWTIncCreate] textLength=', ''))
          }
          if (bwaLog.indexOf('characters processed') !== -1) {
            progress.current = Number(bwaLog.split(' ')[4])
          }
        }
        else if (op === 'mem') {
          if (bwaLog.indexOf('Processed') !== -1) {
            progress.current = Number(bwaLog.split(' ')[2])
          }
        }
        if (progress.current && progress.total) {
          progress.percent = Math.round(progress.current * 100 / progress.total)
        }
        return progress
      }
    }
  }
}
<|endoftext|>


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

function Blockchain(block) {
    var self = this;
    var blocks = [block];
    var blockstore = stores.blockstore();
    blockstore.save(block);

    this.bestBlock = function () { return blocks[blocks.length - 1]; }

    this.add = function (block) {
        if (blockstore.hasBlockHash(block.hash))
            return;

        blockstore.save(block);

        if (isBestBlockChild(block))
            blocks.push(block);

        if (isBetterBestBlock(block))
            tryFork(block);
    }

    function isBestBlockChild(block) {
        var bblock = self.bestBlock();

        return bblock.hash === block.parentHash && bblock.number === block.number - 1;
    }

    function isBetterBestBlock(block) {
        var bblock = self.bestBlock();

        return bblock.number < block.number;
    }

    function tryFork(block) {
        var newbranch = [block];
        var parentHash = block.parentHash;

        while (parentHash && blockstore.hasBlockHash(parentHash)) {
            var parent = blockstore.getByHash(parentHash);

            if (parent.hash === blocks[parent.number].hash)
                return switchToFork(newbranch);

            newbranch.push(parent);

            parentHash = parent.parentHash;
        }
    }

    function getDescendants(block) {
        var children = getChildren(block);

        if (children.length == 0)
            return children;

        var descendants = []

        for (var n in children) {
            var child = children[n];
            descendants = descendants.concat(getChildren(child));
        }
    }

    function switchToFork(newbranch) {
        for (var n = newbranch.length; n-- > 0;) {
            var block = newbranch[n];
            blocks[block.number] = block;
        }
    }
}

function createBlockchain(block) {
    return new Blockchain(block);
}

module.exports = {
    blockchain: createBlockchain
}

<commit_msg>Refactor blockchain add block<commit_after>
var stores = require('./stores');

function Blockchain(block) {
    var self = this;
    var blocks = [block];
    var blockstore = stores.blockstore();
    blockstore.save(block);

    this.bestBlock = function () { return blocks[blocks.length - 1]; }

    this.add = function (block) {
        if (blockstore.hasBlockHash(block.hash))
            return;

        blockstore.save(block);

        tryAdd(block);
    }

    function tryAdd(block) {
        if (isBestBlockChild(block))
            blocks.push(block);

        if (isBetterBestBlock(block))
            tryFork(block);
    }

    function isBestBlockChild(block) {
        var bblock = self.bestBlock();

        return bblock.hash === block.parentHash && bblock.number === block.number - 1;
    }

    function isBetterBestBlock(block) {
        var bblock = self.bestBlock();

        return bblock.number < block.number;
    }

    function tryFork(block) {
        var newbranch = [block];
        var parentHash = block.parentHash;

        while (parentHash && blockstore.hasBlockHash(parentHash)) {
            var parent = blockstore.getByHash(parentHash);

            if (parent.hash === blocks[parent.number].hash)
                return switchToFork(newbranch);

            newbranch.push(parent);

            parentHash = parent.parentHash;
        }
    }

    function getDescendants(block) {
        var children = getChildren(block);

        if (children.length == 0)
            return children;

        var descendants = []

        for (var n in children) {
            var child = children[n];
            descendants = descendants.concat(getChildren(child));
        }
    }

    function switchToFork(newbranch) {
        for (var n = newbranch.length; n-- > 0;) {
            var block = newbranch[n];
            blocks[block.number] = block;
        }
    }
}

function createBlockchain(block) {
    return new Blockchain(block);
}

module.exports = {
    blockchain: createBlockchain
}

<|endoftext|>


<commit_before>'use strict';

const ApiBuilder = require('claudia-api-builder');
const fbSetup = require('./facebook/setup');
const slackSetup = require('./slack/setup');
const telegramSetup = require('./telegram/setup');
const skypeSetup = require('./skype/setup');
const twilioSetup = require('./twilio/setup');
const fbTemplate = require('./facebook/format-message');
const slackTemplate = require('./slack/format-message');
const slackDelayedReply = require('./slack/delayed-reply');

let logError = function (err) {
  console.error(err);
};

module.exports = function botBuilder(messageHandler, optionalLogError) {
  logError = optionalLogError || logError;

  const api = new ApiBuilder(),
    messageHandlerPromise = function (message, originalApiBuilderRequest) {
      return Promise.resolve(message).then(message => messageHandler(message, originalApiBuilderRequest));
    };

  api.get('/', () => 'Ok');

  fbSetup(api, messageHandlerPromise, logError);
  slackSetup(api, messageHandlerPromise, logError);
  telegramSetup(api, messageHandlerPromise, logError);
  skypeSetup(api, messageHandlerPromise, logError);
  twilioSetup(api, messageHandlerPromise, logError);

  return api;
};

module.exports.fbTemplate = fbTemplate;
module.exports.slackTemplate = slackTemplate;
module.exports.slackDelayedReply = slackDelayedReply;
<commit_msg>Export Telegram template<commit_after>'use strict';

const ApiBuilder = require('claudia-api-builder');
const fbSetup = require('./facebook/setup');
const slackSetup = require('./slack/setup');
const telegramSetup = require('./telegram/setup');
const skypeSetup = require('./skype/setup');
const twilioSetup = require('./twilio/setup');
const fbTemplate = require('./facebook/format-message');
const slackTemplate = require('./slack/format-message');
const telegramTemplate = require('./telegram/format-message');
const slackDelayedReply = require('./slack/delayed-reply');

let logError = function (err) {
  console.error(err);
};

module.exports = function botBuilder(messageHandler, optionalLogError) {
  logError = optionalLogError || logError;

  const api = new ApiBuilder(),
    messageHandlerPromise = function (message, originalApiBuilderRequest) {
      return Promise.resolve(message).then(message => messageHandler(message, originalApiBuilderRequest));
    };

  api.get('/', () => 'Ok');

  fbSetup(api, messageHandlerPromise, logError);
  slackSetup(api, messageHandlerPromise, logError);
  telegramSetup(api, messageHandlerPromise, logError);
  skypeSetup(api, messageHandlerPromise, logError);
  twilioSetup(api, messageHandlerPromise, logError);

  return api;
};

module.exports.fbTemplate = fbTemplate;
module.exports.slackTemplate = slackTemplate;
module.exports.telegramTemplate = telegramTemplate;
module.exports.slackDelayedReply = slackDelayedReply;
<|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path');
var Flow = require('./misc/flow');
var extract = require('../extract');
var command = require('./command');
var chalk = require('chalk');
var readline = require('readline');
var utils = require('./misc/utils'); // TODO: make it explicit

//
// launched by another module
//
exports.build = function(config){
  if (this === command)
    build(config);

  if (this === exports)
    build(command.normalize(config));
};

//
// launched directly (i.e. node index.js ..)
//
if (process.mainModule === module)
  command.run();

//
function getToolsId(){
  var toolsPkg = require('../../package.json');
  var toolsId = toolsPkg._id;
  var commit;

  if (!toolsId)
  {
    commit = utils.fetchCommit(__dirname + '/../..');
    toolsId = toolsPkg.name + '@' + toolsPkg.version;
  }
  else
  {
    if (toolsPkg._resolved)
    {
      var m = toolsPkg._resolved.match(/#(.{1,10})/);
      if (m)
        commit = m[1];
    }
  }

  return toolsId + (commit ? ' (' + commit + ')' : '');
}

//
// main function
//
function build(config){

  //
  // init
  //

  var options = command.norm(config);
  var inputFilename = options.file;
  var flow = new Flow(
    options.base,
    path.dirname(path.relative(options.base, inputFilename)),
    options
  );
  var fconsole = flow.console;

  flow.exitOnFatal = true;
  flow.outputResourceDir = 'res/';

  fconsole.enabled = options.verbose;
  chalk.enabled = options.color && process.stdout.isTTY;

  if (options.verbose)
  {
    // TODO: add more settings output
    fconsole.start('Build info (' + getToolsId() + ')');
    fconsole.log('Base:', options.base);
    fconsole.log('Index file:', options.file);
    fconsole.log('Output:', options.output);
    fconsole.endl();
  }
  else
  {
    var cwd = process.env.PWD || process.cwd();

    process.stdout.write(
      'Build with ' + chalk.green(getToolsId()) + '\n' +
      'Base path: ' +
        options.base + '\n' +
      'Index file: ' +
        chalk.green(path.relative(cwd, options.file).replace(/^([^\.\/])/, './$1').replace(/\\/g, '/')) + '\n' +
      'Output: ' +
        chalk.green(path.relative(cwd, options.output).replace(/^([^\.\/])/, './$1').replace(/\\/g, '/') || '<current folder>') + '\n' +
      '\n'
    );
  }

  flow.files.typeByExt = options.extFileTypes;

  //
  // preprocessing
  //

  fconsole.start('Preprocessors');
  for (var type in options.preprocess)
  {
    var list = options.preprocess[type];
    var newList = flow.files.preprocess[type] = [];
    var hasPrerocessor = false;

    for (var i = 0; i < list.length; i++)
    {
      var preprocessorPath = list[i];

      fconsole.log('[' + type + '] ' + preprocessorPath);

      try {
        var processor = require(preprocessorPath);

        if (typeof processor.process == 'function')
        {
          newList.push(processor.process);
          hasPrerocessor = true;
        }
        else
        {
          console.warn('[ERROR] Preprocessor has no process function. Skipped.');
          process.exit();
        }
      } catch(e) {
        console.warn('[ERROR] Error on preprocessor load: ' + e);
        process.exit();
      }

      fconsole.end();
    }
  }
  if (!hasPrerocessor)
    fconsole.log('  not defined');
  fconsole.endl();

  //
  // process input
  //

  // check input file exists
  if (!fs.existsSync(inputFilename) || !fs.statSync(inputFilename).isFile())
  {
    console.warn('Input file ' + inputFilename + ' not found');
    process.exit();
  }

  fconsole.start('\nInit\n====\n');

  // add input file in queue
  flow.indexFile = flow.files.add({
    isIndexFile: true,
    filename: path.relative(options.base, inputFilename)
  });

  //
  // Main part
  //

  var handlers = extract.handlers({
    cssInfo: flow.options.cssOptimizeNames || flow.options.cssCutUnused,
    l10nInfo: true
  }).concat([
    // convert resources to base64 if it make sense
    require('./res/base64'),

    // process css
    require('./css/cutUnused'),
    require('./css/optimizeNames'),
    require('./css/makePackages'),
    require('./css/linear'),
    require('./css/merge'),
    require('./css/pack'),
    require('./css/translate'),

    // process l10n
    require('./l10n/buildIndex'),
    require('./l10n/makePackages'),
    require('./l10n/relink'),
    require('./l10n/pack'),

    // process tmpl
    require('./tmpl/translate'),
    require('./tmpl/pregenerate'),

    // css/html resources
    require('./res/translate'),
    require('./res/buildMap'),

    // process js
    require('./js/relink'),
    //require('./js/merge'),
    require('./js/makePackages'),
    require('./js/resolvePathes'),
    require('./js/translate'),
    require('./js/json'),
    require('./js/buildPackages'),
    require('./js/pack'),
    require('./js/realignHtml'),

    // process html
    require('./html/translate'),

    // target transformation
    {
      'output-graph': require('./target/outputGraph'),
      'zip': require('./target/zip')
    }[options.target],

    // flush output
    require('./misc/writeFiles'),

    finalHandler
  ]).filter(Boolean);

  var taskCount = 0;
  var timing = [];
  var time;
  var stdoutPos;

  function asyncTaskStart(){
    taskCount++;
  }
  function asyncTaskDone(){
    taskCount--;
    nextHandler();
  }

  function nextHandler(){
    if (!taskCount && handlers.length)
    {
      time.time = new Date - time.time;
      timing.push(time);

      if (!options.verbose)
      {
        var extraInfo = typeof time.handler.extraInfo == 'function'
          ? time.handler.extraInfo(flow)
          : '';
        if (process.stdout.isTTY)
        {

          if (process.stdout._bytesDispatched == stdoutPos)
          {
            readline.moveCursor(process.stdout, 0, -1);
            readline.clearLine(process.stdout, 0);
            process.stdout.write(
              stdoutHandlerTitle +
              (extraInfo ? chalk.gray(' [') + chalk.yellow(extraInfo) + chalk.gray(']') : '') +
              chalk.gray(' – '));
          }
          else
          {
            if (extraInfo)
              process.stdout.write('       ' + chalk.yellow(extraInfo) + '\n');

            process.stdout.write('       ');
          }

          process.stdout.write(
            chalk.green('DONE') +
            (time.time > 10 ? chalk.gray(' (' + time.time + 'ms)') : '') +
            '\n'
          );
        }
        else
        {
          if (extraInfo)
            process.stdout.write('       * ' + extraInfo + '\n');
        }
      }

      fconsole.resetDeep();

      process.nextTick(runHandler);
    }
  }

  function runHandler(){
    var handler = handlers.shift();
    var title = handler.handlerName || 'Untitled handler';

    if (options.verbose)
      fconsole.log('\n' + title + '\n' + ('='.repeat(title.length)) + '\n');
    else
    {
      if (handler != finalHandler)
      {
        stdoutHandlerTitle = title.replace(/^(?:\[(\S+)\] ?|)/, function(m, topic){
          return '     '.substr((topic || '').length) + chalk.cyan(topic || '') + '  ';
        });
        process.stdout.write(stdoutHandlerTitle + '\n');
        stdoutPos = process.stdout._bytesDispatched;
      }
    }

    fconsole.incDeep();

    time = {
      handler: handler,
      name: title,
      time: Number(new Date)
    };
    handler(flow, asyncTaskStart, asyncTaskDone);

    nextHandler();
  }

  runHandler();

  //
  // show summary
  //
  function finalHandler(){
    if (!options.verbose)
    {
      fconsole.resetDeep();
      fconsole.enabled = true;
      process.stdout.write('\n');
    }

    if (options.verbose)
    {
      // file types
      (function(){
        var fileTypeMap = {};
        var fileMap = {};
        var outputFileCount = 0;
        var outputSize = 0;

        flow.files.queue.forEach(function(file){
          var stat = fileTypeMap[file.type];

          if (!stat)
          {
            stat = fileTypeMap[file.type] = {
              queueFiles: [],
              outputFiles: [],
              outputSize: 0
            };
          }

          stat.queueFiles.push(file.filename);

          if (file.outputFilename && 'outputContent' in file)
          {
            if (!fileMap[file.outputFilename]) // prevent duplicates
            {
              fileMap[file.outputFilename] = true;
              outputFileCount++;

              var fileSize = Buffer.byteLength(file.outputContent, file.encoding);
              outputSize += fileSize;
              stat.outputSize += fileSize;
              stat.outputFiles.push(file.outputFilename + ' ' + fileSize + ' bytes');
            }
          }
        }, fileTypeMap);

        fconsole.start('File queue:');
        for (var key in fileTypeMap)
          fconsole.log(key + ': ' + fileTypeMap[key].queueFiles.length);
        fconsole.endl();

        fconsole.start('Output ' + outputFileCount + ' files in ' + outputSize + ' bytes:');
        for (var key in fileTypeMap)
        {
          var files = fileTypeMap[key].outputFiles;

          if (!files.length)
            continue;

          var header = key + ': ' + files.length + ', ' + fileTypeMap[key].outputSize + ' bytes';
          if (key == 'script' || key == 'style')
          {
            fconsole.start(header);
            fconsole.list(files);
            fconsole.end();
          }
          else
            fconsole.log(header);
        }
        fconsole.endl();

      })();

      // timing
      fconsole.start('Timing:');
      timing.forEach(function(t){
        var time = String(t.time || 0);
        fconsole.log(' '.repeat(6 - time.length) + time + '  ' + (t.name || '[No title step]'));
      });
      fconsole.endl();
    }

    // total time
    fconsole.log('Warnings: ' + (flow.warns.length ? chalk.bgRed(flow.warns.length) : chalk.green('NO')));
    if (options.warnings)
    {
      (function(){
        var warns = {};

        flow.warns.forEach(function(item){
          var filename = item.file || '[no file]';
          if (!warns[filename])
            warns[filename] = [];
          warns[filename].push(item.message);
        });

        fconsole.incDeep();
        for (var filename in warns)
        {
          fconsole.start(filename);
          fconsole.list(warns[filename]);
          fconsole.endl();
        }
        fconsole.end();
      })();
    }

    fconsole.log('Build done in ' + chalk.yellow((flow.time() / 1000).toFixed(3) + 's') + '\n');
  }

  finalHandler.handlerName = 'Build stat';
}
<commit_msg>build: change log header<commit_after>var fs = require('fs');
var path = require('path');
var Flow = require('./misc/flow');
var extract = require('../extract');
var command = require('./command');
var chalk = require('chalk');
var readline = require('readline');
var utils = require('./misc/utils'); // TODO: make it explicit

//
// launched by another module
//
exports.build = function(config){
  if (this === command)
    build(config);

  if (this === exports)
    build(command.normalize(config));
};

//
// launched directly (i.e. node index.js ..)
//
if (process.mainModule === module)
  command.run();

//
function getToolsId(){
  var toolsPkg = require('../../package.json');
  var toolsId = toolsPkg._id;
  var commit;

  if (!toolsId)
  {
    commit = utils.fetchCommit(__dirname + '/../..');
    toolsId = toolsPkg.name + '@' + toolsPkg.version;
  }
  else
  {
    if (toolsPkg._resolved)
    {
      var m = toolsPkg._resolved.match(/#(.{1,10})/);
      if (m)
        commit = m[1];
    }
  }

  return toolsId + (commit ? ' (' + commit + ')' : '');
}

function normalizePath(filename){
  if (!/^([a-z]:|[\/\\\.])/i.test(filename))
    filename = './' + filename;
  return filename.replace(/\\/g, '/');
}

//
// main function
//
function build(config){

  //
  // init
  //

  var options = command.norm(config);
  var inputFilename = options.file;
  var flow = new Flow(
    options.base,
    path.dirname(path.relative(options.base, inputFilename)),
    options
  );
  var fconsole = flow.console;

  flow.exitOnFatal = true;
  flow.outputResourceDir = 'res/';

  fconsole.enabled = options.verbose;
  chalk.enabled = options.color && process.stdout.isTTY;

  if (options.verbose)
  {
    // TODO: add more settings output
    fconsole.start('Build info (' + getToolsId() + ')');
    fconsole.log('Base:', options.base);
    fconsole.log('Index file:', options.file);
    fconsole.log('Output:', options.output);
    fconsole.endl();
  }
  else
  {
    var cwd = process.env.PWD || process.cwd();

    process.stdout.write(
      'Build with ' + chalk.yellow(getToolsId()) + '\n' +
      'Base path: ' +
        chalk.green(normalizePath(options.base)) + '\n' +
      'Index file: ' +
        chalk.green(normalizePath(path.relative(cwd, options.file))) + '\n' +
      'Output: ' +
        chalk.green(normalizePath(path.relative(cwd, options.output)) || '<current folder>') + '\n' +
      '\n'
    );
  }

  flow.files.typeByExt = options.extFileTypes;

  //
  // preprocessing
  //

  fconsole.start('Preprocessors');
  for (var type in options.preprocess)
  {
    var list = options.preprocess[type];
    var newList = flow.files.preprocess[type] = [];
    var hasPrerocessor = false;

    for (var i = 0; i < list.length; i++)
    {
      var preprocessorPath = list[i];

      fconsole.log('[' + type + '] ' + preprocessorPath);

      try {
        var processor = require(preprocessorPath);

        if (typeof processor.process == 'function')
        {
          newList.push(processor.process);
          hasPrerocessor = true;
        }
        else
        {
          console.warn('[ERROR] Preprocessor has no process function. Skipped.');
          process.exit();
        }
      } catch(e) {
        console.warn('[ERROR] Error on preprocessor load: ' + e);
        process.exit();
      }

      fconsole.end();
    }
  }
  if (!hasPrerocessor)
    fconsole.log('  not defined');
  fconsole.endl();

  //
  // process input
  //

  // check input file exists
  if (!fs.existsSync(inputFilename) || !fs.statSync(inputFilename).isFile())
  {
    console.warn('Input file ' + inputFilename + ' not found');
    process.exit();
  }

  fconsole.start('\nInit\n====\n');

  // add input file in queue
  flow.indexFile = flow.files.add({
    isIndexFile: true,
    filename: path.relative(options.base, inputFilename)
  });

  //
  // Main part
  //

  var handlers = extract.handlers({
    cssInfo: flow.options.cssOptimizeNames || flow.options.cssCutUnused,
    l10nInfo: true
  }).concat([
    // convert resources to base64 if it make sense
    require('./res/base64'),

    // process css
    require('./css/cutUnused'),
    require('./css/optimizeNames'),
    require('./css/makePackages'),
    require('./css/linear'),
    require('./css/merge'),
    require('./css/pack'),
    require('./css/translate'),

    // process l10n
    require('./l10n/buildIndex'),
    require('./l10n/makePackages'),
    require('./l10n/relink'),
    require('./l10n/pack'),

    // process tmpl
    require('./tmpl/translate'),
    require('./tmpl/pregenerate'),

    // css/html resources
    require('./res/translate'),
    require('./res/buildMap'),

    // process js
    require('./js/relink'),
    //require('./js/merge'),
    require('./js/makePackages'),
    require('./js/resolvePathes'),
    require('./js/translate'),
    require('./js/json'),
    require('./js/buildPackages'),
    require('./js/pack'),
    require('./js/realignHtml'),

    // process html
    require('./html/translate'),

    // target transformation
    {
      'output-graph': require('./target/outputGraph'),
      'zip': require('./target/zip')
    }[options.target],

    // flush output
    require('./misc/writeFiles'),

    finalHandler
  ]).filter(Boolean);

  var taskCount = 0;
  var timing = [];
  var time;
  var stdoutPos;

  function asyncTaskStart(){
    taskCount++;
  }
  function asyncTaskDone(){
    taskCount--;
    nextHandler();
  }

  function nextHandler(){
    if (!taskCount && handlers.length)
    {
      time.time = new Date - time.time;
      timing.push(time);

      if (!options.verbose)
      {
        var extraInfo = typeof time.handler.extraInfo == 'function'
          ? time.handler.extraInfo(flow)
          : '';
        if (process.stdout.isTTY)
        {

          if (process.stdout._bytesDispatched == stdoutPos)
          {
            readline.moveCursor(process.stdout, 0, -1);
            readline.clearLine(process.stdout, 0);
            process.stdout.write(
              stdoutHandlerTitle +
              (extraInfo ? chalk.gray(' [') + chalk.yellow(extraInfo) + chalk.gray(']') : '') +
              chalk.gray(' – '));
          }
          else
          {
            if (extraInfo)
              process.stdout.write('       ' + chalk.yellow(extraInfo) + '\n');

            process.stdout.write('       ');
          }

          process.stdout.write(
            chalk.green('DONE') +
            (time.time > 10 ? chalk.gray(' (' + time.time + 'ms)') : '') +
            '\n'
          );
        }
        else
        {
          if (extraInfo)
            process.stdout.write('       * ' + extraInfo + '\n');
        }
      }

      fconsole.resetDeep();

      process.nextTick(runHandler);
    }
  }

  function runHandler(){
    var handler = handlers.shift();
    var title = handler.handlerName || 'Untitled handler';

    if (options.verbose)
      fconsole.log('\n' + title + '\n' + ('='.repeat(title.length)) + '\n');
    else
    {
      if (handler != finalHandler)
      {
        stdoutHandlerTitle = title.replace(/^(?:\[(\S+)\] ?|)/, function(m, topic){
          return '     '.substr((topic || '').length) + chalk.cyan(topic || '') + '  ';
        });
        process.stdout.write(stdoutHandlerTitle + '\n');
        stdoutPos = process.stdout._bytesDispatched;
      }
    }

    fconsole.incDeep();

    time = {
      handler: handler,
      name: title,
      time: Number(new Date)
    };
    handler(flow, asyncTaskStart, asyncTaskDone);

    nextHandler();
  }

  runHandler();

  //
  // show summary
  //
  function finalHandler(){
    if (!options.verbose)
    {
      fconsole.resetDeep();
      fconsole.enabled = true;
      process.stdout.write('\n');
    }

    if (options.verbose)
    {
      // file types
      (function(){
        var fileTypeMap = {};
        var fileMap = {};
        var outputFileCount = 0;
        var outputSize = 0;

        flow.files.queue.forEach(function(file){
          var stat = fileTypeMap[file.type];

          if (!stat)
          {
            stat = fileTypeMap[file.type] = {
              queueFiles: [],
              outputFiles: [],
              outputSize: 0
            };
          }

          stat.queueFiles.push(file.filename);

          if (file.outputFilename && 'outputContent' in file)
          {
            if (!fileMap[file.outputFilename]) // prevent duplicates
            {
              fileMap[file.outputFilename] = true;
              outputFileCount++;

              var fileSize = Buffer.byteLength(file.outputContent, file.encoding);
              outputSize += fileSize;
              stat.outputSize += fileSize;
              stat.outputFiles.push(file.outputFilename + ' ' + fileSize + ' bytes');
            }
          }
        }, fileTypeMap);

        fconsole.start('File queue:');
        for (var key in fileTypeMap)
          fconsole.log(key + ': ' + fileTypeMap[key].queueFiles.length);
        fconsole.endl();

        fconsole.start('Output ' + outputFileCount + ' files in ' + outputSize + ' bytes:');
        for (var key in fileTypeMap)
        {
          var files = fileTypeMap[key].outputFiles;

          if (!files.length)
            continue;

          var header = key + ': ' + files.length + ', ' + fileTypeMap[key].outputSize + ' bytes';
          if (key == 'script' || key == 'style')
          {
            fconsole.start(header);
            fconsole.list(files);
            fconsole.end();
          }
          else
            fconsole.log(header);
        }
        fconsole.endl();

      })();

      // timing
      fconsole.start('Timing:');
      timing.forEach(function(t){
        var time = String(t.time || 0);
        fconsole.log(' '.repeat(6 - time.length) + time + '  ' + (t.name || '[No title step]'));
      });
      fconsole.endl();
    }

    // total time
    fconsole.log('Warnings: ' + (flow.warns.length ? chalk.bgRed(flow.warns.length) : chalk.green('NO')));
    if (options.warnings)
    {
      (function(){
        var warns = {};

        flow.warns.forEach(function(item){
          var filename = item.file || '[no file]';
          if (!warns[filename])
            warns[filename] = [];
          warns[filename].push(item.message);
        });

        fconsole.incDeep();
        for (var filename in warns)
        {
          fconsole.start(filename);
          fconsole.list(warns[filename]);
          fconsole.endl();
        }
        fconsole.end();
      })();
    }

    fconsole.log('Build done in ' + chalk.yellow((flow.time() / 1000).toFixed(3) + 's') + '\n');
  }

  finalHandler.handlerName = 'Build stat';
}
<|endoftext|>