<commit_before>/*!
 * dir-info
 * 2015 Codenautas
 * GNU Licensed
 */
"use strict";
/*jshint eqnull:true */
/*jshint globalstrict:true */
/*jshint node:true */

var Promises = require('best-promise');
var Path = require('path');
var fs = require('fs-promise');
var exec = require('child-process-promise').exec;
var readYaml = require('read-yaml-promise');
var winOS = Path.sep==='\\';

var dirInfo = {}; // this module

dirInfo.config = { gitDir:false };

/*
    This function will search for the directory containing the git executable
    in this order:
    - dirInfo.config.gitDir
    - config.gitDir in packaje.json
    - GITDIR environment variable
    - A set of predefinded paths
*/
dirInfo.findGitDir = function findGitDir() {
    var paths;
    var localyaml='./local-config.yaml';
    return Promises.start(function() {
        paths=[
            'c:\\Git\\bin',
            'c:\\Archivos de programa\\Git\\bin',
            'c:\\Program Files\\Git\\bin',
            'c:\\Program Files (x86)\\Git\\bin',
            '/usr/bin',
            '/usr/local/bin',
            '/bin'
        ];
        if(dirInfo.config.gitDir) {
            paths.unshift(dirInfo.config.gitDir);
        }
        return fs.exists(localyaml);
    }).then(function(existsYAML) {
        if(existsYAML) { return readYaml(localyaml); }
        return false;
    }).then(function(yconf){
        if(yconf && yconf.git_dir) {
            paths.unshift(yconf.git_dir);
        }
        if(process.env.GITDIR) {
            paths.unshift(process.env.GITDIR);
        }
        return paths.reduce(function(promiseChain, path){
            return promiseChain.catch(function(){
                return fs.stat(path).then(function(stat){
                    if(stat.isDirectory()){
                        return path;
                    }else{
                        return Promises.reject('not dir');
                    }
                });
            });
        },Promises.reject());
    });
};

dirInfo.getInfo = function getInfo(path, opts){
    opts = opts || {};
    var info={
        name:Path.basename(path), // BAD! only the last dirname
        origin:null
    };
    return Promises.start(function(){
        if(!path) { throw new Error('null path'); }
        return fs.exists(path);
    }).then(function(exists) {
        if(!exists) { throw new Error("'"+path+"' does not exists"); }
        return fs.stat(path);
    }).then(function(stat) {
        var gitDir='';
        var execOptions = {};
        if(stat.isDirectory()) {
            gitDir = path+Path.sep+".git";
            return fs.stat(gitDir).then(function(statDotGit){
                return statDotGit.isDirectory();
            }).catch(function(err){
                return false;
            }).then(function(isDirDotGit) {
                if(isDirDotGit){
                    info.isGit = true;
                }
                if(opts.cmd) {
                    return Promises.start(function(){
                        return dirInfo.findGitDir();
                    }).then(function(gitDir) {
                        execOptions.cwd = path;
                        execOptions.env = process.env;
                        execOptions.env.PATH+=Path.delimiter+gitDir;
                        return exec('git status -z', execOptions);
                    }).then(function(resStatusZ) {
                        if(!info.isGit){
                            info.isGitSubdir=true;
                        }
                        return exec('git config --get remote.origin.url', execOptions).catch(function(err){
                            if(err.code===1){
                                return {errorInExec:true};
                            }else{
                                throw err;
                            }
                        }).then(function(resConfig) {
                            if(!resConfig.errorInExec){
                                info.origin=resConfig.stdout.replace(/([\t\r\n ]*)$/g,'');
                                if(resConfig.stdout.match(/github/)) {
                                    info.isGithub = true;
                                }
                            }
                            return exec('git rev-parse --abbrev-ref HEAD', execOptions);
                        }).then(function(resBranch) {
                            info.branch = resBranch.stdout.substring(0, resBranch.stdout.length-1);
                            return exec('git rev-parse --show-toplevel', execOptions);
                        }).then(function(resTopLevel) {
                            resStatusZ.topLevel = resTopLevel.stdout;
                            return resStatusZ;
                        });
                    }).then(function(resStatusZ){
                        var topDir=resStatusZ.topLevel;
                        topDir = topDir.substring(0,topDir.length-1);
                        var reMods = /(M|A|D|\?\?) (?:\s)?([^\u0000]+)\s*/g;
                        var modifieds=[];
                        var deletes=[];
                        var addeds=[];
                        var untrackeds=[];
                        var absPath=Path.resolve(path);
                        var mod;
                        while ((mod = reMods.exec(resStatusZ.stdout)) !== null) {
                            //var msg = 'Found ' + mod[1] + ' ['+mod[2]+']'; console.log(msg);
                            var fullPath = topDir+'/'+mod[2];
                            // ATENCION: esto funciona porque nunca se incluyen los parent dirs
                            if(Path.resolve(fullPath).substring(0,absPath.length)===absPath){
                                var file = fullPath.substring(absPath.length+1);
                                if(fullPath.indexOf(Path.basename(path))==-1){
                                    continue;
                                }
                                ({
                                    M: modifieds,
                                    D: deletes,
                                    A: addeds,
                                    '??': untrackeds
                                })[mod[1]].push(file);
                            }
                        }
                        var hasChanges = modifieds.length || addeds.length || untrackeds.length || deletes.length;
                        if(hasChanges) {
                            if(modifieds.length) { info.modifieds = modifieds; }
                            if(deletes.length) {
                                info.deletes = deletes;
                            }
                            if(addeds.length) { info.addeds = addeds; }
                            if(untrackeds.length) {
                                info.untrackeds = untrackeds;
                            }
                        }
                        if(opts.net && info.isGithub) {
                            return exec('git remote show origin', execOptions).catch(function(err) {
                                return {errorInExec:true};
                            }).then(function(resRemote) {
                                if(!resRemote.errorInExec) {
                                    if(resRemote.stdout.match(/local out of date/)) {
                                        info.syncPending = true;
                                    }
                                }
                                return exec('git log --branches --not --remotes', execOptions);
                            }).then(function(resLOG) {
                                var rst=resLOG.stdout.substring(0, resLOG.stdout.length-1);
                                if(rst !== "") { info.pushPending = true; }
                                return info;
                            });
                        }
                    }).catch(function(err){
                        //console.log("Error en path ", path, ":", err);
                        if(err.code!=128){
                            throw err;
                        }
                    }).then(function(){
                        return info;
                    });
                }
                return info;
            });
        } else { // it's a file
            info.name = Path.basename(Path.dirname(path))+'/'+Path.basename(path);
            if(path.match(/(package.json)$/i)) {
                info.isPackageJson = true;
            }
            if(path.match(/(\.json)$/i)) {
                info.isJson = true;
            }
            if(info.isJson && opts.cmd) {
                return fs.readJson(path).catch(function(err) {
                    info.hasError = true;
                    return {errorInRJS:true};
                }).then(function(json) {
                    if(!json.errorInRJS && opts.cmd) {
                        if(opts.net) {
                            var ncu = __dirname+'/node_modules/npm-check-updates/bin/npm-check-updates';
                            var cat = winOS ? 'type' : 'cat';
                            return fs.exists(ncu).then(function(haveNCU) {
                                if(!haveNCU) {
                                    throw new Error("Cannot find npm-check-updates");
                                }
                                var input=Path.normalize(path);
                                var cmd = cat + ' "'+input+'" | node '+ncu;
                                return exec(cmd).catch(function(err) {
                                }).then(function(npm) {
                                    //console.log("npm", npm.stdout);
                                    //console.log(input, " outdated:", npm.stdout.match(/(can be updated)|(version is behind)/));
                                    if(npm.stdout.match(/(can be updated)|(version is behind)/)) {
                                        info.isOutdated = true;
                                    }
                                   return info;
                                });
                            });
                        }
                    }
                    return info;
                });
            }
            return info;
        }
    }).then(function(infoForClean){
        return infoForClean;
    });
};

exports = module.exports = dirInfo;
<commit_msg>Resuelvo ubicación de npm-check-updates usándolo desde el código. Close #17<commit_after>/*!
 * dir-info
 * 2015 Codenautas
 * GNU Licensed
 */
"use strict";
/*jshint eqnull:true */
/*jshint globalstrict:true */
/*jshint node:true */

var Promises = require('best-promise');
var Path = require('path');
var fs = require('fs-promise');
var exec = require('child-process-promise').exec;
var readYaml = require('read-yaml-promise');
var winOS = Path.sep==='\\';
var ncu = require('npm-check-updates');

var dirInfo = {}; // this module

dirInfo.config = { gitDir:false };

