<commit_before>// Sample Config
//{
//  "platform": "wssensor",
//  "name": "wssensor",
//  "port": 8080,
//  "refresh": "60",
//  "leak": "10",
//  "aliases": {
//    "NODE-2BA0FF": "Porch Motion"
//  }
//}

'use strict';

var util = require('util');
var Utils = require('./lib/utils.js').Utils;
var WsSensorAccessory = require('./lib/accessory.js').Accessory;
var Websocket = require('./lib/websocket.js').Websocket;
var debug = require('debug')('wssensor');
var Advertise = require('./lib/advertise.js').Advertise;
var WebSocket = require('ws');
const moment = require('moment');
var os = require("os");
var hostname = os.hostname();

var Accessory, Service, Characteristic, UUIDGen, CustomCharacteristic, FakeGatoHistoryService;
var cachedAccessories = 0;
var count = 0;

var platform_name = "wssensor";
var plugin_name = "homebridge-" + platform_name;

module.exports = function(homebridge) {
  console.log("homebridge API version: " + homebridge.version);

  CustomCharacteristic = require('./lib/CustomCharacteristic.js')(homebridge);
  FakeGatoHistoryService = require('fakegato-history')(homebridge);

  Accessory = homebridge.platformAccessory;

  Service = homebridge.hap.Service;
  Characteristic = homebridge.hap.Characteristic;
  UUIDGen = homebridge.hap.uuid; // Universally Unique IDentifier

  homebridge.registerPlatform(plugin_name, platform_name, WsSensorPlatform, true);
}

function WsSensorPlatform(log, config, api) {

  this.log = log;
  this.accessories = {};
  this.hap_accessories = {};

  debug("config = %s", JSON.stringify(config));

  if (typeof(config) !== "undefined" && config !== null) {
    this.port = config.port || {
      "port": 4050
    };
    this.refresh = config['refresh'] || 60; // Update every minute
    this.storage = config.storage || "fs";
  } else {
    this.log.error("config undefined or null!");
    return
  }

  if (typeof(config.aliases) !== "undefined" && config.aliases !== null) {
    this.aliases = config.aliases;
  }

  var plugin_version = Utils.readPluginVersion();
  this.log("%s v%s", plugin_name, plugin_version);

  var params = {
    "log": this.log,
    "plugin_name": plugin_name,
    "port": this.port,
    "accessories": this.accessories,
    "Characteristic": Characteristic,
    "addAccessory": this.addAccessory.bind(this),
    "removeAccessory": this.removeAccessory.bind(this),
    "getAccessories": this.getAccessories.bind(this),
    "sendEvent": this.sendEvent.bind(this)
  }
  this.Websocket = new Websocket(params);

  this.Advertise = new Advertise(params);

  Utils.read_npmVersion(plugin_name, function(npm_version) {
    if (npm_version > plugin_version) {
      this.log("A new version %s is avaiable", npm_version);
    }
  }.bind(this));

  if (api) {
    this.api = api;

    this.api.on('didFinishLaunching', function() {
      this.log("Plugin - DidFinishLaunching");

      this.Websocket.startServer();

      this.Advertise.createAdvertisement();

      debug("Number of cached Accessories: %s", cachedAccessories);
      this.log("Number of Accessories: %s", Object.keys(this.accessories).length);

    }.bind(this));
    //debug("WsSensorPlatform %s", JSON.stringify(this.accessories));

    setInterval(function() {
      for (var k in this.accessories) {

        var ws = this.accessories[k].ws;
        debug("Poll", k, count);
        if (ws && ws.readyState === WebSocket.OPEN) {
          count++;
          var msg = {
            "count": count, "sensitivity":400
          }
          ws.send(JSON.stringify(msg, null, 2));
        } else {
          this.log("No socket", k);
          this.accessories[k].getService(Service.TemperatureSensor).getCharacteristic(Characteristic.CurrentTemperature)
            .updateValue(new Error("Not Responding"));
          //          this.accessories[k].getService(Service.MotionSensor).getCharacteristic(Characteristic.MotionDetected)
          //            .updateValue(new Error("Not Responding"));
        }

      }
    }.bind(this), this.refresh * 1000);

  }
}

//{ "Hostname": "NODE-2BA0FF", "Model": "MS", "Version": "2.0", "Firmware": "2.1.0", "Data": {  "Motion": "1" }}

WsSensorPlatform.prototype.sendEvent = function(err, message) {

  if (err) {
    this.log("Not sending event due to Error");
  } else {

    var name = message.Hostname;

    for (var k in message.Data) {
      //      debug(k, message.Data[k]);
      switch (k) {
        case "Motion":
          var value = message.Data[k] > 0;
          if (this.accessories[name].getService(Service.MotionSensor).getCharacteristic(Characteristic.MotionDetected).value != value) {
            this.accessories[name].getService(Service.MotionSensor).getCharacteristic(CustomCharacteristic.LastActivation)
              .updateValue(moment().unix() - this.accessories[name].mLoggingService.getInitialTime());
          }
          this.accessories[name].getService(Service.MotionSensor).getCharacteristic(Characteristic.MotionDetected)
            .updateValue(value);
          this.accessories[name].mLoggingService.addEntry({
            time: moment().unix(),
            status: value
          });
          break;

        case "Trigger":
          var value = (message.Data[k] ? 1 : 0);
          debug("Trigger", value);
          this.accessories[name].getService(Service.MotionSensor).getCharacteristic(Characteristic.MotionDetected)
            .updateValue(value);
          this.accessories[name].getService(Service.MotionSensor).getCharacteristic(CustomCharacteristic.LastActivation)
            .updateValue(moment().unix() - this.accessories[name].mLoggingService.getInitialTime());
          this.accessories[name].mLoggingService.addEntry({
            time: moment().unix(),
            status: value
          });
          break;

        case "Temperature":
          var value = message.Data[k];
          this.accessories[name].getService(Service.TemperatureSensor).getCharacteristic(Characteristic.CurrentTemperature)
            .updateValue(value);
          break;

        case "Humidity":
          var value = message.Data[k];
          this.accessories[name].getService(Service.TemperatureSensor).getCharacteristic(Characteristic.CurrentRelativeHumidity)
            .updateValue(value);
          break;

        case "Barometer":
          var value = message.Data[k];
          this.accessories[name].getService(Service.TemperatureSensor).getCharacteristic(CustomCharacteristic.AtmosphericPressureLevel)
            .updateValue(value);
          break;

        case "Status":
          var value = message.Data[k];
          switch (value) {
            case 0:
              //              this.accessories[name].getService(Service.TemperatureSensor).getCharacteristic(Characteristic.StatusActive)
              //                .updateValue(true);
              //              this.accessories[name].getService(Service.TemperatureSensor).getCharacteristic(Characteristic.StatusFault)
              //                .updateValue(Characteristic.StatusFault.NO_FAULT);
              this.accessories[name].getService(Service.TemperatureSensor).getCharacteristic(Characteristic.StatusLowBattery)
                .updateValue(Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL);
              //              this.accessories[name].getService(Service.TemperatureSensor).getCharacteristic(Characteristic.StatusTampered)
              //                .updateValue(Characteristic.StatusTampered.NOT_TAMPERED);
              break;
            default:
              //              this.accessories[name].getService(Service.TemperatureSensor).getCharacteristic(Characteristic.StatusActive)
              //                .updateValue(false);
              //              this.accessories[name].getService(Service.TemperatureSensor).getCharacteristic(Characteristic.StatusFault)
              //                .updateValue(Characteristic.StatusFault.GENERAL_FAULT);
              this.accessories[name].getService(Service.TemperatureSensor).getCharacteristic(Characteristic.StatusLowBattery)
                .updateValue(Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW);
              //              this.accessories[name].getService(Service.TemperatureSensor).getCharacteristic(Characteristic.StatusTampered)
              //                .updateValue(Characteristic.StatusTampered.TAMPERED);
          }
      }
    }

    //  this.accessories[name].wLoggingService.addEntry({
    //    time: moment().unix(),
    //    temp: roundInt(message.Data.Temperature),
    //    pressure: roundInt(message.Data.Barometer),
    //    humidity: roundInt(message.Data.Humidity)
    //  });

  }
}

