<commit_before>// load('can/util/make.js')

/**
 * How this all works:
 *
 * There are 4 scenarios to account for with canjs library loading:
 * development, building with env.js, using the standalone canjs scripts,
 * and using a fully built production.js file.
 *
 * 1) development mode - the libaries will be loaded by their corresponding util plugin
 * 		(the _skip option is ignored in dev mode)
 * 2) while building with env.js - skipCallbacks is set in steal and _skip option causes env.js
 * 		not load the libary files (because isBuilding is set in open.js).  All this is to avoid loading
 * 		the libraries in env.js, because env throws errors while loading them.  skipCallbacks allows no
 * 		steal callbacks to be called, so the build finishes without error.  This is mainly for use in this
 * 		make.js script. The libs other than jQuery can't be used yet in a full production.js build because
 * 		of this env weakness.
 * 3) using the standalone canjs scripts - these scripts are build with pluginify, so they don't include any
 * 		reference to steal.  They require the user to load the actual libarary file first, then the corresponding
 * 		canjs script.
 * 4) using a fully built production.js file - This is only really relevant for jQuery until the env build
 * 		problem is fixed. The libs are built into the production.js file.
 *
 */

load("steal/rhino/rhino.js");
steal('steal/build/pluginify', function() {

	steal.File("can/dist").mkdirs();
	steal.File("can/dist/edge").mkdirs();
	steal.build.pluginify("can/util/make/jquery.js",{
		out : "can/dist/edge/can.jquery.min.js",
		global : "can = {}",
		onefunc : true,
		compress: true,
		skipCallbacks: true,
		exclude : "can/util/jquery/jquery.1.7.1.js"
	});

	steal.build.pluginify("can/util/make/mootools.js",{
		out : "can/dist/edge/can.mootools.min.js",
		global : "can = {}",
		onefunc : true,
		compress: true,
		skipCallbacks: true
	});

	steal.build.pluginify("can/util/make/zepto.js",{
		out : "can/dist/edge/can.zepto.min.js",
		global : "can = {}",
		onefunc : true,
		compress: true,
		skipCallbacks: true
	});

	steal.build.pluginify("can/util/make/dojo.js",{
		out : "can/dist/edge/can.dojo.min.js",
		global : "can = {}",
		onefunc : true,
		compress: true,
		wrapInner: ['\ndefine("can/dojo", ["dojo/query", "dojo/NodeList-dom", "dojo/NodeList-traverse"], function(){\n', '\nreturn can;\n});\n'],
		skipCallbacks: true
	});

	steal.build.pluginify("can/util/make/yui.js",{
		out : "can/dist/edge/can.yui.min.js",
		global : "can = {}",
		onefunc : true,
		compress: true,
		wrapInner: ['\nYUI().add("can", function(Y) {\ncan.Y = Y;\n','}, "0.0.1", {\nrequires: ["node", "io-base", "querystring", "event-focus", "array-extras"]\noptional: ["selector-css2", "selector-css3"]\n});\n'],
		skipCallbacks: true
	});

	steal.build.pluginify("can/util/make/jquery.js",{
		out : "can/dist/edge/can.jquery.js",
		global : "can = {}",
		onefunc : true,
		compress: false,
		skipCallbacks: true,
		exclude : "can/util/jquery/jquery.1.7.1.js"
	});

	steal.build.pluginify("can/util/make/mootools.js",{
		out : "can/dist/edge/can.mootools.js",
		global : "can = {}",
		onefunc : true,
		compress: false,
		skipCallbacks: true
	});

	steal.build.pluginify("can/util/make/zepto.js",{
		out : "can/dist/edge/can.zepto.js",
		global : "can = {}",
		onefunc : true,
		compress: false,
		skipCallbacks: true
	});

	steal.build.pluginify("can/util/make/dojo.js",{
		out : "can/dist/edge/can.dojo.js",
		global : "can = {}",
		onefunc : true,
		compress: false,
		wrapInner: ['\ndefine("can/dojo", ["dojo/query", "dojo/NodeList-dom", "dojo/NodeList-traverse"], function(){\n', '\nreturn can;\n});\n'],
		skipCallbacks: true
	});

	steal.build.pluginify("can/util/make/yui.js",{
		out : "can/dist/edge/can.yui.js",
		global : "can = {}",
		onefunc : true,
		compress: false,
		wrapInner: ['\nYUI().add("can", function(Y) {\n','}, "0.0.1", {\nrequires: ["node", "io-base", "querystring", "event-focus", "array-extras"],\noptional: ["selector-css2", "selector-css3"]\n});\n'],
		skipCallbacks: true
	});

	STEALJQUERY = true;
	STEALDOJO = false;
	STEALMOO = false;
	STEALYUI = false;
	STEALZEPTO = false;

	steal.build.pluginify("can/construct/proxy/proxy.js", {
		out: "can/dist/edge/can.construct.proxy.js",
		global: "can = {}",
		onefunc: true,
		compress: false,
		skipCallbacks: true,
		standAlone: true
	});

	steal.build.pluginify("can/construct/super/super.js", {
		out: "can/dist/edge/can.construct.super.js",
		global: "can = {}",
		onefunc: true,
		compress: false,
		skipCallbacks: true,
		standAlone: true
	});

	steal.build.pluginify("can/control/plugin/plugin.js", {
		out: "can/dist/edge/can.control.plugin.js",
		global: "can = {}",
		onefunc: true,
		compress: false,
		skipCallbacks: true,
		standAlone: true
	});

	steal.build.pluginify("can/observe/attributes/attributes.js", {
		out: "can/dist/edge/can.observe.attributes.js",
		global: "can = {}",
		onefunc: true,
		compress: false,
		skipCallbacks: true,
		standAlone: true
	});

	steal.build.pluginify("can/observe/delegate/delegate.js", {
		out: "can/dist/edge/can.observe.delegate.js",
		global: "can = {}",
		onefunc: true,
		compress: false,
		skipCallbacks: true,
		standAlone: true
	});

	steal.build.pluginify("can/observe/setter/setter.js", {
		out: "can/dist/edge/can.observe.setter.js",
		global: "can = {}",
		onefunc: true,
		compress: false,
		skipCallbacks: true,
		standAlone: true
	});

	steal.build.pluginify("can/observe/backup/backup.js", {
		out: "can/dist/edge/can.observe.backup.js",
		global: "can = {}",
		onefunc: true,
		compress: false,
		skipCallbacks: true,
		standAlone: true
	});

	steal.build.pluginify("can/observe/validations/validations.js", {
		out: "can/dist/edge/can.observe.validations.js",
		global: "can = {}",
		onefunc: true,
		compress: false,
		skipCallbacks: true,
		standAlone: true
	});

	steal.build.pluginify("can/construct/proxy/proxy.js", {
		out: "can/dist/edge/can.construct.proxy.min.js",
		global: "can = {}",
		onefunc: true,
		compress: true,
		skipCallbacks: true,
		standAlone: true
	});

	steal.build.pluginify("can/construct/super/super.js", {
		out: "can/dist/edge/can.construct.super.min.js",
		global: "can = {}",
		onefunc: true,
		compress: true,
		skipCallbacks: true,
		standAlone: true
	});

	steal.build.pluginify("can/control/plugin/plugin.js", {
		out: "can/dist/edge/can.control.plugin.min.js",
		global: "can = {}",
		onefunc: true,
		compress: true,
		skipCallbacks: true,
		standAlone: true
	});

	steal.build.pluginify("can/observe/attributes/attributes.js", {
		out: "can/dist/edge/can.observe.attributes.min.js",
		global: "can = {}",
		onefunc: true,
		compress: true,
		skipCallbacks: true,
		standAlone: true
	});

	steal.build.pluginify("can/observe/delegate/delegate.js", {
		out: "can/dist/edge/can.observe.delegate.min.js",
		global: "can = {}",
		onefunc: true,
		compress: true,
		skipCallbacks: true,
		standAlone: true
	});

	steal.build.pluginify("can/observe/setter/setter.js", {
		out: "can/dist/edge/can.observe.setter.min.js",
		global: "can = {}",
		onefunc: true,
		compress: true,
		skipCallbacks: true,
		standAlone: true
	});

	steal.build.pluginify("can/observe/backup/backup.js", {
		out: "can/dist/edge/can.observe.backup.min.js",
		global: "can = {}",
		onefunc: true,
		compress: true,
		skipCallbacks: true,
		standAlone: true
	});

	steal.build.pluginify("can/observe/validations/validations.js", {
		out: "can/dist/edge/can.observe.validations.min.js",
		global: "can = {}",
		onefunc: true,
		compress: true,
		skipCallbacks: true,
		standAlone: true
	});

});<commit_msg>fixing yui build<commit_after>// load('can/util/make.js')

/**
 * How this all works:
 *
 * There are 4 scenarios to account for with canjs library loading:
 * development, building with env.js, using the standalone canjs scripts,
 * and using a fully built production.js file.
 *
 * 1) development mode - the libaries will be loaded by their corresponding util plugin
 * 		(the _skip option is ignored in dev mode)
 * 2) while building with env.js - skipCallbacks is set in steal and _skip option causes env.js
 * 		not load the libary files (because isBuilding is set in open.js).  All this is to avoid loading
 * 		the libraries in env.js, because env throws errors while loading them.  skipCallbacks allows no
 * 		steal callbacks to be called, so the build finishes without error.  This is mainly for use in this
 * 		make.js script. The libs other than jQuery can't be used yet in a full production.js build because
 * 		of this env weakness.
 * 3) using the standalone canjs scripts - these scripts are build with pluginify, so they don't include any
 * 		reference to steal.  They require the user to load the actual libarary file first, then the corresponding
 * 		canjs script.
 * 4) using a fully built production.js file - This is only really relevant for jQuery until the env build
 * 		problem is fixed. The libs are built into the production.js file.
 *
 */