/*
    This function will search for the directory containing the git executable
    in this order:
    - dirInfo.config.gitDir
    - config.gitDir in packaje.json
    - GITDIR environment variable
    - A set of predefinded paths
*/
dirInfo.findGitDir = function findGitDir() {
    var paths;
    var localyaml='./local-config.yaml';
    return Promises.start(function() {
        paths=[
            'c:\\Git\\bin',
            'c:\\Archivos de programa\\Git\\bin',
            'c:\\Program Files\\Git\\bin',
            'c:\\Program Files (x86)\\Git\\bin',
            '/usr/bin',
            '/usr/local/bin',
            '/bin'
        ];
        if(dirInfo.config.gitDir) {
            paths.unshift(dirInfo.config.gitDir);
        }
        return fs.exists(localyaml);
    }).then(function(existsYAML) {
        if(existsYAML) { return readYaml(localyaml); }
        return false;
    }).then(function(yconf){
        if(yconf && yconf.git_dir) {
            paths.unshift(yconf.git_dir);
        }
        if(process.env.GITDIR) {
            paths.unshift(process.env.GITDIR);
        }
        return paths.reduce(function(promiseChain, path){
            return promiseChain.catch(function(){
                return fs.stat(path).then(function(stat){
                    if(stat.isDirectory()){
                        return path;
                    }else{
                        return Promises.reject('not dir');
                    }
                });
            });
        },Promises.reject());
    });
};

dirInfo.getInfo = function getInfo(path, opts){
    opts = opts || {};
    var info={
        name:Path.basename(path), // BAD! only the last dirname
        origin:null
    };
    return Promises.start(function(){
        if(!path) { throw new Error('null path'); }
        return fs.exists(path);
    }).then(function(exists) {
        if(!exists) { throw new Error("'"+path+"' does not exists"); }
        return fs.stat(path);
    }).then(function(stat) {
        var gitDir='';
        var execOptions = {};
        if(stat.isDirectory()) {
            gitDir = path+Path.sep+".git";
            return fs.stat(gitDir).then(function(statDotGit){
                return statDotGit.isDirectory();
            }).catch(function(err){
                return false;
            }).then(function(isDirDotGit) {
                if(isDirDotGit){
                    info.isGit = true;
                }
                if(opts.cmd) {
                    return Promises.start(function(){
                        return dirInfo.findGitDir();
                    }).then(function(gitDir) {
                        execOptions.cwd = path;
                        execOptions.env = process.env;
                        execOptions.env.PATH+=Path.delimiter+gitDir;
                        return exec('git status -z', execOptions);
                    }).then(function(resStatusZ) {
                        if(!info.isGit){
                            info.isGitSubdir=true;
                        }
                        return exec('git config --get remote.origin.url', execOptions).catch(function(err){
                            if(err.code===1){
                                return {errorInExec:true};
                            }else{
                                throw err;
                            }
                        }).then(function(resConfig) {
                            if(!resConfig.errorInExec){
                                info.origin=resConfig.stdout.replace(/([\t\r\n ]*)$/g,'');
                                if(resConfig.stdout.match(/github/)) {
                                    info.isGithub = true;
                                }
                            }
                            return exec('git rev-parse --abbrev-ref HEAD', execOptions);
                        }).then(function(resBranch) {
                            info.branch = resBranch.stdout.substring(0, resBranch.stdout.length-1);
                            return exec('git rev-parse --show-toplevel', execOptions);
                        }).then(function(resTopLevel) {
                            resStatusZ.topLevel = resTopLevel.stdout;
                            return resStatusZ;
                        });
                    }).then(function(resStatusZ){
                        var topDir=resStatusZ.topLevel;
                        topDir = topDir.substring(0,topDir.length-1);
                        var reMods = /(M|A|D|\?\?) (?:\s)?([^\u0000]+)\s*/g;
                        var modifieds=[];
                        var deletes=[];
                        var addeds=[];
                        var untrackeds=[];
                        var absPath=Path.resolve(path);
                        var mod;
                        while ((mod = reMods.exec(resStatusZ.stdout)) !== null) {
                            //var msg = 'Found ' + mod[1] + ' ['+mod[2]+']'; console.log(msg);
                            var fullPath = topDir+'/'+mod[2];
                            // ATENCION: esto funciona porque nunca se incluyen los parent dirs
                            if(Path.resolve(fullPath).substring(0,absPath.length)===absPath){
                                var file = fullPath.substring(absPath.length+1);
                                if(fullPath.indexOf(Path.basename(path))==-1){
                                    continue;
                                }
                                ({
                                    M: modifieds,
                                    D: deletes,
                                    A: addeds,
                                    '??': untrackeds
                                })[mod[1]].push(file);
                            }
                        }
                        var hasChanges = modifieds.length || addeds.length || untrackeds.length || deletes.length;
                        if(hasChanges) {
                            if(modifieds.length) { info.modifieds = modifieds; }
                            if(deletes.length) {
                                info.deletes = deletes;
                            }
                            if(addeds.length) { info.addeds = addeds; }
                            if(untrackeds.length) {
                                info.untrackeds = untrackeds;
                            }
                        }
                        if(opts.net && info.isGithub) {
                            return exec('git remote show origin', execOptions).catch(function(err) {
                                return {errorInExec:true};
                            }).then(function(resRemote) {
                                if(!resRemote.errorInExec) {
                                    if(resRemote.stdout.match(/local out of date/)) {
                                        info.syncPending = true;
                                    }
                                }
                                return exec('git log --branches --not --remotes', execOptions);
                            }).then(function(resLOG) {
                                var rst=resLOG.stdout.substring(0, resLOG.stdout.length-1);
                                if(rst !== "") { info.pushPending = true; }
                                return info;
                            });
                        }
                    }).catch(function(err){
                        //console.log("Error en path ", path, ":", err);
                        if(err.code!=128){
                            throw err;
                        }
                    }).then(function(){
                        return info;
                    });
                }
                return info;
            });
        } else { // it's a file
            info.name = Path.basename(Path.dirname(path))+'/'+Path.basename(path);
            if(path.match(/(package.json)$/i)) {
                info.isPackageJson = true;
            }
            if(path.match(/(\.json)$/i)) {
                info.isJson = true;
            }
            if(info.isJson && opts.cmd) {
                return fs.readJson(path).catch(function(err) {
                    info.hasError = true;
                    return {errorInRJS:true};
                }).then(function(json) {
                    if(!json.errorInRJS && opts.cmd) {
                        if(opts.net) {
                            return ncu.run({packageFile: Path.normalize(path)}).then(function(npmres) {
                                function hasUpdates(o) {
                                    for(var prop in o) { if (o.hasOwnProperty(prop)) { return true; } }
                                    return false;
                                }
                                if(hasUpdates(npmres)) {
                                    info.isOutdated = true;
                                }
                                return info;
                            });
                        }
                    }
                    return info;
                });
            }
            return info;
        }
    }).then(function(infoForClean){
        return infoForClean;
    });
};

exports = module.exports = dirInfo;
<|endoftext|>


<commit_before>var path          = require('path');
var AvisynthError = require('./errors').AvisynthError;
var pluginSystem  = require('./plugin-system');
var addPlugin     = pluginSystem.addPlugin;

// This file contains an implementation of each of the various core filters
// bundled with AviSynth, to ease their usage in script objects.
// Also, screw code re-use, accounting for the minimal difference between each
// core filter and coming up with an elegant solution would take too much time.

// Shared implementation of a few filters to improve code re-use.
function sharedAviSource(name, disableOptions) {

    // Pixel types supported by this filter.
    var pixelTypes = ['YV24', 'YV16', 'YV12', 'YV411', 'YUY2', 'RGB32', 'RGB24', 'Y8', 'AUTO', 'FULL'];

    return function(filename, audio, pixelType, fourCC) {
        if (typeof filename !== 'string') throw new AvisynthError('filename must be a string!');
        var filenames = [];
        var audioArg, pixelTypeArg, fourCCArg;
        for (var i = 0; i < arguments.length; i++) {
            if (typeof arguments[i] === 'string') {
                filenames.push(path.resolve(arguments[i]));
            } else {
                audioArg     = arguments[i];
                pixelTypeArg = arguments[i + 1];
                fourCCArg    = arguments[i + 2];
                break;
            }
        }
        if (pixelTypeArg && pixelTypes.indexOf(pixelTypeArg) === -1) throw new AvisynthError('bad pixel type (' + pixelTypeArg + ')!');
        var clips = filenames.join('", "');
        if (!disableOptions) {
            if (typeof fourCCArg !== 'undefined') return name + '("' + clips + '", ' + !!audioArg + ', "' + pixelTypeArg + '", "' + fourCCArg + '")';
            if (typeof pixelTypeArg !== 'undefined') return name + '("' + clips + '", ' + !!audioArg + ', "' + pixelTypeArg + '")';
            if (typeof audioArg !== 'undefined') return name + '("' + clips + '", ' + !!audioArg + ')';
        }
        return name + '("' + clips + '")';
    }
}

