<commit_before>steal.plugins('jquery/event','jquery/event/livehack').then(function($){
/**
 * @class jQuery.Hover
 * @plugin jquery/event/hover
 * @download  http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/event/hover/hover.js
 * Provides delegate-able hover events.
 *

 * 	A hover happens when the mouse stops moving
 * over an element for a period of time.  You can listen
 * and configure hover with the following events:
 *

 *

 *
[jQuery.event.special.hoverinit hoverinit] - called on mouseenter, use this event to customize
 *      [jQuery.Hover.prototype.delay] and [jQuery.Hover.prototype.distance]

 *
[jQuery.event.special.hoverenter hoverenter] - an element is being hovered

 *
[jQuery.event.special.hovermove hovermove] - the mouse moves on an element that has been hovered

 *
[jQuery.event.special.hoverleave hoverleave] - the mouse leaves the element that has been hovered

 *

 *
Quick Example

 * The following listens for hoverenter and adds a class to style
 * the element, and removes the class on hoverleave.
 * @codestart
 * $('#menu').delegate(".option","hoverenter",function(){
 *   $(this).addClass("hovering");
 * }).delegate(".option","hoverleave",function(){
 *   $(this).removeClass("hovering");
 * })
 * @codeend
 *
Configuring Distance and Delay

 *
An element is hovered when the mouse
 *   moves less than a certain distance in
 *   specific time over the element.
 *

 *

 *   You can configure that distance and time by
 *   adjusting the distance and
 *   delay values.
 *

 *
You can set delay and distance globally
 * by adjusting the static properties:

 *

 * @codestart
 * $.Hover.delay = 10
 * $.Hover.distance = 1
 * @codeend
 *
Or you can adjust delay and distance for
 * an individual element in hoverenter:

 * @codestart
 * $(".option").live("hoverinit", function(ev, hover){
 * //set the distance to 10px
 * hover.distance(10)
 * //set the delay to 200ms
 * hover.delay(10)
 * })
 * @codeend
 *
Demo

 * @demo jquery/event/hover/hover.html
 * @parent specialevents
 * @constructor Creates a new hover.  This is never
 * called directly.
 */
$.Hover = function(){
	this._delay =  $.Hover.delay;
	this._distance = $.Hover.distance;
	this._leave = $.Hover.leave
};
/**
 * @Static
 */
$.extend($.Hover,{
	/**
	 * @attribute delay
	 * A hover is  activated if it moves less than distance in this time.
	 * Set this value as a global default.
	 */
	delay: 100,
	/**
	 * @attribute distance
	 * A hover is activated if it moves less than this distance in delay time.
	 * Set this value as a global default.
	 */
	distance: 10,
	leave : 0
})

/**
 * @Prototype
 */
$.extend($.Hover.prototype,{
	/**
	 * Sets the delay for this hover.  This method should
	 * only be used in hoverinit.
	 * @param {Number} delay the number of milliseconds used to determine a hover
	 *
	 */
	delay: function( delay ) {
		this._delay = delay;
		return this;
	},
	/**
	 * Sets the distance for this hover.  This method should
	 * only be used in hoverinit.
	 * @param {Number} distance the max distance in pixels a mouse can move to be considered a hover
	 */
	distance: function( distance ) {
		this._distance = distance;
		return this;
	},
	leave : function(leave){
		this._leave = leave;
		return this;
	}
})
var event = $.event,
	handle  = event.handle,
	onmouseenter = function(ev){
		//now start checking mousemoves to update location
		var delegate = ev.liveFired || ev.currentTarget;
		var selector = ev.handleObj.selector;
		var loc = {
				pageX : ev.pageX,
				pageY : ev.pageY
			},
			dist = 0,
			timer,
			enteredEl = this,
			hovered = false,
			lastEv = ev,
			hover = new $.Hover(),
			leaveTimer,
			callHoverLeave = function(){
				$.each(event.find(delegate, ["hoverleave"], selector), function(){
					this.call(enteredEl, ev, hover)
				})
				$(enteredEl).unbind("mouseleave",mouseleave)
				$(enteredEl).unbind("mousemove",mouseenter)
			},
			mouseenter = function(ev){
				clearTimeout(leaveTimer);
				dist += Math.pow( ev.pageX-loc.pageX, 2 ) + Math.pow( ev.pageY-loc.pageY, 2 );
				loc = {
					pageX : ev.pageX,
					pageY : ev.pageY
				}
				lastEv = ev
			},
			mouseleave = function(ev){
				clearTimeout(timer);
				// go right away
				if(hovered){
					if(hover._leave === 0){
						callHoverLeave();
					}else{
						clearTimeout(leaveTimer);
						leaveTimer = setTimeout(function(){
							callHoverLeave();
						}, hover._leave)
					}

				}
			};

		$(enteredEl).bind("mousemove",mouseenter).bind("mouseleave", mouseleave);
		$.each(event.find(delegate, ["hoverinit"], selector), function(){
			this.call(enteredEl, ev, hover)
		})

		timer = setTimeout(function(){
			//check that we aren't moveing around
			if(dist < hover._distance && $(enteredEl).queue().length == 0){
				$.each(event.find(delegate, ["hoverenter"], selector), function(){
					this.call(enteredEl, lastEv, hover)
				})
				hovered = true;
			}else{
				dist = 0;
				timer = setTimeout(arguments.callee, hover._delay)
			}
		}, hover._delay)

	};

/**
 * @add jQuery.event.special
 */
event.setupHelper( [
/**
 * @attribute hoverinit
 * Listen for hoverinit events to configure
 * [jQuery.Hover.prototype.delay] and [jQuery.Hover.prototype.distance]
 * for the current element.  Hoverinit is called on mouseenter.
 * @codestart
 * $(".option").live("hoverinit", function(ev, hover){
 *    //set the distance to 10px
 *    hover.distance(10)
 *    //set the delay to 200ms
 *    hover.delay(10)
 * })
 * @codeend
 */
"hoverinit",
/**
 * @attribute hoverenter
 * Hoverenter events are called when the mouses less
 * than [jQuery.Hover.prototype.distance] pixels in
 * [jQuery.Hover.prototype.delay] milliseconds.
 * @codestart
 * $(".option").live("hoverenter", function(ev, hover){
 *    $(this).addClass("hovering");
 * })
 * @codeend
 */
"hoverenter",
/**
 * @attribute hoverleave
 * Called when the mouse leaves an element that has been
 * hovered.
 * @codestart
 * $(".option").live("hoverleave", function(ev, hover){
 *    $(this).removeClass("hovering");
 * })
 * @codeend
 */
"hoverleave",
/**
 * @attribute hovermove
 * Called when the mouse moves on an element that
 * has been hovered.
 * @codestart
 * $(".option").live("hovermove", function(ev, hover){
 *    //not sure why you would want to listen for this
 *    //but we provide it just in case
 * })
 * @codeend
 */
"hovermove"], "mouseenter", onmouseenter )

})<commit_msg>hover only runs one mouseenter / mouseleave per selector at a time<commit_after>steal.plugins('jquery/event','jquery/event/livehack').then(function($){
/**
 * @class jQuery.Hover
 * @plugin jquery/event/hover
 * @download  http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/event/hover/hover.js
 * Provides delegate-able hover events.
 *

 * 	A hover happens when the mouse stops moving
 * over an element for a period of time.  You can listen
 * and configure hover with the following events:
 *

 *

 *
[jQuery.event.special.hoverinit hoverinit] - called on mouseenter, use this event to customize
 *      [jQuery.Hover.prototype.delay] and [jQuery.Hover.prototype.distance]

 *
[jQuery.event.special.hoverenter hoverenter] - an element is being hovered

 *
[jQuery.event.special.hovermove hovermove] - the mouse moves on an element that has been hovered

 *
[jQuery.event.special.hoverleave hoverleave] - the mouse leaves the element that has been hovered

 *

 *
Quick Example

 * The following listens for hoverenter and adds a class to style
 * the element, and removes the class on hoverleave.
 * @codestart
 * $('#menu').delegate(".option","hoverenter",function(){
 *   $(this).addClass("hovering");
 * }).delegate(".option","hoverleave",function(){
 *   $(this).removeClass("hovering");
 * })
 * @codeend
 *
Configuring Distance and Delay

 *
An element is hovered when the mouse
 *   moves less than a certain distance in
 *   specific time over the element.
 *

 *

 *   You can configure that distance and time by
 *   adjusting the distance and
 *   delay values.
 *

 *
You can set delay and distance globally
 * by adjusting the static properties:

 *

 * @codestart
 * $.Hover.delay = 10
 * $.Hover.distance = 1
 * @codeend
 *
Or you can adjust delay and distance for
 * an individual element in hoverenter:

 * @codestart
 * $(".option").live("hoverinit", function(ev, hover){
 * //set the distance to 10px
 * hover.distance(10)
 * //set the delay to 200ms
 * hover.delay(10)
 * })
 * @codeend
 *
Demo

 * @demo jquery/event/hover/hover.html
 * @parent specialevents
 * @constructor Creates a new hover.  This is never
 * called directly.
 */
$.Hover = function(){
	this._delay =  $.Hover.delay;
	this._distance = $.Hover.distance;
	this._leave = $.Hover.leave
};
/**
 * @Static
 */
$.extend($.Hover,{
	/**
	 * @attribute delay
	 * A hover is  activated if it moves less than distance in this time.
	 * Set this value as a global default.
	 */
	delay: 100,
	/**
	 * @attribute distance
	 * A hover is activated if it moves less than this distance in delay time.
	 * Set this value as a global default.
	 */
	distance: 10,
	leave : 0
})

/**
 * @Prototype
 */
$.extend($.Hover.prototype,{
	/**
	 * Sets the delay for this hover.  This method should
	 * only be used in hoverinit.
	 * @param {Number} delay the number of milliseconds used to determine a hover
	 *
	 */
	delay: function( delay ) {
		this._delay = delay;
		return this;
	},
	/**
	 * Sets the distance for this hover.  This method should
	 * only be used in hoverinit.
	 * @param {Number} distance the max distance in pixels a mouse can move to be considered a hover
	 */
	distance: function( distance ) {
		this._distance = distance;
		return this;
	},
	leave : function(leave){
		this._leave = leave;
		return this;
	}
})
var event = $.event,
	handle  = event.handle,
	onmouseenter = function(ev){
		//now start checking mousemoves to update location
		var delegate = ev.liveFired || ev.currentTarget;
		var selector = ev.handleObj.selector;
		//prevents another mouseenter until current has run its course
		if($.data(delegate,"_hover"+selector)){
			return;
		}
		$.data(delegate,"_hover"+selector, true)
		var loc = {
				pageX : ev.pageX,
				pageY : ev.pageY
			},
			dist = 0,
			timer,
			enteredEl = this,
			hovered = false,
			lastEv = ev,
			hover = new $.Hover(),
			leaveTimer,
			callHoverLeave = function(){
				$.each(event.find(delegate, ["hoverleave"], selector), function(){
					this.call(enteredEl, ev, hover)
				})
				cleanUp();
			},
			mouseenter = function(ev){
				clearTimeout(leaveTimer);
				dist += Math.pow( ev.pageX-loc.pageX, 2 ) + Math.pow( ev.pageY-loc.pageY, 2 );
				loc = {
					pageX : ev.pageX,
					pageY : ev.pageY
				}
				lastEv = ev
			},
			mouseleave = function(ev){
				clearTimeout(timer);
				// go right away
				if(hovered){
					if(hover._leave === 0){
						callHoverLeave();
					}else{
						clearTimeout(leaveTimer);
						leaveTimer = setTimeout(function(){
							callHoverLeave();
						}, hover._leave)
					}
				}else{
					cleanUp();
				}
			},
			cleanUp = function(){
				$(enteredEl).unbind("mouseleave",mouseleave)
				$(enteredEl).unbind("mousemove",mouseenter);
				$.removeData(delegate,"_hover"+selector)
			};

		$(enteredEl).bind("mousemove",mouseenter).bind("mouseleave", mouseleave);
		$.each(event.find(delegate, ["hoverinit"], selector), function(){
			this.call(enteredEl, ev, hover)
		})

		timer = setTimeout(function(){
			//check that we aren't moveing around
			if(dist < hover._distance && $(enteredEl).queue().length == 0){
				$.each(event.find(delegate, ["hoverenter"], selector), function(){
					this.call(enteredEl, lastEv, hover)
				})
				hovered = true;
				return;
			}else{
				dist = 0;
				timer = setTimeout(arguments.callee, hover._delay)
			}
		}, hover._delay)

	};

/**
 * @add jQuery.event.special
 */
event.setupHelper( [
/**
 * @attribute hoverinit
 * Listen for hoverinit events to configure
 * [jQuery.Hover.prototype.delay] and [jQuery.Hover.prototype.distance]
 * for the current element.  Hoverinit is called on mouseenter.
 * @codestart
 * $(".option").live("hoverinit", function(ev, hover){
 *    //set the distance to 10px
 *    hover.distance(10)
 *    //set the delay to 200ms
 *    hover.delay(10)
 * })
 * @codeend
 */
"hoverinit",
/**
 * @attribute hoverenter
 * Hoverenter events are called when the mouses less
 * than [jQuery.Hover.prototype.distance] pixels in
 * [jQuery.Hover.prototype.delay] milliseconds.
 * @codestart
 * $(".option").live("hoverenter", function(ev, hover){
 *    $(this).addClass("hovering");
 * })
 * @codeend
 */
"hoverenter",
/**
 * @attribute hoverleave
 * Called when the mouse leaves an element that has been
 * hovered.
 * @codestart
 * $(".option").live("hoverleave", function(ev, hover){
 *    $(this).removeClass("hovering");
 * })
 * @codeend
 */
"hoverleave",
/**
 * @attribute hovermove
 * Called when the mouse moves on an element that
 * has been hovered.
 * @codestart
 * $(".option").live("hovermove", function(ev, hover){
 *    //not sure why you would want to listen for this
 *    //but we provide it just in case
 * })
 * @codeend
 */
"hovermove"], "mouseenter", onmouseenter )

})<|endoftext|>


