<commit_before>/*
 * Copyright 2014 Basho Technologies, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var Joi = require('joi');
var events = require('events');
var util = require('util');
var RiakConnection = require('./riakconnection');
var LinkedList = require('linkedlist');
var RiakProtobuf = require('../protobuf/riakprotobuf');

function RiakNode(options) {

    events.EventEmitter.call(this);

    var self = this;

    Joi.validate(options, schema, function(err, options) {

        if (err) {
            throw err;
        }

        self.remoteAddress = options.remoteAddress;
        self.remotePort = options.remotePort;
        self.minConnections = options.minConnections;
        self.maxConnections = options.maxConnections;
        self.idleTimeout = options.idleTimeout;
        self.connectionTimeout = options.connectionTimeout;
        self.state = State.CREATED;
    });

    this._available = new LinkedList();
    this._consecutiveConnectFailures = 0;
    this._currentNumConnections = 0;

}

util.inherits(RiakNode, events.EventEmitter);

RiakNode.prototype.start = function() {
    this._stateCheck([State.CREATED]);
    var self = this;

    // Fire up connection pool
    for (i = 0; i < this.minConnections; i++) {

        this._createNewConnection(this._returnConnectionToPool.bind(this),
                                    function(){});
    }

    this._expireTimer = setInterval(function() {
       self._expireIdleConnections.bind(self);
    }, 30000);

    // We actually don't care if the connections have started up yet or not
    this.state = State.RUNNING;
    this.emit('stateChange', this, this.state);
};

RiakNode.prototype._createNewConnection = function(postConnectFunc, postFailFunc) {

    var conn = new RiakConnection({
        remoteAddress : this.remoteAddress,
        remotePort : this.remotePort,
        connectionTimeout : this.connectionTimeout
    });

    var self = this;

    conn.on('connected', function(conn) {
        self._consecutiveConnectFailures = 0;
        self._currentNumConnections++;
        conn.on('responseReceived', self._responseReceived.bind(self));
        conn.on('connectionClosed', self._connectionClosed.bind(self));
        postConnectFunc(conn);
    });

    conn.on('connectFailed', function(){
       self._consecutiveConnectFailures++;
       postFailFunc();
    });

    conn.connect();

};

RiakNode.prototype.stop = function() {
    this._stateCheck([State.RUNNING, State.HEALTH_CHECKING]);

    clearInterval(this._expireTimer);

    while (this._available.next()) {
        var conn = this._available.removeCurrent();
        this._currentNumConnections--;
        conn.close();
    }
    this._available.resetCursor();

    if (this._currentNumConnections === 0) {
        this.state = State.SHUTDOWN;
    } else {
        // There's still connections out and being used
        this.state = State.SHUTTING_DOWN;
    }

    this.emit('stateChange', this, this.state);
};

RiakNode.prototype.execute = function(command) {
    this._stateCheck([State.RUNNING, State.HEALTH_CHECKING]);
    var conn = this._available.shift();
    var self = this;
    // conn will be undefined if there's no available connections.
    if (!conn) {
        if (this._currentNumConnections < this.maxConnections) {

            this._createNewConnection(function(newConn) {
                newConn.execute(command);
            }, function() {
                if (self._consecutiveConnectFailures > 5 &&
                        self.state === State.RUNNING) {
                    self.state = State.HEALTH_CHECKING;
                    setTimeout(self._healthCheck.bind(self), 1000);
                }
                self.emit('operationFailed', self, command);
            });

            return true;

        } else {
            console.log('Riaknode: all connections in use and at max');
            return false;
        }
    } else {
        conn.execute(command);
        return true;
    }

};

RiakNode.prototype._responseReceived = function(conn, command, code, decoded) {

    command.remainingTries--;
    if (code === RiakProtobuf.getCodeFor('RpbErrorResp')) {
        this._returnConnectionToPool(conn);
        console.log('RiakNode: recevied RpbErrorResp for command; ' + decoded.getErrmsg().toString());
        if (command.remainingTries) {
            this.emit('retryCommand', command);
        } else {
            command.onRiakError(decoded);
        }
    } else if (code !== command.getExpectedResponseCode()) {
        // TODO: Nuke connetion here?
        this._returnConnectionToPool(conn);
        var msg = 'Riaknode received wrong reponse; expected ' +
                        command.getExpectedResponseCode() +
                        ' received ' + code;
        if (command.remainingTries) {
            this.emit('retryCommand', command);
        } else {
            command.onError(msg);
        }
    } else {
        var done = command.onSuccess(decoded);
        if (done) {
            console.log('Riaknode: command complete');
            this._returnConnectionToPool(conn);
        }
    }

};

RiakNode.prototype._returnConnectionToPool = function(conn) {

    if (this.state !== State.SHUTTING_DOWN) {
        conn.inFlight = false;
        conn.resetBuffer();
        this._available.unshift(conn);
        console.log("Number of avail connections: " + this._available.length);
    } else {
        this._currentNumConnections--;
        conn.close();
        if (this._currentNumConnections === 0) {
            this.state = State.SHUTDOWN;
            this.emit('stateChange', this, this.state);
        }
    }

};

RiakNode.prototype._connectionClosed = function(conn) {
    this._currentNumConnections--;
    // See if a command was being handled
    console.log("RiakNode: Connection closed; inFlight: " + conn.inFlight);
    if (conn.inFlight) {
        var command = conn.command;
        command.remainingTries--;
        if (command.remainingTries) {
            this.emit('retryCommand', command);
        } else {
            command.callback(msg, null);
        }
    }

    if (this.state === State.SHUTTING_DOWN && this._currentNumConnections === 0) {
        this.state = State.SHUTDOWN;
        this.emit('stateChange', this, this.state);
    }

    // PB connections don't time out. If one disconnects it's highly likely
    // the node went down or there's a network issue
    if (this.state !== State.HEALTH_CHECKING) {
        this.state = State.HEALTH_CHECKING;
        var self = this;
        setTimeout(function() {
            self._healthCheck.bind(self);
        }, 1000);

        this.emit('stateChange', this, this.state);
    }
};

RiakNode.prototype._stateCheck = function(allowedStates) {
    if (allowedStates.indexOf(this.state) === -1) {
        throw "Illegal State; required: " + allowedStates + "current: " + this.state;
    }
};

RiakNode.prototype._healthCheck = function() {

    // TODO: Add ping op instead of just connecting
    var conn = new RiakConnection({
        remoteAddress : this.remoteAddress,
        remotePort : this.remotePort,
        connectionTimeout : this.connectionTimeout
    });

    var self = this;

    conn.on('connected', function(conn) {
        self._currentNumConnections++;
        self._consecutiveConnectFailures = 0;
        conn.on('responseReceived', self._responseReceived.bind(self));
        conn.on('connectionClosed', self._connectionClosed.bind(self));
        self._returnConnectionToPool(conn);
        self.state = State.RUNNING;
        self.emit('stateChange', self, self.state);
    });

    conn.on('connectFailed', function(conn, err) {
        self._consecutiveConnectFailures++;
        setTimeout(self._healthCheck.bind(self), 30000);
    });

    conn.connect();

};

RiakNode.prototype._expireIdleConnecitons = function() {
    var now = Date.now();
    while (this._available.next() && this._currentNumConnections > this.minConnections) {
        if (now - this._available.current >= this.idleTimeout) {
            var conn = this._available.removeCurrent();
            this._currentNumConnections--;
            conn.close();
        }
    }
    this._available.resetCursor();
};

var State = Object.freeze({ CREATED : 0,
                            RUNNING : 1,
                            HEALTH_CHECKING : 2,
                            SHUTTING_DOWN : 3,
                            SHUTDOWN : 4});

var defaultRemoteAddress = "127.0.0.1";
var defaultRemotePort = 8087;
var defaultMinConnections = 1;
var defaultMaxConnections = 10000; // magic number but close enough
var defaultIdleTimeout = 3000;
var defaultConnectionTimeout = 0;

var schema = Joi.object().keys({
    remoteAddress: Joi.string().default(defaultRemoteAddress),
    remotePort: Joi.number().min(1).default(defaultRemotePort),
    minConnections: Joi.number().min(0).default(defaultMinConnections),
    maxConnections: Joi.number().min(0).default(defaultMaxConnections),
    idleTimeout: Joi.number().min(1000).default(defaultIdleTimeout),
    connectionTimeout: Joi.number().min(1).default(defaultConnectionTimeout)
});

module.exports = RiakNode;<commit_msg>Changed _healthCheck to use _createNewConnection<commit_after>/*
 * Copyright 2014 Basho Technologies, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var Joi = require('joi');
var events = require('events');
var util = require('util');
var RiakConnection = require('./riakconnection');
var LinkedList = require('linkedlist');
var RiakProtobuf = require('../protobuf/riakprotobuf');

function RiakNode(options) {

    events.EventEmitter.call(this);

    var self = this;

    Joi.validate(options, schema, function(err, options) {

        if (err) {
            throw err;
        }

        self.remoteAddress = options.remoteAddress;
        self.remotePort = options.remotePort;
        self.minConnections = options.minConnections;
        self.maxConnections = options.maxConnections;
        self.idleTimeout = options.idleTimeout;
        self.connectionTimeout = options.connectionTimeout;
        self.state = State.CREATED;
    });

    this._available = new LinkedList();
    this._consecutiveConnectFailures = 0;
    this._currentNumConnections = 0;

}

util.inherits(RiakNode, events.EventEmitter);

RiakNode.prototype.start = function() {
    this._stateCheck([State.CREATED]);
    var self = this;

    // Fire up connection pool
    for (i = 0; i < this.minConnections; i++) {

        this._createNewConnection(this._returnConnectionToPool.bind(this),
                                    function(){});
    }

    this._expireTimer = setInterval(function() {
       self._expireIdleConnections.bind(self);
    }, 30000);

    // We actually don't care if the connections have started up yet or not
    this.state = State.RUNNING;
    this.emit('stateChange', this, this.state);
};

RiakNode.prototype._createNewConnection = function(postConnectFunc, postFailFunc) {

    var conn = new RiakConnection({
        remoteAddress : this.remoteAddress,
        remotePort : this.remotePort,
        connectionTimeout : this.connectionTimeout
    });

    var self = this;

    conn.on('connected', function(conn) {
        self._consecutiveConnectFailures = 0;
        self._currentNumConnections++;
        conn.on('responseReceived', self._responseReceived.bind(self));
        conn.on('connectionClosed', self._connectionClosed.bind(self));
        postConnectFunc(conn);
    });

    conn.on('connectFailed', function(){
       self._consecutiveConnectFailures++;
       postFailFunc();
    });

    conn.connect();

};

RiakNode.prototype.stop = function() {
    this._stateCheck([State.RUNNING, State.HEALTH_CHECKING]);

    clearInterval(this._expireTimer);

    while (this._available.next()) {
        var conn = this._available.removeCurrent();
        this._currentNumConnections--;
        conn.close();
    }
    this._available.resetCursor();

    if (this._currentNumConnections === 0) {
        this.state = State.SHUTDOWN;
    } else {
        // There's still connections out and being used
        this.state = State.SHUTTING_DOWN;
    }

    this.emit('stateChange', this, this.state);
};

RiakNode.prototype.execute = function(command) {
    this._stateCheck([State.RUNNING, State.HEALTH_CHECKING]);
    var conn = this._available.shift();
    var self = this;
    // conn will be undefined if there's no available connections.
    if (!conn) {
        if (this._currentNumConnections < this.maxConnections) {

            this._createNewConnection(function(newConn) {
                newConn.execute(command);
            }, function() {
                if (self._consecutiveConnectFailures > 5 &&
                        self.state === State.RUNNING) {
                    self.state = State.HEALTH_CHECKING;
                    setTimeout(self._healthCheck.bind(self), 1000);
                }
                self.emit('operationFailed', self, command);
            });

            return true;

        } else {
            console.log('Riaknode: all connections in use and at max');
            return false;
        }
    } else {
        conn.execute(command);
        return true;
    }

};

RiakNode.prototype._responseReceived = function(conn, command, code, decoded) {

    command.remainingTries--;
    if (code === RiakProtobuf.getCodeFor('RpbErrorResp')) {
        this._returnConnectionToPool(conn);
        console.log('RiakNode: recevied RpbErrorResp for command; ' + decoded.getErrmsg().toString());
        if (command.remainingTries) {
            this.emit('retryCommand', command);
        } else {
            command.onRiakError(decoded);
        }
    } else if (code !== command.getExpectedResponseCode()) {
        // TODO: Nuke connetion here?
        this._returnConnectionToPool(conn);
        var msg = 'Riaknode received wrong reponse; expected ' +
                        command.getExpectedResponseCode() +
                        ' received ' + code;
        if (command.remainingTries) {
            this.emit('retryCommand', command);
        } else {
            command.onError(msg);
        }
    } else {
        var done = command.onSuccess(decoded);
        if (done) {
            console.log('Riaknode: command complete');
            this._returnConnectionToPool(conn);
        }
    }

};

RiakNode.prototype._returnConnectionToPool = function(conn) {

    if (this.state !== State.SHUTTING_DOWN) {
        conn.inFlight = false;
        conn.resetBuffer();
        this._available.unshift(conn);
        console.log("Number of avail connections: " + this._available.length);
    } else {
        this._currentNumConnections--;
        conn.close();
        if (this._currentNumConnections === 0) {
            this.state = State.SHUTDOWN;
            this.emit('stateChange', this, this.state);
        }
    }

};

RiakNode.prototype._connectionClosed = function(conn) {
    this._currentNumConnections--;
    // See if a command was being handled
    console.log("RiakNode: Connection closed; inFlight: " + conn.inFlight);
    if (conn.inFlight) {
        var command = conn.command;
        command.remainingTries--;
        if (command.remainingTries) {
            this.emit('retryCommand', command);
        } else {
            command.callback(msg, null);
        }
    }

    if (this.state === State.SHUTTING_DOWN && this._currentNumConnections === 0) {
        this.state = State.SHUTDOWN;
        this.emit('stateChange', this, this.state);
    }

    // PB connections don't time out. If one disconnects it's highly likely
    // the node went down or there's a network issue
    if (this.state !== State.HEALTH_CHECKING) {
        this.state = State.HEALTH_CHECKING;
        var self = this;
        setTimeout(function() {
            self._healthCheck.bind(self);
        }, 1000);

        this.emit('stateChange', this, this.state);
    }
};

RiakNode.prototype._stateCheck = function(allowedStates) {
    if (allowedStates.indexOf(this.state) === -1) {
        throw "Illegal State; required: " + allowedStates + "current: " + this.state;
    }
};

RiakNode.prototype._healthCheck = function() {

    // TODO: Add ping op instead of just connecting
    var self = this;

    this._createNewConnection(function(newConn) {
        self._returnConnectionToPool(newConn);
        self.state = State.RUNNING;
        self.emit('stateChange', self, self.state);
    }, function() {
        setTimeout(self._healthCheck.bind(self), 30000);
    });
};

RiakNode.prototype._expireIdleConnecitons = function() {
    var now = Date.now();
    while (this._available.next() && this._currentNumConnections > this.minConnections) {
        if (now - this._available.current >= this.idleTimeout) {
            var conn = this._available.removeCurrent();
            this._currentNumConnections--;
            conn.close();
        }
    }
    this._available.resetCursor();
};

var State = Object.freeze({ CREATED : 0,
                            RUNNING : 1,
                            HEALTH_CHECKING : 2,
                            SHUTTING_DOWN : 3,
                            SHUTDOWN : 4});

var defaultRemoteAddress = "127.0.0.1";
var defaultRemotePort = 8087;
var defaultMinConnections = 1;
var defaultMaxConnections = 10000; // magic number but close enough
var defaultIdleTimeout = 3000;
var defaultConnectionTimeout = 0;

var schema = Joi.object().keys({
    remoteAddress: Joi.string().default(defaultRemoteAddress),
    remotePort: Joi.number().min(1).default(defaultRemotePort),
    minConnections: Joi.number().min(0).default(defaultMinConnections),
    maxConnections: Joi.number().min(0).default(defaultMaxConnections),
    idleTimeout: Joi.number().min(1000).default(defaultIdleTimeout),
    connectionTimeout: Joi.number().min(1).default(defaultConnectionTimeout)
});

module.exports = RiakNode;<|endoftext|>


<commit_before>'use strict';

const sysPath = require('path');
const fs = require('fs');
const mediator = require('../mediator');
const modules = require('./modules');
const explore = require('./explore');
const helpers = require('./helpers');

const dir = sysPath.dirname(sysPath.dirname(require.resolve('.')));
const readFile = (path, callback) => fs.readFile(path, {encoding: 'utf8'}, callback);

const wrapInModule = (filePath, opts) => new Promise((resolve, reject) => {
  if (opts == null) opts = {};
  if (opts.paths == null) {
    const ref = process.env.NODE_PATH;
    opts.paths = (ref != null ? ref.split(':') : void 0) || [];
  }
  if (opts.basedir == null) opts.basedir = process.cwd();

  filePath = sysPath.resolve(opts.basedir, filePath);

  return readFile(filePath, (err, src) => {
    if (err) return reject(err);
    modules.cacheMain(filePath).then(() => resolve(modules.generateModule(filePath, src)));
  });
});

const brunchRe = /brunch/;

const needsProcessing = file => file.path.indexOf('node_modules') !== -1 &&
  (file.path.indexOf('.js') !== -1 || file.path.indexOf('.json') !== -1) &&
  !brunchRe.test(file.path) &&
  helpers.isPackage(file.path) ||
  exports.isNpm(file.path);

exports.exploreDeps = explore;
exports.wrapInModule = wrapInModule;
exports.loadInit = require('./init');
exports.needsProcessing = needsProcessing;
exports.processFiles = require('./process');

exports.isShim = path => path.indexOf(dir) === 0;
exports.isNpm = path => {
  if (!mediator.npmIsEnabled) return false;
  return path.indexOf('node_modules') >= 0 &&
    !brunchRe.test(path) && path.indexOf('.css') === -1 &&
    helpers.isPackage(path) ||
    path.indexOf(dir) === 0;
};

exports.isNpmJSON = path => {
  return exports.isNpm(path) && path.indexOf('.json') !== -1;
};

// exports.init = require('./init');
// exports.process = require('./process');
<commit_msg>Fix deppack grouping for shims issue caused by b4dcb83<commit_after>'use strict';

const sysPath = require('path');
const fs = require('fs');
const mediator = require('../mediator');
const modules = require('./modules');
const explore = require('./explore');
const helpers = require('./helpers');

const dir = sysPath.dirname(sysPath.dirname(require.resolve('..')));
const readFile = (path, callback) => fs.readFile(path, {encoding: 'utf8'}, callback);

const wrapInModule = (filePath, opts) => new Promise((resolve, reject) => {
  if (opts == null) opts = {};
  if (opts.paths == null) {
    const ref = process.env.NODE_PATH;
    opts.paths = (ref != null ? ref.split(':') : void 0) || [];
  }
  if (opts.basedir == null) opts.basedir = process.cwd();

  filePath = sysPath.resolve(opts.basedir, filePath);

  return readFile(filePath, (err, src) => {
    if (err) return reject(err);
    modules.cacheMain(filePath).then(() => resolve(modules.generateModule(filePath, src)));
  });
});

const brunchRe = /brunch/;

const needsProcessing = file => file.path.indexOf('node_modules') !== -1 &&
  (file.path.indexOf('.js') !== -1 || file.path.indexOf('.json') !== -1) &&
  !brunchRe.test(file.path) &&
  helpers.isPackage(file.path) ||
  exports.isNpm(file.path);

exports.exploreDeps = explore;
exports.wrapInModule = wrapInModule;
exports.loadInit = require('./init');
exports.needsProcessing = needsProcessing;
exports.processFiles = require('./process');

exports.isShim = path => path.indexOf(dir) === 0;
exports.isNpm = path => {
  if (!mediator.npmIsEnabled) return false;
  return path.indexOf('node_modules') >= 0 &&
    !brunchRe.test(path) && path.indexOf('.css') === -1 &&
    helpers.isPackage(path) ||
    path.indexOf(dir) === 0;
};

exports.isNpmJSON = path => {
  return exports.isNpm(path) && path.indexOf('.json') !== -1;
};

// exports.init = require('./init');
// exports.process = require('./process');
<|endoftext|>


<commit_before>/*
 * @copyright Copyright (c) Sematext Group, Inc. - All Rights Reserved
 *
 * @licence SPM for Docker is free-to-use, proprietary software.
 * THIS IS PROPRIETARY SOURCE CODE OF Sematext Group, Inc. (Sematext)
 * This source code may not be copied, reverse engineered, or altered for any purpose.
 * This source code is to be used exclusively by users and customers of Sematext.
 * Please see the full license (found in LICENSE in this distribution) for details on its license and the licenses of its dependencies.
 */