// DirectShowSource is significantly different from AviSource-like source filters (and more versatile).
function directShowSource(filename, fps, seek, audio, video, convertfps, seekzero, timeout, pixelType, framecount, logfile, logmask) {
    // Perform a couple of sanity checks.
    if (typeof filename !== 'string' || !filename) throw new AvisynthError('filename is a required argument!');
    if (typeof fps === 'string') throw new AvisynthError('only one filename is supported (unlike some other source filters)!');

    // Notice how the pixel types supported differ from the AviSource family.
    var pixelTypes = ['YV24', 'YV16', 'YV12', 'YUY2', 'AYUV', 'Y41P', 'Y411', 'ARGB', 'RGB32', 'RGB24', 'YUV', 'YUVex', 'RGB', 'AUTO', 'FULL'];
    if (pixelType && pixelTypes.indexOf(pixelType) === -1) throw new AvisynthError('bad pixel type (' + pixelType + ')!');

    // Start building the parameter list.
    var params = ['"' + path.resolve(filename) + '"'];
    if (typeof fps        !== 'undefined') params.push('fps='        + fps);
    if (typeof seek       !== 'undefined') params.push('seek='       + seek);
    if (typeof audio      !== 'undefined') params.push('audio='      + audio);
    if (typeof video      !== 'undefined') params.push('video='      + video);
    if (typeof convertfps !== 'undefined') params.push('convertfps=' + convertfps);
    if (typeof seekzero   !== 'undefined') params.push('seekzero='   + seekzero);
    if (typeof timeout    !== 'undefined') params.push('timeout='    + timeout);
    if (typeof pixelType  !== 'undefined') params.push('pixel_type=' + '"' + pixelType + '"');
    if (typeof framecount !== 'undefined') params.push('framecount=' + framecount);
    if (typeof logfile    !== 'undefined') params.push('logfile='    + '"' + path.resolve(logfile) + '"');
    if (typeof logmask    !== 'undefined') params.push('logmask='    + logmask);
    return 'DirectShowSource(' + params.join(', ') + ')';
}

function sharedImageSource(name) {
    return function(file, start, end, fps, useDevIL, info, pixelType) {
        // Perform a couple of sanity checks.
        if (typeof file !== 'string' || !file) throw new AvisynthError('filename is a required argument!');
        if (typeof start === 'string') throw new AvisynthError('only one filename is supported (unlike some other source filters)!');

        // Different pixel type support too.
        var pixelTypes = ['Y8', 'RGB24', 'RGB32'];
        if (pixelType && pixelTypes.indexOf(pixelType) === -1) throw new AvisynthError('bad pixel type (' + pixelType + ')!');

        // Start building the parameter list.
        var params = ['"' + path.resolve(file) + '"'];
        if (typeof start     !== 'undefined') params.push('start='      + start);
        if (typeof end       !== 'undefined') params.push('end='        + end);
        if (typeof fps       !== 'undefined') params.push('fps='        + fps);
        if (typeof useDevIL  !== 'undefined') params.push('use_DevIL='  + useDevIL);
        if (typeof info      !== 'undefined') params.push('info='       + info);
        if (typeof pixelType !== 'undefined') params.push('pixel_type=' + '"' + pixelType + '"');
        return name + '(' + params.join(', ') + ')';
    }
}

function imageSourceAnim(file, fps, info, pixelType) {
    // Perform a couple of sanity checks.
    if (typeof file !== 'string' || !file) throw new AvisynthError('filename is a required argument!');
    if (typeof fps === 'string') throw new AvisynthError('only one filename is supported (unlike some other source filters)!');

    var pixelTypes = ['Y8', 'RGB24', 'RGB32'];
    if (pixelType && pixelTypes.indexOf(pixelType) === -1) throw new AvisynthError('bad pixel type (' + pixelType + ')!');

    // Start building the parameter list.
    var params = ['"' + path.resolve(file) + '"'];
    if (typeof fps       !== 'undefined') params.push('fps='        + fps);
    if (typeof info      !== 'undefined') params.push('info='       + info);
    if (typeof pixelType !== 'undefined') params.push('pixel_type=' + '"' + pixelType + '"');
    return 'ImageSourceAnim(' + params.join(', ') + ')';
}

function imageWriter(file, start, end, type, info) {
    if (typeof file !== 'string' || !file) throw new AvisynthError('filename is a required argument!');

    // Start building the parameter list.
    var params = ['"' + path.resolve(file) + '"'];
    if (typeof start     !== 'undefined') params.push('start=' + start);
    if (typeof end       !== 'undefined') params.push('end='   + end);
    if (typeof type      !== 'undefined') params.push('type='  + '"' + type + '"');
    if (typeof info      !== 'undefined') params.push('info='  + info);
    return 'ImageWriter(' + params.join(', ') + ')';
}

addPlugin('AviSource', sharedAviSource('AviSource'));
addPlugin('OpenDMLSource', sharedAviSource('OpenDMLSource'));
addPlugin('AviFileSource', sharedAviSource('AviFileSource'));
addPlugin('WavSource', sharedAviSource('WavSource', true));
addPlugin('DirectShowSource', directShowSource);
addPlugin('ImageSource', sharedImageSource('ImageSource'));
addPlugin('ImageReader', sharedImageSource('ImageReader'));
addPlugin('ImageSourceAnim', imageSourceAnim);
addPlugin('ImageWriter', imageWriter);
<commit_msg>Massive overhaul to how core filter plugins are being defined.<commit_after>var path          = require('path');
var AvisynthError = require('./errors').AvisynthError;
var pluginSystem  = require('./plugin-system');
var addPlugin     = pluginSystem.addPlugin;

// This file contains an implementation of each of the various core filters
// bundled with AviSynth, to ease their usage in script objects.

// We'll first define some methods to improve code re-use.

function isDefined(value) {
    return typeof value !== 'undefined' && value !== null;
}

function checkType(value, allowed) {
    if (value && allowed.indexOf(value) === -1) {
        throw new AvisynthError('bad type (' + value + ')! allowed values: ' + allowed);
    }
}

// This attempts to be a shared implementation that covers most use-cases.
// It returns the function for a core filter, built from a description of "how it works".
// A quick note on modifiers:
// q: quoted.
// p: file path (resolved to absolute), implies q.
// f: forced file path, implies p.
// n: not a path (actually, not a string). Throws if a string is given.
// t: a type, this is checked against options.types. Implies q.
function coreFilter(name, options, types) {

    // Lazyness taken to new heights. First parameter can succintly describe some filters.
    // If combined with defining the second parameter, that will represent the types.
    // TODO: fix this and figure out why the hell it's not working. Tomorrow.
    if (name.indexOf('(') !== -1) {
        var matches = name.match(/([^() ]*)\s*(\((.*)\))?/);
        name = matches[1];
        if (matches[3]) {
            if (options) types = options;
            options = matches[3];
        }
    }

    // Conveniently cast options/types from string to array, for the condition below.
    if (typeof options === 'string') options = options.split(/\s*,\s*/);
    if (typeof types   === 'string') types   =   types.split(/\s*,\s*/);

    // If options is an array instead of object, it is treated as options.params.
    // Optionally, options.types can be inlined too, by passing a second array.
    if (options && isDefined(options.length)) {
        return coreFilter(name, {params: options, types: types});
    }

    return function() {
        // Construct parameter definitons.
        var definitions = [];
        if (options.params) options.params.forEach(function(param) {
            // Each item in options.params should follow modifier:identifier format.
            var matches = param.match(/^((.*):)?(.*)$/);
            definitions.push({modifier: matches[2], identifier: matches[3]});
        });

        // Construct parameter list.
        var params = [];
        // There are two iterators; "a" is for actual argument, "d" is for definiton.
        // These may progress independently if a definiton accepts multiple arguments.
        for (var a = 0, d = 0; a < arguments.length; a++, d++) {
            var definition = definitions[d];
            if (!definition) throw new AvisynthError('Too many arguments for ' + name);
            var value = arguments[a];
            if (!isDefined(value)) continue;
            var m = definition.modifier;
            if (m && /[t]/.test(m)) checkType(value, options.types);
            if (m && /[fp]/.test(m)) value = path.resolve(value);
            if (m && /[fpqt]/.test(m)) value = '"' + value + '"';
            if (m && /[n]/.test(m) && typeof value === 'string') throw new AvisynthError('Only one path supported!');
            params.push((definition.identifier ? definition.identifier + '=' : '') + value);
        }

        // All filename arguments are required; ensure that.
        for (var i = 0; i < definitions.length; i++) {
            var def = definitions[i];
            if (def.modifier && /[f]/.test(def.modifier) && !arguments[i]) {
                throw new AvisynthError('filename is a required argument!')
            }
        }

        return name + '(' + params.join(', ') + ')';
    };
}

// Utility that eases the inline creation and addition of a core filter.
function newPlugin(name, options, types) {
    addPlugin(name, coreFilter(name, options, types));
}

// Shared implementation of a few filters to improve code re-use.
function sharedAviSource(name, disableOptions) {

    var pixelTypes = ['YV24', 'YV16', 'YV12', 'YV411', 'YUY2', 'RGB32', 'RGB24', 'Y8', 'AUTO', 'FULL'];

    return function(filename, audio, pixelType, fourCC) {
        if (typeof filename !== 'string') throw new AvisynthError('filename must be a string!');
        var filenames = [];
        var audioArg, pixelTypeArg, fourCCArg;
        for (var i = 0; i < arguments.length; i++) {
            if (typeof arguments[i] === 'string') {
                filenames.push(path.resolve(arguments[i]));
            } else {
                audioArg     = arguments[i];
                pixelTypeArg = arguments[i + 1];
                fourCCArg    = arguments[i + 2];
                break;
            }
        }

        checkType(pixelTypeArg, pixelTypes);

        var clips = filenames.join('", "');
        if (!disableOptions) {
            if (typeof fourCCArg !== 'undefined') return name + '("' + clips + '", ' + !!audioArg + ', "' + pixelTypeArg + '", "' + fourCCArg + '")';
            if (typeof pixelTypeArg !== 'undefined') return name + '("' + clips + '", ' + !!audioArg + ', "' + pixelTypeArg + '")';
            if (typeof audioArg !== 'undefined') return name + '("' + clips + '", ' + !!audioArg + ')';
        }
        return name + '("' + clips + '")';
    }
}

