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

(function() {

    var fs = require('fs');
    var path = require('path');
    var resolve = require('resolve');

    var File = require('vinyl'); // The module file to be checked.

    var resolution = {}; // The dependency tree being resolved.
    var checked = []; // List of modules already checked.
    var toCheck = []; // List of modules to parse next.

    var defaultOpts = {
        parseRequires: true, // Naively parses source for require statements.
        indexCoreModules: false, //Whether to index core modules or skip them.
        indexPackageJSONDeps: true, // Indexes dependencies in pacakge.json
        indexPackageJSONOptDeps: true, // Indexes optional dependencies in pacakge.json
        indexPac: true, // Indexes dependencies in pacakge.json
        indexRequiresByName: true, // Indexes parsed dependencies required by name.
        indexRequiresByPath: false, // Indexes parsed dependencies required by path.
        recursePackageJSONDeps: true, // Recurse through package.json dependencies.
        recursePackageJSONOptDeps: true, // Recurse through package.json optional dependencies.
        recurseRequiresByName: true, //TODO: Recurse through parsed dependencies required by name.
        recurseRequiresByPath: true, // Recurse through parsed dependencies required by path.
        verbose: false, // Print logging info.
        limit: 1000000, // Maximum number of modules checked recursively.
                        // Setting this to `1` stops the recursion at checking only the given module's dependencies.
                        // But this isn't really a recursion counter, as all dependencies beyond the first level count towards the limit individually.
        offsetPath: __dirname, // All resolved modules are made relative to this path.
        externalize: [] // A list of files to not recurse over.
    };

    // Set opts.
    var opts = {};
    var setOpts = function(passedOpts) {
        for ( var key in defaultOpts ) {
            if ( typeof passedOpts === typeof {} && passedOpts[key] !== undefined ) {
                opts[key] = passedOpts[key];
            } else {
                opts[key] = defaultOpts[key];
            }
        }
    };

    // Actual logic for parsing files.
    var checkByFile = function(file) {

        // Check for the "recursion" limit.
        if (opts.limit >= 0) {
            opts.limit--;
        }
        else {
            throw "Recursion limit reached.";
        }

        var basedir = path.resolve(path.dirname(file.path));

        // Skip externalized files.
        if ( opts.externalize.length > 0 ) {
            for ( var i in opts.externalize ) {
                // Resolve external file path.
                var externalPathLocal = resolve.sync(opts.externalize[i], {
                    basedir: basedir
                });
                // Make external file path absolute.
                var externalPathAbsolute = path.resolve(externalPathLocal);
                if ( path.resolve(file.path) == externalPathAbsolute ) {
                    if (opts.verbose) console.log("External file `" + opts.externalize[i] + "` skipped.");
                    return
                }
            }
        }

        // Parse package.json.
        if ( opts.indexPackageJSONDeps || opts.indexPackageJSONOptDeps || opts.recursePackageJSONDeps || opts.recursePackageJSONOptDeps ) {
            require('closest-package').sync(basedir, function(json, filename) {

                if ( opts.indexPackageJSONDeps || opts.recursePackageJSONDeps ) {
                    for (var moduleName in json.dependencies) {

                        // Resolve module path.
                        var modulePathLocal = resolve.sync(moduleName, {
                            basedir: basedir
                        });
                        // Make path absolute.
                        var modulePathAbsolute = path.resolve(modulePathLocal);

                        // Add resolution to output.
                        if (opts.indexPackageJSONDeps) {
                            if (typeof resolution[basedir] !== typeof {}) resolution[basedir] = {};
                            resolution[basedir][moduleName] = path.relative(opts.offsetPath, modulePathAbsolute);
                            if (opts.verbose) console.log("Indexed package.json dependency `" + moduleName + "`.");
                        }

                        // Add dependency to be checked recursively.
                        if  (opts.recursePackageJSONDeps && toCheck.indexOf(modulePathAbsolute) <= -1 ) {
                            toCheck.push(modulePathAbsolute);
                        }

                    }
                }

                if ( opts.indexPackageJSONOptDeps || opts.recursePackageJSONOptDeps ) {
                    for (var moduleName in json.optionalDependencies) {

                        // Resolve module path.
                        var modulePathLocal = resolve.sync(moduleName, {
                            basedir: basedir
                        });
                        // Make path absolute.
                        var modulePathAbsolute = path.resolve(modulePathLocal);

                        // Add resolution to output.
                        if (opts.indexPackageJSONOptDeps) {
                            if (typeof resolution[basedir] !== typeof {}) resolution[basedir] = {};
                            resolution[basedir][moduleName] = path.relative(opts.offsetPath, modulePathAbsolute);
                            if (opts.verbose) console.log("Indexed package.json optional dependency `" + moduleName + "`.");
                        }

                        // Add dependency to be checked recursively.
                        if ( opts.recursePackageJSONOptDeps && toCheck.indexOf(modulePathAbsolute) <= -1 ) {
                            toCheck.push(modulePathAbsolute);
                        }

                    }
                }

                return true; //NOTE: Because this is a filtering function and the lookup would onlt stop at true. And we do want the very closest one.
            });
        }

        // Parse file body for requires.

        if (opts.parseRequires) {

            var input = file.contents.toString('utf-8');

            var regex = /\brequire\(([^\)]*)\)/g;

            var matchObject;
            while (matchObject = regex.exec(input)) {

                var fullMatch = matchObject[0];
                var match = matchObject[1];

                try {

                    // Evaluate and "clean" module name.
                    var moduleName = eval(match);

                    if (resolve.isCore(moduleName)) {
                        if (opts.indexCoreModules) {
                            // Make path absolute.
                            if (typeof resolution[basedir] !== typeof {}) resolution[basedir] = {};
                            resolution[basedir][moduleName] = moduleName;
                            if (opts.verbose) console.log("Indexed core module `" + moduleName + "`.");
                        } else {
                            // Throw a fit if module is core to Node.
                            throw "Core modules do not run in the browser!";
                        }
                    }
                    else {

                        // Else continue.
                        // Check if module was required by path.
                        var requiredByPath = /^(?:\.{0,2})\//.test(moduleName);

                        // Check whether to parse path'd modules.
                        if (!opts.recurseRequiresByPath && requiredByPath) {
                            throw "Will not parse modules required by path.";
                        }

                        // Resolve module.
                        var modulePathLocal = resolve.sync(moduleName, {
                            basedir: basedir
                        });
                        // Make path absolute.
                        var modulePathAbsolute = path.resolve(modulePathLocal);

                        // Add resolution to index of module wasn't required in path form.
                        if ( (opts.indexRequiresByName && !requiredByPath ) || (opts.indexRequiresByPath && requiredByPath) ) {
                            if (path.resolve(file.path) != modulePathAbsolute) {
                                if (typeof resolution[basedir] !== typeof {}) resolution[basedir] = {};
                                resolution[basedir][moduleName] = path.relative(opts.offsetPath, modulePathAbsolute);
                                if (opts.verbose) console.log("Indexed required module `" + moduleName + "`.");
                            }
                        }
                        else {
                            if (opts.verbose) console.log("Did not index required module `" + moduleName + "`.");
                        }

                        // Add dependency to be checked recursively.
                        if (toCheck.indexOf(modulePathAbsolute) <= -1) {
                            if (requiredByPath) {
                                if (opts.recurseRequiresByPath) {
                                    toCheck.push(modulePathAbsolute);
                                }
                            } else {
                                if (opts.recurseRequiresByName) {
                                    toCheck.push(modulePathAbsolute);
                                }
                            }
                            if (opts.verbose) console.log("Will recurse `" + moduleName + "`.");
                        }

                    }

                }
                catch (e) {
                    console.error("Could not resolve `" + match + "`: " + (e.toString()));
                }

            }

        }

        var modulePathAbsolute = toCheck.shift();
        while (modulePathAbsolute) {
            checkByModule(modulePathAbsolute);
            modulePathAbsolute = toCheck.shift();
        }

    };

    // Shortcut for checking by filepath or module name.
    var checkByModule = function(name) {

        // Resolve absolute module path.
        var filePathAbsolute = path.resolve(resolve.sync(name, {
            basedir: __dirname
        }));

        // Check if absolute filepath has not already been checked.
        if (checked.indexOf(filePathAbsolute) <= -1) {
            // Add absolute filepath to checked list.
            checked.push(filePathAbsolute);
            // Parse for dependencies.
            checkByFile(new File({
                cwd: process.cwd(),
                base: path.dirname(filePathAbsolute),
                path: filePathAbsolute,
                contents: fs.readFileSync(filePathAbsolute)
            }), opts);
        }

        // Verbose log for files checked for requires.
        if (opts.verbose) {
            console.log("Parsing dependency `" + name + "`.");
        }

        // Return the resolution map.
        return resolution;

    };

    // Clear resolved dependencies.
    var clearResolution = function () {
        while(resolution.length > 0) {
            resolution.pop();
        }
    };

    // Exports.
    module.exports = checkByModule;
    module.exports.checkByFile = checkByFile;
    module.exports.defaultOpts = defaultOpts;
    module.exports.clearResolution = clearResolution;
    module.exports.version = '0.0.0'

    // Run from command-line.
    if (require.main === module) {

        var argv = require('yargs')
            .default(defaultOpts)
            .boolean('parseRequires')
            .boolean('indexCoreModules')
            .boolean('indexPackageJSONDeps')
            .boolean('indexPackageJSONOptDeps')
            .boolean('indexRequiresByName')
            .boolean('indexRequiresByPath')
            .boolean('recursePackageJSONDeps')
            .boolean('recursePackageJSONOptDeps')
            .boolean('recurseRequiresByName')
            .boolean('recurseRequiresByPath')
            .boolean('verbose')
            .alias( 'parseRequires', 'r' )
            .alias( 'indexCoreModules', 'c' )
            .alias( 'indexPackageJSONDeps', 'd' )
            .alias( 'indexPackageJSONOptDeps', 'o' )
            .alias( 'indexRequiresByName', 'n' )
            .alias( 'indexRequiresByPath', 'p' )
            .alias( 'recursePackageJSONDeps', 'D' )
            .alias( 'recursePackageJSONOptDeps', 'O' )
            .alias( 'recurseRequiresByName', 'N' )
            .alias( 'recurseRequiresByPath', 'P' )
            .alias( 'verbose', 'v' )
            .alias( 'limit', 'l' )
            .alias( 'offsetPath', 'f' )
            .alias( 'externalize', 'x' )
            .argv;
        var args = argv._;

        if ( typeof argv.externalize !== typeof [] ) {
            argv.externalize = [argv.externalize];
        }

        setOpts(argv);

        clearResolution();

        for (var i = 0; i < args.length; i++) {
            var infile = args[i];
            checkByModule(infile);
        }
        console.log(resolution);

    }

}).call(this);<commit_msg>Bumped to version 0.1.0<commit_after>#!/usr/bin/env node