var stats = require('docker-stats')
var flatten = require('flat')
var through = require('through2')
var Aggregator = require('./aggregator.js')
var SpmAgent = require('spm-agent')
var config = SpmAgent.Config
var statsCallBackFuntion = null

var opts = {
  docker: null, //  here goes options for Dockerode
  events: null,  //  an instance of docker-allcontainers
  matchByName: process.env.SPM_MATCH_BY_NAME,
  matchByImage: process.env.SPM_MATCH_BY_IMAGE,
  skipByName: process.env.SPM_SKIP_BY_NAME,
  skipByImage: process.env.SPM_SKIP_BY_IMAGE
}
// holds aggregation object for each container
var cMetrics = {}
var counter = require('measured').createCollection()

function processStats (chunk, enc, cb) {
  var stats = flatten(chunk.stats)
  var metric = {}
  if (process.env.spmagent_logger__level === 'silly') {
    console.log(stats)
  }
  counter.meter('requestsPerSecond').mark()
  if (cMetrics[chunk.id] === undefined) {
    cMetrics[chunk.id] = new Aggregator()
  }
  metric.name = chunk.name
  metric.dockerId = chunk.id
  metric.image = chunk.image
  var agg = cMetrics[chunk.id]
  agg.info = metric
  metrics.forEach(function (key) {
    var value = stats[key] || 0
    if (/service_time_/i.test(key) || /wait_time_/i.test(key)) {
      // micro seconds to ms
      value = value / (1000 * 1000)
    }
    agg.update(stats['read'], key, value, useDivForAggregation[key] || false)
  })
  // setTimeout (cb, 10)
  cb()
}

function getDockerStats (dockerStatsCallback) {
  var dockerStatsStream = stats(opts)
  dockerStatsStream.pipe(through.obj(processStats))
  dockerStatsStream.on('closed', function () {
    console.log('docker stats stream closed')
    // process.exit()
  })
  dockerStatsStream.once('error', function (err) {
    console.log('docker stats stream error:' + err)
    // try to reconnect
    setTimeout (function () {
      getDockerStats(dockerStatsCallback)
    }, 15000)
    try {
      dockerStatsStream.close()
    } catch (ex) {
      console.log (ex)
    }
  })
}

function getStatsForContainer (container, aggStats) {
  var agg = cMetrics[container]
  if (!agg) {
    return null
  }
  var values = []
  aggStats.forEach(function (key) {
    var metricStats = agg.get(key)
    metricStats.id = container
    values.push(metricStats)
  })
  agg.reset()
  return values
}

var cpuMetrics = [
  // CPU
  // 'cpu_stats.cpu_usage.total_usage',
  // 'cpu_stats.cpu_usage.percpu_usage.0',
  // 'cpu_stats.cpu_usage.usage_in_kernelmode',
  // 'cpu_stats.cpu_usage.usage_in_usermode',
  'cpu_stats.cpu_usage.cpu_percent',
  // 'cpu_stats.system_cpu_usage',
  // 'cpu_stats.throttling_data.periods',
  // 'cpu_stats.throttling_data.throttled_periods',
  'cpu_stats.throttling_data.throttled_time'
]

var networkMetrics = [
  // NETWORK
  'network.rx_bytes',
  'network.rx_packets',
  'network.rx_errors',
  'network.rx_dropped',
  'network.tx_bytes',
  'network.tx_packets',
  'network.tx_errors',
  'network.tx_dropped'
]