var imageSourceDefinition = {
    params: ['f:', 'n:start', 'end', 'fps', 'use_DevIL', 'info', 't:pixel_type'],
    types: ['Y8', 'RGB24', 'RGB32']
};

var directShowSourceDefinition = {
    params: ['f:', 'n:fps', 'seek', 'audio', 'video', 'convertfps', 'seekzero', 'timeout', 't:pixel_type', 'framecount', 'p:logfile', 'logmask'],
    types: ['YV24', 'YV16', 'YV12', 'YUY2', 'AYUV', 'Y41P', 'Y411', 'ARGB', 'RGB32', 'RGB24', 'YUV', 'YUVex', 'RGB', 'AUTO', 'FULL']
};

addPlugin('AviSource', sharedAviSource('AviSource'));
addPlugin('OpenDMLSource', sharedAviSource('OpenDMLSource'));
addPlugin('AviFileSource', sharedAviSource('AviFileSource'));
addPlugin('WavSource', sharedAviSource('WavSource', true));
newPlugin('DirectShowSource', directShowSourceDefinition);
newPlugin('ImageSource', imageSourceDefinition);
newPlugin('ImageReader', imageSourceDefinition);
newPlugin('ImageSourceAnim', ['f:', 'n:fps', 'info', 't:pixel_type'], ['Y8', 'RGB24', 'RGB32']);
newPlugin('ImageWriter', 'f:, start, end, q:type, info');
<|endoftext|>


<commit_before>function main() {
  // Since we don't have the fallback of attachEvent and
  // other IE only stuff we won't try to run JS for IE.
  // It will run though when using Google Chrome Frame
  if (document.all) { return; }

  var currentSlideNo;
  var notesOn = false;
  var slides = document.getElementsByClassName('slide');
  var touchStartX = 0;
  var spaces = /\s+/, a1 = [""];

  var str2array = function(s) {
    if (typeof s == "string" || s instanceof String) {
      if (s.indexOf(" ") < 0) {
        a1[0] = s;
        return a1;
      } else {
        return s.split(spaces);
      }
    }
    return s;
  };

  var trim = function(str) {
    return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
  };

  var addClass = function(node, classStr) {
    classStr = str2array(classStr);
    var cls = " " + node.className + " ";
    for (var i = 0, len = classStr.length, c; i < len; ++i) {
      c = classStr[i];
      if (c && cls.indexOf(" " + c + " ") < 0) {
        cls += c + " ";
      }
    }
    node.className = trim(cls);
  };

  var removeClass = function(node, classStr) {
    var cls;
    if (classStr !== undefined) {
      classStr = str2array(classStr);
      cls = " " + node.className + " ";
      for (var i = 0, len = classStr.length; i < len; ++i) {
        cls = cls.replace(" " + classStr[i] + " ", " ");
      }
      cls = trim(cls);
    } else {
      cls = "";
    }
    if (node.className != cls) {
      node.className = cls;
    }
  };

  var getSlideEl = function(slideNo) {
    if (slideNo > 0) {
      return slides[slideNo - 1];
    } else {
      return null;
    }
  };

  var getSlideTitle = function(slideNo) {
    var el = getSlideEl(slideNo);
    if (el) {
      var headers = el.getElementsByTagName('header');
      if (headers.length > 0) {
        return el.getElementsByTagName('header')[0].innerText;
      }
    }
    return null;
  };

  var changeSlideElClass = function(slideNo, className) {
    var el = getSlideEl(slideNo);
    if (el) {
      removeClass(el, 'far-past past current future far-future');
      addClass(el, className);
    }
  };

  var updateSlideClasses = function() {
    window.location.hash = "slide" + currentSlideNo;

    for (var i=1; i<currentSlideNo-1; i++) {
      changeSlideElClass(i, 'far-past');
    }

    changeSlideElClass(currentSlideNo - 1, 'past');
    changeSlideElClass(currentSlideNo, 'current');
    changeSlideElClass(currentSlideNo + 1, 'future');

    for (var i=currentSlideNo+2; i<slides.length+1; i++) {
      changeSlideElClass(i, 'far-future');
    }

    highlightCurrentTocLink();

    document.getElementsByTagName('title')[0].innerText = getSlideTitle(currentSlideNo);
  };

  var highlightCurrentTocLink = function() {
    var tocRows = document.getElementById('toc').getElementsByTagName('tr');
    for (var i=0; i<tocRows.length; i++) {
      removeClass(tocRows.item(i), 'active');
    }

    var currentTocRow = document.getElementById('toc-row-' + currentSlideNo);
    if (currentTocRow) {
      addClass(currentTocRow, 'active');
    }
  }

  var nextSlide = function() {
    if (currentSlideNo < slides.length) {
      currentSlideNo++;
    }
    updateSlideClasses();
  };

  var prevSlide = function() {
    if (currentSlideNo > 1) {
      currentSlideNo--;
    }
    updateSlideClasses();
  };

  var showNotes = function() {
    var notes = getSlideEl(currentSlideNo).getElementsByClassName('notes');
    for (var i = 0, len = notes.length; i < len; i++) {
      notes.item(i).style.display = (notesOn) ? 'none':'block';
    }
    notesOn = (notesOn) ? false : true;
  };

  var showSlideNumbers = function() {
    // We only use aside elements for slide numbers, so this is safe
    var asides = document.getElementsByTagName('aside');
    var hidden = asides[0].style.display != 'block';
    for (var i = 0; i < asides.length; i++) {
      asides.item(i).style.display = hidden ? 'block' : 'none';
    }
  };

  var showToc = function() {
    var toc = document.getElementById('toc');
    var hidden = toc.className != 'visible';
    toc.className = hidden ? 'visible' : 'hidden';
    return false;
  };

  var switch3D = function() {
    if (document.body.className.indexOf('three-d') == -1) {
      document.getElementsByClassName('presentation')[0].style.webkitPerspective = '1000px';
      document.body.className += ' three-d';
    } else {
      window.setTimeout("document.getElementsByClassName('presentation')[0].style.webkitPerspective = '0';", 2000);
      document.body.className = document.body.className.replace(/three-d/, '');
    }
  };

  var handleBodyKeyDown = function(event) {
    switch (event.keyCode) {
      case 37: // left arrow
        prevSlide();
        break;
      case 39: // right arrow
      case 32: // space
        nextSlide();
        break;
      case 50: // 2
        showNotes();
        break;
      case 51: // 3
        switch3D();
        break;
      case 78: // n
        showSlideNumbers();
        break;
      case 84: // t
        showToc();
        break;
    }
  };

  var handleWheel = function(event) {
    var delta = 0;
    if (!event) event = window.event;

    if (event.wheelDelta) {
      delta = event.wheelDelta/120;
      if (window.opera) delta = -delta;
    } else if (event.detail) {
      delta = -event.detail/3;
    }

    if (delta && delta <0)
      nextSlide();
    else if (delta)
      prevSlide();
  };

  var addTouchListeners = function() {
    document.addEventListener('touchstart', function(e) {
      touchStartX = e.touches[0].pageX;
    }, false);
    document.addEventListener('touchend', function(e) {
      var pixelsMoved = touchStartX - e.changedTouches[0].pageX;
      var SWIPE_SIZE = 150;
      if (pixelsMoved > SWIPE_SIZE) {
        nextSlide();
      }
      else if (pixelsMoved < -SWIPE_SIZE) {
       prevSlide();
      }
    }, false);
  };

  var addTocLinksListeners = function() {
    var tocLinks = document.getElementById('toc').getElementsByTagName('a');
    for (var i=0; i < tocLinks.length; i++) {
      tocLinks.item(i).addEventListener('click', function(e) {
        currentSlideNo = Number(this.attributes['href'].value.replace('#slide', ''));
        updateSlideClasses();
        return false;
      }, true);
    }
  };

  // initialize

  (function() {
    if (window.location.hash != "") {
      currentSlideNo = Number(window.location.hash.replace('#slide', ''));
    } else {
      currentSlideNo = 1;
    }

    document.addEventListener('keydown', handleBodyKeyDown, false);
    document.addEventListener('DOMMouseScroll', handleWheel, false);
    window.onmousewheel = document.onmousewheel = handleWhe

    var els = slides;
    for (var i = 0, el; el = els[i]; i++) {
      addClass(el, 'slide far-future');
    }
    updateSlideClasses();

    // add support for finger events (filter it by property detection?)
    addTouchListeners();

    addTocLinksListeners();
  })();
};
<commit_msg>added mousewheel navigation support (patch from agonzalezro)<commit_after>function main() {
  // Since we don't have the fallback of attachEvent and
  // other IE only stuff we won't try to run JS for IE.
  // It will run though when using Google Chrome Frame
  if (document.all) { return; }

  var currentSlideNo;
  var notesOn = false;
  var slides = document.getElementsByClassName('slide');
  var touchStartX = 0;
  var spaces = /\s+/, a1 = [""];

  var str2array = function(s) {
    if (typeof s == "string" || s instanceof String) {
      if (s.indexOf(" ") < 0) {
        a1[0] = s;
        return a1;
      } else {
        return s.split(spaces);
      }
    }
    return s;
  };

  var trim = function(str) {
    return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
  };

  var addClass = function(node, classStr) {
    classStr = str2array(classStr);
    var cls = " " + node.className + " ";
    for (var i = 0, len = classStr.length, c; i < len; ++i) {
      c = classStr[i];
      if (c && cls.indexOf(" " + c + " ") < 0) {
        cls += c + " ";
      }
    }
    node.className = trim(cls);
  };

  var removeClass = function(node, classStr) {
    var cls;
    if (classStr !== undefined) {
      classStr = str2array(classStr);
      cls = " " + node.className + " ";
      for (var i = 0, len = classStr.length; i < len; ++i) {
        cls = cls.replace(" " + classStr[i] + " ", " ");
      }
      cls = trim(cls);
    } else {
      cls = "";
    }
    if (node.className != cls) {
      node.className = cls;
    }
  };

  var getSlideEl = function(slideNo) {
    if (slideNo > 0) {
      return slides[slideNo - 1];
    } else {
      return null;
    }
  };

  var getSlideTitle = function(slideNo) {
    var el = getSlideEl(slideNo);
    if (el) {
      var headers = el.getElementsByTagName('header');
      if (headers.length > 0) {
        return el.getElementsByTagName('header')[0].innerText;
      }
    }
    return null;
  };

  var changeSlideElClass = function(slideNo, className) {
    var el = getSlideEl(slideNo);
    if (el) {
      removeClass(el, 'far-past past current future far-future');
      addClass(el, className);
    }
  };

  var updateSlideClasses = function() {
    window.location.hash = "slide" + currentSlideNo;

    for (var i=1; i<currentSlideNo-1; i++) {
      changeSlideElClass(i, 'far-past');
    }

    changeSlideElClass(currentSlideNo - 1, 'past');
    changeSlideElClass(currentSlideNo, 'current');
    changeSlideElClass(currentSlideNo + 1, 'future');

    for (var i=currentSlideNo+2; i<slides.length+1; i++) {
      changeSlideElClass(i, 'far-future');
    }

    highlightCurrentTocLink();

    document.getElementsByTagName('title')[0].innerText = getSlideTitle(currentSlideNo);
  };

  var highlightCurrentTocLink = function() {
    var tocRows = document.getElementById('toc').getElementsByTagName('tr');
    for (var i=0; i<tocRows.length; i++) {
      removeClass(tocRows.item(i), 'active');
    }

    var currentTocRow = document.getElementById('toc-row-' + currentSlideNo);
    if (currentTocRow) {
      addClass(currentTocRow, 'active');
    }
  }

  var nextSlide = function() {
    if (currentSlideNo < slides.length) {
      currentSlideNo++;
    }
    updateSlideClasses();
  };

  var prevSlide = function() {
    if (currentSlideNo > 1) {
      currentSlideNo--;
    }
    updateSlideClasses();
  };

  var showNotes = function() {
    var notes = getSlideEl(currentSlideNo).getElementsByClassName('notes');
    for (var i = 0, len = notes.length; i < len; i++) {
      notes.item(i).style.display = (notesOn) ? 'none':'block';
    }
    notesOn = (notesOn) ? false : true;
  };

  var showSlideNumbers = function() {
    // We only use aside elements for slide numbers, so this is safe
    var asides = document.getElementsByTagName('aside');
    var hidden = asides[0].style.display != 'block';
    for (var i = 0; i < asides.length; i++) {
      asides.item(i).style.display = hidden ? 'block' : 'none';
    }
  };

  var showToc = function() {
    var toc = document.getElementById('toc');
    var hidden = toc.className != 'visible';
    toc.className = hidden ? 'visible' : 'hidden';
    return false;
  };

  var switch3D = function() {
    if (document.body.className.indexOf('three-d') == -1) {
      document.getElementsByClassName('presentation')[0].style.webkitPerspective = '1000px';
      document.body.className += ' three-d';
    } else {
      window.setTimeout("document.getElementsByClassName('presentation')[0].style.webkitPerspective = '0';", 2000);
      document.body.className = document.body.className.replace(/three-d/, '');
    }
  };

  var handleBodyKeyDown = function(event) {
    switch (event.keyCode) {
      case 37: // left arrow
        prevSlide();
        break;
      case 39: // right arrow
      case 32: // space
        nextSlide();
        break;
      case 50: // 2
        showNotes();
        break;
      case 51: // 3
        switch3D();
        break;
      case 78: // n
        showSlideNumbers();
        break;
      case 84: // t
        showToc();
        break;
    }
  };

  var handleWheel = function(event) {
    var delta = 0;
    if (!event) event = window.event;

    if (event.wheelDelta) {
      delta = event.wheelDelta/120;
      if (window.opera) delta = -delta;
    } else if (event.detail) {
      delta = -event.detail/3;
    }

    if (delta && delta <0)
      nextSlide();
    else if (delta)
      prevSlide();
  };

  var addTouchListeners = function() {
    document.addEventListener('touchstart', function(e) {
      touchStartX = e.touches[0].pageX;
    }, false);
    document.addEventListener('touchend', function(e) {
      var pixelsMoved = touchStartX - e.changedTouches[0].pageX;
      var SWIPE_SIZE = 150;
      if (pixelsMoved > SWIPE_SIZE) {
        nextSlide();
      }
      else if (pixelsMoved < -SWIPE_SIZE) {
       prevSlide();
      }
    }, false);
  };

  var addTocLinksListeners = function() {
    var tocLinks = document.getElementById('toc').getElementsByTagName('a');
    for (var i=0; i < tocLinks.length; i++) {
      tocLinks.item(i).addEventListener('click', function(e) {
        currentSlideNo = Number(this.attributes['href'].value.replace('#slide', ''));
        updateSlideClasses();
        return false;
      }, true);
    }
  };

  // initialize

  (function() {
    if (window.location.hash != "") {
      currentSlideNo = Number(window.location.hash.replace('#slide', ''));
    } else {
      currentSlideNo = 1;
    }

    document.addEventListener('keydown', handleBodyKeyDown, false);
    document.addEventListener('DOMMouseScroll', handleWheel, false);
    window.onmousewheel = document.onmousewheel = handleWheel

    var els = slides;
    for (var i = 0, el; el = els[i]; i++) {
      addClass(el, 'slide far-future');
    }
    updateSlideClasses();

    // add support for finger events (filter it by property detection?)
    addTouchListeners();

    addTocLinksListeners();
  })();
};
<|endoftext|>