<commit_before>function getVoucher(href){return href.substr(href.lastIndexOf("/")+1);};
function signInAndSubscribe(voucher, confirmationQuestion, placeholder, message){
	new WindowsAzure.MobileServiceClient("https://tertulias.azurewebsites.net","309180942544-p7pg44n9uamccukt8caic0jerl2jpmta.apps.googleusercontent.com")
	.login("google")
	.done(function(results){
			var userSid=results.userId;
			var voucher=getVoucher(window.location.href);
			areYouSure(confirmationQuestion, userSid, voucher, placeholder, message);
		},
		function(err){alert("Error: "+err);});
};
function areYouSure(confirmationQuestion, userSid, voucher, placeholder, message){
	if (!confirm(confirmationQuestion)) return;
	document.getElementById(placeholder).innerHTML=message+" "+userSid+".";
	console.log('subscribing');
	subscribe(userSid, voucher);
};
function subscribe(userSid,voucher){
	var msc = new WindowsAzure.MobileServiceClient("https://tertulias.azurewebsites.net","309180942544-p7pg44n9uamccukt8caic0jerl2jpmta.apps.googleusercontent.com");
	msc.invokeApi("/", {
        body: null,
        method: "get"
    }).done(function (results) {
    	alert(results.result);
    }, function (error) {
        var dialog = new Windows.UI.Popups.MessageDialog(error.message);
        dialog.commands.append(okCommand);
        dialog.showAsync().done();
    });
};
<commit_msg>wip save<commit_after>function getVoucher(href){return href.substr(href.lastIndexOf("/")+1);};
function signInAndSubscribe(voucher, confirmationQuestion, placeholder, message){
	new WindowsAzure.MobileServiceClient("https://tertulias.azurewebsites.net","309180942544-p7pg44n9uamccukt8caic0jerl2jpmta.apps.googleusercontent.com")
	.login("google")
	.done(function(results){
			var userSid=results.userId;
			var voucher=getVoucher(window.location.href);
			areYouSure(confirmationQuestion, userSid, voucher, placeholder, message);
		},
		function(err){alert("Error: "+err);});
};
function areYouSure(confirmationQuestion, userSid, voucher, placeholder, message){
	if (!confirm(confirmationQuestion)) return;
	document.getElementById(placeholder).innerHTML=message+" "+userSid+".";
	console.log('subscribing');
	subscribe(userSid, voucher);
};
function subscribe(userSid,voucher){
	var msc = new WindowsAzure.MobileServiceClient("https://tertulias.azurewebsites.net","309180942544-p7pg44n9uamccukt8caic0jerl2jpmta.apps.googleusercontent.com");
	msc.invokeApi("/", {
        body: null,
        method: "get"
    }).done(function (results) {
    	alert(results.result.toString());
    }, function (error) {
        var dialog = new Windows.UI.Popups.MessageDialog(error.message);
        dialog.commands.append(okCommand);
        dialog.showAsync().done();
    });
};
<|endoftext|>


<commit_before>var express = require("express");
  var bodyParser = require("body-parser");
  var cookieParser = require("cookie-parser");
  var methodOverride = require("method-override");
  var session = require("express-session");
  var cors = require("cors");
var app = express();

var http = require("http");
var path = require("path");
var jwt = require("jsonwebtoken");
var mongoose = require("mongoose/");

var configDB = require("./config/db.js").getDev(process.env.DBUSERNAME, process.env.DBPASSWORD);
//var configDB = require("./config/db.js").getLocal(null, null);
mongoose.connect(configDB);

var ipaddress = process.env.OPENSHIFT_NODEJS_IP || "127.0.0.1";
var port = process.env.OPENSHIFT_NODEJS_PORT || 3000;

var corsOptions = {
  origin: true,
  methods: ["GET", "POST"]
};

app.set("port", port);
app.set("ip", ipaddress);
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "html");
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(methodOverride());
app.use(cookieParser());
app.use(session({secret: process.env.DBEXPRESSSECRET, resave: false, saveUninitialized: false}));
app.use(express.static(path.join(__dirname, "public")));
app.use(cors(corsOptions));

var scriptVersion = "0.26b";

require("./routes.min.js")(app, jwt, scriptVersion);

http.createServer(app).listen(app.get("port"), app.get("ip"), function() { "use strict";
  console.log("Express server listening at " + app.get("ip") + ":" + app.get("port"));
});
<commit_msg>use live config if openshift env variables are set<commit_after>var express = require("express");
  var bodyParser = require("body-parser");
  var cookieParser = require("cookie-parser");
  var methodOverride = require("method-override");
  var session = require("express-session");
  var cors = require("cors");
var app = express();

var http = require("http");
var path = require("path");
var jwt = require("jsonwebtoken");
var mongoose = require("mongoose/");

var configDB;

if(process.env.OPENSHIFT_NODEJS_PORT || process.env.OPENSHIFT_NODEJS_IP) {
	configDB = require("./config/db.js").getLive(process.env.DBUSERNAME, process.env.DBPASSWORD);
} else {
	configDB = require("./config/db.js").getDev(process.env.DBUSERNAME, process.env.DBPASSWORD);
	//var configDB = require("./config/db.js").getLocal(null, null);
}

mongoose.connect(configDB);

var ipaddress = process.env.OPENSHIFT_NODEJS_IP || "127.0.0.1";
var port = process.env.OPENSHIFT_NODEJS_PORT || 3000;

var corsOptions = {
  origin: true,
  methods: ["GET", "POST"]
};

app.set("port", port);
app.set("ip", ipaddress);
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "html");
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(methodOverride());
app.use(cookieParser());
app.use(session({secret: process.env.DBEXPRESSSECRET, resave: false, saveUninitialized: false}));
app.use(express.static(path.join(__dirname, "public")));
app.use(cors(corsOptions));

var scriptVersion = "0.26b";

require("./routes.min.js")(app, jwt, scriptVersion);

http.createServer(app).listen(app.get("port"), app.get("ip"), function() { "use strict";
  console.log("Express server listening at " + app.get("ip") + ":" + app.get("port"));
});
<|endoftext|>


<commit_before>'use strict';

const BbPromise = require('bluebird');
const _ = require('lodash');
const path = require('path');
const childProcess = require('child_process');
const fse = require('fs-extra');
const isBuiltinModule = require('is-builtin-module');