load("steal/rhino/rhino.js");
steal('steal/build/pluginify', function() {

	steal.File("can/dist").mkdirs();
	steal.File("can/dist/edge").mkdirs();
	steal.build.pluginify("can/util/make/jquery.js",{
		out : "can/dist/edge/can.jquery.min.js",
		global : "can = {}",
		onefunc : true,
		compress: true,
		skipCallbacks: true,
		exclude : "can/util/jquery/jquery.1.7.1.js"
	});

	steal.build.pluginify("can/util/make/mootools.js",{
		out : "can/dist/edge/can.mootools.min.js",
		global : "can = {}",
		onefunc : true,
		compress: true,
		skipCallbacks: true
	});

	steal.build.pluginify("can/util/make/zepto.js",{
		out : "can/dist/edge/can.zepto.min.js",
		global : "can = {}",
		onefunc : true,
		compress: true,
		skipCallbacks: true
	});

	steal.build.pluginify("can/util/make/dojo.js",{
		out : "can/dist/edge/can.dojo.min.js",
		global : "can = {}",
		onefunc : true,
		compress: true,
		wrapInner: ['\ndefine("can/dojo", ["dojo/query", "dojo/NodeList-dom", "dojo/NodeList-traverse"], function(){\n', '\nreturn can;\n});\n'],
		skipCallbacks: true
	});

	steal.build.pluginify("can/util/make/yui.js",{
		out : "can/dist/edge/can.yui.min.js",
		global : "can = {}",
		onefunc : true,
		compress: true,
		wrapInner: ['\nYUI().add("can", function(Y) {\ncan.Y = Y;\n','}, "0.0.1", {\nrequires: ["node", "io-base", "querystring", "event-focus", "array-extras"]\n, optional: ["selector-css2", "selector-css3"]\n});\n'],
		skipCallbacks: true
	});

	steal.build.pluginify("can/util/make/jquery.js",{
		out : "can/dist/edge/can.jquery.js",
		global : "can = {}",
		onefunc : true,
		compress: false,
		skipCallbacks: true,
		exclude : "can/util/jquery/jquery.1.7.1.js"
	});

	steal.build.pluginify("can/util/make/mootools.js",{
		out : "can/dist/edge/can.mootools.js",
		global : "can = {}",
		onefunc : true,
		compress: false,
		skipCallbacks: true
	});

	steal.build.pluginify("can/util/make/zepto.js",{
		out : "can/dist/edge/can.zepto.js",
		global : "can = {}",
		onefunc : true,
		compress: false,
		skipCallbacks: true
	});

	steal.build.pluginify("can/util/make/dojo.js",{
		out : "can/dist/edge/can.dojo.js",
		global : "can = {}",
		onefunc : true,
		compress: false,
		wrapInner: ['\ndefine("can/dojo", ["dojo/query", "dojo/NodeList-dom", "dojo/NodeList-traverse"], function(){\n', '\nreturn can;\n});\n'],
		skipCallbacks: true
	});

	steal.build.pluginify("can/util/make/yui.js",{
		out : "can/dist/edge/can.yui.js",
		global : "can = {}",
		onefunc : true,
		compress: false,
		wrapInner: ['\nYUI().add("can", function(Y) {\n','}, "0.0.1", {\nrequires: ["node", "io-base", "querystring", "event-focus", "array-extras"],\n, optional: ["selector-css2", "selector-css3"]\n});\n'],
		skipCallbacks: true
	});

	STEALJQUERY = true;
	STEALDOJO = false;
	STEALMOO = false;
	STEALYUI = false;
	STEALZEPTO = false;

	steal.build.pluginify("can/construct/proxy/proxy.js", {
		out: "can/dist/edge/can.construct.proxy.js",
		global: "can = {}",
		onefunc: true,
		compress: false,
		skipCallbacks: true,
		standAlone: true
	});

	steal.build.pluginify("can/construct/super/super.js", {
		out: "can/dist/edge/can.construct.super.js",
		global: "can = {}",
		onefunc: true,
		compress: false,
		skipCallbacks: true,
		standAlone: true
	});

	steal.build.pluginify("can/control/plugin/plugin.js", {
		out: "can/dist/edge/can.control.plugin.js",
		global: "can = {}",
		onefunc: true,
		compress: false,
		skipCallbacks: true,
		standAlone: true
	});

	steal.build.pluginify("can/observe/attributes/attributes.js", {
		out: "can/dist/edge/can.observe.attributes.js",
		global: "can = {}",
		onefunc: true,
		compress: false,
		skipCallbacks: true,
		standAlone: true
	});

	steal.build.pluginify("can/observe/delegate/delegate.js", {
		out: "can/dist/edge/can.observe.delegate.js",
		global: "can = {}",
		onefunc: true,
		compress: false,
		skipCallbacks: true,
		standAlone: true
	});

	steal.build.pluginify("can/observe/setter/setter.js", {
		out: "can/dist/edge/can.observe.setter.js",
		global: "can = {}",
		onefunc: true,
		compress: false,
		skipCallbacks: true,
		standAlone: true
	});

	steal.build.pluginify("can/observe/backup/backup.js", {
		out: "can/dist/edge/can.observe.backup.js",
		global: "can = {}",
		onefunc: true,
		compress: false,
		skipCallbacks: true,
		standAlone: true
	});

	steal.build.pluginify("can/observe/validations/validations.js", {
		out: "can/dist/edge/can.observe.validations.js",
		global: "can = {}",
		onefunc: true,
		compress: false,
		skipCallbacks: true,
		standAlone: true
	});

});<|endoftext|>


<commit_before>var Task = require('./task').Task,
    IonicStats = require('./stats').IonicStats,
    fs = require('fs'),
    Q = require('q'),
    argv = require('optimist').boolean(['nohooks', 'n', 'r', 'noresources', 'nosave', 'e']).argv,
    path = require('path'),
    exec = require('child_process').exec,
    colors = require('colors'),
    shelljs = require('shelljs'),
    generate = require('./resources/generate'),
    settings = require('./resources/settings'),
    ionicAppLib = require('ionic-app-lib'),
    Cordova = ionicAppLib.cordova,
    Hooks = require('./hooks'),
    State = require('./state');

var IonicTask = function() {};

IonicTask.prototype = new Task();

IonicTask.prototype.run = function(ionic) {
  this.ionic = ionic;
  var self = this;
  var cmdName = process.argv[2].toLowerCase();
  var q;

  this.isLiveReload = ((cmdName == 'run' || cmdName == 'emulate') && (argv.livereload || argv['live-reload'] || argv.l));

  // Cordova.addPlatform(path.resolve('.'));
  // return;

  this.addIcons = !(argv.noresources || argv.r);

  if(this.isLiveReload) {
    q = self.setupLiveReload();

  } else {
    // ensure the content node was set back to its original
    q = self.ionic.setConfigXml({
      resetContent: true,
      errorWhenNotFound: false
    });
  }

  var addDefaultResources = false;
  var isPlatformCmd = argv._.indexOf('platform') != -1;
  var isAddCmd = argv._.indexOf('add') != -1;
  var isPluginCmd = argv._.indexOf('plugin') != -1;
  var isRmCmd = argv._.indexOf('rm') != -1 || argv._.indexOf('remove') != -1;

  if(isPlatformCmd && isAddCmd) {
    addDefaultResources = true;
  }
  // console.log('Icons: ', addDefaultResources, 'Add icons:', this.addIcons)

  q.then(function(){
    if(addDefaultResources && self.addIcons) {
      return generate.copyIconFilesIntoResources()
      .then(function() {
        return generate.addIonicIcons(argv._[2]);
      })
    } else {
      return false;
    }
  })
  .then(function() {
    return self.runCordova(cmdName);
  })
  .then(function(runCode) {
    //We dont want to do anything if the cordova command failed
    if(runCode !== 0 || argv.nosave) {
      return
    }
    if (isPlatformCmd && isAddCmd) {
      addDefaultResources = true;
      console.log('Saving platform to package.json file'.blue)
      return State.savePlatform(argv);
    } else if (isPlatformCmd && isRmCmd) {
      console.log('Removing platform from package.json file'.blue)
      return State.removePlatform(argv);
    } else if (isPluginCmd && isAddCmd) {
      console.log('Saving plugin to package.json file'.blue)
      return State.savePlugin(argv);
    } else if (isPluginCmd && isRmCmd) {
      console.log('Removing plugin from package.json file'.blue)
      return State.removePlugin(argv);
    }
  })
}

IonicTask.prototype.runCordova = function(cmdName) {
  var deferred = Q.defer();
  var self = this;
  var cmdArgs = (process.argv.length > 3 ? process.argv.slice(3) : []);
  var cmdArg, x, y;

  // backwards compatibility prior to fully wrapping cordova cmds
  if(cmdName == 'platform') {
    // `ionic platform <PLATFORM>` used to actually run `ionic platform add <PLATFORM>`
    // if a cordova platform cmd isn't the cmd then automatically insert `add`
    var hasCordovaCmd = false;
    var validCommands = 'add remove rm list ls update up check'.split(' ');
    for(x=0; x<cmdArgs.length; x++) {
      cmdArg = cmdArgs[x].toLowerCase();
      for(y=0; y<validCommands.length; y++) {
        if(cmdArg == validCommands[y]) {
          hasCordovaCmd = true;
          break;
        }
      }
    }

    if(!hasCordovaCmd) {
      cmdArgs.unshift('add');
    }
  }

  // var noHook = argv.nohooks || argv.n;

  // if (!noHook) {
  //   console.log('Adding in default Ionic hooks'.yellow.bold)
  //   // this.addHooks();
  //   // this.removeOldPluginHooks();
  // } else {
  //   console.log('Option passed to not install default Ionic hooks'.yellow.bold)
  // }

  cmdArgs.unshift(cmdName);

  // clean out any cmds that may confuse cordova
  var cleanArgs = [];
  var port = argv.port || argv.p || '';
  var liveReloadPort = argv.livereloadport || argv['livereload-port'] || argv.r || '';
  var ignoreCmds = '--livereload -l --consolelogs -c --serverlogs -s --port -p --livereload-port -i -r'.split(' ');
  var isValdCmd;
  for(x=0; x<cmdArgs.length; x++) {
    cmdArg = cmdArgs[x];
    if(port && cmdArg == port) continue;
    if(liveReloadPort && cmdArg == liveReloadPort) continue;
    isValdCmd = true;
    for(y=0; y<ignoreCmds.length; y++) {
      if(cmdArg == ignoreCmds[y]) {
        isValdCmd = false;
        break;
      }
    }
    if(isValdCmd) {
      // make sure --target= has double quotes around it (process.argv removes them)
      if(cmdArg.indexOf('--target=') === 0 && cmdArg.indexOf('"') === -1) {
        cmdArg = cmdArg.replace('--target=', '--target="') + '"';
      }

      cleanArgs.push(cmdArg);
    }
  }

  var cordovaProcess = exec('cordova ' + cleanArgs.join(' '));
  console.log('running cordova ' + cleanArgs.join(' '))

  cordovaProcess.stdout.on('data', function (data) {
    process.stdout.write(data);
  });

  cordovaProcess.stderr.on('data', function (data) {
    if(data) {
      process.stderr.write(data.toString().error.bold);
    }
  });

  cordovaProcess.on('close', function(code) {
    deferred.resolve(code);
  });

  if(self.isLiveReload) {
    cordovaProcess.on('exit', function(){
      console.log('cordova process is exiting');
      setTimeout(function(){
        // set it back to the original src after a few seconds
        self.ionic.setConfigXml({
          resetContent: true,
          errorWhenNotFound: true
        });
        // deferred.resolve();
      }, 5000);
    });

    process.on('exit', function(){
      // verify it was set back
      self.ionic.setConfigXml({
        resetContent: true,
        errorWhenNotFound: false
      });
    });

    var readLine = require("readline");
    if(process.platform === "win32") {
      var rl = readLine.createInterface ({
          input: process.stdin,
          output: process.stdout
      });

      rl.on("SIGINT", function (){
        process.emit("SIGINT");
      });
    }

    process.on("SIGINT", function(){
      process.exit();
    });
  }

  IonicStats.t();

  return deferred.promise;
};