var memoryMetrics = [
  // MEMORY
  'memory_stats.usage',
  'memory_stats.limit',
  'memory_stats.failcnt',
  // 'memory_stats.max_usage',
  // 'memory_stats.active_anon',
  // 'memory_stats.active_file',
  // 'memory_stats.cache',
  // 'memory_stats.hierarchical_memory_limit',
  // 'memory_stats.inactive_anon',
  // 'memory_stats.inactive_file',
  // 'memory_stats.mapped_file',
  'memory_stats.stats.pgfault',
  // 'memory_stats.pgmajfault',
  'memory_stats.stats.pgpgin',
  'memory_stats.stats.pgpgout'
  // 'memory_stats.ss',
  // 'memory_stats.rss_huge',
  // MEMORY FAIL COUNTER

  // MEMORY LIMIT

// MEMORY TOTAL
// 'memory_stats.total_active_anon',
// 'memory_stats.total_active_file',
// 'memory_stats.total_cache',
// 'memory_stats.total_inactive_anon',
// 'memory_total_inactive_file',
// 'memory_stats.total_mapped_file',
// 'memory_stats.total_pgfault',
// 'memory_stats.total_pgmajfault',
// 'memory_stats.total_pgpgin',
// 'memory_stats.total_pgpgout',
// 'memory_stats.total_rss',
// 'memory_stats.total_rss_huge',
// 'memory_stats.total_unevictable',
// 'memory_stats.stats.total_writeback',
// 'memory_stats.unevictable',
// 'memory_stats.writeback'
]

var ioMetrics = [
  // IO STATS
  // READ
  'blkio_stats.io_service_bytes_recursive.0.value',
  // READ time
  'blkio_stats.io_service_time_recursive.0.value',
  // READ wait time
  'blkio_stats.io_wait_time_recursive.0.value',
  // WRITE
  'blkio_stats.io_service_bytes_recursive.1.value',
  // Write time
  'blkio_stats.io_service_time_recursive.1.value',
  // Write wait time
  'blkio_stats.io_wait_time_recursive.1.value'
// 'blkio_io_service_bytes_recursive',
// 'blkio_io_serviced_recursive',
// 'blkio_io_queue_recursive',
// 'blkio_io_service_time_recursive',
// 'blkio_io_wait_time_recursive',
// 'blkio_io_merged_recursive',
// 'blkio_io_time_recursive',
// 'blkio_sectors_recursive'
]
var metrics = []
metrics = metrics.concat(cpuMetrics).concat(networkMetrics).concat(memoryMetrics).concat(ioMetrics)
var avgAggregation = {
  'cpu_stats.cpu_usage.cpu_percent': true,
  'cpu_stats.throttling_data.throttled_time': true,
  'memory_stats.usage': true,
  'memory_stats.limit': true,
  // READ time
  'blkio_stats.io_service_time_recursive.0.value': true,
  // READ wait time
  'blkio_stats.io_wait_time_recursive.0.value': true,
  // Write time
  'blkio_stats.io_service_time_recursive.1.value': true,
  // Write wait time
  'blkio_stats.io_wait_time_recursive.1.value': true
}
var useDivForAggregation = {
  'network.rx_bytes': true,
  'network.rx_packets': true,
  'network.rx_errors': true,
  'network.rx_dropped': true,
  'network.tx_bytes': true,
  'network.tx_packets': true,
  'network.tx_errors': true,
  'network.tx_dropped': true,
  'memory_stats.failcnt': true,
  'memory_stats.stats.pgfault': true,
  'memory_stats.stats.pgpgin': true,
  'memory_stats.stats.pgpgout': true,
  'blkio_stats.io_service_bytes_recursive.0.value': true,
  // READ time
  'blkio_stats.io_service_time_recursive.0.value': true,
  // READ wait time
  'blkio_stats.io_wait_time_recursive.0.value': true,
  // WRITE
  'blkio_stats.io_service_bytes_recursive.1.value': true,
  // Write time
  'blkio_stats.io_service_time_recursive.1.value': true,
  // Write wait time
  'blkio_stats.io_wait_time_recursive.1.value': true
}

function getValueAsNum (value) {
  var rv = 0
  if (!isNaN(value)) {
    rv = value
  }
  return rv
}

function getStatsValue (metric) {
  if (avgAggregation[metric.name]) {
    return getValueAsNum(metric.mean)
  } else {
    return getValueAsNum(metric.sum)
  }
}
function dockerStatsCollector (statsCallback) {
  // start streaming docker stats
  getDockerStats()
  var count = 0
  setInterval(function () {
    count++
    var containerCount = 0
    for (var container in cMetrics) {
      containerCount++
      var values = getStatsForContainer(container, metrics)
      if (!values) {
        return statsCallback(null)
      }
      values = values.map(function (v) {
        var rv = getStatsValue(v)
        return rv
      })
      var stats = {dockerId: container, image: cMetrics[container].info.image, name: cMetrics[container].info.name, value: values}
      statsCallback(stats)

      // cMetrics = {}
    }
    statsCallback({type: 'container', name: 'count', value: containerCount})
    if (count > 20) {
      count = 0
      cMetrics = {}
    }
  }, config.collectionInterval)
}

module.exports = dockerStatsCollector
<commit_msg>update counter in each collectionInterval<commit_after>/*
 * @copyright Copyright (c) Sematext Group, Inc. - All Rights Reserved
 *
 * @licence SPM for Docker is free-to-use, proprietary software.
 * THIS IS PROPRIETARY SOURCE CODE OF Sematext Group, Inc. (Sematext)
 * This source code may not be copied, reverse engineered, or altered for any purpose.
 * This source code is to be used exclusively by users and customers of Sematext.
 * Please see the full license (found in LICENSE in this distribution) for details on its license and the licenses of its dependencies.
 */
var stats = require('docker-stats')
var flatten = require('flat')
var through = require('through2')
var Aggregator = require('./aggregator.js')
var SpmAgent = require('spm-agent')
var config = SpmAgent.Config
var statsCallBackFuntion = null

var opts = {
  docker: null, //  here goes options for Dockerode
  events: null,  //  an instance of docker-allcontainers
  matchByName: process.env.SPM_MATCH_BY_NAME,
  matchByImage: process.env.SPM_MATCH_BY_IMAGE,
  skipByName: process.env.SPM_SKIP_BY_NAME,
  skipByImage: process.env.SPM_SKIP_BY_IMAGE
}
// holds aggregation object for each container
var cMetrics = {}
var counter = require('measured').createCollection()

function processStats (chunk, enc, cb) {
  var stats = flatten(chunk.stats)
  var metric = {}
  if (process.env.spmagent_logger__level === 'silly') {
    console.log(stats)
  }
  counter.meter('requestsPerSecond').mark()
  if (cMetrics[chunk.id] === undefined) {
    cMetrics[chunk.id] = new Aggregator()
  }
  metric.name = chunk.name
  metric.dockerId = chunk.id
  metric.image = chunk.image
  var agg = cMetrics[chunk.id]
  agg.info = metric
  metrics.forEach(function (key) {
    var value = stats[key] || 0
    if (/service_time_/i.test(key) || /wait_time_/i.test(key)) {
      // micro seconds to ms
      value = value / (1000 * 1000)
    }
    agg.update(stats['read'], key, value, useDivForAggregation[key] || false)
  })
  // setTimeout (cb, 10)
  cb()
}

function getDockerStats (dockerStatsCallback) {
  var dockerStatsStream = stats(opts)
  dockerStatsStream.pipe(through.obj(processStats))
  dockerStatsStream.on('closed', function () {
    console.log('docker stats stream closed')
    // process.exit()
  })
  dockerStatsStream.once('error', function (err) {
    console.log('docker stats stream error:' + err)
    // try to reconnect
    setTimeout (function () {
      getDockerStats(dockerStatsCallback)
    }, 15000)
    try {
      dockerStatsStream.close()
    } catch (ex) {
      console.log (ex)
    }
  })
}

function getStatsForContainer (container, aggStats) {
  var agg = cMetrics[container]
  if (!agg) {
    return null
  }
  var values = []
  aggStats.forEach(function (key) {
    var metricStats = agg.get(key)
    metricStats.id = container
    values.push(metricStats)
  })
  agg.reset()
  return values
}

var cpuMetrics = [
  // CPU
  // 'cpu_stats.cpu_usage.total_usage',
  // 'cpu_stats.cpu_usage.percpu_usage.0',
  // 'cpu_stats.cpu_usage.usage_in_kernelmode',
  // 'cpu_stats.cpu_usage.usage_in_usermode',
  'cpu_stats.cpu_usage.cpu_percent',
  // 'cpu_stats.system_cpu_usage',
  // 'cpu_stats.throttling_data.periods',
  // 'cpu_stats.throttling_data.throttled_periods',
  'cpu_stats.throttling_data.throttled_time'
]

var networkMetrics = [
  // NETWORK
  'network.rx_bytes',
  'network.rx_packets',
  'network.rx_errors',
  'network.rx_dropped',
  'network.tx_bytes',
  'network.tx_packets',
  'network.tx_errors',
  'network.tx_dropped'
]

var memoryMetrics = [
  // MEMORY
  'memory_stats.usage',
  'memory_stats.limit',
  'memory_stats.failcnt',
  // 'memory_stats.max_usage',
  // 'memory_stats.active_anon',
  // 'memory_stats.active_file',
  // 'memory_stats.cache',
  // 'memory_stats.hierarchical_memory_limit',
  // 'memory_stats.inactive_anon',
  // 'memory_stats.inactive_file',
  // 'memory_stats.mapped_file',
  'memory_stats.stats.pgfault',
  // 'memory_stats.pgmajfault',
  'memory_stats.stats.pgpgin',
  'memory_stats.stats.pgpgout'
  // 'memory_stats.ss',
  // 'memory_stats.rss_huge',
  // MEMORY FAIL COUNTER

  // MEMORY LIMIT

// MEMORY TOTAL
// 'memory_stats.total_active_anon',
// 'memory_stats.total_active_file',
// 'memory_stats.total_cache',
// 'memory_stats.total_inactive_anon',
// 'memory_total_inactive_file',
// 'memory_stats.total_mapped_file',
// 'memory_stats.total_pgfault',
// 'memory_stats.total_pgmajfault',
// 'memory_stats.total_pgpgin',
// 'memory_stats.total_pgpgout',
// 'memory_stats.total_rss',
// 'memory_stats.total_rss_huge',
// 'memory_stats.total_unevictable',
// 'memory_stats.stats.total_writeback',
// 'memory_stats.unevictable',
// 'memory_stats.writeback'
]

var ioMetrics = [
  // IO STATS
  // READ
  'blkio_stats.io_service_bytes_recursive.0.value',
  // READ time
  'blkio_stats.io_service_time_recursive.0.value',
  // READ wait time
  'blkio_stats.io_wait_time_recursive.0.value',
  // WRITE
  'blkio_stats.io_service_bytes_recursive.1.value',
  // Write time
  'blkio_stats.io_service_time_recursive.1.value',
  // Write wait time
  'blkio_stats.io_wait_time_recursive.1.value'
// 'blkio_io_service_bytes_recursive',
// 'blkio_io_serviced_recursive',
// 'blkio_io_queue_recursive',
// 'blkio_io_service_time_recursive',
// 'blkio_io_wait_time_recursive',
// 'blkio_io_merged_recursive',
// 'blkio_io_time_recursive',
// 'blkio_sectors_recursive'
]
var metrics = []
metrics = metrics.concat(cpuMetrics).concat(networkMetrics).concat(memoryMetrics).concat(ioMetrics)
var avgAggregation = {
  'cpu_stats.cpu_usage.cpu_percent': true,
  'cpu_stats.throttling_data.throttled_time': true,
  'memory_stats.usage': true,
  'memory_stats.limit': true,
  // READ time
  'blkio_stats.io_service_time_recursive.0.value': true,
  // READ wait time
  'blkio_stats.io_wait_time_recursive.0.value': true,
  // Write time
  'blkio_stats.io_service_time_recursive.1.value': true,
  // Write wait time
  'blkio_stats.io_wait_time_recursive.1.value': true
}
var useDivForAggregation = {
  'network.rx_bytes': true,
  'network.rx_packets': true,
  'network.rx_errors': true,
  'network.rx_dropped': true,
  'network.tx_bytes': true,
  'network.tx_packets': true,
  'network.tx_errors': true,
  'network.tx_dropped': true,
  'memory_stats.failcnt': true,
  'memory_stats.stats.pgfault': true,
  'memory_stats.stats.pgpgin': true,
  'memory_stats.stats.pgpgout': true,
  'blkio_stats.io_service_bytes_recursive.0.value': true,
  // READ time
  'blkio_stats.io_service_time_recursive.0.value': true,
  // READ wait time
  'blkio_stats.io_wait_time_recursive.0.value': true,
  // WRITE
  'blkio_stats.io_service_bytes_recursive.1.value': true,
  // Write time
  'blkio_stats.io_service_time_recursive.1.value': true,
  // Write wait time
  'blkio_stats.io_wait_time_recursive.1.value': true
}