function getProdModules(externalModules, packagePath, dependencyGraph) {
  const packageJsonPath = path.join(process.cwd(), packagePath);
  const packageJson = require(packageJsonPath);
  const prodModules = [];

  // only process the module stated in dependencies section
  if (!packageJson.dependencies) {
    return [];
  }

  // Get versions of all transient modules
  _.forEach(externalModules, module => {
    let moduleVersion = packageJson.dependencies[module.external];

    if (moduleVersion) {
      prodModules.push(`${module.external}@${moduleVersion}`);

      // Check if the module has any peer dependencies and include them too
      try {
        const modulePackagePath = path.join(
          path.dirname(path.join(process.cwd(), packagePath)),
          'node_modules',
          module.external,
          'package.json'
        );
        const peerDependencies = require(modulePackagePath).peerDependencies;
        if (!_.isEmpty(peerDependencies)) {
          this.options.verbose && this.serverless.cli.log(`Adding explicit peers for dependency ${module.external}`);
          const peerModules = getProdModules.call(this, _.map(peerDependencies, (value, key) => ({ external: key })), packagePath, dependencyGraph);
          Array.prototype.push.apply(prodModules, peerModules);
        }
      } catch (e) {
        this.serverless.cli.log(`WARNING: Could not check for peer dependencies of ${module.external}`);
      }
    } else if (!_.has(packageJson, `devDependencies.${module.external}`)) {
      // Add transient dependencies if they appear not in the service's dev dependencies
      const originInfo = _.get(dependencyGraph, `dependencies.${module.origin}`, {});
      moduleVersion = _.get(originInfo, `dependencies.${module.external}.version`);
      if (!moduleVersion) {
        this.serverless.cli.log(`WARNING: Could not determine version of module ${module.external}`);
      }
      prodModules.push(moduleVersion ? `${module.external}@${moduleVersion}` : module.external);
    }
  });

  return prodModules;
}

function getExternalModuleName(module) {
  const path = /^external "(.*)"$/.exec(module.identifier())[1];
  const pathComponents = path.split('/');
  const main = pathComponents[0];

  // this is a package within a namespace
  if (main.charAt(0) == '@') {
    return `${main}/${pathComponents[1]}`;
  }

  return main;
}

function isExternalModule(module) {
  return _.startsWith(module.identifier(), 'external ') && !isBuiltinModule(getExternalModuleName(module));
}

/**
 * Find the original module that required the transient dependency. Returns
 * undefined if the module is a first level dependency.
 * @param {Object} issuer - Module issuer
 */
function findExternalOrigin(issuer) {
  if (!_.isNil(issuer) && _.startsWith(issuer.rawRequest, './')) {
    return findExternalOrigin(issuer.issuer);
  }
  return issuer;
}

function getExternalModules(stats) {
  const externals = new Set();

  _.forEach(stats.compilation.chunks, chunk => {
    // Explore each module within the chunk (built inputs):
    _.forEach(chunk.modules, module => {
      if (isExternalModule(module)) {
        externals.add({
          origin: _.get(findExternalOrigin(module.issuer), 'rawRequest'),
          external: getExternalModuleName(module)
        });
      }
    });
  });

  return Array.from(externals);
}

module.exports = {
  /**
   * We need a performant algorithm to install the packages for each single
   * function (in case we package individually).
   * (1) We fetch ALL packages needed by ALL functions in a first step
   * and use this as a base npm checkout. The checkout will be done to a
   * separate temporary directory with a package.json that contains everything.
   * (2) For each single compile we copy the whole node_modules to the compile
   * directory and create a (function) compile specific package.json and store
   * it in the compile directory. Now we start npm again there, and npm will just
   * remove the superfluous packages and optimize the remaining dependencies.
   * This will utilize the npm cache at its best and give us the needed results
   * and performance.
   */
  packExternalModules(stats) {

    const includes = (
      this.serverless.service.custom &&
      this.serverless.service.custom.webpackIncludeModules
    );

    if (!includes) {
      return BbPromise.resolve(stats);
    }

    const packageForceIncludes = _.get(includes, 'forceInclude', []);
    const packagePath = includes.packagePath || './package.json';
    const packageJsonPath = path.join(process.cwd(), packagePath);

    this.options.verbose && this.serverless.cli.log(`Fetch dependency graph from ${packageJsonPath}`);
    // Get first level dependency graph
    const command = 'npm ls -prod -json -depth=1';  // Only prod dependencies

    const ignoredNpmErrors = [
      { npmError: 'extraneous', log: false },
      { npmError: 'missing', log: false },
      { npmError: 'peer dep missing', log: true },
    ];

    return BbPromise.fromCallback(cb => {
      childProcess.exec(command, {
        cwd: path.dirname(packageJsonPath),
        maxBuffer: this.serverless.service.custom.packExternalModulesMaxBuffer || 200 * 1024,
        encoding: 'utf8'
      }, (err, stdout, stderr) => {
        if (err) {
          // Only exit with an error if we have critical npm errors for 2nd level inside
          const errors = _.split(stderr, '\n');
          const failed = _.reduce(errors, (failed, error) => {
            if (failed) {
              return true;
            }
            return !_.isEmpty(error) && !_.some(ignoredNpmErrors, ignoredError => _.startsWith(error, `npm ERR! ${ignoredError.npmError}`));
          }, false);

          if (failed) {
            return cb(err);
          }
        }
        return cb(null, stdout);
      });
    })
    .then(depJson => BbPromise.try(() => JSON.parse(depJson)))
    .then(dependencyGraph => {
      const problems = _.get(dependencyGraph, 'problems', []);
      if (this.options.verbose && !_.isEmpty(problems)) {
        this.serverless.cli.log(`Ignoring ${_.size(problems)} NPM errors:`);
        _.forEach(problems, problem => {
          this.serverless.cli.log(`=> ${problem}`);
        });
      }

      // (1) Generate dependency composition
      const compositeModules = _.uniq(_.flatMap(stats.stats, compileStats => {
        const externalModules = _.concat(
          getExternalModules.call(this, compileStats),
          _.map(packageForceIncludes, whitelistedPackage => ({ external: whitelistedPackage }))
        );
        return getProdModules.call(this, externalModules, packagePath, dependencyGraph);
      }));

      if (_.isEmpty(compositeModules)) {
        // The compiled code does not reference any external modules at all
        this.serverless.cli.log('No external modules needed');
        return BbPromise.resolve(stats);
      }

      // (1.a) Install all needed modules
      const compositeModulePath = path.join(this.webpackOutputPath, 'dependencies');
      const compositePackageJson = path.join(compositeModulePath, 'package.json');

      // (1.a.1) Create a package.json
      const compositePackage = {
        name: this.serverless.service.service,
        version: '1.0.0',
        description: `Packaged externals for ${this.serverless.service.service}`,
        private: true
      };
      _.forEach(compositeModules, compositeModule => {
        const splitModule = _.split(compositeModule, '@');
        // If we have a scoped module we have to re-add the @
        if (_.startsWith(compositeModule, '@')) {
          splitModule.splice(0, 1);
          splitModule[0] = '@' + splitModule[0];
        }
        const moduleVersion = _.join(_.tail(splitModule), '@');
        _.set(compositePackage, `dependencies.${_.first(splitModule)}`, moduleVersion);
      });
      this.serverless.utils.writeFileSync(compositePackageJson, JSON.stringify(compositePackage, null, 2));

      // (1.a.2) Copy package-lock.json if it exists, to prevent unwanted upgrades
      const packageLockPath = path.join(path.dirname(packageJsonPath), 'package-lock.json');
      return BbPromise.fromCallback(cb => fse.pathExists(packageLockPath, cb))
      .then(exists => {
        if (exists) {
          this.serverless.cli.log('Package lock found - Using locked versions');
          return BbPromise.fromCallback(cb => fse.copy(packageLockPath, path.join(compositeModulePath, 'package-lock.json'), cb))
          .catch(err => this.serverless.cli.log(`Warning: Could not copy lock file: ${err.message}`));
        }
        return BbPromise.resolve();
      })
      .then(() => {
        const start = _.now();
        this.serverless.cli.log('Packing external modules: ' + compositeModules.join(', '));
        return BbPromise.fromCallback(cb => {
          childProcess.exec('npm install', {
            cwd: compositeModulePath,
            maxBuffer: this.serverless.service.custom.packExternalModulesMaxBuffer || 200 * 1024,
            encoding: 'utf8'
          }, cb);
        })
        .then(() => this.options.verbose && this.serverless.cli.log(`Package took [${_.now() - start} ms]`))
        .return(stats.stats);
      })
      .mapSeries(compileStats => {
        const modulePath = compileStats.compilation.compiler.outputPath;

        // Create package.json
        const modulePackageJson = path.join(modulePath, 'package.json');
        const modulePackage = {
          dependencies: {}
        };
        const prodModules = getProdModules.call(this,
          _.concat(
            getExternalModules.call(this, compileStats),
            _.map(packageForceIncludes, whitelistedPackage => ({ external: whitelistedPackage }))
          ), packagePath, dependencyGraph);
        _.forEach(prodModules, prodModule => {
          const splitModule = _.split(prodModule, '@');
          // If we have a scoped module we have to re-add the @
          if (_.startsWith(prodModule, '@')) {
            splitModule.splice(0, 1);
            splitModule[0] = '@' + splitModule[0];
          }
          const moduleVersion = _.join(_.tail(splitModule), '@');
          modulePackage.dependencies[_.first(splitModule)] = moduleVersion;
        });
        this.serverless.utils.writeFileSync(modulePackageJson, JSON.stringify(modulePackage, null, 2));

        // Copy modules
        const startCopy = _.now();
        return BbPromise.fromCallback(callback => fse.copy(path.join(compositeModulePath, 'node_modules'), path.join(modulePath, 'node_modules'), callback))
        .tap(() => this.options.verbose && this.serverless.cli.log(`Copy modules: ${modulePath} [${_.now() - startCopy} ms]`))
        .then(() => {
          // Prune extraneous packages - removes not needed ones
          const startPrune = _.now();
          return BbPromise.fromCallback(callback => {
            childProcess.exec('npm prune', {
              cwd: modulePath
            }, callback);
          })
          .tap(() => this.options.verbose && this.serverless.cli.log(`Prune: ${modulePath} [${_.now() - startPrune} ms]`));
        });
      })
      .return(stats);
    });
  }
};
<commit_msg>Do not let lodash parse module names as path elements<commit_after>'use strict';