IonicTask.prototype.setupLiveReload = function() {
  var d = Q.defer();

  console.log('Setup Live Reload'.green.bold);

  var self = this;
  var serve = new require('./serve');
  var serveTask = new serve.IonicTask();
  serveTask.ionic = this.ionic;
  serveTask.isPlatformServe = true;

  serveTask.loadSettings();

  serveTask.getAddress()
  .then(function() {
    return serveTask.checkPorts(true, serveTask.port, serveTask.address);
  })
  .then(function() {
    if(serveTask.runLivereload) {
      return serveTask.checkPorts(false, serveTask.liveReloadPort, serveTask.address);
    }
  })
  .then(function() {

    serveTask.runLivereload = true;
    serveTask.launchBrowser = false;
    serveTask.launchLab = false;
    serveTask.start(self.ionic);

    if(self.ionic.hasFailed) return;

    self.ionic.setConfigXml({
      devServer: serveTask.devServer
    }).then(function(){
      d.resolve();
    });
  })
  .catch(function(error) {

  })

  return d.promise;
};

exports.IonicTask = IonicTask;
<commit_msg>Removing cordova exec message<commit_after>var Task = require('./task').Task,
    IonicStats = require('./stats').IonicStats,
    fs = require('fs'),
    Q = require('q'),
    argv = require('optimist').boolean(['nohooks', 'n', 'r', 'noresources', 'nosave', 'e']).argv,
    path = require('path'),
    exec = require('child_process').exec,
    colors = require('colors'),
    shelljs = require('shelljs'),
    generate = require('./resources/generate'),
    settings = require('./resources/settings'),
    ionicAppLib = require('ionic-app-lib'),
    Cordova = ionicAppLib.cordova,
    Hooks = require('./hooks'),
    State = require('./state');

var IonicTask = function() {};

IonicTask.prototype = new Task();

IonicTask.prototype.run = function(ionic) {
  this.ionic = ionic;
  var self = this;
  var cmdName = process.argv[2].toLowerCase();
  var q;

  this.isLiveReload = ((cmdName == 'run' || cmdName == 'emulate') && (argv.livereload || argv['live-reload'] || argv.l));

  // Cordova.addPlatform(path.resolve('.'));
  // return;

  this.addIcons = !(argv.noresources || argv.r);

  if(this.isLiveReload) {
    q = self.setupLiveReload();

  } else {
    // ensure the content node was set back to its original
    q = self.ionic.setConfigXml({
      resetContent: true,
      errorWhenNotFound: false
    });
  }

  var addDefaultResources = false;
  var isPlatformCmd = argv._.indexOf('platform') != -1;
  var isAddCmd = argv._.indexOf('add') != -1;
  var isPluginCmd = argv._.indexOf('plugin') != -1;
  var isRmCmd = argv._.indexOf('rm') != -1 || argv._.indexOf('remove') != -1;

  if(isPlatformCmd && isAddCmd) {
    addDefaultResources = true;
  }
  // console.log('Icons: ', addDefaultResources, 'Add icons:', this.addIcons)

  q.then(function(){
    if(addDefaultResources && self.addIcons) {
      return generate.copyIconFilesIntoResources()
      .then(function() {
        return generate.addIonicIcons(argv._[2]);
      })
    } else {
      return false;
    }
  })
  .then(function() {
    return self.runCordova(cmdName);
  })
  .then(function(runCode) {
    //We dont want to do anything if the cordova command failed
    if(runCode !== 0 || argv.nosave) {
      return
    }
    if (isPlatformCmd && isAddCmd) {
      addDefaultResources = true;
      console.log('Saving platform to package.json file'.blue)
      return State.savePlatform(argv);
    } else if (isPlatformCmd && isRmCmd) {
      console.log('Removing platform from package.json file'.blue)
      return State.removePlatform(argv);
    } else if (isPluginCmd && isAddCmd) {
      console.log('Saving plugin to package.json file'.blue)
      return State.savePlugin(argv);
    } else if (isPluginCmd && isRmCmd) {
      console.log('Removing plugin from package.json file'.blue)
      return State.removePlugin(argv);
    }
  })
}

IonicTask.prototype.runCordova = function(cmdName) {
  var deferred = Q.defer();
  var self = this;
  var cmdArgs = (process.argv.length > 3 ? process.argv.slice(3) : []);
  var cmdArg, x, y;

  // backwards compatibility prior to fully wrapping cordova cmds
  if(cmdName == 'platform') {
    // `ionic platform <PLATFORM>` used to actually run `ionic platform add <PLATFORM>`
    // if a cordova platform cmd isn't the cmd then automatically insert `add`
    var hasCordovaCmd = false;
    var validCommands = 'add remove rm list ls update up check'.split(' ');
    for(x=0; x<cmdArgs.length; x++) {
      cmdArg = cmdArgs[x].toLowerCase();
      for(y=0; y<validCommands.length; y++) {
        if(cmdArg == validCommands[y]) {
          hasCordovaCmd = true;
          break;
        }
      }
    }

    if(!hasCordovaCmd) {
      cmdArgs.unshift('add');
    }
  }

  // var noHook = argv.nohooks || argv.n;

  // if (!noHook) {
  //   console.log('Adding in default Ionic hooks'.yellow.bold)
  //   // this.addHooks();
  //   // this.removeOldPluginHooks();
  // } else {
  //   console.log('Option passed to not install default Ionic hooks'.yellow.bold)
  // }

  cmdArgs.unshift(cmdName);

  // clean out any cmds that may confuse cordova
  var cleanArgs = [];
  var port = argv.port || argv.p || '';
  var liveReloadPort = argv.livereloadport || argv['livereload-port'] || argv.r || '';
  var ignoreCmds = '--livereload -l --consolelogs -c --serverlogs -s --port -p --livereload-port -i -r'.split(' ');
  var isValdCmd;
  for(x=0; x<cmdArgs.length; x++) {
    cmdArg = cmdArgs[x];
    if(port && cmdArg == port) continue;
    if(liveReloadPort && cmdArg == liveReloadPort) continue;
    isValdCmd = true;
    for(y=0; y<ignoreCmds.length; y++) {
      if(cmdArg == ignoreCmds[y]) {
        isValdCmd = false;
        break;
      }
    }
    if(isValdCmd) {
      // make sure --target= has double quotes around it (process.argv removes them)
      if(cmdArg.indexOf('--target=') === 0 && cmdArg.indexOf('"') === -1) {
        cmdArg = cmdArg.replace('--target=', '--target="') + '"';
      }

      cleanArgs.push(cmdArg);
    }
  }

  var cordovaProcess = exec('cordova ' + cleanArgs.join(' '));
  // console.log('running cordova ' + cleanArgs.join(' '))

  cordovaProcess.stdout.on('data', function (data) {
    process.stdout.write(data);
  });

  cordovaProcess.stderr.on('data', function (data) {
    if(data) {
      process.stderr.write(data.toString().error.bold);
    }
  });

  cordovaProcess.on('close', function(code) {
    deferred.resolve(code);
  });

  if(self.isLiveReload) {
    cordovaProcess.on('exit', function(){
      console.log('cordova process is exiting');
      setTimeout(function(){
        // set it back to the original src after a few seconds
        self.ionic.setConfigXml({
          resetContent: true,
          errorWhenNotFound: true
        });
        // deferred.resolve();
      }, 5000);
    });

    process.on('exit', function(){
      // verify it was set back
      self.ionic.setConfigXml({
        resetContent: true,
        errorWhenNotFound: false
      });
    });

    var readLine = require("readline");
    if(process.platform === "win32") {
      var rl = readLine.createInterface ({
          input: process.stdin,
          output: process.stdout
      });

      rl.on("SIGINT", function (){
        process.emit("SIGINT");
      });
    }

    process.on("SIGINT", function(){
      process.exit();
    });
  }

  IonicStats.t();

  return deferred.promise;
};

IonicTask.prototype.setupLiveReload = function() {
  var d = Q.defer();

  console.log('Setup Live Reload'.green.bold);

  var self = this;
  var serve = new require('./serve');
  var serveTask = new serve.IonicTask();
  serveTask.ionic = this.ionic;
  serveTask.isPlatformServe = true;

  serveTask.loadSettings();

  serveTask.getAddress()
  .then(function() {
    return serveTask.checkPorts(true, serveTask.port, serveTask.address);
  })
  .then(function() {
    if(serveTask.runLivereload) {
      return serveTask.checkPorts(false, serveTask.liveReloadPort, serveTask.address);
    }
  })
  .then(function() {

    serveTask.runLivereload = true;
    serveTask.launchBrowser = false;
    serveTask.launchLab = false;
    serveTask.start(self.ionic);

    if(self.ionic.hasFailed) return;

    self.ionic.setConfigXml({
      devServer: serveTask.devServer
    }).then(function(){
      d.resolve();
    });
  })
  .catch(function(error) {

  })

  return d.promise;
};

exports.IonicTask = IonicTask;
<|endoftext|>


<commit_before>'use strict';
var gulp = require('gulp');
var gulpconfig = require('./gulp-config');

function getTask(taskname, gulpDeps){
	if(gulpDeps){
		return require(gulpconfig.taskspath + taskname)(gulp, gulpconfig, gulpDeps);
	}else{
		return require(gulpconfig.taskspath + taskname)(gulp, gulpconfig);
	}
}

module.exports = {
	getTask: getTask
};<commit_msg>getTask-Function changed<commit_after>'use strict';
var gulp = require('gulp');
var gulpconfig = require('./gulp-config');

function getTask(taskname, gulpDeps) {
	return require(gulpconfig.taskspath + taskname)(gulp, gulpconfig, gulpDeps);
}

module.exports = {
	getTask: getTask
};<|endoftext|>


<commit_before>
/**
 * access to the Enterprise Services backend service.
 *
 * @param kidoApp {object} - instance of the Kido class.
 */

var KidoService = function ( kidoApp, name ) {

    var self = this;

    if (!(this instanceof KidoService)) return new KidoService(kidoApp);
    if (!kidoApp) throw "The 'kidoApp' argument is required by the KidoService class.";

    /** variables **/

    this.app = kidoApp;
    this.name = name;
    this._defaults = {};

    /** methods **/

    this.defaults = function ( opts ) {

        self._defaults = $.extend(self._defaults, opts || {});
        return self;
    };

    this.invoke = function ( name, opts ) {
        var result = $.Deferred();
        var args = $.extend({}, self._defaults, opts);
        self.app
            .post("/api/services/" + self.name + "/invoke/" + name, args)
            .done(function ( res ) {
                if (res.error) {
                    return result.reject(res.error);
                }
                result.resolve(res.data || res);
            })
            .fail(function (err) {
                result.reject(err);
            });
        return result;
    };
};

Kido.prototype.services = function ( name ) {
    return new KidoService(this, name);
};<commit_msg>Added timeout parameter to service invocation<commit_after>/**
 * access to the Enterprise Services backend service.
 *
 * @param kidoApp {object} - instance of the Kido class.
 */

var KidoService = function ( kidoApp, name ) {

    var self = this;

    if (!(this instanceof KidoService)) return new KidoService(kidoApp);
    if (!kidoApp) throw "The 'kidoApp' argument is required by the KidoService class.";

    /** variables **/

    this.app = kidoApp;
    this.name = name;
    this._defaults = {};

    /** methods **/

    this.defaults = function ( opts ) {

        self._defaults = $.extend(self._defaults, opts || {});
        return self;
    };

    this.invoke = function ( name, opts, timeout ) {
        var result = $.Deferred();
        var args = $.extend({}, self._defaults, opts);
        var settings = timeout ? { headers: { "timeout": timeout } } : {};
        self.app
            .post("/api/services/" + self.name + "/invoke/" + name, args, settings)
            .done(function ( res ) {
                if (res.error) {
                    return result.reject(res.error);
                }
                result.resolve(res.data || res);
            })
            .fail(function (err) {
                result.reject(err);
            });
        return result;
    };
};