(function() {

    var fs = require('fs');
    var path = require('path');
    var resolve = require('resolve');

    var File = require('vinyl'); // The module file to be checked.

    var resolution = {}; // The dependency tree being resolved.
    var checked = []; // List of modules already checked.
    var toCheck = []; // List of modules to parse next.

    var defaultOpts = {
        parseRequires: true, // Naively parses source for require statements.
        indexCoreModules: false, //Whether to index core modules or skip them.
        indexPackageJSONDeps: true, // Indexes dependencies in pacakge.json
        indexPackageJSONOptDeps: true, // Indexes optional dependencies in pacakge.json
        indexPac: true, // Indexes dependencies in pacakge.json
        indexRequiresByName: true, // Indexes parsed dependencies required by name.
        indexRequiresByPath: false, // Indexes parsed dependencies required by path.
        recursePackageJSONDeps: true, // Recurse through package.json dependencies.
        recursePackageJSONOptDeps: true, // Recurse through package.json optional dependencies.
        recurseRequiresByName: true, //TODO: Recurse through parsed dependencies required by name.
        recurseRequiresByPath: true, // Recurse through parsed dependencies required by path.
        verbose: false, // Print logging info.
        limit: 1000000, // Maximum number of modules checked recursively.
                        // Setting this to `1` stops the recursion at checking only the given module's dependencies.
                        // But this isn't really a recursion counter, as all dependencies beyond the first level count towards the limit individually.
        offsetPath: __dirname, // All resolved modules are made relative to this path.
        externalize: [] // A list of files to not recurse over.
    };

    // Set opts.
    var opts = {};
    var setOpts = function(passedOpts) {
        for ( var key in defaultOpts ) {
            if ( typeof passedOpts === typeof {} && passedOpts[key] !== undefined ) {
                opts[key] = passedOpts[key];
            } else {
                opts[key] = defaultOpts[key];
            }
        }
    };

    // Actual logic for parsing files.
    var checkByFile = function(file) {

        // Check for the "recursion" limit.
        if (opts.limit >= 0) {
            opts.limit--;
        }
        else {
            throw "Recursion limit reached.";
        }

        var basedir = path.resolve(path.dirname(file.path));

        // Skip externalized files.
        if ( opts.externalize.length > 0 ) {
            for ( var i in opts.externalize ) {
                // Resolve external file path.
                var externalPathLocal = resolve.sync(opts.externalize[i], {
                    basedir: basedir
                });
                // Make external file path absolute.
                var externalPathAbsolute = path.resolve(externalPathLocal);
                if ( path.resolve(file.path) == externalPathAbsolute ) {
                    if (opts.verbose) console.log("External file `" + opts.externalize[i] + "` skipped.");
                    return
                }
            }
        }

        // Parse package.json.
        if ( opts.indexPackageJSONDeps || opts.indexPackageJSONOptDeps || opts.recursePackageJSONDeps || opts.recursePackageJSONOptDeps ) {
            require('closest-package').sync(basedir, function(json, filename) {

                if ( opts.indexPackageJSONDeps || opts.recursePackageJSONDeps ) {
                    for (var moduleName in json.dependencies) {

                        // Resolve module path.
                        var modulePathLocal = resolve.sync(moduleName, {
                            basedir: basedir
                        });
                        // Make path absolute.
                        var modulePathAbsolute = path.resolve(modulePathLocal);

                        // Add resolution to output.
                        if (opts.indexPackageJSONDeps) {
                            if (typeof resolution[basedir] !== typeof {}) resolution[basedir] = {};
                            resolution[basedir][moduleName] = path.relative(opts.offsetPath, modulePathAbsolute);
                            if (opts.verbose) console.log("Indexed package.json dependency `" + moduleName + "`.");
                        }

                        // Add dependency to be checked recursively.
                        if  (opts.recursePackageJSONDeps && toCheck.indexOf(modulePathAbsolute) <= -1 ) {
                            toCheck.push(modulePathAbsolute);
                        }

                    }
                }

                if ( opts.indexPackageJSONOptDeps || opts.recursePackageJSONOptDeps ) {
                    for (var moduleName in json.optionalDependencies) {

                        // Resolve module path.
                        var modulePathLocal = resolve.sync(moduleName, {
                            basedir: basedir
                        });
                        // Make path absolute.
                        var modulePathAbsolute = path.resolve(modulePathLocal);

                        // Add resolution to output.
                        if (opts.indexPackageJSONOptDeps) {
                            if (typeof resolution[basedir] !== typeof {}) resolution[basedir] = {};
                            resolution[basedir][moduleName] = path.relative(opts.offsetPath, modulePathAbsolute);
                            if (opts.verbose) console.log("Indexed package.json optional dependency `" + moduleName + "`.");
                        }

                        // Add dependency to be checked recursively.
                        if ( opts.recursePackageJSONOptDeps && toCheck.indexOf(modulePathAbsolute) <= -1 ) {
                            toCheck.push(modulePathAbsolute);
                        }

                    }
                }

                return true; //NOTE: Because this is a filtering function and the lookup would onlt stop at true. And we do want the very closest one.
            });
        }

        // Parse file body for requires.

        if (opts.parseRequires) {

            var input = file.contents.toString('utf-8');

            var regex = /\brequire\(([^\)]*)\)/g;

            var matchObject;
            while (matchObject = regex.exec(input)) {

                var fullMatch = matchObject[0];
                var match = matchObject[1];

                try {

                    // Evaluate and "clean" module name.
                    var moduleName = eval(match);

                    if (resolve.isCore(moduleName)) {
                        if (opts.indexCoreModules) {
                            // Make path absolute.
                            if (typeof resolution[basedir] !== typeof {}) resolution[basedir] = {};
                            resolution[basedir][moduleName] = moduleName;
                            if (opts.verbose) console.log("Indexed core module `" + moduleName + "`.");
                        } else {
                            // Throw a fit if module is core to Node.
                            throw "Core modules do not run in the browser!";
                        }
                    }
                    else {

                        // Else continue.
                        // Check if module was required by path.
                        var requiredByPath = /^(?:\.{0,2})\//.test(moduleName);

                        // Check whether to parse path'd modules.
                        if (!opts.recurseRequiresByPath && requiredByPath) {
                            throw "Will not parse modules required by path.";
                        }

                        // Resolve module.
                        var modulePathLocal = resolve.sync(moduleName, {
                            basedir: basedir
                        });
                        // Make path absolute.
                        var modulePathAbsolute = path.resolve(modulePathLocal);

                        // Add resolution to index of module wasn't required in path form.
                        if ( (opts.indexRequiresByName && !requiredByPath ) || (opts.indexRequiresByPath && requiredByPath) ) {
                            if (path.resolve(file.path) != modulePathAbsolute) {
                                if (typeof resolution[basedir] !== typeof {}) resolution[basedir] = {};
                                resolution[basedir][moduleName] = path.relative(opts.offsetPath, modulePathAbsolute);
                                if (opts.verbose) console.log("Indexed required module `" + moduleName + "`.");
                            }
                        }
                        else {
                            if (opts.verbose) console.log("Did not index required module `" + moduleName + "`.");
                        }

                        // Add dependency to be checked recursively.
                        if (toCheck.indexOf(modulePathAbsolute) <= -1) {
                            if (requiredByPath) {
                                if (opts.recurseRequiresByPath) {
                                    toCheck.push(modulePathAbsolute);
                                }
                            } else {
                                if (opts.recurseRequiresByName) {
                                    toCheck.push(modulePathAbsolute);
                                }
                            }
                            if (opts.verbose) console.log("Will recurse `" + moduleName + "`.");
                        }

                    }

                }
                catch (e) {
                    console.error("Could not resolve `" + match + "`: " + (e.toString()));
                }

            }

        }

        var modulePathAbsolute = toCheck.shift();
        while (modulePathAbsolute) {
            checkByModule(modulePathAbsolute);
            modulePathAbsolute = toCheck.shift();
        }

    };

    // Shortcut for checking by filepath or module name.
    var checkByModule = function(name) {

        // Resolve absolute module path.
        var filePathAbsolute = path.resolve(resolve.sync(name, {
            basedir: __dirname
        }));

        // Check if absolute filepath has not already been checked.
        if (checked.indexOf(filePathAbsolute) <= -1) {
            // Add absolute filepath to checked list.
            checked.push(filePathAbsolute);
            // Parse for dependencies.
            checkByFile(new File({
                cwd: process.cwd(),
                base: path.dirname(filePathAbsolute),
                path: filePathAbsolute,
                contents: fs.readFileSync(filePathAbsolute)
            }), opts);
        }

        // Verbose log for files checked for requires.
        if (opts.verbose) {
            console.log("Parsing dependency `" + name + "`.");
        }

        // Return the resolution map.
        return resolution;

    };

    // Clear resolved dependencies.
    var clearResolution = function () {
        while(resolution.length > 0) {
            resolution.pop();
        }
    };

    // Exports.
    module.exports = checkByModule;
    module.exports.checkByFile = checkByFile;
    module.exports.defaultOpts = defaultOpts;
    module.exports.clearResolution = clearResolution;
    module.exports.version = '0.1.0'

    // Run from command-line.
    if (require.main === module) {

        var argv = require('yargs')
            .default(defaultOpts)
            .boolean('parseRequires')
            .boolean('indexCoreModules')
            .boolean('indexPackageJSONDeps')
            .boolean('indexPackageJSONOptDeps')
            .boolean('indexRequiresByName')
            .boolean('indexRequiresByPath')
            .boolean('recursePackageJSONDeps')
            .boolean('recursePackageJSONOptDeps')
            .boolean('recurseRequiresByName')
            .boolean('recurseRequiresByPath')
            .boolean('verbose')
            .alias( 'parseRequires', 'r' )
            .alias( 'indexCoreModules', 'c' )
            .alias( 'indexPackageJSONDeps', 'd' )
            .alias( 'indexPackageJSONOptDeps', 'o' )
            .alias( 'indexRequiresByName', 'n' )
            .alias( 'indexRequiresByPath', 'p' )
            .alias( 'recursePackageJSONDeps', 'D' )
            .alias( 'recursePackageJSONOptDeps', 'O' )
            .alias( 'recurseRequiresByName', 'N' )
            .alias( 'recurseRequiresByPath', 'P' )
            .alias( 'verbose', 'v' )
            .alias( 'limit', 'l' )
            .alias( 'offsetPath', 'f' )
            .alias( 'externalize', 'x' )
            .argv;
        var args = argv._;

        if ( typeof argv.externalize !== typeof [] ) {
            argv.externalize = [argv.externalize];
        }

        setOpts(argv);

        clearResolution();

        for (var i = 0; i < args.length; i++) {
            var infile = args[i];
            checkByModule(infile);
        }
        console.log(resolution);

    }

}).call(this);<|endoftext|>


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

const cluster = require('cluster');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
    for (let i = 0; i < numCPUs; i++) {
        cluster.fork();
    }
} else {

    const readFile = require("fs").readFile;
    const Transform = require("stream").Transform;
    const resolve = require("path").resolve;
    const LRU = require("lru-cache");
    const Registry = require(__dirname + "/node_modules/flow-registry");
    const Flow = require(__dirname + "/node_modules/flow");
    const sequence_id = process.argv[2];
    const base_path = resolve(process.argv[3] || '.');

    if (!sequence_id) {
        process.stderr.write('Start sequence missing. Example: flow sequenceId');
        process.exit(0);
    }

    const event = Flow({
        cache: LRU({max: 500}),
        seq: (sequence_id, role, cb) => {
            readFile(base_path + "/" + sequence_id + ".json", (err, data) => {

                if (err) {
                    return cb(err);
                }

                try {
                    cb(null, JSON.parse(data));
                } catch(err) {
                    cb(err);
                }
            });
        },

        fn: Registry.getFn
    })({
        sequence: sequence_id,
        role: '_:3389dae361af79b04c9c8e7057f60cc6',
        base: base_path
    });

    event.on("error", (err) => {
        err = err.stack ? err.stack : err;
        process.stderr.write(err.toString());
    });

    process.stdin.pipe(event).pipe(process.stdout);
}
<commit_msg>transform stream is not used anymore<commit_after>#!/usr/bin/env node

const cluster = require('cluster');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
    for (let i = 0; i < numCPUs; i++) {
        cluster.fork();
    }
} else {

    const module_root = __dirname + "/node_modules/"
    const readFile = require("fs").readFile;
    const resolve = require("path").resolve;
    const Flow = require(module_root + "flow");
    const Registry = require(module_root + "flow-registry");
    const LRU = require("lru-cache");
    const sequence_id = process.argv[2];
    const base_path = resolve(process.argv[3] || '.');

    if (!sequence_id) {
        process.stderr.write('Start sequence missing. Example: flow sequenceId');
        process.exit(0);
    }

    const event = Flow({
        cache: LRU({max: 500}),
        seq: (sequence_id, role, cb) => {
            readFile(base_path + "/" + sequence_id + ".json", (err, data) => {

                if (err) {
                    return cb(err);
                }

                try {
                    cb(null, JSON.parse(data));
                } catch(err) {
                    cb(err);
                }
            });
        },

        fn: Registry.getFn
    })({
        sequence: sequence_id,
        role: '_:3389dae361af79b04c9c8e7057f60cc6',
        base: base_path
    });

    event.on("error", (err) => {
        err = err.stack ? err.stack : err;
        process.stderr.write(err.toString());
    });

    process.stdin.pipe(event).pipe(process.stdout);
}
<|endoftext|>