const BbPromise = require('bluebird');
const _ = require('lodash');
const path = require('path');
const childProcess = require('child_process');
const fse = require('fs-extra');
const isBuiltinModule = require('is-builtin-module');

function getProdModules(externalModules, packagePath, dependencyGraph) {
  const packageJsonPath = path.join(process.cwd(), packagePath);
  const packageJson = require(packageJsonPath);
  const prodModules = [];

  // only process the module stated in dependencies section
  if (!packageJson.dependencies) {
    return [];
  }

  // Get versions of all transient modules
  _.forEach(externalModules, module => {
    let moduleVersion = packageJson.dependencies[module.external];

    if (moduleVersion) {
      prodModules.push(`${module.external}@${moduleVersion}`);

      // Check if the module has any peer dependencies and include them too
      try {
        const modulePackagePath = path.join(
          path.dirname(path.join(process.cwd(), packagePath)),
          'node_modules',
          module.external,
          'package.json'
        );
        const peerDependencies = require(modulePackagePath).peerDependencies;
        if (!_.isEmpty(peerDependencies)) {
          this.options.verbose && this.serverless.cli.log(`Adding explicit peers for dependency ${module.external}`);
          const peerModules = getProdModules.call(this, _.map(peerDependencies, (value, key) => ({ external: key })), packagePath, dependencyGraph);
          Array.prototype.push.apply(prodModules, peerModules);
        }
      } catch (e) {
        this.serverless.cli.log(`WARNING: Could not check for peer dependencies of ${module.external}`);
      }
    } else if (!packageJson.devDependencies || !packageJson.devDependencies[module.external]) {
      // Add transient dependencies if they appear not in the service's dev dependencies
      const originInfo = _.get(dependencyGraph, 'dependencies', {})[module.origin] || {};
      moduleVersion = _.get(_.get(originInfo, 'dependencies', {})[module.external], 'version');
      if (!moduleVersion) {
        this.serverless.cli.log(`WARNING: Could not determine version of module ${module.external}`);
      }
      prodModules.push(moduleVersion ? `${module.external}@${moduleVersion}` : module.external);
    }
  });

  return prodModules;
}

function getExternalModuleName(module) {
  const path = /^external "(.*)"$/.exec(module.identifier())[1];
  const pathComponents = path.split('/');
  const main = pathComponents[0];

  // this is a package within a namespace
  if (main.charAt(0) == '@') {
    return `${main}/${pathComponents[1]}`;
  }

  return main;
}

function isExternalModule(module) {
  return _.startsWith(module.identifier(), 'external ') && !isBuiltinModule(getExternalModuleName(module));
}

/**
 * Find the original module that required the transient dependency. Returns
 * undefined if the module is a first level dependency.
 * @param {Object} issuer - Module issuer
 */
function findExternalOrigin(issuer) {
  if (!_.isNil(issuer) && _.startsWith(issuer.rawRequest, './')) {
    return findExternalOrigin(issuer.issuer);
  }
  return issuer;
}

function getExternalModules(stats) {
  const externals = new Set();

  _.forEach(stats.compilation.chunks, chunk => {
    // Explore each module within the chunk (built inputs):
    _.forEach(chunk.modules, module => {
      if (isExternalModule(module)) {
        externals.add({
          origin: _.get(findExternalOrigin(module.issuer), 'rawRequest'),
          external: getExternalModuleName(module)
        });
      }
    });
  });

  return Array.from(externals);
}

module.exports = {
  /**
   * We need a performant algorithm to install the packages for each single
   * function (in case we package individually).
   * (1) We fetch ALL packages needed by ALL functions in a first step
   * and use this as a base npm checkout. The checkout will be done to a
   * separate temporary directory with a package.json that contains everything.
   * (2) For each single compile we copy the whole node_modules to the compile
   * directory and create a (function) compile specific package.json and store
   * it in the compile directory. Now we start npm again there, and npm will just
   * remove the superfluous packages and optimize the remaining dependencies.
   * This will utilize the npm cache at its best and give us the needed results
   * and performance.
   */
  packExternalModules(stats) {

    const includes = (
      this.serverless.service.custom &&
      this.serverless.service.custom.webpackIncludeModules
    );

    if (!includes) {
      return BbPromise.resolve(stats);
    }

    const packageForceIncludes = _.get(includes, 'forceInclude', []);
    const packagePath = includes.packagePath || './package.json';
    const packageJsonPath = path.join(process.cwd(), packagePath);

    this.options.verbose && this.serverless.cli.log(`Fetch dependency graph from ${packageJsonPath}`);
    // Get first level dependency graph
    const command = 'npm ls -prod -json -depth=1';  // Only prod dependencies

    const ignoredNpmErrors = [
      { npmError: 'extraneous', log: false },
      { npmError: 'missing', log: false },
      { npmError: 'peer dep missing', log: true },
    ];

    return BbPromise.fromCallback(cb => {
      childProcess.exec(command, {
        cwd: path.dirname(packageJsonPath),
        maxBuffer: this.serverless.service.custom.packExternalModulesMaxBuffer || 200 * 1024,
        encoding: 'utf8'
      }, (err, stdout, stderr) => {
        if (err) {
          // Only exit with an error if we have critical npm errors for 2nd level inside
          const errors = _.split(stderr, '\n');
          const failed = _.reduce(errors, (failed, error) => {
            if (failed) {
              return true;
            }
            return !_.isEmpty(error) && !_.some(ignoredNpmErrors, ignoredError => _.startsWith(error, `npm ERR! ${ignoredError.npmError}`));
          }, false);

          if (failed) {
            return cb(err);
          }
        }
        return cb(null, stdout);
      });
    })
    .then(depJson => BbPromise.try(() => JSON.parse(depJson)))
    .then(dependencyGraph => {
      const problems = _.get(dependencyGraph, 'problems', []);
      if (this.options.verbose && !_.isEmpty(problems)) {
        this.serverless.cli.log(`Ignoring ${_.size(problems)} NPM errors:`);
        _.forEach(problems, problem => {
          this.serverless.cli.log(`=> ${problem}`);
        });
      }

      // (1) Generate dependency composition
      const compositeModules = _.uniq(_.flatMap(stats.stats, compileStats => {
        const externalModules = _.concat(
          getExternalModules.call(this, compileStats),
          _.map(packageForceIncludes, whitelistedPackage => ({ external: whitelistedPackage }))
        );
        return getProdModules.call(this, externalModules, packagePath, dependencyGraph);
      }));

      if (_.isEmpty(compositeModules)) {
        // The compiled code does not reference any external modules at all
        this.serverless.cli.log('No external modules needed');
        return BbPromise.resolve(stats);
      }

      // (1.a) Install all needed modules
      const compositeModulePath = path.join(this.webpackOutputPath, 'dependencies');
      const compositePackageJson = path.join(compositeModulePath, 'package.json');

      // (1.a.1) Create a package.json
      const compositePackage = {
        name: this.serverless.service.service,
        version: '1.0.0',
        description: `Packaged externals for ${this.serverless.service.service}`,
        private: true
      };
      _.forEach(compositeModules, compositeModule => {
        const splitModule = _.split(compositeModule, '@');
        // If we have a scoped module we have to re-add the @
        if (_.startsWith(compositeModule, '@')) {
          splitModule.splice(0, 1);
          splitModule[0] = '@' + splitModule[0];
        }
        const moduleVersion = _.join(_.tail(splitModule), '@');
        compositePackage.dependencies = compositePackage.dependencies || {};
        compositePackage.dependencies[_.first(splitModule)] = moduleVersion;
      });
      this.serverless.utils.writeFileSync(compositePackageJson, JSON.stringify(compositePackage, null, 2));

      // (1.a.2) Copy package-lock.json if it exists, to prevent unwanted upgrades
      const packageLockPath = path.join(path.dirname(packageJsonPath), 'package-lock.json');
      return BbPromise.fromCallback(cb => fse.pathExists(packageLockPath, cb))
      .then(exists => {
        if (exists) {
          this.serverless.cli.log('Package lock found - Using locked versions');
          return BbPromise.fromCallback(cb => fse.copy(packageLockPath, path.join(compositeModulePath, 'package-lock.json'), cb))
          .catch(err => this.serverless.cli.log(`Warning: Could not copy lock file: ${err.message}`));
        }
        return BbPromise.resolve();
      })
      .then(() => {
        const start = _.now();
        this.serverless.cli.log('Packing external modules: ' + compositeModules.join(', '));
        return BbPromise.fromCallback(cb => {
          childProcess.exec('npm install', {
            cwd: compositeModulePath,
            maxBuffer: this.serverless.service.custom.packExternalModulesMaxBuffer || 200 * 1024,
            encoding: 'utf8'
          }, cb);
        })
        .then(() => this.options.verbose && this.serverless.cli.log(`Package took [${_.now() - start} ms]`))
        .return(stats.stats);
      })
      .mapSeries(compileStats => {
        const modulePath = compileStats.compilation.compiler.outputPath;

        // Create package.json
        const modulePackageJson = path.join(modulePath, 'package.json');
        const modulePackage = {
          dependencies: {}
        };
        const prodModules = getProdModules.call(this,
          _.concat(
            getExternalModules.call(this, compileStats),
            _.map(packageForceIncludes, whitelistedPackage => ({ external: whitelistedPackage }))
          ), packagePath, dependencyGraph);
        _.forEach(prodModules, prodModule => {
          const splitModule = _.split(prodModule, '@');
          // If we have a scoped module we have to re-add the @
          if (_.startsWith(prodModule, '@')) {
            splitModule.splice(0, 1);
            splitModule[0] = '@' + splitModule[0];
          }
          const moduleVersion = _.join(_.tail(splitModule), '@');
          modulePackage.dependencies[_.first(splitModule)] = moduleVersion;
        });
        this.serverless.utils.writeFileSync(modulePackageJson, JSON.stringify(modulePackage, null, 2));

        // Copy modules
        const startCopy = _.now();
        return BbPromise.fromCallback(callback => fse.copy(path.join(compositeModulePath, 'node_modules'), path.join(modulePath, 'node_modules'), callback))
        .tap(() => this.options.verbose && this.serverless.cli.log(`Copy modules: ${modulePath} [${_.now() - startCopy} ms]`))
        .then(() => {
          // Prune extraneous packages - removes not needed ones
          const startPrune = _.now();
          return BbPromise.fromCallback(callback => {
            childProcess.exec('npm prune', {
              cwd: modulePath
            }, callback);
          })
          .tap(() => this.options.verbose && this.serverless.cli.log(`Prune: ${modulePath} [${_.now() - startPrune} ms]`));
        });
      })
      .return(stats);
    });
  }
};
<|endoftext|>