WsSensorPlatform.prototype.addAccessory = function(accessoryDef, ws) {

  var name = accessoryDef.Hostname;
  var displayName = this.aliases[name];
  if (typeof(displayName) == "undefined")
    displayName = name;

  var ack, message;
  var isValid;

  this.log("addAccessory", name, displayName);

  if (!this.accessories[name]) {
    var uuid = UUIDGen.generate(name);

    var newAccessory = new Accessory(displayName, uuid);
    newAccessory.reachable = true;
    newAccessory.context.service_name = accessoryDef.Model;
    newAccessory.context.hostname = name;
    newAccessory.ws = ws;

    newAccessory.getService(Service.AccessoryInformation)
      .setCharacteristic(Characteristic.Manufacturer, "WSSENSOR")
      .setCharacteristic(Characteristic.Model, accessoryDef.Model + " " + accessoryDef.Version)
      .setCharacteristic(Characteristic.FirmwareRevision, require('./package.json').version)
      .setCharacteristic(Characteristic.SerialNumber, hostname + "-" + name);

    var sensors = accessoryDef.Model.split('-');

    for (var i = 0; i < sensors.length; i++) {
      switch (sensors[i]) {
        case "MS":
          newAccessory.addService(Service.MotionSensor, displayName);
          newAccessory
            .getService(Service.MotionSensor)
            .addCharacteristic(CustomCharacteristic.Sensitivity);
          newAccessory
            .getService(Service.MotionSensor)
            .addCharacteristic(CustomCharacteristic.LastActivation);
          newAccessory
            .getService(Service.MotionSensor)
            .addCharacteristic(CustomCharacteristic.Duration);
          break;
        case "BME":
          newAccessory.addService(Service.TemperatureSensor, displayName)
            .getCharacteristic(Characteristic.CurrentTemperature)
            .setProps({
              minValue: -100,
              maxValue: 100
            });
          newAccessory
            .getService(Service.TemperatureSensor)
            .addCharacteristic(Characteristic.CurrentRelativeHumidity);
          newAccessory
            .getService(Service.TemperatureSensor)
            .addCharacteristic(CustomCharacteristic.AtmosphericPressureLevel);
          break;
        case "ACL":
          newAccessory.addService(Service.MotionSensor, displayName);
          newAccessory
            .getService(Service.MotionSensor)
            .addCharacteristic(CustomCharacteristic.Sensitivity);
          newAccessory
            .getService(Service.MotionSensor)
            .addCharacteristic(CustomCharacteristic.Duration);
          newAccessory
            .getService(Service.MotionSensor)
            .addCharacteristic(CustomCharacteristic.LastActivation);
          newAccessory.addService(Service.TemperatureSensor, displayName)
            .getCharacteristic(Characteristic.CurrentTemperature)
            .setProps({
              minValue: -100,
              maxValue: 100
            });
          break;
        default:
          this.log.error("Unknown Sensor Type", sensors[i], name, displayName);
      }
    }
    newAccessory.log = this.log;
    newAccessory.mLoggingService = new FakeGatoHistoryService("motion", newAccessory, {
      storage: this.storage,
      minutes: this.refresh * 10 / 60
    });

    //    newAccessory.wLoggingService = new FakeGatoHistoryService("weather", newAccessory, {
    //      storage: this.storage,
    //      minutes: this.refresh * 10 / 60
    //    });

    this.accessories[name] = newAccessory;
    this.api.registerPlatformAccessories(plugin_name, platform_name, [newAccessory]);

  } else {
    debug("accessory already created");
  }
}

WsSensorPlatform.prototype.configureAccessory = function(accessory) {

  //debug("configureAccessory %s", JSON.stringify(accessory.services, null, 2));

  cachedAccessories++;
  var name = accessory.context.hostname;

  this.accessories[name] = accessory;

  accessory.log = this.log;
  accessory.mLoggingService = new FakeGatoHistoryService("motion", accessory, {
    storage: this.storage,
    minutes: this.refresh * 10 / 60
  });

  //  accessory.wLoggingService = new FakeGatoHistoryService("weather", accessory, {
  //    storage: this.storage,
  //    minutes: this.refresh * 10 / 60
  //  });

  this.log("configureAccessory", name);
}

WsSensorPlatform.prototype.removeAccessory = function(name) {

  var ack, message;

  if (typeof(this.accessories[name]) !== "undefined") {
    debug("removeAccessory '%s'", name);

    this.api.unregisterPlatformAccessories(plugin_name, platform_name, [this.hap_accessories[name]]);
    delete this.accessories[name];
    delete this.hap_accessories[name];
    ack = true;
    message = "accessory '" + name + "' is removed.";
  } else {
    ack = false;
    message = "accessory '" + name + "' not found.";
  }
  this.log("removeAccessory %s", message);
  this.Websocket.sendAck(ack, message);
}

WsSensorPlatform.prototype.getAccessories = function(name) {

  var accessories = {};
  var def = {};
  var service, characteristics;

  switch (name) {
    case "all":
      for (var k in this.accessories) {
        //this.log("getAccessories %s", JSON.stringify(this.accessories[k], null, 2));
        service = this.accessories[k].service_name;
        characteristics = this.accessories[k].i_value;
        def = {
          "service": service,
          "characteristics": characteristics
        };
        accessories[k] = def;
      }
      break;

    default:
      service = this.accessories[name].service_name;
      characteristics = this.accessories[name].i_value;
      def = {
        "service": service,
        "characteristics": characteristics
      };
      accessories[name] = def;
  }

  //this.log("getAccessory %s", JSON.stringify(accessories, null, 2));
  this.Websocket.sendAccessories(accessories);
}

WsSensorPlatform.prototype.buildParams = function(accessoryDef) {

  var params = {
    "accessoryDef": accessoryDef,
    "log": this.log,
    "Service": Service,
    "Characteristic": Characteristic,
    "WebSocket": this.WebSocket
  }
  debug("configureAccessories %s", JSON.stringify(params));
  return params;
}

function roundInt(string) {
  return Math.round(parseFloat(string) * 10) / 10;
}
<commit_msg>Duration<commit_after>// Sample Config
//{
//  "platform": "wssensor",
//  "name": "wssensor",
//  "port": 8080,
//  "refresh": "60",
//  "leak": "10",
//  "aliases": {
//    "NODE-2BA0FF": "Porch Motion"
//  }
//}

'use strict';

var util = require('util');
var Utils = require('./lib/utils.js').Utils;
var WsSensorAccessory = require('./lib/accessory.js').Accessory;
var Websocket = require('./lib/websocket.js').Websocket;
var debug = require('debug')('wssensor');
var Advertise = require('./lib/advertise.js').Advertise;
var WebSocket = require('ws');
const moment = require('moment');
var os = require("os");
var hostname = os.hostname();

var Accessory, Service, Characteristic, UUIDGen, CustomCharacteristic, FakeGatoHistoryService;
var cachedAccessories = 0;
var count = 0;

var platform_name = "wssensor";
var plugin_name = "homebridge-" + platform_name;

module.exports = function(homebridge) {
  console.log("homebridge API version: " + homebridge.version);

  CustomCharacteristic = require('./lib/CustomCharacteristic.js')(homebridge);
  FakeGatoHistoryService = require('fakegato-history')(homebridge);

  Accessory = homebridge.platformAccessory;

  Service = homebridge.hap.Service;
  Characteristic = homebridge.hap.Characteristic;
  UUIDGen = homebridge.hap.uuid; // Universally Unique IDentifier

  homebridge.registerPlatform(plugin_name, platform_name, WsSensorPlatform, true);
}

function WsSensorPlatform(log, config, api) {

  this.log = log;
  this.accessories = {};
  this.hap_accessories = {};

  debug("config = %s", JSON.stringify(config));

  if (typeof(config) !== "undefined" && config !== null) {
    this.port = config.port || {
      "port": 4050
    };
    this.refresh = config['refresh'] || 60; // Update every minute
    this.storage = config.storage || "fs";
    this.duration = config['duration'] || 10; // Duration of on event in seconds ( ACL )
    this.sensitivity = config['sensitivity'] || 400; // Sensitivity of sensor ( ACL )

  } else {
    this.log.error("config undefined or null!");
    return
  }

  if (typeof(config.aliases) !== "undefined" && config.aliases !== null) {
    this.aliases = config.aliases;
  }

  var plugin_version = Utils.readPluginVersion();
  this.log("%s v%s", plugin_name, plugin_version);

  var params = {
    "log": this.log,
    "plugin_name": plugin_name,
    "port": this.port,
    "accessories": this.accessories,
    "Characteristic": Characteristic,
    "addAccessory": this.addAccessory.bind(this),
    "removeAccessory": this.removeAccessory.bind(this),
    "getAccessories": this.getAccessories.bind(this),
    "sendEvent": this.sendEvent.bind(this)
  }
  this.Websocket = new Websocket(params);

  this.Advertise = new Advertise(params);

  Utils.read_npmVersion(plugin_name, function(npm_version) {
    if (npm_version > plugin_version) {
      this.log("A new version %s is avaiable", npm_version);
    }
  }.bind(this));

  if (api) {
    this.api = api;

    this.api.on('didFinishLaunching', function() {
      this.log("Plugin - DidFinishLaunching");

      this.Websocket.startServer();

      this.Advertise.createAdvertisement();

      debug("Number of cached Accessories: %s", cachedAccessories);
      this.log("Number of Accessories: %s", Object.keys(this.accessories).length);

    }.bind(this));
    //debug("WsSensorPlatform %s", JSON.stringify(this.accessories));

    setInterval(function() {
      for (var k in this.accessories) {

        var ws = this.accessories[k].ws;
        debug("Poll", k, count);
        if (ws && ws.readyState === WebSocket.OPEN) {
          count++;
          var msg = {
            "count": count,
            "sensitivity": this.sensitivity,
            "duration": this.duration
          }
          ws.send(JSON.stringify(msg, null, 2));
        } else {
          this.log("No socket", k);
          this.accessories[k].getService(Service.TemperatureSensor).getCharacteristic(Characteristic.CurrentTemperature)
            .updateValue(new Error("Not Responding"));
          //          this.accessories[k].getService(Service.MotionSensor).getCharacteristic(Characteristic.MotionDetected)
          //            .updateValue(new Error("Not Responding"));
        }

      }
    }.bind(this), this.refresh * 1000);

  }
}