<commit_before>module.exports = function (map, width, inOrder) {
  inOrder = inOrder === undefined ? true : inOrder
  var reading = false, abort
  return function (read) {
    var i = 0, j = 0, last = 0
    var seen = [], started = false, ended = false, _cb, error

    function drain () {
      if(_cb) {
        var cb = _cb
        if(error) {
          _cb = null
          return cb(error)
        }
        if(Object.hasOwnProperty.call(seen, j)) {
          _cb = null
          var data = seen[j]; delete seen[j]; j++
          cb(null, data)
          if(width) start()
        } else if(j >= last && ended) {
          _cb = null
          cb(ended)
        }
      }
    }

    function start () {
      started = true
      if(ended) return drain()
      if(reading || width && (i - width >= j)) return
      reading = true
      read(abort, function (end, data) {
        reading = false
        if(end) {
          last = i; ended = end
          drain()
        } else {
          var k = i++

          map(data, function (err, data) {
            if (inOrder) seen[k] = data
            else seen.push(data)
            if(err) error = err
            drain()
          })

          if(!ended)
            start()

        }
      })
    }

    return function (_abort, cb) {
      if(_abort)
        read(ended = abort = _abort, function (err) {
          if(cb) return cb(err)
        })
      else {
        _cb = cb
        if(!started) start()
        drain()
      }
    }
  }
}

<commit_msg>use looper to prevent RangeErrors<commit_after>var looper = require('looper')
module.exports = function (map, width, inOrder) {
  inOrder = inOrder === undefined ? true : inOrder
  var reading = false, abort
  return function (read) {
    var i = 0, j = 0, last = 0
    var seen = [], started = false, ended = false, _cb, error

    function drain () {
      if(_cb) {
        var cb = _cb
        if(error) {
          _cb = null
          return cb(error)
        }
        if(Object.hasOwnProperty.call(seen, j)) {
          _cb = null
          var data = seen[j]; delete seen[j]; j++
          cb(null, data)
          if(width) start()
        } else if(j >= last && ended) {
          _cb = null
          cb(ended)
        }
      }
    }

    var start = looper(function () {
      started = true
      if(ended) return drain()
      if(reading || width && (i - width >= j)) return
      reading = true
      read(abort, function (end, data) {
        reading = false
        if(end) {
          last = i; ended = end
          drain()
        } else {
          var k = i++

          map(data, function (err, data) {
            if (inOrder) seen[k] = data
            else seen.push(data)
            if(err) error = err
            drain()
          })

          if(!ended)
            start()

        }
      })
    })

    return function (_abort, cb) {
      if(_abort)
        read(ended = abort = _abort, function (err) {
          if(cb) return cb(err)
        })
      else {
        _cb = cb
        if(!started) start()
        drain()
      }
    }
  }
}

<|endoftext|>


<commit_before>var $ = require('dom')

module.exports = Button

function Button(ele, opts) {
  if (!(this instanceof Button))
    return new Button(ele, opts)

  if ('string' === typeof opts) {
    opts = {
      loadingText: opts
    }
  }
  opts = opts || {}
  this.opts = {
    loadingText: opts.loadingText || 'loading...'
  }
  this.ele = $(ele)
  this.isLoading = false
}

Button.prototype.setState = function(state) {
  var d = 'disabled'
  var is = this.isInput()
  var val = is ? 'val' : 'html'
  var state_ = state + '-text'
  state = state + 'Text'

  if (!this.ele.data('reset-text')) {
    var v = is ? this.ele.value() : this.ele.html()
    this.ele.data('reset-text', v)
  }

  if (this.ele.data(state_) == null) {
    var v = this.opts[state]
    if (is) this.ele.value(v)
    else this.ele.html(v)
  } else {
    var v = this.ele.data(state_)
    if (is) this.ele.value(v)
    else this.ele.html(v)
  }

  this.proxy(state)
}
  }
}

Button.prototype.isInput = function() {
  var tag = this.ele[0].tagName && this.ele[0].tagName.toLowerCase()
  return tag && tag === 'input'
}

Button.prototype.val = function() {
  if (this.isInput())
    return this.ele.value()

  return this.ele.html()
}

Button.prototype.proxy = function(state) {
  if (state === 'loadingText' || state === 'loading-text') {
    this.isLoading = true
    this.ele.addClass('disabled').attr('disabled', 'disabled')
  } else if (this.isLoading) {
    this.isLoading = false
    this.ele.removeClass('disabled').removeAttr('disabled')
  }
}
<commit_msg>Add Button.toggle()<commit_after>var $ = require('dom')

module.exports = Button

function Button(ele, opts) {
  if (!(this instanceof Button))
    return new Button(ele, opts)

  if ('string' === typeof opts) {
    opts = {
      loadingText: opts
    }
  }
  opts = opts || {}
  this.opts = {
    loadingText: opts.loadingText || 'loading...'
  }
  this.ele = $(ele)
  this.isLoading = false
}

Button.prototype.setState = function(state) {
  var d = 'disabled'
  var is = this.isInput()
  var val = is ? 'val' : 'html'
  var state_ = state + '-text'
  state = state + 'Text'

  if (!this.ele.data('reset-text')) {
    var v = is ? this.ele.value() : this.ele.html()
    this.ele.data('reset-text', v)
  }

  if (this.ele.data(state_) == null) {
    var v = this.opts[state]
    if (is) this.ele.value(v)
    else this.ele.html(v)
  } else {
    var v = this.ele.data(state_)
    if (is) this.ele.value(v)
    else this.ele.html(v)
  }

  this.proxy(state)
}

Button.prototype.toggle = function() {
  if (this.isLoading)
    return this.setState('reset')

  return this.setState('loading')
}

Button.prototype.isInput = function() {
  var tag = this.ele[0].tagName && this.ele[0].tagName.toLowerCase()
  return tag && tag === 'input'
}

Button.prototype.val = function() {
  if (this.isInput())
    return this.ele.value()

  return this.ele.html()
}

Button.prototype.proxy = function(state) {
  if (state === 'loadingText' || state === 'loading-text') {
    this.isLoading = true
    this.ele.addClass('disabled').attr('disabled', 'disabled')
  } else if (this.isLoading) {
    this.isLoading = false
    this.ele.removeClass('disabled').removeAttr('disabled')
  }
}
<|endoftext|>


<commit_before>var ctx = document.getElementById("canvas").getContext("2d"), faces = ['J', 'Q', 'K'];
ctx.font = '2px serif';
ctx.lineWidth = 0.5;

function normalizeData(data, x1, y1, x2, y2) {
  for (i = 0; i < data.length;) {
    data[i] = (data[i++] - x1) / (x2 - x1);
    data[i] = (data[i++] - y1) / (y2 - y1);
  }
  return data;
}

function drawWrapper(color, data, drawer) {
  return function(x, y, s) {
    ctx.save();
    ctx.transform(s, 0, 0, s, x, y);
    ctx.beginPath();
    ctx.fillStyle = color;
    drawer(data);
    ctx.fill();
    ctx.restore();
  }
}

function drawSuit(data){
  ctx.moveTo(data[0], data[1]);
  for (i = 2; i < data.length;)
    ctx.bezierCurveTo(data[i++], data[i++], data[i++], data[i++], data[i++], data[i++])
}

function drawCard(x, y, s, number, suitDrawer) {
  ctx.save();
  ctx.transform(s, 0, 0, s, x, y);
  ctx.strokeRect(0, 0, 10, 14);

  if (number <= 10) {
    for (j = 0; j < number;) {
      suitDrawer(j++ % 2 * 3 + 2.5, 10 / number * j, 2);
    }
  } else {
    number = faces[number - 11];
    ctx.fillText(number, 4, 7);
  }

  ctx.fillText(number, 0.5, 2);
  suitDrawer(0.5, 2, 1);
  ctx.transform(-1, 0, 0, -1, 10, 14);
  ctx.fillText(number, 0.5, 2);
  suitDrawer(0.5, 2, 1);

  ctx.restore();
}

/* SUITS
 * 0 = CLUBS
 * 1 = DIAMONDS
 * 2 = SPADES
 * 3 = HEARTS
 */
var suits = [
  drawWrapper(null, normalizeData([522,1635,584,1512,629,1385,635,1251,643,1200,612,1200,609,1237,522,1568,56,1478,73,1164,87,911,340,855,472,939,522,970,519,950,491,919,295,700,416,419,680,414,966,430,1039,734,865,911,842,930,795,1001,865,950,1045,826,1289,961,1283,1155,1275,1512,840,1540,744,1239,736,1208,710,1192,719,1248,730,1349,758,1503,834,1635], 73, 414, 1283, 1635), drawSuit),
  drawWrapper('red', normalizeData([64,1029,269,829,404,611,532,402,645,632,807,834,982,1029,795,1223,650,1430,533,1647,404,1424,267,1222,64,1029], 0, 402, 1045, 1647), drawSuit),
  drawWrapper(null, normalizeData([493,1252,493,1213,459,1213,462,1241,459,1387,334,1460,242,1444,102,1416,58,1278,60,1197,63,944,318,759,547,437,714,728,990,957,1006,1181,1030,1481,649,1592,594,1244,592,1221,563,1207,566,1244,573,1338,560,1380,670,1613,670,1613,388,1613,388,1613,451,1504,488,1369,493,1252], 60, 437, 1006, 1613), drawSuit),
  drawWrapper('red', normalizeData([330,404,490,394,573,530,589,638,599,655,605,650,608,637,616,499,740,386,854,401,1040,404,1153,611,1122,756,1076,971,967,1100,880,1233,781,1370,648,1569,605,1664,605,1664,470,1459,294,1217,176,1055,84,879,73,728,63,586,134,431,330,404], 73, 401, 1122, 1664), drawSuit)
];
for (n = 0; n < 13;) {
  x = n++ * 100;
  for (s = 0; s < 4;)
    drawCard(x, s * 140, 10, n, suits[s++]);
}
<commit_msg>996bytes -> 989bytes<commit_after>var ctx = document.getElementById("canvas").getContext("2d"), faces = ['J', 'Q', 'K'];
ctx.font = '2px serif';
ctx.lineWidth = 0.5;

function normalizeData(data, x1, y1, x2, y2) {
  for (i = 0; i < data.length;) {
    data[i] = (data[i++] - x1) / (x2 - x1);
    data[i] = (data[i++] - y1) / (y2 - y1);
  }
  return data;
}

function drawWrapper(color, data) {
  return function(x, y, s) {
    ctx.save();
    ctx.transform(s, 0, 0, s, x, y);
    ctx.beginPath();
    ctx.fillStyle = color;
    ctx.moveTo(data[0], data[1]);
    for (i = 2; i < data.length;)
      ctx.bezierCurveTo(data[i++], data[i++], data[i++], data[i++], data[i++], data[i++])
    ctx.fill();
    ctx.restore();
  }
}

function drawCard(x, y, s, number, suitDrawer) {
  ctx.save();
  ctx.transform(s, 0, 0, s, x, y);
  ctx.strokeRect(0, 0, 10, 14);

  if (number <= 10) {
    for (j = 0; j < number;) {
      suitDrawer(j++ % 2 * 3 + 2.5, 10 / number * j, 2);
    }
  } else {
    number = faces[number - 11];
    ctx.fillText(number, 4, 7);
  }

  ctx.fillText(number, 0.5, 2);
  suitDrawer(0.5, 2, 1);
  ctx.transform(-1, 0, 0, -1, 10, 14);
  ctx.fillText(number, 0.5, 2);
  suitDrawer(0.5, 2, 1);

  ctx.restore();
}