<commit_before>
var os = require('os');
var io = require('socket.io-client');
var FileNotify = require('filenotify');

module.exports = function() {
  var Collector = function Collector(files, url, key, callback) {
    var that = this;
    var watchers = {};

    this.key = key;
    this.files = files;

    var conn = this.conn = io.connect(url);

    // On connect register with server
    conn.on('connect', function() {
      that.register(callback);
    });

    // Start monitoring of a file/stream
    conn.on('start', function(data, callback) {
      if(!watchers[data.file]) {
        watchers[data.file] = new FileNotify(files[data.file]);
        watchers[data.file].on('data', function(lines) {
          that.conn.emit('lines', {
            'data': new Date().toUTCString(),
            'watchable': data.file,
            'lines': lines
          });
        });
      }

      if(callback) {
        callback(null, 'started')
      }
    });

    // Stop monitoring of a file/stream
    conn.on('stop', function(data, callback) {
      if(watchers[data.file]) {
        watchers[data.file].destroy();
      }

      if(callback) {
        callback(null, 'stopped')
      }
    });
  };

  Collector.prototype.register = function(callback) {
    var files = {};
    for(var f in this.files) {
      files[f] = {};
    }

    var data = {
      'hostname': os.hostname(),
      'watchables': files,
      'key': this.key,
      'type': 'collector'
    };

    // Register with aggregator
    this.conn.emit('register', data, function(error, result) {
      if(error) {
        if(callback) {
          return callback(error);
        } else {
          throw error;
        }
      }

      if(callback) {
        callback(null, true);
      }
    });
  };

  // Unregister with aggregator
  Collector.prototype.unregister = function() {
    var data = {
      'hostname': os.hostname()
    };
    this.conn.emit('unregister', data, function() {

    });
  };

  return Collector;
}();<commit_msg>Fixed typo<commit_after>
var os = require('os');
var io = require('socket.io-client');
var FileNotify = require('filenotify');