Kido.prototype.services = function ( name ) {
    return new KidoService(this, name);
};
<|endoftext|>


<commit_before>'use strict';

var names = require('../utils/names.js');

// https://www.w3.org/TR/css-values-3/#lengths
var LENGTH = {
    // absolute length units
    'px': true,
    'mm': true,
    'cm': true,
    'in': true,
    'pt': true,
    'pc': true,
    'q': true,

    // relative length units
    'em': true,
    'ex': true,
    'ch': true,
    'rem': true,

    // viewport-percentage lengths
    'vh': true,
    'vw': true,
    'vmin': true,
    'vmax': true,
    'vm': true
};

var ANGLE = {
    'deg': true,
    'grad': true,
    'rad': true,
    'turn': true
};

var TIME = {
    's': true,
    'ms': true
};

var FREQUENCY = {
    'hz': true,
    'khz': true
};

// https://www.w3.org/TR/css-values-3/#resolution
// https://www.w3.org/TR/css3-images/#resolution-type
var RESOLUTION = {
    'dpi': true,
    'dpcm': true,
    'dppx': true
};

// https://drafts.csswg.org/css-grid/#fr-unit
var FLEX = {
    'fr': true
};

// https://www.w3.org/TR/css3-speech/#mixing-props-voice-volume
var DECIBEL = {
    'db': true
};

// https://www.w3.org/TR/css3-speech/#voice-props-voice-pitch
var SEMITONES = {
    'st': true
};

// can be used wherever <length>, <frequency>, <angle>, <time>, <percentage>, <number>, or <integer> values are allowed
// https://drafts.csswg.org/css-values/#calc-notation
function isCalc(node) {
    if (node.data.type !== 'Function') {
        return false;
    }

    var keyword = names.keyword(node.data.name);

    if (keyword.name !== 'calc') {
        return false;
    }

    // there were some prefixed implementations
    return keyword.vendor === '' ||
           keyword.vendor === '-moz-' ||
           keyword.vendor === '-webkit-';
}

function astNode(type) {
    return function(node) {
        return node.data.type === type;
    };
}

function dimension(type) {
    return function(node) {
        return isCalc(node) ||
               (node.data.type === 'Dimension' && type.hasOwnProperty(node.data.unit.toLowerCase()));
    };
}

function zeroUnitlessDimension(type) {
    return function(node) {
        return isCalc(node) ||
               (node.data.type === 'Dimension' && type.hasOwnProperty(node.data.unit.toLowerCase())) ||
               (node.data.type === 'Number' && Number(node.data.value) === 0);
    };
}

function attr(node) {
    return node.data.type === 'Function' && node.data.name.toLowerCase() === 'attr';
}

function number(node) {
    return isCalc(node) || node.data.type === 'Number';
}

function numberZeroOne(node) {
    if (isCalc(node) || node.data.type === 'Number') {
        var value = Number(node.data.value);

        return value >= 0 && value <= 1;
    }

    return false;
}

function numberOneOrGreater(node) {
    if (isCalc(node) || node.data.type === 'Number') {
        return Number(node.data.value) >= 1;
    }

    return false;
}

// TODO: fail on 10e-2
function integer(node) {
    return isCalc(node) ||
           (node.data.type === 'Number' && node.data.value.indexOf('.') === -1);
}

// TODO: fail on 10e-2
function positiveInteger(node) {
    return isCalc(node) ||
           (node.data.type === 'Number' && node.data.value.indexOf('.') === -1 && node.data.value.charAt(0) !== '-');
}

function percentage(node) {
    return isCalc(node) ||
           node.data.type === 'Percentage';
}

function hexColor(node) {
    if (node.data.type !== 'HexColor') {
        return false;
    }

    var hex = node.data.value;

    return /^[0-9a-fA-F]{3,8}$/.test(hex) &&
           (hex.length === 3 || hex.length === 4 || hex.length === 6 || hex.length === 8);
}

function expression(node) {
    return node.data.type === 'Function' && node.data.name.toLowerCase() === 'expression';
}

// https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident
function customIdent(node) {
    if (node.data.type !== 'Identifier') {
        return false;
    }

    var name = node.data.name.toLowerCase();

    // can't be a global CSS value
    if (name === 'unset' || name === 'initial' || name === 'inherit') {
        return false;
    }

    // TODO: ignore property specific keywords (as described https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident)

    return true;
}

module.exports = {
    'angle': zeroUnitlessDimension(ANGLE),
    'attr()': attr,
    'custom-ident': customIdent,
    'decibel': dimension(DECIBEL),
    'dimension': astNode('Dimension'),
    'frequency': dimension(FREQUENCY),
    'flex': dimension(FLEX),
    'hex-color': hexColor,
    'id-selector': astNode('IdSelector'), // element( <id-selector> )
    'ident': astNode('Identifier'),
    'integer': integer,
    'length': zeroUnitlessDimension(LENGTH),
    'number': number,
    'number-zero-one': numberZeroOne,
    'number-one-or-greater': numberOneOrGreater,
    'percentage': percentage,
    'positive-integer': positiveInteger,
    'resolution': dimension(RESOLUTION),
    'semitones': dimension(SEMITONES),
    'string': astNode('String'),
    'time': dimension(TIME),
    'unicode-range': astNode('UnicodeRange'),
    'url': astNode('Url'),

    // old IE stuff
    'progid': astNode('Raw'),
    'expression': expression
};
<commit_msg>add `x` unit to resolution<commit_after>'use strict';

var names = require('../utils/names.js');

// https://www.w3.org/TR/css-values-3/#lengths
var LENGTH = {
    // absolute length units
    'px': true,
    'mm': true,
    'cm': true,
    'in': true,
    'pt': true,
    'pc': true,
    'q': true,

    // relative length units
    'em': true,
    'ex': true,
    'ch': true,
    'rem': true,

    // viewport-percentage lengths
    'vh': true,
    'vw': true,
    'vmin': true,
    'vmax': true,
    'vm': true
};

var ANGLE = {
    'deg': true,
    'grad': true,
    'rad': true,
    'turn': true
};

var TIME = {
    's': true,
    'ms': true
};

var FREQUENCY = {
    'hz': true,
    'khz': true
};

// https://www.w3.org/TR/css-values-3/#resolution (https://drafts.csswg.org/css-values/#resolution)
var RESOLUTION = {
    'dpi': true,
    'dpcm': true,
    'dppx': true,
    'x': true      // https://github.com/w3c/csswg-drafts/issues/461
};

// https://drafts.csswg.org/css-grid/#fr-unit
var FLEX = {
    'fr': true
};

// https://www.w3.org/TR/css3-speech/#mixing-props-voice-volume
var DECIBEL = {
    'db': true
};

// https://www.w3.org/TR/css3-speech/#voice-props-voice-pitch
var SEMITONES = {
    'st': true
};

// can be used wherever <length>, <frequency>, <angle>, <time>, <percentage>, <number>, or <integer> values are allowed
// https://drafts.csswg.org/css-values/#calc-notation
function isCalc(node) {
    if (node.data.type !== 'Function') {
        return false;
    }

    var keyword = names.keyword(node.data.name);

    if (keyword.name !== 'calc') {
        return false;
    }

    // there were some prefixed implementations
    return keyword.vendor === '' ||
           keyword.vendor === '-moz-' ||
           keyword.vendor === '-webkit-';
}

function astNode(type) {
    return function(node) {
        return node.data.type === type;
    };
}

function dimension(type) {
    return function(node) {
        return isCalc(node) ||
               (node.data.type === 'Dimension' && type.hasOwnProperty(node.data.unit.toLowerCase()));
    };
}

function zeroUnitlessDimension(type) {
    return function(node) {
        return isCalc(node) ||
               (node.data.type === 'Dimension' && type.hasOwnProperty(node.data.unit.toLowerCase())) ||
               (node.data.type === 'Number' && Number(node.data.value) === 0);
    };
}

function attr(node) {
    return node.data.type === 'Function' && node.data.name.toLowerCase() === 'attr';
}

function number(node) {
    return isCalc(node) || node.data.type === 'Number';
}

function numberZeroOne(node) {
    if (isCalc(node) || node.data.type === 'Number') {
        var value = Number(node.data.value);

        return value >= 0 && value <= 1;
    }

    return false;
}

function numberOneOrGreater(node) {
    if (isCalc(node) || node.data.type === 'Number') {
        return Number(node.data.value) >= 1;
    }

    return false;
}

// TODO: fail on 10e-2
function integer(node) {
    return isCalc(node) ||
           (node.data.type === 'Number' && node.data.value.indexOf('.') === -1);
}

// TODO: fail on 10e-2
function positiveInteger(node) {
    return isCalc(node) ||
           (node.data.type === 'Number' && node.data.value.indexOf('.') === -1 && node.data.value.charAt(0) !== '-');
}

function percentage(node) {
    return isCalc(node) ||
           node.data.type === 'Percentage';
}

function hexColor(node) {
    if (node.data.type !== 'HexColor') {
        return false;
    }

    var hex = node.data.value;

    return /^[0-9a-fA-F]{3,8}$/.test(hex) &&
           (hex.length === 3 || hex.length === 4 || hex.length === 6 || hex.length === 8);
}

function expression(node) {
    return node.data.type === 'Function' && node.data.name.toLowerCase() === 'expression';
}

// https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident
function customIdent(node) {
    if (node.data.type !== 'Identifier') {
        return false;
    }

    var name = node.data.name.toLowerCase();

    // can't be a global CSS value
    if (name === 'unset' || name === 'initial' || name === 'inherit') {
        return false;
    }

    // TODO: ignore property specific keywords (as described https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident)

    return true;
}

module.exports = {
    'angle': zeroUnitlessDimension(ANGLE),
    'attr()': attr,
    'custom-ident': customIdent,
    'decibel': dimension(DECIBEL),
    'dimension': astNode('Dimension'),
    'frequency': dimension(FREQUENCY),
    'flex': dimension(FLEX),
    'hex-color': hexColor,
    'id-selector': astNode('IdSelector'), // element( <id-selector> )
    'ident': astNode('Identifier'),
    'integer': integer,
    'length': zeroUnitlessDimension(LENGTH),
    'number': number,
    'number-zero-one': numberZeroOne,
    'number-one-or-greater': numberOneOrGreater,
    'percentage': percentage,
    'positive-integer': positiveInteger,
    'resolution': dimension(RESOLUTION),
    'semitones': dimension(SEMITONES),
    'string': astNode('String'),
    'time': dimension(TIME),
    'unicode-range': astNode('UnicodeRange'),
    'url': astNode('Url'),

    // old IE stuff
    'progid': astNode('Raw'),
    'expression': expression
};
<|endoftext|>


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

'use strict'

/**
 * The `Validator` can be used as an add-on to `Parser` class, to enable
 * validation of segments, elements and components. This class implements a
 * tolerant validator, only segments and elemens for which definitions are
 * provided will be validated. Other segments or elements will pass through
 * untouched. Validation includes:
 * * Checking data element counts, including mandatory elements.
 * * Checking component counts, including mandatory components.
 * * Checking components against they're required format.
 */