/* SUITS
 * 0 = CLUBS
 * 1 = DIAMONDS
 * 2 = SPADES
 * 3 = HEARTS
 */
var suits = [
  drawWrapper(null, normalizeData([522,1635,584,1512,629,1385,635,1251,643,1200,612,1200,609,1237,522,1568,56,1478,73,1164,87,911,340,855,472,939,522,970,519,950,491,919,295,700,416,419,680,414,966,430,1039,734,865,911,842,930,795,1001,865,950,1045,826,1289,961,1283,1155,1275,1512,840,1540,744,1239,736,1208,710,1192,719,1248,730,1349,758,1503,834,1635], 73, 414, 1283, 1635)),
  drawWrapper('red', normalizeData([64,1029,269,829,404,611,532,402,645,632,807,834,982,1029,795,1223,650,1430,533,1647,404,1424,267,1222,64,1029], 0, 402, 1045, 1647)),
  drawWrapper(null, normalizeData([493,1252,493,1213,459,1213,462,1241,459,1387,334,1460,242,1444,102,1416,58,1278,60,1197,63,944,318,759,547,437,714,728,990,957,1006,1181,1030,1481,649,1592,594,1244,592,1221,563,1207,566,1244,573,1338,560,1380,670,1613,670,1613,388,1613,388,1613,451,1504,488,1369,493,1252], 60, 437, 1006, 1613)),
  drawWrapper('red', normalizeData([330,404,490,394,573,530,589,638,599,655,605,650,608,637,616,499,740,386,854,401,1040,404,1153,611,1122,756,1076,971,967,1100,880,1233,781,1370,648,1569,605,1664,605,1664,470,1459,294,1217,176,1055,84,879,73,728,63,586,134,431,330,404], 73, 401, 1122, 1664))
];
for (n = 0; n < 13;) {
  x = n++ * 100;
  for (s = 0; s < 4;)
    drawCard(x, s * 140, 10, n, suits[s++]);
}
<|endoftext|>


<commit_before>const fs = require('fs')
const fw = require('fw')
const path = require('path')
const resolve = require('resolve')
const assign = require('object-assign')

// List of packages that doesn't have a main module.
const resolutions = {
  'spdx-exceptions': 'spdx-exceptions/index.json'
}

exports.resolutions = resolutions
exports.byName = resolveByName
exports.packages = resolveByName
exports.manifest = manifest
exports.flatten = flatten
exports.flattenMap = flattenMap

function manifest (meta, params, cb) {
  if (typeof params === 'function') { cb = params; params = {} }

  const opts = setOptions(params)
  const deps = readDependencies(meta, opts)

  resolveByName(deps, opts, cb)
}

function resolveByName (names, params, cb, lookups) {
  lookups = lookups || []

  if (typeof params === 'function') { cb = params; params = {} }
  if (typeof names === 'string') names = [ names ]

  const opts = setOptions(params)
  const pkgs = mapPackages(names, opts, lookups)

  lookupPackages(pkgs, opts, lookups, cb)
}

function flatten (tree, buf) {
  return tree
  .filter(exists)
  .reduce(function (buf, pkg) {
    buf.push(pkg)
    if (Array.isArray(pkg.dependencies)) {
      flatten(pkg.dependencies, buf)
    }
    return buf
  }, buf || [])
}

function flattenMap (tree, field) {
  const mapper = typeof field === 'function' ? field : function (pkg) {
    return pkg[field || 'manifest']
  }
  return flatten(tree).filter(notEmpty).map(mapper)
}

function lookupPackages (pkgs, opts, lookups, cb) {
  fw.each(pkgs, resolvePackage(lookups), function (err, pkgs) {
    if (err) return cb(err)
    resolveDependencies(pkgs, opts, lookups, resolve)
  })

  function resolve (err, pkgs) {
    if (err || !pkgs) return cb(err, [])
    cb(null, pkgs.filter(exists))
  }
}

function findPredecessor (lookups, pkg) {
  const predecessor = lookups.reduce(function (match, lookup) {
    if (match) return match
    if (lookup === pkg) return null
    if (lookup.root === pkg.root) return lookup
  }, null)

  if (predecessor) {
    return assign({ repeated: true }, predecessor)
  }

  return null
}

function resolvePackage (lookups) {
  return function (pkg, next) {
    const name = resolutions.hasOwnProperty(pkg.name)
      ? resolutions[pkg.name]
      : pkg.name

    resolve(name, { basedir: pkg.basedir }, function (err, main) {
      if (err) return next(err)
      resolveManifest(main, pkg, lookups, next)
    })
  }
}

function resolveManifest (main, pkg, lookups, next) {
  const base = path.dirname(main)
  findMainfest(base, function (err, manifestPath) {
    if (err) return next(new Error('Cannot find package.json for package: ' + pkg.name))

    const manifest = readJSON(manifestPath)
    if (!manifest) return next(new Error('Bad formed JSON: ' + manifestPath))

    // Attach package required fields
    pkg.main = main
    pkg.manifest = manifestPath
    pkg.root = path.dirname(manifestPath)
    pkg.meta = manifest
    pkg.version = manifest.version

    // Detect if it is a redundant dependency
    const predecessor = findPredecessor(lookups, pkg)
    if (predecessor) return next(null, predecessor)

    next(null, pkg)
  })
}

function resolveDependencies (pkgs, opts, lookups, cb) {
  fw.each(pkgs, function (pkg, next) {
    const deps = readDependencies(pkg.meta, opts)
    if (!deps.length) return next(null, pkg)

    // Overwrite options for the next lookup
    const options = assign({}, opts)
    options.basedir = path.dirname(pkg.manifest)

    // If circular, just continue with it
    if (pkg.repeated) return next(null, pkg)

    // Resolve package child dependencies
    resolveByName(deps, options, childDependencies(pkg, next), lookups)
  }, cb)
}

function childDependencies (pkg, next) {
  return function (err, deps) {
    if (err) return next(err)
    next(err, attachDependencies(pkg, deps))
  }
}

function attachDependencies (pkg, deps) {
  pkg.dependencies = deps.filter(function (pkg) {
    return pkg && typeof pkg === 'object'
  })
  return pkg
}

function findMainfest (base, cb) {
  const file = path.join(base, 'package.json')

  fs.exists(file, function (exists) {
    if (exists) return cb(null, file)

    const parent = path.join(base, '..')
    if (isRoot(parent)) return cb(new Error('Cannot find package.json'))

    // Find package in parent directory
    findMainfest(parent, cb)
  })
}

function readDependencies (manifest, opts) {
  return opts.lookups.reduce(function (buf, type) {
    const deps = Object.keys(manifest[type] || {})
    return buf.concat(deps)
  }, [])
}

function mapPackages (pkgs, opts, lookups) {
  return pkgs.map(function (name) {
    const basedir = opts.basedir
    const pkgPath = path.join(basedir, 'node_modules', name, 'package.json')

    const pkg = {
      name: name,
      manifest: pkgPath,
      basedir: basedir
    }

    lookups.push(pkg)
    return pkg
  })
}

function setOptions (params) {
  const cwd = process.cwd()
  const defaults = {
    lookups: ['dependencies'],
    basedir: cwd,
    root: cwd
  }
  return assign(defaults, params)
}

function readJSON (path) {
  try {
    return require(path)
  } catch (e) {
    return false
  }
}

function isRoot (dir) {
  return path.dirname(dir) === '/'
}

function notEmpty (x) {
  return x != null
}

function exists (pkg) {
  return pkg && pkg.root
}
<commit_msg>feat(resolutions): add previous package<commit_after>const fs = require('fs')
const fw = require('fw')
const path = require('path')
const resolve = require('resolve')
const assign = require('object-assign')

// List of packages that doesn't have a main module.
const resolutions = {
  'mz': 'mz/fs',
  'spdx-exceptions': 'spdx-exceptions/index.json'
}

exports.resolutions = resolutions
exports.byName = resolveByName
exports.packages = resolveByName
exports.manifest = manifest
exports.flatten = flatten
exports.flattenMap = flattenMap

function manifest (meta, params, cb) {
  if (typeof params === 'function') { cb = params; params = {} }

  const opts = setOptions(params)
  const deps = readDependencies(meta, opts)

  resolveByName(deps, opts, cb)
}

function resolveByName (names, params, cb, lookups) {
  lookups = lookups || []

  if (typeof params === 'function') { cb = params; params = {} }
  if (typeof names === 'string') names = [ names ]

  const opts = setOptions(params)
  const pkgs = mapPackages(names, opts, lookups)

  lookupPackages(pkgs, opts, lookups, cb)
}

function flatten (tree, buf) {
  return tree
  .filter(exists)
  .reduce(function (buf, pkg) {
    buf.push(pkg)
    if (Array.isArray(pkg.dependencies)) {
      flatten(pkg.dependencies, buf)
    }
    return buf
  }, buf || [])
}

function flattenMap (tree, field) {
  const mapper = typeof field === 'function' ? field : function (pkg) {
    return pkg[field || 'manifest']
  }
  return flatten(tree).filter(notEmpty).map(mapper)
}

function lookupPackages (pkgs, opts, lookups, cb) {
  fw.each(pkgs, resolvePackage(lookups), function (err, pkgs) {
    if (err) return cb(err)
    resolveDependencies(pkgs, opts, lookups, resolve)
  })

  function resolve (err, pkgs) {
    if (err || !pkgs) return cb(err, [])
    cb(null, pkgs.filter(exists))
  }
}

function findPredecessor (lookups, pkg) {
  const predecessor = lookups.reduce(function (match, lookup) {
    if (match) return match
    if (lookup === pkg) return null
    if (lookup.root === pkg.root) return lookup
  }, null)

  if (predecessor) {
    return assign({ repeated: true }, predecessor)
  }

  return null
}

function resolvePackage (lookups) {
  return function (pkg, next) {
    const name = resolutions.hasOwnProperty(pkg.name)
      ? resolutions[pkg.name]
      : pkg.name

    resolve(name, { basedir: pkg.basedir }, function (err, main) {
      if (err) return next(err)
      resolveManifest(main, pkg, lookups, next)
    })
  }
}

function resolveManifest (main, pkg, lookups, next) {
  const base = path.dirname(main)
  findMainfest(base, function (err, manifestPath) {
    if (err) return next(new Error('Cannot find package.json for package: ' + pkg.name))

    const manifest = readJSON(manifestPath)
    if (!manifest) return next(new Error('Bad formed JSON: ' + manifestPath))

    // Attach package required fields
    pkg.main = main
    pkg.manifest = manifestPath
    pkg.root = path.dirname(manifestPath)
    pkg.meta = manifest
    pkg.version = manifest.version

    // Detect if it is a redundant dependency
    const predecessor = findPredecessor(lookups, pkg)
    if (predecessor) return next(null, predecessor)

    next(null, pkg)
  })
}

function resolveDependencies (pkgs, opts, lookups, cb) {
  fw.each(pkgs, function (pkg, next) {
    const deps = readDependencies(pkg.meta, opts)
    if (!deps.length) return next(null, pkg)

    // Overwrite options for the next lookup
    const options = assign({}, opts)
    options.basedir = path.dirname(pkg.manifest)

    // If circular, just continue with it
    if (pkg.repeated) return next(null, pkg)

    // Resolve package child dependencies
    resolveByName(deps, options, childDependencies(pkg, next), lookups)
  }, cb)
}

function childDependencies (pkg, next) {
  return function (err, deps) {
    if (err) return next(err)
    next(err, attachDependencies(pkg, deps))
  }
}