//{ "Hostname": "NODE-2BA0FF", "Model": "MS", "Version": "2.0", "Firmware": "2.1.0", "Data": {  "Motion": "1" }}

WsSensorPlatform.prototype.sendEvent = function(err, message) {

  if (err) {
    this.log("Not sending event due to Error");
  } else {

    var name = message.Hostname;

    for (var k in message.Data) {
      //      debug(k, message.Data[k]);
      switch (k) {
        case "Motion":
          var value = message.Data[k] > 0;
          if (this.accessories[name].getService(Service.MotionSensor).getCharacteristic(Characteristic.MotionDetected).value != value) {
            this.accessories[name].getService(Service.MotionSensor).getCharacteristic(CustomCharacteristic.LastActivation)
              .updateValue(moment().unix() - this.accessories[name].mLoggingService.getInitialTime());
          }
          this.accessories[name].getService(Service.MotionSensor).getCharacteristic(Characteristic.MotionDetected)
            .updateValue(value);
          this.accessories[name].mLoggingService.addEntry({
            time: moment().unix(),
            status: value
          });
          break;

        case "Trigger":
          var value = (message.Data[k] ? 1 : 0);
          debug("Trigger", value);
          this.accessories[name].getService(Service.MotionSensor).getCharacteristic(Characteristic.MotionDetected)
            .updateValue(value);
          this.accessories[name].getService(Service.MotionSensor).getCharacteristic(CustomCharacteristic.LastActivation)
            .updateValue(moment().unix() - this.accessories[name].mLoggingService.getInitialTime());
          this.accessories[name].mLoggingService.addEntry({
            time: moment().unix(),
            status: value
          });
          break;

        case "Temperature":
          var value = message.Data[k];
          this.accessories[name].getService(Service.TemperatureSensor).getCharacteristic(Characteristic.CurrentTemperature)
            .updateValue(value);
          break;

        case "Humidity":
          var value = message.Data[k];
          this.accessories[name].getService(Service.TemperatureSensor).getCharacteristic(Characteristic.CurrentRelativeHumidity)
            .updateValue(value);
          break;

        case "Barometer":
          var value = message.Data[k];
          this.accessories[name].getService(Service.TemperatureSensor).getCharacteristic(CustomCharacteristic.AtmosphericPressureLevel)
            .updateValue(value);
          break;

        case "Status":
          var value = message.Data[k];
          switch (value) {
            case 0:
              //              this.accessories[name].getService(Service.TemperatureSensor).getCharacteristic(Characteristic.StatusActive)
              //                .updateValue(true);
              //              this.accessories[name].getService(Service.TemperatureSensor).getCharacteristic(Characteristic.StatusFault)
              //                .updateValue(Characteristic.StatusFault.NO_FAULT);
              this.accessories[name].getService(Service.TemperatureSensor).getCharacteristic(Characteristic.StatusLowBattery)
                .updateValue(Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL);
              //              this.accessories[name].getService(Service.TemperatureSensor).getCharacteristic(Characteristic.StatusTampered)
              //                .updateValue(Characteristic.StatusTampered.NOT_TAMPERED);
              break;
            default:
              //              this.accessories[name].getService(Service.TemperatureSensor).getCharacteristic(Characteristic.StatusActive)
              //                .updateValue(false);
              //              this.accessories[name].getService(Service.TemperatureSensor).getCharacteristic(Characteristic.StatusFault)
              //                .updateValue(Characteristic.StatusFault.GENERAL_FAULT);
              this.accessories[name].getService(Service.TemperatureSensor).getCharacteristic(Characteristic.StatusLowBattery)
                .updateValue(Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW);
              //              this.accessories[name].getService(Service.TemperatureSensor).getCharacteristic(Characteristic.StatusTampered)
              //                .updateValue(Characteristic.StatusTampered.TAMPERED);
          }
      }
    }

    //  this.accessories[name].wLoggingService.addEntry({
    //    time: moment().unix(),
    //    temp: roundInt(message.Data.Temperature),
    //    pressure: roundInt(message.Data.Barometer),
    //    humidity: roundInt(message.Data.Humidity)
    //  });

  }
}

WsSensorPlatform.prototype.setDuration = function(value, callback) {
  debug("setDuration");
  this.duration = value;
  callback();
}

WsSensorPlatform.prototype.setSensitivity = function(value, callback) {

  debug("setSensitivity");
  this.sensitivity = value;
  callback();
}

WsSensorPlatform.prototype.addAccessory = function(accessoryDef, ws) {

  var name = accessoryDef.Hostname;
  var displayName = this.aliases[name];
  if (typeof(displayName) == "undefined")
    displayName = name;

  var ack, message;
  var isValid;

  this.log("addAccessory", name, displayName);

  if (!this.accessories[name]) {
    var uuid = UUIDGen.generate(name);

    var newAccessory = new Accessory(displayName, uuid);
    newAccessory.reachable = true;
    newAccessory.context.service_name = accessoryDef.Model;
    newAccessory.context.hostname = name;
    newAccessory.ws = ws;

    newAccessory.getService(Service.AccessoryInformation)
      .setCharacteristic(Characteristic.Manufacturer, "WSSENSOR")
      .setCharacteristic(Characteristic.Model, accessoryDef.Model + " " + accessoryDef.Version)
      .setCharacteristic(Characteristic.FirmwareRevision, require('./package.json').version)
      .setCharacteristic(Characteristic.SerialNumber, hostname + "-" + name);

    var sensors = accessoryDef.Model.split('-');

    for (var i = 0; i < sensors.length; i++) {
      switch (sensors[i]) {
        case "MS":
          newAccessory.addService(Service.MotionSensor, displayName);
          newAccessory
            .getService(Service.MotionSensor)
            .addCharacteristic(CustomCharacteristic.Sensitivity);
          newAccessory
            .getService(Service.MotionSensor)
            .getCharacteristic(CustomCharacteristic.Sensitivity)
            .on('set', this.setSensitivity.bind(this));
          newAccessory
            .getService(Service.MotionSensor)
            .addCharacteristic(CustomCharacteristic.LastActivation);
          newAccessory
            .getService(Service.MotionSensor)
            .addCharacteristic(CustomCharacteristic.Duration);
          newAccessory
            .getService(Service.MotionSensor)
            .getCharacteristic(CustomCharacteristic.Duration)
            .on('set', this.setDuration.bind(this));
          break;
        case "BME":
          newAccessory.addService(Service.TemperatureSensor, displayName)
            .getCharacteristic(Characteristic.CurrentTemperature)
            .setProps({
              minValue: -100,
              maxValue: 100
            });
          newAccessory
            .getService(Service.TemperatureSensor)
            .addCharacteristic(Characteristic.CurrentRelativeHumidity);
          newAccessory
            .getService(Service.TemperatureSensor)
            .addCharacteristic(CustomCharacteristic.AtmosphericPressureLevel);
          break;
        case "ACL":
          newAccessory.addService(Service.MotionSensor, displayName);
          newAccessory
            .getService(Service.MotionSensor)
            .addCharacteristic(CustomCharacteristic.Sensitivity);
          newAccessory
            .getService(Service.MotionSensor)
            .addCharacteristic(CustomCharacteristic.Duration);
          newAccessory
            .getService(Service.MotionSensor)
            .addCharacteristic(CustomCharacteristic.LastActivation);
          newAccessory.addService(Service.TemperatureSensor, displayName)
            .getCharacteristic(Characteristic.CurrentTemperature)
            .setProps({
              minValue: -100,
              maxValue: 100
            });
          break;
        default:
          this.log.error("Unknown Sensor Type", sensors[i], name, displayName);
      }
    }
    newAccessory.log = this.log;
    newAccessory.mLoggingService = new FakeGatoHistoryService("motion", newAccessory, {
      storage: this.storage,
      minutes: this.refresh * 10 / 60
    });

    //    newAccessory.wLoggingService = new FakeGatoHistoryService("weather", newAccessory, {
    //      storage: this.storage,
    //      minutes: this.refresh * 10 / 60
    //    });

    this.accessories[name] = newAccessory;
    this.api.registerPlatformAccessories(plugin_name, platform_name, [newAccessory]);

  } else {
    debug("accessory already created");
  }
}