var Validator = function () {
  this._segments = {};
  this._elements = {};
  this._formats = {};
  this._counts = {
    segment: 0,
    element: 0,
    component: 0
  };
  this._state = Validator.states.all;
}

/**
 * @summary Disable validation.
 */
Validator.prototype.disable = function () {
  this._state = Validator.states.none;
}

/**
 * @summary Enable validation on the next segment.
 */
Validator.prototype.enable = function () {
  this._state = Validator.states.enable;
}

/**
 * To define a segment or element the definitions object should contain the
 * name as a key, and an object describing it's structure as a value. This
 * object contains the `requires` key to define the number of mandatory
 * elements or components. The key `elements` should be included containing a
 * list of element names to describe a segment. Similarly, an element
 * definition contains a `components` array describing the format of the
 * components.
 *
 * To simplify things, a non-composite element is regarded as an element
 * having only one component.
 *
 * @summary Define segment and element structures.
 * @param {Object} definitions An object containing the definitions.
 */
Validator.prototype.define = function (definitions) {
  for (var key in definitions) {
    if (definitions[key].elements && key.length === 3) {
      this._segments[key] = definitions[key];
    }
    if (definitions[key].components && key.length === 4) {
      this._elements[key] = definitions[key];
    }
  }
}

/**
 * @summary Request a component definition associated with a format string.
 * @returns {Object} A component definition.
 */
Validator.prototype.format = function (formatString) {
  // Check if we have a component definition in cache for this format string.
  if (this._formats[formatString]) {
    return this._formats[formatString];
  } else {
    var parts;
    if ((parts = /^(a|an|n)(\.\.)?([1-9][0-9]*)?$/.exec(formatString))) {
      var max = parseInt(parts[3]);
      var min = parts[2] === '..' ? 0 : max;
      var alpha, numeric;
      switch (parts[1]) {
      case 'a':
        alpha = true;
        break;
      case 'n':
        numeric = true;
        break;
      case 'an':
        alpha = true;
        numeric = true;
        break;
      }
      return this._formats[formatString] = { alpha: alpha, numeric: numeric, minimum: min, maximum: max };
    } else {
      throw Validator.errors.invalidFormatString(formatString);
    }
  }
}

/**
 * @summary Open a new segment.
 * @param {String} segment The segment name.
 */
Validator.prototype.onopensegment = function (segment) {
  switch (this._state) {
  case Validator.states.all:
  case Validator.states.elements:
  case Validator.states.segments:
  case Validator.states.enable:
    // Try to retrieve a segment definition if validation is not turned off.
    if ((this._segment = this._segments[segment])) {
      this._state = Validator.states.enter;
    } else {
      this._state = Validator.states.segments;
    }
  }
  this._counts.segment += 1;
  this._counts.element = 0;
}

/**
 * @summary Start validation for a new element.
 */
Validator.prototype.onelement = function () {
  switch (this._state) {
  case Validator.states.all:
    // Check component count of the previous enter.
    if (this._counts.component < this._element.requires) {
      throw Validator.errors.tooFewComponents(this._segment.elements[this._counts.element], this._element.requires, this._counts.component);
    }
    // Fall through to continue with element count validation.
  case Validator.states.enter:
    // Skip component count checks for the first element.
  case Validator.states.elements:
    if ((this._element = this._elements[this._segment.elements[this._counts.element]])) {
      this._state = Validator.states.all;
    } else {
      this._state = Validator.states.elements;
    }
  }
  this._counts.element += 1;
  this._counts.component = 0;
}

/**
 * @summary Start validation for a new component.
 * @param {Object} buffer - An object which implements the buffer interface.
 *
 * The buffer object should allow the mode to be set to alpha, numeric or
 * alphanumeric with their corresponding methods.
 */
Validator.prototype.onopencomponent = function (buffer) {
  switch (this._state) {
  case Validator.states.all:
    // Retrieve a component definition if validation is set to all.
    this._component = this.format(this._element.components[this._counts.component]);
    this._minimum = this._component.minimum;
    this._maximum = this._component.maximum;
    // Set the corresponding buffer mode.
    if (this._component.alpha) {
      if (this._component.numeric) {
        buffer.alphanumeric();
      } else {
        buffer.alpha();
      }
    } else {
      if (this._component.numeric) {
        buffer.numeric();
      } else {
        buffer.alphanumeric();
      }
    }
    break;
  default:
    // Set the buffer to it's default mode.
    buffer.alphanumeric();
  }
  this._counts.component += 1;
}

Validator.prototype.onclosecomponent = function (buffer) {
  var length;

  switch (this._state) {
  case Validator.states.all:
    // Component validation is only needed when validation is set to all.
    length = buffer.length();
    if (length < this._minimum || length > this._maximum) {
      throw Validator.errors.invalidData(buffer.content());
    }
  }
}

/**
 * @summary Finish validation for the current segment.
 */
Validator.prototype.onclosesegment = function (segment) {
  switch (this._state) {
  case Validator.states.all:
    if (this._counts.component < this._element.requires) {
      throw Validator.errors.tooFewComponents(this._segment.elements[this._counts.element], this._element.requires, this._counts.component);
    }
    // Fall through to continue with element count validation.
  case Validator.states.elements:
    if (this._counts.element < this._segment.requires) {
      throw Validator.errors.tooFewElements(segment, this._segment.requires, this._counts.element);
    }
  }
}

Validator.states = {
  none: 0,
  enable: 1,
  segments: 2,
  elements: 3,
  enter: 4,
  all: 5
};

Validator.errors = {
  invalidData: function (data) {
    var message = '';
    message += 'Could not accept ' + data;
    return new Error(message);
  },
  invalidFormatString: function (formatString) {
    return new Error('Invalid format string ' + formatString);
  },
  tooFewComponents: function (element, requires, count) {
    var message = '';
    message += 'Element ' + element;
    message += ' only got ' + count + ' components';
    message += ' but requires at least ' + requires;
    return new Error(message);
  },
  tooFewElements: function (segment, requires, count) {
    var message = '';
    message += 'Segment ' + segment;
    message += ' only got ' + count + ' elements';
    message += ' but requires at least ' + requires;
    return new Error(message);
  }
};

module.exports = Validator;
<commit_msg>Simplify Validator states.<commit_after>/**
 * @author Tom De Caluwé
 * @copyright 2016 Tom De Caluwé
 * @license Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict'

/**
 * The `Validator` can be used as an add-on to `Parser` class, to enable
 * validation of segments, elements and components. This class implements a
 * tolerant validator, only segments and elemens for which definitions are
 * provided will be validated. Other segments or elements will pass through
 * untouched. Validation includes:
 * * Checking data element counts, including mandatory elements.
 * * Checking component counts, including mandatory components.
 * * Checking components against they're required format.
 */
var Validator = function () {
  this._segments = {};
  this._elements = {};
  this._formats = {};
  this._counts = {
    segment: 0,
    element: 0,
    component: 0
  };
  this._state = Validator.states.all;
}

/**
 * @summary Disable validation.
 */
Validator.prototype.disable = function () {
  this._state = Validator.states.none;
}

/**
 * @summary Enable validation on the next segment.
 */
Validator.prototype.enable = function () {
  this._state = Validator.states.segments;
}

/**
 * To define a segment or element the definitions object should contain the
 * name as a key, and an object describing it's structure as a value. This
 * object contains the `requires` key to define the number of mandatory
 * elements or components. The key `elements` should be included containing a
 * list of element names to describe a segment. Similarly, an element
 * definition contains a `components` array describing the format of the
 * components.
 *
 * To simplify things, a non-composite element is regarded as an element
 * having only one component.
 *
 * @summary Define segment and element structures.
 * @param {Object} definitions An object containing the definitions.
 */
Validator.prototype.define = function (definitions) {
  for (var key in definitions) {
    if (definitions[key].elements) {
      this._segments[key] = definitions[key];
    }
    if (definitions[key].components) {
      this._elements[key] = definitions[key];
    }
  }
}

/**
 * @summary Request a component definition associated with a format string.
 * @returns {Object} A component definition.
 */
Validator.prototype.format = function (formatString) {
  // Check if we have a component definition in cache for this format string.
  if (this._formats[formatString]) {
    return this._formats[formatString];
  } else {
    var parts;
    if ((parts = /^(a|an|n)(\.\.)?([1-9][0-9]*)?$/.exec(formatString))) {
      var max = parseInt(parts[3]);
      var min = parts[2] === '..' ? 0 : max;
      var alpha, numeric;
      switch (parts[1]) {
      case 'a':
        alpha = true;
        break;
      case 'n':
        numeric = true;
        break;
      case 'an':
        alpha = true;
        numeric = true;
        break;
      }
      return this._formats[formatString] = { alpha: alpha, numeric: numeric, minimum: min, maximum: max };
    } else {
      throw Validator.errors.invalidFormatString(formatString);
    }
  }
}

/**
 * @summary Open a new segment.
 * @param {String} segment The segment name.
 */
Validator.prototype.onopensegment = function (segment) {
  switch (this._state) {
  case Validator.states.all:
  case Validator.states.elements:
  case Validator.states.segments:
  case Validator.states.enable:
    // Try to retrieve a segment definition if validation is not turned off.
    if ((this._segment = this._segments[segment])) {
      // The onelement function will close the previous element, however we
      // don't want the component counts to be checked. To disable them we put
      // the validator in the elements state.
      this._state = Validator.states.elements;
    } else {
      this._state = Validator.states.segments;
    }
  }
  this._counts.segment += 1;
  this._counts.element = 0;
}

/**
 * @summary Start validation for a new element.
 */
Validator.prototype.onelement = function () {
  switch (this._state) {
  case Validator.states.all:
    // Check component count of the previous enter.
    if (this._counts.component < this._element.requires) {
      throw Validator.errors.tooFewComponents(this._segment.elements[this._counts.element], this._element.requires, this._counts.component);
    }
    // Fall through to continue with element count validation.
  case Validator.states.enter:
    // Skip component count checks for the first element.
  case Validator.states.elements:
    if ((this._element = this._elements[this._segment.elements[this._counts.element]])) {
      this._state = Validator.states.all;
    } else {
      this._state = Validator.states.elements;
    }
  }
  this._counts.element += 1;
  this._counts.component = 0;
}

/**
 * @summary Start validation for a new component.
 * @param {Object} buffer - An object which implements the buffer interface.
 *
 * The buffer object should allow the mode to be set to alpha, numeric or
 * alphanumeric with their corresponding methods.
 */
Validator.prototype.onopencomponent = function (buffer) {
  switch (this._state) {
  case Validator.states.all:
    // Retrieve a component definition if validation is set to all.
    this._component = this.format(this._element.components[this._counts.component]);
    this._minimum = this._component.minimum;
    this._maximum = this._component.maximum;
    // Set the corresponding buffer mode.
    if (this._component.alpha) {
      if (this._component.numeric) {
        buffer.alphanumeric();
      } else {
        buffer.alpha();
      }
    } else {
      if (this._component.numeric) {
        buffer.numeric();
      } else {
        buffer.alphanumeric();
      }
    }
    break;
  default:
    // Set the buffer to it's default mode.
    buffer.alphanumeric();
  }
  this._counts.component += 1;
}