function attachDependencies (pkg, deps) {
  pkg.dependencies = deps.filter(function (pkg) {
    return pkg && typeof pkg === 'object'
  })
  return pkg
}

function findMainfest (base, cb) {
  const file = path.join(base, 'package.json')

  fs.exists(file, function (exists) {
    if (exists) return cb(null, file)

    const parent = path.join(base, '..')
    if (isRoot(parent)) return cb(new Error('Cannot find package.json'))

    // Find package in parent directory
    findMainfest(parent, cb)
  })
}

function readDependencies (manifest, opts) {
  return opts.lookups.reduce(function (buf, type) {
    const deps = Object.keys(manifest[type] || {})
    return buf.concat(deps)
  }, [])
}

function mapPackages (pkgs, opts, lookups) {
  return pkgs.map(function (name) {
    const basedir = opts.basedir
    const pkgPath = path.join(basedir, 'node_modules', name, 'package.json')

    const pkg = {
      name: name,
      manifest: pkgPath,
      basedir: basedir
    }

    lookups.push(pkg)
    return pkg
  })
}

function setOptions (params) {
  const cwd = process.cwd()
  const defaults = {
    lookups: ['dependencies'],
    basedir: cwd,
    root: cwd
  }
  return assign(defaults, params)
}

function readJSON (path) {
  try {
    return require(path)
  } catch (e) {
    return false
  }
}

function isRoot (dir) {
  return path.dirname(dir) === '/'
}

function notEmpty (x) {
  return x != null
}

function exists (pkg) {
  return pkg && pkg.root
}
<|endoftext|>


<commit_before>/* eslint-env node */
'use strict';

module.exports = {
  name: 'ember-m3',

  options: {
    babel: {
      loose: true,
    },
  },
};
<commit_msg>Do not put mutable state on the prototype.<commit_after>/* eslint-env node */
'use strict';

module.exports = {
  name: 'ember-m3',

  init() {
    this._super.init.apply(this, arguments);

    this.options = this.options || {};
    this.options.babel = this.options.babel || {};
    this.options.babel.loose = true;
  },
};
<|endoftext|>


<commit_before>'use strict';

const fs = require('fs');
const css = require('css');
const hash = require('hash-sum');
const cssWhat = require('css-what');
const stripBom = require('strip-bom');
const compiler = require('vue-template-compiler');

/**
 * [stringify description]
 * @type {Function} stringify
 */
const stringify = require('./css-what/stringify');
window.stringify = stringify;
window.cssWhat = cssWhat;

/**
 * In Browser Environment
 * @type {Boolean} browserEnv
 */
let browserEnv = false;
try {
    document;
    browserEnv = true;
} catch (e) {}

/**
 * Save Loaders of different Language
 * @type {Object} store
 */
let store = {
    style : {
        defaults : '',
        langs : {},
    },
    script : {
        defaults : '',
        langs : {},
    },
    template : {
        defaults : '',
        langs : {},
    },
};

/**
 * Set default Loader of different Language
 * @param {String} type | style | script | template |
 * @param {String} lang scss, ts, jade etc.
 */
function set ( type, lang ) {
    store[type].defaults = lang;
}

/**
 * Register Loader of different Language
 * @param {String} type | style | script | template |
 * @param {String} lang scss, ts, jade etc.
 * @param {Function} handler handler
 */
function register ( type, lang, handler ) {
    store[type].langs[lang] = handler;
}

/**
 * Require extension vue hook
 * @param {Module} module module
 * @param {String} filePath file path
 * @export {Vue} Vue Component after compile
 */
function loader ( module, filePath ) {

    let content = fs.readFileSync(filePath, 'utf8');
    let moduleId = `_v-${ hash(filePath) }`;

    let vueTemplate = '';
    let vueComponent = compiler.parseComponent(stripBom(content));

    let script = vueComponent.script;
    let styles = vueComponent.styles;
    let template = vueComponent.template;

    let scoped = styles.some(({ attrs }) => attrs.scoped);

    [].concat(script, template, styles).forEach(( tag ) => {
        if (tag) {
            let type = tag.type;
            let content = tag.content;
            let lang = tag.attrs.lang || store[type].defaults;
            let handler = store[type].langs[lang];
            if (handler) {
                content = handler(content, filePath);
            }
            switch (type) {
                case 'style':
                    if (browserEnv) {
                        /**
                         * Only in Browser Environment, append style to head
                         */
                        if (content instanceof Promise) {
                            /**
                             * Style support async
                             */
                            content.then(sync);
                        } else {
                            sync(content);
                        }
                        function sync ( content ) {
                            if (tag.attrs.scoped) {
                                let ast = css.parse(content);
                                ast.stylesheet.rules.forEach(( rule ) => {
                                    rule.selectors = rule.selectors.map(( selector ) => {
                                        // TODO:
                                        console.log(selector);
                                        let [ tokens ] = cssWhat(selector);
                                        let index = tokens.length - 1;
                                        tokens.some(({ type }) => {
                                            index--;
                                            if (type !== 'pseudo' && type !== 'pseudo-element') {
                                                return true;
                                            }
                                        });
                                        tokens.splice(index + 1, 0, {
                                            value : '',
                                            name : moduleId,
                                            action : 'exists',
                                            type : 'attribute',
                                            ignoreCase : false,
                                        });
                                        let test = stringify([tokens]);
                                        console.log(test);
                                        // TODO:
                                        return `${ selector }[${ moduleId }]`;
                                    });
                                });
                                content = css.stringify(ast);
                            }
                            let style = document.createElement('style');
                            style.innerHTML = content;
                            document.head.appendChild(style);
                        }
                    }
                    break;
                case 'script':
                    module._compile(content, filePath);
                    break;
                case 'template':
                    if (browserEnv) {
                        /**
                         * Only in Browser Environment, set Attribute for each element
                         */
                        if (scoped) {
                            let div = document.createElement('div');
                            div.innerHTML = content;
                            let root = div.firstElementChild;
                            walk(root, ( element ) => {
                                element.setAttribute(moduleId, '');
                            });
                            function walk ( element, handler ) {
                                handler(element);
                                let children = element.children || [];
                                [].forEach.call(children, ( child ) => {
                                    walk(child, handler);
                                });
                            }
                            content = div.innerHTML;
                        }
                    }
                    vueTemplate = content;
                    break;
            }
        }
    });

    module.exports.template = vueTemplate;
}

/**
 * Exports API to expand
 */
['style', 'script', 'template'].forEach(( type ) => {
    loader[type] = {
        set ( lang ) {
            set(type, lang);
            return this;
        },
        register ( lang, handler ) {
            register(type, lang, handler);
            return this;
        },
    };
});

/**
 * Register Loader as default .vue hook
 */
require.extensions['.vue'] = require.extensions['.vue'] || loader;

/**
 * @export {Function} loader
 */
module.exports = loader;
<commit_msg>update js<commit_after>'use strict';

const fs = require('fs');
const css = require('css');
const hash = require('hash-sum');
const cssWhat = require('css-what');
const stripBom = require('strip-bom');
const compiler = require('vue-template-compiler');

/**
 * @fork https://github.com/fb55/css-what/blob/master/stringify.js
 * @type {Function} stringify
 */
cssWhat.stringify = require('./css-what/stringify');

/**
 * In Browser Environment
 * @type {Boolean} browserEnv
 */
let browserEnv = false;
try {
    document;
    browserEnv = true;
} catch (e) {}

/**
 * Save Loaders of different Language
 * @type {Object} store
 */
let store = {
    style : {
        defaults : '',
        langs : {},
    },
    script : {
        defaults : '',
        langs : {},
    },
    template : {
        defaults : '',
        langs : {},
    },
};

/**
 * Set default Loader of different Language
 * @param {String} type | style | script | template |
 * @param {String} lang scss, ts, jade etc.
 */
function set ( type, lang ) {
    store[type].defaults = lang;
}

/**
 * Register Loader of different Language
 * @param {String} type | style | script | template |
 * @param {String} lang scss, ts, jade etc.
 * @param {Function} handler handler
 */
function register ( type, lang, handler ) {
    store[type].langs[lang] = handler;
}

/**
 * Require extension vue hook
 * @param {Module} module module
 * @param {String} filePath file path
 * @export {Vue} Vue Component after compile
 */
function loader ( module, filePath ) {

    let content = fs.readFileSync(filePath, 'utf8');
    let moduleId = `_v-${ hash(filePath) }`;

    let vueTemplate = '';
    let vueComponent = compiler.parseComponent(stripBom(content));

    let script = vueComponent.script;
    let styles = vueComponent.styles;
    let template = vueComponent.template;

    let scoped = styles.some(({ attrs }) => attrs.scoped);

    [].concat(script, template, styles).forEach(( tag ) => {
        if (tag) {
            let type = tag.type;
            let content = tag.content;
            let lang = tag.attrs.lang || store[type].defaults;
            let handler = store[type].langs[lang];
            if (handler) {
                content = handler(content, filePath);
            }
            switch (type) {
                case 'style':
                    if (browserEnv) {
                        /**
                         * Only in Browser Environment, append style to head
                         */
                        if (content instanceof Promise) {
                            /**
                             * Style support async
                             */
                            content.then(sync);
                        } else {
                            sync(content);
                        }
                        function sync ( content ) {
                            if (tag.attrs.scoped) {
                                let ast = css.parse(content);
                                ast.stylesheet.rules.forEach(( rule ) => {
                                    rule.selectors = rule.selectors.map(( selector ) => {
                                        let [ patterns ] = cssWhat(selector);
                                        let index = patterns.length - 1;
                                        for (; index >= 0; index--) {
                                            let { type } = patterns[index];
                                            if (type !== 'pseudo' && type !== 'pseudo-element') {
                                                break;
                                            }
                                        }
                                        patterns.splice(index + 1, 0, {
                                            value : '',
                                            name : moduleId,
                                            action : 'exists',
                                            type : 'attribute',
                                            ignoreCase : false,
                                        });
                                        return stringify([patterns]);
                                    });
                                });
                                content = css.stringify(ast);
                            }
                            let style = document.createElement('style');
                            style.innerHTML = content;
                            document.head.appendChild(style);
                        }
                    }
                    break;
                case 'script':
                    module._compile(content, filePath);
                    break;
                case 'template':
                    if (browserEnv) {
                        /**
                         * Only in Browser Environment, set Attribute for each element
                         */
                        if (scoped) {
                            let div = document.createElement('div');
                            div.innerHTML = content;
                            let root = div.firstElementChild;
                            walk(root, ( element ) => {
                                element.setAttribute(moduleId, '');
                            });
                            function walk ( element, handler ) {
                                handler(element);
                                let children = element.children || [];
                                [].forEach.call(children, ( child ) => {
                                    walk(child, handler);
                                });
                            }
                            content = div.innerHTML;
                        }
                    }
                    vueTemplate = content;
                    break;
            }
        }
    });

    module.exports.template = vueTemplate;
}

/**
 * Exports API to expand
 */
['style', 'script', 'template'].forEach(( type ) => {
    loader[type] = {
        set ( lang ) {
            set(type, lang);
            return this;
        },
        register ( lang, handler ) {
            register(type, lang, handler);
            return this;
        },
    };
});

/**
 * Register Loader as default .vue hook
 */
require.extensions['.vue'] = require.extensions['.vue'] || loader;

/**
 * @export {Function} loader
 */
module.exports = loader;
<|endoftext|>


<commit_before>'use strict';

/**
 * Regular expression for matching Bitcoin addresses
 *
 * @api public
 */

module.exports = function () {
	return /(?:^|\s)(?:[13][1-9A-Za-z][^O0Il]{24,32})/g;
};
<commit_msg>Beginning of the line or white space is optional<commit_after>'use strict';

/**
 * Regular expression for matching Bitcoin addresses
 *
 * @api public
 */

module.exports = function () {
	return /(?:^|\s)?(?:[13][1-9A-Za-z][^O0Il]{24,32})/g;
};
<|endoftext|>


