<commit_before>var spawn = require('child_process').spawn
var dargs = require('dargs')
var noop = function () {}

module.exports = command.bind(null, 'install')
module.exports.uninstall = command.bind(null, 'uninstall')

function command (cmd, packages, opt, cb) {
  if (typeof opt === 'function') {
    cb = opt
    opt = {}
  } else {
    opt = opt || {}
  }
  cb = cb || noop
  if (typeof packages === 'function') {
    throw new TypeError('expected packages as first argument')
  }

  // packages to install
  var deps = [].concat(packages).filter(Boolean)
  if (deps.length === 0) {
    return process.nextTick(function () {
      cb(null)
    })
  }

  var npmCmd = process.platform === 'win32'
    ? 'npm.cmd'
    : 'npm'

  var spawnArgs = {
    cwd: opt.cwd,
    env: opt.env || process.env,
    stdio: opt.stdio
  }

  var cliArgs = dargs(opt, {
    excludes: ['cwd', 'env', 'stdio']
  })
  var args = [cmd].concat(deps).concat(cliArgs)
  var proc = spawn(npmCmd, args, spawnArgs)
  var error = ''

  if (proc.stderr) {
    proc.stderr.on('data', function (data) {
      error += data.toString()
    })
  }

  proc.once('exit', function (code) {
    // ensure we pass an Error
    if (code === 0) {
      cb(null)
    } else {
      var msg = error || 'exit code ' + code
      cb(new Error(msg))
    }
  })

  return proc
}
<commit_msg>spacing<commit_after>var spawn = require('child_process').spawn
var dargs = require('dargs')
var noop = function () {}

module.exports = command.bind(null, 'install')
module.exports.uninstall = command.bind(null, 'uninstall')

function command (cmd, packages, opt, cb) {
  if (typeof opt === 'function') {
    cb = opt
    opt = {}
  } else {
    opt = opt || {}
  }
  cb = cb || noop
  if (typeof packages === 'function') {
    throw new TypeError('expected packages as first argument')
  }

  // packages to install
  var deps = [].concat(packages).filter(Boolean)
  if (deps.length === 0) {
    return process.nextTick(function () {
      cb(null)
    })
  }

  var npmCmd = process.platform === 'win32'
    ? 'npm.cmd'
    : 'npm'

  var spawnArgs = {
    cwd: opt.cwd,
    env: opt.env || process.env,
    stdio: opt.stdio
  }
  var cliArgs = dargs(opt, {
    excludes: Object.keys(spawnArgs)
  })
  var args = [cmd].concat(deps).concat(cliArgs)
  var proc = spawn(npmCmd, args, spawnArgs)
  var error = ''

  if (proc.stderr) {
    proc.stderr.on('data', function (data) {
      error += data.toString()
    })
  }

  proc.once('exit', function (code) {
    // ensure we pass an Error
    if (code === 0) {
      cb(null)
    } else {
      var msg = error || 'exit code ' + code
      cb(new Error(msg))
    }
  })

  return proc
}
<|endoftext|>


<commit_before>/*!
 * expand-args <https://github.com/jonschlinkert/expand-args>
 *
 * Copyright (c) 2015, Jon Schlinkert.
 * Licensed under the MIT License.
 */

'use strict';

var utils = require('./utils');
var sep = /[=:]/;

function expand(argv, options) {
  var opts = utils.merge({}, options);
  var res = {};
  var segs;
  var val;
  var key;

  argv = preProcess(argv, options);

  function merge(key, val) {
    if (key === '_') {
      res = utils.merge({}, res, val);
    } else {
      utils.set(res, key, val);
    }
  }

  for (key in argv) {
    if (argv.hasOwnProperty(key)) {
      val = argv[key];

      // '{'a b': true}'
      if (sep.test(key) && isBoolean(val)) {
        segs = key.split(sep);
        val = segs.pop();
        key = segs.join('.');
      }

      val = toBoolean(val);

      switch (utils.typeOf(val)) {
        case 'object':
          res[key] = expand(val);
          break;
        case 'string':
          if (~val.indexOf('|')) {
            val = val.split('|');
            utils.set(res, key, expandEach(val));

          } else if (isUrl(val)) {
            utils.set(res, key, expandString(val));

          } else if (/\w,\w/.test(val)) {
            val = expandString(val);
            if (Array.isArray(val) && hasObjects(val)) {
              val.forEach(function(ele) {
                merge(key, toBoolean(ele));
              });
            } else {
              merge(key, val);
            }

          } else if (sep.test(val)) {
            if (opts.esc && ~opts.esc.indexOf(key)) {
              val = val.split('.').join('\\.');
            }
            var str = key + ':' + val;
            segs = str.split(sep);
            val = toBoolean(segs.pop());
            key = segs.join('.');
            utils.set(res, key, expandString(val));

          } else {
            res[key] = val.split('\\.').join('.');
          }
          break;
        case 'array':
          if (hasObjects(val)) {
            merge(key, expandEach(val));
          } else {
            res[key] = val.map(function(ele) {
              return toBoolean(ele);
            });
          }
          break;
        case 'boolean':
        default: {
          res[key] = val;
          break;
        }
      }
    }
  }
  return res;
}

function expandString(val) {
  if (isUrl(val)) {
    return val;
  }

  if (isPath(val)) {
    val = unescape(val);
    if (~val.indexOf(':')) {
      return toObject(val);
    }
    if (~val.indexOf(',')) {
      return val.split(',');
    }
    return toBoolean(val);
  }

  if (!/\W/.test(val)) {
    return val;
  }

  return utils.expand(val, {
    toBoolean: true
  });
}