WsSensorPlatform.prototype.configureAccessory = function(accessory) {

  //debug("configureAccessory %s", JSON.stringify(accessory.services, null, 2));

  cachedAccessories++;
  var name = accessory.context.hostname;

  this.accessories[name] = accessory;

  accessory.log = this.log;
  accessory.mLoggingService = new FakeGatoHistoryService("motion", accessory, {
    storage: this.storage,
    minutes: this.refresh * 10 / 60
  });

  //  accessory.wLoggingService = new FakeGatoHistoryService("weather", accessory, {
  //    storage: this.storage,
  //    minutes: this.refresh * 10 / 60
  //  });

  this.log("configureAccessory", name);
}

WsSensorPlatform.prototype.removeAccessory = function(name) {

  var ack, message;

  if (typeof(this.accessories[name]) !== "undefined") {
    debug("removeAccessory '%s'", name);

    this.api.unregisterPlatformAccessories(plugin_name, platform_name, [this.hap_accessories[name]]);
    delete this.accessories[name];
    delete this.hap_accessories[name];
    ack = true;
    message = "accessory '" + name + "' is removed.";
  } else {
    ack = false;
    message = "accessory '" + name + "' not found.";
  }
  this.log("removeAccessory %s", message);
  this.Websocket.sendAck(ack, message);
}

WsSensorPlatform.prototype.getAccessories = function(name) {

  var accessories = {};
  var def = {};
  var service, characteristics;

  switch (name) {
    case "all":
      for (var k in this.accessories) {
        //this.log("getAccessories %s", JSON.stringify(this.accessories[k], null, 2));
        service = this.accessories[k].service_name;
        characteristics = this.accessories[k].i_value;
        def = {
          "service": service,
          "characteristics": characteristics
        };
        accessories[k] = def;
      }
      break;

    default:
      service = this.accessories[name].service_name;
      characteristics = this.accessories[name].i_value;
      def = {
        "service": service,
        "characteristics": characteristics
      };
      accessories[name] = def;
  }

  //this.log("getAccessory %s", JSON.stringify(accessories, null, 2));
  this.Websocket.sendAccessories(accessories);
}

WsSensorPlatform.prototype.buildParams = function(accessoryDef) {

  var params = {
    "accessoryDef": accessoryDef,
    "log": this.log,
    "Service": Service,
    "Characteristic": Characteristic,
    "WebSocket": this.WebSocket
  }
  debug("configureAccessories %s", JSON.stringify(params));
  return params;
}

function roundInt(string) {
  return Math.round(parseFloat(string) * 10) / 10;
}
<|endoftext|>


<commit_before>import React from 'react';
import styles from './Banner.scss';

const Banner = () => (

      This game has a play testing session available.

        {' '}You are eligible!

      <button className={styles.Start}>Start Session</button>
      <button className={styles.Hide}>Hide</button>

);

export default Banner;
<commit_msg>Add basic hide functionality to banner<commit_after>import React, { Component } from 'react';
import styles from './Banner.scss';

class Banner extends Component {
  state = {
    hide: false
  }

  onHide = () => this.setState({ hide: true });

  render() {
    const { hide } = this.state;
    return !hide
      ? (

            This game has a play testing session available.

              {' '}You are eligible!

            <button className={styles.Start}>Start Session</button>
            <button className={styles.Hide} onClick={this.onHide}>Hide</button>

      )
      : null;
  }
}

export default Banner;
<|endoftext|>


<commit_before>var path = require('path');
var fs = require('fs');
var os = require('os');

var PLUGIN_VERSION = '3.1.1';
var _log = console.log.bind(console);

function targetsAndroid(projectDir) {
    var pkg = require(path.join(projectDir, 'package.json'));
    if (!pkg.nativescript) {
        throw new Error('Not a NativeScript project');
    }

    return ('tns-android' in pkg.nativescript);
}

function buildGradleExists(platformsDir) {
    return fs.existsSync(_getProjectBuildGradlePath(platformsDir));
}

function checkForGoogleServicesJson(projectDir, resourcesDir) {
    var androidIsTargeted = targetsAndroid(projectDir);
    var resourcesPath = path.join(resourcesDir, 'Android', 'google-services.json');

    if (androidIsTargeted && !fs.existsSync(resourcesPath)) {
        _log('|!| google-services.json appears to be missing. Please make sure it is present in the "app/App_Resources/Android" folder, in order to use FCM push notifications |!|');
    }
}

function addOnPluginInstall(platformsDir) {
    if (buildGradleExists(platformsDir)) {
        addIfNecessary(platformsDir);
    }
}

function addIfNecessary(platformsDir) {
    _amendBuildGradle(platformsDir, function(pluginImported, pluginApplied, fileContents) {
        if (!pluginImported) {
            fileContents.projectFileContents = _addPluginImport(fileContents.projectFileContents);
        }

        if (!pluginApplied) {
            if (fileContents.appFileContents) {
                fileContents.appFileContents = _addPluginApplication(fileContents.appFileContents);
            } else {
                fileContents.projectFileContents = _addPluginApplication(fileContents.projectFileContents);
            }
        }
        return fileContents;
    });

    _copyGoogleServices(platformsDir);
}

function removeIfPresent(platformsDir) {
    _amendBuildGradle(platformsDir, function(pluginImported, pluginApplied, fileContents) {
        if (pluginImported) {
            fileContents.projectFileContents = _removePluginImport(fileContents.projectFileContents);
        }

        if (pluginApplied) {
            if (fileContents.appFileContents) {
                fileContents.appFileContents = _removePluginApplication(fileContents.appFileContents);
            } else {
                fileContents.projectFileContents = _removePluginApplication(fileContents.projectFileContents);
            }
        }
        return fileContents;
    });
}

function setLogger(logFunc) {
    _log = logFunc;
}

// ============= private

var _quotesRegExp = '["\']';
var _versionRegExp = '[^\'"]+';
var _pluginImportName = 'com.google.gms:google-services';
var _pluginApplicationName = 'com.google.gms.google-services';

function _copyGoogleServices(platformsDir) {
    var srcServicesFile = path.join(platformsDir, '..', 'app', 'App_Resources', 'Android', 'google-services.json');
    var dstServicesFile = path.join(platformsDir, 'android', 'app', 'google-services.json');
    if (fs.existsSync(srcServicesFile) && !fs.existsSync(dstServicesFile) && fs.existsSync(path.join(platformsDir, 'android', 'app'))) {
        // try to copy google-services config file to platform app directory
        fs.writeFileSync(dest, fs.readFileSync(src, 'utf-8'));
    }
}

function _amendBuildGradle(platformsDir, applyAmendment) {
    if (!buildGradleExists(platformsDir)) {
        return _log('build.gradle file not found');
    }

    var projectPath = _getProjectBuildGradlePath(platformsDir);
    var appPath = _getAppBuildGradlePath(platformsDir);

    if (!fs.existsSync(appPath)) {
        // NativeScript <= 3.3.1
        appPath = null;
    }
    var fileContents = {
        projectFileContents: fs.readFileSync(projectPath, 'utf8'),
        appFileContents: appPath ? fs.readFileSync(appPath, 'utf8') : null
    };
    var pluginImported = _checkForImport(fileContents.projectFileContents);
    var pluginApplied = _checkForApplication(fileContents.appFileContents ? fileContents.appFileContents : fileContents.projectFileContents);
    var newContents = applyAmendment(pluginImported, pluginApplied, fileContents);

    fs.writeFileSync(projectPath, newContents.projectFileContents, 'utf8');
    if (appPath) {
        fs.writeFileSync(appPath, newContents.appFileContents, 'utf8');
    }
}

function _removePluginImport(buildGradleContents) {
    var regExpStr = '\\s*classpath +' + _formNamePartOfRegExp(true) + '{0,0}:' + _versionRegExp + _quotesRegExp;
    var regExp = new RegExp(regExpStr, 'i');
    return buildGradleContents.replace(regExp, '');
}

function _removePluginApplication(buildGradleContents) {
    var regExpStr = '\\s*apply plugin: +' + _formNamePartOfRegExp(false);
    var regExp = new RegExp(regExpStr, 'i');
    return buildGradleContents.replace(regExp, '');
}

