<commit_before>var os = Npm.require('os');
var usage = Npm.require('pidusage');
var EventLoopMonitor = Npm.require('evloop-monitor');

SystemModel = function () {
  var self = this;
  this.startTime = Ntp._now();
  this.newSessions = 0;
  this.sessionTimeout = 1000 * 60 * 30; //30 min

  this.currentUsage = {};
  this.usageLookup = Kadira._wrapAsync(usage.stat.bind(usage));
  this.evloopMonitor = new EventLoopMonitor(200);
  this.evloopMonitor.start();
}

_.extend(SystemModel.prototype, KadiraModel.prototype);

SystemModel.prototype.buildPayload = function() {
  var metrics = {};
  var now = Ntp._now();
  metrics.startTime = Kadira.syncedDate.syncTime(this.startTime);
  metrics.endTime = Kadira.syncedDate.syncTime(now);

  metrics.sessions = _.keys(Meteor.default_server.sessions).length;
  metrics.memory = process.memoryUsage().rss / (1024*1024);
  metrics.newSessions = this.newSessions;
  this.newSessions = 0;

  var usage = this.getUsage();
  metrics.pcpu = usage.cpu;
  if(usage.cpuInfo) {
    metrics.cputime = usage.cpuInfo.cpuTime;
    metrics.pcpuUser = usage.cpuInfo.pcpuUser;
    metrics.pcpuSystem = usage.cpuInfo.pcpuSystem;
  }

  // track eventloop blockness
  metrics.pctEvloopBlock = this.evloopMonitor.status().pctBlock;

  this.startTime = now;
  return {systemMetrics: [metrics]};
};

SystemModel.prototype.getUsage = function() {
  this.currentUsage = this.usageLookup(process.pid) || {};
  return this.currentUsage;
};

SystemModel.prototype.handleSessionActivity = function(msg, session) {
  if(msg.msg === 'connect' && !msg.session) {
    this.countNewSession(session);
  } else if(['sub', 'method'].indexOf(msg.msg) != -1) {
    if(!this.isSessionActive(session)) {
      this.countNewSession(session);
    }
  }
  session._activeAt = Date.now();
}

SystemModel.prototype.countNewSession = function(session) {
  if(!isLocalAddress(session.socket)) {
    this.newSessions++;
  }
}

SystemModel.prototype.isSessionActive = function(session) {
  var inactiveTime = Date.now() - session._activeAt;
  return inactiveTime < this.sessionTimeout;
}

// ------------------------------------------------------------------------- //

// http://regex101.com/r/iF3yR3/2
var isLocalHostRegex = /^(?:.*\.local|localhost)(?:\:\d+)?|127(?:\.\d{1,3}){3}|192\.168(?:\.\d{1,3}){2}|10(?:\.\d{1,3}){3}|172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2}$/;

// http://regex101.com/r/hM5gD8/1
var isLocalAddressRegex = /^127(?:\.\d{1,3}){3}|192\.168(?:\.\d{1,3}){2}|10(?:\.\d{1,3}){3}|172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2}$/;

function isLocalAddress (socket) {
  var host = socket.headers['host'];
  if(host) return isLocalHostRegex.test(host);
  var address = socket.headers['x-forwarded-for'] || socket.remoteAddress;
  if(address) return isLocalAddressRegex.test(address);
}
<commit_msg>Update cpu usage<commit_after>var os = Npm.require('os');
var usage = Npm.require('pidusage');
var EventLoopMonitor = Npm.require('evloop-monitor');

SystemModel = function () {
  var self = this;
  this.startTime = Ntp._now();
  this.newSessions = 0;
  this.sessionTimeout = 1000 * 60 * 30; //30 min

  this.usageLookup = Kadira._wrapAsync(usage.stat.bind(usage));
  this.evloopMonitor = new EventLoopMonitor(200);
  this.evloopMonitor.start();
}

_.extend(SystemModel.prototype, KadiraModel.prototype);

SystemModel.prototype.buildPayload = function() {
  var metrics = {};
  var now = Ntp._now();
  metrics.startTime = Kadira.syncedDate.syncTime(this.startTime);
  metrics.endTime = Kadira.syncedDate.syncTime(now);

  metrics.sessions = _.keys(Meteor.default_server.sessions).length;
  metrics.memory = process.memoryUsage().rss / (1024*1024);
  metrics.newSessions = this.newSessions;
  this.newSessions = 0;

  var usage = this.getUsage();
  metrics.pcpu = usage.cpu;
  if(usage.cpuInfo) {
    metrics.cputime = usage.cpuInfo.cpuTime;
    metrics.pcpuUser = usage.cpuInfo.pcpuUser;
    metrics.pcpuSystem = usage.cpuInfo.pcpuSystem;
  }

  // track eventloop blockness
  metrics.pctEvloopBlock = this.evloopMonitor.status().pctBlock;

  this.startTime = now;
  return {systemMetrics: [metrics]};
};

SystemModel.prototype.getUsage = function() {
  var usage = this.usageLookup(process.pid) || {};
  Kadira.docSzCache.setPcpu(usage);
  return usage;
};

SystemModel.prototype.handleSessionActivity = function(msg, session) {
  if(msg.msg === 'connect' && !msg.session) {
    this.countNewSession(session);
  } else if(['sub', 'method'].indexOf(msg.msg) != -1) {
    if(!this.isSessionActive(session)) {
      this.countNewSession(session);
    }
  }
  session._activeAt = Date.now();
}

SystemModel.prototype.countNewSession = function(session) {
  if(!isLocalAddress(session.socket)) {
    this.newSessions++;
  }
}

SystemModel.prototype.isSessionActive = function(session) {
  var inactiveTime = Date.now() - session._activeAt;
  return inactiveTime < this.sessionTimeout;
}

// ------------------------------------------------------------------------- //

// http://regex101.com/r/iF3yR3/2
var isLocalHostRegex = /^(?:.*\.local|localhost)(?:\:\d+)?|127(?:\.\d{1,3}){3}|192\.168(?:\.\d{1,3}){2}|10(?:\.\d{1,3}){3}|172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2}$/;

// http://regex101.com/r/hM5gD8/1
var isLocalAddressRegex = /^127(?:\.\d{1,3}){3}|192\.168(?:\.\d{1,3}){2}|10(?:\.\d{1,3}){3}|172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2}$/;

function isLocalAddress (socket) {
  var host = socket.headers['host'];
  if(host) return isLocalHostRegex.test(host);
  var address = socket.headers['x-forwarded-for'] || socket.remoteAddress;
  if(address) return isLocalAddressRegex.test(address);
}
<|endoftext|>


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

// init flow with core module
//flow(this.exports);

exports.composition = '@C';
exports.markup = '@M';

exports.log = function (err) {return err}; //require('./logs') ||

exports.cache = function () {

};

exports.client = function () {

};

exports.module = loadModule;

// load module bundles and retun the entry-point exports
function loadModule (name, callback) {

    // crate script dom elemeent
    var node = document.createElement('script');

    node.onload = function () {
        callback(null, require(name));
    };

    // set url and append dom script elm to the document head
    node.src = '/' + name + '/client.js';
    document.head.appendChild(node);
    node.remove();
}
<commit_msg>working on flow interface<commit_after>var Flow = require('../flow/flow');

// init flow with core module
Flow({

    // load module bundles and return the entry-point exports
    module: function (name, callback) {

        // crate script dom elemeent
        var node = document.createElement('script');

        node.onload = function () {
            callback(null, require(name));
        };

        // set url and append dom script elm to the document head
        node.src = '/' + name + '/client.js';
        document.head.appendChild(node);
        node.remove();
    },
    composition: '@C',
    markup: '@M',
    cache: function () {},
    log: function (err) {return err} //require('./logs') ||
});
<|endoftext|>


<commit_before>var M = process.mono;
var EventEmitter = require('events').EventEmitter;

var broadcast = require(M.config.paths.SERVER_ROOT + 'send').broadcast;
var model = require(M.config.paths.MODELS + 'factory');
var view = require(M.config.paths.VIEWS + 'factory');

// TODO get this values from a config
var moduleModel = {
    name: 'modules'
};
var instanceModel = {
    name: 'instances'
};

module.exports = init;

function sendHandler (event) {
    return function (err, data) {
        var self = this;

        // websocket link
        if (self.link && self.link.ws) {
            self.link.send(event, err, data);
        }
    };
}

// create instance
function instanceFactory (module, dbInstance) {

    // create new Mono observer instance
    var instance = new EventEmitter();
    instance.M = {
        module: module.source + '/' + module.owner + '/' + module.name + '/' + module.version + '/',
        name: name,
        client: dbInstance.client || {},

        // allow only the clients events to be emitted form the server
        access: {},
        roles: {}
    };

    // handle ready
    instance.on('ready', function (err) {
        callback(err,  instance.mono.client);
    });

    // attach the broadcast functionality
    instance.broadcast = broadcast;

    // save module name in client config
    instance.mono.client.module = instance.mono.module;

    // add roles to cache
    for (var i = 0, l = dbInstance._ro.length; i < l; ++i) {
        instance.mono.roles[dbInstance._ro[i]] = 1;
    }

    // merge scripts
    // all dependencies of the instance dependencies must be in this array!
    // while installing a module, save all dependencies in the module deps
    // dependencies: ['./file.js', 's/o/modA/v']
    // => ModA deps: ['./file.js', 's/o/modB/v'] => ModB deps: []
    // => to client: ['./file.js', 's/o/n/v/file.js']
    if (module.dependencies) {
        instance.mono.client.scripts = module.dependencies.concat(instance.mono.client.scripts || []);
    }

    // add client events config to client config
    if (dbInstance.client.events) {

        dbInstance.client.events.push('inst>');

        // allow server to emit client events
        for (i = 0, l = dbInstance.client.events.length; i < l; ++i) {
            instance.mono.access[dbInstance.client.events[i]] = true;
        }
    }

    // this are the events which have automatically send as handler
    if (dbInstance.server && dbInstance.server.events) {

        dbInstance.server.events.push('<inst');

        for (i = 0, l = dbInstance.server.events.length; i < l; ++i) {
            instance.on(dbInstance.server.events[i], sendHandler(dbInstance.server.events[i]));
        }
    }

    // listen to "inst>" client event
    instance.on('inst>', load);

    // setup model events and add model factory to instance
    model.setup(instance);
    instance.model = model.factory;

    // setup view events and add model factory to instance
    instance.view = view(instance);

    // save instance in cache
    // TODO update this cache when a instance config changes
    M.cache.instances.save(name, instance);

    // require and init mono module
    if (module.main) {
        // TODO do not use try catch when in dev mode
        try {
            var monoModule = require(M.config.paths.MODULE_ROOT + instance.mono.module + module.main);

            if (typeof monoModule === 'function') {
                monoModule.call(instance, dbInstance.server ? dbInstance.server.data : {});
            }
        } catch (err) {
            return callback('Module ' + name + ' init error: ' + err.toString());
        }
    } else {
        instance.emit('ready');
    }
}

// init module with newly created module instance as this
function loadinstance (name, roleId, callback) {
    var query = {
        _ro: roleId,
        name: name
    };

    model.factory(instanceModel, function (err, instModel) {

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

        instModel.request({m: 'findOne', q: query, o: {fields: {_id: 0, name: 0}}}, function (err, dbInstance) {

            if (err || !dbInstance) {
                return callback(err || 'Instance "' + name + '" not found');
            }

            // get module from cache
            var module = M.cache.instances.get(dbInstance.module);
            if (module) {
                return instanceFactory(module, dbInstance);
            }

            // get module version from db
            model.factory(moduleModel, function (err, modModel) {

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

                modModel.request({m: 'findOne', q: {_id: dbInstance.module}}, function (err, module) {

                    if (err || !module) {
                        return callback(err || 'not found');
                    }

                    // save module in cache
                    M.cache.modules.save(dbInstance.module, module);

                    // create instance
                    instanceFactory(module, dbInstance);
                });
            });
        });
    });
}