<commit_before>import React, { Component } from "react";
import gql from "graphql-tag.macro";
import { graphql, withApollo, Mutation } from "react-apollo";
import { Table, Button } from "reactstrap";
import { InputField, OutputField } from "../../generic/core";
import SubscriptionHelper from "helpers/subscriptionHelper";

const fragment = gql`
  fragment PowerData on Reactor {
    id
    type
    model
    efficiency
    displayName
    powerOutput
  }
`;
const REACTOR_SUB = gql`
  subscription ReactorsUpdate($simulatorId: ID!) {
    reactorUpdate(simulatorId: $simulatorId) {
      ...PowerData
    }
  }
  ${fragment}
`;

const SYSTEMS_SUB = gql`
  subscription SystemsUpdate($simulatorId: ID) {
    systemsUpdate(simulatorId: $simulatorId) {
      id
      name
      displayName
      power {
        power
        powerLevels
      }
      damage {
        damaged
        report
        destroyed
        which
      }
      simulatorId
      type
    }
  }
`;

const options = [
  { key: "destroy", title: "Destroy" },
  { key: "rnd", title: "R&D" },
  { key: "engineering", title: "Engineering" }
];
class DamageControlCore extends Component {
  constructor(props) {
    super(props);
    this.state = {
      deck: null,
      room: null
    };
  }
  systemStyle(sys) {
    const obj = {
      listStyle: "none",
      cursor: "pointer"
    };
    if (
      sys.power &&
      sys.power.powerLevels &&
      sys.power.powerLevels.length > 0 &&
      !sys.power.powerLevels.find(p => p <= sys.power.power)
    ) {
      obj.color = "#888";
    }
    // Overloaded the power levels
    if (
      sys.power &&
      sys.power.powerLevels &&
      sys.power.powerLevels.length > 0 &&
      sys.power.powerLevels[sys.power.powerLevels.length - 1] < sys.power.power
    ) {
      obj.color = "goldenrod";
    }
    if (sys.damage.damaged) {
      obj.color = "red";
    }
    if (!sys.name) {
      obj.color = "purple";
    }
    if (sys.damage.which === "rnd") {
      obj.color = "orange";
    }
    if (sys.damage.which === "engineering") {
      obj.color = "rgb(0,128,255)";
    }
    if (sys.damage.destroyed) {
      obj.color = "black";
      obj.textShadow = "0px 0px 1px rgba(255,255,255,1)";
    }
    return obj;
  }
  systemName(sys) {
    if (sys.type === "Shield") {
      return `${sys.name} Shields`;
    }
    return sys.displayName || sys.name;
  }
  setPower(system, power) {
    const mutation = gql`
      mutation SetPower($systemId: ID!, $power: Int!) {
        changePower(systemId: $systemId, power: $power)
      }
    `;
    const variables = {
      systemId: system.id,
      power
    };
    this.props.client.mutate({
      mutation,
      variables
    });
  }
  setPowerOutput = output => {
    if ((!output || !parseFloat(output)) && output !== "0") return;
    const reactor = this.props.data.reactors.find(r => r.model === "reactor");
    const mutation = gql`
      mutation ReactorPowerLevel($id: ID!, $output: Int!) {
        reactorChangeOutput(id: $id, output: $output)
      }
    `;
    const variables = {
      id: reactor.id,
      output: parseInt(output, 10)
    };
    this.props.client.mutate({
      mutation,
      variables
    });
  };
  toggleDamage = (e, system, destroyed = false, which) => {
    e.preventDefault();
    const variables = {
      systemId: system.id,
      destroyed,
      which
    };
    let mutation;
    if (system.damage.damaged) {
      // Fix it
      mutation = gql`
        mutation RepairSystem($systemId: ID!) {
          repairSystem(systemId: $systemId)
        }
      `;
    } else {
      // Break it
      mutation = gql`
        mutation DamageSystem(
          $systemId: ID!
          $destroyed: Boolean
          $which: String
        ) {
          damageSystem(
            systemId: $systemId
            destroyed: $destroyed
            which: $which
          )
        }
      `;
    }
    this.props.client.mutate({
      mutation,
      variables
    });
  };
  setContext = (e, s) => {
    e.preventDefault();
    this.setState({
      context: {
        system: s,
        x: e.clientX,
        y: e.clientY
      }
    });
    //this.toggleDamage(e, s, true)
  };
  damageOption = (e, option) => {
    const { system } = this.state.context;
    if (option === "destroy") {
      this.toggleDamage(e, system, true);
    } else {
      this.toggleDamage(e, system, false, option);
    }
    this.setState({ context: null });
  };
  render() {
    if (
      this.props.data.loading ||
      !this.props.data.systems ||
      !this.props.data.reactors
    )
      return null;
    const reactor = this.props.data.reactors.find(r => r.model === "reactor");
    return (
      <Mutation
        mutation={gql`
          mutation FluxPower($id: ID, $all: Boolean, $simulatorId: ID) {
            fluxSystemPower(id: $id, all: $all, simulatorId: $simulatorId)
          }
        `}
        variables={{ simulatorId: this.props.simulator.id }}
      >
        {action => (

 this.setState({ context: null })}>

              <SubscriptionHelper
                subscribe={() =>
                  this.props.data.subscribeToMore({
                    document: SYSTEMS_SUB,
                    variables: {
                      simulatorId: this.props.simulator.id
                    },
                    updateQuery: (previousResult, { subscriptionData }) => {
                      return Object.assign({}, previousResult, {
                        systems: subscriptionData.data.systemsUpdate
                      });
                    }
                  })
                }
              />
              <SubscriptionHelper
                subscribe={() =>
                  this.props.data.subscribeToMore({
                    document: REACTOR_SUB,
                    variables: {
                      simulatorId: this.props.simulator.id
                    },
                    updateQuery: (previousResult, { subscriptionData }) => {
                      return Object.assign({}, previousResult, {
                        reactors: subscriptionData.data.reactorUpdate
                      });
                    }
                  })
                }
              />

                  System
                  Set

                  Req
                  Flux

                {this.props.data.systems
                  .concat()
                  .sort((a, b) => {
                    if (
                      !(
                        (a.power.power || a.power.power === 0) &&
                        a.power.powerLevels.length
                      ) &&
                      ((b.power.power || b.power.power === 0) &&
                        b.power.powerLevels.length)
                    )
                      return 1;
                    if (
                      !(
                        (b.power.power || b.power.power === 0) &&
                        b.power.powerLevels.length
                      ) &&
                      ((a.power.power || a.power.power === 0) &&
                        a.power.powerLevels.length)
                    )
                      return -1;
                    if (a.type > b.type) return 1;
                    if (a.type  b.name) return 1;
                    if (a.name  (

                       this.toggleDamage(e, s)}
                        onContextMenu={e => this.setContext(e, s)}
                        style={this.systemStyle(s)}
                      >
                        {this.systemName(s)}

                        {(s.power.power || s.power.power === 0) && (
                          <InputField
                            prompt="What is the power?"
                            onClick={this.setPower.bind(this, s)}
                          >
                            {s.power.power}
                          </InputField>
                        )}

                      /

                        {(s.power.power || s.power.power === 0) && (
                          <OutputField>{s.power.powerLevels[0]}</OutputField>
                        )}

                        {s.power.powerLevels &&
                          s.power.powerLevels.length > 0 && (
                            <Button
                              size="sm"
                              color="warning"
                              title="Flux"
                              style={{ height: "15px" }}
                              onClick={() =>
                                action({ variables: { id: s.id } })
                              }
                            />
                          )}

                  ))}

                  Total

                    <OutputField
                      alert={
                        Math.round(reactor.powerOutput * reactor.efficiency) <
                        this.props.data.systems.reduce(
                          (prev, next) =>
                            next.power ? prev + next.power.power : prev,
                          0
                        )
                      }
                    >
                      {this.props.data.systems.reduce(
                        (prev, next) =>
                          next.power ? prev + next.power.power : prev,
                        0
                      )}
                    </OutputField>

                  {reactor && "/"}

                    {reactor && (
                      <OutputField title="Reactor Output">
                        {Math.round(reactor.powerOutput * reactor.efficiency)}
                      </OutputField>
                    )}

                    {reactor && (
                      <InputField
                        title="Reactor Power Level"
                        prompt="What is the new power output?"
                        onClick={this.setPowerOutput}
                      >
                        {reactor.powerOutput}
                      </InputField>
                    )}

                  Right-Click for options

                    <Button block size="sm" color="warning" onClick={action}>
                      Flux Random
                    </Button>

                    <Button
                      block
                      size="sm"
                      color="danger"
                      onClick={() =>
                        action({
                          variables: {
                            all: true,
                            simulatorId: this.props.simulator.id
                          }
                        })
                      }
                    >
                      Flux All
                    </Button>

            {this.state.context && (

                {options.map(o => (

 this.damageOption(e, o.key)}>
                    {o.title}

                ))}

            )}

        )}
      </Mutation>
    );
  }
}
const SYSTEMS_QUERY = gql`
  query Systems($simulatorId: ID) {
    reactors(simulatorId: $simulatorId) {
      ...PowerData
    }
    systems(simulatorId: $simulatorId) {
      id
      name
      displayName
      power {
        power
        powerLevels
      }
      damage {
        damaged
        report
        destroyed
        which
      }
      simulatorId
      type
    }
  }
  ${fragment}
`;

export default graphql(SYSTEMS_QUERY, {
  options: ownProps => ({
    fetchPolicy: "cache-and-network",
    variables: { simulatorId: ownProps.simulator.id }
  })
})(withApollo(DamageControlCore));
<commit_msg>fix(Systems): Fixes an issue where not having a proper reactor breaks the systems core. Closes #2194<commit_after>import React, { Component } from "react";
import gql from "graphql-tag.macro";
import { graphql, withApollo, Mutation } from "react-apollo";
import { Table, Button } from "reactstrap";
import { InputField, OutputField } from "../../generic/core";
import SubscriptionHelper from "helpers/subscriptionHelper";