Validator.prototype.onclosecomponent = function (buffer) {
  var length;

  switch (this._state) {
  case Validator.states.all:
    // Component validation is only needed when validation is set to all.
    length = buffer.length();
    if (length < this._minimum || length > this._maximum) {
      throw Validator.errors.invalidData(buffer.content());
    }
  }
}

/**
 * @summary Finish validation for the current segment.
 */
Validator.prototype.onclosesegment = function (segment) {
  switch (this._state) {
  case Validator.states.all:
    if (this._counts.component < this._element.requires) {
      throw Validator.errors.tooFewComponents(this._segment.elements[this._counts.element], this._element.requires, this._counts.component);
    }
    // Fall through to continue with element count validation.
  case Validator.states.elements:
    if (this._counts.element < this._segment.requires) {
      throw Validator.errors.tooFewElements(segment, this._segment.requires, this._counts.element);
    }
  }
}

Validator.states = {
  // Setting validation to none will disable the validator completely. The
  // validator will not even try to obtain a segment description for segments
  // encountered. Almost all overhead is eliminated in this state.
  none: 0,
  // The segments state implies no segment definition was found for the current
  // segment, so validation should be disabled for its elements and components.
  // Normal validation should be resumed, however, as of the next segment.
  segments: 1,
  // The elements state is equivalent to the segments state, but validation is
  // only temporary disabled for the current element. Normal validation resumes
  // as of the next element.
  elements: 2,
  enter: 4,
  // Validation is enabled for all entities, including segments, elements and
  // components.
  all: 3
};

Validator.errors = {
  invalidData: function (data) {
    var message = '';
    message += 'Could not accept ' + data;
    return new Error(message);
  },
  invalidFormatString: function (formatString) {
    return new Error('Invalid format string ' + formatString);
  },
  tooFewComponents: function (element, requires, count) {
    var message = '';
    message += 'Element ' + element;
    message += ' only got ' + count + ' components';
    message += ' but requires at least ' + requires;
    return new Error(message);
  },
  tooFewElements: function (segment, requires, count) {
    var message = '';
    message += 'Segment ' + segment;
    message += ' only got ' + count + ' elements';
    message += ' but requires at least ' + requires;
    return new Error(message);
  }
};

module.exports = Validator;
<|endoftext|>


<commit_before>var fs = require('fs')
    , util = require('util')
    , stream = require('stream')
    , es = require('event-stream');

// var parse = require('./parse.js')
var usfmValidate = require('./usfmValidate.js')

var input = './Tests/3JN.usfm';

var output = [];
var lines = [];
var count = 0;

var s = fs.createReadStream(input)
    .pipe(es.split())
    .pipe(es.mapSync(function(line){
        count ++;

        //object element for each line
        var data = {} ;
        var dataArr = line.split("\\");
        dataArr = dataArr.splice(1, dataArr.length);

        // loop through each lines
        // for(var i=0; i<dataArr.length; i++){
        if(dataArr.length != 0){

            //marker and values from each line
            data.marker = dataArr[0].split(" ")[0] ;

            // check if values null after each marker
            // this works for lines which only contains a single marker with no text following eg: \p
            if(dataArr[0].split(/^[^ ]+ /)[1] !== undefined){
                data.value = dataArr[0].split(/^[^ ]+ /)[1]
            }
            else{
                data.value = "null";
            }
            if (data.marker == 'v'){
                data.number = dataArr[0].split(" ")[1];
                data.value = dataArr[0].split(/\d+ /)[1];
            }

            // handle inline markers as children of the corresponding line
            data.children = [];

            if(dataArr.length > 1){
                childArr = dataArr.slice(1);

                //inline markers structure starts from here
                for (var j = 0; j < childArr.length; j++) {
                    let split = childArr[j].split(" ");
                    // object for inline markers
                    // ternary operator handles if only markers are exist with out any values
                    data.children.push({
                        marker: split[0],
                        value: ((split[1] == "" ||split[1] == undefined) ? null : split.slice(1).join(" "))
                    });
                }
            }
            else{
                data.children = "null";
            }
            // count holds the line numbers in each line
            data.count = count;
            lines.push(data);
        }
        else{
            console.log("newline")
        }
    })
    .on('error', function(){
        console.log('Error while reading file.');
    })
    .on('end', function(){
        console.log(lines)
        // usfmValidate.Validate(lines)
        // console.log('Read entire file.')
    })
);
module.exports = s;

<commit_msg>working fine for all initial single tags<commit_after>var fs = require('fs')
    , util = require('util')
    , stream = require('stream')
    , es = require('event-stream');

// var parse = require('./parse.js')
var usfmValidate = require('./usfmValidate.js')

var input = './Tests/3JN.usfm';

var output = [];
var lines = [];
var count = 0;

var s = fs.createReadStream(input)
    .pipe(es.split())
    .pipe(es.mapSync(function(line){
        count ++;

        //object element for each line
        var data = {} ;
        var dataArr = line.split("\\");
        dataArr = dataArr.splice(1, dataArr.length);

        // if the line is not empty
        if(dataArr.length != 0){

            //marker and values from each line
            data.marker = dataArr[0].split(" ")[0] ;

            // check if values null after each marker
            // this works for lines which only contains a single marker with no text following eg: \p
            if(dataArr[0].split(/^[^ ]+ /)[1] !== undefined){
                data.value = dataArr[0].split(/^[^ ]+ /)[1]
            }
            else{
                data.value = "null";
            }
            if (data.marker == 'v'){
                data.number = dataArr[0].split(" ")[1];
                data.value = dataArr[0].split(/\d+ /)[1];
            }

            // handle inline markers as children of the corresponding line
            // data.children = [];
            child = [];

            if(dataArr.length > 1){
                childArr = dataArr.slice(1);

                //inline markers structure starts from here
                for (var j = 0; j < childArr.length; j++) {
                    let split = childArr[j].split(" ");
                    // object for inline markers
                    // ternary operator handles if only markers exist with out any values
                    child.push({
                        marker: split[0],
                        value: ((split[1] == "" ||split[1] == undefined) ? "null" : split.slice(1).join(" "))
                    });
                }
            }
            else{
                data.children = "null";
            }
            // count holds the line numbers in each line
            data.count = count;
            lines.push(data);
        }
    })
    .on('error', function(){
        console.log('Error while reading file.');
    })
    .on('end', function(){
        console.log(lines)
        // usfmValidate.Validate(lines)
        // console.log('Read entire file.')
    })
);
module.exports = s;

<|endoftext|>


<commit_before>var debug = require('debug')('hci-ble');

var events = require('events');
var spawn = require('child_process').spawn;
var util = require('util');

var HciBle = function() {
  var hciBle = __dirname + '/../../build/Release/hci-ble';

  debug('hciBle = ' + hciBle);

  this._hciBle = spawn(hciBle);
  this._hciBle.on('close', this.onClose.bind(this));

  this._hciBle.stdout.on('data', this.onStdoutData.bind(this));
  this._hciBle.stderr.on('data', this.onStderrData.bind(this));

  this._hciBle.on('error', function() { });

  this._buffer = "";

  this._discoveries = {};
};

util.inherits(HciBle, events.EventEmitter);

HciBle.prototype.onClose = function(code) {
  debug('close = ' + code);
};

HciBle.prototype.onStdoutData = function(data) {
  this._buffer += data.toString();

  debug('buffer = ' + JSON.stringify(this._buffer));

  var newLineIndex;
  while ((newLineIndex = this._buffer.indexOf('\n')) !== -1) {
    var line = this._buffer.substring(0, newLineIndex);
    var found;

    this._buffer = this._buffer.substring(newLineIndex + 1);

    debug('line = ' + line);

    if ((found = line.match(/^adapterState (.*)$/))) {
      var adapterState = found[1];

      debug('adapterState = ' + adapterState);

      if (adapterState === 'unauthorized') {
        console.log('noble warning: adapter state unauthorized, please run as root or with sudo');
        console.log('               or see README for information on running without root/sudo:');
        console.log('               https://github.com/sandeepmistry/noble#running-on-linux');
      }

      if (adapterState === 'unsupported') {
        console.log('noble warning: adapter does not support Bluetooth Low Energy (BLE, Bluetooth Smart).');
        console.log('               Try to run with environment variable:');
        console.log('               [sudo] NOBLE_HCI_DEVICE_ID=x node ...');
      }

      this.emit('stateChange', adapterState);
    } else if ((found = line.match(/^event (.*)$/))) {
      var event = found[1];
      var splitEvent = event.split(',');

      var address = splitEvent[0];
      var addressType = splitEvent[1];
      var eir = new Buffer(splitEvent[2], 'hex');
      var rssi = parseInt(splitEvent[3], 10);

      debug('address = ' + address);
      debug('addressType = ' + addressType);
      debug('eir = ' + eir.toString('hex'));
      debug('rssi = ' + rssi);

      var previouslyDiscovered = !!this._discoveries[address];
      var advertisement =  previouslyDiscovered ? this._discoveries[address].advertisement : {
        localName: undefined,
        txPowerLevel: undefined,
        manufacturerData: undefined,
        serviceData: [],
        serviceUuids: []
      };

      var discoveryCount = previouslyDiscovered ? this._discoveries[address].count : 0;

      if (discoveryCount % 2 === 0) {
        // reset service data every second event
        advertisement.serviceData = [];
      }

      var i = 0;
      var j = 0;
      var serviceUuid = null;

      while ((i + 1) < eir.length) {
        var length = eir.readUInt8(i);

        if (length < 1) {
          debug('invalid EIR data, length = ' + length);
          break;
        }

        var type = eir.readUInt8(i + 1); // https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile

        if ((i + length + 1) > eir.length) {
          debug('invalid EIR data, out of range of buffer length');
          break;
        }

        var bytes = eir.slice(i + 2).slice(0, length - 1);

        switch(type) {
          case 0x02: // Incomplete List of 16-bit Service Class UUID
          case 0x03: // Complete List of 16-bit Service Class UUIDs
            for (j = 0; j < bytes.length; j += 2) {
              serviceUuid = bytes.readUInt16LE(j).toString(16);
              if (advertisement.serviceUuids.indexOf(serviceUuid) === -1) {
                advertisement.serviceUuids.push(serviceUuid);
              }
            }
            break;

          case 0x06: // Incomplete List of 128-bit Service Class UUIDs
          case 0x07: // Complete List of 128-bit Service Class UUIDs
            for (j = 0; j < bytes.length; j += 16) {
              serviceUuid = bytes.slice(j, j + 16).toString('hex').match(/.{1,2}/g).reverse().join('');
              if (advertisement.serviceUuids.indexOf(serviceUuid) === -1) {
                advertisement.serviceUuids.push(serviceUuid);
              }
            }
            break;

          case 0x08: // Shortened Local Name
          case 0x09: // Complete Local Name»
            advertisement.localName = bytes.toString('utf8');
            break;

          case 0x0a: // Tx Power Level
            advertisement.txPowerLevel = bytes.readInt8(0);
            break;

          case 0x16: // Service Data, there can be multiple occurences
            var serviceDataUuid = bytes.slice(0, 2).toString('hex').match(/.{1,2}/g).reverse().join('');
            var serviceData = bytes.slice(2, bytes.length);

            advertisement.serviceData.push({
              uuid: serviceDataUuid,
              data: serviceData
            });
            break;

          case 0xff: // Manufacturer Specific Data
            advertisement.manufacturerData = bytes;
            break;
        }

        i += (length + 1);
      }

      debug('advertisement = ' + JSON.stringify(advertisement, null, 0));

      this._discoveries[address] = {
        address: address,
        addressType: addressType,
        advertisement: advertisement,
        rssi: rssi,
        count: (discoveryCount + 1)
      };

      // only report after an even number of events, so more advertisement data can be collected
      if (this._discoveries[address].count % 2 === 0 || process.env.NOBLE_REPORT_ALL_HCI_EVENTS) {
        this.emit('discover', address, addressType, advertisement, rssi);
      }
    }
  }
};