function getValueAsNum (value) {
  var rv = 0
  if (!isNaN(value)) {
    rv = value
  }
  return rv
}

function getStatsValue (metric) {
  if (avgAggregation[metric.name]) {
    return getValueAsNum(metric.mean)
  } else {
    return getValueAsNum(metric.sum)
  }
}
function dockerStatsCollector (statsCallback) {
  // start streaming docker stats
  getDockerStats()
  var count = 0
  setInterval(function () {
    count++
    var containerCount = 0
    for (var container in cMetrics) {
      containerCount++
      var values = getStatsForContainer(container, metrics)
      if (!values) {
        return statsCallback(null)
      }
      values = values.map(function (v) {
        var rv = getStatsValue(v)
        return rv
      })
      var stats = {dockerId: container, image: cMetrics[container].info.image, name: cMetrics[container].info.name, value: values}
      statsCallback(stats)
    }
    statsCallback({type: 'container', name: 'count', value: containerCount})
    cMetrics = {}
  }, config.collectionInterval)
}

module.exports = dockerStatsCollector
<|endoftext|>


<commit_before>'use strict';

// required components

function flattenPoints(points) {
  var result = [];

  for (var i = 0, p; !!(p = points[i]); i++) {
    result.push(p.x);
    result.push(p.y);
  }

  return result;
}

/**
 * @class Renderer
 *
 * The default renderer used for shapes and connections.
 *
 * @param {Styles} styles
 */
function Renderer(styles) {
  this.CONNECTION_STYLE = styles.style([ 'no-fill' ], { strokeWidth: 5 });
  this.SHAPE_STYLE = styles.style({ fill: 'white', stroke: 'fuchsia', strokeWidth: 2 });
}

Renderer.prototype.drawShape = function drawShape(gfxGroup, data) {
  if (data.width === undefined ||
      data.height === undefined) {

    throw new Error('must specify width and height properties for new shape');
  }

  return gfxGroup.rect(0, 0, data.width, data.height, 10, 10).attr(this.SHAPE_STYLE);
};

Renderer.prototype.drawConnection = function drawConnection(gfxGroup, data) {
  var points = flattenPoints(data.waypoints);
  return gfxGroup.polyline(points).attr(this.CONNECTION_STYLE);
};

Renderer.$inject = ['styles'];

module.exports = Renderer;
module.exports.flattenPoints = flattenPoints;<commit_msg>feat(draw/Renderer): make connections visible<commit_after>'use strict';

// required components

function flattenPoints(points) {
  var result = [];

  for (var i = 0, p; !!(p = points[i]); i++) {
    result.push(p.x);
    result.push(p.y);
  }

  return result;
}

/**
 * @class Renderer
 *
 * The default renderer used for shapes and connections.
 *
 * @param {Styles} styles
 */
function Renderer(styles) {
  this.CONNECTION_STYLE = styles.style([ 'no-fill' ], { strokeWidth: 5, stroke: 'fuchsia' });
  this.SHAPE_STYLE = styles.style({ fill: 'white', stroke: 'fuchsia', strokeWidth: 2 });
}

Renderer.prototype.drawShape = function drawShape(gfxGroup, data) {
  if (data.width === undefined ||
      data.height === undefined) {

    throw new Error('must specify width and height properties for new shape');
  }

  return gfxGroup.rect(0, 0, data.width, data.height, 10, 10).attr(this.SHAPE_STYLE);
};

Renderer.prototype.drawConnection = function drawConnection(gfxGroup, data) {
  var points = flattenPoints(data.waypoints);
  return gfxGroup.polyline(points).attr(this.CONNECTION_STYLE);
};

Renderer.$inject = ['styles'];

module.exports = Renderer;
module.exports.flattenPoints = flattenPoints;<|endoftext|>


<commit_before>module.exports = {
	'env': {
		'amd': false,
		'browser': true,
		'mocha': true,
		'node': true
	},

	'globals': {
		'AUI': true,
		'CKEDITOR': true,
		'Liferay': true,
		'YUI': true,
		'alert': true,
		'confirm': true,
		'submitForm': true,
		'themeDisplay': true
	},

	'rules': {
		'consistent-return': 2,
		'consistent-this': [1, 'instance'],
		'curly': [2, 'all'],
		'dot-notation': 2,
		'new-parens': 2,
		'no-array-constructor': 2,
		'no-caller': 2,
		'no-catch-shadow': 2,
		'no-comma-dangle': 2,
		'no-cond-assign': 2,
		'no-console': 2,
		'no-constant-condition': 2,
		'no-control-regex': 2,
		'no-debugger': 2,
		'no-delete-var': 2,
		'no-dupe-keys': 2,
		'no-empty': 2,
		'no-empty-class': 2,
		'no-empty-label': 2,
		'no-eval': 2,
		'no-ex-assign': 2,
		'no-extend-native': 2,
		'no-extra-boolean-cast': 2,
		'no-extra-strict': 2,
		'no-fallthrough': 2,
		'no-func-assign': 2,
		'no-implied-eval': 2,
		'no-inner-declarations': [2, 'functions'],
		'no-invalid-regexp': 2,
		'no-iterator': 2,
		'no-label-var': 2,
		'no-labels': 2,
		'no-lone-blocks': 2,
		'no-loop-func': 2,
		//'no-multi-spaces': 2,
		'no-multi-str': 2,
		'no-native-reassign': 2,
		'no-negated-in-lhs': 2,
		'no-new-func': 2,
		'no-new-object': 2,
		'no-new-wrappers': 2,
		'no-obj-calls': 2,
		'no-octal': 2,
		'no-octal-escape': 2,
		'no-process-exit': 2,
		'no-proto': 2,
		'no-redeclare': 2,
		'no-regex-spaces': 2,
		'no-return-assign': 2,
		'no-sequences': 2,
		'no-shadow': 0,
		'no-shadow-restricted-names': 2,
		'no-space-before-semi': 2,
		'no-spaced-func': 2,
		'no-sparse-arrays': 2,
		'no-undef': 2,
		'no-undef-init': 2,
		'no-unreachable': 2,
		'no-unused-expressions': 2,
		'no-use-before-define': 0,
		'no-with': 2,
		'no-wrap-func': 2,
		'yoda': 2,
		'quotes': [2, 'single'],
		'semi': [2, 'always'],
		'space-infix-ops': 2,
		'comma-spacing': 2,
		'space-return-throw-case': 2,
		'use-isnan': 2,
		'valid-typeof': 2,
		'no-nested-ternary': 2,
		'radix': 2,
		'brace-style': [2, 'stroustrup'],
		'no-lonely-if': 2,
		'no-else-return': 2,
		'space-after-keywords': [2, 'always'],
		'sort-vars': 2,
		'space-unary-ops': [1, {'words': true, 'nonwords': false}],

		'csf-no-extra-semi': 2,
		'csf-sort-props': 2,
		'csf-sort-requires': 2,
		'csf-no-use-before-define': [2, {'samescope': true}],
		'csf-array-spacing': 2,
		'csf-array-spacing-chars': 2,
		'csf-no-is-prefix': 2,
		'csf-multiple-vars': 2,
		'csf-format-constants': 2,
		'csf-sort-constants': 2,
		'csf-catch-format': 2,
		'csf-catch-arg-name': 2,
		'csf-format-args': 2,
		'csf-format-multiline-vars': 2,

		'no-extra-parens': 0,
		'space-in-brackets': [0, 'never'],
		'block-scoped-var': 2,
		'complexity': [0, 11],
		'default-case': 0,
		'func-names': 0,
		'func-style': [0, 'declaration'],
		'handle-callback-err': 0,
		'max-depth': [0, 4],
		'max-len': [0, 80, 4],
		'max-nested-callbacks': [0, 2],
		'max-params': [0, 3],
		'max-statements': [0, 10],
		'no-bitwise': 0,
		'no-div-regex': 0,
		'no-eq-null': 0,
		'no-floating-decimal': 0,
		'no-mixed-requires': [0, false],
		'no-new-require': 0,
		'no-path-concat': 0,
		'no-plusplus': 0,
		'no-restricted-modules': 0,
		'no-script-url': 0,
		'no-self-compare': 0,
		'no-sync': 0,
		'no-ternary': 0,
		'no-warning-comments': [0, { 'terms': ['todo', 'fixme', 'xxx'], 'location': 'start' }],
		'one-var': 0,
		'quote-props': 0,
		'valid-jsdoc': 0,
		'wrap-iife': 0,
		'wrap-regex': 0,

		'camelcase': 0,
		'new-cap': 0,
		'no-alert': 0,
		'no-new': 0,
		'no-extra-semi': 0,
		'no-underscore-dangle': 0,
		'no-unused-vars': [0, {'vars': 'local', 'args': 'after-used'}],
		'eqeqeq': 0,
		'guard-for-in': 0,
		'strict': 0
	}
};<commit_msg>Expanding spacing rules<commit_after>module.exports = {
	'env': {
		'amd': false,
		'browser': true,
		'mocha': true,
		'node': true
	},

	'globals': {
		'AUI': true,
		'CKEDITOR': true,
		'Liferay': true,
		'YUI': true,
		'alert': true,
		'confirm': true,
		'submitForm': true,
		'themeDisplay': true
	},

	'rules': {
		'consistent-return': 2,
		'consistent-this': [1, 'instance'],
		'curly': [2, 'all'],
		'dot-notation': 2,
		'new-parens': 2,
		'no-array-constructor': 2,
		'no-caller': 2,
		'no-catch-shadow': 2,
		'no-comma-dangle': 2,
		'no-cond-assign': 2,
		'no-console': 2,
		'no-constant-condition': 2,
		'no-control-regex': 2,
		'no-debugger': 2,
		'no-delete-var': 2,
		'no-dupe-keys': 2,
		'no-empty': 2,
		'no-empty-class': 2,
		'no-empty-label': 2,
		'no-eval': 2,
		'no-ex-assign': 2,
		'no-extend-native': 2,
		'no-extra-boolean-cast': 2,
		'no-extra-strict': 2,
		'no-fallthrough': 2,
		'no-func-assign': 2,
		'no-implied-eval': 2,
		'no-inner-declarations': [2, 'functions'],
		'no-invalid-regexp': 2,
		'no-iterator': 2,
		'no-label-var': 2,
		'no-labels': 2,
		'no-lone-blocks': 2,
		'no-loop-func': 2,
		'no-multi-spaces': 2,
		'key-spacing': 2,
		'no-multi-str': 2,
		'no-native-reassign': 2,
		'no-negated-in-lhs': 2,
		'no-new-func': 2,
		'no-new-object': 2,
		'no-new-wrappers': 2,
		'no-obj-calls': 2,
		'no-octal': 2,
		'no-octal-escape': 2,
		'no-process-exit': 2,
		'no-proto': 2,
		'no-redeclare': 2,
		'no-regex-spaces': 2,
		'no-return-assign': 2,
		'no-sequences': 2,
		'no-shadow': 0,
		'no-shadow-restricted-names': 2,
		'no-space-before-semi': 2,
		'no-spaced-func': 2,
		'no-sparse-arrays': 2,
		'no-undef': 2,
		'no-undef-init': 2,
		'no-unreachable': 2,
		'no-unused-expressions': 2,
		'no-use-before-define': 0,
		'no-with': 2,
		'no-wrap-func': 2,
		'yoda': 2,
		'quotes': [2, 'single'],
		'semi': [2, 'always'],
		'space-infix-ops': 2,
		'comma-spacing': 2,
		'space-return-throw-case': 2,
		'use-isnan': 2,
		'valid-typeof': 2,
		'no-nested-ternary': 2,
		'radix': 2,
		'brace-style': [2, 'stroustrup'],
		'no-lonely-if': 2,
		'no-else-return': 2,
		'space-after-keywords': [2, 'always'],
		'sort-vars': 2,
		'space-unary-ops': [1, {'words': true, 'nonwords': false}],

		'csf-no-extra-semi': 2,
		'csf-sort-props': 2,
		'csf-sort-requires': 2,
		'csf-no-use-before-define': [2, {'samescope': true}],
		'csf-array-spacing': 2,
		'csf-array-spacing-chars': 2,
		'csf-no-is-prefix': 2,
		'csf-multiple-vars': 2,
		'csf-format-constants': 2,
		'csf-sort-constants': 2,
		'csf-catch-format': 2,
		'csf-catch-arg-name': 2,
		'csf-format-args': 2,
		'csf-format-multiline-vars': 2,

		'no-extra-parens': 0,
		'space-in-brackets': [0, 'never'],
		'block-scoped-var': 2,
		'complexity': [0, 11],
		'default-case': 0,
		'func-names': 0,
		'func-style': [0, 'declaration'],
		'handle-callback-err': 0,
		'max-depth': [0, 4],
		'max-len': [0, 80, 4],
		'max-nested-callbacks': [0, 2],
		'max-params': [0, 3],
		'max-statements': [0, 10],
		'no-bitwise': 0,
		'no-div-regex': 0,
		'no-eq-null': 0,
		'no-floating-decimal': 0,
		'no-mixed-requires': [0, false],
		'no-new-require': 0,
		'no-path-concat': 0,
		'no-plusplus': 0,
		'no-restricted-modules': 0,
		'no-script-url': 0,
		'no-self-compare': 0,
		'no-sync': 0,
		'no-ternary': 0,
		'no-warning-comments': [0, { 'terms': ['todo', 'fixme', 'xxx'], 'location': 'start' }],
		'one-var': 0,
		'quote-props': 0,
		'valid-jsdoc': 0,
		'wrap-iife': 0,
		'wrap-regex': 0,

		'camelcase': 0,
		'new-cap': 0,
		'no-alert': 0,
		'no-new': 0,
		'no-extra-semi': 0,
		'no-underscore-dangle': 0,
		'no-unused-vars': [0, {'vars': 'local', 'args': 'after-used'}],
		'eqeqeq': 0,
		'guard-for-in': 0,
		'strict': 0
	}
};<|endoftext|>