const fragment = gql`
  fragment PowerData on Reactor {
    id
    type
    model
    efficiency
    displayName
    powerOutput
  }
`;
const REACTOR_SUB = gql`
  subscription ReactorsUpdate($simulatorId: ID!) {
    reactorUpdate(simulatorId: $simulatorId) {
      ...PowerData
    }
  }
  ${fragment}
`;

const SYSTEMS_SUB = gql`
  subscription SystemsUpdate($simulatorId: ID) {
    systemsUpdate(simulatorId: $simulatorId) {
      id
      name
      displayName
      power {
        power
        powerLevels
      }
      damage {
        damaged
        report
        destroyed
        which
      }
      simulatorId
      type
    }
  }
`;

const options = [
  { key: "destroy", title: "Destroy" },
  { key: "rnd", title: "R&D" },
  { key: "engineering", title: "Engineering" }
];
class DamageControlCore extends Component {
  constructor(props) {
    super(props);
    this.state = {
      deck: null,
      room: null
    };
  }
  systemStyle(sys) {
    const obj = {
      listStyle: "none",
      cursor: "pointer"
    };
    if (
      sys.power &&
      sys.power.powerLevels &&
      sys.power.powerLevels.length > 0 &&
      !sys.power.powerLevels.find(p => p <= sys.power.power)
    ) {
      obj.color = "#888";
    }
    // Overloaded the power levels
    if (
      sys.power &&
      sys.power.powerLevels &&
      sys.power.powerLevels.length > 0 &&
      sys.power.powerLevels[sys.power.powerLevels.length - 1] < sys.power.power
    ) {
      obj.color = "goldenrod";
    }
    if (sys.damage.damaged) {
      obj.color = "red";
    }
    if (!sys.name) {
      obj.color = "purple";
    }
    if (sys.damage.which === "rnd") {
      obj.color = "orange";
    }
    if (sys.damage.which === "engineering") {
      obj.color = "rgb(0,128,255)";
    }
    if (sys.damage.destroyed) {
      obj.color = "black";
      obj.textShadow = "0px 0px 1px rgba(255,255,255,1)";
    }
    return obj;
  }
  systemName(sys) {
    if (sys.type === "Shield") {
      return `${sys.name} Shields`;
    }
    return sys.displayName || sys.name;
  }
  setPower(system, power) {
    const mutation = gql`
      mutation SetPower($systemId: ID!, $power: Int!) {
        changePower(systemId: $systemId, power: $power)
      }
    `;
    const variables = {
      systemId: system.id,
      power
    };
    this.props.client.mutate({
      mutation,
      variables
    });
  }
  setPowerOutput = output => {
    if ((!output || !parseFloat(output)) && output !== "0") return;
    const reactor = this.props.data.reactors.find(r => r.model === "reactor");
    const mutation = gql`
      mutation ReactorPowerLevel($id: ID!, $output: Int!) {
        reactorChangeOutput(id: $id, output: $output)
      }
    `;
    const variables = {
      id: reactor.id,
      output: parseInt(output, 10)
    };
    this.props.client.mutate({
      mutation,
      variables
    });
  };
  toggleDamage = (e, system, destroyed = false, which) => {
    e.preventDefault();
    const variables = {
      systemId: system.id,
      destroyed,
      which
    };
    let mutation;
    if (system.damage.damaged) {
      // Fix it
      mutation = gql`
        mutation RepairSystem($systemId: ID!) {
          repairSystem(systemId: $systemId)
        }
      `;
    } else {
      // Break it
      mutation = gql`
        mutation DamageSystem(
          $systemId: ID!
          $destroyed: Boolean
          $which: String
        ) {
          damageSystem(
            systemId: $systemId
            destroyed: $destroyed
            which: $which
          )
        }
      `;
    }
    this.props.client.mutate({
      mutation,
      variables
    });
  };
  setContext = (e, s) => {
    e.preventDefault();
    this.setState({
      context: {
        system: s,
        x: e.clientX,
        y: e.clientY
      }
    });
    //this.toggleDamage(e, s, true)
  };
  damageOption = (e, option) => {
    const { system } = this.state.context;
    if (option === "destroy") {
      this.toggleDamage(e, system, true);
    } else {
      this.toggleDamage(e, system, false, option);
    }
    this.setState({ context: null });
  };
  render() {
    if (
      this.props.data.loading ||
      !this.props.data.systems ||
      !this.props.data.reactors
    )
      return null;
    const reactor = this.props.data.reactors.find(r => r.model === "reactor");
    return (
      <Mutation
        mutation={gql`
          mutation FluxPower($id: ID, $all: Boolean, $simulatorId: ID) {
            fluxSystemPower(id: $id, all: $all, simulatorId: $simulatorId)
          }
        `}
        variables={{ simulatorId: this.props.simulator.id }}
      >
        {action => (

 this.setState({ context: null })}>

              <SubscriptionHelper
                subscribe={() =>
                  this.props.data.subscribeToMore({
                    document: SYSTEMS_SUB,
                    variables: {
                      simulatorId: this.props.simulator.id
                    },
                    updateQuery: (previousResult, { subscriptionData }) => {
                      return Object.assign({}, previousResult, {
                        systems: subscriptionData.data.systemsUpdate
                      });
                    }
                  })
                }
              />
              <SubscriptionHelper
                subscribe={() =>
                  this.props.data.subscribeToMore({
                    document: REACTOR_SUB,
                    variables: {
                      simulatorId: this.props.simulator.id
                    },
                    updateQuery: (previousResult, { subscriptionData }) => {
                      return Object.assign({}, previousResult, {
                        reactors: subscriptionData.data.reactorUpdate
                      });
                    }
                  })
                }
              />

                  System
                  Set

                  Req
                  Flux

                {this.props.data.systems
                  .concat()
                  .sort((a, b) => {
                    if (
                      !(
                        (a.power.power || a.power.power === 0) &&
                        a.power.powerLevels.length
                      ) &&
                      ((b.power.power || b.power.power === 0) &&
                        b.power.powerLevels.length)
                    )
                      return 1;
                    if (
                      !(
                        (b.power.power || b.power.power === 0) &&
                        b.power.powerLevels.length
                      ) &&
                      ((a.power.power || a.power.power === 0) &&
                        a.power.powerLevels.length)
                    )
                      return -1;
                    if (a.type > b.type) return 1;
                    if (a.type  b.name) return 1;
                    if (a.name  (

                       this.toggleDamage(e, s)}
                        onContextMenu={e => this.setContext(e, s)}
                        style={this.systemStyle(s)}
                      >
                        {this.systemName(s)}

                        {(s.power.power || s.power.power === 0) && (
                          <InputField
                            prompt="What is the power?"
                            onClick={this.setPower.bind(this, s)}
                          >
                            {s.power.power}
                          </InputField>
                        )}

                      /

                        {(s.power.power || s.power.power === 0) && (
                          <OutputField>{s.power.powerLevels[0]}</OutputField>
                        )}

                        {s.power.powerLevels &&
                          s.power.powerLevels.length > 0 && (
                            <Button
                              size="sm"
                              color="warning"
                              title="Flux"
                              style={{ height: "15px" }}
                              onClick={() =>
                                action({ variables: { id: s.id } })
                              }
                            />
                          )}

                  ))}

                  Total

                    <OutputField
                      alert={
                        reactor &&
                        Math.round(reactor.powerOutput * reactor.efficiency) <
                          this.props.data.systems.reduce(
                            (prev, next) =>
                              next.power ? prev + next.power.power : prev,
                            0
                          )
                      }
                    >
                      {this.props.data.systems.reduce(
                        (prev, next) =>
                          next.power ? prev + next.power.power : prev,
                        0
                      )}
                    </OutputField>

                  {reactor && "/"}

                    {reactor && (
                      <OutputField title="Reactor Output">
                        {Math.round(reactor.powerOutput * reactor.efficiency)}
                      </OutputField>
                    )}

                    {reactor && (
                      <InputField
                        title="Reactor Power Level"
                        prompt="What is the new power output?"
                        onClick={this.setPowerOutput}
                      >
                        {reactor.powerOutput}
                      </InputField>
                    )}

                  Right-Click for options

                    <Button block size="sm" color="warning" onClick={action}>
                      Flux Random
                    </Button>

                    <Button
                      block
                      size="sm"
                      color="danger"
                      onClick={() =>
                        action({
                          variables: {
                            all: true,
                            simulatorId: this.props.simulator.id
                          }
                        })
                      }
                    >
                      Flux All
                    </Button>

            {this.state.context && (

                {options.map(o => (

 this.damageOption(e, o.key)}>
                    {o.title}

                ))}

            )}

        )}
      </Mutation>
    );
  }
}
const SYSTEMS_QUERY = gql`
  query Systems($simulatorId: ID) {
    reactors(simulatorId: $simulatorId) {
      ...PowerData
    }
    systems(simulatorId: $simulatorId) {
      id
      name
      displayName
      power {
        power
        powerLevels
      }
      damage {
        damaged
        report
        destroyed
        which
      }
      simulatorId
      type
    }
  }
  ${fragment}
`;

export default graphql(SYSTEMS_QUERY, {
  options: ownProps => ({
    fetchPolicy: "cache-and-network",
    variables: { simulatorId: ownProps.simulator.id }
  })
})(withApollo(DamageControlCore));
<|endoftext|>


<commit_before>'use strict';