HciBle.prototype.onStderrData = function(data) {
  console.error('stderr: ' + data);
};

HciBle.prototype.startScanning = function(allowDuplicates) {
  this._hciBle.kill(allowDuplicates ? 'SIGUSR2' : 'SIGUSR1');

  this.emit('scanStart');
};

HciBle.prototype.stopScanning = function() {
  this._hciBle.kill('SIGHUP');

  this.emit('scanStop');
};

module.exports = HciBle;
<commit_msg>On Linux, refresh serviceUuids for incoming advertisement<commit_after>var debug = require('debug')('hci-ble');

var events = require('events');
var spawn = require('child_process').spawn;
var util = require('util');

var HciBle = function() {
  var hciBle = __dirname + '/../../build/Release/hci-ble';

  debug('hciBle = ' + hciBle);

  this._hciBle = spawn(hciBle);
  this._hciBle.on('close', this.onClose.bind(this));

  this._hciBle.stdout.on('data', this.onStdoutData.bind(this));
  this._hciBle.stderr.on('data', this.onStderrData.bind(this));

  this._hciBle.on('error', function() { });

  this._buffer = "";

  this._discoveries = {};
};

util.inherits(HciBle, events.EventEmitter);

HciBle.prototype.onClose = function(code) {
  debug('close = ' + code);
};

HciBle.prototype.onStdoutData = function(data) {
  this._buffer += data.toString();

  debug('buffer = ' + JSON.stringify(this._buffer));

  var newLineIndex;
  while ((newLineIndex = this._buffer.indexOf('\n')) !== -1) {
    var line = this._buffer.substring(0, newLineIndex);
    var found;

    this._buffer = this._buffer.substring(newLineIndex + 1);

    debug('line = ' + line);

    if ((found = line.match(/^adapterState (.*)$/))) {
      var adapterState = found[1];

      debug('adapterState = ' + adapterState);

      if (adapterState === 'unauthorized') {
        console.log('noble warning: adapter state unauthorized, please run as root or with sudo');
        console.log('               or see README for information on running without root/sudo:');
        console.log('               https://github.com/sandeepmistry/noble#running-on-linux');
      }

      if (adapterState === 'unsupported') {
        console.log('noble warning: adapter does not support Bluetooth Low Energy (BLE, Bluetooth Smart).');
        console.log('               Try to run with environment variable:');
        console.log('               [sudo] NOBLE_HCI_DEVICE_ID=x node ...');
      }

      this.emit('stateChange', adapterState);
    } else if ((found = line.match(/^event (.*)$/))) {
      var event = found[1];
      var splitEvent = event.split(',');

      var address = splitEvent[0];
      var addressType = splitEvent[1];
      var eir = new Buffer(splitEvent[2], 'hex');
      var rssi = parseInt(splitEvent[3], 10);

      debug('address = ' + address);
      debug('addressType = ' + addressType);
      debug('eir = ' + eir.toString('hex'));
      debug('rssi = ' + rssi);

      var previouslyDiscovered = !!this._discoveries[address];
      var advertisement =  previouslyDiscovered ? this._discoveries[address].advertisement : {
        localName: undefined,
        txPowerLevel: undefined,
        manufacturerData: undefined,
        serviceData: [],
        serviceUuids: []
      };

      var discoveryCount = previouslyDiscovered ? this._discoveries[address].count : 0;

      if (discoveryCount % 2 === 0) {
        // reset service data every second event
        advertisement.serviceData = [];
        advertisement.serviceUuids = [];
      }

      var i = 0;
      var j = 0;
      var serviceUuid = null;

      while ((i + 1) < eir.length) {
        var length = eir.readUInt8(i);

        if (length < 1) {
          debug('invalid EIR data, length = ' + length);
          break;
        }

        var type = eir.readUInt8(i + 1); // https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile

        if ((i + length + 1) > eir.length) {
          debug('invalid EIR data, out of range of buffer length');
          break;
        }

        var bytes = eir.slice(i + 2).slice(0, length - 1);

        switch(type) {
          case 0x02: // Incomplete List of 16-bit Service Class UUID
          case 0x03: // Complete List of 16-bit Service Class UUIDs
            for (j = 0; j < bytes.length; j += 2) {
              serviceUuid = bytes.readUInt16LE(j).toString(16);
              if (advertisement.serviceUuids.indexOf(serviceUuid) === -1) {
                advertisement.serviceUuids.push(serviceUuid);
              }
            }
            break;

          case 0x06: // Incomplete List of 128-bit Service Class UUIDs
          case 0x07: // Complete List of 128-bit Service Class UUIDs
            for (j = 0; j < bytes.length; j += 16) {
              serviceUuid = bytes.slice(j, j + 16).toString('hex').match(/.{1,2}/g).reverse().join('');
              if (advertisement.serviceUuids.indexOf(serviceUuid) === -1) {
                advertisement.serviceUuids.push(serviceUuid);
              }
            }
            break;

          case 0x08: // Shortened Local Name
          case 0x09: // Complete Local Name»
            advertisement.localName = bytes.toString('utf8');
            break;

          case 0x0a: // Tx Power Level
            advertisement.txPowerLevel = bytes.readInt8(0);
            break;

          case 0x16: // Service Data, there can be multiple occurences
            var serviceDataUuid = bytes.slice(0, 2).toString('hex').match(/.{1,2}/g).reverse().join('');
            var serviceData = bytes.slice(2, bytes.length);

            advertisement.serviceData.push({
              uuid: serviceDataUuid,
              data: serviceData
            });
            break;

          case 0xff: // Manufacturer Specific Data
            advertisement.manufacturerData = bytes;
            break;
        }

        i += (length + 1);
      }

      debug('advertisement = ' + JSON.stringify(advertisement, null, 0));

      this._discoveries[address] = {
        address: address,
        addressType: addressType,
        advertisement: advertisement,
        rssi: rssi,
        count: (discoveryCount + 1)
      };

      // only report after an even number of events, so more advertisement data can be collected
      if (this._discoveries[address].count % 2 === 0 || process.env.NOBLE_REPORT_ALL_HCI_EVENTS) {
        this.emit('discover', address, addressType, advertisement, rssi);
      }
    }
  }
};

HciBle.prototype.onStderrData = function(data) {
  console.error('stderr: ' + data);
};

HciBle.prototype.startScanning = function(allowDuplicates) {
  this._hciBle.kill(allowDuplicates ? 'SIGUSR2' : 'SIGUSR1');

  this.emit('scanStart');
};

HciBle.prototype.stopScanning = function() {
  this._hciBle.kill('SIGHUP');

  this.emit('scanStop');
};

module.exports = HciBle;
<|endoftext|>


<commit_before>var debug = require('debug')('hci-ble');

var events = require('events');
var spawn = require('child_process').spawn;
var util = require('util');

var HciBle = function() {
  var hciBle = __dirname + '/../../build/Release/hci-ble';

  debug('hciBle = ' + hciBle);

  this._hciBle = spawn('stdbuf', ['-o', '0', '-e', '0', '-i', '0', hciBle]);
  this._hciBle.on('close', this.onClose.bind(this));

  this._hciBle.stdout.on('data', this.onStdoutData.bind(this));
  this._hciBle.stderr.on('data', this.onStderrData.bind(this));

  this._hciBle.on('error', function() { });

  this._buffer = "";
};

util.inherits(HciBle, events.EventEmitter);

HciBle.prototype.onClose = function(code) {
  debug('close = ' + code);
};