<commit_before>// TODO:
// - Update comments.
// - Update *removeListener* to support namespaced events - low prio
// - Update *listener* to support namespaced events - low prio

;!function(root) {

  var EventEmitter2 = root.EventEmitter2 = function EventEmitter2(conf) {
    this.initializeEvents(conf);
  };

  EventEmitter2.prototype.initializeEvents = function(conf) {
    conf = conf || {};
    this.setEventDelimiter(conf.delimiter);
    this._eventCaseSensitive = conf.eventCaseSensitive || false;
    this._eventDelimiter = conf.eventDelimiter || '.';
    this._maxListeners = conf.maxListeners === 0 ? 0 : conf.maxListeners || 10;
    this._listeners = {};
    return this;
  }

  EventEmitter2.prototype.addListener = function(event, listener) {
    var me = this;

    // If the listener is not a function throw an error. A listener that is not
    // a function can not be called when an event is emitted and therefor is
    // not allowed to be added.
    if ('function' !== typeof listener) {
      throw new Error('addListener only accepts instances of Function');
    }

    // If *_listeners* is undefined invoke *initializeEvents* to set the
    // default properties.
    if (!me._listeners) me.initializeEvents();

    // Set variables, if they are undefined set default values.
    // PERFORMANCE???
    var delimiter = me._eventDelimiter,
        caseSensative = me._eventCaseSensitive,
        listeners = me._listeners,
        maxListeners = me._maxListeners,
        event = caseSensative ? event.toLowerCase() : event,
        ns, exploreNs = listeners,
        listenToEvent, eventListeners;

    // If an event starts or ends with a delimiter character throw an error.
    // Starting or ending an event with a delimiter character creates empty
    // namespaces which don't work and therefor are not allowed.
    if (event[event.length-1] === delimiter || event[0] === delimiter) {
      me.eventNameError('addListener');
      return false;
    }

    // If the event is namespaced loop through the namespaces, set seperate
    // events for each namespace and set *listenToEvent* to the last
    // namespace to attach the listener function to this event after the loop.
    if (~event.indexOf(delimiter)) {

      // Split the event into a namespace array for looping.
      ns = event.split(delimiter);

      // PERFORMANCE???
      if (ns.some(function(event) { return event === ''; })) {
        me.eventNameError('addListener');
        return false;
      }

      // Loop through the namespaces.
      for (var i = 0, l = ns.length; i < l; i++) {

        // If the event is undefined in *exploreNs* it means it doesn't exist
        // in *listeners* so a new event should be created.
        if (!exploreNs[ns[i]]) {
          exploreNs[ns[i]] = {
              _name: ns[i],
              _fn: [],
              _ns: {}
            };
        }

        // If the loop is at the end set *listenToEvent* to the current
        // namespace - which is the last one - to attach the listener to this
        // event. If the loop is not at the end rebase *exploreNs* to loop the
        // current event's namespaces.
        if (i === ns.length - 1) {
          listenToEvent = exploreNs[ns[i]];
        } else {
          exploreNs = exploreNs[ns[i]]._ns;
        }
      }
    }

    // If the event is not namespaced set the single event and set
    // *listenToEvent* to this event to attach the listener to.
    else {

      // If the event is undefined in *listeners* it means it doesn't exist
      // so a new event should be created.
      if (!listeners[event]) {
        listeners[event] = {
          _name: event,
          _fn: [],
          _ns: {}
        };
      }

      // Set *listenToEvent* to the current event to attach the listener to.
      listenToEvent = listeners[event];
    }

    eventListeners = listenToEvent._fn;

    // Signal that a new listener is being added.
    me.emit('newListener', event, listener);

    // If the max amount of listeners has been reached signal and return to
    // cancel the addition of this new event.
    if (eventListeners.length >= maxListeners) {
      me.emit('maxListeners', event);
      return me;
    }

    // Add the listener to the event.
    eventListeners.push(listener);
    return me;
  };

  EventEmitter2.prototype.on = EventEmitter2.prototype.addListener;

  EventEmitter2.prototype.once = function(event, listener) {
    this.many(event, 1, listener);
    return this;
  };

  EventEmitter2.prototype.many = function(event, ttl, listener) {
    var me = this;

    me.addListener(event, function() {
      if(ttl-- == 0) {
        me.removeListener(event, listener);
      } else {
        listener.apply(null, arguments);
      }
    });

    return me;
  };

  EventEmitter2.prototype.emit = function(event) {
    var me = this,
        args = arguments,
        i = 0,
        delimiter = me._eventDelimiter,
        caseSensitive = me._eventCaseSensitive,
        listeners = me._listeners,
        ns, exploreNs = [listeners], collectedListeners = [],
        invoked = false;

    // If no listeners are defined the emit will not be able to invoke a
    // function. Therefore return *invoked* to exit.
    if (!listeners) return invoked;

    // If an event starts or ends with a delimiter character throw an error.
    // Starting or ending an event with a delimiter character creates empty
    // namespaces which don't work and therefor are not allowed.
    if (event[event.length-1] === delimiter || event[0] === delimiter) {
      me.eventNameError('emit');
      return false;
    }

    // If the event is namespaced loop through the namespaces, find all the
    // listeners for the namespaces and wildcards and add them to the
    // *collectedListeners* array for listener invocation after the loop.
    if (~event.indexOf(delimiter) || event === '*') {

      // Split the event into a namespace array for looping.
      ns = event.split(delimiter);

      // PERFORMANCE???
      if (ns.some(function(event) { return event === ''; })) {
        me.eventNameError('emit');
        return false;
      }

      // Loop through the namespaces.
      for (i = 0; i < ns.length; i++) {

        // While looping through the namespace array loop through *exploreNs*
        // with *i* as well. This is basicaly the same as looping through the
        // the different levels of *events*. *collectedNs* is used to collect
        // all the namespaces that are going to be explored for the next level
        // of *events*.
        var currentNs = ns[i],
            currentExploreNs = exploreNs[i],
            collectedNs = [];

        // Loop through the current level of *events*.
        for (var key1 in currentExploreNs) {

          // Set the current namespace in *events* that is being explored.
          var exploredNs = currentExploreNs[key1],
              name = caseSensitive ? exploredNs._name.toLowerCase() : exploredNs._name;

          // If there is a match for the namespace or a wildcard collect the
          // next level of namespaces or collect the listeners of this
          // particular namespace.
          if (currentNs === '*' || (name === currentNs || name === '*')) {

            // If the loop is at the end collect the listeners for this
            // particular event and add them to the *collectedListeners* array
            // for listener invocation after the loop. If the loop is not at
            // the end collect the next level of namespaces.
            if (i === ns.length - 1) {
              var listeners = exploredNs._fn;
              if (listeners.length > 0) {
                collectedListeners = collectedListeners.concat(listeners);
              }
            } else {
              for (var key2 in exploredNs._ns) {
                collectedNs.push(exploredNs._ns[key2]);
              }
            }
          }
        }

        exploreNs.push(collectedNs);
      }
    }

    // If the event is not namespaced collect all the listeners for this
    // particular event and from the wildcard event and add them to
    // the *collectedListeners* array for listener invocation.
    else if (event !== '*' && event !== 'all' && listeners[event] && listeners[event]._fn.length > 0) {
      if (listeners['*'] && listeners['*']._fn.length > 0) {
        collectedListeners = collectedListeners.concat(listeners['*']._fn);
      }
      collectedListeners = collectedListeners.concat(listeners[event]._fn);
    }

    // If the event is "all" fire all events?
    if (event === 'all') {}

    // Loop through the collected listeners and invoce them.
    for (i = 0, l = collectedListeners.length; i < l; i++) {
      collectedListeners[i].apply(me, args);
      invoked = true;
    }

    // If a listener "all" is defined in *events* invoce its functions.
    if (listeners['all'] && listeners['all']._fn.length > 0){
      for (i = 0, l = listeners['all']._fn.length; i < l; i++) {
        listeners['all']._fn[i].apply(me, args);
        invoked = true;
      }
    }

    return invoked;
  };

  EventEmitter2.prototype.removeListener = function(event, listener) {
    var me = this;

    if(listener && me._listeners[event] && me._listeners[event]._fn) {
      var listeners = me._listeners[event]._fn;

      for(var i = 0, l = listeners.length; i < l; i++) {
        if(listener === listeners[i]) {
          // Break out and return the removed listener.
          return listeners.splice(i, 1);
        }
      }
    } else {
      me._listeners[event] = {};
    }
    return me;
  };

  EventEmitter2.prototype.un = EventEmitter2.prototype.removeListener;

  EventEmitter2.prototype.removeAllListeners = function() {
    this._listeners = {};
    return this;
  };

  EventEmitter2.prototype.setEventDelimiter = function(delimiter) {
    if (delimiter === '*' && delimiter.length === 1) {
      throw new Error('setEventDelimiter doesn\'t accept a "*" (wild-card) character');
    } else {
      this._eventDelimiter = delimiter;
    }
    return this;
  };

  EventEmitter2.prototype.setEventCaseSensitive = function(caseSensative) {
    this._eventCaseSensitive = caseSensative;
    return this;
  };

  EventEmitter2.prototype.setMaxListeners = function(n) {
    this._maxListeners = n;
    return this;
  };

  EventEmitter2.prototype.listeners = function(event) {
    if(this._listeners[event]) {
      return this._listeners[event]._fn;
    } else {
      return false;
    }
  };

  EventEmitter2.prototype.eventNameError = function(fn) {
    throw new Error(fn + ' doesn\'t accept empty namespaces or events starting or ending with a "' + this._eventDelimiter + '" (delimiter) character ');
  };

}(typeof exports === 'undefined' ? window : exports);<commit_msg>instead of doing a function call to check for empty namespaces now check of indexof<commit_after>// TODO:
// - Update comments.
// - Update *removeListener* to support namespaced events - low prio
// - Update *listener* to support namespaced events - low prio