<commit_before>'use strict';
var AnsiEscapes = require('ansi-escapes');
var AnsiStyles = require('ansi-styles');
var webpack = require('webpack');

require('object.assign').shim();

var bold = AnsiStyles.bold;
var inverse = AnsiStyles.inverse;

var red = AnsiStyles.red;
var yellow = AnsiStyles.yellow;
var green = AnsiStyles.green;
var blue = AnsiStyles.blue;
var magenta = AnsiStyles.magenta;

var bgRed = AnsiStyles.bgRed;
var bgYellow = AnsiStyles.bgYellow;
var bgGreen = AnsiStyles.bgGreen;
var bgBlue = AnsiStyles.bgBlue;

var cursorUp = AnsiEscapes.cursorUp;
var cursorDown = AnsiEscapes.cursorDown;
var eraseEndLine = AnsiEscapes.eraseEndLine;
var cursorSavePosition = AnsiEscapes.cursorSavePosition;
var cursorRestorePosition = AnsiEscapes.cursorRestorePosition;

var width = 50;
var stdoutLineCount = 0;

var nyanTemplate = {
  ascii: [
    ' ,--------,     ',
    ' │▗▝ ▞ ▝ ˄---˄  ',
    '~│ ▞  ▞ ❬.◕‿‿◕.❭',
    ' `w-w---- w w   '
  ],
  colors: [
    ' ggggggggggg    ',
    ' gMMMMMMMggggg  ',
    'ggMMMMMMgwwwwwwg',
    ' gggggggggggg   '
  ]
};

var nyanSaysTemplate = {
  ascii: [
    ' ,--------,      ,(-)-.',
    ' │▗▝ ▞ ▝ ˄---˄  / (X) |',
    '~│ ▞  ▞ ❬.◕‿‿◕.❭--(-)-’',
    ' `w-w---- w w            '
  ],
  colors: [
    ' ggggggggggg     w(w)ww',
    ' gMMMMMMMggggg  ww(w)ww',
    'ggMMMMMMgwwwwwwgww(w)ww',
    ' gggggggggggg            '
  ]
};

var templateColorMap = {
  g: function(t) { return t; },
  M: function(t) { return wrap(bold, wrap(magenta, wrap(inverse, t))); },
  w: function(t) { return wrap(bold, t); }
}

function wrap(color, text) {
  return color.open + text + color.close;
}

function prepareNyan(template, colorToAscii, text) {
  text = text && text.toString();
  return template.ascii.map(function(row, idx) {
    return row.replace(/\((.)\)/, function(m, c) {
      return c === 'X' ? text : text.replace(/./g, c);
    }).split('').reduce(function (arr, chr, j) {
      var color = template.colors[idx][j];
      var last = arr[arr.length - 1];
      if (last && last.colorCode === color) {
        last.text += chr;
        return arr;
      } else {
        return arr.concat({
          colorCode: color,
          color: colorToAscii[color] || function(t) { return t; },
          text: chr
        });
      }
    }, []);
  });
}

var nyanDefault = prepareNyan(nyanTemplate, templateColorMap);

var rainbow = [
  [
    function(t) { return wrap(red, t); },
    function(t) { return t.replace(/./g, ' '); }
  ],
  [
    function(t) { return wrap(bgRed, wrap(yellow, t)); },
    function(t) { return wrap(bold, wrap(red, wrap(bgRed, t))); }
  ],
  [
    function(t) { return wrap(bgYellow, wrap(green, t)); },
    function(t) { return wrap(bold, wrap(yellow, wrap(bgYellow, t))); }
  ],
  [
    function(t) { return wrap(bgGreen, wrap(blue, t)); },
    function(t) { return wrap(bold, wrap(green, wrap(bgGreen, t))); }
  ],
  [
    function(t) { return wrap(inverse, wrap(blue, t)); },
    function(t) { return wrap(bold, wrap(blue, wrap(bgBlue, t))); }
  ]
];

function drawRainbow(colors, width, step) {
  var wave = ['\u2584', '\u2591'];
  var text = '';
  var line = '';
  var idx = step;
  for (var i = 0; i < width; i++) {
    text += wave[idx % 2];
    if((step + i) % 4 === 0) {
      line += colors[idx % 2](text);
      text = '';
      idx++;
    }
  }
  return text ? line + colors[idx % 2](text) : line;
}

function drawNyan(nyan, line, idx) {
  return nyan[idx].reduce(function(l, obj) {
    return l + obj.color(obj.text);
  }, line);
}

function onProgress(progress, messages, step, isInProgress, options) {
  var progressWidth = Math.ceil(progress * width);
  var nyanText = options.nyanCatSays(progress, messages);

  if (isInProgress) {
    if (options.restoreCursorPosition) {
      options.logger(cursorSavePosition + cursorUp(1));
    }
    options.logger(cursorUp(rainbow.length + stdoutLineCount + 2));
  }

  for (var i = 0; i < rainbow.length; i++) {
    var line = drawRainbow(rainbow[i], progressWidth, step);
    var nyanLine = i + ((step % 8 < 4) ? -1 : 0);
    if (nyanLine < 4 && nyanLine >= 0) {
      line = drawNyan(
        nyanText ? prepareNyan(nyanSaysTemplate, templateColorMap, nyanText) : nyanDefault,
        line,
        nyanLine
      );
    }

    options.logger(line + eraseEndLine);
  }
  options.logger(options.getProgressMessage(progress, messages, AnsiStyles) +
    eraseEndLine + (!isInProgress ? cursorDown(1) : '')
  );
  if (isInProgress) {
    if (options.restoreCursorPosition) {
      options.logger(cursorRestorePosition + cursorUp(1));
    } else if (stdoutLineCount > 0) {
      options.logger(cursorDown(stdoutLineCount - 1));
    }
  }
}

module.exports = function NyanProgressPlugin(options) {
  var timer = 0;
  var shift = 0;
  var originalStdoutWrite;
  var isPrintingProgress = false;
  var isStarted = false;
  var startTime = 0;

  options = Object.assign({
    debounceInterval: 180,
    logger: console.log.bind(console), // eslint-disable-line no-console
    hookStdout: true,
    getProgressMessage: function(percentage, messages, styles) {
      return styles.cyan.open + messages[0] + styles.cyan.close +
        (messages[1] ?
          ' ' + styles.green.open + '(' + messages[1] + ')' + styles.green.close :
          ''
        );
    },
    nyanCatSays: function (progress) { return progress === 1 && 'Nyan!'; }
  }, options);

  if (options.hookStdout) {
    originalStdoutWrite = process.stdout.write;
    process.stdout.write = function(msg) {
      originalStdoutWrite.apply(process.stdout, arguments);
      if (isStarted && !isPrintingProgress) {
        stdoutLineCount += msg.split('\n').length - 1;
      }
    }
  }

  return new webpack.ProgressPlugin(function(progress, message) {
    var now = new Date().getTime();
    if (!isStarted) {
      onProgress(progress, [message], shift++, false, options);
      startTime = now;
      isStarted = true;
    } else if (progress === 1) {
      isPrintingProgress = true;
      var endTimeMessage = 'build time: ' + (now - startTime) / 1000 + 's';
      onProgress(progress, [message, endTimeMessage], shift++, true, options);
      isPrintingProgress = false;

      if (originalStdoutWrite) {
        process.stdout.write = originalStdoutWrite;
      }
      stdoutLineCount = 0;
      isStarted = false;
    } else if (now - timer > options.debounceInterval) {
      timer = now;
      isPrintingProgress = true;
      onProgress(progress, [message], shift++, true, options);
      isPrintingProgress = false;
    }
  });
};
<commit_msg>minor fix<commit_after>'use strict';
var AnsiEscapes = require('ansi-escapes');
var AnsiStyles = require('ansi-styles');
var webpack = require('webpack');

require('object.assign').shim();

var bold = AnsiStyles.bold;
var inverse = AnsiStyles.inverse;

var red = AnsiStyles.red;
var yellow = AnsiStyles.yellow;
var green = AnsiStyles.green;
var blue = AnsiStyles.blue;
var magenta = AnsiStyles.magenta;

var bgRed = AnsiStyles.bgRed;
var bgYellow = AnsiStyles.bgYellow;
var bgGreen = AnsiStyles.bgGreen;
var bgBlue = AnsiStyles.bgBlue;

var cursorUp = AnsiEscapes.cursorUp;
var cursorDown = AnsiEscapes.cursorDown;
var eraseEndLine = AnsiEscapes.eraseEndLine;
var cursorSavePosition = AnsiEscapes.cursorSavePosition;
var cursorRestorePosition = AnsiEscapes.cursorRestorePosition;

var width = 50;
var stdoutLineCount = 0;

var nyanTemplate = {
  ascii: [
    ' ,--------,     ',
    ' │▗▝ ▞ ▝ ˄---˄  ',
    '~│ ▞  ▞ ❬.◕‿‿◕.❭',
    ' `w-w---- w w   '
  ],
  colors: [
    ' ggggggggggg    ',
    ' gMMMMMMMggggg  ',
    'ggMMMMMMgwwwwwwg',
    ' gggggggggggg   '
  ]
};

var nyanSaysTemplate = {
  ascii: [
    ' ,--------,      ,(-)-.',
    ' │▗▝ ▞ ▝ ˄---˄  / (X) |',
    '~│ ▞  ▞ ❬.◕‿‿◕.❭--(-)-’',
    ' `w-w---- w w            '
  ],
  colors: [
    ' ggggggggggg     w(w)ww',
    ' gMMMMMMMggggg  ww(w)ww',
    'ggMMMMMMgwwwwwwgww(w)ww',
    ' gggggggggggg            '
  ]
};

var templateColorMap = {
  g: function(t) { return t; },
  M: function(t) { return wrap(bold, wrap(magenta, wrap(inverse, t))); },
  w: function(t) { return wrap(bold, t); }
}

function wrap(color, text) {
  return color.open + text + color.close;
}

function prepareNyan(template, colorToAscii, text) {
  text = text && text.toString();
  return template.ascii.map(function(row, idx) {
    return row.replace(/\((.)\)/, function(m, c) {
      return c === 'X' ? text : text.replace(/./g, c);
    }).split('').reduce(function (arr, chr, j) {
      var color = template.colors[idx][j];
      var last = arr[arr.length - 1];
      if (last && last.colorCode === color) {
        last.text += chr;
        return arr;
      } else {
        return arr.concat({
          colorCode: color,
          color: colorToAscii[color] || function(t) { return t; },
          text: chr
        });
      }
    }, []);
  });
}

var nyanDefault = prepareNyan(nyanTemplate, templateColorMap);

var rainbow = [
  [
    function(t) { return wrap(red, t); },
    function(t) { return t.replace(/./g, ' '); }
  ],
  [
    function(t) { return wrap(bgRed, wrap(yellow, t)); },
    function(t) { return wrap(bold, wrap(red, wrap(bgRed, t))); }
  ],
  [
    function(t) { return wrap(bgYellow, wrap(green, t)); },
    function(t) { return wrap(bold, wrap(yellow, wrap(bgYellow, t))); }
  ],
  [
    function(t) { return wrap(bgGreen, wrap(blue, t)); },
    function(t) { return wrap(bold, wrap(green, wrap(bgGreen, t))); }
  ],
  [
    function(t) { return wrap(inverse, wrap(blue, t)); },
    function(t) { return wrap(bold, wrap(blue, wrap(bgBlue, t))); }
  ]
];

function drawRainbow(colors, width, step) {
  var wave = ['\u2584', '\u2591'];
  var text = '';
  var line = '';
  var idx = step;
  for (var i = 0; i < width; i++) {
    text += wave[idx % 2];
    if((step + i) % 4 === 0) {
      line += colors[idx % 2](text);
      text = '';
      idx++;
    }
  }
  return text ? line + colors[idx % 2](text) : line;
}