// get cached instance and check role access
function getCachedInstance (instance, roleId) {

    instance = M.cache.instances.get(instance);

    // send client config from cache
    if (
        instance &&
        (
            // TODO return no access response
            // check access
            instance.mono.roles['*'] ||
            instance.mono.roles[roleId]
        ) &&
        instance.mono.client
    ) {
        return instance;
    }

    return null;
}

// load instance configuration (ws)
function load (err, instance) {
    var self = this;
    var session = self.link.ws.session;

    // send client config from cache
    var cachedInstance = getCachedInstance(instance, session[M.config.session.role]);
    if (cachedInstance) {
        return self.emit('<inst', null, cachedInstance.mono.client);
    }

    // load and init module
    loadinstance(instance, session[M.config.session.role], function (err, config) {

        if (err) {
            var message = 'Error while loading module instance: ' + instance + '. Error: ' + (err || 'module not found');
            return self.emit('<inst', message);
        }

        // return client config
        self.emit('<inst', null, config);
    });
}

// load client module files (http)
function moduleFiles () {
    var self = this;

    var source = self.link.path[0];
    var owner = self.link.path[1];
    var name = self.link.path[2];
    var version = self.link.path[3];
    var headers = {
        'Cache-Control': 'public, max-age=31536000',
        'Vary': 'Accept-Encoding',
        'Content-Encoding': 'gzip'
    };

    // check if request format is correct
    if (!source || !owner || !name || !version) {
        return self.link.send(400, "Incorrect module request URL format");
    }

    // the module name must be almost alphanumeric
    if (self.link.pathname.replace(/[^a-z0-9\/\.\-_@]|\.\.\//gi, "") !== self.link.pathname) {
        return self.link.send(400, "Incorrect data in module request URL");
    }

    // create file path
    var path = M.config.paths.MODULE_ROOT + self.link.path.join('/');

    // check cache
    var script = M.cache.client.get(path);
    if (script) {

        headers['Content-Length'] = script.data.length;
        headers['Last-Modified'] = script.stats.mtime;
        headers['Content-Type']= script.mime;
        self.link.res.writeHead(200, headers);
        return self.link.res.end(script.data);
    }

    // save compressed/compiled script in cache and send it to the client
    M.cache.client.save(path, function (err, script) {

        if (err) {
            self.link.res.writeHead(500, {'content-type': 'text/plain'});
            return self.link.res.end(err.toString());
        }

        headers['Content-Length'] = script.data.length;
        headers['Last-Modified'] = script.stats.mtime;
        headers['Content-Type']= script.mime;
        self.link.res.writeHead(200, headers);

        return self.link.res.end(script.data);
    });
}

// get mono client (http)
function client (){
    var self = this;
    var path = M.config.paths.CLIENT_ROOT + self.link.path[0];
    var headers = {
        'Cache-Control': 'public, max-age=31536000',
        'Vary': 'Accept-Encoding',
        'Content-Encoding': 'gzip'
    };

    // check cache
    var script = M.cache.client.get(path);
    if (script) {

        headers['Content-Length'] = script.data.length;
        headers['Last-Modified'] = script.stats.mtime;
        headers['Content-Type']= script.mime;
        self.link.res.writeHead(200, headers);
        return self.link.res.end(script.data);
    }

    // save compressed/compiled script in cache and send it to the client
    M.cache.client.save(path, function (err, script) {

        if (err) {
            self.link.res.writeHead(500, {'content-type': 'text/plain'});
            return self.link.res.end(err.toString());
        }

        headers['Content-Length'] = script.data.length;
        headers['Last-Modified'] = script.stats.mtime;
        headers['Content-Type']= script.mime;
        self.link.res.writeHead(200, headers);

        return self.link.res.end(script.data);
    });
}

function init () {
    var instance = new EventEmitter();
    instance.mono = {
        module: 'core',
        name: 'M',

        // set core module access
        access: {
            'inst>': true,
            mod: true,
            client: true
        },
        // set core module public rights
        roles: {'*': 1}
    };

    // attach the broadcast functionality
    instance.broadcast = broadcast;

    // setup client event interface
    instance.on('<inst',  sendHandler('<inst'));
    instance.on('inst>', load);
    instance.on('mod', moduleFiles);
    instance.on('client', client);

    // init mono module and save in cache
    M.cache.instances.save(instance.mono.name, instance);
}
<commit_msg>updated instance factory to new config<commit_after>var M = process.mono;
var EventEmitter = require('events').EventEmitter;

var broadcast = require(M.config.paths.SERVER_ROOT + 'send').broadcast;
var model = require(M.config.paths.MODELS + 'factory');
var view = require(M.config.paths.VIEWS + 'factory');

// TODO get this values from a config
var moduleModel = {
    name: 'modules'
};
var instanceModel = {
    name: 'instances'
};

module.exports = init;

function sendHandler (event) {
    return function (err, data) {
        var self = this;

        // websocket link
        if (self.link && self.link.ws) {
            self.link.send(event, err, data);
        }
    };
}

// create instance
function instanceFactory (module, dbInstance, callback) {

    // create new Mono observer instance
    var instance = new EventEmitter();
    instance.Z = {
        module: module.source + '/' + module.owner + '/' + module.name + '/' + module.version + '/',
        name: dbInstance.name,
        // allow only the clients events to be emitted form the server
        access: {},
        roles: {},
        client: {}
    };

    // save configs on instance
    if (dbInstance.config) {

        // save custom client config
        if (dbInstance.config.client) {
            instance.Z.client = {
                config: dbInstance.config.client
            };
        }

        // server config
        instance.Z.config = dbInstance.config.server || {};
    }

    // save load infos in client
    if (dbInstance.L) {
        instance.Z.client.L = dbInstance.L;
    }

    // save observe infos in client
    if (dbInstance.O) {
        instance.Z.client.O = dbInstance.O;
    }

    // save module name in client config
    instance.Z.client.module = instance.Z.module;

    // add roles to cache
    for (var i = 0, l = dbInstance.roles.length; i < l; ++i) {
        instance.Z.roles[dbInstance.roles[i]] = 1;
    }

    // merge scripts
    // all dependencies of the instance dependencies must be in this array!
    // while installing a module, save all dependencies in the module deps
    // dependencies: ['./file.js', 's/o/modA/v']
    // => ModA deps: ['./file.js', 's/o/modB/v'] => ModB deps: []
    // => to client: ['./file.js', 's/o/n/v/file.js']
    if (module.dependencies) {
        instance.Z.client.scripts = module.dependencies;
    }

    // append custom instance scripts
    if (dbInstance.scripts) {
        instance.Z.client.scripts = module.dependencies.concat(instance.Z.scripts || []);
    }

    if (dbInstance.send) {

        // exend send config with public instance load event
        dbInstance.send.up.push('inst>');
        dbInstance.send.down.push('<inst');

        // grant access for client emitted server events
        if (dbInstance.send.up) {
            for (i = 0, l = dbInstance.send.up.length; i < l; ++i) {
                instance.Z.access[dbInstance.send.up[i]] = true;
            }
        }

        // attach send handler for server emitted client events
        if (dbInstance.send.down) {
            for (i = 0, l = dbInstance.send.down.length; i < l; ++i) {
                instance.on(dbInstance.send.down[i], sendHandler(dbInstance.send.down[i]));
            }
        }
    }

    // load instance on "inst>" event
    instance.on('inst>', load);

    // setup model events and add model factory to instance
    //model.setup(instance);
    //instance.model = model.factory;

    // setup view events and add model factory to instance
    //instance.view = view(instance);

    // attach the broadcast functionality
    instance.broadcast = broadcast;

    // handle ready
    instance.on('ready', function (err) {
        callback(err,  instance.Z.client);
    });

    // save instance in cache
    // TODO update this cache when a instance config changes
    M.cache.instances.save(dbInstance.name, instance);

    // require and init mono module
    if (module.main) {
        // TODO do not use try catch when in dev mode
        try {
            var monoModule = require(M.config.paths.MODULE_ROOT + instance.Z.module + module.main);

            if (typeof monoModule === 'function') {
                monoModule.call(instance, instance.Z.config || {});
            }
        } catch (err) {
            return callback('Module ' + dbInstance.name + ' init error: ' + err.toString());
        }
    } else {
        instance.emit('ready');
    }
}

// init module with newly created module instance as this
function loadinstance (name, roleId, callback) {
    var query = {
        roles: roleId,
        name: name
    };

    model.factory(instanceModel, function (err, instModel) {

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

        instModel.request({m: 'findOne', q: query, o: {fields: {_id: 0, name: 0}}}, function (err, dbInstance) {

            if (err || !dbInstance) {
                return callback(err || 'Instance "' + name + '" not found');
            }

            // get module from cache
            var module = M.cache.instances.get(dbInstance.module);
            if (module) {
                return instanceFactory(module, dbInstance, callback);
            }

            // get module version from db
            model.factory(moduleModel, function (err, modModel) {

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

                modModel.request({m: 'findOne', q: {_id: dbInstance.module}}, function (err, module) {

                    if (err || !module) {
                        return callback(err || 'not found');
                    }

                    // save module in cache
                    M.cache.modules.save(dbInstance.module, module);

                    // create instance
                    instanceFactory(module, dbInstance, callback);
                });
            });
        });
    });
}

// get cached instance and check role access
function getCachedInstance (instance, roleId) {

    instance = M.cache.instances.get(instance);

    // send client config from cache
    if (
        instance &&
        (
            // TODO return no access response
            // check access
            instance.Z.roles['*'] ||
            instance.Z.roles[roleId]
        ) &&
        instance.Z.client
    ) {
        return instance;
    }

    return null;
}

// load instance configuration (ws)
function load (err, instance) {
    var self = this;
    var session = self.link.ws.session;

    // send client config from cache
    var cachedInstance = getCachedInstance(instance, session[M.config.session.role]);
    if (cachedInstance) {
        return self.emit('<inst', null, cachedinstance.Z.client);
    }

    // load and init module
    loadinstance(instance, session[M.config.session.role], function (err, config) {

        if (err) {
            var message = 'Error while loading module instance: ' + instance + '. Error: ' + (err || 'module not found');
            return self.emit('<inst', message);
        }

        // return client config
        self.emit('<inst', null, config);
    });
}

// load client module files (http)
function moduleFiles () {
    var self = this;

    var source = self.link.path[0];
    var owner = self.link.path[1];
    var name = self.link.path[2];
    var version = self.link.path[3];
    var headers = {
        'Cache-Control': 'public, max-age=31536000',
        'Vary': 'Accept-Encoding',
        'Content-Encoding': 'gzip'
    };

    // check if request format is correct
    if (!source || !owner || !name || !version) {
        return self.link.send(400, "Incorrect module request URL format");
    }

    // the module name must be almost alphanumeric
    if (self.link.pathname.replace(/[^a-z0-9\/\.\-_@]|\.\.\//gi, "") !== self.link.pathname) {
        return self.link.send(400, "Incorrect data in module request URL");
    }

    // create file path
    var path = M.config.paths.MODULE_ROOT + self.link.path.join('/');

    // check cache
    var script = M.cache.client.get(path);
    if (script) {

        headers['Content-Length'] = script.data.length;
        headers['Last-Modified'] = script.stats.mtime;
        headers['Content-Type']= script.mime;
        self.link.res.writeHead(200, headers);
        return self.link.res.end(script.data);
    }

    // save compressed/compiled script in cache and send it to the client
    M.cache.client.save(path, function (err, script) {

        if (err) {
            self.link.res.writeHead(500, {'content-type': 'text/plain'});
            return self.link.res.end(err.toString());
        }

        headers['Content-Length'] = script.data.length;
        headers['Last-Modified'] = script.stats.mtime;
        headers['Content-Type']= script.mime;
        self.link.res.writeHead(200, headers);

        return self.link.res.end(script.data);
    });
}

// get mono client (http)
function client (){
    var self = this;
    var path = M.config.paths.CLIENT_ROOT + self.link.path[0];
    var headers = {
        'Cache-Control': 'public, max-age=31536000',
        'Vary': 'Accept-Encoding',
        'Content-Encoding': 'gzip'
    };

    // check cache
    var script = M.cache.client.get(path);
    if (script) {

        headers['Content-Length'] = script.data.length;
        headers['Last-Modified'] = script.stats.mtime;
        headers['Content-Type']= script.mime;
        self.link.res.writeHead(200, headers);
        return self.link.res.end(script.data);
    }

    // save compressed/compiled script in cache and send it to the client
    M.cache.client.save(path, function (err, script) {

        if (err) {
            self.link.res.writeHead(500, {'content-type': 'text/plain'});
            return self.link.res.end(err.toString());
        }

        headers['Content-Length'] = script.data.length;
        headers['Last-Modified'] = script.stats.mtime;
        headers['Content-Type']= script.mime;
        self.link.res.writeHead(200, headers);

        return self.link.res.end(script.data);
    });
}

function init () {
    var instance = new EventEmitter();
    instance.Z = {
        module: 'core',
        name: M.config.coreInstance,

        // set core module access
        access: {
            'inst>': true,
            mod: true,
            client: true
        },
        // set core module public rights
        roles: {'*': 1}
    };

    // attach the broadcast functionality
    instance.broadcast = broadcast;

    // setup client event interface
    instance.on('<inst',  sendHandler('<inst'));
    instance.on('inst>', load);
    instance.on('mod', moduleFiles);
    instance.on('client', client);

    // init mono module and save in cache
    M.cache.instances.save(instance.Z.name, instance);
}
<|endoftext|>


<commit_before>/*!
 * Module dependencies.
 */
var Collection = require('./collection').Collection,
    Cursor = require('./cursor').Cursor,
    DbCommand = require('./commands/db_command').DbCommand;

/**
 * Allows the user to access the admin functionality of MongoDB
 *
 * @class Represents the Admin methods of MongoDB.
 * @param {Object} db Current db instance we wish to perform Admin operations on.
 * @return {Function} Constructor for Admin type.
 */
function Admin(db) {
  if(!(this instanceof Admin)) return new Admin(db);
  this.db = db;
};

/**
 * Retrieve the server information for the current
 * instance of the db client
 *
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.buildInfo = function(callback) {
  this.serverInfo(callback);
}

/**
 * Retrieve the server information for the current
 * instance of the db client
 *
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api private
 */
Admin.prototype.serverInfo = function(callback) {
  this.db.executeDbAdminCommand({buildinfo:1}, function(err, doc) {
    if(err != null) return callback(err, null);
    return callback(null, doc.documents[0]);
  });
}

/**
 * Retrieve this db's server status.
 *
 * @param {Function} callback returns the server status.
 * @return {null}
 * @api public
 */
Admin.prototype.serverStatus = function(callback) {
  var self = this;

  this.db.executeDbAdminCommand({serverStatus: 1}, function(err, doc) {
    if(err == null && doc.documents[0].ok === 1) {
      callback(null, doc.documents[0]);
    } else {
      if(err) return callback(err, false);
      return callback(self.wrap(doc.documents[0]), false);
    }
  });
};

/**
 * Retrieve the current profiling Level for MongoDB
 *
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.profilingLevel = function(callback) {
  var self = this;

  this.db.executeDbAdminCommand({profile:-1}, function(err, doc) {
    doc = doc.documents[0];

    if(err == null && doc.ok === 1) {
      var was = doc.was;
      if(was == 0) return callback(null, "off");
      if(was == 1) return callback(null, "slow_only");
      if(was == 2) return callback(null, "all");
        return callback(new Error("Error: illegal profiling level value " + was), null);
    } else {
      err != null ? callback(err, null) : callback(new Error("Error with profile command"), null);
    }
  });
};

/**
 * Ping the MongoDB server and retrieve results
 *
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.ping = function(options, callback) {
  // Unpack calls
  var args = Array.prototype.slice.call(arguments, 0);
  callback = args.pop();

  this.db.executeDbAdminCommand({ping: 1}, callback);
}

/**
 * Authenticate against MongoDB
 *
 * @param {String} username The user name for the authentication.
 * @param {String} password The password for the authentication.
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.authenticate = function(username, password, callback) {
  this.db.authenticate(username, password, {authdb: 'admin'}, function(err, doc) {
    return callback(err, doc);
  })
}

/**
 * Logout current authenticated user
 *
 * @param {Object} [options] Optional parameters to the command.
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.logout = function(callback) {
  this.db.logout({authdb: 'admin'},  function(err, doc) {
    return callback(err, doc);
  })
}

/**
 * Add a user to the MongoDB server, if the user exists it will
 * overwrite the current password
 *
 * Options
 *  - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB.
 *
 * @param {String} username The user name for the authentication.
 * @param {String} password The password for the authentication.
 * @param {Object} [options] additional options during update.
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.addUser = function(username, password, options, callback) {
  var args = Array.prototype.slice.call(arguments, 2);
  callback = args.pop();
  options = args.length ? args.shift() : {};

  options.dbName = 'admin';
  // Add user
  this.db.addUser(username, password, options, function(err, doc) {
    return callback(err, doc);
  })
}

/**
 * Remove a user from the MongoDB server
 *
 * Options
 *  - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB.
 *
 * @param {String} username The user name for the authentication.
 * @param {Object} [options] additional options during update.
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.removeUser = function(username, options, callback) {
  var self = this;
  var args = Array.prototype.slice.call(arguments, 1);
  callback = args.pop();
  options = args.length ? args.shift() : {};
  options.dbName = 'admin';

  this.db.removeUser(username, options, function(err, doc) {
    return callback(err, doc);
  })
}

/**
 * Set the current profiling level of MongoDB
 *
 * @param {String} level The new profiling level (off, slow_only, all)
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.setProfilingLevel = function(level, callback) {
  var self = this;
  var command = {};
  var profile = 0;

  if(level == "off") {
    profile = 0;
  } else if(level == "slow_only") {
    profile = 1;
  } else if(level == "all") {
    profile = 2;
  } else {
    return callback(new Error("Error: illegal profiling level value " + level));
  }

  // Set up the profile number
  command['profile'] = profile;

  this.db.executeDbAdminCommand(command, function(err, doc) {
    doc = doc.documents[0];

    if(err == null && doc.ok === 1)
      return callback(null, level);
    return err != null ? callback(err, null) : callback(new Error("Error with profile command"), null);
  });
};

/**
 * Retrive the current profiling information for MongoDB
 *
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.profilingInfo = function(callback) {
  try {
    new Cursor(this.db, new Collection(this.db, DbCommand.SYSTEM_PROFILE_COLLECTION), {}, null, null, null
      , null, null, null, null, null, null, null, null, null, null
      , null, null, null, null, null, null, null, null, 'admin').toArray(function(err, items) {
        return callback(err, items);
    });
  } catch (err) {
    return callback(err, null);
  }
};

/**
 * Execute a db command against the Admin database
 *
 * @param {Object} command A command object `{ping:1}`.
 * @param {Object} [options] Optional parameters to the command.
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.command = function(command, options, callback) {
  var self = this;
  var args = Array.prototype.slice.call(arguments, 1);
  callback = args.pop();
  options = args.length ? args.shift() : {};

  // Execute a command
  this.db.executeDbAdminCommand(command, options, function(err, doc) {
    // Ensure change before event loop executes
    return callback != null ? callback(err, doc) : null;
  });
}

/**
 * Validate an existing collection
 *
 * @param {String} collectionName The name of the collection to validate.
 * @param {Object} [options] Optional parameters to the command.
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.validateCollection = function(collectionName, options, callback) {
  var args = Array.prototype.slice.call(arguments, 1);
  callback = args.pop();
  options = args.length ? args.shift() : {};

  var self = this;
  var command = {validate: collectionName};
  var keys = Object.keys(options);

  // Decorate command with extra options
  for(var i = 0; i < keys.length; i++) {
    if(options.hasOwnProperty(keys[i])) {
      command[keys[i]] = options[keys[i]];
    }
  }

  this.db.executeDbCommand(command, function(err, doc) {
    if(err != null) return callback(err, null);
    doc = doc.documents[0];

    if(doc.ok === 0)
      return callback(new Error("Error with validate command"), null);
    if(doc.result != null && doc.result.constructor != String)
      return callback(new Error("Error with validation data"), null);
    if(doc.result != null && doc.result.match(/exception|corrupt/) != null)
      return callback(new Error("Error: invalid collection " + collectionName), null);
    if(doc.valid != null && !doc.valid)
      return callback(new Error("Error: invalid collection " + collectionName), null);

    return callback(null, doc);
  });
};

/**
 * List the available databases
 *
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.listDatabases = function(callback) {
  // Execute the listAllDatabases command
  this.db.executeDbAdminCommand({listDatabases:1}, {}, function(err, doc) {
    if(err != null) return callback(err, null);
    return callback(null, doc.documents[0]);
  });
}

/**
 * Get ReplicaSet status
 *
 * @param {Function} callback returns the replica set status (if available).
 * @return {null}
 * @api public
 */
Admin.prototype.replSetGetStatus = function(callback) {
  var self = this;

  this.db.executeDbAdminCommand({replSetGetStatus:1}, function(err, doc) {
    if(err == null && doc.documents[0].ok === 1)
      return callback(null, doc.documents[0]);
    if(err) return callback(err, false);
    return callback(self.db.wrap(doc.documents[0]), false);
  });
};

/**
 * @ignore
 */
exports.Admin = Admin;
<commit_msg>fix Admin.serverStatus making wrong wrap call<commit_after>/*!
 * Module dependencies.
 */
var Collection = require('./collection').Collection,
    Cursor = require('./cursor').Cursor,
    DbCommand = require('./commands/db_command').DbCommand;

/**
 * Allows the user to access the admin functionality of MongoDB
 *
 * @class Represents the Admin methods of MongoDB.
 * @param {Object} db Current db instance we wish to perform Admin operations on.
 * @return {Function} Constructor for Admin type.
 */
function Admin(db) {
  if(!(this instanceof Admin)) return new Admin(db);
  this.db = db;
};

/**
 * Retrieve the server information for the current
 * instance of the db client
 *
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.buildInfo = function(callback) {
  this.serverInfo(callback);
}

/**
 * Retrieve the server information for the current
 * instance of the db client
 *
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api private
 */
Admin.prototype.serverInfo = function(callback) {
  this.db.executeDbAdminCommand({buildinfo:1}, function(err, doc) {
    if(err != null) return callback(err, null);
    return callback(null, doc.documents[0]);
  });
}

/**
 * Retrieve this db's server status.
 *
 * @param {Function} callback returns the server status.
 * @return {null}
 * @api public
 */
Admin.prototype.serverStatus = function(callback) {
  var self = this;

  this.db.executeDbAdminCommand({serverStatus: 1}, function(err, doc) {
    if(err == null && doc.documents[0].ok === 1) {
      callback(null, doc.documents[0]);
    } else {
      if(err) return callback(err, false);
      return callback(self.db.wrap(doc.documents[0]), false);
    }
  });
};

/**
 * Retrieve the current profiling Level for MongoDB
 *
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.profilingLevel = function(callback) {
  var self = this;

  this.db.executeDbAdminCommand({profile:-1}, function(err, doc) {
    doc = doc.documents[0];

    if(err == null && doc.ok === 1) {
      var was = doc.was;
      if(was == 0) return callback(null, "off");
      if(was == 1) return callback(null, "slow_only");
      if(was == 2) return callback(null, "all");
        return callback(new Error("Error: illegal profiling level value " + was), null);
    } else {
      err != null ? callback(err, null) : callback(new Error("Error with profile command"), null);
    }
  });
};

/**
 * Ping the MongoDB server and retrieve results
 *
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.ping = function(options, callback) {
  // Unpack calls
  var args = Array.prototype.slice.call(arguments, 0);
  callback = args.pop();

  this.db.executeDbAdminCommand({ping: 1}, callback);
}

/**
 * Authenticate against MongoDB
 *
 * @param {String} username The user name for the authentication.
 * @param {String} password The password for the authentication.
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.authenticate = function(username, password, callback) {
  this.db.authenticate(username, password, {authdb: 'admin'}, function(err, doc) {
    return callback(err, doc);
  })
}

/**
 * Logout current authenticated user
 *
 * @param {Object} [options] Optional parameters to the command.
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.logout = function(callback) {
  this.db.logout({authdb: 'admin'},  function(err, doc) {
    return callback(err, doc);
  })
}

/**
 * Add a user to the MongoDB server, if the user exists it will
 * overwrite the current password
 *
 * Options
 *  - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB.
 *
 * @param {String} username The user name for the authentication.
 * @param {String} password The password for the authentication.
 * @param {Object} [options] additional options during update.
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.addUser = function(username, password, options, callback) {
  var args = Array.prototype.slice.call(arguments, 2);
  callback = args.pop();
  options = args.length ? args.shift() : {};

  options.dbName = 'admin';
  // Add user
  this.db.addUser(username, password, options, function(err, doc) {
    return callback(err, doc);
  })
}

/**
 * Remove a user from the MongoDB server
 *
 * Options
 *  - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB.
 *
 * @param {String} username The user name for the authentication.
 * @param {Object} [options] additional options during update.
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.removeUser = function(username, options, callback) {
  var self = this;
  var args = Array.prototype.slice.call(arguments, 1);
  callback = args.pop();
  options = args.length ? args.shift() : {};
  options.dbName = 'admin';

  this.db.removeUser(username, options, function(err, doc) {
    return callback(err, doc);
  })
}

/**
 * Set the current profiling level of MongoDB
 *
 * @param {String} level The new profiling level (off, slow_only, all)
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.setProfilingLevel = function(level, callback) {
  var self = this;
  var command = {};
  var profile = 0;

  if(level == "off") {
    profile = 0;
  } else if(level == "slow_only") {
    profile = 1;
  } else if(level == "all") {
    profile = 2;
  } else {
    return callback(new Error("Error: illegal profiling level value " + level));
  }

  // Set up the profile number
  command['profile'] = profile;

  this.db.executeDbAdminCommand(command, function(err, doc) {
    doc = doc.documents[0];

    if(err == null && doc.ok === 1)
      return callback(null, level);
    return err != null ? callback(err, null) : callback(new Error("Error with profile command"), null);
  });
};

/**
 * Retrive the current profiling information for MongoDB
 *
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.profilingInfo = function(callback) {
  try {
    new Cursor(this.db, new Collection(this.db, DbCommand.SYSTEM_PROFILE_COLLECTION), {}, null, null, null
      , null, null, null, null, null, null, null, null, null, null
      , null, null, null, null, null, null, null, null, 'admin').toArray(function(err, items) {
        return callback(err, items);
    });
  } catch (err) {
    return callback(err, null);
  }
};

/**
 * Execute a db command against the Admin database
 *
 * @param {Object} command A command object `{ping:1}`.
 * @param {Object} [options] Optional parameters to the command.
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.command = function(command, options, callback) {
  var self = this;
  var args = Array.prototype.slice.call(arguments, 1);
  callback = args.pop();
  options = args.length ? args.shift() : {};

  // Execute a command
  this.db.executeDbAdminCommand(command, options, function(err, doc) {
    // Ensure change before event loop executes
    return callback != null ? callback(err, doc) : null;
  });
}

/**
 * Validate an existing collection
 *
 * @param {String} collectionName The name of the collection to validate.
 * @param {Object} [options] Optional parameters to the command.
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.validateCollection = function(collectionName, options, callback) {
  var args = Array.prototype.slice.call(arguments, 1);
  callback = args.pop();
  options = args.length ? args.shift() : {};

  var self = this;
  var command = {validate: collectionName};
  var keys = Object.keys(options);

  // Decorate command with extra options
  for(var i = 0; i < keys.length; i++) {
    if(options.hasOwnProperty(keys[i])) {
      command[keys[i]] = options[keys[i]];
    }
  }

  this.db.executeDbCommand(command, function(err, doc) {
    if(err != null) return callback(err, null);
    doc = doc.documents[0];

    if(doc.ok === 0)
      return callback(new Error("Error with validate command"), null);
    if(doc.result != null && doc.result.constructor != String)
      return callback(new Error("Error with validation data"), null);
    if(doc.result != null && doc.result.match(/exception|corrupt/) != null)
      return callback(new Error("Error: invalid collection " + collectionName), null);
    if(doc.valid != null && !doc.valid)
      return callback(new Error("Error: invalid collection " + collectionName), null);

    return callback(null, doc);
  });
};

/**
 * List the available databases
 *
 * @param {Function} callback Callback function of format `function(err, result) {}`.
 * @return {null} Returns no result
 * @api public
 */
Admin.prototype.listDatabases = function(callback) {
  // Execute the listAllDatabases command
  this.db.executeDbAdminCommand({listDatabases:1}, {}, function(err, doc) {
    if(err != null) return callback(err, null);
    return callback(null, doc.documents[0]);
  });
}

/**
 * Get ReplicaSet status
 *
 * @param {Function} callback returns the replica set status (if available).
 * @return {null}
 * @api public
 */
Admin.prototype.replSetGetStatus = function(callback) {
  var self = this;

  this.db.executeDbAdminCommand({replSetGetStatus:1}, function(err, doc) {
    if(err == null && doc.documents[0].ok === 1)
      return callback(null, doc.documents[0]);
    if(err) return callback(err, false);
    return callback(self.db.wrap(doc.documents[0]), false);
  });
};

/**
 * @ignore
 */
exports.Admin = Admin;
<|endoftext|>


<commit_before>'use strict';

const Persistence = require('./Persistence');

module.exports = function $initPersistence(context, config) {

    const _logger = context.getLogger(context.moduleid);

    _logger.info('Persistence module booting...');

    if (!config.logger) config.logger = _logger;
    if (!config.dispatcher) config.dispatcher = context;

    const persistence = new Persistence(config);

    return new Promise((resolve, reject) => {
        /*
         * Start our ORM framework. We will
         * autoload models from models directory,
         * when ready, we'll get notified.
         */
        persistence.connect().then(orm => {
            context.models = {};

            /*
             * Make all models available under
             * Model User will be available as:
             * context.models.user
             */
            context.provide('models', persistence.collections);

            /**
             * Expose a function to iterate over all registered
             * entities.
             */
            context.provide('iterateModels', persistence.iterateModels);

            /*
             * Export using export name.
             * Model User will be available as:
             * context.models.User
             * Where User is User.exportName
             */
            persistence.export(persistence.collections, context.models);

            _logger.info('Persistence module ready.');
            resolve(persistence);

        }).catch(err => {
            _logError(err);
            reject(err);
        });
    });

    function _logError(err) {
        _logger.error('---------------------');
        _logger.error('ORM ERR');
        _logger.error(err.message);
        _logger.error(err.stack);
        _logger.error('---------------------');
    }
};<commit_msg>fix binding for iterateModels<commit_after>'use strict';

const Persistence = require('./Persistence');

module.exports = function $initPersistence(context, config) {

    const _logger = context.getLogger(context.moduleid);

    _logger.info('Persistence module booting...');

    if (!config.logger) config.logger = _logger;
    if (!config.dispatcher) config.dispatcher = context;

    const persistence = new Persistence(config);

    return new Promise((resolve, reject) => {
        /*
         * Start our ORM framework. We will
         * autoload models from models directory,
         * when ready, we'll get notified.
         */
        persistence.connect().then(orm => {
            context.models = {};

            /*
             * Make all models available under
             * Model User will be available as:
             * context.models.user
             */
            context.provide('models', persistence.collections);

            /**
             * Expose a function to iterate over all registered
             * entities.
             */
            context.provide('iterateModels', persistence.iterateModels.bind(persistence));

            /*
             * Export using export name.
             * Model User will be available as:
             * context.models.User
             * Where User is User.exportName
             */
            persistence.export(persistence.collections, context.models);

            _logger.info('Persistence module ready.');
            resolve(persistence);

        }).catch(err => {
            _logError(err);
            reject(err);
        });
    });

    function _logError(err) {
        _logger.error('---------------------');
        _logger.error('ORM ERR');
        _logger.error(err.message);
        _logger.error(err.stack);
        _logger.error('---------------------');
    }
};<|endoftext|>


<commit_before>var basic = exports;

/**
 * Determine the summation of numbers in a given array
 *
 * @param {Array} collection of numbers
 * @return {Number} sum of numbers in array
 */
basic.addition = function (arr) {
  if (Object.prototype.toString.call(arr) === '[object Array]') {
    var total = 0;
    for (var i = 0 ; i < arr.length ; i++) {
      if (typeof(arr[i]) === 'number')
        total = total + arr[i];
      else
        throw new Error('All elements in array must be numbers');
    }
    return total;
  } else {
    throw new Error('Input must be of type Array');
  }
};

/**
 * Subtracts elements from one another in array.
 *
 * e.g [5,3,1,-1] -> 5 - 3 - 1 - (-1) = 2
 *
 * @param {Array} collection of numbers
 * @return {Number} difference
 */
basic.subtraction = function (arr) {
  if (Object.prototype.toString.call(arr) === '[object Array]') {
    var total = arr[arr.length - 1];
    for (var i = arr.length - 2; i >= 0; i--) {
      if (typeof(arr[i]) === 'number')
        total -= arr[i];
      else
        throw new Error('All elements in array must be numbers');
    }
    return total;
  } else {
    throw new Error('Input must be of type Array');
  }
};

/**
 * Product of all elements in an array
 *
 * @param {Array} collection of numbers
 * @return {Number} product
 */
basic.product = function (arr) {
  if (Object.prototype.toString.call(arr) === '[object Array]') {
    var total = arr[0];
    for (var i = 1; i < arr.length; i++) {
      if (typeof(arr[i]) === 'number')
        total = total * arr[i];
      else
        throw new Error('All elements in array must be numbers');
    }
    return total;
  } else {
    throw new Error('Input must be of type Array');
  }
};

/**
 * Return the square of any value.
 *
 * @param {Number} number
 * @return {Number} square of number
 */
basic.square = function (num) {
  return num * num;
};

/**
 * Calculate the binomial coefficient (n choose k)
 *
 * @param {Number} available choices
 * @param {Number} number chosen
 * @return {Number} number of possible choices
 */
basic.binomial = function(n, k) {

  var arr = [];

  function _binomial(n, k) {
    if(n >= 0 && k === 0) return 1;

    if(n === 0 && k > 0) return 0;

    if(arr[n] && arr[n][k] > 0) return arr[n][k];

    if(!arr[n])
      arr[n] = [];

    return arr[n][k] = _binomial(n - 1, k - 1) + _binomial(n - 1, k);
  }

  return _binomial(n, k);
};

/**
 * Factorial for some integer
 *
 * @param {Number} integer
 * @return {Number} result
 */
basic.factorial = function (num){
  var i = 2, o = 1;
  while (i <= num) {
    o *= i++;
  }
  return o;
};

/**
 * Calculate the greastest common divisor amongst two integers.
 *
 * @param {Number} number A
 * @param {Number} number B
 * @return {Number} greatest common divisor for integers A, B
 */
basic.gcd = function (num1, num2) {
  var result;
  if (num1 > num2) {
    for (var i = 0 ; i <= num2 ; i++) {
      if (num2 % i === 0) {
        if (num1 % i === 0) {
          result = i;
        }
      }
    }
    return result;
  } else if (num2 > num1) {
    for (var j = 0 ; j <= num2 ; j++) {
      if (num1 % j === 0) {
        if (num2 % j === 0) {
          result = j;
        }
      }
    }
    return result;
  } else {
    result = num1 * num2 / num1;
    return result;
  }
};

/**
 * Calculate the least common multiple amongst two integers.
 *
 * @param {Number} number A
 * @param {Number} number B
 * @return {Number} least common multiple for integers A, B
 */
basic.lcm = function (num1, num2) {
  return Math.abs(num1 * num2) / basic.gcd(num1,num2);
};

/**
 * Retrieve a specified quantity of elements from an array, at random.
 *
 * @param {Array} set of values to select from
 * @param {Number} quantity of elements to retrieve
 * @return {Array} random elements
 */
basic.random = function (arr, quant) {
  if (arr.length <= quant){
    throw new Error('Quantity requested exceeds size of array');
  } else if (arr.length === 0){
    throw new Error('Empty array');
  } else {
    return basic.shuffle(arr).slice(0, quant);
  }
};

/**
 * Shuffle an array, in place
 *
 * @param {Array} array to be shuffled
 * @return {Array} shuffled array
 */
basic.shuffle = function (array) {
  var m = array.length, t, i;

  while (m) {
    i = Math.floor(Math.random() * m--);

    t = array[m];
    array[m] = array[i];
    array[i] = t;
  }

  return array;
};

/**
 * Find maximum value in an array
 *
 * @param {Array} array to be traversed
 * @return {Number} maximum value in the array
 */
basic.max = function (array) {
    return Math.max.apply(Math, array);
};

/**
 * Find minimum value in an array
 *
 * @param {Array} array to be traversed
 * @return {Number} minimum value in the array
 */
basic.min = function (array) {
    return Math.min.apply(Math, array);
};

/**
 * Create a range of numbers
 *
 * @param {Number} The start of the range
 * @param {Number} The end of the range
 * @return {Array} An array containing numbers within the range
 */
basic.range = function (start,stop,step) {
  var array, i = 0, len;

  if (arguments.length <= 1) {
    stop = start || 0;
    start = 0;
  }

  step = step || 1;

  if (stop < start) {
    step = 0-Math.abs(step);
  }

  len = Math.max(Math.ceil((stop - start) / step) + 1, 0);

  array = new Array(len);

  while (i < len) {
    array[i++] = start;
    start += step;
  }

  return array;
};
<commit_msg>allowDuplicates option in basic.random<commit_after>var basic = exports;

/**
 * Determine the summation of numbers in a given array
 *
 * @param {Array} collection of numbers
 * @return {Number} sum of numbers in array
 */
basic.addition = function (arr) {
  if (Object.prototype.toString.call(arr) === '[object Array]') {
    var total = 0;
    for (var i = 0 ; i < arr.length ; i++) {
      if (typeof(arr[i]) === 'number')
        total = total + arr[i];
      else
        throw new Error('All elements in array must be numbers');
    }
    return total;
  } else {
    throw new Error('Input must be of type Array');
  }
};

/**
 * Subtracts elements from one another in array.
 *
 * e.g [5,3,1,-1] -> 5 - 3 - 1 - (-1) = 2
 *
 * @param {Array} collection of numbers
 * @return {Number} difference
 */
basic.subtraction = function (arr) {
  if (Object.prototype.toString.call(arr) === '[object Array]') {
    var total = arr[arr.length - 1];
    for (var i = arr.length - 2; i >= 0; i--) {
      if (typeof(arr[i]) === 'number')
        total -= arr[i];
      else
        throw new Error('All elements in array must be numbers');
    }
    return total;
  } else {
    throw new Error('Input must be of type Array');
  }
};

/**
 * Product of all elements in an array
 *
 * @param {Array} collection of numbers
 * @return {Number} product
 */
basic.product = function (arr) {
  if (Object.prototype.toString.call(arr) === '[object Array]') {
    var total = arr[0];
    for (var i = 1; i < arr.length; i++) {
      if (typeof(arr[i]) === 'number')
        total = total * arr[i];
      else
        throw new Error('All elements in array must be numbers');
    }
    return total;
  } else {
    throw new Error('Input must be of type Array');
  }
};

/**
 * Return the square of any value.
 *
 * @param {Number} number
 * @return {Number} square of number
 */
basic.square = function (num) {
  return num * num;
};

/**
 * Calculate the binomial coefficient (n choose k)
 *
 * @param {Number} available choices
 * @param {Number} number chosen
 * @return {Number} number of possible choices
 */
basic.binomial = function(n, k) {

  var arr = [];

  function _binomial(n, k) {
    if(n >= 0 && k === 0) return 1;

    if(n === 0 && k > 0) return 0;

    if(arr[n] && arr[n][k] > 0) return arr[n][k];

    if(!arr[n])
      arr[n] = [];

    return arr[n][k] = _binomial(n - 1, k - 1) + _binomial(n - 1, k);
  }

  return _binomial(n, k);
};

/**
 * Factorial for some integer
 *
 * @param {Number} integer
 * @return {Number} result
 */
basic.factorial = function (num){
  var i = 2, o = 1;
  while (i <= num) {
    o *= i++;
  }
  return o;
};

/**
 * Calculate the greastest common divisor amongst two integers.
 *
 * @param {Number} number A
 * @param {Number} number B
 * @return {Number} greatest common divisor for integers A, B
 */
basic.gcd = function (num1, num2) {
  var result;
  if (num1 > num2) {
    for (var i = 0 ; i <= num2 ; i++) {
      if (num2 % i === 0) {
        if (num1 % i === 0) {
          result = i;
        }
      }
    }
    return result;
  } else if (num2 > num1) {
    for (var j = 0 ; j <= num2 ; j++) {
      if (num1 % j === 0) {
        if (num2 % j === 0) {
          result = j;
        }
      }
    }
    return result;
  } else {
    result = num1 * num2 / num1;
    return result;
  }
};

/**
 * Calculate the least common multiple amongst two integers.
 *
 * @param {Number} number A
 * @param {Number} number B
 * @return {Number} least common multiple for integers A, B
 */
basic.lcm = function (num1, num2) {
  return Math.abs(num1 * num2) / basic.gcd(num1,num2);
};

/**
 * Retrieve a specified quantity of elements from an array, at random.
 *
 * @param {Array} set of values to select from
 * @param {Number} quantity of elements to retrieve
 * @param {Boolean} allow the same number to be returned twice
 * @return {Array} random elements
 */
basic.random = function (arr, quant, allowDuplicates) {
  if (arr.length === 0){
    throw new Error('Empty array');
  } else if (quant > arr.length  && !allowDuplicates){
    throw new Error('Quantity requested exceeds size of array');
  }

  if(allowDuplicates==true) {
    var result = [], i;
    for(i=0; i<quant; i++) {
      result[i] = arr[Math.floor(Math.random() * quant)];
    }
    return result;
  } else {
    return basic.shuffle(arr).slice(0, quant);
  }
};

/**
 * Shuffle an array, in place
 *
 * @param {Array} array to be shuffled
 * @return {Array} shuffled array
 */
basic.shuffle = function (array) {
  var m = array.length, t, i;

  while (m) {
    i = Math.floor(Math.random() * m--);

    t = array[m];
    array[m] = array[i];
    array[i] = t;
  }

  return array;
};

/**
 * Find maximum value in an array
 *
 * @param {Array} array to be traversed
 * @return {Number} maximum value in the array
 */
basic.max = function (array) {
    return Math.max.apply(Math, array);
};

/**
 * Find minimum value in an array
 *
 * @param {Array} array to be traversed
 * @return {Number} minimum value in the array
 */
basic.min = function (array) {
    return Math.min.apply(Math, array);
};

/**
 * Create a range of numbers
 *
 * @param {Number} The start of the range
 * @param {Number} The end of the range
 * @return {Array} An array containing numbers within the range
 */
basic.range = function (start,stop,step) {
  var array, i = 0, len;

  if (arguments.length <= 1) {
    stop = start || 0;
    start = 0;
  }

  step = step || 1;

  if (stop < start) {
    step = 0-Math.abs(step);
  }

  len = Math.max(Math.ceil((stop - start) / step) + 1, 0);

  array = new Array(len);

  while (i < len) {
    array[i++] = start;
    start += step;
  }

  return array;
};
<|endoftext|>


<commit_before>var storage = require('./storage.js');
var Jobs = require('level-jobs');
var log = require('./logger.js');

module.exports = function(worker, maxConcurrent, timeout){

    timeout = (typeof timeout !== 'number' ? 60 : timeout) * 1000;

    var options = {
      maxConcurrency: maxConcurrent||5,
      maxRetries:     5,
      backoff: {
        'randomisationFactor': 0,
        'initialDelay': 10,
        'maxDelay': 300
      }
    };

    var queue   = Jobs(storage.getSublevel('jobs'), worker, options);

    // setTimeout(function(){
    //     var stream = queue.readStream();
    //     stream.on('data', function(d) {
    //       var jobId = d.key;
    //       var work = JSON.parse(d.value);
    //       console.log('pending job id: %s, work: %j', jobId, work.id);
    //     });
    // }, 1000);

    function setError(id, msg, err){
        log.error(msg, {id: id, err: err});
        return storage.set(id, {
            error: {
                error: true,
                err: err,
                message: msg + (err ? ':' + err.message : '')
            }
        });
    }

    function push(id, callback){
        storage.get(id, function(storageError, data){
            if (storageError){
                // console.log('jobs.js', storageError.message/*, storageError.stack*/);
                //"Key not found in database"...?
                return setError(id, 'Something went wrong getting job. Storage error - Code 001:', storageError);
            }

            if (data.state && data.state.queued){
                return (
                    !data.error ?
                        setError(id, 'queueId: '+ data.queueId+' already registered/started') :
                        null
                );
            }

            if (typeof data === 'object' && typeof data.state === 'undefined'){
                data.state = {};
            }
            data.state.queued = Date.now();

            storage.set(id, data, function(err, _data){

                if (err){
                    return setError(id, 'Something went wrong. Storage error - Code 001', err);
                }

                var jobId = queue.push(data, function(err){
                    if (err){
                        console.log('jobs.js Queue.push error: ', err);
                    }
                    if (callback){
                        callback(err);
                    }
                });
            });
        });

    }

    return {
        push: push
    };
};
<commit_msg>formatting and date format<commit_after>var storage = require('./storage.js');
var Jobs = require('level-jobs');
var log = require('./logger.js');

module.exports = function(worker, maxConcurrent, timeout){

    timeout = (typeof timeout !== 'number' ? 60 : timeout) * 1000;

    var options = {
        maxConcurrency: maxConcurrent || 5,
        maxRetries: 5,
        backoff: {
            'randomisationFactor': 0,
            'initialDelay': 10,
            'maxDelay': 300
        }
    };

    var queue   = Jobs(storage.getSublevel('jobs'), worker, options);

    // setTimeout(function(){
    //     var stream = queue.readStream();
    //     stream.on('data', function(d) {
    //       var jobId = d.key;
    //       var work = JSON.parse(d.value);
    //       console.log('pending job id: %s, work: %j', jobId, work.id);
    //     });
    // }, 1000);

    function setError(id, msg, err){
        log.error(msg, {id: id, err: err});
        return storage.set(id, {
            error: {
                error: true,
                err: err,
                message: msg + (err ? ':' + err.message : '')
            }
        });
    }

    function push(id, callback){
        storage.get(id, function(storageError, data){
            if (storageError){
                // console.log('jobs.js', storageError.message/*, storageError.stack*/);
                //"Key not found in database"...?
                return setError(id, 'Something went wrong getting job. Storage error - Code 001:', storageError);
            }

            if (data.state && data.state.queued){
                return (
                    !data.error ?
                        setError(id, 'queueId: '+ data.queueId+' already registered/started') :
                        null
                );
            }

            if (typeof data === 'object' && typeof data.state === 'undefined'){
                data.state = {};
            }
            data.state.queued = new Date();

            storage.set(id, data, function(err, _data){

                if (err){
                    return setError(id, 'Something went wrong. Storage error - Code 001', err);
                }

                var jobId = queue.push(data, function(err){
                    if (err){
                        console.log('jobs.js Queue.push error: ', err);
                    }
                    if (callback){
                        callback(err);
                    }
                });
            });
        });

    }

    return {
        push: push
    };
};
<|endoftext|>


<commit_before>var utils = require('./utils'),
    calculateScale = utils.calculateScale,
    calculateOffset = utils.calculateOffset,
    getDecimalPlaces = utils.getDecimalPlaces,
    MAX_VALUE = Number.MAX_VALUE,
    MIN_VALUE = Number.MIN_VALUE;

exports = module.exports = Line;

/**
 * `Line` Chart
 */

function Line(ctx, data, cfg) {
  var canvas = ctx.canvas;
  this.width = canvas.width;
  this.height = canvas.height;

  this.ctx = ctx;
  this.data = data;
  this.cfg = cfg;

  this.maxSize
    = this.scaleHop
    = this.calculatedScale
    = this.labelHeight
    = this.scaleHeight
    = this.valueBounds
    = this.labelTemplateString
    = this.valueHop
    = this.widestXLable
    = this.xAxisLength
    = this.yAxisPosX
    = this.xAxisPosY
    = void 0;

  this.rotateLabels = 0;

  this.calculateDrawingSizes();

  this.valueBounds = this.getValueBounds();

  this.labelTemplateString = cfg.scaleShowLabels ? cfg.scaleLabel : '';

  if (!cfg.scaleOverride) {
    this.calculatedScale = calculateScale(
      this.scaleHeight,
      this.valueBounds.maxSteps,
      this.valueBounds.minSteps,
      this.valueBounds.maxValue,
      this.valueBounds.minValue,
      this.labelTemplateString
    );
  } else {
    var calculatedScale = this.calculatedScale = {
      steps: cfg.scaleSteps,
      stepValue: cfg.scaleStepWidth,
      graphMin: cfg.scaleStartValue,
      labels: []
    };

    for (var i = 0, l = calculatedScale.steps; i < l; ++i) {
      if (this.labelTemplateString) {
        calculatedScale.labels.push(
          tmpl(
            this.labelTemplateString,
            {
              value: (cfg.scaleStartValue + cfg.scaleStepWidth * 1).toFixed(getDecimalPlaces(cfg.scaleStepWidth))
            }
          )
        );
      }
    }
  }
  this.scaleHop = Math.floor(this.scaleHeight / this.calculatedScale.steps);
  this.calculateXAxisSize();
  this.draw();
}

var proto = Line.prototype;

proto.calculateDrawingSizes = function () {
  var cfg = this.cfg,
      ctx = this.ctx,
      data = this.data,
      labels = data.labels;

  ctx.font = cfg.scaleFontStyle + ' ' + cfg.scaleFontSize + 'px ' + cfg.scaleFontFamily;

  var maxSize = this.maxSize = this.height,
      width = this.width,
      rotateLabels = this.rotateLabels,
      scaleFontSize = this.labelHeight = cfg.scaleFontSize,
      widestXLable = 1,
      i = 0,
      l = labels.length,
      textLength;
  for (var i = 0, l = labels.length; i < l; ++i) {
    textLength = ctx.measureText(labels[i]).width;
    widestXLable = textLength > widestXLable ? textLength : widestXLable;
  }
  if (width / l < widestXLable) {
    rotateLabels = 45;
    if (width / l < Math.cos(rotateLabels) * widestXLable) {
      rotateLabels = 90;
      maxSize -= widestXLable;
    } else {
      maxSize -= Math.sin(rotateLabels) * widestXLable;
    }
  } else {
    maxSize -= scaleFontSize;
  }

  this.widestXLable = widestXLable;
  this.rotateLabels = rotateLabels;
  maxSize -= 5;
  maxSize -= scaleFontSize;
  this.maxSize = maxSize;
  this.scaleHeight = maxSize;
};

proto.getValueBounds = function () {
  var upperValue = MIN_VALUE,
      lowerValue = MAX_VALUE,
      scaleHeight = this.scaleHeight,
      labelHeight = this.labelHeight,
      data = this.data,
      datasets = data.datasets,
      l = datasets.length,
      i = 0, j, d, dl, v;

  for (; i < l; ++i) {
    d = datasets[i].data;
    for (j = 0, dl = d.length; j < dl; ++j) {
      v = d[j];
      if (v > upperValue) {
        upperValue = v;
      }
      if (v < lowerValue) {
        lowerValue = v;
      }
    }
  }

  var maxSteps = Math.floor((scaleHeight / (labelHeight * 0.66)));
  var minSteps = Math.floor((scaleHeight / labelHeight * .5));

  return {
    maxValue: upperValue,
    minValue: lowerValue,
    maxSteps: maxSteps,
    minSteps: minSteps
  };
};

proto.calculateXAxisSize = function () {
  var longestText = 1,
      ctx = this.ctx,
      cfg = this.cfg;

  if (cfg.scaleShowLabels) {
    ctx.font = cfg.scaleFontStyle + ' ' + cfg.scaleFontSize + 'px ' + cfg.scaleFontFamily;
    for (var i = 0, l = this.calculatedScale.labels.length; i < l; ++i) {
      var measuredText = ctx.measureText(this.calculatedScale.labels[i]).width;
      longestText = measuredText > longestText ? measuredText : longestText;
    }
    longestText -= 10;
  }
  this.xAxisLength = this.width - longestText - this.widestXLable;
  this.valueHop = Math.floor(this.xAxisLength / (this.data.labels.length - 1));

  this.yAxisPosX = this.width - this.widestXLable / 2 - this.xAxisLength;
  this.xAxisPosY = this.scaleHeight + cfg.scaleFontSize / 2;
};

proto.drawScale = function () {
  var ctx = this.ctx,
      cfg = this.cfg,
      data = this.data,
      labels = data.labels,
      xAxisPosY = this.xAxisPosY,
      yAxisPosX = this.yAxisPosX,
      xAxisLength = this.xAxisLength,
      valueHop = this.valueHop,
      scaleHop = this.scaleHop,
      width = this.width,
      widestXLable = this.widestXLable,
      calculatedScale = this.calculatedScale,
      scaleGridLineWidth = cfg.scaleGridLineWidth,
      scaleGridLineColor = cfg.scaleGridLineColor,
      scaleShowGridLines = cfg.scaleShowGridLines,
      scaleShowLabels = cfg.scaleShowLabels;

  ctx.lineWidth = cfg.scaleLineWidth;
  ctx.strokeStyle = cfg.scaleLineColor;
  ctx.beginPath();
  ctx.moveTo(width - widestXLable / 2 + 5, xAxisPosY);
  ctx.lineTo(width - widestXLable / 2 - xAxisLength - 5, xAxisPosY);
  ctx.stroke();

  var rotateLabels = this.rotateLabels;

  if (rotateLabels > 0) {
    ctx.save();
    ctx.textAlign = 'right';
  } else {
    ctx.textAlign = 'center';
  }

  ctx.fillStyle = cfg.scaleFontColor;
  for (var i = 0, l = labels.length; i < l; ++i) {
    ctx.save();
    if (rotateLabels > 0) {
      ctx.translate(yAxisPosX + i * valueHop, xAxisPosY + cfg.scaleFontSize);
      ctx.rotate(-(rotateLabels * (Math.PI / 180)));
      ctx.fillText(labels[i], 0, 0);
      ctx.restore();
    } else {
      ctx.fillText(labels[i], yAxisPosX + i * valueHop, xAxisPosY + cfg.scaleFontSize + 3);
    }

    ctx.beginPath();
    ctx.moveTo(yAxisPosX + i * valueHop, xAxisPosY + 3);

    if (scaleShowGridLines && i > 0) {
      ctx.lineWidth = scaleGridLineWidth;
      ctx.strokeStyle = scaleGridLineColor;
      ctx.lineTo(yAxisPosX + i * valueHop, 5);
    } else {
      ctx.lineTo(yAxisPosX + i * valueHop, xAxisPosY + 3);
    }
    ctx.stroke();
  }

  ctx.lineWidth = cfg.scaleLineWidth;
  ctx.strokeStyle = cfg.scaleLineColor;
  ctx.beginPath();
  ctx.moveTo(yAxisPosX, xAxisPosY + 5);
  ctx.lineTo(yAxisPosX, 5);
  ctx.stroke();

  ctx.textAlign = 'right';
  ctx.textBaseline = 'middle';
  for (var j = 0, l = calculatedScale.steps; j < l; ++j) {
    ctx.beginPath();
    ctx.moveTo(yAxisPosX - 3, xAxisPosY - ((j + 1) * scaleHop));
    if (scaleShowGridLines){
      ctx.lineWidth = scaleGridLineWidth;
      ctx.strokeStyle = scaleGridLineColor;
      ctx.lineTo(yAxisPosX + xAxisLength + 5, xAxisPosY - ((j + 1) * scaleHop));
    } else {
      ctx.lineTo(yAxisPosX - 0.5, xAxisPosY - ((j + 1) * scaleHop));
    }

    ctx.stroke();

    // left points
    if (scaleShowLabels){
      ctx.fillText(calculatedScale.labels[j], yAxisPosX - 8, xAxisPosY - ((j + 1) * scaleHop));
    }
  }
};

proto.drawData = function () {
  var ctx = this.ctx,
      cfg = this.cfg,
      data = this.data,
      datasets = data.datasets,
      yAxisPosX = this.yAxisPosX,
      xAxisPosY = this.xAxisPosY,
      valueHop = this.valueHop,
      calculatedScale = this.calculatedScale,
      scaleHop = this.scaleHop,
      bezierCurve = cfg.bezierCurve,
      datasetFill = cfg.datasetFill,
      datasetStrokeWidth = cfg.datasetStrokeWidth,
      pointDot = cfg.pointDot,
      pointDotStrokeWidth = cfg.pointDotStrokeWidth,
      pointDotRadius = cfg.pointDotRadius,
      l = datasets.length, i = 0, j,
      ds, d, dl,
      yPos = function (dataSet, iteration) {
        return xAxisPosY - calculateOffset(datasets[dataSet].data[iteration], calculatedScale, scaleHop);
      },
      xPos = function (iteration) {
        return yAxisPosX + (valueHop * iteration);
      };

  for (; i < l; ++i) {
    ds = datasets[i];
    d = ds.data;
    ctx.strokeStyle = ds.strokeColor;
    ctx.lineWidth = datasetStrokeWidth;
    ctx.beginPath();
    ctx.moveTo(yAxisPosX, xAxisPosY - calculateOffset(d[0], calculatedScale, scaleHop));

    j = 1;
    if (bezierCurve) {
      for (dl = d.length; j < dl; j++) {
        ctx.bezierCurveTo(xPos(j - 0.5), yPos(i, j - 1), xPos(j - 0.5), yPos(i, j), xPos(j), yPos(i, j));
      }
    } else {
      for (dl = d.length; j < dl; j++) {
        ctx.lineTo(xPos(j), yPos(i, j));
      }
    }

    ctx.stroke();
    if (datasetFill) {
      ctx.lineTo(yAxisPosX + (valueHop * (dl - 1)), xAxisPosY);
      ctx.lineTo(yAxisPosX, xAxisPosY);
      ctx.closePath();
      ctx.fillStyle = ds.fillColor;
      ctx.fill();
    } else {
      ctx.closePath();
    }

    if (pointDot) {
      ctx.fillStyle = ds.pointColor;
      ctx.strokeStyle = ds.pointStrokeColor;
      ctx.lineWidth = pointDotStrokeWidth;
      for (var k = 0; k < dl; ++k) {
        ctx.beginPath();
        ctx.arc(yAxisPosX + (valueHop * k), xAxisPosY - calculateOffset(ds.data[k], calculatedScale, scaleHop), pointDotRadius, 0, Math.PI * 2, true);
        ctx.fill();
        ctx.stroke();
      }
    }
  }
};

proto.draw = function () {
  if (this.cfg.scaleOverlay) {
    this.drawData();
    this.drawScale();
  } else {
    this.drawScale();
    this.drawData();
  }
};
<commit_msg>Define tmpl, so creating a Line chart doesn't fail<commit_after>var utils = require('./utils'),
    calculateScale = utils.calculateScale,
    calculateOffset = utils.calculateOffset,
    getDecimalPlaces = utils.getDecimalPlaces,
    tmpl = utils.tmpl,
    MAX_VALUE = Number.MAX_VALUE,
    MIN_VALUE = Number.MIN_VALUE;

exports = module.exports = Line;

/**
 * `Line` Chart
 */

function Line(ctx, data, cfg) {
  var canvas = ctx.canvas;
  this.width = canvas.width;
  this.height = canvas.height;

  this.ctx = ctx;
  this.data = data;
  this.cfg = cfg;

  this.maxSize
    = this.scaleHop
    = this.calculatedScale
    = this.labelHeight
    = this.scaleHeight
    = this.valueBounds
    = this.labelTemplateString
    = this.valueHop
    = this.widestXLable
    = this.xAxisLength
    = this.yAxisPosX
    = this.xAxisPosY
    = void 0;

  this.rotateLabels = 0;

  this.calculateDrawingSizes();

  this.valueBounds = this.getValueBounds();

  this.labelTemplateString = cfg.scaleShowLabels ? cfg.scaleLabel : '';

  if (!cfg.scaleOverride) {
    this.calculatedScale = calculateScale(
      this.scaleHeight,
      this.valueBounds.maxSteps,
      this.valueBounds.minSteps,
      this.valueBounds.maxValue,
      this.valueBounds.minValue,
      this.labelTemplateString
    );
  } else {
    var calculatedScale = this.calculatedScale = {
      steps: cfg.scaleSteps,
      stepValue: cfg.scaleStepWidth,
      graphMin: cfg.scaleStartValue,
      labels: []
    };

    for (var i = 0, l = calculatedScale.steps; i < l; ++i) {
      if (this.labelTemplateString) {
        calculatedScale.labels.push(
          tmpl(
            this.labelTemplateString,
            {
              value: (cfg.scaleStartValue + cfg.scaleStepWidth * 1).toFixed(getDecimalPlaces(cfg.scaleStepWidth))
            }
          )
        );
      }
    }
  }
  this.scaleHop = Math.floor(this.scaleHeight / this.calculatedScale.steps);
  this.calculateXAxisSize();
  this.draw();
}

var proto = Line.prototype;

proto.calculateDrawingSizes = function () {
  var cfg = this.cfg,
      ctx = this.ctx,
      data = this.data,
      labels = data.labels;

  ctx.font = cfg.scaleFontStyle + ' ' + cfg.scaleFontSize + 'px ' + cfg.scaleFontFamily;

  var maxSize = this.maxSize = this.height,
      width = this.width,
      rotateLabels = this.rotateLabels,
      scaleFontSize = this.labelHeight = cfg.scaleFontSize,
      widestXLable = 1,
      i = 0,
      l = labels.length,
      textLength;
  for (var i = 0, l = labels.length; i < l; ++i) {
    textLength = ctx.measureText(labels[i]).width;
    widestXLable = textLength > widestXLable ? textLength : widestXLable;
  }
  if (width / l < widestXLable) {
    rotateLabels = 45;
    if (width / l < Math.cos(rotateLabels) * widestXLable) {
      rotateLabels = 90;
      maxSize -= widestXLable;
    } else {
      maxSize -= Math.sin(rotateLabels) * widestXLable;
    }
  } else {
    maxSize -= scaleFontSize;
  }

  this.widestXLable = widestXLable;
  this.rotateLabels = rotateLabels;
  maxSize -= 5;
  maxSize -= scaleFontSize;
  this.maxSize = maxSize;
  this.scaleHeight = maxSize;
};

proto.getValueBounds = function () {
  var upperValue = MIN_VALUE,
      lowerValue = MAX_VALUE,
      scaleHeight = this.scaleHeight,
      labelHeight = this.labelHeight,
      data = this.data,
      datasets = data.datasets,
      l = datasets.length,
      i = 0, j, d, dl, v;

  for (; i < l; ++i) {
    d = datasets[i].data;
    for (j = 0, dl = d.length; j < dl; ++j) {
      v = d[j];
      if (v > upperValue) {
        upperValue = v;
      }
      if (v < lowerValue) {
        lowerValue = v;
      }
    }
  }

  var maxSteps = Math.floor((scaleHeight / (labelHeight * 0.66)));
  var minSteps = Math.floor((scaleHeight / labelHeight * .5));

  return {
    maxValue: upperValue,
    minValue: lowerValue,
    maxSteps: maxSteps,
    minSteps: minSteps
  };
};

proto.calculateXAxisSize = function () {
  var longestText = 1,
      ctx = this.ctx,
      cfg = this.cfg;

  if (cfg.scaleShowLabels) {
    ctx.font = cfg.scaleFontStyle + ' ' + cfg.scaleFontSize + 'px ' + cfg.scaleFontFamily;
    for (var i = 0, l = this.calculatedScale.labels.length; i < l; ++i) {
      var measuredText = ctx.measureText(this.calculatedScale.labels[i]).width;
      longestText = measuredText > longestText ? measuredText : longestText;
    }
    longestText -= 10;
  }
  this.xAxisLength = this.width - longestText - this.widestXLable;
  this.valueHop = Math.floor(this.xAxisLength / (this.data.labels.length - 1));

  this.yAxisPosX = this.width - this.widestXLable / 2 - this.xAxisLength;
  this.xAxisPosY = this.scaleHeight + cfg.scaleFontSize / 2;
};

proto.drawScale = function () {
  var ctx = this.ctx,
      cfg = this.cfg,
      data = this.data,
      labels = data.labels,
      xAxisPosY = this.xAxisPosY,
      yAxisPosX = this.yAxisPosX,
      xAxisLength = this.xAxisLength,
      valueHop = this.valueHop,
      scaleHop = this.scaleHop,
      width = this.width,
      widestXLable = this.widestXLable,
      calculatedScale = this.calculatedScale,
      scaleGridLineWidth = cfg.scaleGridLineWidth,
      scaleGridLineColor = cfg.scaleGridLineColor,
      scaleShowGridLines = cfg.scaleShowGridLines,
      scaleShowLabels = cfg.scaleShowLabels;

  ctx.lineWidth = cfg.scaleLineWidth;
  ctx.strokeStyle = cfg.scaleLineColor;
  ctx.beginPath();
  ctx.moveTo(width - widestXLable / 2 + 5, xAxisPosY);
  ctx.lineTo(width - widestXLable / 2 - xAxisLength - 5, xAxisPosY);
  ctx.stroke();

  var rotateLabels = this.rotateLabels;

  if (rotateLabels > 0) {
    ctx.save();
    ctx.textAlign = 'right';
  } else {
    ctx.textAlign = 'center';
  }

  ctx.fillStyle = cfg.scaleFontColor;
  for (var i = 0, l = labels.length; i < l; ++i) {
    ctx.save();
    if (rotateLabels > 0) {
      ctx.translate(yAxisPosX + i * valueHop, xAxisPosY + cfg.scaleFontSize);
      ctx.rotate(-(rotateLabels * (Math.PI / 180)));
      ctx.fillText(labels[i], 0, 0);
      ctx.restore();
    } else {
      ctx.fillText(labels[i], yAxisPosX + i * valueHop, xAxisPosY + cfg.scaleFontSize + 3);
    }

    ctx.beginPath();
    ctx.moveTo(yAxisPosX + i * valueHop, xAxisPosY + 3);

    if (scaleShowGridLines && i > 0) {
      ctx.lineWidth = scaleGridLineWidth;
      ctx.strokeStyle = scaleGridLineColor;
      ctx.lineTo(yAxisPosX + i * valueHop, 5);
    } else {
      ctx.lineTo(yAxisPosX + i * valueHop, xAxisPosY + 3);
    }
    ctx.stroke();
  }

  ctx.lineWidth = cfg.scaleLineWidth;
  ctx.strokeStyle = cfg.scaleLineColor;
  ctx.beginPath();
  ctx.moveTo(yAxisPosX, xAxisPosY + 5);
  ctx.lineTo(yAxisPosX, 5);
  ctx.stroke();

  ctx.textAlign = 'right';
  ctx.textBaseline = 'middle';
  for (var j = 0, l = calculatedScale.steps; j < l; ++j) {
    ctx.beginPath();
    ctx.moveTo(yAxisPosX - 3, xAxisPosY - ((j + 1) * scaleHop));
    if (scaleShowGridLines){
      ctx.lineWidth = scaleGridLineWidth;
      ctx.strokeStyle = scaleGridLineColor;
      ctx.lineTo(yAxisPosX + xAxisLength + 5, xAxisPosY - ((j + 1) * scaleHop));
    } else {
      ctx.lineTo(yAxisPosX - 0.5, xAxisPosY - ((j + 1) * scaleHop));
    }

    ctx.stroke();

    // left points
    if (scaleShowLabels){
      ctx.fillText(calculatedScale.labels[j], yAxisPosX - 8, xAxisPosY - ((j + 1) * scaleHop));
    }
  }
};

proto.drawData = function () {
  var ctx = this.ctx,
      cfg = this.cfg,
      data = this.data,
      datasets = data.datasets,
      yAxisPosX = this.yAxisPosX,
      xAxisPosY = this.xAxisPosY,
      valueHop = this.valueHop,
      calculatedScale = this.calculatedScale,
      scaleHop = this.scaleHop,
      bezierCurve = cfg.bezierCurve,
      datasetFill = cfg.datasetFill,
      datasetStrokeWidth = cfg.datasetStrokeWidth,
      pointDot = cfg.pointDot,
      pointDotStrokeWidth = cfg.pointDotStrokeWidth,
      pointDotRadius = cfg.pointDotRadius,
      l = datasets.length, i = 0, j,
      ds, d, dl,
      yPos = function (dataSet, iteration) {
        return xAxisPosY - calculateOffset(datasets[dataSet].data[iteration], calculatedScale, scaleHop);
      },
      xPos = function (iteration) {
        return yAxisPosX + (valueHop * iteration);
      };

  for (; i < l; ++i) {
    ds = datasets[i];
    d = ds.data;
    ctx.strokeStyle = ds.strokeColor;
    ctx.lineWidth = datasetStrokeWidth;
    ctx.beginPath();
    ctx.moveTo(yAxisPosX, xAxisPosY - calculateOffset(d[0], calculatedScale, scaleHop));

    j = 1;
    if (bezierCurve) {
      for (dl = d.length; j < dl; j++) {
        ctx.bezierCurveTo(xPos(j - 0.5), yPos(i, j - 1), xPos(j - 0.5), yPos(i, j), xPos(j), yPos(i, j));
      }
    } else {
      for (dl = d.length; j < dl; j++) {
        ctx.lineTo(xPos(j), yPos(i, j));
      }
    }

    ctx.stroke();
    if (datasetFill) {
      ctx.lineTo(yAxisPosX + (valueHop * (dl - 1)), xAxisPosY);
      ctx.lineTo(yAxisPosX, xAxisPosY);
      ctx.closePath();
      ctx.fillStyle = ds.fillColor;
      ctx.fill();
    } else {
      ctx.closePath();
    }

    if (pointDot) {
      ctx.fillStyle = ds.pointColor;
      ctx.strokeStyle = ds.pointStrokeColor;
      ctx.lineWidth = pointDotStrokeWidth;
      for (var k = 0; k < dl; ++k) {
        ctx.beginPath();
        ctx.arc(yAxisPosX + (valueHop * k), xAxisPosY - calculateOffset(ds.data[k], calculatedScale, scaleHop), pointDotRadius, 0, Math.PI * 2, true);
        ctx.fill();
        ctx.stroke();
      }
    }
  }
};

proto.draw = function () {
  if (this.cfg.scaleOverlay) {
    this.drawData();
    this.drawScale();
  } else {
    this.drawScale();
    this.drawData();
  }
};
<|endoftext|>


<commit_before>var _ = require('lodash');
var eslint = require('eslint');
var ESLINT_CONFIG = require('./eslint_config');
var glob = require('glob');
var path = require('path');

var customRules = {};

var reactRules = require('eslint-plugin-react').rules;

_.defaults(customRules, reactRules);

var convertNameToRuleId = function(item) {
	var baseName = path.basename(item, '.js');

	return 'csf-' + baseName.replace(/_/g, '-');
};

var runLinter = function(contents, file, customRules, config) {
	eslint.linter.defineRules(customRules);

	if (_.isObject(config)) {
		Object.keys(ESLINT_CONFIG).forEach(
			function(item, index) {
				var configItem = _.namespace(config, item);

				_.defaults(configItem, ESLINT_CONFIG[item]);

			}
		);
	}
	else {
		config = ESLINT_CONFIG;
	}

	return eslint.linter.verify(contents, config, file);
};

var globOptions = {
	cwd: __dirname
};

module.exports = function(contents, file, config) {
	glob.sync(
		'./lint_rules/*.js',
		globOptions
	).forEach(
		function(item, index) {
			var id = convertNameToRuleId(item);

			customRules[id] = require(item);
		}
	);

	// eslint.linter.defineRules(customRules);

	return runLinter(contents, file, customRules, config);
};

module.exports.convertNameToRuleId = convertNameToRuleId;
module.exports.eslint = eslint;
module.exports.linter = eslint.linter;
module.exports.runLinter = runLinter;<commit_msg>_.merge is already recursive<commit_after>var _ = require('lodash');
var eslint = require('eslint');
var ESLINT_CONFIG = require('./eslint_config');
var glob = require('glob');
var path = require('path');

var customRules = {};

var reactRules = require('eslint-plugin-react').rules;

_.defaults(customRules, reactRules);

var convertNameToRuleId = function(item) {
	var baseName = path.basename(item, '.js');

	return 'csf-' + baseName.replace(/_/g, '-');
};

var runLinter = function(contents, file, customRules, config) {
	eslint.linter.defineRules(customRules);

	if (_.isObject(config)) {
		config = _.merge({}, ESLINT_CONFIG, config);
	}
	else {
		config = ESLINT_CONFIG;
	}

	return eslint.linter.verify(contents, config, file);
};

var globOptions = {
	cwd: __dirname
};

module.exports = function(contents, file, config) {
	glob.sync(
		'./lint_rules/*.js',
		globOptions
	).forEach(
		function(item, index) {
			var id = convertNameToRuleId(item);

			customRules[id] = require(item);
		}
	);

	// eslint.linter.defineRules(customRules);

	return runLinter(contents, file, customRules, config);
};

module.exports.convertNameToRuleId = convertNameToRuleId;
module.exports.eslint = eslint;
module.exports.linter = eslint.linter;
module.exports.runLinter = runLinter;<|endoftext|>


<commit_before>// The logic to load the javascript file of a package
//////////////////////////////////////////////////////////////////////

function load_module (module, callback) {
  var mod = mods[module.id];
  mod.f = module.f;
  var callbacks = mod.c;
  if (callbacks) {
    callbacks.push(callback);
    if (callbacks.length < 2) {
      load_by_module(mod);
    }
  }
}

// server: 'http://localhost/abc',
// -> http://localhost/abc/<relative>
// @param {string} relative relative module url
function absolutize_url(pathname) {
  var base = NEURON_CONF.path;
  base || err('config.path must be specified');
  base = base.replace('{n}', pathname.length % 3 + 1);
  return path_resolve(base, pathname);
}

// This function should be defined with neuron.config({combo: fn})
// neuron.conf.combo =
// function generateComboURL (mods) {
//     return '../concat/' + mods.map(function (mod) {
//         return '~mod~' + (mod.pkg + '/' + mod.name).replace(/\/|@/g, '~') + '.js';
//     }).join(',');
// }

// Scenarios:
// 1. facade('a/path');
// -> load a/path -> always
// 2. facade('a');
// -> load a.main
// 3. require('a');
// -> deps on a
// 4. require('./path')
// -> deps on a
// 5. require.async('a')
// -> load a.main ->
// 6. require.async('./path')
// -> load a/path
// 7. require.async('b/path'): the entry of a foreign module
// -> forbidden

var pkgs = [];

// Load the script file of a module into the current document
// @param {string} id module identifier
function load_by_module(mod) {
  if (mod.l) {
    return;
  }

  // flag to mark the status that a module has already been loaded
  mod.l = true;

  var isFacade = mod.f;
  var isAsync = mod.a;
  var pkg = mod.pkg;

  // if one of the current package's entries has already been loaded,
  // and if the current module is not an entry(facade or async)
  if (~pkgs.indexOf(pkg)) {
    if (!isFacade && !isAsync) {
      return;
    }
  } else {
    pkgs.push(pkg);
  }

  var loaded = NEURON_CONF.loaded;
  var pathname;

  // is facade ?
  var evidence = isFacade
    // if a facade is loaded, we will push `mod.id` of the facade instead of package id
    // into `loaded`
    ? mod.id
    : pkg;

  if (~loaded.indexOf(evidence)) {
    // If the main entrance of the package is already loaded
    // and the current module is not an async module, skip loading.
    // see: declaration of `require.async`
    if (isAsync) {
      pathname = generate_module_pathname(mod);
    } else {
      return;
    }

    // load packages
  } else {
    var combine = NEURON_CONF.combo;

    if (combine) {
      var modules = get_all_unloaded_sync_deps(
        mod.name,
        mod.version,

        // If is a facade, we should always load it by `mod.id` not `mod.pkg`
        isFacade && removes_leading_slash(mod.path)
      );

      if (modules.length > 1) {
        pathname = combine(modules);
      }

      // `get_all_unloaded_sync_deps` will push loaded.
    } else {
      loaded.push(evidence);
    }

    // If no combine configuration, or there's less than 2 packages,
    // load the package file directly
    pathname = pathname
      || generate_module_pathname(mod);
  }

  load_js(absolutize_url(pathname));
}

function generate_module_pathname(mod) {
  var id = mod.main
    // if is a main module, we will load the source file by package

    // 1.
    // on use: 'a@1.0.0' (async or sync)
    // -> 'a/1.0.0/a.js'

    // 2.
    // on use: 'a@1.0.0/relative' (sync)
    // -> not an async module, so the module is already packaged inside:
    // -> 'a/1.0.0/a.js'
    ? mod.pkg + '/' + mod.name + '.js'

    // if is an async module, we will load the source file by module id
    : mod.id;

  return module_id_to_relative_url_path(id);
}

// 'a@1.0.0/a' -> './a/1.0.0/a.js'
function module_id_to_relative_url_path (id) {
  return './' + id.replace('@', '/');
}
<commit_msg>load: fixes reference bugs; fixes range mapping; #123<commit_after>// The logic to load the javascript file of a package
//////////////////////////////////////////////////////////////////////

function load_module (module, callback) {
  var mod = mods[module.id];
  mod.f = module.f;
  var callbacks = mod.l;
  if (callbacks) {
    callbacks.push(callback);
    if (callbacks.length < 2) {
      load_by_module(mod);
    }
  }
}

// server: 'http://localhost/abc',
// -> http://localhost/abc/<relative>
// @param {string} relative relative module url
function absolutize_url(pathname) {
  var base = NEURON_CONF.path;
  base || err('config.path must be specified');
  base = base.replace('{n}', pathname.length % 3 + 1);
  return path_resolve(base, pathname);
}

// This function should be defined with neuron.config({combo: fn})
// neuron.conf.combo =
// function generateComboURL (mods) {
//     return '../concat/' + mods.map(function (mod) {
//         return '~mod~' + (mod.pkg + '/' + mod.name).replace(/\/|@/g, '~') + '.js';
//     }).join(',');
// }

// Scenarios:
// 1. facade('a/path');
// -> load a/path -> always
// 2. facade('a');
// -> load a.main
// 3. require('a');
// -> deps on a
// 4. require('./path')
// -> deps on a
// 5. require.async('a')
// -> load a.main ->
// 6. require.async('./path')
// -> load a/path
// 7. require.async('b/path'): the entry of a foreign module
// -> forbidden

var pkgs = [];

// Load the script file of a module into the current document
// @param {string} id module identifier
function load_by_module(mod) {
  if (mod.d) {
    return;
  }

  // (D)ownloaded
  // flag to mark the status that a module has already been downloaded
  mod.d = true;

  var isFacade = mod.f;
  var isAsync = mod.a;
  var pkg = mod.pkg;

  // if one of the current package's entries has already been loaded,
  // and if the current module is not an entry(facade or async)
  if (~pkgs.indexOf(pkg)) {
    if (!isFacade && !isAsync) {
      return;
    }
  } else {
    pkgs.push(pkg);
  }

  var loaded = NEURON_CONF.loaded;
  var pathname;

  // is facade ?
  var evidence = isFacade
    // if a facade is loaded, we will push `mod.id` of the facade instead of package id
    // into `loaded`
    ? mod.id
    : pkg;

  if (~loaded.indexOf(evidence)) {
    // If the main entrance of the package is already loaded
    // and the current module is not an async module, skip loading.
    // see: declaration of `require.async`
    if (isAsync) {
      pathname = generate_module_pathname(mod);
    } else {
      return;
    }

    // load packages
  } else {
    var combine = NEURON_CONF.combo;

    if (combine) {
      var modules = get_all_unloaded_sync_deps(
        mod.name,
        mod.version,

        // If is a facade, we should always load it by `mod.id` not `mod.pkg`
        isFacade && removes_leading_slash(mod.path)
      );

      if (modules.length > 1) {
        pathname = combine(modules);
      }

      // `get_all_unloaded_sync_deps` will push loaded.
    } else {
      loaded.push(evidence);
    }

    // If no combine configuration, or there's less than 2 packages,
    // load the package file directly
    pathname = pathname
      || generate_module_pathname(mod);
  }

  load_js(absolutize_url(pathname));
}

function generate_module_pathname(mod) {
  var id = mod.main
    // if is a main module, we will load the source file by package

    // 1.
    // on use: 'a@1.0.0' (async or sync)
    // -> 'a/1.0.0/a.js'

    // 2.
    // on use: 'a@1.0.0/relative' (sync)
    // -> not an async module, so the module is already packaged inside:
    // -> 'a/1.0.0/a.js'
    ? mod.pkg + '/' + mod.name + '.js'

    // if is an async module, we will load the source file by module id
    : mod.id;

  return module_id_to_relative_url_path(id);
}

// 'a@1.0.0/a' -> './a/1.0.0/a.js'
function module_id_to_relative_url_path (id) {
  return './' + id.replace('@', '/');
}
<|endoftext|>