;!function(root) {

  var EventEmitter2 = root.EventEmitter2 = function EventEmitter2(conf) {
    this.initializeEvents(conf);
  };

  EventEmitter2.prototype.initializeEvents = function(conf) {
    conf = conf || {};
    var me = this;
    me.setEventDelimiter(conf.delimiter);
    me._eventCaseSensitive = conf.eventCaseSensitive || false;
    me._eventDelimiter = conf.eventDelimiter || '.';
    me._maxListeners = conf.maxListeners === 0 ? 0 : conf.maxListeners || 10;
    me._listeners = {};
    return me;
  }

  EventEmitter2.prototype.addListener = function(event, listener) {
    var me = this;

    // If the listener is not a function throw an error. A listener that is not
    // a function can not be called when an event is emitted and therefor is
    // not allowed to be added.
    if ('function' !== typeof listener) {
      throw new Error('addListener only accepts instances of Function');
    }

    // If *_listeners* is undefined invoke *initializeEvents* to set the
    // default properties.
    if (!me._listeners) me.initializeEvents();

    // Set variables.
    var delimiter = me._eventDelimiter,
        caseSensative = me._eventCaseSensitive,
        listeners = me._listeners,
        maxListeners = me._maxListeners,
        event = caseSensative ? event.toLowerCase() : event,
        ns, exploreNs = listeners,
        listenToEvent, eventListeners;

    // If an event starts or ends with a delimiter character throw an error.
    // Starting or ending an event with a delimiter character creates empty
    // namespaces which don't work and therefor are not allowed.
    if (event[event.length-1] === delimiter || event[0] === delimiter) {
      me.eventNameError('addListener');
      return false;
    }

    // If the event is namespaced loop through the namespaces, set seperate
    // events for each namespace and set *listenToEvent* to the last
    // namespace to attach the listener function to this event after the loop.
    if (~event.indexOf(delimiter)) {

      // Split the event into a namespace array for looping.
      ns = event.split(delimiter);

      // If an event contains an empty namespace throw an error. Using two or
      // more delimiters like for example ".." is incorrect and therefor not
      // allowed.
      if (~ns.indexOf('')) {
        me.eventNameError('addListener');
        return false;
      }

      // Loop through the namespaces.
      for (var i = 0, l = ns.length; i < l; i++) {

        // If the event is undefined in *exploreNs* it means it doesn't exist
        // in *listeners* so a new event should be created.
        if (!exploreNs[ns[i]]) {
          exploreNs[ns[i]] = {
              _name: ns[i],
              _fn: [],
              _ns: {}
            };
        }

        // If the loop is at the end set *listenToEvent* to the current
        // namespace - which is the last one - to attach the listener to this
        // event. If the loop is not at the end rebase *exploreNs* to loop the
        // current event's namespaces.
        if (i === ns.length - 1) {
          listenToEvent = exploreNs[ns[i]];
        } else {
          exploreNs = exploreNs[ns[i]]._ns;
        }
      }
    }

    // If the event is not namespaced set the single event and set
    // *listenToEvent* to this event to attach the listener to.
    else {

      // If the event is undefined in *listeners* it means it doesn't exist
      // so a new event should be created.
      if (!listeners[event]) {
        listeners[event] = {
          _name: event,
          _fn: [],
          _ns: {}
        };
      }

      // Set *listenToEvent* to the current event to attach the listener to.
      listenToEvent = listeners[event];
    }

    eventListeners = listenToEvent._fn;

    // Signal that a new listener is being added.
    me.emit('newListener', event, listener);

    // If the max amount of listeners has been reached signal and return to
    // cancel the addition of this new event.
    if (eventListeners.length >= maxListeners) {
      me.emit('maxListeners', event);
      return me;
    }

    // Add the listener to the event.
    eventListeners.push(listener);
    return me;
  };

  EventEmitter2.prototype.on = EventEmitter2.prototype.addListener;

  EventEmitter2.prototype.once = function(event, listener) {
    this.many(event, 1, listener);
    return this;
  };

  EventEmitter2.prototype.many = function(event, ttl, listener) {
    var me = this;

    me.addListener(event, function() {
      if(ttl-- == 0) {
        me.removeListener(event, listener);
      } else {
        listener.apply(null, arguments);
      }
    });

    return me;
  };

  EventEmitter2.prototype.emit = function(event) {
    var me = this,
        args = arguments,
        i = 0,
        delimiter = me._eventDelimiter,
        caseSensitive = me._eventCaseSensitive,
        listeners = me._listeners,
        ns, exploreNs = [listeners], collectedListeners = [],
        invoked = false;

    // If no listeners are defined the emit will not be able to invoke a
    // function. Therefore return *invoked* to exit.
    if (!listeners) return invoked;

    // If an event starts or ends with a delimiter character throw an error.
    // Starting or ending an event with a delimiter character creates empty
    // namespaces which don't work and therefor are not allowed.
    if (event[event.length-1] === delimiter || event[0] === delimiter) {
      me.eventNameError('emit');
      return false;
    }

    // If the event is namespaced loop through the namespaces, find all the
    // listeners for the namespaces and wildcards and add them to the
    // *collectedListeners* array for listener invocation after the loop.
    if (~event.indexOf(delimiter) || event === '*') {

      // Split the event into a namespace array for looping.
      ns = event.split(delimiter);

      // If an event contains an empty namespace throw an error. Using two or
      // more delimiters like for example ".." is incorrect and therefor not
      // allowed.
      if (~ns.indexOf('')) {
        me.eventNameError('addListener');
        return false;
      }

      // Loop through the namespaces.
      for (i = 0; i < ns.length; i++) {

        // While looping through the namespace array loop through *exploreNs*
        // with *i* as well. This is basicaly the same as looping through the
        // the different levels of *events*. *collectedNs* is used to collect
        // all the namespaces that are going to be explored for the next level
        // of *events*.
        var currentNs = ns[i],
            currentExploreNs = exploreNs[i],
            collectedNs = [];

        // Loop through the current level of *events*.
        for (var key1 in currentExploreNs) {

          // Set the current namespace in *events* that is being explored.
          var exploredNs = currentExploreNs[key1],
              name = caseSensitive ? exploredNs._name.toLowerCase() : exploredNs._name;

          // If there is a match for the namespace or a wildcard collect the
          // next level of namespaces or collect the listeners of this
          // particular namespace.
          if (currentNs === '*' || (name === currentNs || name === '*')) {

            // If the loop is at the end collect the listeners for this
            // particular event and add them to the *collectedListeners* array
            // for listener invocation after the loop. If the loop is not at
            // the end collect the next level of namespaces.
            if (i === ns.length - 1) {
              var listeners = exploredNs._fn;
              if (listeners.length > 0) {
                collectedListeners = collectedListeners.concat(listeners);
              }
            } else {
              for (var key2 in exploredNs._ns) {
                collectedNs.push(exploredNs._ns[key2]);
              }
            }
          }
        }

        exploreNs.push(collectedNs);
      }
    }

    // If the event is not namespaced collect all the listeners for this
    // particular event and from the wildcard event and add them to
    // the *collectedListeners* array for listener invocation.
    else if (event !== '*' && event !== 'all' && listeners[event] && listeners[event]._fn.length > 0) {
      if (listeners['*'] && listeners['*']._fn.length > 0) {
        collectedListeners = collectedListeners.concat(listeners['*']._fn);
      }
      collectedListeners = collectedListeners.concat(listeners[event]._fn);
    }

    // If the event is "all" fire all events?
    if (event === 'all') {}

    // Loop through the collected listeners and invoke them.
    for (i = 0, l = collectedListeners.length; i < l; i++) {
      collectedListeners[i].apply(me, args);
      invoked = true;
    }

    // If a listener "all" is defined in *events* invoke its functions.
    if (listeners['all'] && listeners['all']._fn.length > 0){
      for (i = 0, l = listeners['all']._fn.length; i < l; i++) {
        listeners['all']._fn[i].apply(me, args);
        invoked = true;
      }
    }

    return invoked;
  };

  EventEmitter2.prototype.removeListener = function(event, listener) {
    var me = this;

    if(listener && me._listeners[event] && me._listeners[event]._fn) {
      var listeners = me._listeners[event]._fn;

      for(var i = 0, l = listeners.length; i < l; i++) {
        if(listener === listeners[i]) {
          // Break out and return the removed listener.
          return listeners.splice(i, 1);
        }
      }
    } else {
      me._listeners[event] = {};
    }
    return me;
  };

  EventEmitter2.prototype.un = EventEmitter2.prototype.removeListener;

  EventEmitter2.prototype.removeAllListeners = function() {
    this._listeners = {};
    return this;
  };

  EventEmitter2.prototype.setEventDelimiter = function(delimiter) {
    if (delimiter === '*' && delimiter.length === 1) {
      throw new Error('setEventDelimiter doesn\'t accept a "*" (wild-card) character');
    } else {
      this._eventDelimiter = delimiter;
    }
    return this;
  };

  EventEmitter2.prototype.setEventCaseSensitive = function(caseSensative) {
    this._eventCaseSensitive = caseSensative;
    return this;
  };

  EventEmitter2.prototype.setMaxListeners = function(n) {
    this._maxListeners = n;
    return this;
  };

  EventEmitter2.prototype.listeners = function(event) {
    if(this._listeners[event]) {
      return this._listeners[event]._fn;
    } else {
      return false;
    }
  };

  EventEmitter2.prototype.eventNameError = function(fn) {
    throw new Error(fn + ' doesn\'t accept empty namespaces or events starting or ending with a "' + this._eventDelimiter + '" (delimiter) character ');
  };

}(typeof exports === 'undefined' ? window : exports);<|endoftext|>


<commit_before>/*
 * xbee-api
 * https://github.com/jouz/xbee-api
 *
 * Copyright (c) 2013 Jan Kolkmeier
 * Licensed under the MIT license.
 */

'use strict';

var assert = require('assert'),
    C = require('./constants');

var frame_builder = module.exports = {
  frameId: 0,
  nextFrameId: function nextFrameId() {
    this.frameId = this.frameId > 0xff ? 1 : ++this.frameId;
    return this.frameId;
  },

  getFrameId: function getFrameId(frame) {
    assert(frame, 'Frame parameter must be supplied');
    var id = frame.id || (frame.id !== 0 && this.nextFrameId()) || frame.id;
    return frame.id = id;
  }
};

// Appends data provided as Array, String, or Buffer
function appendData(data, builder) {
  if(Array.isArray(data)) {
    data = new Buffer(data);
  } else {
    data = new Buffer(data, 'ascii');
  }

  builder.appendBuffer(data);
}

frame_builder[C.FRAME_TYPE.AT_COMMAND] =
frame_builder[C.FRAME_TYPE.AT_COMMAND_QUEUE_PARAMETER_VALUE] = function(frame, builder) {
  builder.appendUInt8(frame.type);
  builder.appendUInt8(this.getFrameId(frame));
  builder.appendString(frame.command, 'ascii');
  appendData(frame.commandParameter, builder);
};

frame_builder[C.FRAME_TYPE.REMOTE_AT_COMMAND_REQUEST] = function(frame, builder) {
  builder.appendUInt8(frame.type);
  builder.appendUInt8(this.getFrameId(frame));
  builder.appendString(frame.destination64 || C.UNKNOWN_64, 'hex');
  builder.appendString(frame.destination16 || C.UNKNOWN_16, 'hex');
  builder.appendUInt8(frame.remoteCommandOptions || 0x02);
  builder.appendString(frame.command, 'ascii');
  appendData(frame.commandParameter, builder);
};

frame_builder[C.FRAME_TYPE.ZIGBEE_TRANSMIT_REQUEST] = function(frame, builder) {
  builder.appendUInt8(frame.type);
  builder.appendUInt8(this.getFrameId(frame));
  builder.appendString(frame.destination64 || C.UNKNOWN_64, 'hex');
  builder.appendString(frame.destination16 || C.UNKNOWN_16, 'hex');
  builder.appendUInt8(frame.broadcastRadius || 0x00);
  builder.appendUInt8(frame.options || 0x00);
  appendData(frame.data, builder);
};