function preProcess(argv, options) {
  var obj = {};

  if (Array.isArray(argv)) {
    argv = argv.reduce(function(acc, str) {
      if (!/['"]/.test(str)) {
        return acc.concat(str.split(' '));
      }
      return acc.concat(str);
    }, []);

    argv = argv.map(function(str) {
      if (isUrl(str) || /['"]/.test(str)) {
        var m = /[=:.]/.exec(str);
        if (m) {
          var key = str.slice(0, m.index);
          var val = str.slice(m.index + 1);
          if (isUrl(val)) {
            obj[key] = val;
            return;
          }
          if (/^['"]/.test(val) && /['"]$/.test(val)) {
            obj[key] = val.slice(1, val.length - 1);
            return;
          }
        }
        return str;
      }

      if (!/=.*,/.test(str)) {
        str = str.split(':').join('=');
      }
      return str;
    });

    argv = utils.minimist(argv, options);
  }

  argv = utils.merge({}, argv, obj);
  return utils.omitEmpty(argv);
}

function expandEach(arr) {
  var len = arr.length;
  var idx = -1;
  var res = {};
  while (++idx < len) {
    utils.merge(res, expand(utils.expand(arr[idx], {toBoolean: true})));
  }
  return res;
}

function isBoolean(val) {
  return val === 'false'
    || val === 'true'
    || val === false
    || val === true;
}

function isUrl(val) {
  return /\w+:\/\/\w/.test(val);
}

function isPath(val) {
  return /(?:[\\\/]|\\\.)/.test(val);
}

function unescape(val) {
  if (isString(val)) {
    return val.split('\\').join('');
  }
  if (isObject(val)) {
    for (var key in val) {
      val[key] = unescape(val[key]);
    }
    return val;
  }
  if (Array.isArray(val)) {
    return val.map(unescape);
  }
  return val;
}

function isString(val) {
  return typeof val === 'string';
}

function toBoolean(val) {
  if (val === 'true') val = true;
  if (val === 'false') val = false;
  return val;
}

function isObject(val) {
  return utils.typeOf(val) === 'object';
}

function toObject(str) {
  var res = {};
  var segs = str.split(':');
  var val = segs.pop();
  res[segs.join('.')] = val;
  return res;
}

function hasObjects(arr) {
  var len = arr.length;
  var idx = -1;

  while (++idx < len) {
    if (isObject(arr[idx]) || /[:=|,]/.test(arr[idx])) {
      return true;
    }
  }
  return false;
}

/**
 * Expose `expand`
 */

module.exports = expand;
<commit_msg>ensure prefixes are stripped<commit_after>/*!
 * expand-args <https://github.com/jonschlinkert/expand-args>
 *
 * Copyright (c) 2015, Jon Schlinkert.
 * Licensed under the MIT License.
 */

'use strict';

var utils = require('./utils');
var sep = /[=:]/;

function expand(argv, options) {
  var opts = utils.merge({}, options);
  var res = {};
  var segs;
  var val;
  var key;

  argv = preProcess(argv, options);

  function merge(key, val) {
    if (key === '_') {
      res = utils.merge({}, res, val);
    } else {
      utils.set(res, key, val);
    }
  }

  for (key in argv) {
    if (argv.hasOwnProperty(key)) {
      val = argv[key];

      // '{'a b': true}'
      if (sep.test(key) && isBoolean(val)) {
        segs = key.split(sep);
        val = segs.pop();
        key = segs.join('.');
      }

      val = toBoolean(val);

      switch (utils.typeOf(val)) {
        case 'object':
          res[key] = expand(val);
          break;
        case 'string':
          if (~val.indexOf('|')) {
            val = val.split('|');
            utils.set(res, key, expandEach(val));

          } else if (isUrl(val)) {
            utils.set(res, key, expandString(val));

          } else if (/\w,\w/.test(val)) {
            val = expandString(val);
            if (Array.isArray(val) && hasObjects(val)) {
              val.forEach(function(ele) {
                merge(key, toBoolean(ele));
              });
            } else {
              merge(key, val);
            }

          } else if (sep.test(val)) {
            if (opts.esc && ~opts.esc.indexOf(key)) {
              val = val.split('.').join('\\.');
            }
            var str = key + ':' + val;
            segs = str.split(sep);
            val = toBoolean(segs.pop());
            key = segs.join('.');
            utils.set(res, key, expandString(val));

          } else {
            res[key] = val.split('\\.').join('.');
          }
          break;
        case 'array':
          if (hasObjects(val)) {
            merge(key, expandEach(val));
          } else {
            res[key] = val.map(function(ele) {
              return toBoolean(ele);
            });
          }
          break;
        case 'boolean':
        default: {
          res[key] = val;
          break;
        }
      }
    }
  }
  return res;
}

function expandString(val) {
  if (isUrl(val)) {
    return val;
  }

  if (isPath(val)) {
    val = unescape(val);
    if (~val.indexOf(':')) {
      return toObject(val);
    }
    if (~val.indexOf(',')) {
      return val.split(',');
    }
    return toBoolean(val);
  }

  if (!/\W/.test(val)) {
    return val;
  }

  return utils.expand(val, {
    toBoolean: true
  });
}

function preProcess(argv, options) {
  var obj = {};

  if (Array.isArray(argv)) {
    argv = argv.reduce(function(acc, str) {
      if (!/['"]/.test(str)) {
        return acc.concat(str.split(' '));
      }
      return acc.concat(str);
    }, []);

    argv = argv.map(function(str) {
      if (isUrl(str) || /['"]/.test(str)) {
        str = str.replace(/^-+/, '');
        var m = /[=:.]/.exec(str);
        if (m) {
          var key = str.slice(0, m.index);
          var val = str.slice(m.index + 1);
          if (isUrl(val)) {
            obj[key] = val;
            return;
          }
          if (/^['"]/.test(val) && /['"]$/.test(val)) {
            obj[key] = val.slice(1, val.length - 1);
            return;
          }
        }
        return str;
      }

      if (!/=.*,/.test(str)) {
        str = str.split(':').join('=');
      }
      return str;
    });

    argv = utils.minimist(argv, options);
  }

  argv = utils.merge({}, argv, obj);
  return utils.omitEmpty(argv);
}

function expandEach(arr) {
  var len = arr.length;
  var idx = -1;
  var res = {};
  while (++idx < len) {
    utils.merge(res, expand(utils.expand(arr[idx], {toBoolean: true})));
  }
  return res;
}

function isBoolean(val) {
  return val === 'false'
    || val === 'true'
    || val === false
    || val === true;
}

function isUrl(val) {
  return /\w+:\/\/\w/.test(val);
}

function isPath(val) {
  return /(?:[\\\/]|\\\.)/.test(val);
}

function unescape(val) {
  if (isString(val)) {
    return val.split('\\').join('');
  }
  if (isObject(val)) {
    for (var key in val) {
      val[key] = unescape(val[key]);
    }
    return val;
  }
  if (Array.isArray(val)) {
    return val.map(unescape);
  }
  return val;
}

function isString(val) {
  return typeof val === 'string';
}

function toBoolean(val) {
  if (val === 'true') val = true;
  if (val === 'false') val = false;
  return val;
}

function isObject(val) {
  return utils.typeOf(val) === 'object';
}

function toObject(str) {
  var res = {};
  var segs = str.split(':');
  var val = segs.pop();
  res[segs.join('.')] = val;
  return res;
}

function hasObjects(arr) {
  var len = arr.length;
  var idx = -1;

  while (++idx < len) {
    if (isObject(arr[idx]) || /[:=|,]/.test(arr[idx])) {
      return true;
    }
  }
  return false;
}

/**
 * Expose `expand`
 */

module.exports = expand;
<|endoftext|>


<commit_before>var EventEmitter = require('events').EventEmitter;
var net = require('net');
var fs = require('fs');
var util = require('util');

util.inherits(MaxCube, EventEmitter);

function padLeft(nr, n, str){
  return Array(n-String(nr).length+1).join(str||'0')+nr;
}

function MaxCube(ip, port, heartbeatInterval) {
  this.ip = ip;
  this.port = port;
  this.interval = heartbeatInterval || 20000;
  this.isConnected = false;
  this.busy = false;
  this.callback = null;
  this.dutyCycle = 0;
  this.memorySlots = 0;

  this.rooms = [];
  this.devices = {};
  this.deviceCount = 0;
  this.client = new net.Socket();

  this.client.on('data', this.onData.bind(this));

  this.connect();
}

MaxCube.prototype.connect = function () {
  if (!this.isConnected) {
    this.client.connect(this.port, this.ip, function() {
      console.log('Connected');
      this.isConnected = true;
      this.emit('connected');
    }.bind(this));
  } else {
    this.send('l:\r\n');
  }

  setTimeout(this.connect.bind(this), this.interval);
};

MaxCube.prototype.send = function (message) {
  if (!this.busy) {
    console.log('Sending command: ' + message.substr(0,1));
    this.busy = true;
    this.client.write(message);
  }
};

MaxCube.prototype.onData = function (data) {
  data = data.toString('utf-8');
  data = data.split('\r\n');
  data.forEach(function (line) {
    if (line.length > 0) {
      var commandType = line.substr(0, 1);
      var payload = line.substring(2);
      console.log('Data received: ' + commandType);
      var dataObj = this.parseCommand(commandType, payload);
      console.log(dataObj);
    }
  }.bind(this));
  this.busy = false;
  this.emit('update', this.devices);
};

MaxCube.prototype.getDeviceType = function (deviceId) {
  var type = null;
  switch (deviceId) {
    case 0:
      type = 'Cube';
      break;
    case 1:
      type = 'Heating Thermostat';
      break;
    case 2:
      type = 'Heating Thermostat Plus';
      break;
    case 3:
      type = 'Wall mounted Thermostat';
      break;
    case 4:
      type = 'Shutter Contact';
      break;
    case 5:
      type = 'Push Button';
      break;
    default:
      type = 'unknown';
      break;
  }
  return type;
};

MaxCube.prototype.parseCommand = function (type, payload) {
  var data = null;
  switch (type) {
    case 'H':
      data = this.parseCommandHello(payload);
      break;
    case 'M':
      data = this.parseCommandMetadata(payload);
      break;
    case 'C':
      data = this.parseCommandDeviceConfiguration(payload);
      break;
    case 'L':
      data = this.parseCommandDeviceList(payload);
      break;
    case 'S':
      data = this.parseCommandSendDevice(payload);
      break;
    default:
      console.log('Unknown command type: ' + type);
      break;
  }
  return data;
};

MaxCube.prototype.parseCommandHello = function (payload) {
  var payloadArr = payload.split(",");

  var dataObj = {
    serial: payloadArr[0],
    address: payloadArr[1],
    firmware: payloadArr[2],
    connectionId: payloadArr[4],
    dutyCycle: parseInt(payloadArr[5], 16),
    freeMemorySlots: parseInt(payloadArr[6], 16),
    date: 2000 + parseInt(payloadArr[7].substr(0, 2), 16) + '-' + parseInt(payloadArr[7].substr(2, 2), 16) + '-' + parseInt(payloadArr[7].substr(4, 2), 16),
    time: parseInt(payloadArr[8].substr(0, 2), 16) + ':' + parseInt(payloadArr[8].substr(2, 2), 16) ,
    stateTime: payloadArr[9],
    ntpCounter: payloadArr[10],
  };

  this.dutyCycle = dataObj.duty_cycle;
  this.memorySlots = dataObj.free_memory_slots;

  return dataObj;
};

MaxCube.prototype.parseCommandDeviceConfiguration = function (payload) {
  var payloadArr = payload.split(",");
  var decodedPayload = new Buffer(payloadArr[1], 'base64');

  var address = decodedPayload.slice(1, 4).toString('hex');
  var devicetype = this.getDeviceType(parseInt(decodedPayload[4].toString(10)));
  if (devicetype == 'Heating Thermostat' && this.devices[address]) {
    this.devices[address].comfortTemperature = parseInt(decodedPayload[18].toString(10)) / 2;
    this.devices[address].ecoTemperature = parseInt(decodedPayload[19].toString(10)) / 2;
    this.devices[address].maxTemperature = parseInt(decodedPayload[20].toString(10)) / 2;
    this.devices[address].minTemperature = parseInt(decodedPayload[21].toString(10)) / 2;
    this.devices[address].temperatureOffset = parseInt(decodedPayload[22].toString(10)) / 2;
    this.devices[address].windowOpenTemperature = parseInt(decodedPayload[23].toString(10)) / 2;
    return this.devices[address];
  }
  return null;
};

MaxCube.prototype.parseCommandMetadata = function (payload) {
  var payloadArr = payload.split(",");

  var decodedPayload = new Buffer(payloadArr[2], 'base64');
  var room_count = parseInt(decodedPayload[2].toString(10));
  var currentIndex = 3;

  // parse rooms
  for (var i = 0; i < room_count; i++) {
    var roomData = {};
    roomData.roomId = parseInt(decodedPayload[currentIndex].toString(10));
    var room_length = parseInt(decodedPayload[currentIndex + 1].toString(10));
    roomData.name = decodedPayload.slice(currentIndex + 2, currentIndex + 2 + room_length).toString('utf-8');
    roomData.groupAddress = decodedPayload.slice(currentIndex + 2 + room_length, currentIndex + room_length + 5).toString('hex');
    this.rooms.push(roomData);
    currentIndex = currentIndex + room_length + 5;
  }

  if (currentIndex < decodedPayload.length) {
    this.deviceCount = parseInt(decodedPayload[currentIndex].toString(10));

    for (var j = 0; j < this.deviceCount; j++) {
      var deviceData = {};
      deviceData.type = this.getDeviceType(parseInt(decodedPayload[currentIndex + 1].toString(10)));
      deviceData.address = decodedPayload.slice(currentIndex + 2, currentIndex + 5).toString('hex');
      deviceData.serial = decodedPayload.slice(currentIndex + 5, currentIndex + 13).toString();
      device_length = parseInt(decodedPayload[currentIndex + 15].toString(10));
      deviceData.name = decodedPayload.slice(currentIndex + 16, currentIndex + 16 + device_length).toString('utf-8');
      deviceData.roomId = parseInt(decodedPayload[currentIndex + 16 + device_length].toString(10));
      this.devices[deviceData.address] = deviceData;
      currentIndex = currentIndex + 16 + device_length;
    }
  }
  return {
    rooms: this.rooms,
    devices: this.devices
  };
};

MaxCube.prototype.parseCommandDeviceList = function (payload) {
  var decodedPayload = new Buffer(payload, 'base64');
  var currentIndex = 1;
  for(var i = 1; i <= this.deviceCount; i++) {
    var data = '';
    var length = parseInt(decodedPayload[currentIndex - 1].toString());
    var address = decodedPayload.slice(currentIndex, currentIndex + 3).toString('hex');
    if (this.devices[address] && this.devices[address].type === 'Heating Thermostat') {
      this.devices[address].valve = decodedPayload[currentIndex + 6];
      this.devices[address].setpoint = parseInt(decodedPayload[currentIndex + 7].toString(10)) / 2;
      data = padLeft(decodedPayload[currentIndex + 5].toString(2), 8);
      this.devices[address].battery = parseInt(data.substr(0, 1)) ? 'low' : 'ok';
      switch (data.substr(6, 2)) {
        case '00': this.devices[address].mode = "auto"; break;
        case '01': this.devices[address].mode = "manu"; break;
        case '10': this.devices[address].mode = "vacation"; break;
        case '11': this.devices[address].mode = "boost"; break;
      }
    }
    else if (this.devices[address] && this.devices[address].type === 'Shutter Contact') {
      data = padLeft(decodedPayload[currentIndex + 5].toString(2), 8);
      this.devices[address].state = parseInt(data.substr(6, 1)) ? 'open' : 'closed';
      this.devices[address].battery = parseInt(data.substr(0, 1)) ? 'low' : 'ok';
    }
    currentIndex = currentIndex + length + 1;
  }
  return this.devices;
};

MaxCube.prototype.parseCommandSendDevice = function (payload) {
  var payloadArr = payload.split(",");

  var dataObj = {
    accepted: payloadArr[1] == '1',
    duty_cycle: parseInt(payloadArr[0], 16),
    free_memory_slots: parseInt(payloadArr[2], 16)
  };

  return dataObj;
};

MaxCube.prototype.setTemperature = function (rfAdress, mode, temperature) {
  var reqTempHex, reqTempBinary;
  if (!this.isConnected) {
    console.log('Not connected');
    return;
  }

  // 00 = Auto weekprog (no temp is needed, just make the whole byte 00)
  // 01 = Permanent
  // 10 = Temporarily
  var modeBin;
  switch (mode) {
    case 'auto':
      modeBin = '00';
      break;
    case 'manual':
      modeBin = '01';
      break;
    case 'boost':
      modeBin = '11';
      break;
    default:
      console.log('Unknown mode: ' + mode);
      return false;
  }

  reqTempBinary = modeBin + ("000000" + (temperature * 2).toString(2)).substr(-6);
  reqTempHex = parseInt(reqTempBinary, 2).toString(16);

  var payload = new Buffer('000440000000' + rfAdress + '01' + reqTempHex, 'hex').toString('base64');
  var data = 's:' + payload + '\r\n';
  this.send(data);
};

module.exports = MaxCube;
<commit_msg>removed debug to let pimatic handle the output<commit_after>var EventEmitter = require('events').EventEmitter;
var net = require('net');
var fs = require('fs');
var util = require('util');

util.inherits(MaxCube, EventEmitter);

function padLeft(nr, n, str){
  return Array(n-String(nr).length+1).join(str||'0')+nr;
}

function MaxCube(ip, port, heartbeatInterval) {
  this.ip = ip;
  this.port = port;
  this.interval = heartbeatInterval || 20000;
  this.isConnected = false;
  this.busy = false;
  this.callback = null;
  this.dutyCycle = 0;
  this.memorySlots = 0;

  this.rooms = [];
  this.devices = {};
  this.deviceCount = 0;
  this.client = new net.Socket();

  this.client.on('data', this.onData.bind(this));

  this.connect();
}

MaxCube.prototype.connect = function () {
  if (!this.isConnected) {
    this.client.connect(this.port, this.ip, function() {
      //console.log('Connected');
      this.isConnected = true;
      this.emit('connected');
    }.bind(this));
  } else {
    this.send('l:\r\n');
  }

  setTimeout(this.connect.bind(this), this.interval);
};

MaxCube.prototype.send = function (message) {
  if (!this.busy) {
    //console.log('Sending command: ' + message.substr(0,1));
    this.busy = true;
    this.client.write(message);
  }
};

MaxCube.prototype.onData = function (data) {
  data = data.toString('utf-8');
  data = data.split('\r\n');
  data.forEach(function (line) {
    if (line.length > 0) {
      var commandType = line.substr(0, 1);
      var payload = line.substring(2);
      //console.log('Data received: ' + commandType);
      var dataObj = this.parseCommand(commandType, payload);
      //console.log(dataObj);
    }
  }.bind(this));
  this.busy = false;
  this.emit('update', this.devices);
};

MaxCube.prototype.getDeviceType = function (deviceId) {
  var type = null;
  switch (deviceId) {
    case 0:
      type = 'Cube';
      break;
    case 1:
      type = 'Heating Thermostat';
      break;
    case 2:
      type = 'Heating Thermostat Plus';
      break;
    case 3:
      type = 'Wall mounted Thermostat';
      break;
    case 4:
      type = 'Shutter Contact';
      break;
    case 5:
      type = 'Push Button';
      break;
    default:
      type = 'unknown';
      break;
  }
  return type;
};

MaxCube.prototype.parseCommand = function (type, payload) {
  var data = null;
  switch (type) {
    case 'H':
      data = this.parseCommandHello(payload);
      break;
    case 'M':
      data = this.parseCommandMetadata(payload);
      break;
    case 'C':
      data = this.parseCommandDeviceConfiguration(payload);
      break;
    case 'L':
      data = this.parseCommandDeviceList(payload);
      break;
    case 'S':
      data = this.parseCommandSendDevice(payload);
      break;
    default:
      console.log('Unknown command type: ' + type);
      break;
  }
  return data;
};

MaxCube.prototype.parseCommandHello = function (payload) {
  var payloadArr = payload.split(",");

  var dataObj = {
    serial: payloadArr[0],
    address: payloadArr[1],
    firmware: payloadArr[2],
    connectionId: payloadArr[4],
    dutyCycle: parseInt(payloadArr[5], 16),
    freeMemorySlots: parseInt(payloadArr[6], 16),
    date: 2000 + parseInt(payloadArr[7].substr(0, 2), 16) + '-' + parseInt(payloadArr[7].substr(2, 2), 16) + '-' + parseInt(payloadArr[7].substr(4, 2), 16),
    time: parseInt(payloadArr[8].substr(0, 2), 16) + ':' + parseInt(payloadArr[8].substr(2, 2), 16) ,
    stateTime: payloadArr[9],
    ntpCounter: payloadArr[10],
  };

  this.dutyCycle = dataObj.duty_cycle;
  this.memorySlots = dataObj.free_memory_slots;

  return dataObj;
};

MaxCube.prototype.parseCommandDeviceConfiguration = function (payload) {
  var payloadArr = payload.split(",");
  var decodedPayload = new Buffer(payloadArr[1], 'base64');

  var address = decodedPayload.slice(1, 4).toString('hex');
  var devicetype = this.getDeviceType(parseInt(decodedPayload[4].toString(10)));
  if (devicetype == 'Heating Thermostat' && this.devices[address]) {
    this.devices[address].comfortTemperature = parseInt(decodedPayload[18].toString(10)) / 2;
    this.devices[address].ecoTemperature = parseInt(decodedPayload[19].toString(10)) / 2;
    this.devices[address].maxTemperature = parseInt(decodedPayload[20].toString(10)) / 2;
    this.devices[address].minTemperature = parseInt(decodedPayload[21].toString(10)) / 2;
    this.devices[address].temperatureOffset = parseInt(decodedPayload[22].toString(10)) / 2;
    this.devices[address].windowOpenTemperature = parseInt(decodedPayload[23].toString(10)) / 2;
    return this.devices[address];
  }
  return null;
};

MaxCube.prototype.parseCommandMetadata = function (payload) {
  var payloadArr = payload.split(",");

  var decodedPayload = new Buffer(payloadArr[2], 'base64');
  var room_count = parseInt(decodedPayload[2].toString(10));
  var currentIndex = 3;

  // parse rooms
  for (var i = 0; i < room_count; i++) {
    var roomData = {};
    roomData.roomId = parseInt(decodedPayload[currentIndex].toString(10));
    var room_length = parseInt(decodedPayload[currentIndex + 1].toString(10));
    roomData.name = decodedPayload.slice(currentIndex + 2, currentIndex + 2 + room_length).toString('utf-8');
    roomData.groupAddress = decodedPayload.slice(currentIndex + 2 + room_length, currentIndex + room_length + 5).toString('hex');
    this.rooms.push(roomData);
    currentIndex = currentIndex + room_length + 5;
  }

  if (currentIndex < decodedPayload.length) {
    this.deviceCount = parseInt(decodedPayload[currentIndex].toString(10));

    for (var j = 0; j < this.deviceCount; j++) {
      var deviceData = {};
      deviceData.type = this.getDeviceType(parseInt(decodedPayload[currentIndex + 1].toString(10)));
      deviceData.address = decodedPayload.slice(currentIndex + 2, currentIndex + 5).toString('hex');
      deviceData.serial = decodedPayload.slice(currentIndex + 5, currentIndex + 13).toString();
      device_length = parseInt(decodedPayload[currentIndex + 15].toString(10));
      deviceData.name = decodedPayload.slice(currentIndex + 16, currentIndex + 16 + device_length).toString('utf-8');
      deviceData.roomId = parseInt(decodedPayload[currentIndex + 16 + device_length].toString(10));
      this.devices[deviceData.address] = deviceData;
      currentIndex = currentIndex + 16 + device_length;
    }
  }
  return {
    rooms: this.rooms,
    devices: this.devices
  };
};

MaxCube.prototype.parseCommandDeviceList = function (payload) {
  var decodedPayload = new Buffer(payload, 'base64');
  var currentIndex = 1;
  for(var i = 1; i <= this.deviceCount; i++) {
    var data = '';
    var length = parseInt(decodedPayload[currentIndex - 1].toString());
    var address = decodedPayload.slice(currentIndex, currentIndex + 3).toString('hex');
    if (this.devices[address] && this.devices[address].type === 'Heating Thermostat') {
      this.devices[address].valve = decodedPayload[currentIndex + 6];
      this.devices[address].setpoint = parseInt(decodedPayload[currentIndex + 7].toString(10)) / 2;
      data = padLeft(decodedPayload[currentIndex + 5].toString(2), 8);
      this.devices[address].battery = parseInt(data.substr(0, 1)) ? 'low' : 'ok';
      switch (data.substr(6, 2)) {
        case '00': this.devices[address].mode = "auto"; break;
        case '01': this.devices[address].mode = "manu"; break;
        case '10': this.devices[address].mode = "vacation"; break;
        case '11': this.devices[address].mode = "boost"; break;
      }
    }
    else if (this.devices[address] && this.devices[address].type === 'Shutter Contact') {
      data = padLeft(decodedPayload[currentIndex + 5].toString(2), 8);
      this.devices[address].state = parseInt(data.substr(6, 1)) ? 'open' : 'closed';
      this.devices[address].battery = parseInt(data.substr(0, 1)) ? 'low' : 'ok';
    }
    currentIndex = currentIndex + length + 1;
  }
  return this.devices;
};

MaxCube.prototype.parseCommandSendDevice = function (payload) {
  var payloadArr = payload.split(",");

  var dataObj = {
    accepted: payloadArr[1] == '1',
    duty_cycle: parseInt(payloadArr[0], 16),
    free_memory_slots: parseInt(payloadArr[2], 16)
  };

  return dataObj;
};

MaxCube.prototype.setTemperature = function (rfAdress, mode, temperature) {
  var reqTempHex, reqTempBinary;
  if (!this.isConnected) {
    //console.log('Not connected');
    return;
  }

  // 00 = Auto weekprog (no temp is needed, just make the whole byte 00)
  // 01 = Permanent
  // 10 = Temporarily
  var modeBin;
  switch (mode) {
    case 'auto':
      modeBin = '00';
      break;
    case 'manual':
      modeBin = '01';
      break;
    case 'boost':
      modeBin = '11';
      break;
    default:
      console.log('Unknown mode: ' + mode);
      return false;
  }

  reqTempBinary = modeBin + ("000000" + (temperature * 2).toString(2)).substr(-6);
  reqTempHex = parseInt(reqTempBinary, 2).toString(16);

  var payload = new Buffer('000440000000' + rfAdress + '01' + reqTempHex, 'hex').toString('base64');
  var data = 's:' + payload + '\r\n';
  this.send(data);
};

module.exports = MaxCube;
<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies
 */

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

/**
 * Expose `mapFiles`
 */

module.exports = mapFiles;

/**
 * Return an object for all files matching the given `patterns`
 * and `opts`. By default the full filepath of the file is used
 * as the key, but this can be changed by passing a `name` function
 * on the options.
 *
 * @param  {String} `patterns` Glob patterns to pass to [globby]
 * @param  {Object} `opts` Options for globby, or the following:
 *     @option {Boolean} [opts] `cache` If true, results will be cached in memory so that subsequent lookups for the same cwd and patterns don't repeatedly hit the file system.
 *     @option {Function} [opts] `glob`: Custom glob function. Default is globby.
 *     @option {Function} [opts] `read`: Custom read function. Default is `fs.readFileSync`
 *     @option {Function} [opts] `name`: Custom name function for renaming object keys. Default is the asename of the file, excluding extension.
 * @return {Object}
 * @api public
 */

function mapFiles(patterns, opts) {
  opts = opts || {};

  opts.cwd = opts && opts.cwd || process.cwd();
  var files = glob(patterns, opts);

  if (opts.cache === true) {
    var fn = memo('files', opts.cwd, patterns, reduce);
    return fn(files, opts);
  }
  return reduce(files, opts);
};

/**
 * Expose results cache.
 */

var cache = mapFiles.cache = {};

function reduce(files, opts) {
  return files.reduce(function (acc, fp) {
    fp = path.resolve(opts.cwd, fp);
    var key = name(fp, acc, opts);
    var str = read(fp, acc, opts);
    acc[key] = str;
    return acc;
  }, {});
}

/**
 * Default glob function
 */

function glob(patterns, opts) {
  if (opts && opts.glob) {
    return opts.glob(patterns, opts);
  }
  if (opts.cache === true) {
    var fn = memo('glob', opts.cwd, patterns, globby.sync);
    return fn(patterns, opts);
  }
  return globby.sync(patterns, opts);
}

/**
 * Default renaming function
 */

function name(fp, acc, opts) {
  var fn = opts && opts.name || opts.renameKey;
  if (fn) {
    return opts.name(fp, acc, opts);
  }
  var ext = path.extname(fp);
  return path.basename(fp, ext);
}

/**
 * Default read function
 */

function read(fp, acc, opts) {
  fp = path.resolve(fp);
  if (opts && opts.read) {
    return opts.read(fp, acc, opts);
  }
  var res = {};
  res.content = fs.readFileSync(fp, 'utf8');
  res.path = fp;
  return res;
}

/**
 * Files cache.
 */

function memo(name, cwd, patterns, fn) {
  var key = name + ':' + cwd + '/' + patterns;
  return function () {
    if (cache.hasOwnProperty(key)) {
      return cache[key];
    }
    return (cache[key] = fn.apply(fn, arguments));
  };
}
<commit_msg>type checking on custom functions<commit_after>'use strict';

/**
 * Module dependencies
 */

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

/**
 * Expose `mapFiles`
 */

module.exports = mapFiles;

/**
 * Return an object for all files matching the given `patterns`
 * and `opts`. By default the full filepath of the file is used
 * as the key, but this can be changed by passing a `name` function
 * on the options.
 *
 * @param  {String} `patterns` Glob patterns to pass to [globby]
 * @param  {Object} `opts` Options for globby, or the following:
 *     @option {Boolean} [opts] `cache` If true, results will be cached in memory so that subsequent lookups for the same cwd and patterns don't repeatedly hit the file system.
 *     @option {Function} [opts] `glob`: Custom glob function. Default is globby.
 *     @option {Function} [opts] `read`: Custom read function. Default is `fs.readFileSync`
 *     @option {Function} [opts] `name`: Custom name function for renaming object keys. Default is the asename of the file, excluding extension.
 * @return {Object}
 * @api public
 */

function mapFiles(patterns, opts) {
  opts = opts || {};
  opts.cwd = opts.cwd ? path.resolve(opts.cwd) : process.cwd();
  var files = glob(patterns, opts);

  if (opts.cache === true) {
    var fn = memo('files', opts.cwd, patterns, reduce);
    return fn(files, opts);
  }
  return reduce(files, opts);
}

/**
 * Expose results cache.
 */

var cache = mapFiles.cache = {};

function reduce(files, opts) {
  return files.reduce(function (acc, fp) {
    fp = path.resolve(opts.cwd, fp);
    var key = name(fp, acc, opts);
    var str = read(fp, acc, opts);
    acc[key] = str;
    return acc;
  }, {});
}

/**
 * Default glob function
 */

function glob(patterns, opts) {
  opts = opts || {};
  if (typeof opts.glob === 'function') {
    return opts.glob(patterns, opts);
  }
  if (opts.cache === true) {
    var fn = memo('glob', opts.cwd, patterns, globby.sync);
    return fn(patterns, opts);
  }
  return globby.sync(patterns, opts);
}

/**
 * Default renaming function
 */

function name(fp, acc, opts) {
  var fn = (opts && opts.name) || opts.renameKey;
  if (typeof fn === 'function') {
    return fn(fp, acc, opts);
  }
  var ext = path.extname(fp);
  return path.basename(fp, ext);
}

/**
 * Default read function
 */

function read(fp, acc, opts) {
  fp = path.resolve(fp);
  opts = opts || {};
  if (typeof opts.read === 'function') {
    return opts.read(fp, acc, opts);
  }
  var res = {};
  res.content = fs.readFileSync(fp, 'utf8');
  res.path = fp;
  return res;
}

/**
 * Files cache.
 */

function memo(name, cwd, patterns, fn) {
  var key = name + ':' + cwd + '/' + patterns;
  return function () {
    if (cache.hasOwnProperty(key)) {
      return cache[key];
    }
    return (cache[key] = fn.apply(fn, arguments));
  };
}
<|endoftext|>


<commit_before>const openweatherConfig = require('../config/openweather.json');
const servicelimitConfig  =  require('../config/servicelimits.json');
const http = require('http');
const Koa = require('koa');
const router = require('./router');

class JBweatherService {
  constructor() {
  }

  bootStrapConfig() {
    if(servicelimitConfig.ratelimit.max > openweatherConfig.account.default.max) {
      throw('Invalid configuration, JB limits cannot exceed openweather limits');
    }
  }

  start() {
    try{
      this.bootStrapConfig();

    } catch(ex) {
      throw(ex);
    }
  }
}

// const server = new JBweatherService();
// server.start();

const app = new Koa();
app.use(router);
http
  .createServer(app.callback())
  .listen(8009);
console.log("Weather service listening on 8099"); <commit_msg>Update server.js<commit_after>const openweatherConfig = require('../config/openweather.json');
const servicelimitConfig  =  require('../config/servicelimits.json');
const http = require('http');
const Koa = require('koa');
const router = require('./router');

class JBweatherService {
  constructor() {
  }

  bootStrapConfig() {
    if(servicelimitConfig.ratelimit.max > openweatherConfig.account.default.max) {
      throw('Invalid configuration, JB limits cannot exceed openweather limits');
    }
  }

  start() {
    try{
      this.bootStrapConfig();

    } catch(ex) {
      throw(ex);
    }
  }
}

// const server = new JBweatherService();
// server.start();

const app = new Koa();
app.use(router);
http
  .createServer(app.callback())
  .listen(8009);
console.log("Weather service listening on 8009");
<|endoftext|>


<commit_before>'use strict';

var debug = require('debug')('licenses::parse')
  , Registry = require('npm.js')
  , async = require('async')
  , url = require('url');

/**
 * Start searching for license information for the given module name.
 *
 * Options:
 *
 * - githulk: A pre-configured githulk instance.
 * - order: The order of resolving license information.
 * - npmjs: A pre-configured npm.js instance.
 * - registry: A registry to use for the npmjs instance.
 *
 * @param {Mixed} name The module name or the package.json contents.
 * @param {Object} options Configuration of the parse process.
 * @param {Function} fn Callback.
 * @api public
 */
function parse(name, options, fn) {
  if ('function' === typeof options) {
    fn = options;
    options = null;
  }

  options = options || {};
  options.githulk = options.githulk || null;
  options.order = options.order || ['registry', 'github', 'content'];
  options.registry = options.registy || Registry.mirrors.nodejitsu;
  options.npmjs = options.npmjs || new Registry({
    registry: options.registry,
    githulk: options.githulk
  });

  async.waterfall([
    //
    // Make sure that we have the correct contents to start searching for
    // license information.
    //
    function fetch(next) {
      if ('string' !== typeof name) return next(undefined, name);

      options.npmjs.packages.get(name, next);
    },

    //
    // Search for the correct way of parsing out the license information.
    //
    function search(data, next) {
      if (!options.order.length) return next();
      if (Array.isArray(data)) data = data[0];

      debug('searching for licensing information for %s', data.name);

      var parser, result, name;

      async.doWhilst(function does(next) {
        name = options.order.shift();
        parser = parse.parsers[name];

        if (!parser.supported(data)) return next();

        debug('attempting to extract the license information using: %s', name);

        parser.parse(data, options, function parsed(err, license) {
          if (err) return next(err);

          result = license;

          if (result) debug('parsing with %s was successful', name);
          next();
        });
      }, function select() {
        return !result && options.order.length;
      }, function done(err) {
        next(err, result, name);
      });
    }
  ], fn);
}

//
// Expose the Parser class so we easily add new parsers through third-party if
// needed. (Think bitbucket and other code hosting sites)
//
parse.Registry = require('./registry'); // Parse license out of package
parse.Content = require('./content');   // Parse license of out file content.
parse.Parser  = require('./parser');    // Base parser class.
parse.Github  = require('./github');    // Parse license info from github.

//
// Expose our primary parsers that we can leverage to retrieve license content.
//
parse.parsers = {};
parse.parsers.registry  = new parse.Registry(parse.parsers);
parse.parsers.content   = new parse.Content(parse.parsers);
parse.parsers.github    = new parse.Github(parse.parsers);

//
// Expose the actual module.
//
module.exports = parse;
<commit_msg>[minor] Just clean up references<commit_after>'use strict';

var debug = require('debug')('licenses::parse')
  , Registry = require('npm.js')
  , async = require('async')
  , url = require('url');

/**
 * Start searching for license information for the given module name.
 *
 * Options:
 *
 * - githulk: A pre-configured githulk instance.
 * - order: The order of resolving license information.
 * - npmjs: A pre-configured npm.js instance.
 * - registry: A registry to use for the npmjs instance.
 *
 * @param {Mixed} name The module name or the package.json contents.
 * @param {Object} options Configuration of the parse process.
 * @param {Function} fn Callback.
 * @api public
 */
function parse(name, options, fn) {
  if ('function' === typeof options) {
    fn = options;
    options = null;
  }

  options = options || {};
  options.githulk = options.githulk || null;
  options.order = options.order || ['registry', 'github', 'content'];
  options.registry = options.registy || Registry.mirrors.nodejitsu;
  options.npmjs = options.npmjs || new Registry({
    registry: options.registry,
    githulk: options.githulk
  });

  async.waterfall([
    //
    // Make sure that we have the correct contents to start searching for
    // license information.
    //
    function fetch(next) {
      if ('string' !== typeof name) return next(undefined, name);

      options.npmjs.packages.get(name, next);
    },

    //
    // Search for the correct way of parsing out the license information.
    //
    function search(data, next) {
      if (!options.order.length) return next();
      if (Array.isArray(data)) data = data[0];

      debug('searching for licensing information for %s', data.name);

      var parser, result, name;

      async.doWhilst(function does(next) {
        name = options.order.shift();
        parser = parse.parsers[name];

        if (!parser.supported(data)) return next();

        debug('attempting to extract the license information using: %s', name);

        parser.parse(data, options, function parsed(err, license) {
          if (err) return next(err);

          result = license;

          if (result) debug('parsing with %s was successful', name);
          next();
        });
      }, function select() {
        return !result && options.order.length;
      }, function cleanup(err) {
        options = null;
        next(err, result, name);
      });
    }
  ], fn);
}

//
// Expose the Parser class so we easily add new parsers through third-party if
// needed. (Think bitbucket and other code hosting sites)
//
parse.Registry = require('./registry'); // Parse license out of package
parse.Content = require('./content');   // Parse license of out file content.
parse.Parser  = require('./parser');    // Base parser class.
parse.Github  = require('./github');    // Parse license info from github.

//
// Expose our primary parsers that we can leverage to retrieve license content.
//
parse.parsers = {};
parse.parsers.registry  = new parse.Registry(parse.parsers);
parse.parsers.content   = new parse.Content(parse.parsers);
parse.parsers.github    = new parse.Github(parse.parsers);

//
// Expose the actual module.
//
module.exports = parse;
<|endoftext|>


<commit_before>'use strict'
GLOBAL.__IS_BROWSER__ = false

let Hapi = require('hapi')
let R = require('ramda')
let path = require('path')
let jade = require('jade')
let immstruct = require('immstruct')
let Boom = require('boom')
let Logger = require('js-logger-aknudsen')
let logger = Logger.get('server')
Logger.useDefaults({
  formatter: (messages, context) => {
    messages.unshift(`${context.level.name} - [${context.name}]`)
  },
})

let server = new Hapi.Server({
  connections: {
    routes: {
      files: {
        relativeTo: path.join(__dirname, '../public'),
      },
    },
  },
})
let port = 8000
server.connection({
  host: '0.0.0.0',
  port,
})

server.register(R.map((x) => {return require(x)}, ['inert', 'vision',]), (err) => {
  if (err != null) {
    throw err
  }

  server.views({
    engines: { jade, },
    path: __dirname + '/templates',
    compileOptions: {
      pretty: true,
    },
  })

  server.route({
    method: ['GET',],
    path: '/{path*}',
    handler: (request, reply) => {
      reply.view('index')
    },
  })
  server.route({
    method: ['GET',],
    path: '/bundle.js',
    handler: {
      file: path.join(__dirname, '../dist/bundle.js'),
    },
  })
  server.route({
    method: 'GET',
    path: '/assets/{param*}',
    handler: {
      directory: {
        path: '.',
        redirectToSlash: true,
        listing: true,
      },
    },
  })

  server.start((err) => {
    if (err != null) {
      logger.error(`Failed to start server: ${err}`)
      process.exit(1)
    } else {
      logger.info('Server running at', server.info.uri)
    }
  })
})
<commit_msg>Make port configurable<commit_after>'use strict'
GLOBAL.__IS_BROWSER__ = false

let Hapi = require('hapi')
let R = require('ramda')
let path = require('path')
let jade = require('jade')
let immstruct = require('immstruct')
let Boom = require('boom')
let Logger = require('js-logger-aknudsen')
let logger = Logger.get('server')
Logger.useDefaults({
  formatter: (messages, context) => {
    messages.unshift(`${context.level.name} - [${context.name}]`)
  },
})

let server = new Hapi.Server({
  connections: {
    routes: {
      files: {
        relativeTo: path.join(__dirname, '../public'),
      },
    },
  },
})
let port = parseInt(process.env.PORT || '8000')
server.connection({
  host: '0.0.0.0',
  port,
})

server.register(R.map((x) => {return require(x)}, ['inert', 'vision',]), (err) => {
  if (err != null) {
    throw err
  }

  server.views({
    engines: { jade, },
    path: __dirname + '/templates',
    compileOptions: {
      pretty: true,
    },
  })

  server.route({
    method: ['GET',],
    path: '/{path*}',
    handler: (request, reply) => {
      reply.view('index')
    },
  })
  server.route({
    method: ['GET',],
    path: '/bundle.js',
    handler: {
      file: path.join(__dirname, '../dist/bundle.js'),
    },
  })
  server.route({
    method: 'GET',
    path: '/assets/{param*}',
    handler: {
      directory: {
        path: '.',
        redirectToSlash: true,
        listing: true,
      },
    },
  })

  server.start((err) => {
    if (err != null) {
      logger.error(`Failed to start server: ${err}`)
      process.exit(1)
    } else {
      logger.info('Server running at', server.info.uri)
    }
  })
})
<|endoftext|>


<commit_before>
/* !
 * vector2
 * JavaScript math library for 2d vector
 * Copyright (c) 2012 Enrico Marino (http://onirame.no.de)
 * MIT License
 */

 !(function (exports) {

  /**
   * Library namespace.
   */

  var vector2 = exports.vector2 = {};

  /**
   * Library version.
   */

  vector2.version = '0.0.0';

  /**
   * create
   * Create a 2d vector.
   *
   * @return {Float32Array} a 2d vector
   * @api public
   */

  vector2.create = function () {
    return new Float32Array([0.0, 0.0]);
  };

  /**
   * set
   * Set vector.
   *
   * @param {Float32Array} self destination vector
   * @param {Float32Array} v source vector
   * @return {Float32Array} destination vector
   * @api public
   */

  vector2.set = function (self, v) {
    self[0] = v[0];
    self[1] = v[1];

    return self;
  };

  /**
   * zero
   * Set vector to zero.
   *
   * @param {Float32Array} self destination vector
   * @return {Float32Array} destination vector
   * @api public
   */

  vector2.zero = function (self) {
    self[0] = 0.0;
    self[1] = 0.0;

    return self;
  };

  /**
   * sum
   * Set vector to the sum of `a` and `b`.
   *
   * @param {Float32Array} self destination vector
   * @param {Float32Array} a vector
   * @param {Float32Array} b vector
   * @return {Float32Array} destination vector
   * @api public
   */

  vector2.sum = function (self, a, b) {
    self[0] = a[0] + b[0];
    self[1] = a[1] + b[1];

    return self;
  };

  /**
   * diff
   * Set vector to the difference of `a` and `b`.
   *
   * @param {Float32Array} self destination vector
   * @param {Float32Array} a vector
   * @param {Float32Array} b vector
   * @return {Float32Array} destination vector
   * @api public
   */

  vector2.diff = function (self, a, b) {
    self[0] = a[0] - b[0];
    self[1] = a[1] - b[1];

    return self;
  };

  /**
   * add
   * Add vector.
   *
   * @param {Float32Array} self destination vector
   * @param {Float32Array} v vector
   * @return {Float32Array} destination vector
   * @api public
   */

  vector2.add = function (self, v) {
    self[0] += v[0];
    self[1] += v[1];

    return self;
  };

  /**
   * sub
   * Sub vector.
   *
   * @param {Float32Array} self destination vector
   * @param {Float32Array} v vector
   * @return {Float32Array} destination vector
   * @api public
   */

  vector2.sub = function (self, v) {
    self[0] -= v[0];
    self[1] -= v[1];

    return self;
  };

  /**
   * diff
   * Set vector to the opposite of `v`.
   *
   * @param {Float32Array} self destination vector
   * @param {Float32Array} v vector
   * @return {Float32Array} destination vector
   * @api public
   */

  vector2.opposite = function (self, v) {
    self[0] = -v[0];
    self[1] = -v[1];

    return self;
  };

  /**
   * neg
   * Negate vector.
   *
   * @param {Float32Array} self destination vector
   * @return {Float32Array} destination vector
   * @api public
   */

  vector2.neg = function (self) {
    self[0] = -self[0];
    self[1] = -self[1];

    return self;
  };

  /**
   * scale
   * Scale vector.
   *
   * @param {Float32Array} self destination vector
   * @param {Number} k scaling value
   * @return {Float32Array} destination vector
   * @api public
   */

  vector2.scale = function (self, k) {
    self[0] *= k;
    self[1] *= k;

    return self;
  };

  /**
   * length
   * Get vector length.
   *
   * @param {Float32Array} self vector
   * @return {Number} vector length
   * @api public
   */

  vector2.length = function (self) {
    var x = self[0];
    var y = self[1];

    return sqrt(x*x + y*y);
  };

}(this));<commit_msg>added vector2.length_squared<commit_after>
/* !
 * vector2
 * JavaScript math library for 2d vector
 * Copyright (c) 2012 Enrico Marino (http://onirame.no.de)
 * MIT License
 */

 !(function (exports) {

  /**
   * Library namespace.
   */

  var vector2 = exports.vector2 = {};

  /**
   * Library version.
   */

  vector2.version = '0.0.0';

  /**
   * create
   * Create a 2d vector.
   *
   * @return {Float32Array} a 2d vector
   * @api public
   */

  vector2.create = function () {
    return new Float32Array([0.0, 0.0]);
  };

  /**
   * set
   * Set vector.
   *
   * @param {Float32Array} self destination vector
   * @param {Float32Array} v source vector
   * @return {Float32Array} destination vector
   * @api public
   */

  vector2.set = function (self, v) {
    self[0] = v[0];
    self[1] = v[1];

    return self;
  };

  /**
   * zero
   * Set vector to zero.
   *
   * @param {Float32Array} self destination vector
   * @return {Float32Array} destination vector
   * @api public
   */

  vector2.zero = function (self) {
    self[0] = 0.0;
    self[1] = 0.0;

    return self;
  };

  /**
   * sum
   * Set vector to the sum of `a` and `b`.
   *
   * @param {Float32Array} self destination vector
   * @param {Float32Array} a vector
   * @param {Float32Array} b vector
   * @return {Float32Array} destination vector
   * @api public
   */

  vector2.sum = function (self, a, b) {
    self[0] = a[0] + b[0];
    self[1] = a[1] + b[1];

    return self;
  };

  /**
   * diff
   * Set vector to the difference of `a` and `b`.
   *
   * @param {Float32Array} self destination vector
   * @param {Float32Array} a vector
   * @param {Float32Array} b vector
   * @return {Float32Array} destination vector
   * @api public
   */

  vector2.diff = function (self, a, b) {
    self[0] = a[0] - b[0];
    self[1] = a[1] - b[1];

    return self;
  };

  /**
   * add
   * Add vector.
   *
   * @param {Float32Array} self destination vector
   * @param {Float32Array} v vector
   * @return {Float32Array} destination vector
   * @api public
   */

  vector2.add = function (self, v) {
    self[0] += v[0];
    self[1] += v[1];

    return self;
  };

  /**
   * sub
   * Sub vector.
   *
   * @param {Float32Array} self destination vector
   * @param {Float32Array} v vector
   * @return {Float32Array} destination vector
   * @api public
   */

  vector2.sub = function (self, v) {
    self[0] -= v[0];
    self[1] -= v[1];

    return self;
  };

  /**
   * diff
   * Set vector to the opposite of `v`.
   *
   * @param {Float32Array} self destination vector
   * @param {Float32Array} v vector
   * @return {Float32Array} destination vector
   * @api public
   */

  vector2.opposite = function (self, v) {
    self[0] = -v[0];
    self[1] = -v[1];

    return self;
  };

  /**
   * neg
   * Negate vector.
   *
   * @param {Float32Array} self destination vector
   * @return {Float32Array} destination vector
   * @api public
   */

  vector2.neg = function (self) {
    self[0] = -self[0];
    self[1] = -self[1];

    return self;
  };

  /**
   * scale
   * Scale vector.
   *
   * @param {Float32Array} self destination vector
   * @param {Number} k scaling value
   * @return {Float32Array} destination vector
   * @api public
   */

  vector2.scale = function (self, k) {
    self[0] *= k;
    self[1] *= k;

    return self;
  };

  /**
   * length
   * Get vector length.
   *
   * @param {Float32Array} self vector
   * @return {Number} vector length
   * @api public
   */

  vector2.length = function (self) {
    var x = self[0];
    var y = self[1];

    return sqrt(x*x + y*y);
  };

  /**
   * length_squared
   * Get vector length squared.
   *
   * @param {Float32Array} self vector
   * @return {Number} vector length
   * @api public
   */

  vector2.length_squared = function (self) {
    var x = self[0];
    var y = self[1];

    return (x*x + y*y);
  };

}(this));<|endoftext|>


<commit_before>var venfix = require('venfix'),
    cssTranslate = require('css-translate');

function Sprite(image){
    var sprite = this;

    sprite.element = document.createElement('span');
    sprite.element.style.display = 'inline-block';
    sprite.element.style.overflow = 'hidden';

    if(typeof image === 'string'){
        var src = image;
        image = new Image();
        image.src = src;
    }

    sprite.image = image;

    if(image.height > 0 || image.width > 0){
        sprite.ready();
        return;
    }

    image.addEventListener('load', function(){
        sprite.ready();
    });
}

Sprite.prototype.ready = function(){
    this.element.style.height = this.image.height;
    this.element.style.width = this.image.height;
    this.element.appendChild(this.image);
};

Sprite.prototype.animate = function(){

    var sprite = this,
        theActualyFuckRightShit = parseFloat(this.element.style.width),
        steps = this.image.width / theActualyFuckRightShit,
        currentStep = 1;

    function step(){

        sprite.image.style[venfix('transform')] = cssTranslate('3d', -theActualyFuckRightShit * currentStep, 0, 0);
        currentStep++;
        if(currentStep > steps){
            return;
        }

        requestAnimationFrame(step);
    }

    step();
};

module.exports = Sprite;<commit_msg>clone image<commit_after>var venfix = require('venfix'),
    cssTranslate = require('css-translate');

function Sprite(image){
    var sprite = this;

    sprite.element = document.createElement('span');
    sprite.element.style.display = 'inline-block';
    sprite.element.style.overflow = 'hidden';

    if(typeof image === 'string'){
        var src = image;
        image = new Image();
        image.src = src;
    }

    image = image.cloneNode();
    sprite.image = image;

    if(image.height > 0 || image.width > 0){
        sprite.ready();
        return;
    }

    image.addEventListener('load', function(){
        sprite.ready();
    });
}

Sprite.prototype.ready = function(){
    this.element.style.height = this.image.height;
    this.element.style.width = this.image.height;
    this.element.appendChild(this.image);
};

Sprite.prototype.animate = function(){

    var sprite = this,
        theActualyFuckRightShit = parseFloat(this.element.style.width),
        steps = this.image.width / theActualyFuckRightShit,
        currentStep = 1;

    function step(){

        sprite.image.style[venfix('transform')] = cssTranslate('3d', -theActualyFuckRightShit * currentStep, 0, 0);
        currentStep++;
        if(currentStep > steps){
            return;
        }

        requestAnimationFrame(step);
    }

    step();
};

module.exports = Sprite;<|endoftext|>


<commit_before>/*------------------------------------*
 Server
 *------------------------------------*/

var express         = require('express');
var exphbs          = require('express-handlebars');
var passport        = require('passport');
var util            = require('util');
var https           = require('https');
var fs              = require('fs');
var cookieParser    = require('cookie-parser');
var session         = require('express-session');
var BnetStrategy    = require('passport-bnet').Strategy;
var KEYS            = require('./keys');
var BNET_ID         = KEYS.key;
var BNET_SECRET     = KEYS.secret;

/*------------------------------------*
 Passport setup
 *------------------------------------*/

passport.serializeUser(function(user, done) {
    done(null, user);
});

passport.deserializeUser(function(obj, done) {
    done(null, obj);
});

// Use the BnetStrategy within Passport.
passport.use(new BnetStrategy({
        clientID: BNET_ID,
        clientSecret: BNET_SECRET,
        scope: 'wow.profile',
        callbackURL: 'https://wowguild.jordanranson.com:3000/auth/bnet/callback'
    },
    function(accessToken, refreshToken, profile, done) {
        process.nextTick(function () {
            return done(null, profile);
        });
    })
);

/*------------------------------------*
 Express/HTTP server setup
 *------------------------------------*/

var app = express();

// configure Express
app.use(cookieParser());
app.use(session({
    secret: 'blizzard',
    saveUninitialized: true,
    resave: true
}));

app.engine('.hbs', exphbs({
    defaultLayout: 'master',
    extname: '.hbs',
    helpers: {
        section: function(name, options){
            if(!this._sections) this._sections = {};
            this._sections[name] = options.fn(this);
            return null;
        }
    }
}));
app.set('view engine', '.hbs');

// Initialize Passport
app.use(passport.initialize());
app.use(passport.session());

/*------------------------------------*
 Routes
 *------------------------------------*/

// static content
console.log('Serving static files at', __dirname + '/public/');
app.use('/public', express.static(__dirname + '/public/'));

// authentication
app.get('/auth/bnet',           passport.authenticate('bnet') );
app.get('/auth/bnet/callback',  passport.authenticate('bnet', { failureRedirect: '/' }), function(req, res) {
      res.redirect('/');
});
app.get('/logout', function(req, res) {
    req.logout();
    res.redirect('/');
});

// home
app.get('/', function(req, res) {
    if(req.isAuthenticated()) {
        res.render('home', {
            user: req.user
        });
    } else {
        res.render('home', {
            user: null
        });
    }
});

// topics
app.get('/topics', function(req, res) {
    if(req.isAuthenticated()) {
        res.render('topics', {
            user: req.user
        });
    } else {
        res.render('topics', {
            user: null
        });
    }
});

// threads
app.get('/threads', function(req, res) {
    if(req.isAuthenticated()) {
        res.render('threads', {
            user: req.user
        });
    } else {
        res.render('threads', {
            user: null
        });
    }
});

// thread
app.get('/thread', function(req, res) {
    if(req.isAuthenticated()) {
        res.render('thread', {
            user: req.user
        });
    } else {
        res.render('thread', {
            user: null
        });
    }
});

// roster
app.get('/roster', function(req, res) {
    if(req.isAuthenticated()) {
        res.render('roster', {
            user: req.user
        });
    } else {
        res.render('roster', {
            user: null
        });
    }
});

// gallery
app.get('/gallery', function(req, res) {
    if(req.isAuthenticated()) {
        res.render('gallery', {
            user: req.user
        });
    } else {
        res.render('gallery', {
            user: null
        });
    }
});

/*------------------------------------*
 Initialization
 *------------------------------------*/

var key  = fs.readFileSync('./wowguild.jordanranson.com.key', 'utf8');
var cert = fs.readFileSync('./wowguild.jordanranson.com.cert', 'utf8');
var credentials = { key: key, cert: cert }; // ssl
var server      = https.createServer(credentials, app);
var http        = express();

// set up a route to redirect http to https (shitty, I need to improve this)
http.get('*',function(req,res){
    res.redirect('https://wowguild.jordanranson.com:3000'+req.url)
});
http.listen(8080);

// start real server
server.listen(3000, function() {
    console.log('Listening on port %d', server.address().port);
});<commit_msg>Logging user object<commit_after>/*------------------------------------*
 Server
 *------------------------------------*/

var express         = require('express');
var exphbs          = require('express-handlebars');
var passport        = require('passport');
var util            = require('util');
var https           = require('https');
var fs              = require('fs');
var cookieParser    = require('cookie-parser');
var session         = require('express-session');
var BnetStrategy    = require('passport-bnet').Strategy;
var KEYS            = require('./keys');
var BNET_ID         = KEYS.key;
var BNET_SECRET     = KEYS.secret;

/*------------------------------------*
 Passport setup
 *------------------------------------*/

passport.serializeUser(function(user, done) {
    done(null, user);
});

passport.deserializeUser(function(obj, done) {
    done(null, obj);
});

// Use the BnetStrategy within Passport.
passport.use(new BnetStrategy({
        clientID: BNET_ID,
        clientSecret: BNET_SECRET,
        scope: 'wow.profile',
        callbackURL: 'https://wowguild.jordanranson.com:3000/auth/bnet/callback'
    },
    function(accessToken, refreshToken, profile, done) {
        process.nextTick(function () {
            return done(null, profile);
        });
    })
);

/*------------------------------------*
 Express/HTTP server setup
 *------------------------------------*/

var app = express();

// configure Express
app.use(cookieParser());
app.use(session({
    secret: 'blizzard',
    saveUninitialized: true,
    resave: true
}));

app.engine('.hbs', exphbs({
    defaultLayout: 'master',
    extname: '.hbs',
    helpers: {
        section: function(name, options){
            if(!this._sections) this._sections = {};
            this._sections[name] = options.fn(this);
            return null;
        }
    }
}));
app.set('view engine', '.hbs');

// Initialize Passport
app.use(passport.initialize());
app.use(passport.session());

/*------------------------------------*
 Routes
 *------------------------------------*/

// static content
console.log('Serving static files at', __dirname + '/public/');
app.use('/public', express.static(__dirname + '/public/'));

// authentication
app.get('/auth/bnet',           passport.authenticate('bnet') );
app.get('/auth/bnet/callback',  passport.authenticate('bnet', { failureRedirect: '/' }), function(req, res) {
      res.redirect('/');
});
app.get('/logout', function(req, res) {
    req.logout();
    res.redirect('/');
});

// home
app.get('/', function(req, res) {
    if(req.isAuthenticated()) {
        console.log("User: %j", req.user);
        res.render('home', {
            user: req.user
        });
    } else {
        res.render('home', {
            user: null
        });
    }
});

// topics
app.get('/topics', function(req, res) {
    if(req.isAuthenticated()) {
        res.render('topics', {
            user: req.user
        });
    } else {
        res.render('topics', {
            user: null
        });
    }
});

// threads
app.get('/threads', function(req, res) {
    if(req.isAuthenticated()) {
        res.render('threads', {
            user: req.user
        });
    } else {
        res.render('threads', {
            user: null
        });
    }
});

// thread
app.get('/thread', function(req, res) {
    if(req.isAuthenticated()) {
        res.render('thread', {
            user: req.user
        });
    } else {
        res.render('thread', {
            user: null
        });
    }
});

// roster
app.get('/roster', function(req, res) {
    if(req.isAuthenticated()) {
        res.render('roster', {
            user: req.user
        });
    } else {
        res.render('roster', {
            user: null
        });
    }
});

// gallery
app.get('/gallery', function(req, res) {
    if(req.isAuthenticated()) {
        res.render('gallery', {
            user: req.user
        });
    } else {
        res.render('gallery', {
            user: null
        });
    }
});

/*------------------------------------*
 Initialization
 *------------------------------------*/

var key  = fs.readFileSync('./wowguild.jordanranson.com.key', 'utf8');
var cert = fs.readFileSync('./wowguild.jordanranson.com.cert', 'utf8');
var credentials = { key: key, cert: cert }; // ssl
var server      = https.createServer(credentials, app);
var http        = express();

// set up a route to redirect http to https (shitty, I need to improve this)
http.get('*',function(req,res){
    res.redirect('https://wowguild.jordanranson.com:3000'+req.url)
});
http.listen(8080);

// start real server
server.listen(3000, function() {
    console.log('Listening on port %d', server.address().port);
});<|endoftext|>


<commit_before>/*!
 * Pact
 * Copyright 2011 Yahoo! Inc.
 * Licensed under the BSD license.
 */

/**
 * Dependencies.
 */
var assert = require('assert');

var http = require('./lib/http');
var STATUS_CODES = require('http').STATUS_CODES;

/**
 * A starting server port number.
 */
var _port = 8099;

/**
 * Factory for server port numbers.
 *
 * @return {Number} port A new port number.
 */
function getPort() {
    return _port++;
}

/**
 * Return a function that makes an HTTP request
 * according to what's specified in the provided `req`
 * object.
 *
 * Relative 302 redirects will be followed.
 *
 * You can specify:
 *
 * - url: The path to request. Defaults to a path as the second word of
 *   a context.
 * - method: Defaults to GET.
 * - data: Request body for POST.
 * - headers: HTTP request headers object.
 *
 * These are all optional.
 *
 * Instead of specifying `url` in `req`, you can make it the second word of
 * your context. This lets you omit `req` completely, for example:
 *
 *     "when /foo/bar/baz is requested" : {
 *          topic : request(),
 *          "should succeed" : code(200)
 *     }
 *
 * Your test functions will recieve an object containing:
 *
 *  - body: The response body, which is an object if the response was
 *    application/json.
 *  - status: HTTP status code.
 *  - headers: HTTP headers as an object, with headers in lowercase.
 *
 * A topic function.
 *
 * For an example test function, {@see code}.
 *
 * @param {Object} req Request object.
 * @return {Function} Topic function that makes the request.
 */
function request(req) {
    var path, options = {
        host: 'localhost',
        method: 'GET'
    };
    if (req) {
        if ('url' in req) path = options.path = req.url;
        if ('data' in req) options.body = req.data;
        if ('method' in req) options.method = req.method;
        if ('headers' in req) options.headers = req.headers;
    }
    return function(lastTopic) {
        var vow = this;
        // try to find port number
        var port = Array.prototype.slice.call(arguments, -1)[0];
        if (!isNaN(port))
            options.port = port;
        else throw new Error('Unable to determine port from topic.');
        if ('function' === typeof path)
            options.path = path(lastTopic);
        else if (!path)
            options.path = vow.context.name.split(/ +/)[1];
        http.request(
            options
        ).on('response', function X(res, results) {
            var err = null;
            if (res.statusCode === 302) { // handle redirects
                if (options._302) {
                    err = 'Redirect loop';
                } else {
                    var location = res.headers.location;
                    if (location.indexOf('/') === 0) {
                        // relative path, don't handle absolute
                        options.path = location;
                        options._302 = true;
                        return http.request(options).on('response', X);
                    }
                }
            }
            vow.callback(err, {
                body: results,
                status: res.statusCode,
                headers: res.headers
            });
        });
    }
}

/**
 * Return a function that starts a `http.Server` listening on 127.0.0.1.
 *
 * Your test functions will recieve the port the server is listening on.
 *
 * A topic function.
 *
 * @param {Object} server `http.Server` instance.
 * @param {Number} port Optional. Port to listen on.
 * @return {Function} Topic function that starts the server.
 */
function httpify(server, port) {
    port = port || getPort();
    return function() {
        var vows = this;
        server.listen(port, '127.0.0.1', function(err) {
            vows.callback(err, port);
        });
    };
}

/**
 * Return a function that asserts that `status` matches httpify's status.
 *
 * A test function.
 *
 * @see httpify
 * @param {Number} status Expected HTTP status code.
 * @return {Function} Test function that checks the status.
 */
function code(status) {
    return function(lastTopic) {
        assert.strictEqual(lastTopic.status, status,
            'Expected ' + status +
                  ' ' + STATUS_CODES[status] +
                  ', received: ' + lastTopic.status +
                  ' ' + STATUS_CODES[lastTopic.status] +
                  '.\n' + lastTopic.body
        );
    };
}

/**
 * Export these functions.
 */
module.exports = {
    code: code,
    request: request,
    httpify: httpify
};
<commit_msg>Increase the starting port number.<commit_after>/*!
 * Pact
 * Copyright 2011 Yahoo! Inc.
 * Licensed under the BSD license.
 */

/**
 * Dependencies.
 */
var assert = require('assert');

var http = require('./lib/http');
var STATUS_CODES = require('http').STATUS_CODES;

/**
 * A starting server port number.
 */
var _port = 19100;

/**
 * Factory for server port numbers.
 *
 * @return {Number} port A new port number.
 */
function getPort() {
    return ++_port;
}

/**
 * Return a function that makes an HTTP request
 * according to what's specified in the provided `req`
 * object.
 *
 * Relative 302 redirects will be followed.
 *
 * You can specify:
 *
 * - url: The path to request. Defaults to a path as the second word of
 *   a context.
 * - method: Defaults to GET.
 * - data: Request body for POST.
 * - headers: HTTP request headers object.
 *
 * These are all optional.
 *
 * Instead of specifying `url` in `req`, you can make it the second word of
 * your context. This lets you omit `req` completely, for example:
 *
 *     "when /foo/bar/baz is requested" : {
 *          topic : request(),
 *          "should succeed" : code(200)
 *     }
 *
 * Your test functions will recieve an object containing:
 *
 *  - body: The response body, which is an object if the response was
 *    application/json.
 *  - status: HTTP status code.
 *  - headers: HTTP headers as an object, with headers in lowercase.
 *
 * A topic function.
 *
 * For an example test function, {@see code}.
 *
 * @param {Object} req Request object.
 * @return {Function} Topic function that makes the request.
 */
function request(req) {
    var path, options = {
        host: 'localhost',
        method: 'GET'
    };
    if (req) {
        if ('url' in req) path = options.path = req.url;
        if ('data' in req) options.body = req.data;
        if ('method' in req) options.method = req.method;
        if ('headers' in req) options.headers = req.headers;
    }
    return function(lastTopic) {
        var vow = this;
        // try to find port number
        var port = Array.prototype.slice.call(arguments, -1)[0];
        if (!isNaN(port))
            options.port = port;
        else throw new Error('Unable to determine port from topic.');
        if ('function' === typeof path)
            options.path = path(lastTopic);
        else if (!path)
            options.path = vow.context.name.split(/ +/)[1];
        http.request(
            options
        ).on('response', function X(res, results) {
            var err = null;
            if (res.statusCode === 302) { // handle redirects
                if (options._302) {
                    err = 'Redirect loop';
                } else {
                    var location = res.headers.location;
                    if (location.indexOf('/') === 0) {
                        // relative path, don't handle absolute
                        options.path = location;
                        options._302 = true;
                        return http.request(options).on('response', X);
                    }
                }
            }
            vow.callback(err, {
                body: results,
                status: res.statusCode,
                headers: res.headers
            });
        });
    }
}

/**
 * Return a function that starts a `http.Server` listening on 127.0.0.1.
 *
 * Your test functions will recieve the port the server is listening on.
 *
 * A topic function.
 *
 * @param {Object} server `http.Server` instance.
 * @param {Number} port Optional. Port to listen on.
 * @return {Function} Topic function that starts the server.
 */
function httpify(server, port) {
    port = port || getPort();
    return function() {
        var vows = this;
        server.listen(port, '127.0.0.1', function(err) {
            vows.callback(err, port);
        });
    };
}

/**
 * Return a function that asserts that `status` matches httpify's status.
 *
 * A test function.
 *
 * @see httpify
 * @param {Number} status Expected HTTP status code.
 * @return {Function} Test function that checks the status.
 */
function code(status) {
    return function(lastTopic) {
        assert.strictEqual(lastTopic.status, status,
            'Expected ' + status +
                  ' ' + STATUS_CODES[status] +
                  ', received: ' + lastTopic.status +
                  ' ' + STATUS_CODES[lastTopic.status] +
                  '.\n' + lastTopic.body
        );
    };
}

/**
 * Export these functions.
 */
module.exports = {
    code: code,
    request: request,
    httpify: httpify
};
<|endoftext|>


<commit_before>'use strict'
GLOBAL.__IS_BROWSER__ = false

let Hapi = require('hapi')
let R = require('ramda')
let path = require('path')
let pug = require('pug')
let immstruct = require('immstruct')
let Boom = require('boom')
let moment = require('moment')
let Url = require('url')
let Logger = require('js-logger-aknudsen')
let logger = Logger.get('server')
Logger.useDefaults({
  formatter: (messages, context) => {
    let time = moment().format('HH:mm:ss')
    messages.unshift(`${context.level.name} ${time} - [${context.name}]`)
  },
})
Logger.setHandler((messages, context) => {
  Logger.getDefaultHandler()(messages, context)

  if (context.level === Logger.ERROR) {
    let appUri = getEnvParam('APP_URI')
    let emailAddress = `contact@muzhack.com`
    logger.debug(`Reporting error by email to '${emailAddress}'...`)
    reportError(messages[0])
  }
})

let auth = require('./server/auth')
let api = require('./server/api')
let rendering = require('./server/rendering')
let db = require('./server/db')
let {getEnvParam,} = require('./server/environment')
let emailer = require('./server/emailer')

let reportError = (message) => {
  emailer.sendEmail({
    emailAddress, name: `MuzHack Admin`,
    subject: `Error Detected in MuzHack at ${appUri}`,
    html: `
An error was detected in MuzHack, at ${appUri}

${message}

`,
  })
}

process.on('uncaughtException', (error) => {
  logger.error(`An uncaught exception occurred: ${error}`, error.stack)
})

let server = new Hapi.Server({
  connections: {
    routes: {
      files: {
        relativeTo: path.join(__dirname, '../public'),
      },
    },
  },
})
let port = parseInt(process.env.PORT || '8000')
server.connection({
  host: '0.0.0.0',
  port,
})

if (process.env.MUZHACK_URI == null) {
  process.env.MUZHACK_URI = `http://localhost:${port}`
}

auth.register(server)

server.register(R.map((x) => {return require(x)}, ['inert', 'vision',]), (err) => {
  if (err != null) {
    throw err
  }

  server.ext('onRequest', (request, reply) => {
    // GKE health check
    if (request.headers['user-agent'].toLowerCase().startsWith('googlehc')) {
      return reply('Healthy')
    } else {
      if (request.headers['x-forwarded-proto'] === 'http') {
        logger.debug(`Redirecting to HTTPS, using $APP_URI: ${process.env.APP_URI}`)
        return reply.redirect(Url.format({
          protocol: 'https',
          hostname: Url.parse(process.env.APP_URI).hostname,
          pathname: request.url.path,
          port: 443,
        }))
      } else {
        logger.debug(`Not redirecting to HTTPS`)
        reply.continue()
      }
    }
  })

  server.views({
    engines: { pug, },
    path: __dirname + '/templates',
    compileOptions: {
      pretty: true,
    },
  })

  server.route({
    method: ['GET',],
    path: '/{path*}',
    handler: rendering.renderIndex,
  })
  server.route({
    method: ['GET',],
    path: '/bundle.js',
    handler: {
      file: path.join(__dirname, '../dist/bundle.js'),
    },
  })
  server.route({
    method: 'GET',
    path: '/assets/{param*}',
    handler: {
      directory: {
        path: '.',
        redirectToSlash: true,
        listing: true,
      },
    },
  })
  server.route({
    method: 'GET',
    path: '/robots.txt',
    handler: (request, reply) => {
      if ((process.env.NODE_ENV || '').toLowerCase() !== 'production') {
        reply(`User-agent: *\nDisallow: /`).header('Content-Type', 'text/plain')
      } else {
        reply()
      }
    },
  })

  api.register(server)

  db.setUp()
    .then(() => {
      server.start((err) => {
        if (err != null) {
          logger.error(`Failed to start server: ${err}`)
          process.exit(1)
        } else {
          logger.info('Server running at', server.info.uri)
        }
      })
    }, (error) => {
      logger.error(`Failed to set up database: '${error}'`)
    })
})
<commit_msg>Fix reference error<commit_after>'use strict'
GLOBAL.__IS_BROWSER__ = false

let Hapi = require('hapi')
let R = require('ramda')
let path = require('path')
let pug = require('pug')
let immstruct = require('immstruct')
let Boom = require('boom')
let moment = require('moment')
let Url = require('url')
let Logger = require('js-logger-aknudsen')
let logger = Logger.get('server')
Logger.useDefaults({
  formatter: (messages, context) => {
    let time = moment().format('HH:mm:ss')
    messages.unshift(`${context.level.name} ${time} - [${context.name}]`)
  },
})
Logger.setHandler((messages, context) => {
  Logger.getDefaultHandler()(messages, context)

  if (context.level === Logger.ERROR) {
    let appUri = getEnvParam('APP_URI')
    let emailAddress = `contact@muzhack.com`
    logger.debug(`Reporting error by email to '${emailAddress}'...`)
    emailer.sendEmail({
      emailAddress, name: `MuzHack Admin`,
      subject: `Error Detected in MuzHack at ${appUri}`,
      html: `
An error was detected in MuzHack, at ${appUri}

  ${message}

  `,
    })
  }
})

let auth = require('./server/auth')
let api = require('./server/api')
let rendering = require('./server/rendering')
let db = require('./server/db')
let {getEnvParam,} = require('./server/environment')
let emailer = require('./server/emailer')

process.on('uncaughtException', (error) => {
  logger.error(`An uncaught exception occurred: ${error}`, error.stack)
})

let server = new Hapi.Server({
  connections: {
    routes: {
      files: {
        relativeTo: path.join(__dirname, '../public'),
      },
    },
  },
})
let port = parseInt(process.env.PORT || '8000')
server.connection({
  host: '0.0.0.0',
  port,
})

if (process.env.MUZHACK_URI == null) {
  process.env.MUZHACK_URI = `http://localhost:${port}`
}

auth.register(server)

server.register(R.map((x) => {return require(x)}, ['inert', 'vision',]), (err) => {
  if (err != null) {
    throw err
  }

  server.ext('onRequest', (request, reply) => {
    // GKE health check
    if (request.headers['user-agent'].toLowerCase().startsWith('googlehc')) {
      return reply('Healthy')
    } else {
      if (request.headers['x-forwarded-proto'] === 'http') {
        logger.debug(`Redirecting to HTTPS, using $APP_URI: ${process.env.APP_URI}`)
        return reply.redirect(Url.format({
          protocol: 'https',
          hostname: Url.parse(process.env.APP_URI).hostname,
          pathname: request.url.path,
          port: 443,
        }))
      } else {
        logger.debug(`Not redirecting to HTTPS`)
        reply.continue()
      }
    }
  })

  server.views({
    engines: { pug, },
    path: __dirname + '/templates',
    compileOptions: {
      pretty: true,
    },
  })

  server.route({
    method: ['GET',],
    path: '/{path*}',
    handler: rendering.renderIndex,
  })
  server.route({
    method: ['GET',],
    path: '/bundle.js',
    handler: {
      file: path.join(__dirname, '../dist/bundle.js'),
    },
  })
  server.route({
    method: 'GET',
    path: '/assets/{param*}',
    handler: {
      directory: {
        path: '.',
        redirectToSlash: true,
        listing: true,
      },
    },
  })
  server.route({
    method: 'GET',
    path: '/robots.txt',
    handler: (request, reply) => {
      if ((process.env.NODE_ENV || '').toLowerCase() !== 'production') {
        reply(`User-agent: *\nDisallow: /`).header('Content-Type', 'text/plain')
      } else {
        reply()
      }
    },
  })

  api.register(server)

  db.setUp()
    .then(() => {
      server.start((err) => {
        if (err != null) {
          logger.error(`Failed to start server: ${err}`)
          process.exit(1)
        } else {
          logger.info('Server running at', server.info.uri)
        }
      })
    }, (error) => {
      logger.error(`Failed to set up database: '${error}'`)
    })
})
<|endoftext|>


<commit_before>var Readable = require('readable-stream').Readable;
var Writable = require('readable-stream').Writable;
var Duplex = require('readable-stream').Duplex;
var inherits = require('inherits');
var through = require('through2');

var tokenize = require('html-tokenize');
var select = require('html-select');
var parseTag = require('html-select/lib/parse_tag.js');

module.exports = Trumpet;
inherits(Trumpet, Duplex);

function Trumpet () {
    var self = this;
    if (!(this instanceof Trumpet)) return new Trumpet;
    Duplex.call(this);
    this._tokenize = tokenize();
    this._writing = false;
    this._piping = false;
    this._select = this._tokenize.pipe(select());
}

Trumpet.prototype.pipe = function () {
    this._piping = true;
    return Duplex.prototype.pipe.apply(this, arguments);
};

Trumpet.prototype._read = function (n) {
    var self = this;
    var buf, read = 0;
    var s = this._select;
    while ((row = s.read()) !== null) {
        this.push(row[1]);
        read ++;
    }
    if (read === 0) s.once('readable', function () { self._read(n) });
};

Trumpet.prototype._write = function (buf, enc, next) {
    if (!this._writing && !this._piping) {
        this._piping = true;
        this.resume();
    }
    return this._tokenize._write(buf, enc, next);
};

Trumpet.prototype.select = function (str, cb) {
    var self = this;
    var first = true;

    var res = self._selectAll(str, function (elem) {
        if (!first) return;
        first = false;
        res.createReadStream = function () {};
        res.createWriteStream = function () {};
        res.createStream = function () {};
        if (cb) cb(elem);
    });
    return res;
};

Trumpet.prototype.selectAll = function (str, cb) {
    return this._selectAll(str, cb);
};

Trumpet.prototype._selectAll = function (str, cb) {
    var self = this;
    var readers = [], writers = [];
    var gets = [];

    var element, welem;
    this._select.select(str, function (elem) {
        element = elem;
        welem = wrapElem(elem);
        if (cb) cb(welem);

        elem.once('close', function () {
            element = null;
            welem = null;
        });

        readers.splice(0).forEach(function (r) {
            welem.createReadStream(r._options).pipe(r);
        });

        writers.splice(0).forEach(function (w) {
            w.pipe(welem.createWriteStream(w._options));
        });

        gets.splice(0).forEach(function (g) {
            welem.getAttribute(g[0], g[1]);
        });
    });

    return {
        getAttribute: function (key, cb) {
            if (welem) return welem.getAttribute(key, cb);
            gets.push([ key, cb ]);
        },
        createReadStream: function (opts) {
            if (welem) return welem.createReadStream(opts);
            var r = through();
            r._options = opts;
            readers.push(r);
            return r;
        },
        createWriteStream: function (opts) {
            if (welem) return welem.createWriteStream(opts);
            var w = through();
            w._options = opts;
            writers.push(w);
            return w;
        }
    };
};

function wrapElem (elem) {
    var tag;
    var first = elem._first;
    function getTag () {
        if (tag) return tag;
        tag = parseTag(first[1]);
        return tag;
    }

    return {
        getAttribute: function (key, cb) {
            var value = getTag().getAttributes()[key];
            if (cb) cb(value);
            return value;
        },
        createReadStream: function (opts) {
            if (!opts) opts = {};
            return elem.createReadStream({ inner: !opts.outer })
                .pipe(through.obj(write, end));
            ;
            function write (row, enc, next) { this.push(row[1]); next() }
            function end (next) { this.push(null); next() }
        },
        createWriteStream: function (opts) {
            if (!opts) opts = {};
            var we = elem.createWriteStream({ inner: !opts.outer });
            var ws = new Writable;
            ws._write = function (row, enc, next) {
                we.write(row[1]);
                next()
            };
            ws.once('finish', function () { we.end() });
            return ws;
        },
        createStream: function (opts) {
            if (!opts) opts = {};
            return elem.createStream({ inner: !opts.outer });
        }
    }

}

Trumpet.prototype.createReadStream = function (sel, opts) {
    return this.select(sel).createReadStream(opts);
};

Trumpet.prototype.createWriteStream = function (sel, opts) {
    return this.select(sel).createWriteStream(opts);
};
<commit_msg>duplex streams<commit_after>var Readable = require('readable-stream').Readable;
var Writable = require('readable-stream').Writable;
var Duplex = require('readable-stream').Duplex;
var inherits = require('inherits');
var through = require('through2');
var duplexer = require('duplexer2');

var tokenize = require('html-tokenize');
var select = require('html-select');
var parseTag = require('html-select/lib/parse_tag.js');

module.exports = Trumpet;
inherits(Trumpet, Duplex);

function Trumpet () {
    var self = this;
    if (!(this instanceof Trumpet)) return new Trumpet;
    Duplex.call(this);
    this._tokenize = tokenize();
    this._writing = false;
    this._piping = false;
    this._select = this._tokenize.pipe(select());
}

Trumpet.prototype.pipe = function () {
    this._piping = true;
    return Duplex.prototype.pipe.apply(this, arguments);
};

Trumpet.prototype._read = function (n) {
    var self = this;
    var buf, read = 0;
    var s = this._select;
    while ((row = s.read()) !== null) {
        this.push(row[1]);
        read ++;
    }
    if (read === 0) s.once('readable', function () { self._read(n) });
};

Trumpet.prototype._write = function (buf, enc, next) {
    if (!this._writing && !this._piping) {
        this._piping = true;
        this.resume();
    }
    return this._tokenize._write(buf, enc, next);
};

Trumpet.prototype.select = function (str, cb) {
    var self = this;
    var first = true;

    var res = self._selectAll(str, function (elem) {
        if (!first) return;
        first = false;
        res.createReadStream = function () {};
        res.createWriteStream = function () {};
        res.createStream = function () {};
        if (cb) cb(elem);
    });
    return res;
};

Trumpet.prototype.selectAll = function (str, cb) {
    return this._selectAll(str, cb);
};

Trumpet.prototype._selectAll = function (str, cb) {
    var self = this;
    var readers = [], writers = [], duplex = [];
    var gets = [];

    var element, welem;
    this._select.select(str, function (elem) {
        element = elem;
        welem = wrapElem(elem);
        if (cb) cb(welem);

        elem.once('close', function () {
            element = null;
            welem = null;
        });

        readers.splice(0).forEach(function (r) {
            welem.createReadStream(r._options).pipe(r);
        });

        writers.splice(0).forEach(function (w) {
            w.pipe(welem.createWriteStream(w._options));
        });

        duplex.splice(0).forEach(function (d) {
            d.pipe(welem.createStream(d._options));
        });

        gets.splice(0).forEach(function (g) {
            welem.getAttribute(g[0], g[1]);
        });
    });

    return {
        getAttribute: function (key, cb) {
            if (welem) return welem.getAttribute(key, cb);
            gets.push([ key, cb ]);
        },
        createReadStream: function (opts) {
            if (welem) return welem.createReadStream(opts);
            var r = through();
            r._options = opts;
            readers.push(r);
            return r;
        },
        createWriteStream: function (opts) {
            if (welem) return welem.createWriteStream(opts);
            var w = through();
            w._options = opts;
            writers.push(w);
            return w;
        },
        createStream: function (opts) {
            if (welem) return welem.createStream(opts);
            var d = through();
            d._options = opts;
            duplex.push(d);
            return d;
        }
    };
};

function wrapElem (elem) {
    var tag;
    var first = elem._first;
    function getTag () {
        if (tag) return tag;
        tag = parseTag(first[1]);
        return tag;
    }

    return {
        getAttribute: function (key, cb) {
            var value = getTag().getAttributes()[key];
            if (cb) cb(value);
            return value;
        },
        createReadStream: function (opts) {
            if (!opts) opts = {};
            return elem.createReadStream({ inner: !opts.outer })
                .pipe(through.obj(write, end));
            ;
            function write (row, enc, next) { this.push(row[1]); next() }
            function end (next) { this.push(null); next() }
        },
        createWriteStream: function (opts) {
            if (!opts) opts = {};
            var we = elem.createWriteStream({ inner: !opts.outer });
            var ws = new Writable;
            ws._write = function (row, enc, next) {
                we.write(row[1]);
                next()
            };
            ws.once('finish', function () { we.end() });
            return ws;
        },
        createStream: function (opts) {
            if (!opts) opts = {};
            var w = through.obj(function (buf, enc, next) {
                this.push([ 'data', buf ]);
                next();
            });
            var r = through.obj(function (row, enc, next) {
                this.push(row[1]);
                next();
            });
            var s = elem.createStream({ inner: !opts.outer });
            w.pipe(s).pipe(r);
            return duplexer(w, r);
        }
    }

}

Trumpet.prototype.createReadStream = function (sel, opts) {
    return this.select(sel).createReadStream(opts);
};

Trumpet.prototype.createWriteStream = function (sel, opts) {
    return this.select(sel).createWriteStream(opts);
};
<|endoftext|>


<commit_before>var Raspi = require("raspi-io");
var five = require("johnny-five");
var pitft = require("pitft");
var sleep = require('sleep');

var fb = pitft("/dev/fb1"); // Returns a framebuffer in direct mode.  See the clock.js example for double buffering mode
var xMax = fb.size().width;
var yMax = fb.size().height;
var latitude;
var longitude;
// Clear the screen buffer
fb.clear();
fb.color(1, 1, 1); // Set the color to whit
fb.font("fantasy", 12); // Use the "fantasy" font with size 12

fb.text(0,20,"Latitude:",false);
fb.text(0,40,"Longitude:",false);
fb.text(0,60,"Speed:",false);
fb.text(0,80,"Course:",false);
fb.text(0,100,"Longitude:",false);
fb.text(0,120,"Balance:",false);
fb.text(0,140,"Volume:",false);
fb.text(0,160,"Stroke Rate:",false);
fb.text(0,180,"/500:",false);
fb.text(0,200,"Race Mode: 5000m",false);
fb.text(0,220,"Estimated Finish time:",false);
//fb.font("fantasy", 12); // Use the "fantasy" font with size 12
//fb.text(0, 20, "HI", false); // Draw the text non-centered, rotated _a_ degrees
//sleep.sleep(5);

console.log("Starting Board");

var board = new five.Board({
  io: new Raspi()
});

function displayPush(){
    console.log("displayPush");
    fb.clear();
    fb.text(0,50,latitude,true);
    fb.text(50,50,longitude,true)     // The function returns the product of p1 and p2
}

board.on("ready", function() {

  console.log("this might work");

  var gps = new five.GPS({
    breakout: "ADAFRUIT_ULTIMATE_GPS",
    pins: ['P1-8', 'P1-10']
  });

  gps.on("change", function() {
    fb.text(0,20,this.latitude,false);
    console.log("position");
    console.log("  latitude   : ", this.latitude);
    console.log("  longitude  : ", this.longitude);
    console.log("--------------------------------------");
  });
});
<commit_msg>alright.<commit_after>var Raspi = require("raspi-io");
var five = require("johnny-five");
var pitft = require("pitft");
var sleep = require('sleep');

var fb = pitft("/dev/fb1"); // Returns a framebuffer in direct mode.  See the clock.js example for double buffering mode
var xMax = fb.size().width;
console.log(xMax);
var yMax = fb.size().height;
console.log(yMax);
var latitude;
var longitude;
// Clear the screen buffer
fb.clear();
fb.color(1, 1, 1); // Set the color to whit
fb.font("fantasy", 12); // Use the "fantasy" font with size 12

fb.text(0,20,"Latitude:",false);
fb.text(0,40,"Longitude:",false);
fb.text(0,60,"Speed:",false);
fb.text(0,80,"Course:",false);
fb.text(0,100,"Longitude:",false);
fb.text(0,120,"Balance:",false);
fb.text(0,140,"Volume:",false);
fb.text(0,160,"Stroke Rate:",false);
fb.text(0,180,"/500:",false);
fb.text(0,200,"Race Mode: 5000m",false);
fb.text(0,220,"Estimated Finish time:",false);
//fb.font("fantasy", 12); // Use the "fantasy" font with size 12
//fb.text(0, 20, "HI", false); // Draw the text non-centered, rotated _a_ degrees
//sleep.sleep(5);

console.log("Starting Board");

var board = new five.Board({
  io: new Raspi()
});

function displayPush(){
    console.log("displayPush");
    fb.clear();
    fb.text(0,50,latitude,true);
    fb.text(50,50,longitude,true)     // The function returns the product of p1 and p2
}

board.on("ready", function() {

  console.log("this might work");

  var gps = new five.GPS({
    breakout: "ADAFRUIT_ULTIMATE_GPS",
    pins: ['P1-8', 'P1-10']
  });

  gps.on("change", function() {
    fb.text(0,20,this.latitude,false);
    console.log("position");
    console.log("  latitude   : ", this.latitude);
    console.log("  longitude  : ", this.longitude);
    console.log("--------------------------------------");
  });
});
<|endoftext|>