module.exports = function() {
  var Collector = function Collector(files, url, key, callback) {
    var that = this;
    var watchers = {};

    this.key = key;
    this.files = files;

    var conn = this.conn = io.connect(url);

    // On connect register with server
    conn.on('connect', function() {
      that.register(callback);
    });

    // Start monitoring of a file/stream
    conn.on('start', function(data, callback) {
      if(!watchers[data.file]) {
        watchers[data.file] = new FileNotify(files[data.file]);
        watchers[data.file].on('data', function(lines) {
          that.conn.emit('lines', {
            'date': new Date().toUTCString(),
            'watchable': data.file,
            'lines': lines
          });
        });
      }

      if(callback) {
        callback(null, 'started')
      }
    });

    // Stop monitoring of a file/stream
    conn.on('stop', function(data, callback) {
      if(watchers[data.file]) {
        watchers[data.file].destroy();
      }

      if(callback) {
        callback(null, 'stopped')
      }
    });
  };

  Collector.prototype.register = function(callback) {
    var files = {};
    for(var f in this.files) {
      files[f] = {};
    }

    var data = {
      'hostname': os.hostname(),
      'watchables': files,
      'key': this.key,
      'type': 'collector'
    };

    // Register with aggregator
    this.conn.emit('register', data, function(error, result) {
      if(error) {
        if(callback) {
          return callback(error);
        } else {
          throw error;
        }
      }

      if(callback) {
        callback(null, true);
      }
    });
  };

  // Unregister with aggregator
  Collector.prototype.unregister = function() {
    var data = {
      'hostname': os.hostname()
    };
    this.conn.emit('unregister', data, function() {

    });
  };

  return Collector;
}();<|endoftext|>


<commit_before>/**
 * the function to convert the from into json
 * @returns {{string: string}} - the from converted to json
 */
function jsonifyForm () {
    var form = {}
    $.each($('form').serializeArray(), function (i, field) {
        form[field.name] = field.value || ''
    })
    return form
}

/**
 * the function to run the error modal
 * @param htmlMsg {string} - the message to display, you can put html in it
 */
function runModal (htmlMsg) {
    $('#error-modal-message').html(htmlMsg)
    $('#error-modal').modal()
}

/**
 * the function to do ajax in dendrogram
 * @param url {string} - the url to do post
 */
function doAjax (url) {
    // show loading icon
    $('#status-analyze').css({'visibility': 'visible'})

    var form = jsonifyForm()
    $.ajax({
            type: 'POST',
            url: url,
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            data: JSON.stringify(form),
            complete: function (response) {
                $('#status-analyze').css({'visibility': 'hidden'})
                $('#dendrogram-result').html(response['responseJSON']['dendroDiv'])
            },
            error: function (jqXHR, textStatus, errorThrown) {
                console.log('textStatus: ' + textStatus)
                console.log('errorThrown: ' + errorThrown)
                runModal('error encountered while plotting the dendrogram.')
            }
        }
    )
}

/**
 * the error message for the submission
 * @returns {string | null} - if it is null, it means no error, else then the string is the error message
 */
function submissionError () {
    const err = 'A dendrogram requires at least 2 active documents to be created.'
    const activeFiles = $('#num_active_files').val()
    if (activeFiles < 2)
        return err
    else
        return null
}

/**
 * When the HTML documents finish loading
 */
$(document).ready(function () {

    /**
     * the events after dendrogram is clicked
     */
    $('#getdendro').on('click', function () {
        const error = submissionError()  // the error happens during submission

        if (error === null) {  // if there is no error
            doAjax('/dendrogramDiv', null)
        }
        else {
            runModal(error)
        }

    })

})
<commit_msg>change the js to deferred object<commit_after>/**
 * the function to convert the from into json
 * @returns {{string: string}} - the from converted to json
 */
function jsonifyForm () {
    var form = {}
    $.each($('form').serializeArray(), function (i, field) {
        form[field.name] = field.value || ''
    })
    return form
}

/**
 * the function to run the error modal
 * @param htmlMsg {string} - the message to display, you can put html in it
 */
function runModal (htmlMsg) {
    $('#error-modal-message').html(htmlMsg)
    $('#error-modal').modal()
}

/**
 * the function to do ajax in dendrogram
 */
function doAjax () {
    // show loading icon
    $('#status-analyze').css({'visibility': 'visible'})

    // convert form into an object map string to string
    var form = jsonifyForm()

    // make the ajax request
    $.ajax({
        type: 'POST',
        url: '/dendrogramDiv',
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        data: JSON.stringify(form)
    })
        .done(
            function (response) {
                $('#dendrogram-result').html(response['dendroDiv'])
            })
        .fail(
            function (jqXHR, textStatus, errorThrown) {
                console.log('textStatus: ' + textStatus)
                console.log('errorThrown: ' + errorThrown)
                runModal('error encountered while plotting the dendrogram.')
            })
        .always(
            function () {
                $('#status-analyze').css({'visibility': 'hidden'})
            })
}

/**
 * the error message for the submission
 * @returns {string | null} - if it is null, it means no error, else then the string is the error message
 */
function submissionError () {
    const active_file_num_too_few_err = 'A dendrogram requires at least 2 active documents to be created.'
    const activeFiles = $('#num_active_files').val()
    if (activeFiles < 2)
        return active_file_num_too_few_err
    else
        return null
}

/**
 * When the HTML documents finish loading
 */
$(function () {

    /**
     * the events after dendrogram is clicked
     */
    $('#getdendro').on('click', function () {
        const error = submissionError()  // the error happens during submission

        if (error === null) {  // if there is no error
            doAjax()
        }
        else {
            runModal(error)
        }
    })

})
<|endoftext|>


<commit_before>/**
 * Show the request user has made in the last times (month or 21 days)
 *
 * It just prints the requests data as a simple chart.
 * It needs the data as an Array to work.
 *
 * Usage example:
 *
 *    // D3 API Requests
 *    this.stats = this.stats = new cdb.admin.D3Stats({
 *      el: this.$el.find("li:eq(2)"),
 *      api_calls: this.model.attributes.api_calls
 *    });
 */

cdb.admin.D3Stats = cdb.core.View.extend({

  tagName: 'div',
  className: 'stats',

  initialize: function() {
    // Get data
    this.requests = this.options.api_calls || [];

    // Render graphic!
    this.render();
  },

  render: function() {

    // SVG
    var width = 291
      , height = 36
      , svg = d3.select(this.$el.find("div.stats")[0])
                .append("svg")
                .attr("width",width)
                .attr("height",height)
      , max = _.max(_(this.requests).map(function(m){ return parseInt(m, 10) }));

    // Get scales and create the line
    var x = d3.scale.linear().domain([0, this.requests.length]).range([0, width])
      , y = d3.scale.linear().domain([0,max]).range([height,2])
      , line = d3.svg.line()
                .x(function(d,i) { return x(i); })
                .y(function(d) { return y(d); })
      , area = d3.svg.area()
                .x(function(d,i) { return x(i); })
                .y0(function(d) { return height; })
                .y1(function(d) { return y(d); });

      // display the line by appending an svg:path element with the data line we created above
      svg.append("svg:path")
        .attr("d", area(this.requests))
        .style("fill", "#ECF5FA")

      svg.append("svg:path")
        .attr("d", line(this.requests))
        .style("fill", "none")
        .style("stroke-width", "2")
        .style("stroke", "#409FCE")

    // Put total api calls
    this.$el.find("p").html(
      "" + _.reduce(this.requests, function(memo, num){ return memo + num; }, 0) + " API calls the last " + _.size(this.requests) + " days"
    )

    return this;
  }

});
<commit_msg>prevent stats being cut<commit_after>/**
 * Show the request user has made in the last times (month or 21 days)
 *
 * It just prints the requests data as a simple chart.
 * It needs the data as an Array to work.
 *
 * Usage example:
 *
 *    // D3 API Requests
 *    this.stats = this.stats = new cdb.admin.D3Stats({
 *      el: this.$el.find("li:eq(2)"),
 *      api_calls: this.model.attributes.api_calls
 *    });
 */

cdb.admin.D3Stats = cdb.core.View.extend({

  tagName: 'div',
  className: 'stats',

  initialize: function() {
    // Get data
    this.requests = this.options.api_calls || [];

    // Render graphic!
    this.render();
  },

  render: function() {

    // SVG
    var width = 291
      , height = 33
      , svg = d3.select(this.$el.find("div.stats")[0])
                .append("svg")
                .attr("width",width)
                .attr("height",height + 3)
      , max = _.max(_(this.requests).map(function(m){ return parseInt(m, 10) }));

    // Get scales and create the line
    var x = d3.scale.linear().domain([0, this.requests.length]).range([0, width])
      , y = d3.scale.linear().domain([0,max]).range([height,2])
      , line = d3.svg.line()
                .x(function(d,i) { return x(i); })
                .y(function(d) { return y(d); })
      , area = d3.svg.area()
                .x(function(d,i) { return x(i); })
                .y0(function(d) { return height + 3; })
                .y1(function(d) { return y(d); });

      // display the line by appending an svg:path element with the data line we created above
      svg.append("svg:path")
        .attr("d", area(this.requests))
        .style("fill", "#ECF5FA")

      svg.append("svg:path")
        .attr("d", line(this.requests))
        .style("fill", "none")
        .style("stroke-width", "2")
        .style("stroke", "#409FCE")

    // Put total api calls
    this.$el.find("p").html(
      "" + _.reduce(this.requests, function(memo, num){ return memo + num; }, 0) + " API calls the last " + _.size(this.requests) + " days"
    )

    return this;
  }

});
<|endoftext|>


<commit_before>var
    esPhinx,
    Iterable;