angular.module('spinnaker.migrator.service', [
  'spinnaker.utils.lodash',
  'spinnaker.taskExecutor.service',
  ])
  .factory('migratorService', function($timeout, $q, _, taskExecutor) {

    function executeMigration(config) {
      var deferred = $q.defer();
      var task = { id: null, deferred: deferred, dryRun: config.dryRun };
      var taskStarter = taskExecutor.executeTask({
        application: config.application,
        description: 'Migrate ' + config.source.asgName + ' to VPC0',
        job: [{
          source: config.source,
          type: 'deepCopyServerGroup',
          target: config.target,
          dryRun: config.dryRun,
        }]
      });

      taskStarter.then(function(execution) {
        task.id = execution.id;
        task.execution = execution;
        monitorTask(task);
      });

      return task;
    }

    function monitorTask(task) {

      if (task.execution.isFailed) {
        var exception = task.execution.getValueFor('exception') || { message: 'No reason provided.'};
        task.deferred.reject(exception.message);
        return;
      }
      if (task.execution.isCompleted && task.execution.getValueFor('tide.task')) {
        if (task.dryRun) {
          task.executionPlan = buildPreview(task);
        }
        task.deferred.resolve();
      } else {
        if (!task.deferred.promise.cancelled) {
          task.lastResult = extractLastResult(task);
          $timeout(function() {
            task.execution.get().then(function(reloaded) {
              task.execution = reloaded;
              monitorTask(task);
            });
          }, 1000);
        }
      }

    }

    function getTideTask(task) {
      if (task.execution.getValueFor('tide.task')) {
        return task.execution.getValueFor('tide.task');
      }
      return {};
    }

    function extractLastResult(taskResult) {
      var tideTask = getTideTask(taskResult);
      taskResult.eventLog = _(tideTask.history).sortBy('timeStamp')
        .pluck('message')
        .valueOf();
      return taskResult;
    }

    function buildPreview(plan) {
      var tideTask = getTideTask(plan);
      tideTask.mutations = tideTask.mutations || [];
      return {
        securityGroups: tideTask.mutations.filter(function(mutation) { return mutationIs(mutation, 'groupName'); }),
        loadBalancers: tideTask.mutations.filter(function(mutation) { return mutationIs(mutation, 'loadBalancerName'); }),
        serverGroups: tideTask.mutations.filter(function(mutation) { return mutationIs(mutation, 'autoScalingGroupName'); }),
      };
    }

    function mutationIs(mutation, field) {
      return mutation.awsReference && mutation.awsReference.identity && mutation.awsReference.identity[field];
    }

    return {
      executeMigration: executeMigration,
    };

  })
;<commit_msg>surface default error message more gracefully<commit_after>'use strict';

angular.module('spinnaker.migrator.service', [
  'spinnaker.utils.lodash',
  'spinnaker.taskExecutor.service',
  ])
  .factory('migratorService', function($timeout, $q, _, taskExecutor) {

    function executeMigration(config) {
      var deferred = $q.defer();
      var task = { id: null, deferred: deferred, dryRun: config.dryRun };
      var taskStarter = taskExecutor.executeTask({
        application: config.application,
        description: 'Migrate ' + config.source.asgName + ' to VPC0',
        job: [{
          source: config.source,
          type: 'deepCopyServerGroup',
          target: config.target,
          dryRun: config.dryRun,
        }]
      });

      taskStarter.then(function(execution) {
        task.id = execution.id;
        task.execution = execution;
        monitorTask(task);
      });

      return task;
    }

    function monitorTask(task) {

      if (task.execution.isFailed) {
        var exception = task.execution.getValueFor('exception'),
            message = exception && exception.message ? exception.message : 'An internal server error occurred. Please try again later.';
        task.deferred.reject(exception.message);
        return;
      }
      if (task.execution.isCompleted && task.execution.getValueFor('tide.task')) {
        if (task.dryRun) {
          task.executionPlan = buildPreview(task);
        }
        task.deferred.resolve();
      } else {
        if (!task.deferred.promise.cancelled) {
          task.lastResult = extractLastResult(task);
          $timeout(function() {
            task.execution.get().then(function(reloaded) {
              task.execution = reloaded;
              monitorTask(task);
            });
          }, 1000);
        }
      }

    }

    function getTideTask(task) {
      if (task.execution.getValueFor('tide.task')) {
        return task.execution.getValueFor('tide.task');
      }
      return {};
    }

    function extractLastResult(taskResult) {
      var tideTask = getTideTask(taskResult);
      taskResult.eventLog = _(tideTask.history).sortBy('timeStamp')
        .pluck('message')
        .valueOf();
      return taskResult;
    }

    function buildPreview(plan) {
      var tideTask = getTideTask(plan);
      tideTask.mutations = tideTask.mutations || [];
      return {
        securityGroups: tideTask.mutations.filter(function(mutation) { return mutationIs(mutation, 'groupName'); }),
        loadBalancers: tideTask.mutations.filter(function(mutation) { return mutationIs(mutation, 'loadBalancerName'); }),
        serverGroups: tideTask.mutations.filter(function(mutation) { return mutationIs(mutation, 'autoScalingGroupName'); }),
      };
    }

    function mutationIs(mutation, field) {
      return mutation.awsReference && mutation.awsReference.identity && mutation.awsReference.identity[field];
    }

    return {
      executeMigration: executeMigration,
    };

  })
;<|endoftext|>


<commit_before>/* globals define */

define([
  'jquery',
  'underscore',
  'backbone',
  'marionette',
  'buses/event-bus',
  'models/settings-model'
], function ($, _, Backbone, Marionette, EventBus, Settings) {
  'use strict';

  var schema = {
    'url':   function (page) {
      return 'page/' + page;
    },
    'query': function (page) {
      return '&page=' + page;
    }
  };

  function routeIsPaged (route) {
    var isPaged = route.match(/(page\/\d+\/?$)|([?&]page=\d+)/);
    return isPaged !== null && isPaged.length > 0;
  }

  function buildUri(route, replace) {
    var pageRegex   = /(\(\/?page\/.*\))/g;
    var pageSection = route.match(pageRegex);

    pageSection = (_.isEmpty(pageSection)) ? '' : pageSection[0];

    if (!replace.paged || replace.paged < 2) {
      route = route.replace(pageSection, '');
      delete replace.paged;
    } else {
      var pageSectionContentRegex = new RegExp(pageSection, 'g');
      var pageSectionContent      = pageSection.match(pageSectionContentRegex);

      route = route.replace(pageSection, pageSectionContent);
    }

    return route.supplant(replace);
  }

  function getCurlyKey (key) {
    var attrs = key.match(/(:[^\/:()*]+)/g);
    _.each(attrs, function (attr) {
      key = key.replace(attr, '{' + attr.replace(':', '') + '}');
    });

    return key;
  }

  var Navigator = Backbone.Model.extend({
    initialize: function () {
      this.routes = this._processRoutes(Settings.get('routes'));
    },

    navigate: function (route, trigger) {
      route = this._routeFromAbsoluteUrl(route);
      EventBus.trigger('router:nav', {route: route, options: {trigger: trigger}});
    },

    navigateToHome: function (home, paged, trigger) {
      this._navigateToType(this.routes.root[0], {paged: paged}, trigger);
    },

    navigateToSearch: function (search, paged, trigger) {
      this._navigateToType(this.routes.search[0], {search: search, paged: paged}, trigger);
    },

    navigateToAuthor: function (author, paged, trigger) {
      this._navigateToType(this.routes.author[0], {author: author, paged: paged}, trigger);
    },

    navigateToDate: function (date, paged, trigger) {
      var numValues = _.keys(date).length;
      this._navigateToType(this.routes.date[numValues - 1], _.extend(date, {paged: paged}), trigger);
    },

    navigateToPost: function (post, paged, trigger) {
      this.navigateToPostType('post', post, paged, trigger);
    },

    navigateToPage: function (page, paged, trigger) {
      this.navigateToPostType('page', page, paged, trigger);
    },

    navigateToPostType: function (type, post, paged, trigger) {
      var routeParams = {paged: paged};
      routeParams[type] = post;
      this._navigateToType(this.routes[type][0], routeParams, trigger);
    },

    navigateToTaxonomy: function (taxonomy, term, paged, trigger) {
      var routeParams = {paged: paged};
      routeParams[taxonomy] = term;
      this._navigateToType(this.routes[taxonomy][0], routeParams, trigger);
    },

    getRouteOfType: function (type, slug, paged) {
      var data   = {};
      data[type] = slug;
      data.paged = paged;
      return buildUri(this.routes[type][0], data);
    },

    getRoute: function () {
      return Backbone.history.fragment;
    },

    getPagedRoute: function (filter, page) {
      var url   = schema[filter.get('paging-schema')],
          regex = /(page\/\d)|(&page=\d)/,
          route = this.getRoute();

      route = (routeIsPaged(route)) ? route.replace(regex, url(page))
                                    : route + '/' + url(page);
      return route;
    },

    /**
     * Extract route string from an absolute URL.
     * @param  {String} url Absolute or relative URL.
     * @return {String}     Route.
     */
    _routeFromAbsoluteUrl: function (url) {
      var re = new RegExp('^' + Settings.get('site_url') + '/(.+?)/?$', 'g');
      return url.replace(re, '$1');
    },

    _navigateToType: function (type, data, trigger) {
      var route = buildUri(type, data);
      this.navigate(route, trigger);
    },

    _processRoutes: function (routes) {
      var keys    = _.keys(routes),
          mapping = {};

      _.each(keys, function (key) {
        var route = routes[key];
        if (!mapping.hasOwnProperty(route.type)) {
          mapping[route.type] = [];
        }

        mapping[route.type].push(getCurlyKey(key));
      });

      return mapping;
    },
  });

  return new Navigator();
});
<commit_msg>Add new navigation method<commit_after>/* globals define */