HciBle.prototype.onStdoutData = function(data) {
  this._buffer += data.toString();

  debug('buffer = ' + JSON.stringify(this._buffer));

  var newLineIndex;
  while ((newLineIndex = this._buffer.indexOf('\n')) !== -1) {
    var line = this._buffer.substring(0, newLineIndex);
    var found;

    this._buffer = this._buffer.substring(newLineIndex + 1);

    debug('line = ' + line);

    if ((found = line.match(/^adapterState (.*)$/))) {
      var adapterState = found[1];

      debug('adapterState = ' + adapterState);

      if (adapterState === 'unauthorized') {
        console.log('bleno warning: adapter state unauthorized, please run as root or with sudo');
      }

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

HciBle.prototype.onStderrData = function(data) {
  console.error('stderr: ' + data);
};

HciBle.prototype.startAdvertising = function(name, serviceUuids) {
  debug('startAdvertising: name = ' + name);
  var eirDataLength = 3;
  var serviceUuids16bit = [];
  var serviceUuids128bit = [];

  if (name && name.length) {
    eirDataLength += 2 + name.length;
  }

  if (serviceUuids && serviceUuids.length) {
    for (var i = 0; i < serviceUuids.length; i++) {
      var serviceUuid = new Buffer(serviceUuids[i].match(/.{1,2}/g).reverse().join(''), 'hex');

      if (serviceUuid.length === 2) {
        serviceUuids16bit.push(serviceUuid);
      } else if (serviceUuid.length === 16) {
        serviceUuids128bit.push(serviceUuid);
      }
    }
  }

  if (serviceUuids16bit.length) {
    eirDataLength += 2 + 2 * serviceUuids16bit.length;
  }

  if (serviceUuids128bit.length) {
    eirDataLength += 2 + 16 * serviceUuids128bit.length;
  }

  var i = 0;
  var eirData = new Buffer(eirDataLength);

  // flags
  eirData[i++] = 2;
  eirData[i++] = 0x01;
  eirData[i++] = 0x02;

  // name
  if (name && name.length) {
    var nameBuffer = new Buffer(name);

    eirData[i++] = nameBuffer.length + 1;
    eirData[i++] = 0x08;
    for (var j = 0; j < nameBuffer.length; j++) {
      eirData[i++] = nameBuffer[j];
    }
  }

  if (serviceUuids16bit.length) {
    eirData[i++] = 1 + 2 * serviceUuids16bit.length;
    eirData[i++] = 0x02;
    for (var j = 0; j < serviceUuids16bit.length; j++) {
      for (var k = 0; k < serviceUuids16bit[j].length; k++) {
        eirData[i++] = serviceUuids16bit[j][k];
      }
    }
  }

  if (serviceUuids128bit.length) {
    eirData[i++] = 1 + 16 * serviceUuids128bit.length;
    eirData[i++] = 0x06;
    for (var j = 0; j < serviceUuids128bit.length; j++) {
      for (var k = 0; k < serviceUuids128bit[j].length; k++) {
        eirData[i++] = serviceUuids128bit[j][k];
      }
    }
  }

  debug('startAdvertising: eirData = ' + eirData.toString('hex'));

  this._hciBle.stdin.write(eirData.toString('hex') + '\n');

  this.emit('advertisingStart');
};

HciBle.prototype.restartAdvertising = function(name, serviceUuids) {
  this._hciBle.kill('SIGUSR1');
};

HciBle.prototype.stopAdvertising = function() {
  this._hciBle.kill('SIGHUP');

  this.emit('advertisingStop');
};

module.exports = HciBle;

<commit_msg>- add TODO for max EIR data length<commit_after>var debug = require('debug')('hci-ble');

var events = require('events');
var spawn = require('child_process').spawn;
var util = require('util');

var HciBle = function() {
  var hciBle = __dirname + '/../../build/Release/hci-ble';

  debug('hciBle = ' + hciBle);

  this._hciBle = spawn('stdbuf', ['-o', '0', '-e', '0', '-i', '0', hciBle]);
  this._hciBle.on('close', this.onClose.bind(this));

  this._hciBle.stdout.on('data', this.onStdoutData.bind(this));
  this._hciBle.stderr.on('data', this.onStderrData.bind(this));

  this._hciBle.on('error', function() { });

  this._buffer = "";
};

util.inherits(HciBle, events.EventEmitter);

HciBle.prototype.onClose = function(code) {
  debug('close = ' + code);
};

HciBle.prototype.onStdoutData = function(data) {
  this._buffer += data.toString();

  debug('buffer = ' + JSON.stringify(this._buffer));

  var newLineIndex;
  while ((newLineIndex = this._buffer.indexOf('\n')) !== -1) {
    var line = this._buffer.substring(0, newLineIndex);
    var found;

    this._buffer = this._buffer.substring(newLineIndex + 1);

    debug('line = ' + line);

    if ((found = line.match(/^adapterState (.*)$/))) {
      var adapterState = found[1];

      debug('adapterState = ' + adapterState);

      if (adapterState === 'unauthorized') {
        console.log('bleno warning: adapter state unauthorized, please run as root or with sudo');
      }

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

HciBle.prototype.onStderrData = function(data) {
  console.error('stderr: ' + data);
};

HciBle.prototype.startAdvertising = function(name, serviceUuids) {
  debug('startAdvertising: name = ' + name);
  var eirDataLength = 3;
  var serviceUuids16bit = [];
  var serviceUuids128bit = [];

  if (name && name.length) {
    eirDataLength += 2 + name.length;
  }

  if (serviceUuids && serviceUuids.length) {
    for (var i = 0; i < serviceUuids.length; i++) {
      var serviceUuid = new Buffer(serviceUuids[i].match(/.{1,2}/g).reverse().join(''), 'hex');

      if (serviceUuid.length === 2) {
        serviceUuids16bit.push(serviceUuid);
      } else if (serviceUuid.length === 16) {
        serviceUuids128bit.push(serviceUuid);
      }
    }
  }

  if (serviceUuids16bit.length) {
    eirDataLength += 2 + 2 * serviceUuids16bit.length;
  }

  if (serviceUuids128bit.length) {
    eirDataLength += 2 + 16 * serviceUuids128bit.length;
  }

  var i = 0;
  var eirData = new Buffer(eirDataLength);

  // flags
  eirData[i++] = 2;
  eirData[i++] = 0x01;
  eirData[i++] = 0x02;

  // name
  if (name && name.length) {
    var nameBuffer = new Buffer(name);

    eirData[i++] = nameBuffer.length + 1;
    eirData[i++] = 0x08;
    for (var j = 0; j < nameBuffer.length; j++) {
      eirData[i++] = nameBuffer[j];
    }
  }

  if (serviceUuids16bit.length) {
    eirData[i++] = 1 + 2 * serviceUuids16bit.length;
    eirData[i++] = 0x02;
    for (var j = 0; j < serviceUuids16bit.length; j++) {
      for (var k = 0; k < serviceUuids16bit[j].length; k++) {
        eirData[i++] = serviceUuids16bit[j][k];
      }
    }
  }

  if (serviceUuids128bit.length) {
    eirData[i++] = 1 + 16 * serviceUuids128bit.length;
    eirData[i++] = 0x06;
    for (var j = 0; j < serviceUuids128bit.length; j++) {
      for (var k = 0; k < serviceUuids128bit[j].length; k++) {
        eirData[i++] = serviceUuids128bit[j][k];
      }
    }
  }

  // TODO: maximum EIR data length (31 bytes)

  debug('startAdvertising: eirData = ' + eirData.toString('hex'));

  this._hciBle.stdin.write(eirData.toString('hex') + '\n');

  this.emit('advertisingStart');
};

HciBle.prototype.restartAdvertising = function(name, serviceUuids) {
  this._hciBle.kill('SIGUSR1');
};

HciBle.prototype.stopAdvertising = function() {
  this._hciBle.kill('SIGHUP');

  this.emit('advertisingStop');
};

module.exports = HciBle;

<|endoftext|>


<commit_before>function ValueMap(){
    this.charIndex = 0;
    this.items = [];
}
ValueMap.prototype.append = function(originObject){
    this.appendString(originObject.value, originObject, 0)
}
ValueMap.prototype.appendString = function(str, originObject, indexInOriginValue){
    if (indexInOriginValue === undefined) {
        debugger;
    }

    var newCharIndex = this.charIndex + str.length;
    this.items.push({
        originObject: originObject,
        fromCharIndex: this.charIndex,
        toCharIndex: newCharIndex,
        __justForDebuggingStr: str,
        indexInOriginValue: indexInOriginValue
    })
    this.charIndex = newCharIndex
}
ValueMap.prototype.getItemAt = function(charIndex){
    var matchingItems = this.items.filter(function(o){
        return o.fromCharIndex <= charIndex && o.toCharIndex > charIndex
    })
    if (matchingItems.length === 0) {throw "no matches :/"}
    var matchingItem
    if (matchingItems.length > 1 && matchingItems[0].originObject.value === "") {
        // "" can't ever meaningfully be the source of a visible string
        matchingItem = matchingItems[1]
    }
    else {
        matchingItem = matchingItems[0]
    }

    var itemsBeforeMatch = this.items.slice(0, this.items.indexOf(matchingItem));
    var charCountBeforeMatch = 0;
    var charsBelongingToMatchedOrigin = 0;
    itemsBeforeMatch.forEach(function(item){
        var len = item.toCharIndex - item.fromCharIndex
        charCountBeforeMatch += len
        if (item.originObject === matchingItem.originObject) {
            // an origin can be split into multiple items, e.g.
....
 (item at start and end)
            charsBelongingToMatchedOrigin += len;
        }
    })

    var originObject = matchingItem.originObject
    var characterIndex = charIndex - charCountBeforeMatch + charsBelongingToMatchedOrigin +
        matchingItem.indexInOriginValue;

    return {
        originObject: matchingItem.originObject,
        characterIndex: characterIndex
    }
}
ValueMap.prototype.debugginGetValue = function(){
    var value = "";
    this.items.forEach(function(item){
        value += item.__justForDebuggingStr;
    })
    return value;
}
ValueMap.prototype.serialize = function(inputValues){
    console.log("serialize with", inputValues)
    var ret = this.items.map(function(item){
        return {
            originObjectIndex: inputValues.indexOf(item.originObject),
            fromCharIndex: item.fromCharIndex,
            toCharIndex: item.toCharIndex,
            __justForDebuggingStr: item.__justForDebuggingStr,
            indexInOriginValue: item.indexInOriginValue
        }
    })
    return ret
}
ValueMap.deserialize = function(serializedValueMap, inputValues){
    console.log("deserialize with ", inputValues)
    var valueMap = new ValueMap();
    serializedValueMap.forEach(function(item){
        valueMap.items.push({
            fromCharIndex: item.fromCharIndex,
            toCharIndex: item.toCharIndex,
            __justForDebuggingStr: item.__justForDebuggingStr,
            originObject: inputValues[item.originObjectIndex],
            indexInOriginValue: item.indexInOriginValue
        })
    })
    console.log("deserialized valueMap", valueMap)
    return valueMap
}

if (typeof module !== "undefined") {
    module.exports = ValueMap
}
<commit_msg>Remove log call.<commit_after>function ValueMap(){
    this.charIndex = 0;
    this.items = [];
}
ValueMap.prototype.append = function(originObject){
    this.appendString(originObject.value, originObject, 0)
}
ValueMap.prototype.appendString = function(str, originObject, indexInOriginValue){
    if (indexInOriginValue === undefined) {
        debugger;
    }

    var newCharIndex = this.charIndex + str.length;
    this.items.push({
        originObject: originObject,
        fromCharIndex: this.charIndex,
        toCharIndex: newCharIndex,
        __justForDebuggingStr: str,
        indexInOriginValue: indexInOriginValue
    })
    this.charIndex = newCharIndex
}
ValueMap.prototype.getItemAt = function(charIndex){
    var matchingItems = this.items.filter(function(o){
        return o.fromCharIndex <= charIndex && o.toCharIndex > charIndex
    })
    if (matchingItems.length === 0) {throw "no matches :/"}
    var matchingItem
    if (matchingItems.length > 1 && matchingItems[0].originObject.value === "") {
        // "" can't ever meaningfully be the source of a visible string
        matchingItem = matchingItems[1]
    }
    else {
        matchingItem = matchingItems[0]
    }

    var itemsBeforeMatch = this.items.slice(0, this.items.indexOf(matchingItem));
    var charCountBeforeMatch = 0;
    var charsBelongingToMatchedOrigin = 0;
    itemsBeforeMatch.forEach(function(item){
        var len = item.toCharIndex - item.fromCharIndex
        charCountBeforeMatch += len
        if (item.originObject === matchingItem.originObject) {
            // an origin can be split into multiple items, e.g.
....
 (item at start and end)
            charsBelongingToMatchedOrigin += len;
        }
    })

    var originObject = matchingItem.originObject
    var characterIndex = charIndex - charCountBeforeMatch + charsBelongingToMatchedOrigin +
        matchingItem.indexInOriginValue;

    return {
        originObject: matchingItem.originObject,
        characterIndex: characterIndex
    }
}
ValueMap.prototype.debugginGetValue = function(){
    var value = "";
    this.items.forEach(function(item){
        value += item.__justForDebuggingStr;
    })
    return value;
}
ValueMap.prototype.serialize = function(inputValues){
    // console.log("serialize with", inputValues)
    var ret = this.items.map(function(item){
        return {
            originObjectIndex: inputValues.indexOf(item.originObject),
            fromCharIndex: item.fromCharIndex,
            toCharIndex: item.toCharIndex,
            __justForDebuggingStr: item.__justForDebuggingStr,
            indexInOriginValue: item.indexInOriginValue
        }
    })
    return ret
}
ValueMap.deserialize = function(serializedValueMap, inputValues){
    console.log("deserialize with ", inputValues)
    var valueMap = new ValueMap();
    serializedValueMap.forEach(function(item){
        valueMap.items.push({
            fromCharIndex: item.fromCharIndex,
            toCharIndex: item.toCharIndex,
            __justForDebuggingStr: item.__justForDebuggingStr,
            originObject: inputValues[item.originObjectIndex],
            indexInOriginValue: item.indexInOriginValue
        })
    })
    console.log("deserialized valueMap", valueMap)
    return valueMap
}

if (typeof module !== "undefined") {
    module.exports = ValueMap
}
<|endoftext|>