(function($) {
    "use strict";

    $.prototype.extend({

        autocomplete: function(elementsList, options, callback) {
            var
                fillOften,
                searchTextBox = this,
                nonCharacterKeysPattern = new RegExp($
                    .nonCharacterKeysPattern()),
                inline = false,
                elements2Recovery = [],
                afterAmountCharacters = options.afterAmountCharacters,

                fillInToRecovery = function(object, times) {
                    if (typeof times != "number") {times  = 1;}

                    var
                        i = 0;

                    while (i++ < times) {
                        elements2Recovery.push(object);
                    }
                },

                resolveArguments = function(options) {
                    if (Object.getPrototypeOf(options) !=
                        Object.getPrototypeOf({})) {
                        options = {};
                    }

                    if (typeof options.caseSensitive != "boolean") {
                        options.caseSensitive = false;
                    }

                    if (typeof options.orderlySearch != "boolean") {
                        options.orderlySearch = false;
                    }

                    if (typeof afterAmountCharacters != "number") {
                        afterAmountCharacters = 1;
                    }

                },

                inlineSearch = function(element, options) {
                    var
                        eventListenerMethod,
                        previousSearchText = searchTextBox.value();

                    if (typeof eventListenerMethod == "function") {
                        searchTextBox.off("input", eventListenerMethod);
                        searchTextBox.off("focus", eventListenerMethod);
                    }

                    eventListenerMethod = function(e) {
                        var
                            resolvedList,
                            foundElements,
                            startingIndex,
                            finalIndex,
                            foundElement,
                            previousElement = element,
                            parent = element.clone(),
                            searchTextLength = searchTextBox.value().length,
                            charactersDifference = previousSearchText.length -
                                    searchTextLength,

                            replaceLast = function(object) {
                                elements2Recovery.pop();
                                fillInToRecovery(object);
                            };

                        if (searchTextBox.value()) {

                            startingIndex = searchTextBox.cursorPosition() - 2;
                            finalIndex = startingIndex + charactersDifference -
                                1;

                            // when delete
                            if (searchTextLength < previousSearchText.length &&
                                searchTextLength >= afterAmountCharacters) {

                                // debugger
                                if (startingIndex === 0) {
                                    elements2Recovery.delete(startingIndex,
                                        finalIndex);
                                } else {
                                    elements2Recovery.delete(startingIndex,
                                        elements2Recovery.lastIndex());
                                }

                                previousElement = elements2Recovery[
                                        elements2Recovery.lastIndex()];
                            }

                            resolvedList = resolveList(previousElement,
                                options.order);
                            foundElements = resolvedList.elements;

                            // debugger
                            if (searchTextLength > afterAmountCharacters ||
                                afterAmountCharacters == 1) {

                                if (foundElements.some()) {
                                    foundElement = parent
                                                         .append(foundElements);
                                    // there was a difference for more
                                    if (charactersDifference < 0) {
                                        fillOften = Math
                                            .abs(charactersDifference);
                                        fillInToRecovery(foundElement,
                                                       fillOften);
                                    } else {
                                        replaceLast(foundElement);
                                    }

                                    previousElement = foundElement;
                                } else {
                                        // fillOften = searchTextLength - afterAmountCharacters - elements2Recovery.length + 1;
                                    fillInToRecovery(previousElement);
                                }
                            }
                            // debugger

                            previousSearchText = searchTextBox.value();
                            callback.call($(this), foundElements, resolvedList
                                          .maps, e);
                        } else {
                            // reset
                            elements2Recovery = [];
                            previousSearchText = "";
                            previousElement = element;
                            callback.call($(this), $(), e);
                        }

                    };

                    searchTextBox.on("input", eventListenerMethod);
                    searchTextBox.on("focus", eventListenerMethod);
                },

                remoteSearch = function(options) {
                    var
                        word,
                        prevText,
                        nextText,
                        element,
                        URLParameters,
                        resolvedList,
                        clipboardData,

                        request = function(e) {
                            if (options.remote.URLParameters) {
                                URLParameters = options.remote.URLParameters
                                    .call(searchTextBox);
                            }

                            $.Ajax.new(options.remote.url.call(searchTextBox))
                                .get({
                                    URLParameters: URLParameters,
                                    progress: function(xhr) {
                                        if (options.remote.loading) {
                                            options.remote
                                                .loading(xhr, e);
                                        }
                                    },
                                    complete: function() {
                                        $(e.target).off("keypress");
                                    },
                                    success: function(r) {
                                        element = $(r);

                                        if (element.some()) {
                                            fillOften = (searchTextBox
                                                .value().length -
                                                afterAmountCharacters) + 1;

                                            fillInToRecovery(element,
                                                           fillOften);
                                        }

                                        resolvedList = resolveList(element,
                                                                options.order);
                                        callback.call(searchTextBox,
                                            resolvedList.elements,
                                            resolvedList.maps, e);
                                        if (element.length) {
                                            inlineSearch(element, options);
                                        }
                                    }
                                });
                        };

                    searchTextBox.on("keyup", function(e) {
                        word = searchTextBox.value();

                        if (word.length > afterAmountCharacters) {
                            inline = true;
                        } else if (word.length < afterAmountCharacters) {
                            inline = false;
                        }

                        if (word.length == afterAmountCharacters &&
                            !nonCharacterKeysPattern.test(e.key) &&
                            !inline &&
                            options.remote) {
                            $(e.target).on("keypress", function(e) {
                                e.preventDefault();
                            });

                            request(e);
                        }

                    });

                    searchTextBox.on("paste", function(e) {
                        word = searchTextBox.value();
                        prevText = word
                            .slice(0, searchTextBox.cursorPosition());
                        nextText = word
                            .slice(searchTextBox.selectionEnd(), word.length);

                        clipboardData = e.clipboardData.getData("text");

                        if (word.length >= afterAmountCharacters) {
                            inline = true;
                        } else {
                            inline = false;
                        }

                        word = prevText + clipboardData + nextText;

                        if (word.length >= afterAmountCharacters &&
                            !inline &&
                            options.remote) {
                            searchTextBox.value(word);

                            request(e);
                            e.preventDefault();
                        }
                    });

                },

                mapIf = function(searchTextAsArray, textNodeAsArray) {
                    var
                        iterator,
                        sliceIndex,
                        regexp,
                        textNodeHashSet = Object
                            .asCountableLiteralObject(textNodeAsArray),
                        mapped = {},
                        count = 0,
                        index = 0,
                        previousIndex = -1;

                    if (textNodeHashSet.length >= searchTextAsArray.length) {
                        iterator = Iterable.Proxy.new(searchTextAsArray);
                        iterator.each(function(slice) {
                            slice = slice.trim();
                            index = Object.firstFromASlice(textNodeHashSet,
                                                             slice, index,
                                                             options
                                                             .caseSensitive);

                            if (index && ((options.orderlySearch &&
                                index > previousIndex) ||
                                !options.orderlySearch) &&
                                textNodeAsArray.countSlice(slice,
                                    options.caseSensitive) >=
                                    searchTextAsArray.count(slice)) {

                                previousIndex = index;

                                if (options.caseSensitive) {
                                    regexp = new RegExp(slice);
                                } else {
                                    regexp = new RegExp(slice, "i");
                                }

                                sliceIndex = textNodeAsArray[index]
                                    .search(regexp);
                                mapped[index] = textNodeAsArray[index]
                                    .slice(sliceIndex, sliceIndex + slice
                                           .length);
                                Object.delete(textNodeHashSet, index);
                                count += 1;
                            } else {
                                this.finalize();
                            }
                        });

                        if (count == searchTextAsArray.length) {
                            return mapped;
                        }
                    }

                    return false;
                },

                // resolveList = function(list, order = "desc") {
                resolveList = function(list, order) {
                    if (order != "asc") {order = "desc";}
                    var
                        textNode,
                        mapped,
                        textNodeAsArray,
                        sorted,
                        found = {elements: $(), maps: []},
                        textBoxContentArr = searchTextBox.value().split(" ")
                            .compact();

                    if (list.elements().count() == 1 &&
                        list.isA(window.Element)) {
                        list = list.childElements().clone(true);
                    }

                    if (order == "asc") {
                        sorted = list.ascendingSortTextNode();
                    } else {
                        sorted = list.descendingSortTextNode();
                    }

                    sorted.each(function(element) {
                        textNode = $(element).textContent().trim();
                        textNodeAsArray = textNode.split(" ");
                        mapped = mapIf(textBoxContentArr, textNodeAsArray);
                        if (mapped) {
                            found.elements.push(element);
                            found.maps.push(mapped);
                        }
                    });

                    return found;
                };

            resolveArguments(options);

            // init
            if (Object.getPrototypeOf(elementsList) != Object.prototype) {
                inlineSearch(elementsList, options);
            } else {
                options = elementsList;
                remoteSearch(options);
            }
        }

    });

})(esPhinx);
<commit_msg>autocomplete<commit_after>var
    esPhinx,
    Iterable;