define([
  'jquery',
  'underscore',
  'backbone',
  'marionette',
  'buses/event-bus',
  'models/settings-model'
], function ($, _, Backbone, Marionette, EventBus, Settings) {
  'use strict';

  var schema = {
    'url':   function (page) {
      return 'page/' + page;
    },
    'query': function (page) {
      return '&page=' + page;
    }
  };

  function routeIsPaged (route) {
    var isPaged = route.match(/(page\/\d+\/?$)|([?&]page=\d+)/);
    return isPaged !== null && isPaged.length > 0;
  }

  function buildUri(route, replace) {
    var pageRegex   = /(\(\/?page\/.*\))/g;
    var pageSection = route.match(pageRegex);

    pageSection = (_.isEmpty(pageSection)) ? '' : pageSection[0];

    if (!replace.paged || replace.paged < 2) {
      route = route.replace(pageSection, '');
      delete replace.paged;
    } else {
      var pageSectionContentRegex = new RegExp(pageSection, 'g');
      var pageSectionContent      = pageSection.match(pageSectionContentRegex);

      route = route.replace(pageSection, pageSectionContent);
    }

    return route.supplant(replace);
  }

  function getCurlyKey (key) {
    var attrs = key.match(/(:[^\/:()*]+)/g);
    _.each(attrs, function (attr) {
      key = key.replace(attr, '{' + attr.replace(':', '') + '}');
    });

    return key;
  }

  var Navigator = Backbone.Model.extend({
    initialize: function () {
      this.routes = this._processRoutes(Settings.get('routes'));
    },

    navigateToCurrent: function () {
      Backbone.history.loadUrl();
    },

    navigate: function (route, trigger) {
      route = this._routeFromAbsoluteUrl(route);
      EventBus.trigger('router:nav', {route: route, options: {trigger: trigger}});
    },

    navigateToHome: function (home, paged, trigger) {
      this._navigateToType(this.routes.root[0], {paged: paged}, trigger);
    },

    navigateToSearch: function (search, paged, trigger) {
      this._navigateToType(this.routes.search[0], {search: search, paged: paged}, trigger);
    },

    navigateToAuthor: function (author, paged, trigger) {
      this._navigateToType(this.routes.author[0], {author: author, paged: paged}, trigger);
    },

    navigateToDate: function (date, paged, trigger) {
      var numValues = _.keys(date).length;
      this._navigateToType(this.routes.date[numValues - 1], _.extend(date, {paged: paged}), trigger);
    },

    navigateToPost: function (post, paged, trigger) {
      this.navigateToPostType('post', post, paged, trigger);
    },

    navigateToPage: function (page, paged, trigger) {
      this.navigateToPostType('page', page, paged, trigger);
    },

    navigateToPostType: function (type, post, paged, trigger) {
      var routeParams = {paged: paged};
      routeParams[type] = post;
      this._navigateToType(this.routes[type][0], routeParams, trigger);
    },

    navigateToTaxonomy: function (taxonomy, term, paged, trigger) {
      var routeParams = {paged: paged};
      routeParams[taxonomy] = term;
      this._navigateToType(this.routes[taxonomy][0], routeParams, trigger);
    },

    getRouteOfType: function (type, slug, paged) {
      var data   = {};
      data[type] = slug;
      data.paged = paged;
      return buildUri(this.routes[type][0], data);
    },

    getRoute: function () {
      return Backbone.history.fragment;
    },

    getPagedRoute: function (filter, page) {
      var url   = schema[filter.get('paging-schema')],
          regex = /(page\/\d)|(&page=\d)/,
          route = this.getRoute();

      route = (routeIsPaged(route)) ? route.replace(regex, url(page))
                                    : route + '/' + url(page);
      return route;
    },

    /**
     * Extract route string from an absolute URL.
     * @param  {String} url Absolute or relative URL.
     * @return {String}     Route.
     */
    _routeFromAbsoluteUrl: function (url) {
      var re = new RegExp('^' + Settings.get('site_url') + '/(.+?)/?$', 'g');
      return url.replace(re, '$1');
    },

    _navigateToType: function (type, data, trigger) {
      var route = buildUri(type, data);
      this.navigate(route, trigger);
    },

    _processRoutes: function (routes) {
      var keys    = _.keys(routes),
          mapping = {};

      _.each(keys, function (key) {
        var route = routes[key];
        if (!mapping.hasOwnProperty(route.type)) {
          mapping[route.type] = [];
        }

        mapping[route.type].push(getCurlyKey(key));
      });

      return mapping;
    },
  });

  return new Navigator();
});
<|endoftext|>


<commit_before>/* PCM WAV generation */

export function makeWAVURL(data, numChannels, sampleRate, littleEndian = true) {
  let bytesPerSample = data.BYTES_PER_ELEMENT;
  let samplesPerChannel = data.length/numChannels;

  let blockAlign = numChannels * bytesPerSample;
  let byteRate = sampleRate * blockAlign;
  let dataSize = samplesPerChannel * blockAlign;

  let header = new ArrayBuffer(44);            // Header length
  let dv = new DataView(header);

  let chunkID = (littleEndian) ?
    0x52494646 :  // 'RIFF'
    0x52494658 ;  // 'RIFX'

  dv.setUint32(0, chunkID, false);             // ChunkID
  dv.setUint32(4, dataSize + 36, true);        // ChunkSize
  dv.setUint32(8, 0x57415645, false);          // Format ('WAVE')
  dv.setUint32(12, 0x666d7420, false);         // Subchunk1ID ('fmt ')
  dv.setUint32(16, 16, true);                  // Subchunk1Size
  dv.setUint16(20, 1, true);                   // AudioFormat (1 = PCM)
  dv.setUint16(22, numChannels, true);         // NumChannels
  dv.setUint32(24, sampleRate, true);          // SampleRate
  dv.setUint32(28, byteRate, true);            // ByteRate
  dv.setUint16(32, blockAlign, true);          // BlockAlign
  dv.setUint16(34, bytesPerSample * 8, true);  // BitsPerSample
  dv.setUint32(36, 0x64617461, false);         // Subchunk2ID ('data')
  dv.setUint32(40, dataSize, true);            // Subchunk2Size

  let blob = new Blob([header, data], {type: 'audio/wav'});
  return URL.createObjectURL(blob);
}

function quantizeUint8(v) {
  return Math.floor((v + 1) / 2 * 0xff);
}

export function quantizeInt16(v) {
 return Math.floor((v + 1) / 2 * 0xffff - 0x8000);
}

export function Uint8Mono(sampleRate, length, fn) {
  let channelLength = Math.floor(length * sampleRate);
  let buffer = new Uint8Array(channelLength);

  for (let i = 0; i < buffer.length; i++) {
    let t = i/sampleRate;
    buffer[i] = quantizeUint8(fn(t));
  }

  return buffer;
}

export function Uint8Stereo(sampleRate, length, fn) {
  let channelLength = Math.floor(length * sampleRate);
  let buffer = new Uint8Array(2 * channelLength);

  for (let i = 0; i < channelLength; i++) {
    let t = i/sampleRate;
    let [l, r] = fn(t);
    buffer[i * 2] = quantizeUint8(l);
    buffer[i * 2 + 1] = quantizeUint8(r);
  }

  return buffer;
}

export function Int16Mono(sampleRate, length, fn) {
  let channelLength = Math.floor(length * sampleRate);
  let buffer = new Int16Array(channelLength);

  for (let i = 0; i < channelLength; i++) {
    let t = i/sampleRate;
    buffer[i] = quantizeInt16(fn(t));
  }

  return buffer;
}

export function Int16Stereo(sampleRate, length, fn) {
  let channelLength = Math.floor(length * sampleRate);
  let buffer = new Int16Array(2 * channelLength);

  for (let i = 0; i < channelLength; i++) {
    let t = i/sampleRate;
    let [l, r] = fn(t);
    buffer[i * 2] = quantizeInt16(l);
    buffer[i * 2 + 1] = quantizeInt16(r);
  }

  return buffer;
}

import * as myself from './Util.js'
export default myself
<commit_msg>Fix PCM reexport<commit_after>/* PCM WAV generation */

export function makeWAVURL(data, numChannels, sampleRate, littleEndian = true) {
  let bytesPerSample = data.BYTES_PER_ELEMENT;
  let samplesPerChannel = data.length/numChannels;

  let blockAlign = numChannels * bytesPerSample;
  let byteRate = sampleRate * blockAlign;
  let dataSize = samplesPerChannel * blockAlign;

  let header = new ArrayBuffer(44);            // Header length
  let dv = new DataView(header);

  let chunkID = (littleEndian) ?
    0x52494646 :  // 'RIFF'
    0x52494658 ;  // 'RIFX'

  dv.setUint32(0, chunkID, false);             // ChunkID
  dv.setUint32(4, dataSize + 36, true);        // ChunkSize
  dv.setUint32(8, 0x57415645, false);          // Format ('WAVE')
  dv.setUint32(12, 0x666d7420, false);         // Subchunk1ID ('fmt ')
  dv.setUint32(16, 16, true);                  // Subchunk1Size
  dv.setUint16(20, 1, true);                   // AudioFormat (1 = PCM)
  dv.setUint16(22, numChannels, true);         // NumChannels
  dv.setUint32(24, sampleRate, true);          // SampleRate
  dv.setUint32(28, byteRate, true);            // ByteRate
  dv.setUint16(32, blockAlign, true);          // BlockAlign
  dv.setUint16(34, bytesPerSample * 8, true);  // BitsPerSample
  dv.setUint32(36, 0x64617461, false);         // Subchunk2ID ('data')
  dv.setUint32(40, dataSize, true);            // Subchunk2Size

  let blob = new Blob([header, data], {type: 'audio/wav'});
  return URL.createObjectURL(blob);
}

function quantizeUint8(v) {
  return Math.floor((v + 1) / 2 * 0xff);
}

export function quantizeInt16(v) {
 return Math.floor((v + 1) / 2 * 0xffff - 0x8000);
}

export function Uint8Mono(sampleRate, length, fn) {
  let channelLength = Math.floor(length * sampleRate);
  let buffer = new Uint8Array(channelLength);

  for (let i = 0; i < buffer.length; i++) {
    let t = i/sampleRate;
    buffer[i] = quantizeUint8(fn(t));
  }

  return buffer;
}

export function Uint8Stereo(sampleRate, length, fn) {
  let channelLength = Math.floor(length * sampleRate);
  let buffer = new Uint8Array(2 * channelLength);

  for (let i = 0; i < channelLength; i++) {
    let t = i/sampleRate;
    let [l, r] = fn(t);
    buffer[i * 2] = quantizeUint8(l);
    buffer[i * 2 + 1] = quantizeUint8(r);
  }

  return buffer;
}

export function Int16Mono(sampleRate, length, fn) {
  let channelLength = Math.floor(length * sampleRate);
  let buffer = new Int16Array(channelLength);

  for (let i = 0; i < channelLength; i++) {
    let t = i/sampleRate;
    buffer[i] = quantizeInt16(fn(t));
  }

  return buffer;
}

export function Int16Stereo(sampleRate, length, fn) {
  let channelLength = Math.floor(length * sampleRate);
  let buffer = new Int16Array(2 * channelLength);

  for (let i = 0; i < channelLength; i++) {
    let t = i/sampleRate;
    let [l, r] = fn(t);
    buffer[i * 2] = quantizeInt16(l);
    buffer[i * 2 + 1] = quantizeInt16(r);
  }

  return buffer;
}

import * as myself from './PCM.js'
export default myself
<|endoftext|>