frame_builder[C.FRAME_TYPE.EXPLICIT_ADDRESSING_ZIGBEE_COMMAND_FRAME] = function(frame, builder) {
  builder.appendUInt8(frame.type);
  builder.appendUInt8(this.getFrameId(frame));
  builder.appendString(frame.destination64 || C.UNKNOWN_64, 'hex');
  builder.appendString(frame.destination16 || C.UNKNOWN_16, 'hex');
  builder.appendUInt8(frame.sourceEndpoint);
  builder.appendUInt8(frame.destinationEndpoint);

  if (typeof(frame.clusterId) === 'number') {
	  builder.appendUInt16BE(frame.clusterId, 'hex');
  } else {
	  builder.appendString(frame.clusterId, 'hex');
  }

  if (typeof(frame.profileId) === 'number') {
	  builder.appendUInt16BE(frame.profileId, 'hex');
  } else {
	  builder.appendString(frame.profileId, 'hex');
  }

  builder.appendUInt8(frame.broadcastRadius || 0x00);
  builder.appendUInt8(frame.options || 0x00);
  appendData(frame.data, builder);
};

frame_builder[C.FRAME_TYPE.CREATE_SOURCE_ROUTE] = function(frame, builder) {
  builder.appendUInt8(frame.type);
  builder.appendUInt8(0); // Frame ID is always zero for this
  builder.appendString(frame.destination64, 'hex');
  builder.appendString(frame.destination16, 'hex');
  builder.appendUInt8(0); // Route command options always zero
  builder.appendUInt8(frame.addresses.length); // Number of hops
  for (var i = 0; i < frame.addresses.length; i++) {
    builder.appendUInt16BE(frame.addresses[i], 'hex');
  }
};

frame_builder[C.FRAME_TYPE.TX_REQUEST_64] = function(frame, builder) {
  builder.appendUInt8(frame.type);
  builder.appendUInt8(this.getFrameId(frame));
  builder.appendString(frame.destination64 || C.UNKNOWN_64, 'hex');
  builder.appendUInt8(frame.options || 0x00);
  appendData(frame.data, builder);
};

frame_builder[C.FRAME_TYPE.TX_REQUEST_16] = function(frame, builder) {
  builder.appendUInt8(frame.type);
  builder.appendUInt8(this.getFrameId(frame));
  builder.appendString(frame.destination16 || C.BROADCAST_16_XB, 'hex');
  builder.appendUInt8(frame.options || 0x00);
  appendData(frame.data, builder);
};
<commit_msg>Update frame-builder.js<commit_after>/*
 * xbee-api
 * https://github.com/jouz/xbee-api
 *
 * Copyright (c) 2013 Jan Kolkmeier
 * Licensed under the MIT license.
 */

'use strict';

var assert = require('assert'),
    C = require('./constants');

var frame_builder = module.exports = {
  frameId: 0,
  nextFrameId: function nextFrameId() {
    this.frameId = this.frameId >= 0xff ? 1 : ++this.frameId;
    return this.frameId;
  },

  getFrameId: function getFrameId(frame) {
    assert(frame, 'Frame parameter must be supplied');
    var id = frame.id || (frame.id !== 0 && this.nextFrameId()) || frame.id;
    return frame.id = id;
  }
};

// Appends data provided as Array, String, or Buffer
function appendData(data, builder) {
  if(Array.isArray(data)) {
    data = new Buffer(data);
  } else {
    data = new Buffer(data, 'ascii');
  }

  builder.appendBuffer(data);
}

frame_builder[C.FRAME_TYPE.AT_COMMAND] =
frame_builder[C.FRAME_TYPE.AT_COMMAND_QUEUE_PARAMETER_VALUE] = function(frame, builder) {
  builder.appendUInt8(frame.type);
  builder.appendUInt8(this.getFrameId(frame));
  builder.appendString(frame.command, 'ascii');
  appendData(frame.commandParameter, builder);
};

frame_builder[C.FRAME_TYPE.REMOTE_AT_COMMAND_REQUEST] = function(frame, builder) {
  builder.appendUInt8(frame.type);
  builder.appendUInt8(this.getFrameId(frame));
  builder.appendString(frame.destination64 || C.UNKNOWN_64, 'hex');
  builder.appendString(frame.destination16 || C.UNKNOWN_16, 'hex');
  builder.appendUInt8(frame.remoteCommandOptions || 0x02);
  builder.appendString(frame.command, 'ascii');
  appendData(frame.commandParameter, builder);
};

frame_builder[C.FRAME_TYPE.ZIGBEE_TRANSMIT_REQUEST] = function(frame, builder) {
  builder.appendUInt8(frame.type);
  builder.appendUInt8(this.getFrameId(frame));
  builder.appendString(frame.destination64 || C.UNKNOWN_64, 'hex');
  builder.appendString(frame.destination16 || C.UNKNOWN_16, 'hex');
  builder.appendUInt8(frame.broadcastRadius || 0x00);
  builder.appendUInt8(frame.options || 0x00);
  appendData(frame.data, builder);
};

frame_builder[C.FRAME_TYPE.EXPLICIT_ADDRESSING_ZIGBEE_COMMAND_FRAME] = function(frame, builder) {
  builder.appendUInt8(frame.type);
  builder.appendUInt8(this.getFrameId(frame));
  builder.appendString(frame.destination64 || C.UNKNOWN_64, 'hex');
  builder.appendString(frame.destination16 || C.UNKNOWN_16, 'hex');
  builder.appendUInt8(frame.sourceEndpoint);
  builder.appendUInt8(frame.destinationEndpoint);

  if (typeof(frame.clusterId) === 'number') {
	  builder.appendUInt16BE(frame.clusterId, 'hex');
  } else {
	  builder.appendString(frame.clusterId, 'hex');
  }

  if (typeof(frame.profileId) === 'number') {
	  builder.appendUInt16BE(frame.profileId, 'hex');
  } else {
	  builder.appendString(frame.profileId, 'hex');
  }

  builder.appendUInt8(frame.broadcastRadius || 0x00);
  builder.appendUInt8(frame.options || 0x00);
  appendData(frame.data, builder);
};

frame_builder[C.FRAME_TYPE.CREATE_SOURCE_ROUTE] = function(frame, builder) {
  builder.appendUInt8(frame.type);
  builder.appendUInt8(0); // Frame ID is always zero for this
  builder.appendString(frame.destination64, 'hex');
  builder.appendString(frame.destination16, 'hex');
  builder.appendUInt8(0); // Route command options always zero
  builder.appendUInt8(frame.addresses.length); // Number of hops
  for (var i = 0; i < frame.addresses.length; i++) {
    builder.appendUInt16BE(frame.addresses[i], 'hex');
  }
};

frame_builder[C.FRAME_TYPE.TX_REQUEST_64] = function(frame, builder) {
  builder.appendUInt8(frame.type);
  builder.appendUInt8(this.getFrameId(frame));
  builder.appendString(frame.destination64 || C.UNKNOWN_64, 'hex');
  builder.appendUInt8(frame.options || 0x00);
  appendData(frame.data, builder);
};

frame_builder[C.FRAME_TYPE.TX_REQUEST_16] = function(frame, builder) {
  builder.appendUInt8(frame.type);
  builder.appendUInt8(this.getFrameId(frame));
  builder.appendString(frame.destination16 || C.BROADCAST_16_XB, 'hex');
  builder.appendUInt8(frame.options || 0x00);
  appendData(frame.data, builder);
};
<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */
var passport = require('passport')
var co = require('co')

/**
 * Passport's default/connect middleware.
 */
var _initialize   = require('passport/lib/middleware/initialize')
var _authenticate = require('passport/lib/middleware/authenticate')

/**
 * Passport's initialization middleware for Koa.
 *
 * @return {GeneratorFunction}
 * @api private
 */
function initialize(passport) {
  var middleware = _initialize(passport)
  return function* passportInitialize(next) {
    var ctx = this

    // koa <-> connect compatibility:
    this.passport = {}
    var userProperty = passport._userProperty || 'user'
    Object.defineProperty(ctx.req, userProperty, {
      enumerable: true,
      get: function() {
        return ctx.passport[userProperty]
      },
      set: function(val) {
        ctx.passport[userProperty] = val
      }
    })

    var req = createReqMock(ctx)

    // add aliases for passport's request extensions to Koa's context
    var login  = ctx.req.login
    var logout = ctx.req.logout

    ctx.login = ctx.logIn = function(user, options) {
      return login.bind(req, user, options)
    }
    ctx.req.login = ctx.req.logIn = login.bind(req)
    ctx.logout = ctx.logOut = ctx.req.logout = ctx.req.logOut = logout.bind(req)
    ctx.isAuthenticated     = ctx.req.isAuthenticated   = ctx.req.isAuthenticated.bind(req)
    ctx.isUnauthenticated   = ctx.req.isUnauthenticated = ctx.req.isUnauthenticated.bind(req)

    yield middleware.bind(middleware, req, ctx)
    yield next
  }
}

/**
 * Passport's authenticate middleware for Koa.
 *
 * @param {String|Array} name
 * @param {Object} options
 * @param {GeneratorFunction} callback
 * @return {GeneratorFunction}
 * @api private
 */
function authenticate(passport, name, options, callback) {
  // normalize arguments
  if (typeof options === 'function') {
    callback = options
    options  = {}
  }
  options = options || {}

  if (callback) {
    if (callback.constructor.name !== 'GeneratorFunction') {
      throw TypeError('Your custom authentication callback must be a Generator Function')
    }

    // When the callback is set, neither `next`, `res.redirect` or `res.end`
    // are called. That is, a workaround to catch the `callback` is required.
    // The `passportAuthenticate()` method below will therefore set
    // `callback.done`. Then, once the authentication finishes, the modified
    // callback yields the original one and afterwards triggers `callback.done`
    // to inform `passportAuthenticate()` that we are ready.
    var _callback = callback
    callback = co(function*(err, user, info) {
      yield _callback(err, user, info)
      callback.done(null, false)
    })
  }

  var middleware = _authenticate(passport, name, options, callback)
  return function* passportAuthenticate(next) {
    var ctx = this

    // this functions wraps the connect middleware
    // to catch `next`, `res.redirect` and `res.end` calls
    var cont = yield function(done) {
      // mock the `req` object
      var req = createReqMock(ctx)

      // mock the `res` object
      var res = {
        redirect: function(url) {
          ctx.redirect(url)
          done(null, false)
        },
        setHeader: ctx.set.bind(ctx),
        end: function(content) {
          if (content) ctx.body = content
          done(null, false)
        },
        set statusCode(status) {
          ctx.status = status
        },
        get statusCode() {
          return ctx.status
        }
      }

      if (callback) {
        callback.done = done
      }

      // call the connect middleware
      middleware(req, res, done)
    }

    // cont equals `false` when `res.redirect` or `res.end` got called
    // in this case, yield next to continue through Koa's middleware stack
    if (cont !== false) {
      yield next
    }
  }
}

/**
 * Framework support for Koa.
 *
 * This module provides support for using Passport with Koa. It exposes
 * middleware that conform to the `fn*(next)` signature and extends
 * Node's built-in HTTP request object with useful authentication-related
 * functions.
 *
 * @return {Object}
 * @api protected
 */
module.exports = function() {
  return {
    initialize: initialize,
    authenticate: authenticate
  }
}

// create request mock
var properties = require('./request')
function createReqMock(ctx) {
  var req = Object.create(ctx.request, properties)
  return req
}
<commit_msg>adding status argument when using callback<commit_after>/**
 * Module dependencies.
 */
var passport = require('passport')
var co = require('co')

/**
 * Passport's default/connect middleware.
 */
var _initialize   = require('passport/lib/middleware/initialize')
var _authenticate = require('passport/lib/middleware/authenticate')

/**
 * Passport's initialization middleware for Koa.
 *
 * @return {GeneratorFunction}
 * @api private
 */
