<commit_before>// libraries
var sqlite3 = require('sqlite3').verbose();
var fs = require("fs");

var options = {
	requireEndedness : false,
	wordToken : " ",
	sentenceToken : new RegExp(/!\.\?/g),
	verbose : false
};

/**
* convenience method to load a file on disk into memory as a string
*/
function loadFile(filename) {
	return fs.readFileSync( filename ) + "";
}

/**
 * Output log entries if we are in verbose mode
 */
function log() {
	if (console && options.verbose) {
		console.log.apply(console, arguments);
	}
}

function setOption() {
	if (arguments.length == 2) {
		log("Setting " + arguments[0], arguments[1]);
		options[arguments[0]] = arguments[1];
	} else if (arguments.length == 1) {
		for(var i in arguments[0]) {
			log("Setting " + i, arguments[0][i]);
			options[i] = arguments[0][i];
		}
	}
}

/**
 * remove non alpha-nums from a string
 */
function removeNonAlphanumerics(text) {
	return text.replace(/\W/g, '');
}

/**
 * collapse white space into a single space character
 */
function collapseWhitespace(text) {
	return text.replace(/\s/,' ');
}

/**
 * perform basic cleanup on 'text' assuming roman characters, numeric values, punctuation
 */
function clean(text) {
	return text
		.replace(/[^A-Za-z0-9 _.,!?"'/$]/g," ")
		.replace(/\s/g," ");
}

/**
 * get a markov DB instance for database name, or pass nothing to use a db in memory
 */
function getDatabase(db_name) {

	// create or open database, no param means memory
	var db = new sqlite3.Database(db_name || ':memory:');

	function loadPoetry(text) {

		var input = clean(text);

		// split input
		var sentences = input.split(options.sentenceToken);

		for (var i = 0; i < sentences.length; i++) {
			sentences[i] = sentences[i].trim().split(options.wordToken);
		}

		load(sentences);

	}

	function loadProse(text) {

		var input = clean(text);

		// split input
		var sentences = input.split(options.sentenceToken);

		for (var i = 0; i < sentences.length; i++) {
			sentences[i] = sentences[i].trim().split(options.wordToken);
		}

		load(sentences);

	}

	function load(stack) {

		// get db and insert shit
		db.serialize(function() {

			var stmt = db.prepare("INSERT INTO lorem VALUES (?, ?, ?)");

			for (var a = 0; a < stack.length; a++) {
				for (var b = 0; b < stack[a].length; b++) {
					var word = stack[a][b].trim();
					var previous = "";
					var next = "";
					if (b > 0) {
						previous = stack[a][b - 1].trim();
					}
					if (b < stack[a].length - 1) {
						next = stack[a][b + 1].trim();
					}
					if (word != "")
						stmt.run(word, previous, next);
				}
			}

			stmt.finalize();

		});

	}

	function getRandom(callback) {

		db.each("SELECT current, previous, next FROM lorem WHERE next <> $1 ORDER BY RANDOM() LIMIT 1", {
			$1 : ""
		}, function(err, row) {

			if (err) {
				log(err);
			}

			callback(row.current, row.next, row.previous);

		});

	}

	function getNext(current, callback) {

		db.each("SELECT current, previous, next FROM lorem WHERE previous = $1 ORDER BY RANDOM() LIMIT 1", {
			$1 : current
		}, function(err, row) {

			if (err) {
				console.log(err);
			}

			callback(row.current, row.next, row.previous);

		});

	}

	function getPrevious(current, callback) {

		db.each("SELECT current, previous, next FROM lorem WHERE next = $1 ORDER BY RANDOM() LIMIT 1", {
			$1 : current
		}, function(err, row) {

			if (err) {
				console.log(err);
			}

			callback(row.current, row.previous, row.next);

		});

	}

	function getStack(count, callback) {

		count = count || 20;
		var stack = [];

		function _next(current, next, previous) {

			count--;
			stack.push(current);

			if (count > 0 || (options.requireEndedness && count <= 0 && next)) {
				getNext(current,_next);
			} else {
				callback(stack);
			}

		}

		getRandom(_next);

	}

	function getStackFromStart(start, count, callback) {

		count = count || 20;
		var stack = [start];

		function _next(current, next, previous) {

			count--;
			stack.push(current);

			if (count > 0 || (options.requireEndedness && count <= 0 && next)) {
				getNext(current,_next);
			} else {
				callback(stack);
			}

		}

		getNext(start,_next);

	}

	function getStackFromEnd(end, count, callback) {

		count = count || 20;
		var stack = [];

		function _next(current, next, previous) {

			count--;
			stack.push(current);

			if (count > 0 || (options.requireEndedness && count <= 0 && next)) {
				getNext(current,_next);
			} else {
				callback(stack);
			}

		}

		getRandom(_next);

	}

	function createTable() {
		db.run("CREATE TABLE IF NOT EXISTS lorem (current TEXT, previous TEXT, next TEXT)");
	}

	function closeDatabase() {
		db.close();
	}

	// create the table if she no exist
	createTable();

	return {
		load : load,
		loadPoetry : loadPoetry,
		loadProse : loadProse,
		getStack : getStack,
		getRandom : getRandom,
		getNext : getNext,
		getPrevious : getPrevious,
		closeDatabase : closeDatabase
	};

}

exports.log = log;
exports.setOption = setOption;
exports.getDatabase = getDatabase;
exports.loadFile = loadFile;
<commit_msg>notes re: public methods<commit_after>// libraries
var sqlite3 = require('sqlite3').verbose();
var fs = require("fs");

var options = {
	requireEndedness : false,
	wordToken : " ",
	sentenceToken : new RegExp(/!\.\?/g),
	verbose : false
};

/**
* convenience method to load a file on disk into memory as a string
*/
function loadFile(filename) {
	return fs.readFileSync( filename ) + "";
}

/**
 * Output log entries if we are in verbose mode
 */
function log() {
	if (console && options.verbose) {
		console.log.apply(console, arguments);
	}
}

function setOption() {
	if (arguments.length == 2) {
		log("Setting " + arguments[0], arguments[1]);
		options[arguments[0]] = arguments[1];
	} else if (arguments.length == 1) {
		for(var i in arguments[0]) {
			log("Setting " + i, arguments[0][i]);
			options[i] = arguments[0][i];
		}
	}
}

/**
 * remove non alpha-nums from a string
 */
function removeNonAlphanumerics(text) {
	return text.replace(/\W/g, '');
}

/**
 * collapse white space into a single space character
 */
function collapseWhitespace(text) {
	return text.replace(/\s/,' ');
}

/**
 * perform basic cleanup on 'text' assuming roman characters, numeric values, punctuation
 */
function clean(text) {
	return text
		.replace(/[^A-Za-z0-9 _.,!?"'/$]/g," ")
		.replace(/\s/g," ");
}

/**
 * get a markov DB instance for database name, or pass nothing to use a db in memory
 */
function getDatabase(db_name) {

	// create or open database, no param means memory
	var db = new sqlite3.Database(db_name || ':memory:');

	function loadPoetry(text) {

		var input = clean(text);

		// split input
		var sentences = input.split(options.sentenceToken);

		for (var i = 0; i < sentences.length; i++) {
			sentences[i] = sentences[i].trim().split(options.wordToken);
		}

		load(sentences);

	}

	function loadProse(text) {

		var input = clean(text);

		// split input
		var sentences = input.split(options.sentenceToken);

		for (var i = 0; i < sentences.length; i++) {
			sentences[i] = sentences[i].trim().split(options.wordToken);
		}

		load(sentences);

	}

	function load(stack) {

		// get db and insert shit
		db.serialize(function() {

			var stmt = db.prepare("INSERT INTO lorem VALUES (?, ?, ?)");

			for (var a = 0; a < stack.length; a++) {
				for (var b = 0; b < stack[a].length; b++) {
					var word = stack[a][b].trim();
					var previous = "";
					var next = "";
					if (b > 0) {
						previous = stack[a][b - 1].trim();
					}
					if (b < stack[a].length - 1) {
						next = stack[a][b + 1].trim();
					}
					if (word != "")
						stmt.run(word, previous, next);
				}
			}

			stmt.finalize();

		});

	}

	function getRandom(callback) {

		db.each("SELECT current, previous, next FROM lorem WHERE next <> $1 ORDER BY RANDOM() LIMIT 1", {
			$1 : ""
		}, function(err, row) {

			if (err) {
				log(err);
			}

			callback(row.current, row.next, row.previous);

		});

	}

	function getNext(current, callback) {

		db.each("SELECT current, previous, next FROM lorem WHERE previous = $1 ORDER BY RANDOM() LIMIT 1", {
			$1 : current
		}, function(err, row) {

			if (err) {
				console.log(err);
			}

			callback(row.current, row.next, row.previous);

		});

	}

	function getPrevious(current, callback) {

		db.each("SELECT current, previous, next FROM lorem WHERE next = $1 ORDER BY RANDOM() LIMIT 1", {
			$1 : current
		}, function(err, row) {

			if (err) {
				console.log(err);
			}

			callback(row.current, row.previous, row.next);

		});

	}

	function getStack(count, callback) {

		count = count || 20;
		var stack = [];

		function _next(current, next, previous) {

			count--;
			stack.push(current);

			if (count > 0 || (options.requireEndedness && count <= 0 && next)) {
				getNext(current,_next);
			} else {
				callback(stack);
			}

		}

		getRandom(_next);

	}

	function getStackFromStart(start, count, callback) {

		count = count || 20;
		var stack = [start];

		function _next(current, next, previous) {

			count--;
			stack.push(current);

			if (count > 0 || (options.requireEndedness && count <= 0 && next)) {
				getNext(current,_next);
			} else {
				callback(stack);
			}

		}

		getNext(start,_next);

	}

	function getStackFromEnd(end, count, callback) {

		count = count || 20;
		var stack = [];

		function _next(current, next, previous) {

			count--;
			stack.push(current);

			if (count > 0 || (options.requireEndedness && count <= 0 && next)) {
				getNext(current,_next);
			} else {
				callback(stack);
			}

		}

		getRandom(_next);

	}

	function createTable() {
		db.run("CREATE TABLE IF NOT EXISTS lorem (current TEXT, previous TEXT, next TEXT)");
	}

	function closeDatabase() {
		db.close();
	}

	// create the table if she no exist
	createTable();

	return {

		// public load methods
		load : load,
		loadPoetry : loadPoetry,
		loadProse : loadProse,

		// public stack methods
		getStack : getStack,
		getStackFromEnd : getStackFromEnd,
		getStackFromStart : getStackFromStart,

		// public state traversal methods
		getRandom : getRandom,
		getNext : getNext,
		getPrevious : getPrevious,

		// db methods
		closeDatabase : closeDatabase
	};

}

exports.log = log;
exports.setOption = setOption;
exports.getDatabase = getDatabase;
exports.loadFile = loadFile;
<|endoftext|>


<commit_before>import Vue from 'vue';

export var version = '2.0.0';

var compatible = (/^2\./).test(Vue.version);
if (!compatible) {
  Vue.util.warn('VueClickaway ' + version + ' only supports Vue 2.x, and does not support Vue ' + Vue.version);
}

// @SECTION: implementation

var HANDLER = '_vue_clickaway_handler';

function bind(el, binding) {
  unbind(el);

  var callback = binding.value;
  if (typeof callback !== 'function') {
    if (process.env.NODE_ENV !== 'production') {
      Vue.util.warn(
        'v-' + binding.name + '="' +
        binding.expression + '" expects a function value, ' +
        'got ' + callback
      );
    }
    return;
  }

  el[HANDLER] = function(ev) {
    // @NOTE: IE 5.0+
    // @REFERENCE: https://developer.mozilla.org/en/docs/Web/API/Node/contains
    if (!el.contains(ev.target)) {
      return callback(ev);
    }
  };

  document.documentElement.addEventListener('click', el[HANDLER], false);
}

function unbind(el) {
  document.documentElement.removeEventListener('click', el[HANDLER], false);
  delete el[HANDLER];
}

export var directive = {
  bind: bind,
  update: function(el, binding) {
    if (binding.value === binding.oldValue) return;
    bind(el, binding);
  },
  unbind: unbind,
};

export var mixin = {
  directives: { onClickaway: directive },
};
<commit_msg>Fix "origin" click triggering the away callback<commit_after>import Vue from 'vue';

export var version = '2.0.0';

var compatible = (/^2\./).test(Vue.version);
if (!compatible) {
  Vue.util.warn('VueClickaway ' + version + ' only supports Vue 2.x, and does not support Vue ' + Vue.version);
}

// @SECTION: implementation

var HANDLER = '_vue_clickaway_handler';

function bind(el, binding) {
  unbind(el);

  var callback = binding.value;
  if (typeof callback !== 'function') {
    if (process.env.NODE_ENV !== 'production') {
      Vue.util.warn(
        'v-' + binding.name + '="' +
        binding.expression + '" expects a function value, ' +
        'got ' + callback
      );
    }
    return;
  }

  // @NOTE: Vue binds directives in microtasks, while UI events are dispatched
  //        in macrotasks. This causes the listener to be set up before
  //        the "origin" click event (the event that lead to the binding of
  //        the directive) arrives at the document root. To work around that,
  //        we ignore events until the end of the "initial" macrotask.
  // @REFERENCE: https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/
  // @REFERENCE: https://github.com/simplesmiler/vue-clickaway/issues/8
  var initialMacrotaskEnded = false;
  setTimeout(function() {
    initialMacrotaskEnded = true;
  }, 0);

  el[HANDLER] = function(ev) {
    // @NOTE: IE 5.0+
    // @REFERENCE: https://developer.mozilla.org/en/docs/Web/API/Node/contains
    if (initialMacrotaskEnded && !el.contains(ev.target)) {
      return callback(ev);
    }
  };

  document.documentElement.addEventListener('click', el[HANDLER], false);
}

function unbind(el) {
  document.documentElement.removeEventListener('click', el[HANDLER], false);
  delete el[HANDLER];
}

export var directive = {
  bind: bind,
  update: function(el, binding) {
    if (binding.value === binding.oldValue) return;
    bind(el, binding);
  },
  unbind: unbind,
};

export var mixin = {
  directives: { onClickaway: directive },
};
<|endoftext|>


<commit_before>'use strict';
const path = require('path');
const electron = require('electron');
const { BrowserWindow, net } = electron;
const fs = require('fs');

const app = electron.app;
let downloadFolder = app.getPath('downloads');
let lastWindowCreated;

const queue = [];

const _popQueueItem = (url) => {
    let queueItem = queue.find(item => item.url === url);
    queue.splice(queue.indexOf(queueItem), 1);
    return queueItem;
};

function _registerListener(win, opts = {}) {

    lastWindowCreated = win;
    downloadFolder = opts.downloadFolder || downloadFolder;

    const listener = (e, item) => {

        const itemUrl = decodeURIComponent(item.getURL());
        const itemFilename = decodeURIComponent(item.getFilename());

        let queueItem = _popQueueItem(itemUrl);

        if (queueItem) {

            const filePath = path.join(downloadFolder, path.join(queueItem.path, itemFilename));

            const totalBytes = item.getTotalBytes();

            item.setSavePath(filePath);

            // Resuming an interrupted download
            if (item.getState() === 'interrupted') {
                item.resume();
            }

            item.on('updated', () => {
                const progress = item.getReceivedBytes() * 100 / totalBytes;

                if (typeof queueItem.onProgress === 'function') {
                    queueItem.onProgress(progress, item);
                }
            });

            item.on('done', (e, state) => {

                let finishedDownloadCallback = queueItem.callback || function () {};

                if (!win.isDestroyed()) {
                    win.setProgressBar(-1);
                }

                if (state === 'interrupted') {
                    const message = `The download of ${item.getFilename()} was interrupted`;

                    finishedDownloadCallback(new Error(message), { url: item.getURL(), filePath });

                } else if (state === 'completed') {
                    if (process.platform === 'darwin') {
                        app.dock.downloadFinished(filePath);
                    }

                    // TODO: remove this listener, and/or the listener that attach this listener to newly created windows
                    // if (opts.unregisterWhenDone) {
                    //     webContents.session.removeListener('will-download', listener);
                    // }

                    finishedDownloadCallback(null, { url: item.getURL(), filePath });

                }

            });
        }
    };

    win.webContents.session.on('will-download', listener);
}

const register = (opts = {}) => {

    app.on('browser-window-created', (e, win) => {
        _registerListener(win, opts);
    });
};

const download = (options, callback) => {
    let win = BrowserWindow.getFocusedWindow() || lastWindowCreated;
    options = Object.assign({}, { path: '' }, options);

    const request = net.request(options.url);

    request.on('response', function (response) {
        request.abort();

        const filename = decodeURIComponent(path.basename(options.url));
        const url = decodeURIComponent(options.url);

        queue.push({
            url: url,
            filename: filename,
            path: options.path.toString(),
            callback: callback,
            onProgress: options.onProgress
        });

        const filePath = path.join(path.join(downloadFolder, options.path.toString()), filename);

        if (fs.existsSync(filePath)) {
            const stats = fs.statSync(filePath);

            const fileOffset = stats.size;

            const serverFileSize = parseInt(response.headers['content-length']);

            console.log(filename + ' exists, verifying file size: (' + fileOffset + ' / ' + serverFileSize + ' downloaded)');

            // Check if size on disk is lower than server
            if (fileOffset < serverFileSize) {
                console.log('File needs re-downloaded as it was not completed');

                options = {
                    path: filePath,
                    urlChain: [response.request.uri.href],
                    offset: parseInt(fileOffset),
                    length: serverFileSize,
                    lastModified: response.headers['last-modified']
                };

                win.webContents.session.createInterruptedDownload(options);

            } else {

                console.log(filename + ' verified, no download needed');

                let finishedDownloadCallback = callback || function () {};

                finishedDownloadCallback(null, { url, filePath });
            }

        } else {
            console.log(filename + ' does not exist, download it now');
            win.webContents.downloadURL(options.url);
        }
    });
    request.end();
};

const bulkDownload = (options, callback) => {

    options = Object.assign({}, { urls: [], path: '' }, options);

    let urlsCount = options.urls.length;
    let finished = [];
    let errors = [];

    options.urls.forEach((url) => {
        download({ url, path: options.path }, function (error, itemInfo) {

            if (error) {
                errors.push(itemInfo.url);
            } else {
                finished.push(itemInfo.url);
            }

            let errorsCount = errors.length;
            let finishedCount = finished.length;

            if ((finishedCount + errorsCount) === urlsCount) {
                if (errorsCount > 0) {
                    callback(new Error(errorsCount + ' downloads failed'), finished, errors);
                } else {
                    callback(null, finished, []);
                }
            }
        });
    });
};

module.exports = {
    register,
    download,
    bulkDownload
};<commit_msg>Fix "uri is undefined" error.<commit_after>'use strict';
const path = require('path');
const electron = require('electron');
const { BrowserWindow, net } = electron;
const fs = require('fs');

const app = electron.app;
let downloadFolder = app.getPath('downloads');
let lastWindowCreated;

const queue = [];

const _popQueueItem = (url) => {
    let queueItem = queue.find(item => item.url === url);
    queue.splice(queue.indexOf(queueItem), 1);
    return queueItem;
};

function _registerListener(win, opts = {}) {

    lastWindowCreated = win;
    downloadFolder = opts.downloadFolder || downloadFolder;

    const listener = (e, item) => {

        const itemUrl = decodeURIComponent(item.getURL());
        const itemFilename = decodeURIComponent(item.getFilename());

        let queueItem = _popQueueItem(itemUrl);

        if (queueItem) {

            const filePath = path.join(downloadFolder, path.join(queueItem.path, itemFilename));

            const totalBytes = item.getTotalBytes();

            item.setSavePath(filePath);

            // Resuming an interrupted download
            if (item.getState() === 'interrupted') {
                item.resume();
            }

            item.on('updated', () => {
                const progress = item.getReceivedBytes() * 100 / totalBytes;

                if (typeof queueItem.onProgress === 'function') {
                    queueItem.onProgress(progress, item);
                }
            });

            item.on('done', (e, state) => {

                let finishedDownloadCallback = queueItem.callback || function () {};

                if (!win.isDestroyed()) {
                    win.setProgressBar(-1);
                }

                if (state === 'interrupted') {
                    const message = `The download of ${item.getFilename()} was interrupted`;

                    finishedDownloadCallback(new Error(message), { url: item.getURL(), filePath });

                } else if (state === 'completed') {
                    if (process.platform === 'darwin') {
                        app.dock.downloadFinished(filePath);
                    }

                    // TODO: remove this listener, and/or the listener that attach this listener to newly created windows
                    // if (opts.unregisterWhenDone) {
                    //     webContents.session.removeListener('will-download', listener);
                    // }

                    finishedDownloadCallback(null, { url: item.getURL(), filePath });

                }

            });
        }
    };

    win.webContents.session.on('will-download', listener);
}

const register = (opts = {}) => {

    app.on('browser-window-created', (e, win) => {
        _registerListener(win, opts);
    });
};

const download = (options, callback) => {
    let win = BrowserWindow.getFocusedWindow() || lastWindowCreated;
    options = Object.assign({}, { path: '' }, options);

    const request = net.request(options.url);

    request.on('response', function (response) {
        request.abort();

        const filename = decodeURIComponent(path.basename(options.url));
        const url = decodeURIComponent(options.url);

        queue.push({
            url: url,
            filename: filename,
            path: options.path.toString(),
            callback: callback,
            onProgress: options.onProgress
        });

        const filePath = path.join(path.join(downloadFolder, options.path.toString()), filename);

        if (fs.existsSync(filePath)) {
            const stats = fs.statSync(filePath);

            const fileOffset = stats.size;

            const serverFileSize = parseInt(response.headers['content-length']);

            console.log(filename + ' exists, verifying file size: (' + fileOffset + ' / ' + serverFileSize + ' downloaded)');

            // Check if size on disk is lower than server
            if (fileOffset < serverFileSize) {
                console.log('File needs re-downloaded as it was not completed');

                options = {
                    path: filePath,
                    urlChain: [options.url],
                    offset: parseInt(fileOffset),
                    length: serverFileSize,
                    lastModified: response.headers['last-modified']
                };

                win.webContents.session.createInterruptedDownload(options);

            } else {

                console.log(filename + ' verified, no download needed');

                let finishedDownloadCallback = callback || function () {};

                finishedDownloadCallback(null, { url, filePath });
            }

        } else {
            console.log(filename + ' does not exist, download it now');
            win.webContents.downloadURL(options.url);
        }
    });
    request.end();
};

const bulkDownload = (options, callback) => {

    options = Object.assign({}, { urls: [], path: '' }, options);

    let urlsCount = options.urls.length;
    let finished = [];
    let errors = [];

    options.urls.forEach((url) => {
        download({ url, path: options.path }, function (error, itemInfo) {

            if (error) {
                errors.push(itemInfo.url);
            } else {
                finished.push(itemInfo.url);
            }

            let errorsCount = errors.length;
            let finishedCount = finished.length;

            if ((finishedCount + errorsCount) === urlsCount) {
                if (errorsCount > 0) {
                    callback(new Error(errorsCount + ' downloads failed'), finished, errors);
                } else {
                    callback(null, finished, []);
                }
            }
        });
    });
};

module.exports = {
    register,
    download,
    bulkDownload
};
<|endoftext|>


<commit_before>/*jslint vars:true, nomen:true, indent:2, plusplus:true, unparam:true */
"use strict";
var crc32 = require('./crc32.js');
var clc = require('cli-color');
var fs = require('fs');
var path = require('path');
var monk = require('monk');
var linestream = require('line-stream');
var util = require('util');
var MultiTask = require('./multi_task.js');

var MINSCANTIME = 0; // Do not re-check any files which have been checked - for debugging
//var MINSCANTIME = Infinity; // Always recheck every file

var COLLECTION = 'diskcheck';
var FOLDER = '/var/data/diskcheck';

// var COLLECTION = 'test';
// var FOLDER = '/var/data/smb_private/CD Images/';

// var COLLECTION = 'test';
// var FOLDER = '/var/data/smb_stuff/Anime/Promos/';

var ArgumentParser = require('argparse').ArgumentParser;
var parser = new ArgumentParser({
  version: '0.0.1',
  addHelp: true,
  description: 'diskcheck'
});
parser.addArgument([ '-c', '--check' ], { help: 'Run check', action: 'storeTrue'});
parser.addArgument([ '-f', '--fix' ], { help: 'Fix mismatches', action: 'storeTrue'});
var args = parser.parseArgs();
if ((args.check && args.fix) || (!args.check && !args.fix)) {
  console.log('Expected exactly one of --check or --fix');
  process.exit();
}

var db = monk('localhost/diskcheck');
var files = db.get(COLLECTION);

function cleanup() {
  console.log('Cleaning up...');
  db.close();
}

// files.insert({ _id: 'foo.txt', crc: '12345678' }, function (err, doc) {
//   if (err) throw err;
// });
// files.findById('foo.txt', function (err, doc){
//     console.log(doc);
// });

// cb(relpath, stat, next)
function walkDir(base, dir, cb, dir_next) {
  fs.readdir(path.join(base, dir), function (err, files) {
    if (err) {
      throw err;
    }
    var idx = 0;
    function next() {
      if (idx === files.length) {
        return dir_next();
      }
      var filename = files[idx];
      ++idx;
      fs.stat(path.join(base, dir, filename), function (err, stat) {
        if (err) {
          throw err;
        }
        var sub_relpath = path.join(dir, filename);
        if (stat.isDirectory()) {
          walkDir(base, sub_relpath, cb, next);
        } else if (stat.isFile()) {
          cb(sub_relpath, stat, next);
        } else {
          console.log(filename);
          console.log(util.inspect(stat));
          throw "Unknown file type";
        }
      });
    }
    next();
  });
}

function formatCRC(crc) {
  if (crc < 0) {
    crc += 4294967296;
  }
  crc = crc.toString(16);
  while (crc.length < 8) {
    crc = '0' + crc;
  }
  return crc;
}

var crc_regex1 = /\[([0-9a-f]{8})\]/;
var crc_regex2 = /\[([0-9A-F]{8})\]/;
// next(crc || undefined, source)
function crcFromFilename(filename, next) {
  var m = filename.match(crc_regex1);
  if (m) {
    return next(m[1].toLowerCase(), 'filename');
  }
  m = filename.match(crc_regex2);
  if (m) {
    return next(m[1].toLowerCase(), 'filename');
  }
  files.findById(filename, function (err, doc) {
    if (err) {
      throw err;
    }
    if (doc && doc.crc32) {
      return next(doc.crc32, 'database');
    }
    next();
  });
}

function pad2(str) {
  return ('0' + str).slice(-2);
}

function formatBytes(bytes) {
  if (bytes === 1) {
    return '1 byte';
  }
  if (bytes < 1024) {
    return bytes.toFixed(0) + ' bytes';
  }
  if (bytes < 1024 * 1024) {
    return (bytes / 1024).toFixed(2) + ' kb';
  }
  if (bytes < 1024 * 1024 * 1024) {
    return (bytes / 1024 / 1024).toFixed(2) + ' mb';
  }
  if (bytes < 1024 * 1024 * 1024 * 1024) {
    return (bytes / 1024 / 1024 / 1024).toFixed(2) + ' gb';
  }
  return (bytes / 1024 / 1024 / 1024 / 1024).toFixed(2) + ' tb';
}

function shouldCheckFile(filename, cb) {
  if (MINSCANTIME > Date.now()) {
    return cb(true);
  }
  files.findById(filename, function (err, doc) {
    if (!err && doc && doc.crc32 && doc.scantime > MINSCANTIME) {
      return cb(false);
    }
    cb(true);
  });
}

function replace(filename, crc32, scantime, next) {
  files.updateById(filename, { crc32: crc32, scantime: scantime }, function (err, code) {
    if (!err && code === 1) {
      // success
      return next();
    }
    if (err) { throw err; }
    // Else probably did not exist, do an insert
    files.insert({ _id: filename, crc32: crc32, scantime: scantime }, function (err) {
      if (err) { throw err; }
      next();
    });
  });
}

function doCheck(next) {
  var scantime = Date.now();
  var last_print_time = Date.now();
  var count = 0;
  var count_since_print = 0;
  var errors = 0;
  var bytes_read = 0;
  var results = fs.createWriteStream('results.txt');
  results.write('# Scan start: ' + scantime + ' (' + new Date(scantime).toLocaleString() + ')');
  results.write('# Mismatches logged below\n');
  results.write('# First character command of i=ignore d=update database\n');
  results.write('# disk_crc expected source   path\n');

  walkDir(FOLDER, '/', function (relpath, stat, next) {
    ++count;
    ++count_since_print;
    var now = Date.now();
    if ((now - last_print_time) > 30000 || count_since_print > 15) {
      var dt = now - scantime;
      var bps = bytes_read * 1000 / dt;
      count_since_print = 0;
      last_print_time = now;
      console.log(clc.cyan('Checked ' + count + ' files, found '
        + (errors ? clc.yellowBright(errors) : errors)
        + ' error' + (errors === 1 ? '' : 's')
        + ', ' + formatBytes(bytes_read) + ', ' + formatBytes(bps) + '/s'
      ));
    }
    process.stdout.write('\r' + relpath);
    shouldCheckFile(relpath, function (should_check) {
      if (!should_check) {
        console.log('\r' + relpath + clc.blackBright(' -- skipping'));
        return next();
      }
      bytes_read += stat.size;
      crc32.crcFile(path.join(FOLDER, relpath), function (err, crc) {
        if (err) { throw err; }
        crc = formatCRC(crc);
        var line = '\r' + relpath + clc.blackBright(' -- CRC:' + crc);
        process.stdout.write(line);
        crcFromFilename(relpath, function (expected_crc, source) {
          if (!expected_crc) {
            console.log(line + clc.blue('  Inserting CRC into database'));
            replace(relpath, crc, scantime, next);
            return;
          }
          if (expected_crc === crc) {
            // Update database with scan time
            console.log(line + clc.blue('  Matches'));
            replace(relpath, crc, scantime, next);
            return;
          }
          console.log(line + clc.redBright('  CRC Mismatch, expected ' + expected_crc +
            ' from ' + source));
          errors++;
          results.write('d ' + crc + ' ' + expected_crc + ' ' + source + ' ' + relpath + '\n');
          next();
        });
      });
    });
  }, function () {
    var dt = Date.now() - scantime;
    var bps = bytes_read * 1000 / dt;
    console.log(clc.cyanBright('Done checking, ' + errors + ' errors'
      + ', took ' + Math.floor(dt / 1000 / 60) + ':' + pad2(Math.floor(dt / 1000))
      + ', ' + formatBytes(bytes_read) + ', ' + formatBytes(bps) + '/s'
    ));
    results.write('# Scan finish: ' + Date.now() + ' (' + new Date().toLocaleString() + ')');
    results.close();
    next();
  });
}

function doFix(next) {
  var s = linestream();
  var comment_regex = /^\w*#/;

  var mt = new MultiTask(next);

  var scantime = Date.now(); // TODO: grab from results.txt?
  s.on('data', function (line) {
    if (line.match(comment_regex)) {
      return;
    }
    var split = line.split(' ');
    if (split[0] === 'i') {
      return;
    }
    if (split[0] === 'd') {
      var disk_crc = split[1];
      var source = split[3];
      var filename = split.slice(4).join(' ');
      if (source === 'filename') {
        console.log(clc.red('Cannot update CRC from filename for "' + filename + '" disk crc=' + disk_crc));
        return;
      }
      console.log(clc.blue('Updating "' + filename + '" to ' + disk_crc));
      mt.dispatch();
      files.updateById(filename, { crc32: disk_crc, scantime: scantime }, function (err, doc) {
        if (err) { throw err; }
        console.log(clc.blueBright('Updated "' + filename + '" to ' + disk_crc));
        mt.done();
      });
    }
  });
  s.on('end', function () {
    mt.dispatchDone();
  });

  fs.createReadStream('results.txt').pipe(s);
}

if (args.check) {
  doCheck(function () {
    cleanup();
  });
} else if (args.fix) {
  doFix(function () {
    cleanup();
  });
}
<commit_msg>Better error handling, save old results files.<commit_after>/*jslint vars:true, nomen:true, indent:2, plusplus:true, unparam:true, stupid:true */
"use strict";
var crc32 = require('./crc32.js');
var clc = require('cli-color');
var fs = require('fs');
var path = require('path');
var monk = require('monk');
var linestream = require('line-stream');
var util = require('util');
var MultiTask = require('./multi_task.js');

var MINSCANTIME = 0; // Do not re-check any files which have been checked - for debugging
//var MINSCANTIME = Infinity; // Always recheck every file

var COLLECTION = 'diskcheck';
var FOLDER = '/var/data/diskcheck';

// var COLLECTION = 'test';
// var FOLDER = '/var/data/smb_private/CD Images/';

// var COLLECTION = 'test';
// var FOLDER = '/var/data/smb_stuff/Anime/Promos/';

var ArgumentParser = require('argparse').ArgumentParser;
var parser = new ArgumentParser({
  version: '0.0.1',
  addHelp: true,
  description: 'diskcheck'
});
parser.addArgument([ '-c', '--check' ], { help: 'Run check', action: 'storeTrue'});
parser.addArgument([ '-f', '--fix' ], { help: 'Fix mismatches', action: 'storeTrue'});
var args = parser.parseArgs();
if ((args.check && args.fix) || (!args.check && !args.fix)) {
  console.log('Expected exactly one of --check or --fix');
  process.exit();
}

var db = monk('localhost/diskcheck');
var files = db.get(COLLECTION);

function cleanup() {
  console.log('Cleaning up...');
  db.close();
}

// files.insert({ _id: 'foo.txt', crc: '12345678' }, function (err, doc) {
//   if (err) throw err;
// });
// files.findById('foo.txt', function (err, doc){
//     console.log(doc);
// });

// cb(relpath, stat, next)
function walkDir(base, dir, cb, dir_next) {
  fs.readdir(path.join(base, dir), function (err, files) {
    if (err) {
      throw err;
    }
    var idx = 0;
    function next() {
      if (idx === files.length) {
        return dir_next();
      }
      var filename = files[idx];
      ++idx;
      fs.stat(path.join(base, dir, filename), function (err, stat) {
        if (err) {
          throw err;
        }
        var sub_relpath = path.join(dir, filename);
        if (stat.isDirectory()) {
          walkDir(base, sub_relpath, cb, next);
        } else if (stat.isFile()) {
          cb(sub_relpath, stat, next);
        } else {
          console.log(filename);
          console.log(util.inspect(stat));
          throw "Unknown file type";
        }
      });
    }
    next();
  });
}

function formatCRC(crc) {
  if (crc < 0) {
    crc += 4294967296;
  }
  crc = crc.toString(16);
  while (crc.length < 8) {
    crc = '0' + crc;
  }
  return crc;
}

var crc_regex1 = /\[([0-9a-f]{8})\]/;
var crc_regex2 = /\[([0-9A-F]{8})\]/;
// next(crc || undefined, source)
function crcFromFilename(filename, next) {
  var m = filename.match(crc_regex1);
  if (m) {
    return next(m[1].toLowerCase(), 'filename');
  }
  m = filename.match(crc_regex2);
  if (m) {
    return next(m[1].toLowerCase(), 'filename');
  }
  files.findById(filename, function (err, doc) {
    if (err) {
      throw err;
    }
    if (doc && doc.crc32) {
      return next(doc.crc32, 'database');
    }
    next();
  });
}

function pad2(str) {
  return ('0' + str).slice(-2);
}

function formatBytes(bytes) {
  if (bytes === 1) {
    return '1 byte';
  }
  if (bytes < 1024) {
    return bytes.toFixed(0) + ' bytes';
  }
  if (bytes < 1024 * 1024) {
    return (bytes / 1024).toFixed(2) + ' kb';
  }
  if (bytes < 1024 * 1024 * 1024) {
    return (bytes / 1024 / 1024).toFixed(2) + ' mb';
  }
  if (bytes < 1024 * 1024 * 1024 * 1024) {
    return (bytes / 1024 / 1024 / 1024).toFixed(2) + ' gb';
  }
  return (bytes / 1024 / 1024 / 1024 / 1024).toFixed(2) + ' tb';
}

function shouldCheckFile(filename, cb) {
  if (MINSCANTIME > Date.now()) {
    return cb(true);
  }
  files.findById(filename, function (err, doc) {
    if (!err && doc && doc.crc32 && doc.scantime > MINSCANTIME) {
      return cb(false);
    }
    cb(true);
  });
}

function replace(filename, crc32, scantime, next) {
  files.updateById(filename, { crc32: crc32, scantime: scantime }, function (err, code) {
    if (!err && code === 1) {
      // success
      return next();
    }
    if (err) { throw err; }
    // Else probably did not exist, do an insert
    files.insert({ _id: filename, crc32: crc32, scantime: scantime }, function (err) {
      if (err) { throw err; }
      next();
    });
  });
}

function doCheck(next) {
  var scantime = Date.now();
  var last_print_time = Date.now();
  var count = 0;
  var count_since_print = 0;
  var errors = 0;
  var bytes_read = 0;
  if (fs.existsSync('results.txt')) {
    if (fs.existsSync('results.txt.1')) {
      if (fs.existsSync('results.txt.2')) {
        fs.unlinkSync('results.txt.2');
      }
      fs.renameSync('results.txt.1', 'results.txt.2');
    }
    fs.renameSync('results.txt', 'results.txt.1');
  }
  var results = fs.createWriteStream('results.txt');
  results.write('# Scan start: ' + scantime + ' (' + new Date(scantime).toLocaleString() + ')');
  results.write('# Mismatches logged below\n');
  results.write('# First character command of i=ignore d=update database\n');
  results.write('# disk_crc expected source   path\n');

  walkDir(FOLDER, '/', function (relpath, stat, next) {
    ++count;
    ++count_since_print;
    var now = Date.now();
    if ((now - last_print_time) > 30000 || count_since_print > 15) {
      var dt = now - scantime;
      var bps = bytes_read * 1000 / dt;
      count_since_print = 0;
      last_print_time = now;
      console.log(clc.cyan('Checked ' + count + ' files, found '
        + (errors ? clc.yellowBright(errors) : errors)
        + ' error' + (errors === 1 ? '' : 's')
        + ', ' + formatBytes(bytes_read) + ', ' + formatBytes(bps) + '/s'
      ));
    }
    process.stdout.write('\r' + relpath);
    shouldCheckFile(relpath, function (should_check) {
      if (!should_check) {
        console.log('\r' + relpath + clc.blackBright(' -- skipping'));
        return next();
      }
      bytes_read += stat.size;
      crc32.crcFile(path.join(FOLDER, relpath), function (err, crc) {
        if (err) {
          console.log('\r' + relpath + clc.redBright(' -- error reading file: ' + err));
          errors++;
          results.write('# read error ' + (err.code || '') + ' ' + relpath + '\n');
          return next();
        }
        crc = formatCRC(crc);
        var line = '\r' + relpath + clc.blackBright(' -- CRC:' + crc);
        process.stdout.write(line);
        crcFromFilename(relpath, function (expected_crc, source) {
          if (!expected_crc) {
            console.log(line + clc.blue('  Inserting CRC into database'));
            replace(relpath, crc, scantime, next);
            return;
          }
          if (expected_crc === crc) {
            // Update database with scan time
            console.log(line + clc.blue('  Matches'));
            replace(relpath, crc, scantime, next);
            return;
          }
          console.log(line + clc.redBright('  CRC Mismatch, expected ' + expected_crc +
            ' from ' + source));
          errors++;
          results.write('d ' + crc + ' ' + expected_crc + ' ' + source + ' ' + relpath + '\n');
          next();
        });
      });
    });
  }, function () {
    var dt = Date.now() - scantime;
    var bps = bytes_read * 1000 / dt;
    console.log(clc.cyanBright('Done checking, ' + errors + ' errors'
      + ', took ' + Math.floor(dt / 1000 / 60) + ':' + pad2(Math.floor(dt / 1000))
      + ', ' + formatBytes(bytes_read) + ', ' + formatBytes(bps) + '/s'
    ));
    results.write('# Scan finish: ' + Date.now() + ' (' + new Date().toLocaleString() + ')');
    results.close();
    next();
  });
}

function doFix(next) {
  var s = linestream();
  var comment_regex = /^\w*#/;

  var mt = new MultiTask(next);

  var scantime = Date.now(); // TODO: grab from results.txt?
  s.on('data', function (line) {
    if (line.match(comment_regex)) {
      return;
    }
    var split = line.split(' ');
    if (split[0] === 'i') {
      return;
    }
    if (split[0] === 'd') {
      var disk_crc = split[1];
      var source = split[3];
      var filename = split.slice(4).join(' ');
      if (source === 'filename') {
        console.log(clc.red('Cannot update CRC from filename for "' + filename + '" disk crc=' + disk_crc));
        return;
      }
      console.log(clc.blue('Updating "' + filename + '" to ' + disk_crc));
      mt.dispatch();
      files.updateById(filename, { crc32: disk_crc, scantime: scantime }, function (err, doc) {
        if (err) { throw err; }
        console.log(clc.blueBright('Updated "' + filename + '" to ' + disk_crc));
        mt.done();
      });
    }
  });
  s.on('end', function () {
    mt.dispatchDone();
  });

  fs.createReadStream('results.txt').pipe(s);
}

if (args.check) {
  doCheck(function () {
    cleanup();
  });
} else if (args.fix) {
  doFix(function () {
    cleanup();
  });
}
<|endoftext|>


<commit_before>console.log('Initial piece of the Dauria module.');<commit_msg>use a self-calling constructor as in http://habrahabr.ru/post/135027/<commit_after>var Dauria = function(){
   if (!(this instanceof Dauria)) return new Dauria();
};

module.exports = new Dauria();<|endoftext|>


<commit_before>var postcss = require('postcss');
module.exports = postcss.plugin('postcss-reverse-props', function (opts) {
    if (!opts) opts = {};
    opts.symbol = opts.symbol || '%@';
    return function (css) {
        function processNode(parent) {
            parent.walk(function (node) {
                if (node.type === 'atrule') {
                    processNode(node);
                } else if (node.type === 'rule') {
                    processNode(node);
                } else if (node.type === 'decl') {
                    if (node.value.indexOf(opts.symbol) !== -1) {
                        node.value =
                            node.value.replace(opts.symbol, parent.selector);
                    }
                }
            });
        }
        processNode(css);
    };
});
<commit_msg>changing plugin name<commit_after>var postcss = require('postcss');
module.exports = postcss.plugin('postcss-current-selector', function (opts) {
    if (!opts) opts = {};
    opts.symbol = opts.symbol || '%@';
    return function (css) {
        function processNode(parent) {
            parent.walk(function (node) {
                if (node.type === 'atrule') {
                    processNode(node);
                } else if (node.type === 'rule') {
                    processNode(node);
                } else if (node.type === 'decl') {
                    if (node.value.indexOf(opts.symbol) !== -1) {
                        node.value =
                            node.value.replace(opts.symbol, parent.selector);
                    }
                }
            });
        }
        processNode(css);
    };
});
<|endoftext|>


<commit_before>"use strict";

var path = require("path");

var gettextParser = require("gettext-parser");
var through = require("through2");
var acorn = require("acorn-jsx");
var walk = require("acorn/dist/walk");
var gutil = require("gulp-util");

var DEFAULT_FUNCTION_NAMES = {
    gettext: ["msgid"],
    dgettext: ["domain", "msgid"],
    ngettext: ["msgid", "msgid_plural", "count"],
    dngettext: ["domain", "msgid", "msgid_plural", "count"],
    pgettext: ["msgctxt", "msgid"],
    dpgettext: ["domain", "msgctxt", "msgid"],
    npgettext: ["msgctxt", "msgid", "msgid_plural", "count"],
    dnpgettext: ["domain", "msgctxt", "msgid", "msgid_plural", "count"]
};

var DEFAULT_HEADERS = {
    "content-type": "text/plain; charset=UTF-8",
    "plural-forms": "nplurals = 2; plural = (n != 1);"
};

var jsxBase = {
    JSXElement(node, st, c) {
        node.openingElement.attributes.forEach(function(attr) {
            c(attr, st, attr.type);
        });
        node.children.forEach(function(child) {
            c(child, st, child.type);
        });
    },
    JSXExpressionContainer(node, st, c) {
        c(node.expression, st, node.expression.type);
    },
    JSXAttribute(node, st, c) {
        if (node.value !== null) {
            c(node.value, st, node.value.type);
        }
    },
    JSXSpreadAttribute(node, st, c) {
        c(node.argument, st, node.argument.type);
    }
};
Object.setPrototypeOf(jsxBase, walk.base);

module.exports = function(opts) {

    var functionNames = opts.functionNames || DEFAULT_FUNCTION_NAMES;

    var data = {
        charset: "UTF-8",

        headers: opts.headers || DEFAULT_HEADERS,

        translations: {
            context: {
            }
        }
    };
    var defaultContext = data.translations.context;

    var headers = data.headers;
    headers["plural-forms"] = headers["plural-forms"] || DEFAULT_HEADERS["plural-forms"];
    headers["content-type"] = headers["content-type"] || DEFAULT_HEADERS["content-type"];

    var nplurals = /nplurals=(\d)/.exec(headers["plural-forms"])[1];

    var transform = through.obj(function(file, encoding, cb) {

        let src = file.contents.toString();

        var ast = acorn.parse(src, {
            ecmaVersion: 6,
            sourceType: "module",
            plugins: {jsx: true}
        });

        walk.simple(ast, {
            CallExpression: function(node) {
                if (functionNames.hasOwnProperty(node.callee.name)
                    || node.callee.property && functionNames.hasOwnProperty(node.callee.property.name)) {

                    var functionName = functionNames[node.callee.name] || functionNames[node.callee.property.name];
                    var translate = {};

                    var args = node.arguments;
                    for (var i = 0, l = args.length; i < l; i++) {
                        var name = functionName[i];

                        if (name && name !== "count" && name !== "domain") {
                            var arg = args[i];
                            var value = arg.value;

                            if (value) {
                                translate[name] = value;
                            }

                            if (name === "msgid_plural") {
                                translate.msgstr = [];
                                for (var p = 0; p < nplurals; p++) {
                                    translate.msgstr[p] = "";
                                }
                            }
                        }
                    }

                    var context = defaultContext;
                    var msgctxt = translate.msgctxt;
                    if (msgctxt) {
                        data.translations[msgctxt] = data.translations[msgctxt] || {};
                        context = data.translations[msgctxt];
                    }

                    context[translate.msgid] = translate;
                }
            }
        }, jsxBase);

        cb();
    },

    function(cb) {
        var file = new gutil.File({
            base: __dirname,
            cwd: __dirname,
            path: path.join(__dirname, "./gettext.po")
        });

        file.contents = gettextParser.po.compile(data);
        this.push(file);
        cb();
    });

    return transform;
};
<commit_msg>Fix regexp without space<commit_after>"use strict";

var path = require("path");

var gettextParser = require("gettext-parser");
var through = require("through2");
var acorn = require("acorn-jsx");
var walk = require("acorn/dist/walk");
var gutil = require("gulp-util");

var DEFAULT_FUNCTION_NAMES = {
    gettext: ["msgid"],
    dgettext: ["domain", "msgid"],
    ngettext: ["msgid", "msgid_plural", "count"],
    dngettext: ["domain", "msgid", "msgid_plural", "count"],
    pgettext: ["msgctxt", "msgid"],
    dpgettext: ["domain", "msgctxt", "msgid"],
    npgettext: ["msgctxt", "msgid", "msgid_plural", "count"],
    dnpgettext: ["domain", "msgctxt", "msgid", "msgid_plural", "count"]
};

var DEFAULT_HEADERS = {
    "content-type": "text/plain; charset=UTF-8",
    "plural-forms": "nplurals = 2; plural = (n != 1);"
};

var jsxBase = {
    JSXElement(node, st, c) {
        node.openingElement.attributes.forEach(function(attr) {
            c(attr, st, attr.type);
        });
        node.children.forEach(function(child) {
            c(child, st, child.type);
        });
    },
    JSXExpressionContainer(node, st, c) {
        c(node.expression, st, node.expression.type);
    },
    JSXAttribute(node, st, c) {
        if (node.value !== null) {
            c(node.value, st, node.value.type);
        }
    },
    JSXSpreadAttribute(node, st, c) {
        c(node.argument, st, node.argument.type);
    }
};
Object.setPrototypeOf(jsxBase, walk.base);

module.exports = function(opts) {

    var functionNames = opts.functionNames || DEFAULT_FUNCTION_NAMES;

    var data = {
        charset: "UTF-8",

        headers: opts.headers || DEFAULT_HEADERS,

        translations: {
            context: {
            }
        }
    };
    var defaultContext = data.translations.context;

    var headers = data.headers;
    headers["plural-forms"] = headers["plural-forms"] || DEFAULT_HEADERS["plural-forms"];
    headers["content-type"] = headers["content-type"] || DEFAULT_HEADERS["content-type"];

    var nplurals = /nplurals ?= ?(\d)/.exec(headers["plural-forms"])[1];

    var transform = through.obj(function(file, encoding, cb) {

        let src = file.contents.toString();

        var ast = acorn.parse(src, {
            ecmaVersion: 6,
            sourceType: "module",
            plugins: {jsx: true}
        });

        walk.simple(ast, {
            CallExpression: function(node) {
                if (functionNames.hasOwnProperty(node.callee.name)
                    || node.callee.property && functionNames.hasOwnProperty(node.callee.property.name)) {

                    var functionName = functionNames[node.callee.name] || functionNames[node.callee.property.name];
                    var translate = {};

                    var args = node.arguments;
                    for (var i = 0, l = args.length; i < l; i++) {
                        var name = functionName[i];

                        if (name && name !== "count" && name !== "domain") {
                            var arg = args[i];
                            var value = arg.value;

                            if (value) {
                                translate[name] = value;
                            }

                            if (name === "msgid_plural") {
                                translate.msgstr = [];
                                for (var p = 0; p < nplurals; p++) {
                                    translate.msgstr[p] = "";
                                }
                            }
                        }
                    }

                    var context = defaultContext;
                    var msgctxt = translate.msgctxt;
                    if (msgctxt) {
                        data.translations[msgctxt] = data.translations[msgctxt] || {};
                        context = data.translations[msgctxt];
                    }

                    context[translate.msgid] = translate;
                }
            }
        }, jsxBase);

        cb();
    },

    function(cb) {
        var file = new gutil.File({
            base: __dirname,
            cwd: __dirname,
            path: path.join(__dirname, "./gettext.po")
        });

        file.contents = gettextParser.po.compile(data);
        this.push(file);
        cb();
    });

    return transform;
};
<|endoftext|>


<commit_before>const fs = require("fs");
const path = require("path");
const combyne = require("combyne");
const async = require("async");

var support = {};

// Mimic how the actual Combyne stores.
support._filters = {};
support._partials = {};

// Proxy the filter and partial registration methods.
support.registerFilter = combyne.prototype.registerFilter;
support.registerPartial = combyne.prototype.registerPartial;

/**
 * Recursively traverses nodes returning those passing the truth function.
 *
 * @private
 * @param {array} nodes
 * @param {function} test
 * @returns {array} An array of nodes.
 */
function recurse(nodes, test) {
  var memo = [];

  if (!nodes) {
    return memo;
  }

  nodes.forEach(function(node) {
    if (test(node)) {
      memo.push(node);
    }

    memo.push.apply(memo, recurse(node.nodes, test, memo));
  });

  return memo;
}

/**
 * Express support.
 *
 * @param {string} fileName - The template path to load.
 * @param {object} data - The data to render.
 * @param {function} next - The continuation function.
 */
support.__express = function(fileName, data, next) {
  var dirname = path.dirname(fileName);
  var ext = path.extname(fileName);

  // Read in the template name as a buffer.
  fs.readFile(fileName, "utf8", function(err, buffer) {
    // Pass up any errors.
    if (err) {
      return next(err);
    }

    // Send back the compiled template.
    var template = combyne(String(buffer));

    // Find all renders.
    var renders = recurse(template.tree.nodes, function(node) {
      return node.type === "RenderExpression";
    }).map(function(node) { return node.value; });

    // Find all partials.
    var partials = recurse(template.tree.nodes, function(node) {
      return node.type === "PartialExpression";
    }).map(function(node) { return node.value; });

    // Find all filters.
    var filters = recurse(template.tree.nodes, function(node) {
      return node.filters && node.filters.length;
    }).map(function(node) {
      return node.filters.map(function(filter) {
        return filter.value;
      }).join(" ");
    });

    // Flatten the array.
    if (filters.length) {
      filters = filters.join(" ").split(" ");
    }

    // Map all renders to functions.
    renders = renders.map(function(render) {
      return function(callback) {
        var name = render.template;
        var renderPath = path.join(dirname, name + ext);

        fs.readFile(renderPath, "utf8", function(err, contents) {
          template.registerPartial(name, combyne(String(contents)));
          callback(err);
        });
      };
    });

    // Map all partials to functions.
    partials = partials.map(function(name) {
      return function(callback) {
        // Ignore those that have already been defined globally.
        if (name in support._partials) {
          return callback();
        }

        fs.readFile(path.join(dirname, name + ext), function(err, partial) {
          template.registerPartial(name, combyne(String(partial)));
          callback(err);
        });
      };
    });

    // Map all filters to functions.
    filters = filters.map(function(name) {
      // Filters cannot be so easily inferred location-wise, so assume they are
      // preconfigured or exist in a filters directory.
      return function(callback) {
        var filtersDir = support.filtersDir || "filters";
        var filtersPath = path.join(dirname, filtersDir, name + ".js");

        // Ignore those that have already been defined globally.
        if (name in support._filters) {
          return callback();
        }

        // Register the exported function.
        template.registerFilter(name, require(filtersPath));
        callback(err);
      };
    });

    // Find all files and map the partials.
    async.parallel(partials.concat(renders, filters), function(err) {
      // Register all the global partials.
      Object.keys(support._partials).forEach(function(name) {
        var partial = support._partials[name];
        template.registerPartial(name, partial);
      });

      // Register all the global filters.
      Object.keys(support._filters).forEach(function(name) {
        var filter = support._filters[name];
        template.registerFilter(name, filter);
      });

      // Render the template.
      next(null, template.render(data));
    });
  });
};

// Expose configuration express support.
module.exports = function(options) {
  support.__proto__ = options;
  return support.__express;
};

// Ensure support is accessible.
module.exports.__proto__ = support;

module.exports.VERSION = require("./package.json").version;
<commit_msg>Proxy the settings for the internal combyne object.<commit_after>const fs = require("fs");
const path = require("path");
const combyne = require("combyne");
const async = require("async");

var support = {};

// Mimic how the actual Combyne stores.
support._filters = {};
support._partials = {};

// Proxy the filter and partial registration methods.
support.registerFilter = combyne.prototype.registerFilter;
support.registerPartial = combyne.prototype.registerPartial;

// Proxy the settings from the internal combyne object
support.settings = combyne.settings;

/**
 * Recursively traverses nodes returning those passing the truth function.
 *
 * @private
 * @param {array} nodes
 * @param {function} test
 * @returns {array} An array of nodes.
 */
function recurse(nodes, test) {
  var memo = [];

  if (!nodes) {
    return memo;
  }

  nodes.forEach(function(node) {
    if (test(node)) {
      memo.push(node);
    }

    memo.push.apply(memo, recurse(node.nodes, test, memo));
  });

  return memo;
}

/**
 * Express support.
 *
 * @param {string} fileName - The template path to load.
 * @param {object} data - The data to render.
 * @param {function} next - The continuation function.
 */
support.__express = function(fileName, data, next) {
  var dirname = path.dirname(fileName);
  var ext = path.extname(fileName);

  // Read in the template name as a buffer.
  fs.readFile(fileName, "utf8", function(err, buffer) {
    // Pass up any errors.
    if (err) {
      return next(err);
    }

    // Send back the compiled template.
    var template = combyne(String(buffer));

    // Find all renders.
    var renders = recurse(template.tree.nodes, function(node) {
      return node.type === "RenderExpression";
    }).map(function(node) { return node.value; });

    // Find all partials.
    var partials = recurse(template.tree.nodes, function(node) {
      return node.type === "PartialExpression";
    }).map(function(node) { return node.value; });

    // Find all filters.
    var filters = recurse(template.tree.nodes, function(node) {
      return node.filters && node.filters.length;
    }).map(function(node) {
      return node.filters.map(function(filter) {
        return filter.value;
      }).join(" ");
    });

    // Flatten the array.
    if (filters.length) {
      filters = filters.join(" ").split(" ");
    }

    // Map all renders to functions.
    renders = renders.map(function(render) {
      return function(callback) {
        var name = render.template;
        var renderPath = path.join(dirname, name + ext);

        fs.readFile(renderPath, "utf8", function(err, contents) {
          template.registerPartial(name, combyne(String(contents)));
          callback(err);
        });
      };
    });

    // Map all partials to functions.
    partials = partials.map(function(name) {
      return function(callback) {
        // Ignore those that have already been defined globally.
        if (name in support._partials) {
          return callback();
        }

        fs.readFile(path.join(dirname, name + ext), function(err, partial) {
          template.registerPartial(name, combyne(String(partial)));
          callback(err);
        });
      };
    });

    // Map all filters to functions.
    filters = filters.map(function(name) {
      // Filters cannot be so easily inferred location-wise, so assume they are
      // preconfigured or exist in a filters directory.
      return function(callback) {
        var filtersDir = support.filtersDir || "filters";
        var filtersPath = path.join(dirname, filtersDir, name + ".js");

        // Ignore those that have already been defined globally.
        if (name in support._filters) {
          return callback();
        }

        // Register the exported function.
        template.registerFilter(name, require(filtersPath));
        callback(err);
      };
    });

    // Find all files and map the partials.
    async.parallel(partials.concat(renders, filters), function(err) {
      // Register all the global partials.
      Object.keys(support._partials).forEach(function(name) {
        var partial = support._partials[name];
        template.registerPartial(name, partial);
      });

      // Register all the global filters.
      Object.keys(support._filters).forEach(function(name) {
        var filter = support._filters[name];
        template.registerFilter(name, filter);
      });

      // Render the template.
      next(null, template.render(data));
    });
  });
};

// Expose configuration express support.
module.exports = function(options) {
  support.__proto__ = options;
  return support.__express;
};

// Ensure support is accessible.
module.exports.__proto__ = support;

module.exports.VERSION = require("./package.json").version;
<|endoftext|>


<commit_before>'use strict';
/* eslint-env node */
var SassCompilerFactory = require('broccoli-sass-source-maps');
var path = require('path');
var VersionChecker = require('ember-cli-version-checker');
var Funnel = require('broccoli-funnel');
var mergeTrees = require('broccoli-merge-trees');

function SASSPlugin(optionsFn) {
  this.name = 'ember-cli-sass';
  this.optionsFn = optionsFn;
  this.ext = ['scss', 'sass'];
}

SASSPlugin.prototype.toTree = function(tree, inputPath, outputPath, inputOptions) {
  var options = Object.assign({}, this.optionsFn(), inputOptions);
  var inputTrees;

  if (options.onlyIncluded) {
    inputTrees = [new Funnel(tree, {
      include: ['app/styles/**/*'],
      annotation: 'Funnel (styles)'
    })];
  }
  else {
    inputTrees = [tree];
  }

  if (options.includePaths) {
    inputTrees = inputTrees.concat(options.includePaths);
  }

  if (!options.implementation) {
    try {
      // eslint-disable-next-line node/no-unpublished-require
      options.implementation = require('sass');
    } catch (e) {
      var error = new Error(
        'Could not find the default SASS implementation. Run the default blueprint:\n' +
        '   ember g ember-cli-sass\n' +
        'Or install an implementation such as "node-sass" and add an implementation option. For example:\n' +
        '   sassOptions: {implementation: require("node-sass")}');
      error.type = 'Sass Plugin Error';

      throw error;
    }
  }

  var SassCompiler = SassCompilerFactory(options.implementation);
  var ext = options.extension || 'scss';
  var paths = options.outputPaths;
  var trees = Object.keys(paths).map(function(file) {
    var input = path.join(inputPath, file + '.' + ext);
    var output = paths[file];
    return new SassCompiler(inputTrees, input, output, options);
  });

  if (options.passthrough) {
    trees.push(new Funnel(tree, options.passthrough));
  }

  return mergeTrees(trees);
};

module.exports = {
  name:  'ember-cli-sass',

  shouldSetupRegistryInIncluded: function() {
    let checker = new VersionChecker(this);
    return !checker.for('ember-cli').isAbove('0.2.0');
  },

  sassOptions: function () {
    var env  = process.env.EMBER_ENV;
    var envConfig = this.project.config(env).sassOptions;

    // *Either* use the options for an addon which is consuming this, *or* for
    // an app which is consuming this, but never *both* at the same time. The
    // special case here is when testing an addon.
    var options = (this.app && this.app.options && this.app.options.sassOptions)
      || (this.parent && this.parent.options && this.parent.options.sassOptions)
      || {};

    if (envConfig) {
      console.warn("Deprecation warning: sassOptions should be moved to your ember-cli-build"); // eslint-disable-line
      Object.assign(options, envConfig);
    }

    if ((options.sourceMap === undefined) && (env == 'development')) {
      options.sourceMap = true;
    }

    if (options.sourceMap || options.sourceMapEmbed) {
      // we need to embed the sourcesContent in the source map until libsass has better support for broccoli-sass
      options.sourceMapContents = true;
    }

    options.outputFile = options.outputFile || this.project.name() + '.css';
    options.sourceMapRoot = path.join(this.project.root, 'app/styles');

    return options;
  },

  setupPreprocessorRegistry: function(type, registry) {
    registry.add('css', new SASSPlugin(this.sassOptions.bind(this)));

    // prevent conflict with broccoli-sass if it's installed
    if (registry.remove) registry.remove('css', 'broccoli-sass');
  },

  included: function included(app) {
    this._super.included.apply(this, arguments);

    // see: https://github.com/ember-cli/ember-cli/issues/3718
    if (typeof app.import !== 'function' && app.app) {
      app = app.app;
    }

    this.app = app;

    if (this.shouldSetupRegistryInIncluded()) {
      this.setupPreprocessorRegistry('parent', app.registry);
    }
  }
};
<commit_msg>Fall back to host config in engines<commit_after>'use strict';
/* eslint-env node */
var SassCompilerFactory = require('broccoli-sass-source-maps');
var path = require('path');
var VersionChecker = require('ember-cli-version-checker');
var Funnel = require('broccoli-funnel');
var mergeTrees = require('broccoli-merge-trees');

function SASSPlugin(optionsFn) {
  this.name = 'ember-cli-sass';
  this.optionsFn = optionsFn;
  this.ext = ['scss', 'sass'];
}

SASSPlugin.prototype.toTree = function(tree, inputPath, outputPath, inputOptions) {
  var options = Object.assign({}, this.optionsFn(), inputOptions);
  var inputTrees;

  if (options.onlyIncluded) {
    inputTrees = [new Funnel(tree, {
      include: ['app/styles/**/*'],
      annotation: 'Funnel (styles)'
    })];
  }
  else {
    inputTrees = [tree];
  }

  if (options.includePaths) {
    inputTrees = inputTrees.concat(options.includePaths);
  }

  if (!options.implementation) {
    try {
      // eslint-disable-next-line node/no-unpublished-require
      options.implementation = require('sass');
    } catch (e) {
      var error = new Error(
        'Could not find the default SASS implementation. Run the default blueprint:\n' +
        '   ember g ember-cli-sass\n' +
        'Or install an implementation such as "node-sass" and add an implementation option. For example:\n' +
        '   sassOptions: {implementation: require("node-sass")}');
      error.type = 'Sass Plugin Error';

      throw error;
    }
  }

  var SassCompiler = SassCompilerFactory(options.implementation);
  var ext = options.extension || 'scss';
  var paths = options.outputPaths;
  var trees = Object.keys(paths).map(function(file) {
    var input = path.join(inputPath, file + '.' + ext);
    var output = paths[file];
    return new SassCompiler(inputTrees, input, output, options);
  });

  if (options.passthrough) {
    trees.push(new Funnel(tree, options.passthrough));
  }

  return mergeTrees(trees);
};

module.exports = {
  name:  'ember-cli-sass',

  shouldSetupRegistryInIncluded: function() {
    let checker = new VersionChecker(this);
    return !checker.for('ember-cli').isAbove('0.2.0');
  },

  sassOptions: function () {
    var env  = process.env.EMBER_ENV;
    var envConfig = this.project.config(env).sassOptions;

    var app = this.app;
    var parent = this.parent;
    var hostApp = typeof this._findHost === 'function' ? this._findHost() : undefined;

    // *Either* use the options for an addon which is consuming this, *or* for
    // an app which is consuming this, but never *both* at the same time. The
    // special case here is when testing an addon.
    // In lazy loading engines, the host might be different from the parent, so we fall back to that one
    var options = (app && app.options && app.options.sassOptions)
      || (parent && parent.options && parent.options.sassOptions)
      || (hostApp && hostApp.options && hostApp.options.sassOptions)
      || {};

    if (envConfig) {
      console.warn("Deprecation warning: sassOptions should be moved to your ember-cli-build"); // eslint-disable-line
      Object.assign(options, envConfig);
    }

    if ((options.sourceMap === undefined) && (env == 'development')) {
      options.sourceMap = true;
    }

    if (options.sourceMap || options.sourceMapEmbed) {
      // we need to embed the sourcesContent in the source map until libsass has better support for broccoli-sass
      options.sourceMapContents = true;
    }

    options.outputFile = options.outputFile || this.project.name() + '.css';
    options.sourceMapRoot = path.join(this.project.root, 'app/styles');

    return options;
  },

  setupPreprocessorRegistry: function(type, registry) {
    registry.add('css', new SASSPlugin(this.sassOptions.bind(this)));

    // prevent conflict with broccoli-sass if it's installed
    if (registry.remove) registry.remove('css', 'broccoli-sass');
  },

  included: function included(app) {
    this._super.included.apply(this, arguments);

    // see: https://github.com/ember-cli/ember-cli/issues/3718
    if (typeof app.import !== 'function' && app.app) {
      app = app.app;
    }

    this.app = app;

    if (this.shouldSetupRegistryInIncluded()) {
      this.setupPreprocessorRegistry('parent', app.registry);
    }
  }
};
<|endoftext|>


<commit_before>var EventEmitter = require('events').EventEmitter;
var uuid = require('node-uuid');
var streams = require('zetta-streams');
var ObjectStream = streams.ObjectStream;
var BinaryStream = streams.BinaryStream;
var ConsumerStream = streams.ConsumerStream;

var Device = module.exports = function Device() {
  this.id = uuid.v4();

  this.streams = {}; // has __getter__ for consumer streams
  this._streams = {}; // has actual streams supplied to .stream and .monitor
  this._emitter = new EventEmitter();
  this._allowed = {};
  this._transitions = {};
  this._monitors = [];
  this._pubsub = null;
  this._log = null;

  var self = this;
  this.on = function(type, handler) {
    self._emitter.on(type, handler);
  }.bind(this);

  // TODO: Namespace this as something weird so there's no accidental override.
  this.call = this.call.bind(this);
  this.emit = this._emitter.emit.bind(this._emitter);
};

Device.prototype._generate = function(config) {
  var self = this;
  this.type = config._type;
  this.name = config._name;
  this._state = config._state;
  this._transitions = config.transitions;
  this._allowed = config.allowed;

  if (Object.keys(this._transitions).length) {
    var stateStream = self._createStream('state', ObjectStream);
    Object.defineProperty(this, 'state', {
      get: function(){
        return self._state;
      },
      set: function(newValue){
        self._state = newValue;
        stateStream.write(newValue);
      }
    });
  }

  this._monitors = [];
  config.monitors.forEach(function(name) {
    self._initMonitor(name);
    self._monitors.push(name);
  });

  Object.keys(config.streams).forEach(function(name) {
    var s = config.streams[name];
    self._initStream(name, s.handler, s.options);
  });

};

Device.prototype.call = function(/* type, ...args */) {
  var args = Array.prototype.slice.call(arguments);
  var type = args[0];
  var next = args[args.length-1];

  var rest = null;
  if(typeof next !== 'function') {
    next = function(err){
      if (err) {
        throw err;
      }
    };
    rest = args.slice(1, args.length);
  } else {
    rest = args.slice(1, args.length - 1);
  }

  var self = this;
  var cb = function callback() {
    var cbArgs = Array.prototype.slice.call(arguments);
    cbArgs.unshift(type);
    self._emitter.emit.apply(self._emitter, cbArgs);

    var args = [];
    if (self._transitions[type].fields) {
      self._transitions[type].fields.forEach(function(field, idx) {
        args.push({ name: field.name, value: rest[idx] });
      });
    }

    var topic = self.type + '/' + self.id + '/logs';
    var json = ObjectStream.format(topic, null);
    delete json.data;
    json.transition = type;
    json.input = args;
    json.properties = self.properties();
    json.transitions = self.transitionsAvailable();

    self._pubsub.publish(topic, json);
    self._log.emit('log', 'device', self.type + ' transition ' + type, json);

    next.apply(next, arguments);
  };
  var handlerArgs = rest.concat([cb]);
  if (this._transitions[type]) {
    if(this._transitions[type].handler === undefined){
      return next(new Error('Machine does not implement transition '+type));
    }
    var state = self.state;
    var allowed = this._allowed[state];
    if (allowed.indexOf(type) > -1) {
      this._transitions[type].handler.apply(this, handlerArgs);
    } else {
      next(new Error('Machine cannot use transition ' + type + ' while in ' + state));
    }
  }
};

Device.prototype.properties = function() {
  var properties = {};
  var self = this;

  var reserved = ['streams'];

  Object.keys(self).forEach(function(key) {
    if (reserved.indexOf(key) === -1 && typeof self[key] !== 'function' && key[0] !== '_') {
      properties[key] = self[key];
    }
  });

  this._monitors.forEach(function(name) {
    properties[name] = self[name];
  });

  properties.state = this.state;

  return properties;
};

Device.prototype.save = function(cb) {
  this._registry.save(this, cb);
};

Device.prototype._initMonitor = function(queueName) {
  var stream = this._createStream(queueName, ObjectStream);
  var self = this;
  var value = this[queueName]; // initialize value
  Object.defineProperty(this, queueName, {
    get: function(){
      return value;
    },
    set: function(newValue){
      value = newValue;
      stream.write(newValue);
    }
  });
  return this;
};

Device.prototype._initStream = function(queueName, handler, options) {
  if (!options) {
    options = {};
  }
  var Type = (options.binary) ? BinaryStream : ObjectStream;
  var stream = this._createStream(queueName, Type);
  handler.call(this, stream);
  return this;
};

Device.prototype._createStream = function(name, StreamType) {
  var self = this;
  var queue = this.type + '/' + this.id + '/' + name;
  var stream = new StreamType(queue, {}, this._pubsub);
  this._streams[name] = stream;

  Object.defineProperty(this.streams, name, {
    get: function(){
      return new ConsumerStream(queue, { objectMode: stream._writableState.objectMode }, self._pubsub);
    }
  });

  return stream;
};

Device.prototype.transitionsAvailable = function() {
  var self = this;
  var allowed = this._allowed[this.state];
  var ret = {};
  Object.keys(this._transitions).forEach(function(name) {
    if (allowed && allowed.indexOf(name) > -1) {
      ret[name] = self._transitions[name];
    }
  });

  return ret;
};
<commit_msg>Checking for error in transitions cb, not calling log/pubsub if present<commit_after>var EventEmitter = require('events').EventEmitter;
var uuid = require('node-uuid');
var streams = require('zetta-streams');
var ObjectStream = streams.ObjectStream;
var BinaryStream = streams.BinaryStream;
var ConsumerStream = streams.ConsumerStream;

var Device = module.exports = function Device() {
  this.id = uuid.v4();

  this.streams = {}; // has __getter__ for consumer streams
  this._streams = {}; // has actual streams supplied to .stream and .monitor
  this._emitter = new EventEmitter();
  this._allowed = {};
  this._transitions = {};
  this._monitors = [];
  this._pubsub = null;
  this._log = null;

  var self = this;
  this.on = function(type, handler) {
    self._emitter.on(type, handler);
  }.bind(this);

  // TODO: Namespace this as something weird so there's no accidental override.
  this.call = this.call.bind(this);
  this.emit = this._emitter.emit.bind(this._emitter);
};

Device.prototype._generate = function(config) {
  var self = this;
  this.type = config._type;
  this.name = config._name;
  this._state = config._state;
  this._transitions = config.transitions;
  this._allowed = config.allowed;

  if (Object.keys(this._transitions).length) {
    var stateStream = self._createStream('state', ObjectStream);
    Object.defineProperty(this, 'state', {
      get: function(){
        return self._state;
      },
      set: function(newValue){
        self._state = newValue;
        stateStream.write(newValue);
      }
    });
  }

  this._monitors = [];
  config.monitors.forEach(function(name) {
    self._initMonitor(name);
    self._monitors.push(name);
  });

  Object.keys(config.streams).forEach(function(name) {
    var s = config.streams[name];
    self._initStream(name, s.handler, s.options);
  });

};

Device.prototype.call = function(/* type, ...args */) {
  var args = Array.prototype.slice.call(arguments);
  var type = args[0];
  var next = args[args.length-1];

  var rest = null;
  if(typeof next !== 'function') {
    next = function(err){
      if (err) {
        throw err;
      }
    };
    rest = args.slice(1, args.length);
  } else {
    rest = args.slice(1, args.length - 1);
  }

  var self = this;
  var cb = function callback(err) {
    if (err) {
      next(err);
      return;
    }

    var cbArgs = Array.prototype.slice.call(arguments);
    cbArgs.unshift(type);
    self._emitter.emit.apply(self._emitter, cbArgs);

    var args = [];
    if (self._transitions[type].fields) {
      self._transitions[type].fields.forEach(function(field, idx) {
        args.push({ name: field.name, value: rest[idx] });
      });
    }

    var topic = self.type + '/' + self.id + '/logs';
    var json = ObjectStream.format(topic, null);
    delete json.data;
    json.transition = type;
    json.input = args;
    json.properties = self.properties();
    json.transitions = self.transitionsAvailable();

    self._pubsub.publish(topic, json);
    self._log.emit('log', 'device', self.type + ' transition ' + type, json);

    next.apply(next, arguments);
  };
  var handlerArgs = rest.concat([cb]);
  if (this._transitions[type]) {
    if(this._transitions[type].handler === undefined){
      return next(new Error('Machine does not implement transition '+type));
    }
    var state = self.state;
    var allowed = this._allowed[state];
    if (allowed.indexOf(type) > -1) {
      this._transitions[type].handler.apply(this, handlerArgs);
    } else {
      next(new Error('Machine cannot use transition ' + type + ' while in ' + state));
    }
  }
};

Device.prototype.properties = function() {
  var properties = {};
  var self = this;

  var reserved = ['streams'];

  Object.keys(self).forEach(function(key) {
    if (reserved.indexOf(key) === -1 && typeof self[key] !== 'function' && key[0] !== '_') {
      properties[key] = self[key];
    }
  });

  this._monitors.forEach(function(name) {
    properties[name] = self[name];
  });

  properties.state = this.state;

  return properties;
};

Device.prototype.save = function(cb) {
  this._registry.save(this, cb);
};

Device.prototype._initMonitor = function(queueName) {
  var stream = this._createStream(queueName, ObjectStream);
  var self = this;
  var value = this[queueName]; // initialize value
  Object.defineProperty(this, queueName, {
    get: function(){
      return value;
    },
    set: function(newValue){
      value = newValue;
      stream.write(newValue);
    }
  });
  return this;
};

Device.prototype._initStream = function(queueName, handler, options) {
  if (!options) {
    options = {};
  }
  var Type = (options.binary) ? BinaryStream : ObjectStream;
  var stream = this._createStream(queueName, Type);
  handler.call(this, stream);
  return this;
};

Device.prototype._createStream = function(name, StreamType) {
  var self = this;
  var queue = this.type + '/' + this.id + '/' + name;
  var stream = new StreamType(queue, {}, this._pubsub);
  this._streams[name] = stream;

  Object.defineProperty(this.streams, name, {
    get: function(){
      return new ConsumerStream(queue, { objectMode: stream._writableState.objectMode }, self._pubsub);
    }
  });

  return stream;
};

Device.prototype.transitionsAvailable = function() {
  var self = this;
  var allowed = this._allowed[this.state];
  var ret = {};
  Object.keys(this._transitions).forEach(function(name) {
    if (allowed && allowed.indexOf(name) > -1) {
      ret[name] = self._transitions[name];
    }
  });

  return ret;
};
<|endoftext|>


<commit_before>var icicle = require('icicle');

/** environment guarant */
var $ = typeof jQuery === 'undefined' ? undefined : jQuery;
var doc = typeof document === 'undefined' ? undefined : document;
var win = typeof window === 'undefined' ? undefined : window;

/** Lists of methods */
var onNames = ['on', 'bind', 'addEventListener', 'addListener'];
var oneNames = ['one', 'once', 'addOnceEventListener', 'addOnceListener'];
var offNames = ['off', 'unbind', 'removeEventListener', 'removeListener'];
var emitNames = ['emit', 'trigger', 'fire', 'dispatchEvent'];

/** Locker flags */
var emitFlag = emitNames[0], onFlag = onNames[0], oneFlag = onNames[0], offFlag = offNames[0];

/**
 * @constructor
 *
 * Main EventEmitter interface.
 * Wraps any target passed to an Emitter interface
 */
function Emmy(target){
	if (!target) return;

	//create emitter methods on target, if none
	if (!getMethodOneOf(target, onNames)) target.on = EmmyPrototype.on.bind(target);
	if (!getMethodOneOf(target, offNames)) target.off = EmmyPrototype.off.bind(target);
	if (!getMethodOneOf(target, oneNames)) target.one = target.once = EmmyPrototype.one.bind(target);
	if (!getMethodOneOf(target, emitNames)) target.emit = EmmyPrototype.emit.bind(target);

	return target;
}

/** Make DOM objects be wrapped as jQuery objects, if jQuery is enabled */
var EmmyPrototype = Emmy.prototype;

/**
 * Return target’s method one of the passed in list, if target is eventable
 * Use to detect whether target has some fn
 */
function getMethodOneOf(target, list){
	var result;
	for (var i = 0, l = list.length; i < l; i++) {
		result = target[list[i]];
		if (result) return result;
	}
}

/** Set of target callbacks, {target: [cb1, cb2, ...]} */
var targetCbCache = new WeakMap;

/**
* Bind fn to the target
* @todo  recognize jquery object
* @chainable
*/
EmmyPrototype.on =
EmmyPrototype.addEventListener = function(evt, fn){
	var target = this;

	//walk by list of instances
	if (fn instanceof Array){
		for (var i = fn.length; i--;){
			EmmyPrototype.on.call(target, evt, fn[i]);
		}
		return target;
	}

	//target events
	var onMethod = getMethodOneOf(target, onNames);

	//use target event system, if possible
	//avoid self-recursions from the outside
	if (onMethod) {
		//if it’s frozen - ignore call
		if (icicle.freeze(target, onFlag)){
			onMethod.call(target, evt, fn);
			icicle.unfreeze(target, onFlag);
			return target;
		}
	}

	//Save callback
	//ensure callbacks array for target exists
	if (!targetCbCache.has(target)) targetCbCache.set(target, {});
	var targetCallbacks = targetCbCache.get(target);

	(targetCallbacks[evt] = targetCallbacks[evt] || []).push(fn);

	return target;
};

/**
 * Add an event listener that will be invoked once and then removed.
 *
 * @return {Emmy}
 * @chainable
 */
EmmyPrototype.once =
EmmyPrototype.one = function(evt, fn){
	var target = this;

	//walk by list of instances
	if (fn instanceof Array){
		for (var i = fn.length; i--;){
			EmmyPrototype.one.call(target, evt, fn[i]);
		}
		return;
	}

	//target events
	var oneMethod = getMethodOneOf(target, oneNames);

	//use target event system, if possible
	//avoid self-recursions from the outside
	if (oneMethod) {
		if (icicle.freeze(target, oneFlag)){
			//use target event system, if possible
			oneMethod.call(target, evt, fn);
			icicle.unfreeze(target, oneFlag);
			return target;
		}
	}

	//wrap callback to once-call
	function cb() {
		EmmyPrototype.off.call(target, evt, fn);
		fn.apply(target, arguments);
	}

	cb.fn = fn;

	EmmyPrototype.on.call(target, evt, cb);

	return target;
};

/**
* Bind fn to a target
* @chainable
*/
EmmyPrototype.off =
EmmyPrototype.removeListener =
EmmyPrototype.removeAllListeners =
EmmyPrototype.removeEventListener = function (evt, fn){
	var target = this;

	//unbind all listeners passed
	if (fn instanceof Array){
		for (var i = fn.length; i--;){
			EmmyPrototype.off.call(target, evt, fn[i]);
		}
		return target;
	}

	//unbind all listeners if no fn specified
	if (fn === undefined) {
		var callbacks = targetCbCache.get(target);
		if (!callbacks) return target;
		//unbind all if no evtRef defined
		if (evt === undefined) {
			for (var evtName in callbacks) {
				EmmyPrototype.off.call(target, evtName, callbacks[evtName]);
			}
		}
		else if (callbacks[evt]) {
			EmmyPrototype.off.call(target, evt, callbacks[evt]);
		}
		return target;
	}

	//target events
	var offMethod = getMethodOneOf(target, offNames);

	//use target event system, if possible
	//avoid self-recursion from the outside
	if (offMethod) {
		//if it’s frozen - ignore call
		if (icicle.freeze(target, offFlag)){
			offMethod.call(target, evt, fn);
			icicle.unfreeze(target, offFlag);
			return target;
		}
	}

	//Forget callback
	//ignore if no event specified
	if (!targetCbCache.has(target)) return;

	var evtCallbacks = targetCbCache.get(target)[evt];

	if (!evtCallbacks) return;

	//remove specific handler
	for (var i = 0; i < evtCallbacks.length; i++) {
		if (evtCallbacks[i] === fn || evtCallbacks[i].fn === fn) {
			evtCallbacks.splice(i, 1);
			break;
		}
	}

	return target;
};

/**
* Event trigger
* @chainable
*/
EmmyPrototype.emit =
EmmyPrototype.dispatchEvent = function(eventName, data, bubbles){
	var target = this, emitMethod, evt = eventName;
	if (!target) return;

	//Create proper event for DOM objects
	if (target.nodeType || target === doc || target === win) {
		//NOTE: this doesnot bubble on disattached elements

		if (eventName instanceof Event) {
			evt = eventName;
		} else {
			evt =  document.createEvent('CustomEvent');
			evt.initCustomEvent(eventName, bubbles, true, data);
		}

		// var evt = new CustomEvent(eventName, { detail: data, bubbles: bubbles })

		emitMethod = target.dispatchEvent;
	}

	//create event for jQuery object
	else if ($ && target instanceof $) {
		//TODO: decide how to pass data
		var evt = $.Event( eventName, data );
		evt.detail = data;
		emitMethod = bubbles ? targte.trigger : target.triggerHandler;
	}

	//Target events
	else {
		emitMethod = getMethodOneOf(target, emitNames);
	}

	//use locks to avoid self-recursion on objects wrapping this method (e. g. mod instances)
	if (emitMethod) {
		if (icicle.freeze(target, emitFlag)) {
			//use target event system, if possible
			emitMethod.call(target, evt, data, bubbles);
			icicle.unfreeze(target, emitFlag);
			return target;
		}
		//if event was frozen - perform normal callback
	}

	//fall back to default event system
	//ignore if no event specified
	if (!targetCbCache.has(target)) return target;

	var evtCallbacks = targetCbCache.get(target)[evt];

	if (!evtCallbacks) return target;

	//copy callbacks to fire because list can be changed in some handler
	var fireList = evtCallbacks.slice();
	for (var i = 0; i < fireList.length; i++ ) {
		fireList[i] && fireList[i].call(target, {
			detail: data,
			type: eventName
		});
	}

	return target;
};

/**
 * Return array of callbacks for `event`.
 *
 * @param {String} event
 * @return {Array}
 * @api public
 */

EmmyPrototype.listeners = function(evt){
	var callbacks = targetCbCache.get(this);
	return callbacks && callbacks[evt] || [];
};

/**
 * Check if this emitter has `event` handlers.
 *
 * @param {String} event
 * @return {Boolean}
 * @api public
 */

EmmyPrototype.hasListeners = function(evt){
	return !!EmmyPrototype.listeners.call(this, evt).length;
};

/** Static aliases for old API compliance */
Emmy.on = function(a,b,c){EmmyPrototype.on.call(a,b,c); return this;};
Emmy.one =
Emmy.once = function(a,b,c){EmmyPrototype.one.call(a,b,c); return this;};
Emmy.off = function(a,b,c){EmmyPrototype.off.call(a,b,c); return this;};
Emmy.emit = function(a,b,c,d){EmmyPrototype.emit.call(a,b,c,d); return this;};

/** @module muevents */
module.exports = Emmy;<commit_msg>Add spacer<commit_after>var icicle = require('icicle');

/** environment guarant */
var $ = typeof jQuery === 'undefined' ? undefined : jQuery;
var doc = typeof document === 'undefined' ? undefined : document;
var win = typeof window === 'undefined' ? undefined : window;

/** Lists of methods */
var onNames = ['on', 'bind', 'addEventListener', 'addListener'];
var oneNames = ['one', 'once', 'addOnceEventListener', 'addOnceListener'];
var offNames = ['off', 'unbind', 'removeEventListener', 'removeListener'];
var emitNames = ['emit', 'trigger', 'fire', 'dispatchEvent'];

/** Locker flags */
var emitFlag = emitNames[0], onFlag = onNames[0], oneFlag = onNames[0], offFlag = offNames[0];

/**
 * @constructor
 *
 * Main EventEmitter interface.
 * Wraps any target passed to an Emitter interface
 */
function Emmy(target){
	if (!target) return;

	//create emitter methods on target, if none
	if (!getMethodOneOf(target, onNames)) target.on = EmmyPrototype.on.bind(target);
	if (!getMethodOneOf(target, offNames)) target.off = EmmyPrototype.off.bind(target);
	if (!getMethodOneOf(target, oneNames)) target.one = target.once = EmmyPrototype.one.bind(target);
	if (!getMethodOneOf(target, emitNames)) target.emit = EmmyPrototype.emit.bind(target);

	return target;
}

/** Make DOM objects be wrapped as jQuery objects, if jQuery is enabled */
var EmmyPrototype = Emmy.prototype;

/**
 * Return target’s method one of the passed in list, if target is eventable
 * Use to detect whether target has some fn
 */
function getMethodOneOf(target, list){
	var result;
	for (var i = 0, l = list.length; i < l; i++) {
		result = target[list[i]];
		if (result) return result;
	}
}

/** Set of target callbacks, {target: [cb1, cb2, ...]} */
var targetCbCache = new WeakMap;

/**
* Bind fn to the target
* @todo  recognize jquery object
* @chainable
*/
EmmyPrototype.on =
EmmyPrototype.addEventListener = function(evt, fn){
	var target = this;

	//walk by list of instances
	if (fn instanceof Array){
		for (var i = fn.length; i--;){
			EmmyPrototype.on.call(target, evt, fn[i]);
		}
		return target;
	}

	//target events
	var onMethod = getMethodOneOf(target, onNames);

	//use target event system, if possible
	//avoid self-recursions from the outside
	if (onMethod) {
		//if it’s frozen - ignore call
		if (icicle.freeze(target, onFlag)){
			onMethod.call(target, evt, fn);
			icicle.unfreeze(target, onFlag);
			return target;
		}
	}

	//Save callback
	//ensure callbacks array for target exists
	if (!targetCbCache.has(target)) targetCbCache.set(target, {});
	var targetCallbacks = targetCbCache.get(target);

	(targetCallbacks[evt] = targetCallbacks[evt] || []).push(fn);

	return target;
};

/**
 * Add an event listener that will be invoked once and then removed.
 *
 * @return {Emmy}
 * @chainable
 */
EmmyPrototype.once =
EmmyPrototype.one = function(evt, fn){
	var target = this;

	//walk by list of instances
	if (fn instanceof Array){
		for (var i = fn.length; i--;){
			EmmyPrototype.one.call(target, evt, fn[i]);
		}
		return;
	}

	//target events
	var oneMethod = getMethodOneOf(target, oneNames);

	//use target event system, if possible
	//avoid self-recursions from the outside
	if (oneMethod) {
		if (icicle.freeze(target, oneFlag)){
			//use target event system, if possible
			oneMethod.call(target, evt, fn);
			icicle.unfreeze(target, oneFlag);
			return target;
		}
	}

	//wrap callback to once-call
	function cb() {
		EmmyPrototype.off.call(target, evt, fn);
		fn.apply(target, arguments);
	}

	cb.fn = fn;

	EmmyPrototype.on.call(target, evt, cb);

	return target;
};

/**
* Bind fn to a target
* @chainable
*/
EmmyPrototype.off =
EmmyPrototype.removeListener =
EmmyPrototype.removeAllListeners =
EmmyPrototype.removeEventListener = function (evt, fn){
	var target = this;

	//unbind all listeners passed
	if (fn instanceof Array){
		for (var i = fn.length; i--;){
			EmmyPrototype.off.call(target, evt, fn[i]);
		}
		return target;
	}

	//unbind all listeners if no fn specified
	if (fn === undefined) {
		var callbacks = targetCbCache.get(target);
		if (!callbacks) return target;
		//unbind all if no evtRef defined
		if (evt === undefined) {
			for (var evtName in callbacks) {
				EmmyPrototype.off.call(target, evtName, callbacks[evtName]);
			}
		}
		else if (callbacks[evt]) {
			EmmyPrototype.off.call(target, evt, callbacks[evt]);
		}
		return target;
	}

	//target events
	var offMethod = getMethodOneOf(target, offNames);

	//use target event system, if possible
	//avoid self-recursion from the outside
	if (offMethod) {
		//if it’s frozen - ignore call
		if (icicle.freeze(target, offFlag)){
			offMethod.call(target, evt, fn);
			icicle.unfreeze(target, offFlag);
			return target;
		}
	}

	//Forget callback
	//ignore if no event specified
	if (!targetCbCache.has(target)) return;

	var evtCallbacks = targetCbCache.get(target)[evt];

	if (!evtCallbacks) return;

	//remove specific handler
	for (var i = 0; i < evtCallbacks.length; i++) {
		if (evtCallbacks[i] === fn || evtCallbacks[i].fn === fn) {
			evtCallbacks.splice(i, 1);
			break;
		}
	}

	return target;
};

/**
* Event trigger
* @chainable
*/
EmmyPrototype.emit =
EmmyPrototype.dispatchEvent = function(eventName, data, bubbles){
	var target = this, emitMethod, evt = eventName;
	if (!target) return;

	//Create proper event for DOM objects
	if (target.nodeType || target === doc || target === win) {
		//NOTE: this doesnot bubble on disattached elements

		if (eventName instanceof Event) {
			evt = eventName;
		} else {
			evt =  document.createEvent('CustomEvent');
			evt.initCustomEvent(eventName, bubbles, true, data);
		}

		// var evt = new CustomEvent(eventName, { detail: data, bubbles: bubbles })

		emitMethod = target.dispatchEvent;
	}

	//create event for jQuery object
	else if ($ && target instanceof $) {
		//TODO: decide how to pass data
		var evt = $.Event( eventName, data );
		evt.detail = data;
		emitMethod = bubbles ? targte.trigger : target.triggerHandler;
	}

	//Target events
	else {
		emitMethod = getMethodOneOf(target, emitNames);
	}

	//use locks to avoid self-recursion on objects wrapping this method (e. g. mod instances)
	if (emitMethod) {
		if (icicle.freeze(target, emitFlag)) {
			//use target event system, if possible
			emitMethod.call(target, evt, data, bubbles);
			icicle.unfreeze(target, emitFlag);
			return target;
		}
		//if event was frozen - perform normal callback
	}

	//fall back to default event system
	//ignore if no event specified
	if (!targetCbCache.has(target)) return target;

	var evtCallbacks = targetCbCache.get(target)[evt];

	if (!evtCallbacks) return target;

	//copy callbacks to fire because list can be changed in some handler
	var fireList = evtCallbacks.slice();
	for (var i = 0; i < fireList.length; i++ ) {
		fireList[i] && fireList[i].call(target, {
			detail: data,
			type: eventName
		});
	}

	return target;
};

/**
 * Return array of callbacks for `event`.
 *
 * @param {String} event
 * @return {Array}
 * @api public
 */

EmmyPrototype.listeners = function(evt){
	var callbacks = targetCbCache.get(this);
	return callbacks && callbacks[evt] || [];
};

/**
 * Check if this emitter has `event` handlers.
 *
 * @param {String} event
 * @return {Boolean}
 * @api public
 */

EmmyPrototype.hasListeners = function(evt){
	return !!EmmyPrototype.listeners.call(this, evt).length;
};

/** Static aliases for old API compliance */
Emmy.on = function(a,b,c){EmmyPrototype.on.call(a,b,c); return this;};
Emmy.one =
Emmy.once = function(a,b,c){EmmyPrototype.one.call(a,b,c); return this;};
Emmy.off = function(a,b,c){EmmyPrototype.off.call(a,b,c); return this;};
Emmy.emit = function(a,b,c,d){EmmyPrototype.emit.call(a,b,c,d); return this;};

/** @module muevents */
module.exports = Emmy;<|endoftext|>


<commit_before>'use strict';

var util = require('util');

var levels = ['debug', 'info', 'warn', 'error', 'fatal'];

module.exports = function (opts) {
  opts = opts || {};
  opts.level = opts.level || 'info';

  var logger = {};

  var shouldLog = function (level) {
    return levels.indexOf(level) >= levels.indexOf(opts.level);
  };

  levels.forEach(function (level) {
    logger[level] = function () {
      if (!shouldLog(level)) return;

      var prefix = opts.prefix;

      switch (level) {
        case 'debug': level = 'info'; break;
        case 'fatal': level = 'error'; break;
      }

      if (prefix) {
        if (typeof prefix === 'function') prefix = prefix();
        arguments[0] = util.format(prefix, arguments[0]);
      }

      console[level].apply(console, arguments);
    };
  });

  return logger;
};
<commit_msg>Don't leak normalized level<commit_after>'use strict';

var util = require('util');

var levels = ['debug', 'info', 'warn', 'error', 'fatal'];

module.exports = function (opts) {
  opts = opts || {};
  opts.level = opts.level || 'info';

  var logger = {};

  var shouldLog = function (level) {
    return levels.indexOf(level) >= levels.indexOf(opts.level);
  };

  levels.forEach(function (level) {
    logger[level] = function () {
      if (!shouldLog(level)) return;

      var prefix = opts.prefix;
      var normalizedLevel;

      switch (level) {
        case 'debug': normalizedLevel = 'info'; break;
        case 'fatal': normalizedLevel = 'error'; break;
        default: normalizedLevel = level;
      }

      if (prefix) {
        if (typeof prefix === 'function') prefix = prefix();
        arguments[0] = util.format(prefix, arguments[0]);
      }

      console[normalizedLevel].apply(console, arguments);
    };
  });

  return logger;
};
<|endoftext|>