function drawNyan(nyan, line, idx) {
  return nyan[idx].reduce(function(l, obj) {
    return l + obj.color(obj.text);
  }, line);
}

function onProgress(progress, messages, step, isInProgress, options) {
  var progressWidth = Math.ceil(progress * width);
  var nyanText = options.nyanCatSays(progress, messages);

  if (isInProgress) {
    if (options.restoreCursorPosition) {
      options.logger(cursorSavePosition + cursorUp(1));
    }
    options.logger(cursorUp(rainbow.length + stdoutLineCount + 2));
  } else {
    options.logger('');
  }

  for (var i = 0; i < rainbow.length; i++) {
    var line = drawRainbow(rainbow[i], progressWidth, step);
    var nyanLine = i + ((step % 8 < 4) ? -1 : 0);
    if (nyanLine < 4 && nyanLine >= 0) {
      line = drawNyan(
        nyanText ? prepareNyan(nyanSaysTemplate, templateColorMap, nyanText) : nyanDefault,
        line,
        nyanLine
      );
    }

    options.logger(line + eraseEndLine);
  }
  options.logger(options.getProgressMessage(progress, messages, AnsiStyles) +
    eraseEndLine + (!isInProgress ? cursorDown(1) : '')
  );
  if (isInProgress) {
    if (options.restoreCursorPosition) {
      options.logger(cursorRestorePosition + cursorUp(1));
    } else if (stdoutLineCount > 0) {
      options.logger(cursorDown(stdoutLineCount - 1));
    }
  }
}

module.exports = function NyanProgressPlugin(options) {
  var timer = 0;
  var shift = 0;
  var originalStdoutWrite;
  var isPrintingProgress = false;
  var isStarted = false;
  var startTime = 0;

  options = Object.assign({
    debounceInterval: 180,
    logger: console.log.bind(console), // eslint-disable-line no-console
    hookStdout: true,
    getProgressMessage: function(percentage, messages, styles) {
      return styles.cyan.open + messages[0] + styles.cyan.close +
        (messages[1] ?
          ' ' + styles.green.open + '(' + messages[1] + ')' + styles.green.close :
          ''
        );
    },
    nyanCatSays: function (progress) { return progress === 1 && 'Nyan!'; }
  }, options);

  if (options.hookStdout) {
    originalStdoutWrite = process.stdout.write;
    process.stdout.write = function(msg) {
      originalStdoutWrite.apply(process.stdout, arguments);
      if (isStarted && !isPrintingProgress) {
        stdoutLineCount += msg.split('\n').length - 1;
      }
    }
  }

  return new webpack.ProgressPlugin(function(progress, message) {
    var now = new Date().getTime();
    if (!isStarted) {
      onProgress(progress, [message], shift++, false, options);
      startTime = now;
      isStarted = true;
    } else if (progress === 1) {
      isPrintingProgress = true;
      var endTimeMessage = 'build time: ' + (now - startTime) / 1000 + 's';
      onProgress(progress, [message, endTimeMessage], shift++, true, options);
      isPrintingProgress = false;

      if (originalStdoutWrite) {
        process.stdout.write = originalStdoutWrite;
      }
      stdoutLineCount = 0;
      isStarted = false;
    } else if (now - timer > options.debounceInterval) {
      timer = now;
      isPrintingProgress = true;
      onProgress(progress, [message], shift++, true, options);
      isPrintingProgress = false;
    }
  });
};
<|endoftext|>


<commit_before>'use strict'

var through = require('through2')

module.exports = function (/*streams...*/) {
  var firstTick = true;
  var sources = []
  var output  = through.obj()

  output.setMaxListeners(0)

  output.add = add

  output.on('unpipe', remove)

  Array.prototype.slice.call(arguments).forEach(add)

  return output

  function add (source) {
    sources.push(source)
    source.once('end', remove.bind(null, source))
    source.pipe(output, {end: false})
    return source
  }

  function remove (source) {
    sources = sources.filter(function (it) { return it !== source })
    if (!sources.length && output.readable) { output.emit('end') }
  }
}
<commit_msg>Pass an array as an argument<commit_after>'use strict'

var through = require('through2')

module.exports = function (/*streams...*/) {
  var firstTick = true;
  var sources = []
  var output  = through.obj()
  var args = arguments

  if (args[0] instanceof Array){
    args = args[0]
  }

  output.setMaxListeners(0)

  output.add = add

  output.on('unpipe', remove)

  Array.prototype.slice.call(args).forEach(add)

  return output

  function add (source) {
    sources.push(source)
    source.once('end', remove.bind(null, source))
    source.pipe(output, {end: false})
    return source
  }

  function remove (source) {
    sources = sources.filter(function (it) { return it !== source })
    if (!sources.length && output.readable) { output.emit('end') }
  }
}
<|endoftext|>


<commit_before>var express = require('express'),
  router = express.Router(),
  mongoose = require('mongoose'),
  Schema = mongoose.Schema,
  _ = require('underscore'),
  moment = require('moment'),
  debug = require('debug')('mera'),
  XLSX = require('xlsx'),
  os = require('os'),
  path = require('path');

function mongooseRoute(model, options) {
  var router = express.Router();

  var options = options || {},
    omitProps = ['output'].concat(options.omitProps),
    props = options.props || _.keys(model.schema.tree).filter(e => !/^_/.test(e)).filter(e => omitProps.indexOf(e) == -1),
    propsMapping = _.extend({ 'id': '_id' }, options.propsMapping),
    _id = options._id || '_id',
    uploadProps = options.uploadProps || {};

  function error(method, err, statusCode) {
    var msg = 'Failed to ' + method + ' ' + model.modelName + ' : ' + err;
    var retErr = new Error(msg);
    err.statusCode = statusCode || 500;
    debug('err: %j', retErr);
    return retErr;
  }

  function convert(data) {
    _.each(_.keys(propsMapping), k => {
      if (data[k] && propsMapping[k] != k) {
        data[propsMapping[k]] = data[k];
        delete data[k];
      }
    });
    return data;
  }

  function output(item) {
    if (!item) return {};
    var output = {};
    props.forEach(p => { output[p] = item[p] }); // item can have virtual props so they need to be assigned one by one.
    return output;
  }

  // time filter works in such a way:
  // if start is given, only look at end, and start/end are parsed literally by moment.js, gte start, and lt end
  // otherwise look at start_time and then end_time
  // so if given start and end_time, only start takes effects
  // a special handle on end_time is if YYYY-MM-DD is given, we regard it as a full day included
  function getTimeFilter(rawFilter) {
    if (!options.timeFilter) {
      return null;
    }
    var f = {};
    if (rawFilter.start) {
      f.$gte = moment(rawFilter.start).toDate();
      if (rawFilter.end) {
        f.$lt = moment(rawFilter.end).toDate();
      }
    } else if (rawFilter.start_time) {
      f.$gte = moment(rawFilter.start_time).toDate();
      if (rawFilter.end_time) {
        if (/[0-9]{4,4}-[0-9]{2,2}-[0-9]{2,2}/.test(rawFilter.end_time)) {
          f.$lt = moment(rawFilter.end_time).add(1, 'day').startOf('day').toDate();
        } else {
          f.$lt = moment(rawFilter.end_time).toDate();
        }
      }
    }
    if (_.isEmpty(f)) {
      return null;
    }
    var timeFilter = {};
    timeFilter[options.timeFilter] = f;
    return timeFilter;
  }

  function replaceUploaded(req, res, next) {
    if (!_.isEmpty(uploadProps)) {
      _.keys(uploadProps).forEach(k => {
        if (req.body[k]) {
          req.body[uploadProps[k]] = req.body[k];
        }
      });
    }
    next();
  }

  function pickFilters(base, raw) {
    _.keys(raw).forEach(k => {
      var secs = k.split('.'), bk = secs.shift(1);
      if (props.indexOf(bk) == -1)
        return;
      base[k] = raw[k];
    });
    return base;
  }

  function Workbook() {
    if (!(this instanceof Workbook)) return new Workbook();
    this.SheetNames = [];
    this.Sheets = {};
  }

  function datenum(v, date1904) {
    if (date1904) v += 1462;
    var epoch = Date.parse(v);
    return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
  }

  function sheet_from_array_of_arrays(data, opts) {
    var ws = {};
    var range = { s: { c: 10000000, r: 10000000 }, e: { c: 0, r: 0 } };
    for (var R = 0; R != data.length; ++R) {
      for (var C = 0; C != data[R].length; ++C) {
        if (range.s.r > R) range.s.r = R;
        if (range.s.c > C) range.s.c = C;
        if (range.e.r < R) range.e.r = R;
        if (range.e.c < C) range.e.c = C;
        var cell = { v: data[R][C] };
        if (cell.v == null) continue;
        var cell_ref = XLSX.utils.encode_cell({ c: C, r: R });

        if (typeof cell.v === 'number') cell.t = 'n';
        else if (typeof cell.v === 'boolean') cell.t = 'b';
        else if (cell.v instanceof Date) {
          cell.t = 'n'; cell.z = XLSX.SSF._table[14];
          cell.v = datenum(cell.v);
        }
        else cell.t = 's';

        ws[cell_ref] = cell;
      }
    }
    if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
    return ws;
  }

  function formatToXlsx(data, name) {
    var ws_name = "SheetJS";
    var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);

    /* add worksheet to workbook */
    wb.SheetNames.push(ws_name);
    wb.Sheets[ws_name] = ws;

    var tempFile = path.join(os.tmpdir(), (name || (new Date().toString() + '.xlsx')));
    XLSX.writeFile(wb, tempFile);
    return tempFile;
  }

  function formatToCsv(rows, head) {
    var lines = []
    if (head) {
      lines.push(head.map(e => `"${e}"`).join(','))
    }
    rows.forEach(row => {
      lines.push(row.map(e => `"${e}"`).join(','))
    })
    return lines.join('\r\n')
  }

  // protect the method if defined in protects
  router.use('/', function(req, rest, next) {
    var protects = options.protects || {};
    var protect = req.method === 'GET' ? (req.url === '/' ? protects.LIST : protects.GET) : protects[req.method];
    if (protect) {
      protect(req, next);
    } else {
      next();
    }
  });

  router.get('/', function(req, res, next) {

    // filter buildup
    var filter = _.extend({}, options.baseFilter);

    // regard _filter in query firstly
    if (req.query._filters) {
      try {
        pickFilters(filter, JSON.parse(req.query._filters));
      } catch (e) {
        debug('not valid _filter although present: %j', req.query._filter);
      }
    } else {
      pickFilters(filter, req.query);
    }
    filter = convert(filter);
    _.extend(filter, getTimeFilter(req.query));

    debug('List %s by filter %j', model.modelName, filter);

    // listOptions buildup
    var lo = {
      limit: parseInt(req.query._perPage) || 0
    };
    lo.skip = Math.max((req.query._page || 1) - 1, 0) * lo.limit;
    if (req.query._sortField && req.query._sortDir) {
      lo.sort = {};
      lo.sort[req.query._sortField.replace(/^id/, '_id')] = req.query._sortDir.toUpperCase() == 'ASC' ? 1 : -1;
    } else {
      lo.sort = options.defaultSort;
    }
    debug('get list options from request: %j', lo);

    // list model
    model.count(filter, function(err, num) {
      if (err) {
        return next(error('LIST', err));
      }
      var items = [], limit = Math.min(lo.limit, 1000), skip = lo.skip;

      function findBatch(cb) {
        model.find(filter).sort(lo.sort).skip(skip).limit(limit).exec(function(errB, itemsB) {
          if (errB) return cb(errB);
          items = items.concat(itemsB)
          // if get all items, finish batch
          if (items.length >= lo.limit) {
            return cb(null, items)
          }
          // if current fetch is less than a batch, which means no more items to get, finish batch
          if (itemsB.length < limit) {
            return cb(null, items);
          }
          // else, continue
          skip = skip + itemsB.length;
          findBatch(cb)
        });
      }
      findBatch((err2, items) => {
        if (err2) {
          return next(error('LIST', err2));
        }
        if (req.query.format == 'csv') {
          res.set('Content-Type', 'text/csv');
          var rows = items.map(e => props.map(k => e[k]));
          var csvout = formatToCsv(rows, props);
          res.send(csvout);
        } else if (req.query.format == 'xlsx') {
          var rows = items.map(e => props.map(k => e[k]));
          rows.unshift(props);
          var wbout = formatToXlsx(rows, model.modelName + '_' + new Date().getTime().toString() + '.xlsx');
          res.sendfile(wbout);
        } else {
          res.set('X-Total-Count', num).json(items.map(output));
        }
      })
    });
  });

  router.post('/', replaceUploaded, function(req, res, next) {
    var data = convert(req.body);
    debug('Post to model %s by data %j', model.modelName, data);

    model.create(data, function(err, item) {
      if (err) {
        return next(error('POST', err));
      }
      res.json(output(item));
    });
  });

  router.use('/:id', function(req, res, next) {
    req.id_filter = {};
    req.id_filter[options._id || '_id'] = req.params.id;
    next();
  });

  router.get('/:id', function(req, res, next) {
    debug('Get model %s by id %s', model.modelName, req.params.id);
    model.findOne(req.id_filter).exec(function(err, item) {
      if (err) {
        return next(error('GET', err));
      }
      if (!item) {
        return next();
      }
      res.json(output(item));
    });
  });

  router.put('/:id', replaceUploaded, function(req, res, next) {
    var data = convert(req.body);
    debug('Put to model %s, id %s by data %j', model.modelName, req.params.id, data);

    model.findOne(req.id_filter).exec(function(err, item) {
      if (err) {
        return next(error('PUT', err));
      }
      if (!item) {
        return next();
      }
      _.extend(item, data);
      item.save(function(err) {
        if (err) {
          return next(error('PUT', err));
        }
        res.json(output(item));
      });
    });
  });

  router.delete('/:id', function(req, res, next) {
    debug('delete model %s by id %s', model.modelName, req.params.id);

    model.remove(req.id_filter).exec(function(err, item) {
      if (err) {
        return next(error('DELETE', err));
      }
      res.json(output(item));
    });
  });

  return router;
}