function _addPluginImport(buildGradleContents) {
    var androidGradle = 'com.android.tools.build:gradle';
    var insertBeforeDoubleQuotes = 'classpath "' + androidGradle;
    var insertBeforeSingleQoutes = 'classpath \'' + androidGradle;
    var quoteToInsert = '"'
    var matchedString = insertBeforeDoubleQuotes;
    var ind = buildGradleContents.indexOf(insertBeforeDoubleQuotes);

    if (ind === -1) {
        ind = buildGradleContents.indexOf(insertBeforeSingleQoutes);
        quoteToInsert = '\'';
        matchedString = insertBeforeSingleQoutes;
    }

    if (ind === -1) {
        _log('build.gradle has unexpected contents -- please check it manually');
        return buildGradleContents;
    }

    var result = buildGradleContents.substring(0, ind);
    result += 'classpath ' + quoteToInsert + _pluginImportName + ':' + PLUGIN_VERSION + quoteToInsert + os.EOL;
    result += '\t\t' + matchedString;
    result += buildGradleContents.substring(ind + matchedString.length);
    return result;
}

function _addPluginApplication(buildGradleContents) {
    buildGradleContents += os.EOL + 'apply plugin: "' + _pluginApplicationName + '"' + os.EOL;
    return buildGradleContents;
}

function _formNamePartOfRegExp(useImportName) {
    var name = useImportName ? _pluginImportName : _pluginApplicationName;
    return _quotesRegExp + name + _quotesRegExp;
}

function _checkForImport(buildGradleContents) {
    var re = new RegExp('classpath +' + _formNamePartOfRegExp(true) + '{0,0}', 'i');
    return re.test(buildGradleContents);
}

function _checkForApplication(buildGradleContents) {
    var re = new RegExp('apply plugin: +' + _formNamePartOfRegExp(false), 'i');
    return re.test(buildGradleContents);
}

function _getProjectBuildGradlePath(platformsDir) {
    return path.join(platformsDir, 'android', 'build.gradle');
}

function _getAppBuildGradlePath(platformsDir) {
    return path.join(platformsDir, 'android', 'app', 'build.gradle');
}
// ============= end private

module.exports = {
    removeIfPresent: removeIfPresent,
    setLogger: setLogger,
    addIfNecessary: addIfNecessary,
    targetsAndroid: targetsAndroid,
    buildGradleExists: buildGradleExists,
    addOnPluginInstall: addOnPluginInstall,
    checkForGoogleServicesJson: checkForGoogleServicesJson
};<commit_msg>fix typo in copy file code<commit_after>var path = require('path');
var fs = require('fs');
var os = require('os');

var PLUGIN_VERSION = '3.1.1';
var _log = console.log.bind(console);

function targetsAndroid(projectDir) {
    var pkg = require(path.join(projectDir, 'package.json'));
    if (!pkg.nativescript) {
        throw new Error('Not a NativeScript project');
    }

    return ('tns-android' in pkg.nativescript);
}

function buildGradleExists(platformsDir) {
    return fs.existsSync(_getProjectBuildGradlePath(platformsDir));
}

function checkForGoogleServicesJson(projectDir, resourcesDir) {
    var androidIsTargeted = targetsAndroid(projectDir);
    var resourcesPath = path.join(resourcesDir, 'Android', 'google-services.json');

    if (androidIsTargeted && !fs.existsSync(resourcesPath)) {
        _log('|!| google-services.json appears to be missing. Please make sure it is present in the "app/App_Resources/Android" folder, in order to use FCM push notifications |!|');
    }
}

function addOnPluginInstall(platformsDir) {
    if (buildGradleExists(platformsDir)) {
        addIfNecessary(platformsDir);
    }
}

function addIfNecessary(platformsDir) {
    _amendBuildGradle(platformsDir, function(pluginImported, pluginApplied, fileContents) {
        if (!pluginImported) {
            fileContents.projectFileContents = _addPluginImport(fileContents.projectFileContents);
        }

        if (!pluginApplied) {
            if (fileContents.appFileContents) {
                fileContents.appFileContents = _addPluginApplication(fileContents.appFileContents);
            } else {
                fileContents.projectFileContents = _addPluginApplication(fileContents.projectFileContents);
            }
        }
        return fileContents;
    });

    _copyGoogleServices(platformsDir);
}

function removeIfPresent(platformsDir) {
    _amendBuildGradle(platformsDir, function(pluginImported, pluginApplied, fileContents) {
        if (pluginImported) {
            fileContents.projectFileContents = _removePluginImport(fileContents.projectFileContents);
        }

        if (pluginApplied) {
            if (fileContents.appFileContents) {
                fileContents.appFileContents = _removePluginApplication(fileContents.appFileContents);
            } else {
                fileContents.projectFileContents = _removePluginApplication(fileContents.projectFileContents);
            }
        }
        return fileContents;
    });
}

function setLogger(logFunc) {
    _log = logFunc;
}

// ============= private

var _quotesRegExp = '["\']';
var _versionRegExp = '[^\'"]+';
var _pluginImportName = 'com.google.gms:google-services';
var _pluginApplicationName = 'com.google.gms.google-services';

function _copyGoogleServices(platformsDir) {
    var srcServicesFile = path.join(platformsDir, '..', 'app', 'App_Resources', 'Android', 'google-services.json');
    var dstServicesFile = path.join(platformsDir, 'android', 'app', 'google-services.json');
    if (fs.existsSync(srcServicesFile) && !fs.existsSync(dstServicesFile) && fs.existsSync(path.join(platformsDir, 'android', 'app'))) {
        // try to copy google-services config file to platform app directory
        fs.writeFileSync(dstServicesFile, fs.readFileSync(srcServicesFile, 'utf-8'));
    }
}

function _amendBuildGradle(platformsDir, applyAmendment) {
    if (!buildGradleExists(platformsDir)) {
        return _log('build.gradle file not found');
    }

    var projectPath = _getProjectBuildGradlePath(platformsDir);
    var appPath = _getAppBuildGradlePath(platformsDir);

    if (!fs.existsSync(appPath)) {
        // NativeScript <= 3.3.1
        appPath = null;
    }
    var fileContents = {
        projectFileContents: fs.readFileSync(projectPath, 'utf8'),
        appFileContents: appPath ? fs.readFileSync(appPath, 'utf8') : null
    };
    var pluginImported = _checkForImport(fileContents.projectFileContents);
    var pluginApplied = _checkForApplication(fileContents.appFileContents ? fileContents.appFileContents : fileContents.projectFileContents);
    var newContents = applyAmendment(pluginImported, pluginApplied, fileContents);

    fs.writeFileSync(projectPath, newContents.projectFileContents, 'utf8');
    if (appPath) {
        fs.writeFileSync(appPath, newContents.appFileContents, 'utf8');
    }
}

function _removePluginImport(buildGradleContents) {
    var regExpStr = '\\s*classpath +' + _formNamePartOfRegExp(true) + '{0,0}:' + _versionRegExp + _quotesRegExp;
    var regExp = new RegExp(regExpStr, 'i');
    return buildGradleContents.replace(regExp, '');
}

function _removePluginApplication(buildGradleContents) {
    var regExpStr = '\\s*apply plugin: +' + _formNamePartOfRegExp(false);
    var regExp = new RegExp(regExpStr, 'i');
    return buildGradleContents.replace(regExp, '');
}

function _addPluginImport(buildGradleContents) {
    var androidGradle = 'com.android.tools.build:gradle';
    var insertBeforeDoubleQuotes = 'classpath "' + androidGradle;
    var insertBeforeSingleQoutes = 'classpath \'' + androidGradle;
    var quoteToInsert = '"'
    var matchedString = insertBeforeDoubleQuotes;
    var ind = buildGradleContents.indexOf(insertBeforeDoubleQuotes);

    if (ind === -1) {
        ind = buildGradleContents.indexOf(insertBeforeSingleQoutes);
        quoteToInsert = '\'';
        matchedString = insertBeforeSingleQoutes;
    }

    if (ind === -1) {
        _log('build.gradle has unexpected contents -- please check it manually');
        return buildGradleContents;
    }

    var result = buildGradleContents.substring(0, ind);
    result += 'classpath ' + quoteToInsert + _pluginImportName + ':' + PLUGIN_VERSION + quoteToInsert + os.EOL;
    result += '\t\t' + matchedString;
    result += buildGradleContents.substring(ind + matchedString.length);
    return result;
}

function _addPluginApplication(buildGradleContents) {
    buildGradleContents += os.EOL + 'apply plugin: "' + _pluginApplicationName + '"' + os.EOL;
    return buildGradleContents;
}

function _formNamePartOfRegExp(useImportName) {
    var name = useImportName ? _pluginImportName : _pluginApplicationName;
    return _quotesRegExp + name + _quotesRegExp;
}

function _checkForImport(buildGradleContents) {
    var re = new RegExp('classpath +' + _formNamePartOfRegExp(true) + '{0,0}', 'i');
    return re.test(buildGradleContents);
}

function _checkForApplication(buildGradleContents) {
    var re = new RegExp('apply plugin: +' + _formNamePartOfRegExp(false), 'i');
    return re.test(buildGradleContents);
}

function _getProjectBuildGradlePath(platformsDir) {
    return path.join(platformsDir, 'android', 'build.gradle');
}