(function($) {
    "use strict";

    $.prototype.extend({

        autocomplete: function(elementsList, options, callback) {
            var
                fillOften,
                searchTextBox = this,
                nonCharacterKeysPattern = new RegExp($
                    .nonCharacterKeysPattern()),
                inline = false,
                elements2Recovery = [],
                afterAmountCharacters = options.afterAmountCharacters,

                fillInToRecovery = function(object, times) {
                    if (typeof times != "number") {times  = 1;}

                    var
                        i = 0;

                    while (i++ < times) {
                        elements2Recovery.push(object);
                    }
                },

                resolveArguments = function(options) {
                    if (Object.getPrototypeOf(options) !=
                        Object.getPrototypeOf({})) {
                        options = {};
                    }

                    if (typeof options.caseSensitive != "boolean") {
                        options.caseSensitive = false;
                    }

                    if (typeof options.orderlySearch != "boolean") {
                        options.orderlySearch = false;
                    }

                    if (typeof afterAmountCharacters != "number") {
                        afterAmountCharacters = 1;
                    }

                },

                inlineSearch = function(element, options) {
                    var
                        eventListenerMethod,
                        previousSearchText = searchTextBox.value();

                    if (typeof eventListenerMethod == "function") {
                        searchTextBox.off("input", eventListenerMethod);
                    }

                    eventListenerMethod = function(e) {
                        var
                            resolvedList,
                            foundElements,
                            startingIndex,
                            finalIndex,
                            foundElement,
                            previousElement = element,
                            parent = element.clone(),
                            searchTextLength = searchTextBox.value().length,
                            searchTextDifferente = previousSearchText.length -
                                    searchTextLength,
                            searchTextAmount = (searchTextLength -
                                                afterAmountCharacters) + 1,

                            replaceLast = function(object) {
                                elements2Recovery.pop();
                                fillInToRecovery(object);
                            };

                        if (searchTextBox.value()) {
                            startingIndex = searchTextBox.cursorPosition() - 2;

                            if (startingIndex < 0) {
                                startingIndex = 0;
                            }
                            finalIndex = startingIndex + searchTextDifferente -
                                1;

                            // when delete
                            if (searchTextLength < previousSearchText.length &&
                                searchTextLength >= afterAmountCharacters) {

                                // debugger
                                if (startingIndex === 0) {
                                    elements2Recovery.delete(startingIndex,
                                        finalIndex);
                                } else {
                                    elements2Recovery.delete(startingIndex,
                                        elements2Recovery.lastIndex());
                                }

                                previousElement = elements2Recovery[
                                        elements2Recovery.lastIndex()];
                            }

                            resolvedList = resolveList(previousElement,
                                options.order);
                            foundElements = resolvedList.elements;

                            // debugger
                            if (searchTextLength > afterAmountCharacters ||
                                afterAmountCharacters == 1) {

                                if (foundElements.some()) {
                                    foundElement = parent
                                                         .append(foundElements);

                                    // debugger
                                    // check if is necessary insert
                                    if (elements2Recovery.length <
                                        searchTextAmount) {

                                        // there was a difference for more
                                        if (searchTextDifferente < 0) {
                                            fillOften = Math
                                                .abs(searchTextDifferente);
                                            // debugger
                                        } else {
                                            fillOften = searchTextAmount -
                                                elements2Recovery.length;
                                            // debugger
                                        }

                                        fillInToRecovery(foundElement,
                                                       fillOften);
                                    } else {
                                        // debugger
                                        replaceLast(foundElement);
                                    }

                                    previousElement = foundElement;
                                } else {
                                    fillOften = searchTextLength -
                                        afterAmountCharacters;
                                    debugger
                                    // rever critério
                                    if (elements2Recovery.length < fillOften) {
                                        debugger
                                        fillInToRecovery(previousElement,
                                                         fillOften);
                                    } else {
                                        // aparentemente há mais um critério aqui
                                        debugger
                                        fillInToRecovery(previousElement);
                                    }

                                    // usar replaceLast(previousElement); aqui. Mas quando?
                                }
                            }
                            // debugger

                            previousSearchText = searchTextBox.value();
                            callback.call($(this), foundElements, resolvedList
                                          .maps, e);
                        } else {
                            // reset
                            elements2Recovery = [];
                            previousSearchText = "";
                            previousElement = element;
                            callback.call($(this), $(), e);
                        }

                    };

                    searchTextBox.on("input", eventListenerMethod);
                },

                remoteSearch = function(options) {
                    var
                        word,
                        prevText,
                        nextText,
                        element,
                        URLParameters,
                        resolvedList,
                        clipboardData,

                        request = function(e) {
                            if (options.remote.URLParameters) {
                                URLParameters = options.remote.URLParameters
                                    .call(searchTextBox);
                            }

                            $.Ajax.new(options.remote.url.call(searchTextBox))
                                .get({
                                    URLParameters: URLParameters,
                                    progress: function(xhr) {
                                        if (options.remote.loading) {
                                            options.remote
                                                .loading(xhr, e);
                                        }
                                    },
                                    complete: function() {
                                        $(e.target).off("keypress");
                                    },
                                    success: function(r) {
                                        element = $(r);

                                        if (element.some()) {
                                            fillOften = (searchTextBox
                                                .value().length -
                                                afterAmountCharacters) + 1;

                                            fillInToRecovery(element,
                                                           fillOften);
                                        }

                                        resolvedList = resolveList(element,
                                                                options.order);
                                        callback.call(searchTextBox,
                                            resolvedList.elements,
                                            resolvedList.maps, e);
                                        if (element.length) {
                                            inlineSearch(element, options);
                                        }
                                    }
                                });
                        };

                    searchTextBox.on("keyup", function(e) {
                        word = searchTextBox.value();

                        if (word.length > afterAmountCharacters) {
                            inline = true;
                        } else if (word.length < afterAmountCharacters) {
                            inline = false;
                        }

                        if (word.length == afterAmountCharacters &&
                            !nonCharacterKeysPattern.test(e.key) &&
                            !inline &&
                            options.remote) {
                            $(e.target).on("keypress", function(e) {
                                e.preventDefault();
                            });

                            request(e);
                        }

                    });

                    searchTextBox.on("paste", function(e) {
                        word = searchTextBox.value();
                        prevText = word
                            .slice(0, searchTextBox.cursorPosition());
                        nextText = word
                            .slice(searchTextBox.selectionEnd(), word.length);

                        clipboardData = e.clipboardData.getData("text");

                        if (word.length >= afterAmountCharacters) {
                            inline = true;
                        } else {
                            inline = false;
                        }

                        word = prevText + clipboardData + nextText;

                        if (word.length >= afterAmountCharacters &&
                            !inline &&
                            options.remote) {
                            searchTextBox.value(word);

                            request(e);
                            e.preventDefault();
                        }
                    });

                },

                mapIf = function(searchTextAsArray, textNodeAsArray) {
                    var
                        iterator,
                        sliceIndex,
                        regexp,
                        textNodeHashSet = Object
                            .asCountableLiteralObject(textNodeAsArray),
                        mapped = {},
                        count = 0,
                        index = 0,
                        previousIndex = -1;

                    if (textNodeHashSet.length >= searchTextAsArray.length) {
                        iterator = Iterable.Proxy.new(searchTextAsArray);
                        iterator.each(function(slice) {
                            slice = slice.trim();
                            index = Object.firstFromASlice(textNodeHashSet,
                                                             slice, index,
                                                             options
                                                             .caseSensitive);

                            if (index && ((options.orderlySearch &&
                                index > previousIndex) ||
                                !options.orderlySearch) &&
                                textNodeAsArray.countSlice(slice,
                                    options.caseSensitive) >=
                                    searchTextAsArray.count(slice)) {

                                previousIndex = index;

                                if (options.caseSensitive) {
                                    regexp = new RegExp(slice);
                                } else {
                                    regexp = new RegExp(slice, "i");
                                }

                                sliceIndex = textNodeAsArray[index]
                                    .search(regexp);
                                mapped[index] = textNodeAsArray[index]
                                    .slice(sliceIndex, sliceIndex + slice
                                           .length);
                                Object.delete(textNodeHashSet, index);
                                count += 1;
                            } else {
                                this.finalize();
                            }
                        });

                        if (count == searchTextAsArray.length) {
                            return mapped;
                        }
                    }

                    return false;
                },

                // resolveList = function(list, order = "desc") {
                resolveList = function(list, order) {
                    if (order != "asc") {order = "desc";}
                    var
                        textNode,
                        mapped,
                        textNodeAsArray,
                        sorted,
                        found = {elements: $(), maps: []},
                        textBoxContentArr = searchTextBox.value().split(" ")
                            .compact();

                    if (list.elements().count() == 1 &&
                        list.isA(window.Element)) {
                        list = list.childElements().clone(true);
                    }

                    if (order == "asc") {
                        sorted = list.ascendingSortTextNode();
                    } else {
                        sorted = list.descendingSortTextNode();
                    }

                    sorted.each(function(element) {
                        textNode = $(element).textContent().trim();
                        textNodeAsArray = textNode.split(" ");
                        mapped = mapIf(textBoxContentArr, textNodeAsArray);
                        if (mapped) {
                            found.elements.push(element);
                            found.maps.push(mapped);
                        }
                    });

                    return found;
                };

            resolveArguments(options);

            // init
            if (Object.getPrototypeOf(elementsList) != Object.prototype) {
                inlineSearch(elementsList, options);
            } else {
                options = elementsList;
                remoteSearch(options);
            }
        }

    });

})(esPhinx);
<|endoftext|>