module.exports = mongooseRoute;
<commit_msg>make batchSize an option<commit_after>var express = require('express'),
  router = express.Router(),
  mongoose = require('mongoose'),
  Schema = mongoose.Schema,
  _ = require('underscore'),
  moment = require('moment'),
  debug = require('debug')('mera'),
  XLSX = require('xlsx'),
  os = require('os'),
  path = require('path');

function mongooseRoute(model, options) {
  var router = express.Router();

  var options = options || {},
    omitProps = ['output'].concat(options.omitProps),
    props = options.props || _.keys(model.schema.tree).filter(e => !/^_/.test(e)).filter(e => omitProps.indexOf(e) == -1),
    propsMapping = _.extend({ 'id': '_id' }, options.propsMapping),
    _id = options._id || '_id',
    uploadProps = options.uploadProps || {};

  options.batchSize = options.batchSize || 1000;

  function error(method, err, statusCode) {
    var msg = 'Failed to ' + method + ' ' + model.modelName + ' : ' + err;
    var retErr = new Error(msg);
    err.statusCode = statusCode || 500;
    debug('err: %j', retErr);
    return retErr;
  }

  function convert(data) {
    _.each(_.keys(propsMapping), k => {
      if (data[k] && propsMapping[k] != k) {
        data[propsMapping[k]] = data[k];
        delete data[k];
      }
    });
    return data;
  }

  function output(item) {
    if (!item) return {};
    var output = {};
    props.forEach(p => { output[p] = item[p] }); // item can have virtual props so they need to be assigned one by one.
    return output;
  }

  // time filter works in such a way:
  // if start is given, only look at end, and start/end are parsed literally by moment.js, gte start, and lt end
  // otherwise look at start_time and then end_time
  // so if given start and end_time, only start takes effects
  // a special handle on end_time is if YYYY-MM-DD is given, we regard it as a full day included
  function getTimeFilter(rawFilter) {
    if (!options.timeFilter) {
      return null;
    }
    var f = {};
    if (rawFilter.start) {
      f.$gte = moment(rawFilter.start).toDate();
      if (rawFilter.end) {
        f.$lt = moment(rawFilter.end).toDate();
      }
    } else if (rawFilter.start_time) {
      f.$gte = moment(rawFilter.start_time).toDate();
      if (rawFilter.end_time) {
        if (/[0-9]{4,4}-[0-9]{2,2}-[0-9]{2,2}/.test(rawFilter.end_time)) {
          f.$lt = moment(rawFilter.end_time).add(1, 'day').startOf('day').toDate();
        } else {
          f.$lt = moment(rawFilter.end_time).toDate();
        }
      }
    }
    if (_.isEmpty(f)) {
      return null;
    }
    var timeFilter = {};
    timeFilter[options.timeFilter] = f;
    return timeFilter;
  }

  function replaceUploaded(req, res, next) {
    if (!_.isEmpty(uploadProps)) {
      _.keys(uploadProps).forEach(k => {
        if (req.body[k]) {
          req.body[uploadProps[k]] = req.body[k];
        }
      });
    }
    next();
  }

  function pickFilters(base, raw) {
    _.keys(raw).forEach(k => {
      var secs = k.split('.'), bk = secs.shift(1);
      if (props.indexOf(bk) == -1)
        return;
      base[k] = raw[k];
    });
    return base;
  }

  function Workbook() {
    if (!(this instanceof Workbook)) return new Workbook();
    this.SheetNames = [];
    this.Sheets = {};
  }

  function datenum(v, date1904) {
    if (date1904) v += 1462;
    var epoch = Date.parse(v);
    return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
  }

  function sheet_from_array_of_arrays(data, opts) {
    var ws = {};
    var range = { s: { c: 10000000, r: 10000000 }, e: { c: 0, r: 0 } };
    for (var R = 0; R != data.length; ++R) {
      for (var C = 0; C != data[R].length; ++C) {
        if (range.s.r > R) range.s.r = R;
        if (range.s.c > C) range.s.c = C;
        if (range.e.r < R) range.e.r = R;
        if (range.e.c < C) range.e.c = C;
        var cell = { v: data[R][C] };
        if (cell.v == null) continue;
        var cell_ref = XLSX.utils.encode_cell({ c: C, r: R });

        if (typeof cell.v === 'number') cell.t = 'n';
        else if (typeof cell.v === 'boolean') cell.t = 'b';
        else if (cell.v instanceof Date) {
          cell.t = 'n'; cell.z = XLSX.SSF._table[14];
          cell.v = datenum(cell.v);
        }
        else cell.t = 's';

        ws[cell_ref] = cell;
      }
    }
    if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
    return ws;
  }

  function formatToXlsx(data, name) {
    var ws_name = "SheetJS";
    var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);

    /* add worksheet to workbook */
    wb.SheetNames.push(ws_name);
    wb.Sheets[ws_name] = ws;

    var tempFile = path.join(os.tmpdir(), (name || (new Date().toString() + '.xlsx')));
    XLSX.writeFile(wb, tempFile);
    return tempFile;
  }

  function formatToCsv(rows, head) {
    var lines = []
    if (head) {
      lines.push(head.map(e => `"${e}"`).join(','))
    }
    rows.forEach(row => {
      lines.push(row.map(e => `"${e}"`).join(','))
    })
    return lines.join('\r\n')
  }

  // protect the method if defined in protects
  router.use('/', function(req, rest, next) {
    var protects = options.protects || {};
    var protect = req.method === 'GET' ? (req.url === '/' ? protects.LIST : protects.GET) : protects[req.method];
    if (protect) {
      protect(req, next);
    } else {
      next();
    }
  });

  router.get('/', function(req, res, next) {

    // filter buildup
    var filter = _.extend({}, options.baseFilter);

    // regard _filter in query firstly
    if (req.query._filters) {
      try {
        pickFilters(filter, JSON.parse(req.query._filters));
      } catch (e) {
        debug('not valid _filter although present: %j', req.query._filter);
      }
    } else {
      pickFilters(filter, req.query);
    }
    filter = convert(filter);
    _.extend(filter, getTimeFilter(req.query));

    debug('List %s by filter %j', model.modelName, filter);

    // listOptions buildup
    var lo = {
      limit: parseInt(req.query._perPage) || 0
    };
    lo.skip = Math.max((req.query._page || 1) - 1, 0) * lo.limit;
    if (req.query._sortField && req.query._sortDir) {
      lo.sort = {};
      lo.sort[req.query._sortField.replace(/^id/, '_id')] = req.query._sortDir.toUpperCase() == 'ASC' ? 1 : -1;
    } else {
      lo.sort = options.defaultSort;
    }
    debug('get list options from request: %j', lo);

    // list model
    model.count(filter, function(err, num) {
      if (err) {
        return next(error('LIST', err));
      }
      var items = [], limit = Math.min(lo.limit, options.batchSize), skip = lo.skip;

      function findBatch(cb) {
        model.find(filter).sort(lo.sort).skip(skip).limit(limit).exec(function(errB, itemsB) {
          if (errB) return cb(errB);
          items = items.concat(itemsB)
          // if get all items, finish batch
          if (items.length >= lo.limit) {
            return cb(null, items)
          }
          // if current fetch is less than a batch, which means no more items to get, finish batch
          if (itemsB.length < limit) {
            return cb(null, items);
          }
          // else, continue
          skip = skip + itemsB.length;
          findBatch(cb)
        });
      }
      findBatch((err2, items) => {
        if (err2) {
          return next(error('LIST', err2));
        }
        if (req.query.format == 'csv') {
          res.set('Content-Type', 'text/csv');
          var rows = items.map(e => props.map(k => e[k]));
          var csvout = formatToCsv(rows, props);
          res.send(csvout);
        } else if (req.query.format == 'xlsx') {
          var rows = items.map(e => props.map(k => e[k]));
          rows.unshift(props);
          var wbout = formatToXlsx(rows, model.modelName + '_' + new Date().getTime().toString() + '.xlsx');
          res.sendfile(wbout);
        } else {
          res.set('X-Total-Count', num).json(items.map(output));
        }
      })
    });
  });

  router.post('/', replaceUploaded, function(req, res, next) {
    var data = convert(req.body);
    debug('Post to model %s by data %j', model.modelName, data);

    model.create(data, function(err, item) {
      if (err) {
        return next(error('POST', err));
      }
      res.json(output(item));
    });
  });

  router.use('/:id', function(req, res, next) {
    req.id_filter = {};
    req.id_filter[options._id || '_id'] = req.params.id;
    next();
  });

  router.get('/:id', function(req, res, next) {
    debug('Get model %s by id %s', model.modelName, req.params.id);
    model.findOne(req.id_filter).exec(function(err, item) {
      if (err) {
        return next(error('GET', err));
      }
      if (!item) {
        return next();
      }
      res.json(output(item));
    });
  });

  router.put('/:id', replaceUploaded, function(req, res, next) {
    var data = convert(req.body);
    debug('Put to model %s, id %s by data %j', model.modelName, req.params.id, data);

    model.findOne(req.id_filter).exec(function(err, item) {
      if (err) {
        return next(error('PUT', err));
      }
      if (!item) {
        return next();
      }
      _.extend(item, data);
      item.save(function(err) {
        if (err) {
          return next(error('PUT', err));
        }
        res.json(output(item));
      });
    });
  });

  router.delete('/:id', function(req, res, next) {
    debug('delete model %s by id %s', model.modelName, req.params.id);

    model.remove(req.id_filter).exec(function(err, item) {
      if (err) {
        return next(error('DELETE', err));
      }
      res.json(output(item));
    });
  });

  return router;
}

module.exports = mongooseRoute;
<|endoftext|>