function _getAppBuildGradlePath(platformsDir) {
    return path.join(platformsDir, 'android', 'app', 'build.gradle');
}
// ============= end private

module.exports = {
    removeIfPresent: removeIfPresent,
    setLogger: setLogger,
    addIfNecessary: addIfNecessary,
    targetsAndroid: targetsAndroid,
    buildGradleExists: buildGradleExists,
    addOnPluginInstall: addOnPluginInstall,
    checkForGoogleServicesJson: checkForGoogleServicesJson
};<|endoftext|>


<commit_before>(function (ns) {

    var Annotation = require("./../../base/annotation.js").Annotation;
    var FunctionAnnotation = require("./../../base/annotation.js").FunctionAnnotation;
    var Types = require("./../../interfaces.js").TYPES;
    var Kinds = require("./../../interfaces.js").OBJECT_KINDS;
    var walk = require('estraverse'),
        Syntax = walk.Syntax,
        VisitorOption = walk.VisitorOption;

    /**
     * @param {object} opt
     */
    var getHeader = function (opt) {
        if (opt.omitHeader == true)
            return;
        var header = [
            "// Generated by shade.js"
        ];
        var floatPrecision = opt.floatPrecision || "mediump";
        header.push("precision " + floatPrecision + " float;");
        return header;
    }

    var toGLSLType = function (info) {
        switch (info.type) {
            case Types.OBJECT:
                switch (info.kind) {
                    case Kinds.COLOR:
                        return "vec3";
                    default:
                        throw new Error("toGLSLType: Unhandled kind: " + info.kind);
                }
            case Types.UNDEFINED:
                return "void";
            default:
                throw new Error("toGLSLType: Unhandled type: " + info.type);

        }

    }

    var generate = function (ast, opt) {

        opt = opt || {};

        var lines = [];

        walk.traverse(ast, {
                enter: function (node) {
                    var type = node.type;
                    switch (type) {

                        case Syntax.Program:
                            lines = lines.concat(getHeader(opt));
                            break;

                        case Syntax.FunctionDeclaration:
                            var func = new FunctionAnnotation(node);
                            var methodStart = [toGLSLType(func.getReturnInfo())];
                            methodStart.push(node.id.name, '(');
                            if (!(node.params && node.params.length)) {
                               methodStart.push("void");
                            } else {
                                node.params.forEach(function (param) {
                                    methodStart.push(param.id.name);
                                })
                            }
                            methodStart.push(') {');
                            lines.push(methodStart.join(" "));
                            return;

                        case Syntax.ReturnStatement:
                            var hasArguments = node.argument;
                            lines.push("return " + (hasArguments ? handleExpression(node.argument) : "") + ";");
                            return;

                        case Syntax.AssignmentExpression:
                            lines.push(handleExpression(node) + ";");
                            return;

                        case Syntax.ExpressionStatement:
                            lines.push(handleExpression(node.expression) + ";");
                            return VisitorOption.Skip;

                        default:
                            //console.log("Unhandled: " + type);

                    }
                },
                leave: function (node) {
                    var type = node.type;
                    switch (type) {
                        case Syntax.Program:
                            break;
                        case Syntax.FunctionDeclaration:
                            lines.push("};");
                            break
                    }
                }
            }
        );
        return lines.join("\n");
    }

    /**
     *
     * @param node
     * @returns {string}
     */
    var handleExpression = function(node) {
        var result = "<unhandled>";
        switch(node.type) {
            case Syntax.NewExpression:
                result = toGLSLType(node.extra) + "(";
                node.arguments.forEach(function(arg, index) {
                    result += handleExpression(arg);
                    if (index < node.arguments.length - 1) {
                        result += ", ";
                    }
                });
                result += ")";
                break;

            case Syntax.Literal:
                result = node.extra.staticValue;
                break;

            case Syntax.Identifier:
                result = node.name;
                break;

            case Syntax.AssignmentExpression:
                result = handleExpression(node.left);
                result += " " + node.operator + " ";
                result += handleExpression(node.right);
                break;

            case Syntax.ExpressionStatement:

        }
        return result;
    }

    exports.generate = generate;

}(exports));
<commit_msg>Added CallExpression support to code generator<commit_after>(function (ns) {

    var Annotation = require("./../../base/annotation.js").Annotation;
    var FunctionAnnotation = require("./../../base/annotation.js").FunctionAnnotation;
    var Types = require("./../../interfaces.js").TYPES;
    var Kinds = require("./../../interfaces.js").OBJECT_KINDS;
    var walk = require('estraverse'),
        Syntax = walk.Syntax,
        VisitorOption = walk.VisitorOption;

    /**
     * @param {object} opt
     */
    var getHeader = function (opt) {
        if (opt.omitHeader == true)
            return;
        var header = [
            "// Generated by shade.js"
        ];
        var floatPrecision = opt.floatPrecision || "mediump";
        header.push("precision " + floatPrecision + " float;");
        return header;
    }

    var toGLSLType = function (info) {
        switch (info.type) {
            case Types.OBJECT:
                switch (info.kind) {
                    case Kinds.COLOR:
                        return "vec3";
                    default:
                        throw new Error("toGLSLType: Unhandled kind: " + info.kind);
                }
            case Types.UNDEFINED:
                return "void";
            default:
                throw new Error("toGLSLType: Unhandled type: " + info.type);

        }

    }

    var generate = function (ast, opt) {

        opt = opt || {};

        var lines = [];

        walk.traverse(ast, {
                enter: function (node) {
                    var type = node.type;
                    switch (type) {

                        case Syntax.Program:
                            lines = lines.concat(getHeader(opt));
                            break;

                        case Syntax.FunctionDeclaration:
                            var func = new FunctionAnnotation(node);
                            var methodStart = [toGLSLType(func.getReturnInfo())];
                            methodStart.push(node.id.name, '(');
                            if (!(node.params && node.params.length)) {
                               methodStart.push("void");
                            } else {
                                node.params.forEach(function (param) {
                                    methodStart.push(param.name);
                                })
                            }
                            methodStart.push(') {');
                            lines.push(methodStart.join(" "));
                            return;

                        case Syntax.ReturnStatement:
                            var hasArguments = node.argument;
                            lines.push("return " + (hasArguments ? handleExpression(node.argument) : "") + ";");
                            return;

                        case Syntax.AssignmentExpression:
                            lines.push(handleExpression(node) + ";");
                            return;

                        case Syntax.ExpressionStatement:
                            lines.push(handleExpression(node.expression) + ";");
                            return VisitorOption.Skip;

                        default:
                            //console.log("Unhandled: " + type);

                    }
                },
                leave: function (node) {
                    var type = node.type;
                    switch (type) {
                        case Syntax.Program:
                            break;
                        case Syntax.FunctionDeclaration:
                            lines.push("};");
                            break
                    }
                }
            }
        );
        return lines.join("\n");
    }

    /**
     *
     * @param node
     * @returns {string}
     */
    var handleExpression = function(node) {
        var result = "<unhandled>";
        switch(node.type) {
            case Syntax.NewExpression:
                result = toGLSLType(node.extra);
                result += handleArguments(node.arguments);
                break;

            case Syntax.Literal:
                result = node.extra.staticValue;
                break;

            case Syntax.Identifier:
                result = node.name;
                break;

            case Syntax.AssignmentExpression:
                result = handleExpression(node.left);
                result += " " + node.operator + " ";
                result += handleExpression(node.right);
                break;

            case Syntax.CallExpression:
                result = handleExpression(node.callee);
                result += handleArguments(node.arguments);
                break;

            case Syntax.MemberExpression:
                result = handleExpression(node.object);
                result += ".";
                result += handleExpression(node.property);
                break;
            default:
                //console.log("Unhandled: " , node.type);
        }
        return result;
    }

    function handleArguments(container) {
        var result = "(";
        container.forEach(function (arg, index) {
            result += handleExpression(arg);
            if (index < container.length - 1) {
                result += ", ";
            }
        });
        return result + ")";
    }

    exports.generate = generate;

}(exports));
<|endoftext|>


<commit_before>#!/usr/bin/env node
var minimist = require('minimist')
var JSONStream = require('JSONStream')
var ncbi = require('./')

var minimistOptions = {
  alias: {
    limit: 'l',
    throughput: 't'
  }
}

var argv = minimist(process.argv.slice(2), minimistOptions)

var command = argv._[0]
var arg1 = argv._[1]
var lastArg = argv._[argv._.length - 1]
var wantsStdin = false
if (lastArg === '-') {
  wantsStdin = true
  argv._.pop()
}

if (command === 'link') {
  var arg2 = argv._[2]
  var arg3 = argv._[3]
}
else {
  var arg2 = argv._.slice(2).join(' ')
  var arg3 = null
}

var options
if (Object.keys(argv).length > 1) {
  options = {
    limit: argv.limit,
    throughput: argv.throughput,
    db: arg1,
    term: arg2
  }
}