function initialize(passport) {
  var middleware = _initialize(passport)
  return function* passportInitialize(next) {
    var ctx = this

    // koa <-> connect compatibility:
    this.passport = {}
    var userProperty = passport._userProperty || 'user'
    Object.defineProperty(ctx.req, userProperty, {
      enumerable: true,
      get: function() {
        return ctx.passport[userProperty]
      },
      set: function(val) {
        ctx.passport[userProperty] = val
      }
    })

    var req = createReqMock(ctx)

    // add aliases for passport's request extensions to Koa's context
    var login  = ctx.req.login
    var logout = ctx.req.logout

    ctx.login = ctx.logIn = function(user, options) {
      return login.bind(req, user, options)
    }
    ctx.req.login = ctx.req.logIn = login.bind(req)
    ctx.logout = ctx.logOut = ctx.req.logout = ctx.req.logOut = logout.bind(req)
    ctx.isAuthenticated     = ctx.req.isAuthenticated   = ctx.req.isAuthenticated.bind(req)
    ctx.isUnauthenticated   = ctx.req.isUnauthenticated = ctx.req.isUnauthenticated.bind(req)

    yield middleware.bind(middleware, req, ctx)
    yield next
  }
}

/**
 * Passport's authenticate middleware for Koa.
 *
 * @param {String|Array} name
 * @param {Object} options
 * @param {GeneratorFunction} callback
 * @return {GeneratorFunction}
 * @api private
 */
function authenticate(passport, name, options, callback) {
  // normalize arguments
  if (typeof options === 'function') {
    callback = options
    options  = {}
  }
  options = options || {}

  if (callback) {
    if (callback.constructor.name !== 'GeneratorFunction') {
      throw TypeError('Your custom authentication callback must be a Generator Function')
    }

    // When the callback is set, neither `next`, `res.redirect` or `res.end`
    // are called. That is, a workaround to catch the `callback` is required.
    // The `passportAuthenticate()` method below will therefore set
    // `callback.done`. Then, once the authentication finishes, the modified
    // callback yields the original one and afterwards triggers `callback.done`
    // to inform `passportAuthenticate()` that we are ready.
    var _callback = callback
    callback = co(function*(err, user, info, status) {
      yield _callback(err, user, info, status)
      callback.done(null, false)
    })
  }

  var middleware = _authenticate(passport, name, options, callback)
  return function* passportAuthenticate(next) {
    var ctx = this

    // this functions wraps the connect middleware
    // to catch `next`, `res.redirect` and `res.end` calls
    var cont = yield function(done) {
      // mock the `req` object
      var req = createReqMock(ctx)

      // mock the `res` object
      var res = {
        redirect: function(url) {
          ctx.redirect(url)
          done(null, false)
        },
        setHeader: ctx.set.bind(ctx),
        end: function(content) {
          if (content) ctx.body = content
          done(null, false)
        },
        set statusCode(status) {
          ctx.status = status
        },
        get statusCode() {
          return ctx.status
        }
      }

      if (callback) {
        callback.done = done
      }

      // call the connect middleware
      middleware(req, res, done)
    }

    // cont equals `false` when `res.redirect` or `res.end` got called
    // in this case, yield next to continue through Koa's middleware stack
    if (cont !== false) {
      yield next
    }
  }
}

/**
 * Framework support for Koa.
 *
 * This module provides support for using Passport with Koa. It exposes
 * middleware that conform to the `fn*(next)` signature and extends
 * Node's built-in HTTP request object with useful authentication-related
 * functions.
 *
 * @return {Object}
 * @api protected
 */
module.exports = function() {
  return {
    initialize: initialize,
    authenticate: authenticate
  }
}

// create request mock
var properties = require('./request')
function createReqMock(ctx) {
  var req = Object.create(ctx.request, properties)
  return req
}
<|endoftext|>


<commit_before>var support = require("./util/support");
var fastCopy = support.fastCopy;

module.exports = function onMissing(model, path, depth,
                                    outerResults, requestedPath,
                                    optimizedPath, optimizedLength) {
    var pathSlice;
    if (!outerResults.requestedMissingPaths) {
        outerResults.requestedMissingPaths = [];
        outerResults.optimizedMissingPaths = [];
    }

    if (depth < path.length) {
        // If part of path has not been traversed, we need to ensure that there
        // are no empty paths (range(1, 0) or empyt array)
        var isEmpty = false;
        for (var i = depth; i < path.length && !isEmpty; ++i) {
            if (isEmptyAtom(path[i])) {
                return;
            }
        }

        pathSlice = fastCopy(path, depth);
    } else {
        pathSlice = [];
    }

    concatAndInsertMissing(model, pathSlice, depth, requestedPath,
                           optimizedPath, optimizedLength, outerResults);
};

function concatAndInsertMissing(model, remainingPath, depth, requestedPath,
                                optimizedPath, optimizedLength, results) {

    // TODO: Performance.
    results.requestedMissingPaths.push(
        requestedPath.
            slice(0, depth).
            concat(remainingPath));

    results.optimizedMissingPaths.push(
        optimizedPath.slice(0, optimizedLength).concat(remainingPath));
}

function isEmptyAtom(atom) {
    var type = typeof atom;
    if (type !== "object") {
        return false;
    }

    var isArray = Array.isArray(atom);
    if (isArray && atom.length) {
        return false;
    }

    // Empty array
    else if (isArray) {
        return true;
    }

    var from = atom.from;
    var to = atom.to;
    if (from === undefined || from <= to) {
        return false;
    }

    return true;
}
<commit_msg>Check for null in isEmptyAtom.<commit_after>var support = require("./util/support");
var fastCopy = support.fastCopy;

module.exports = function onMissing(model, path, depth,
                                    outerResults, requestedPath,
                                    optimizedPath, optimizedLength) {
    var pathSlice;
    if (!outerResults.requestedMissingPaths) {
        outerResults.requestedMissingPaths = [];
        outerResults.optimizedMissingPaths = [];
    }

    if (depth < path.length) {
        // If part of path has not been traversed, we need to ensure that there
        // are no empty paths (range(1, 0) or empyt array)
        var isEmpty = false;
        for (var i = depth; i < path.length && !isEmpty; ++i) {
            if (isEmptyAtom(path[i])) {
                return;
            }
        }

        pathSlice = fastCopy(path, depth);
    } else {
        pathSlice = [];
    }

    concatAndInsertMissing(model, pathSlice, depth, requestedPath,
                           optimizedPath, optimizedLength, outerResults);
};

function concatAndInsertMissing(model, remainingPath, depth, requestedPath,
                                optimizedPath, optimizedLength, results) {

    // TODO: Performance.
    results.requestedMissingPaths.push(
        requestedPath.
            slice(0, depth).
            concat(remainingPath));

    results.optimizedMissingPaths.push(
        optimizedPath.slice(0, optimizedLength).concat(remainingPath));
}

function isEmptyAtom(atom) {
    if (atom === null || typeof atom !== "object") {
        return false;
    }

    var isArray = Array.isArray(atom);
    if (isArray && atom.length) {
        return false;
    }

    // Empty array
    else if (isArray) {
        return true;
    }

    var from = atom.from;
    var to = atom.to;
    if (from === undefined || from <= to) {
        return false;
    }

    return true;
}
<|endoftext|>


<commit_before>'use strict'

const StatsD = require('hot-shots')

const defaultConfig = {
  host: 'localhost',
  port: 8125,
  prefix: 'jackal.'
}

module.exports = function (config) {
  const grapherConfig = Object.assign(defaultConfig, config)

  return new StatsD(grapherConfig)
}
<commit_msg>Appending . to graphite key if it doesnt exist<commit_after>'use strict'

const StatsD = require('hot-shots')

const defaultConfig = {
  host: 'localhost',
  port: 8125,
  prefix: 'jackal.'
}

module.exports = function (config) {
  const grapherConfig = Object.assign(defaultConfig, config)
  if(!grapherConfig.prefix.endsWith('.')){
    grapherConfig.prefix += '.'
  }

  return new StatsD(grapherConfig)
}
<|endoftext|>


<commit_before>/**
 * image-foldarizer
 * https://github.com/paazmaya/image-foldarizer
 *
 * Copyright (c) Juga Paazmaya <paazmaya@yahoo.com> (https://paazmaya.fi)
 * Licensed under the MIT license
 */

'use strict';

const fs = require('fs'),
  path = require('path');

const checkDestination = require('./check-destination');

/**
 * Move files to subdirectories based on the group structure
 *
 * @param {string} directory  Root directory in which images should be
 * @param {array} groups      Groups of files found
 * @param {object} options    Options that are all boolean values and false by default
 * @param {boolean} options.verbose Print out which file is being processed
 * @param {boolean} options.dryRun  Do not touch files, just show what would happen
 * @param {boolean} options.lowercaseSuffix   Lowercase the resulting file suffix
 * @param {boolean} options.initChar Initial character in the filename needs to be a character
 *
 * @returns {number} Number of files moved
 */
const handleGroups = (directory, groups, options) => {
  const keys = Object.keys(groups);

  let countFiles = 0;

  keys.forEach((key) => {
    const targetDir = path.join(directory, key);

    if (checkDestination(targetDir, options)) {
      groups[key].forEach((filepath) => {
        const namemeta = path.parse(filepath),
          ext = options.lowercaseSuffix ?
            namemeta.ext.toLowerCase() :
            namemeta.ext,
          target = path.join(targetDir, namemeta.name + ext);

        if (options.verbose) {
          const inPath = path.relative(directory, filepath),
            outPath = path.relative(directory, target);
          console.log(`Moving ${inPath} --> ${outPath}`);
        }

        if (!options.dryRun) {
          fs.renameSync(filepath, target);
        }

        ++countFiles;
      });
    }
  });

  return countFiles;
};

module.exports = handleGroups;
<commit_msg>Preparing for allowing destination folder to contain files #18<commit_after>/**
 * image-foldarizer
 * https://github.com/paazmaya/image-foldarizer
 *
 * Copyright (c) Juga Paazmaya <paazmaya@yahoo.com> (https://paazmaya.fi)
 * Licensed under the MIT license
 */

'use strict';

const fs = require('fs'),
  path = require('path');

const checkDestination = require('./check-destination');

/**
 * Check if the given file exists.
 *
 * @param {string} filepath  Root directory in which images should be
 * @returns {boolean} True when file exists
 */
const fileExists = (filepath) => {
  try {
    fs.accessSync(filepath);

    return true;
  }
  catch (error) {
    return false;
  }
};

/**
 * Move the given file to the target directory, after checking if it already exists.
 *
 * @param {string} filepath  Root directory in which images should be
 * @param {string} targetDir  Root directory in which images should be
 * @param {object} options    Options that are all boolean values and false by default
 * @param {boolean} options.verbose Print out which file is being processed
 * @param {boolean} options.dryRun  Do not touch files, just show what would happen
 * @param {boolean} options.lowercaseSuffix   Lowercase the resulting file suffix
 * @param {boolean} options.initChar Initial character in the filename needs to be a character
 *
 * @returns {number} Number of files moved
 */
const move = (filepath, targetDir, options) => {

  const namemeta = path.parse(filepath),
    ext = options.lowercaseSuffix ?
      namemeta.ext.toLowerCase() :
      namemeta.ext;
  let target = path.join(targetDir, namemeta.name + ext),
    suffixCounter = 1;
  while (fileExists(target)) {
    target = path.join(targetDir, namemeta.name + '-' + suffixCounter + ext);
    ++suffixCounter;
  }

  if (!options.dryRun) {
    fs.renameSync(filepath, target);
  }

  return target;
};

/**
 * Move files to subdirectories based on the group structure
 *
 * @param {string} directory  Root directory in which images should be
 * @param {array} groups      Groups of files found
 * @param {object} options    Options that are all boolean values and false by default
 * @param {boolean} options.verbose Print out which file is being processed
 * @param {boolean} options.dryRun  Do not touch files, just show what would happen
 * @param {boolean} options.lowercaseSuffix   Lowercase the resulting file suffix
 * @param {boolean} options.initChar Initial character in the filename needs to be a character
 *
 * @returns {number} Number of files moved
 */
const handleGroups = (directory, groups, options) => {
  const keys = Object.keys(groups);
  let countFiles = 0;

  keys.forEach((key) => {
    const targetDir = path.join(directory, key);

    if (checkDestination(targetDir, options)) {
      countFiles += groups[key].length;
      groups[key].forEach((filepath) => {

        const target = move(filepath, targetDir, options);

        if (options.verbose) {
          const inPath = path.relative(directory, filepath),
            outPath = path.relative(directory, target);
          console.log(`Moving ${inPath} --> ${outPath}`);
        }
      });
    }
  });

  return countFiles;
};

module.exports = handleGroups;
<|endoftext|>