var ncbiStream = options ? ncbi[command](options) : ncbi[command](arg1, arg2, arg3)

ncbiStream.pipe(JSONStream.stringify(false)).pipe(process.stdout)

if (wantsStdin) {
  process.stdin.setEncoding('utf8');

  process.stdin.on('data', function(data) {
    if (data.trim() === '') { return }
    ncbiStream.write(data.trim())
  })
}

<commit_msg>Fix error when output closes before end (e.g., head -n 1)<commit_after>#!/usr/bin/env node
var minimist = require('minimist')
var JSONStream = require('JSONStream')
var ncbi = require('./')

var minimistOptions = {
  alias: {
    limit: 'l',
    throughput: 't'
  }
}

var argv = minimist(process.argv.slice(2), minimistOptions)

var command = argv._[0]
var arg1 = argv._[1]
var lastArg = argv._[argv._.length - 1]
var wantsStdin = false
if (lastArg === '-') {
  wantsStdin = true
  argv._.pop()
}

if (command === 'link') {
  var arg2 = argv._[2]
  var arg3 = argv._[3]
}
else {
  var arg2 = argv._.slice(2).join(' ')
  var arg3 = null
}

var options
if (Object.keys(argv).length > 1) {
  options = {
    limit: argv.limit,
    throughput: argv.throughput,
    db: arg1,
    term: arg2
  }
}

var ncbiStream = options ? ncbi[command](options) : ncbi[command](arg1, arg2, arg3)

ncbiStream.pipe(JSONStream.stringify(false)).pipe(process.stdout)

if (wantsStdin) {
  process.stdin.setEncoding('utf8');

  process.stdin.on('data', function(data) {
    if (data.trim() === '') { return }
    ncbiStream.write(data.trim())
  })
}

process.stdout.on('error', function (err) {
  if (err.code === 'EPIPE') { process.exit(0) }
})
<|endoftext|>


<commit_before>#!/usr/bin/env node
"use strict";

var path = require("path"),
  debug = require("debug"),
  rabbit = require("rabbit.js"),
  Q = require("q");

debug = debug("tile-squirrel-cacher");

module.exports = function(opts) {
  var tilelive = require("tilelive");

  // load and register tilelive modules
  require("tilelive-modules/loader")(tilelive, opts);

  //Load all sources
  var sources = {};
  var sinks = {};

  var config = require(path.resolve(opts.config));

  if (opts.defer) {
    debug("Loading " + Object.keys(config).length + " sources");
    var sourceLoadingPromises = [];
    Object.keys(config).forEach(function(key) {
      (function() {
        var deferred = Q.defer();
        sourceLoadingPromises.push(deferred.promise);
        tilelive.load(config[key]["source"], function(err, src) {
          if (err) {
            console.log("Error loading source " + config[key]["source"]);
            return deferred.reject(err);
          }
          sources[key] = src;
          tilelive.load(config[key]["destination"], function(err, dest) {
            if (err) {
              console.log("Error loading destination " + config[key]["destination"]);
              return deferred.reject(err);
            }
            sinks[key] = dest;
            deferred.resolve();
          });
        });
      })();
    });

    Q.all(sourceLoadingPromises).then(
      function() {
        debug("Finished loading sources");
        start();
      },
      function(err) {
        debug("Error loading sources");
        console.log(err);
        process.exit(-1);
      }
    );
    sourceLoadingPromises = null;
  } else {
    start();
  }

  function start() {
    if (opts.stdin) {
      var pipe = process.stdin.pipe(require("split")());
      var ended = false;
      var requestCount = 0;
      var finishedCount = 0;
      pipe.on("data", function processLine(line) {
        if (line.length) {
          requestCount++;
          processRequest(
            line,
            function() {
              debug("Request finished " + line);
              finishedCount++;
              if (ended && finishedCount == requestCount) {
                process.exit(0);
              }
            },
            function(err) {
              console.log("Error processing request: " + err);
            }
          );
        }
      });
      pipe.on("end", function() {
        ended = true;
        if (requestCount == 0) {
          debug("Finished reading STDIN with data read, exiting.");
          process.exit(0);
        } else {
          debug("Finished reading STDIN, waiting for tile ");
        }
      });
    } else {
      listen();
    }
  }

  function listen() {
    var ampqHost = process.env.AMPQ_HOST || "localhost";
    var server = "amqp://" + ampqHost;
    var ampqTopic = process.env.AMPQ_TOPIC || "tiles";

    debug("Starting queue listener for " + server + "/" + ampqTopic);

    var queueContext = rabbit.createContext(server);
    queueContext.on("ready", function() {
      debug("Connected to context");
      var sub = queueContext.socket("WORKER", { prefetch: 2 });
      sub.connect(ampqTopic, function() {
        debug("Connected to socket for " + ampqTopic);
        sub.on("data", function(note) {
          var subThis = this; //keep a ref to this around for use in later scopes
          debug("Received request " + note.toString());
          processRequestMessage(
            note.toString(),
            function() {
              subThis.ack();
            },
            function(err) {
              subThis.requeue();
            }
          );
        });
      });
    });
  }

  function processRequestMessage(request, success, errorC) {
    var messageComponents = request.split("+");
    var sourceName = messageComponents[0];
    var tileComponents = messageComponents[1].split("/");

    var source = sources[sourceName];
    var dest = sinks[sourceName];
    if (source == null) {
      if (opts.defer) {
        tilelive.load(config[sourceName]["source"], function(err, src) {
          if (err) {
            console.log("Error loading source " + config[sourceName]["source"]);
            return success(err);
          }
          sources[sourceName] = src;
          tilelive.load(config[sourceName]["destination"], function(err, dest) {
            if (err) {
              console.log("Error loading destination " + config[sourceName]["destination"]);
              return errorC(err);
            }
            sinks[sourceName] = dest;
            processRequest(tileComponents, source, dest, success, errorC);
          });
        });
      } else {
        //source not found, send it back to the queue
        console.log("Error: source " + sourceName + " not found");
        return errorC(null);
      }
    } else {
      processRequest(tileComponents, source, dest, success, errorC);
    }
  }

  function processRequest(tileComponents, source, dest, success, errorC) {
    var z = parseInt(tileComponents[0]);
    var startX, endX, startY, endY;
    var xComponents = tileComponents[1].split("-");
    if (xComponents.length == 1) {
      startX = endX = parseInt(xComponents[0]);
    } else {
      startX = parseInt(xComponents[0]);
      endX = parseInt(xComponents[1]);
    }

    var yComponents = tileComponents[2].split("-");
    if (yComponents.length == 1) {
      startY = endY = parseInt(yComponents[0]);
    } else {
      startY = parseInt(yComponents[0]);
      endY = parseInt(yComponents[1]);
    }

    debug("opening source " + config[sourceName]["destination"] + " for writing");
    dest.startWriting(function(err) {
      if (err) {
        console.log(err);
        throw err;
      }
      var tilePromises = [];

      for (var x = startX; x <= endX; x++) {
        for (var y = startY; y <= endY; y++) {
          (function() {
            var tileX = x,
              tileY = y,
              tileZ = z,
              deferred = Q.defer();

            source.getTile(tileZ, tileX, tileY, function(err, tile, options) {
              if (err) {
                console.log(err);
              } else {
                debug("Rendered tile " + sourceName + "+" + tileZ + "/" + tileX + "/" + tileY);
                dest.putTile(tileZ, tileX, tileY, tile, function(err) {
                  if (err) {
                    console.log(err);
                    deferred.reject(err);
                  } else {
                    deferred.resolve();
                  }
                });
              }
            });
            tilePromises.push(deferred.promise);
          })();
        }
      }

      debug("Waiting for " + tilePromises.length + " tiles to render for " + request);
      Q.all(tilePromises).then(
        function() {
          debug("All tile promises resolved, closing source for writing for " + request);
          dest.stopWriting(function(err) {
            if (err) {
              console.log(err);
              errorC(err);
            } else {
              success();
            }
          });
        },
        function(err) {
          console.log("error resolving tile promises", err);
          errorC(err);
        }
      );
    });
  }
};
<commit_msg>Fix backward logic for defer<commit_after>#!/usr/bin/env node
"use strict";

var path = require("path"),
  debug = require("debug"),
  rabbit = require("rabbit.js"),
  Q = require("q");

debug = debug("tile-squirrel-cacher");

module.exports = function(opts) {
  var tilelive = require("tilelive");

  // load and register tilelive modules
  require("tilelive-modules/loader")(tilelive, opts);

  //Load all sources
  var sources = {};
  var sinks = {};

  var config = require(path.resolve(opts.config));
  if (opts.defer) {
    start();
  } else {
    debug("Loading " + Object.keys(config).length + " sources");
    var sourceLoadingPromises = [];
    Object.keys(config).forEach(function(key) {
      (function() {
        var deferred = Q.defer();
        sourceLoadingPromises.push(deferred.promise);
        tilelive.load(config[key]["source"], function(err, src) {
          if (err) {
            console.log("Error loading source " + config[key]["source"]);
            return deferred.reject(err);
          }
          sources[key] = src;
          tilelive.load(config[key]["destination"], function(err, dest) {
            if (err) {
              console.log("Error loading destination " + config[key]["destination"]);
              return deferred.reject(err);
            }
            sinks[key] = dest;
            deferred.resolve();
          });
        });
      })();
    });

    Q.all(sourceLoadingPromises).then(
      function() {
        debug("Finished loading sources");
        start();
      },
      function(err) {
        debug("Error loading sources");
        console.log(err);
        process.exit(-1);
      }
    );
    sourceLoadingPromises = null;
  }

  function start() {
    if (opts.stdin) {
      var pipe = process.stdin.pipe(require("split")());
      var ended = false;
      var requestCount = 0;
      var finishedCount = 0;
      pipe.on("data", function processLine(line) {
        if (line.length) {
          requestCount++;
          processRequest(
            line,
            function() {
              debug("Request finished " + line);
              finishedCount++;
              if (ended && finishedCount == requestCount) {
                process.exit(0);
              }
            },
            function(err) {
              console.log("Error processing request: " + err);
            }
          );
        }
      });
      pipe.on("end", function() {
        ended = true;
        if (requestCount == 0) {
          debug("Finished reading STDIN with data read, exiting.");
          process.exit(0);
        } else {
          debug("Finished reading STDIN, waiting for tile ");
        }
      });
    } else {
      listen();
    }
  }

  function listen() {
    var ampqHost = process.env.AMPQ_HOST || "localhost";
    var server = "amqp://" + ampqHost;
    var ampqTopic = process.env.AMPQ_TOPIC || "tiles";

    debug("Starting queue listener for " + server + "/" + ampqTopic);

    var queueContext = rabbit.createContext(server);
    queueContext.on("ready", function() {
      debug("Connected to context");
      var sub = queueContext.socket("WORKER", { prefetch: 2 });
      sub.connect(ampqTopic, function() {
        debug("Connected to socket for " + ampqTopic);
        sub.on("data", function(note) {
          var subThis = this; //keep a ref to this around for use in later scopes
          debug("Received request " + note.toString());
          processRequestMessage(
            note.toString(),
            function() {
              subThis.ack();
            },
            function(err) {
              subThis.requeue();
            }
          );
        });
      });
    });
  }

  function processRequestMessage(request, success, errorC) {
    var messageComponents = request.split("+");
    var sourceName = messageComponents[0];
    var tileComponents = messageComponents[1].split("/");

    var source = sources[sourceName];
    var dest = sinks[sourceName];
    if (source == null) {
      if (opts.defer) {
        tilelive.load(config[sourceName]["source"], function(err, src) {
          if (err) {
            console.log("Error loading source " + config[sourceName]["source"]);
            return success(err);
          }
          sources[sourceName] = src;
          tilelive.load(config[sourceName]["destination"], function(err, dest) {
            if (err) {
              console.log("Error loading destination " + config[sourceName]["destination"]);
              return errorC(err);
            }
            sinks[sourceName] = dest;
            processRequest(tileComponents, source, dest, success, errorC);
          });
        });
      } else {
        //source not found, send it back to the queue
        console.log("Error: source " + sourceName + " not found");
        return errorC(null);
      }
    } else {
      processRequest(tileComponents, source, dest, success, errorC);
    }
  }

  function processRequest(tileComponents, source, dest, success, errorC) {
    var z = parseInt(tileComponents[0]);
    var startX, endX, startY, endY;
    var xComponents = tileComponents[1].split("-");
    if (xComponents.length == 1) {
      startX = endX = parseInt(xComponents[0]);
    } else {
      startX = parseInt(xComponents[0]);
      endX = parseInt(xComponents[1]);
    }

    var yComponents = tileComponents[2].split("-");
    if (yComponents.length == 1) {
      startY = endY = parseInt(yComponents[0]);
    } else {
      startY = parseInt(yComponents[0]);
      endY = parseInt(yComponents[1]);
    }

    debug("opening source " + config[sourceName]["destination"] + " for writing");
    dest.startWriting(function(err) {
      if (err) {
        console.log(err);
        throw err;
      }
      var tilePromises = [];

      for (var x = startX; x <= endX; x++) {
        for (var y = startY; y <= endY; y++) {
          (function() {
            var tileX = x,
              tileY = y,
              tileZ = z,
              deferred = Q.defer();

            source.getTile(tileZ, tileX, tileY, function(err, tile, options) {
              if (err) {
                console.log(err);
              } else {
                debug("Rendered tile " + sourceName + "+" + tileZ + "/" + tileX + "/" + tileY);
                dest.putTile(tileZ, tileX, tileY, tile, function(err) {
                  if (err) {
                    console.log(err);
                    deferred.reject(err);
                  } else {
                    deferred.resolve();
                  }
                });
              }
            });
            tilePromises.push(deferred.promise);
          })();
        }
      }

      debug("Waiting for " + tilePromises.length + " tiles to render for " + request);
      Q.all(tilePromises).then(
        function() {
          debug("All tile promises resolved, closing source for writing for " + request);
          dest.stopWriting(function(err) {
            if (err) {
              console.log(err);
              errorC(err);
            } else {
              success();
            }
          });
        },
        function(err) {
          console.log("error resolving tile promises", err);
          errorC(err);
        }
      );
    });
  }
};
<|endoftext|>


<commit_before>class MCTemplateBuilderPropertiesComponentController {
    /*@ngInject*/
    constructor(templateUnits) {
        this.templateUnits = templateUnits;
    }

    addUnits(property) {
        this.templateUnits.showChoices().then(
            (unitType) => {
                property.units = unitType.units;
                property.hasUnitGroup = true;
            }
        )
    }

    checkIfEmpty(property) {
        property.hasUnitGroup = units.length;
    }
}

angular.module('materialscommons').component('mcTemplateBuilderProperties', {
    templateUrl: 'app/components/templates/mc-template-builder/mc-template-builder-properties.html',
    controller: MCTemplateBuilderPropertiesComponentController,
    bindings: {
        properties: '=',
        message: '@'
    }
});<commit_msg>Fix error on build<commit_after>class MCTemplateBuilderPropertiesComponentController {
    /*@ngInject*/
    constructor(templateUnits) {
        this.templateUnits = templateUnits;
    }

    addUnits(property) {
        this.templateUnits.showChoices().then(
            (unitType) => {
                property.units = unitType.units;
                property.hasUnitGroup = true;
            }
        )
    }

    checkIfEmpty(property) {
        property.hasUnitGroup = property.units.length;
    }
}

angular.module('materialscommons').component('mcTemplateBuilderProperties', {
    templateUrl: 'app/components/templates/mc-template-builder/mc-template-builder-properties.html',
    controller: MCTemplateBuilderPropertiesComponentController,
    bindings: {
        properties: '=',
        message: '@'
    }
});<|endoftext|>


<commit_before>// Unique ID creation requires a high quality random # generator.  In the
// browser this is a little complicated due to unknown quality of Math.random()
// and inconsistent support for the `crypto` API.  We do the best we can via
// feature-detection

var getRandomValues = typeof(crypto) != 'undefined' && crypto.getRandomValues;

if (getRandomValues) {
  // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto
  var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef

  module.exports = function whatwgRNG() {
    getRandomValues(rnds8);
    return rnds8;
  };
} else {
  // Math.random()-based (RNG)
  //
  // If all else fails, use Math.random().  It's fast, but is of unspecified
  // quality.
  var rnds = new Array(16);

  module.exports = function mathRNG() {
    for (var i = 0, r; i < 16; i++) {
      if ((i & 0x03) === 0) r = Math.random() * 0x100000000;
      rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
    }

    return rnds;
  };
}
<commit_msg>fix: use msCrypto if available. Fixes #241 (#247)<commit_after>// Unique ID creation requires a high quality random # generator.  In the
// browser this is a little complicated due to unknown quality of Math.random()
// and inconsistent support for the `crypto` API.  We do the best we can via
// feature-detection

var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues) ||
                      (typeof(msCrypto) != 'undefined' && msCrypto.getRandomValues);
if (getRandomValues) {
  // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto
  var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef

  module.exports = function whatwgRNG() {
    getRandomValues(rnds8);
    return rnds8;
  };
} else {
  // Math.random()-based (RNG)
  //
  // If all else fails, use Math.random().  It's fast, but is of unspecified
  // quality.
  var rnds = new Array(16);

  module.exports = function mathRNG() {
    for (var i = 0, r; i < 16; i++) {
      if ((i & 0x03) === 0) r = Math.random() * 0x100000000;
      rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
    }

    return rnds;
  };
}
<|endoftext|>