<commit_before>(function(){

	var DEBUG = false;

	var doPost = false;

	try {
		doPost = !!window.top.postMessage;
	} catch(e){}

	var search = window.location.search,
		url, index;
	if( ( index = search.indexOf( "swarmURL=" ) ) != -1 )
		url = decodeURIComponent( search.slice( index + 9 ) );

	if ( !DEBUG && (!url || url.indexOf("http") !== 0) ) {
		return;
	}

	var submitTimeout = 5;

	var curHeartbeat;
	var beatRate = 20;

	// Expose the TestSwarm API
	window.TestSwarm = {
		submit: submit,
		heartbeat: function(){
			if ( curHeartbeat ) {
				clearTimeout( curHeartbeat );
			}

			curHeartbeat = setTimeout(function(){
				submit({ fail: -1, total: -1 });
			}, beatRate * 1000);
		},
		serialize: function(){
			return trimSerialize();
		}
	};

	// Prevent careless things from executing
	window.print = window.confirm = window.alert = window.open = function(){};

	window.onerror = function(e){
		document.body.appendChild( document.createTextNode( "ERROR: " + e ));
		submit({ fail: 0, error: 1, total: 1 });
		return false;
	};

	// QUnit (jQuery)
	// http://docs.jquery.com/QUnit
	if ( typeof QUnit !== "undefined" ) {
		QUnit.done = function(fail, total){
			submit({
				fail: fail,
				error: 0,
				total: total
			});
		};

		QUnit.log = window.TestSwarm.heartbeat;
		window.TestSwarm.heartbeat();

		window.TestSwarm.serialize = function(){
			// Clean up the HTML (remove any un-needed test markup)
			remove("nothiddendiv");
			remove("loadediframe");
			remove("dl");
			remove("main");

			// Show any collapsed results
			var ol = document.getElementsByTagName("ol");
			for ( var i = 0; i < ol.length; i++ ) {
				ol[i].style.display = "block";
			}

			return trimSerialize();
		};

	// UnitTestJS (Prototype, Scriptaculous)
	// http://github.com/tobie/unittest_js/tree/master
	} else if ( typeof Test !== "undefined" && Test && Test.Unit && Test.Unit.runners ) {
		var total_runners = Test.Unit.runners.length, cur_runners = 0;
		var total = 0, fail = 0, error = 0;

		for (var i = 0; i < Test.Unit.runners.length; i++) (function(i){
			var finish = Test.Unit.runners[i].finish;
			Test.Unit.runners[i].finish = function(){
				finish.call( this );

				var results = this.getResult();
				total += results.assertions;
				fail += results.failures;
				error += results.errors;

				if ( ++cur_runners === total_runners ) {
					submit({
						fail: fail,
						error: error,
						total: total
					});
				}
			};
		})(i);

	// JSSpec (MooTools)
	// http://jania.pe.kr/aw/moin.cgi/JSSpec
	} else if ( typeof JSSpec !== "undefined" && JSSpec && JSSpec.Logger ) {
		var onRunnerEnd = JSSpec.Logger.prototype.onRunnerEnd;
		JSSpec.Logger.prototype.onRunnerEnd = function(){
			onRunnerEnd.call(this);

			// Show any collapsed results
			var ul = document.getElementsByTagName("ul");
			for ( var i = 0; i < ul.length; i++ ) {
				ul[i].style.display = "block";
			}

			submit({
				fail: JSSpec.runner.getTotalFailures(),
				error: JSSpec.runner.getTotalErrors(),
				total: JSSpec.runner.totalExamples
			});
		};

		window.TestSwarm.serialize = function(){
			// Show any collapsed results
			var ul = document.getElementsByTagName("ul");
			for ( var i = 0; i < ul.length; i++ ) {
				ul[i].style.display = "block";
			}

			return trimSerialize();
		};

	// JSUnit
	// http://www.jsunit.net/
	// Note: Injection file must be included before the frames
	//       are document.write()d into the page.
	} else if ( typeof JsUnitTestManager !== "undefined" ) {
		var _done = JsUnitTestManager.prototype._done;
		JsUnitTestManager.prototype._done = function(){
			_done.call(this);

			submit({
				fail: this.failureCount,
				error: this.errorCount,
				total: this.totalCount
			});
		};

		window.TestSwarm.serialize = function(){
			return "
" + this.log.join("\n") + "
";
		};

	// Selenium Core
	// http://seleniumhq.org/projects/core/
	} else if ( typeof SeleniumTestResult !== "undefined" && typeof LOG !== "undefined" ) {
		// Completely overwrite the postback
		SeleniumTestResult.prototype.post = function(){
			submit({
				fail: this.metrics.numCommandFailures,
				error: this.metrics.numCommandErrors,
				total: this.metrics.numCommandPasses + this.metrics.numCommandFailures + this.metrics.numCommandErrors
			});
		};

		window.TestSwarm.serialize = function(){
			var results = [];
			while ( LOG.pendingMessages.length ) {
				var msg = LOG.pendingMessages.shift();
				results.push( msg.type + ": " + msg.msg );
			}

			return "
" + results.join("\n") + "
";
		};

	// Dojo Objective Harness
	// http://docs.dojocampus.org/quickstart/doh
	} else if ( typeof doh !== "undefined" && doh._report ) {
		var _report = doh._report;
		doh._report = function(){
			_report.apply(this, arguments);

			submit({
				fail: doh._failureCount,
				error: doh._errorCount,
				total: doh._testCount
			});
		};

		window.TestSwarm.serialize = function(){
			return "
" + document.getElementById("logBody").innerHTML + "
";
		};
	}

	function trimSerialize(doc) {
		doc = doc || document;

		var scripts = doc.getElementsByTagName("script");
		while ( scripts.length ) {
			remove( scripts[0] );
		}

		var root = window.location.href.replace(/(https?:\/\/.*?)\/.*/, "$1");
		var cur = window.location.href.replace(/[^\/]*$/, "");

		var links = doc.getElementsByTagName("link");
		for ( var i = 0; i < links.length; i++ ) {
			var href = links[i].href;
			if ( href.indexOf("/") === 0 ) {
				href = root + href;
			} else if ( !/^https?:\/\//.test( href ) ) {
				href = cur + href;
			}
			links[i].href = href;
		}

		return ("" + doc.documentElement.innerHTML + "")
			.replace(/\s+/g, " ");
	}

	function remove(elem){
		if ( typeof elem === "string" ) {
			elem = document.getElementById( elem );
		}

		if ( elem ) {
			elem.parentNode.removeChild( elem );
		}
	}

	function submit(params){
		if ( curHeartbeat ) {
			clearTimeout( curHeartbeat );
		}

		var paramItems = (url.split("?")[1] || "").split("&");

		for ( var i = 0; i < paramItems.length; i++ ) {
			if ( paramItems[i] ) {
				var parts = paramItems[i].split("=");
				if ( !params[ parts[0] ] ) {
					params[ parts[0] ] = parts[1];
				}
			}
		}

		if ( !params.state ) {
			params.state = "saverun";
		}

		if ( !params.results ) {
			params.results = window.TestSwarm.serialize();
		}

		if ( doPost ) {
			// Build Query String
			var query = "";

			for ( var i in params ) {
				query += ( query ? "&" : "" ) + i + "=" +
					encodeURIComponent(params[i]);
			}

			if ( DEBUG ) {
				alert( query );
			} else {
				window.top.postMessage( query, "*" );
			}

		} else {
			var form = document.createElement("form");
			form.action = url;
			form.method = "POST";

			for ( var i in params ) {
				var input = document.createElement("input");
				input.type = "hidden";
				input.name = i;
				input.value = params[i];
				form.appendChild( input );
			}

			if ( DEBUG ) {
				alert( form.innerHTML );
			} else {

				// Watch for the result submission timing out
				setTimeout(function(){
					submit( params );
				}, submitTimeout * 1000);

				document.body.appendChild( form );
				form.submit();
			}
		}
	}

})();
<commit_msg>Screw.Unit support<commit_after>(function(){

	var DEBUG = false;

	var doPost = false;

	try {
		doPost = !!window.top.postMessage;
	} catch(e){}

	var search = window.location.search,
		url, index;
	if( ( index = search.indexOf( "swarmURL=" ) ) != -1 )
		url = decodeURIComponent( search.slice( index + 9 ) );

	if ( !DEBUG && (!url || url.indexOf("http") !== 0) ) {
		return;
	}

	var submitTimeout = 5;

	var curHeartbeat;
	var beatRate = 20;

	// Expose the TestSwarm API
	window.TestSwarm = {
		submit: submit,
		heartbeat: function(){
			if ( curHeartbeat ) {
				clearTimeout( curHeartbeat );
			}

			curHeartbeat = setTimeout(function(){
				submit({ fail: -1, total: -1 });
			}, beatRate * 1000);
		},
		serialize: function(){
			return trimSerialize();
		}
	};

	// Prevent careless things from executing
	window.print = window.confirm = window.alert = window.open = function(){};

	window.onerror = function(e){
		document.body.appendChild( document.createTextNode( "ERROR: " + e ));
		submit({ fail: 0, error: 1, total: 1 });
		return false;
	};

	// QUnit (jQuery)
	// http://docs.jquery.com/QUnit
	if ( typeof QUnit !== "undefined" ) {
		QUnit.done = function(fail, total){
			submit({
				fail: fail,
				error: 0,
				total: total
			});
		};

		QUnit.log = window.TestSwarm.heartbeat;
		window.TestSwarm.heartbeat();

		window.TestSwarm.serialize = function(){
			// Clean up the HTML (remove any un-needed test markup)
			remove("nothiddendiv");
			remove("loadediframe");
			remove("dl");
			remove("main");

			// Show any collapsed results
			var ol = document.getElementsByTagName("ol");
			for ( var i = 0; i < ol.length; i++ ) {
				ol[i].style.display = "block";
			}

			return trimSerialize();
		};

	// UnitTestJS (Prototype, Scriptaculous)
	// http://github.com/tobie/unittest_js/tree/master
	} else if ( typeof Test !== "undefined" && Test && Test.Unit && Test.Unit.runners ) {
		var total_runners = Test.Unit.runners.length, cur_runners = 0;
		var total = 0, fail = 0, error = 0;

		for (var i = 0; i < Test.Unit.runners.length; i++) (function(i){
			var finish = Test.Unit.runners[i].finish;
			Test.Unit.runners[i].finish = function(){
				finish.call( this );

				var results = this.getResult();
				total += results.assertions;
				fail += results.failures;
				error += results.errors;

				if ( ++cur_runners === total_runners ) {
					submit({
						fail: fail,
						error: error,
						total: total
					});
				}
			};
		})(i);

	// JSSpec (MooTools)
	// http://jania.pe.kr/aw/moin.cgi/JSSpec
	} else if ( typeof JSSpec !== "undefined" && JSSpec && JSSpec.Logger ) {
		var onRunnerEnd = JSSpec.Logger.prototype.onRunnerEnd;
		JSSpec.Logger.prototype.onRunnerEnd = function(){
			onRunnerEnd.call(this);

			// Show any collapsed results
			var ul = document.getElementsByTagName("ul");
			for ( var i = 0; i < ul.length; i++ ) {
				ul[i].style.display = "block";
			}

			submit({
				fail: JSSpec.runner.getTotalFailures(),
				error: JSSpec.runner.getTotalErrors(),
				total: JSSpec.runner.totalExamples
			});
		};

		window.TestSwarm.serialize = function(){
			// Show any collapsed results
			var ul = document.getElementsByTagName("ul");
			for ( var i = 0; i < ul.length; i++ ) {
				ul[i].style.display = "block";
			}

			return trimSerialize();
		};

	// JSUnit
	// http://www.jsunit.net/
	// Note: Injection file must be included before the frames
	//       are document.write()d into the page.
	} else if ( typeof JsUnitTestManager !== "undefined" ) {
		var _done = JsUnitTestManager.prototype._done;
		JsUnitTestManager.prototype._done = function(){
			_done.call(this);

			submit({
				fail: this.failureCount,
				error: this.errorCount,
				total: this.totalCount
			});
		};

		window.TestSwarm.serialize = function(){
			return "
" + this.log.join("\n") + "
";
		};

	// Selenium Core
	// http://seleniumhq.org/projects/core/
	} else if ( typeof SeleniumTestResult !== "undefined" && typeof LOG !== "undefined" ) {
		// Completely overwrite the postback
		SeleniumTestResult.prototype.post = function(){
			submit({
				fail: this.metrics.numCommandFailures,
				error: this.metrics.numCommandErrors,
				total: this.metrics.numCommandPasses + this.metrics.numCommandFailures + this.metrics.numCommandErrors
			});
		};

		window.TestSwarm.serialize = function(){
			var results = [];
			while ( LOG.pendingMessages.length ) {
				var msg = LOG.pendingMessages.shift();
				results.push( msg.type + ": " + msg.msg );
			}

			return "
" + results.join("\n") + "
";
		};

	// Dojo Objective Harness
	// http://docs.dojocampus.org/quickstart/doh
	} else if ( typeof doh !== "undefined" && doh._report ) {
		var _report = doh._report;
		doh._report = function(){
			_report.apply(this, arguments);

			submit({
				fail: doh._failureCount,
				error: doh._errorCount,
				total: doh._testCount
			});
		};

		window.TestSwarm.serialize = function(){
			return "
" + document.getElementById("logBody").innerHTML + "
";
		};
  // Screw.Unit
  // git://github.com/nathansobo/screw-unit.git
	} else if ( typeof Screw !== "undefined" && typeof jQuery !== 'undefined' && Screw && Screw.Unit ) {
    $(Screw).bind("after", function() {
     var passed = $('.passed').length;
     var failed = $('.failed').length;
     submit({
        fail: failed,
        error: 0,
        total: failed + passed
      });
    });

    $(Screw).bind("loaded", function() {
      $('.it')
        .bind("passed", window.TestSwarm.heartbeat)
        .bind("failed", window.TestSwarm.heartbeat);
      window.TestSwarm.heartbeat();
    });

    window.TestSwarm.serialize = function(){
    	return trimSerialize();
    };
  }

	function trimSerialize(doc) {
		doc = doc || document;

		var scripts = doc.getElementsByTagName("script");
		while ( scripts.length ) {
			remove( scripts[0] );
		}

		var root = window.location.href.replace(/(https?:\/\/.*?)\/.*/, "$1");
		var cur = window.location.href.replace(/[^\/]*$/, "");

		var links = doc.getElementsByTagName("link");
		for ( var i = 0; i < links.length; i++ ) {
			var href = links[i].href;
			if ( href.indexOf("/") === 0 ) {
				href = root + href;
			} else if ( !/^https?:\/\//.test( href ) ) {
				href = cur + href;
			}
			links[i].href = href;
		}

		return ("" + doc.documentElement.innerHTML + "")
			.replace(/\s+/g, " ");
	}

	function remove(elem){
		if ( typeof elem === "string" ) {
			elem = document.getElementById( elem );
		}

		if ( elem ) {
			elem.parentNode.removeChild( elem );
		}
	}

	function submit(params){
		if ( curHeartbeat ) {
			clearTimeout( curHeartbeat );
		}

		var paramItems = (url.split("?")[1] || "").split("&");

		for ( var i = 0; i < paramItems.length; i++ ) {
			if ( paramItems[i] ) {
				var parts = paramItems[i].split("=");
				if ( !params[ parts[0] ] ) {
					params[ parts[0] ] = parts[1];
				}
			}
		}

		if ( !params.state ) {
			params.state = "saverun";
		}

		if ( !params.results ) {
			params.results = window.TestSwarm.serialize();
		}

		if ( doPost ) {
			// Build Query String
			var query = "";

			for ( var i in params ) {
				query += ( query ? "&" : "" ) + i + "=" +
					encodeURIComponent(params[i]);
			}

			if ( DEBUG ) {
				alert( query );
			} else {
				window.top.postMessage( query, "*" );
			}

		} else {
			var form = document.createElement("form");
			form.action = url;
			form.method = "POST";

			for ( var i in params ) {
				var input = document.createElement("input");
				input.type = "hidden";
				input.name = i;
				input.value = params[i];
				form.appendChild( input );
			}

			if ( DEBUG ) {
				alert( form.innerHTML );
			} else {

				// Watch for the result submission timing out
				setTimeout(function(){
					submit( params );
				}, submitTimeout * 1000);

				document.body.appendChild( form );
				form.submit();
			}
		}
	}

})();
<|endoftext|>


<commit_before><commit_msg>Update convertJava.js<commit_after><|endoftext|>


<commit_before>// VCE Project - Molecular Dynamics script
//
// This script performs a simple, event-drive molecular dynamics
// simulation on a p5.js canvas.
//
// Requires:
// - p5.js or p5.min.js
// - particle.js
// - event.js
//
// Andrew D. McGuire 2017
// a.mcguire227@gmail.com
//----------------------------------------------------------

// Set-up parameters
var particles = [];    // particle array (to be filled with instances of the Particle class)
var r = null;          // particle radius to use (null = random in range)
var r_upper = 20;      // maximum radius
var r_lower = 5;       // minimum radius
var time = 0.0;        // global simulation time
var xmax;              // canvas x-width
var ymax;              // canvas y-width
var paused_log = true; // paused indicator bool

function setup() {

    /* This function is called upon entry to create the
       simulation canvas which we draw onto and the particle array.
       Canvas size and particle number is dependent on the window
       size. */

    var dimensions = getSimBoxDimensions();
    xmax = dimensions.xmax;
    ymax = dimensions.ymax;
    console.log("xmax=",xmax);
    console.log("ymax=",ymax);
    var canvas= createCanvas(xmax, ymax);
    canvas.parent("sim_container")
    restartParticles();
}

function draw() {

    /* This function drives the simulation forward in time.
       It's continuously called for the
       lifetime of the scripts executions after setup()
       has completed. */

    // set the background-up
    background(51);
    stroke(255);
    strokeWeight(1);

    // draw the particle to the canvas
    for (i = 0; i < particles.length; i++) {
	     particles[i].show();
    }

    // set up stroke for progress box
    noStroke();
    fill(0)
    rect(0.85*xmax,0.92*ymax,0.14*xmax,0.07*ymax)
    fill(255)

    // Step through time unless sim is paused,
    // reporting status in progress box.
    if (!(paused_log)) {
      var dt_step = 1000.0;
      doStep(dt_step);
    }
    writeTime();
}

function writeTime() {

    // Write the current simulation time to the process box
    stroke(255);
    strokeWeight(1);
    fill(255)
    textSize(Math.round(xmax/45.0))
    text("t = "+time.toFixed(0),0.87*xmax,0.93*ymax,0.12*xmax,0.05*ymax);
    //text("t = "+xmax,0.91*xmax,0.95*ymax,0.1*xmax,0.1*ymax);
}

function doStep(dt) {

    /* Advances the particle ensemble over the
       time interval dt, or to the next collision time,
       whichever comes first.
       If a collision is detected within (time,time+dt)
       then it's carried out and the sim time is updated.

       args:
       dt - time to try and advance simulation by
    */

    // Compute the time to the next collision
    var dt_col;
    coll_list = getCollisionList(particles);
    if (coll_list.length < 1) {
      dt_col = dt + 1; // just needs to exceed dt
    } else {
      dt_col = (coll_list[0]).t;
    }

    // Check for collisions in the current time
    if (dt < dt_col) {
	// No collision in the time step
	advanceParticles(dt);
	time = time + dt;
	return 0
    }
    else  {
	// Collision has occured between the step
	// so, carry it out. Highlighting the particles
	// involved.
	advanceParticles(dt_col);
        var firstEvent = coll_list[0];
	highlightEventParticles(firstEvent)
	performCollision(firstEvent);
        time = time + dt_col
    }
}

function highlightEventParticles(CurrentEvent) {

    /* Highlight the particle(s) involved in
       an event

       args:
       CurrentEvent - a valid Event object
    */

    var p1 = particles[CurrentEvent.p1_index];
    p1.highlight();
    if (CurrentEvent.p2_index) {
        var p2 = particles[CurrentEvent.p2_index];
        p2.highlight();
    }
}

function getWallCollisionTime(Part) {

    /* Compute the first collision time with between
       particle Part and any wall */

    // returns object with attributes
    var t    // first collision time
    var wall // wall associated with first collision

    // locals vars
    var t_side // side wall collision time
    var t_ud   // top or bottom wall collision time
    var w_side // which side wall ('r' or 'l')
    var w_ud   // top or bottom wall first? ('u' ,d')

    // side walls
    if (Part.vel.x > 0) {
	t_side = (xmax - Part.pos.x - Part.radius)/Part.vel.x;
	w_side = 'r';
    } else if (Part.vel.x < 0) {
	t_side = (0 - Part.pos.x + Part.radius)/Part.vel.x;
	w_side = 'l';
    } else {
	// particle not moving in x direction
	t_side = NaN;
	w_side = null;
    }

    // top and bottom
    if (Part.vel.y > 0) {
	t_ud = (ymax - Part.pos.y - Part.radius)/Part.vel.y;
	w_ud = 'd';
    } else if (Part.vel.y < 0) {
	t_ud = (0 - Part.pos.y + Part.radius)/Part.vel.y;
	w_ud = 'u';
    } else {
	// particle not moving in y direction
	t_ud = NaN;
	w_ud = null;
    }

    if (t_side === NaN && t_ud === NaN) {
	// part is stationary
	t = NaN;
	wall= null;
    } else if (t_side <= t_ud) {
	t = t_side;
	wall = w_side;
    } else {
	t = t_ud;
	wall = w_ud;
    }

    return {
        t: t,
        wall: wall
    };
}

function getCollisionTime(Part1, Part2) {

    /* Compute the time until collision
       between particle Part1 and Part2.

       return time as NaN if no collision
       time solution found */

    var deltaVel = p5.Vector.sub(Part1.vel,Part2.vel)
    var deltaPos = p5.Vector.sub(Part1.pos,Part2.pos)
    var minDist = Part1.radius + Part2.radius
    var a = p5.Vector.dot(deltaVel, deltaVel)
    var b = 2.0*p5.Vector.dot(deltaPos,deltaVel)
    var c = p5.Vector.dot(deltaPos,deltaPos) - minDist*minDist
    var discrim = b*b - 4*a*c

    if ((discrim > 0) && (b < 0)) {
	var t1 = (-b - Math.sqrt(discrim))/(2*a)
	return t1
    }
    return NaN
}

function getCollisionList(particles) {

    /* Returns an array of collision Event objects,
       ordered by their time attribute
       (smallest to largest, NaNs at the end)

       args:
       particles - an array of Particle objects */

    // return
    var coll_list = []

    // local vars
    var col_time;
    var i, j;
    var firstEvent;
    var wc_time;
    var wall;

    // loop through the particle array
    for (i = 0; i < particles.length; i++) {

	var wall_collision = getWallCollisionTime(particles[i]);
	firstEvent = new Event('w',wall_collision.t,i,null,wall_collision.wall);

	for (j = i+1; j < particles.length; j++) {
	    if (i != j) {
		col_time = getCollisionTime(particles[i],particles[j]);

		// Replace firstEvent if coll time is smaller than current
		// firstEvent.time
	        if (isNaN(col_time) != true) {
                    if (col_time < firstEvent.t) {
			firstEvent = new Event('p',col_time,i,j,null);
                    }
		}
            }
        }
	// Add to the collision list if event is valid
	if (firstEvent.t != NaN) {
            coll_list.push(firstEvent);
	}
    }
    // Sort the Event array and return it
    coll_list.sort(function(a,b){return a.t - b.t});
    return coll_list
}

function performCollision(event) {

    /* Apply collision operator according according to event

       args:
       event - a valid Event object
    */

    if (event.wc_log) {
	// Perform wall collision
	if (event.wall === 'r' || event.wall === 'l') {
	    particles[event.p1_index].reflect_side();
	} else if (event.wall === 'u' || event.wall === 'd') {
	    particles[event.p1_index].reflect_top();
	} else {
	    console.log("Error: performCollision: invalid event");
	    console.log(event);
	}
    } else {
	// Perform binary particle collision
	var J = impulse(particles[event.p1_index],
			particles[event.p2_index]);
	particles[event.p1_index].apply_impulse(J.x,J.y);
	particles[event.p2_index].apply_impulse(-J.x,-J.y);
    }
}

function impulse(Part1,Part2) {

    /* Compute the impulse associated with a particle-particle
       collision
       https://introcs.cs.princeton.edu/java/assignments/collisions.html

       J = 2*m1*m2*(dv*dr)/(sigma*(m1+m2))

       args:
       Part1 - valid Particle object
       Part2 - valid Particle object
    */
    var dr = createVector(Part2.pos.x - Part1.pos.x,
			  Part2.pos.y - Part1.pos.y);
    var dv = createVector(Part2.vel.x - Part1.vel.x,
			  Part2.vel.y - Part1.vel.y);
    var sigma = Part1.radius + Part2.radius;
    var hmm = 2*Part1.mass*Part2.mass/(Part1.mass + Part2.mass);
    var J = p5.Vector.dot(dv,dr)*hmm/sigma;
    return {
	x: J*dr.x/sigma,
	y: J*dr.y/sigma
    };

}

function advanceParticles(dt) {

    /* Advance the ensemble forward in time by dt
       in a straight line trajectory (no collisions) */

    for (i = 0; i < particles.length; i++) {
      particles[i].update(dt);
    }
}

function initParticles(n,r,xmax, ymax) {

    /* Intialise n particles with radius r in box with
       dimensions (xmax,ymax)
       such that there are no overlapping particles

       return:
       particle - an array of Particle objects
    */

    var parts = [];
    var dx = initialSpacing(n, xmax, ymax);
    var n_init = 0 ;
    for (i = 0; i < Math.round(xmax/dx); i++) {
	for (j = 0; j < Math.round(ymax/dx); j++) {
	    if (n_init < n) {
    		parts[n_init] = new Particle(dx*(i+0.5),dx*(j+0.5),getRadius());
	        parts[n_init].show();
		n_init = n_init + 1;
    	    };
        };
    };
    return parts
}

function initialSpacing(n, x, y) {

    /* Returns the intialise spacing
       between particles to put n particles
       on a uniform grid with limits x, y */

    var num1 = -(x+y);
    var num2sqred = Math.pow(x+y,2.0) + 4.0*x*y*(n-1);
    var num2 = Math.pow(num2sqred, 0.5);
    var den = 2.0*(n-1);
    var dx = (num1 + num2) / den;
    return dx
}

function addParticle() {

    // Add a new Particle object to the particles array
    var new_part = new Particle(mouseX,mouseY,getRadius());
    particles.push(new_part);
}

function restartParticles() {
    // re-intialises the particle ensemble
    paused_log = true;
    var dimensions = getSimBoxDimensions();
    xmax = dimensions.xmax;
    ymax = dimensions.ymax;
    var part_to_init = Math.round(xmax*ymax/5000.0);
    particles = initParticles(part_to_init,getRadius(),xmax,ymax);
};

//--------------------------------------------------------------------
//                  Visualisation functionality
//--------------------------------------------------------------------

function mouseinSimBox() {

    if (0 < mouseX && mouseX < xmax && 0 < mouseY && mouseY < ymax) {
	return true;
    };
    return false;
}

function mousePressed() {

    // Act on left mouse press
    if (mouseinSimBox()) {addParticle()};
}

function getSimBoxDimensions() {
    //get the dimension of the simbox
    var sb_ymax = $('#sim_container').outerHeight()*0.95;
    var sb_xmax = $('#sim_container').outerWidth()*0.97;
    return {
	ymax: sb_ymax,
        xmax: sb_xmax
    };
};

function getRadius() {
    return Math.random()*(r_upper-r_lower) + r_lower;
}
//--------------------------------------------------------------------
//                  UI event listners
//--------------------------------------------------------------------
// run button
$('#run').click(async function(){

    // run/pause button functionality
    console.log("You just clicked stream/pause!");
    paused_log = !(paused_log);
    if (paused_log) {
	$("#run").text('Run');
    }
    else {
	$("#run").text('Pause');
    }
});

// restart button
$('#restart').click(async function(){

    // restart button functionality
    console.log("You just clicked restart!");
    restartParticles();
    if (paused_log) {
	$("#run").text('Run');
    }
    else {
	$("#run").text('Pause');
    }
})

// full screen button
const target = $('#target')[0]; // Get DOM element from jQuery collection
$('#fullscreen').on('click', () => {
    console.log("fullscreen requested");
    if (screenfull.enabled) {
	screenfull.request(target);
    }
});
<commit_msg>MD module: partial fix for the overlap issue<commit_after>// VCE Project - Molecular Dynamics script
//
// This script performs a simple, event-drive molecular dynamics
// simulation on a p5.js canvas.
//
// Requires:
// - p5.js or p5.min.js
// - particle.js
// - event.js
//
// Andrew D. McGuire 2017
// a.mcguire227@gmail.com
//----------------------------------------------------------

// Set-up parameters
var particles = [];    // particle array (to be filled with instances of the Particle class)
var r = null;          // particle radius to use (null = random in range)
var r_upper = 20;      // maximum radius
var r_lower = 5;       // minimum radius
var time = 0.0;        // global simulation time
var xmax;              // canvas x-width
var ymax;              // canvas y-width
var paused_log = true; // paused indicator bool

function setup() {

    /* This function is called upon entry to create the
       simulation canvas which we draw onto and the particle array.
       Canvas size and particle number is dependent on the window
       size. */

    var dimensions = getSimBoxDimensions();
    xmax = dimensions.xmax;
    ymax = dimensions.ymax;
    console.log("xmax=",xmax);
    console.log("ymax=",ymax);
    var canvas= createCanvas(xmax, ymax);
    canvas.parent("sim_container")
    restartParticles();
}

function draw() {

    /* This function drives the simulation forward in time.
       It's continuously called for the
       lifetime of the scripts executions after setup()
       has completed. */

    // set the background-up
    background(51);
    stroke(255);
    strokeWeight(1);

    // draw the particle to the canvas
    for (i = 0; i < particles.length; i++) {
	     particles[i].show();
    }

    // set up stroke for progress box
    noStroke();
    fill(0)
    rect(0.85*xmax,0.92*ymax,0.14*xmax,0.07*ymax)
    fill(255)

    // Step through time unless sim is paused,
    // reporting status in progress box.
    if (!(paused_log)) {
      var dt_step = 1000.0;
      doStep(dt_step);
    }
    writeTime();
}

function writeTime() {

    // Write the current simulation time to the process box
    stroke(255);
    strokeWeight(1);
    fill(255)
    textSize(Math.round(xmax/45.0))
    text("t = "+time.toFixed(0),0.87*xmax,0.93*ymax,0.12*xmax,0.05*ymax);
    //text("t = "+xmax,0.91*xmax,0.95*ymax,0.1*xmax,0.1*ymax);
}

function doStep(dt) {

    /* Advances the particle ensemble over the
       time interval dt, or to the next collision time,
       whichever comes first.
       If a collision is detected within (time,time+dt)
       then it's carried out and the sim time is updated.

       args:
       dt - time to try and advance simulation by
    */

    // Compute the time to the next collision
    var dt_col;
    coll_list = getCollisionList(particles);
    if (coll_list.length < 1) {
      dt_col = dt + 1; // just needs to exceed dt
    } else {
      dt_col = (coll_list[0]).t;
    }

    // Check for collisions in the current time
    if (dt < dt_col) {
	// No collision in the time step
	advanceParticles(dt);
	time = time + dt;
	return 0
    }
    else  {
	// Collision has occured between the step
	// so, carry it out. Highlighting the particles
	// involved.
	advanceParticles(dt_col);
        var firstEvent = coll_list[0];
	highlightEventParticles(firstEvent)
	performCollision(firstEvent);
        time = time + dt_col
    }
}

function highlightEventParticles(CurrentEvent) {

    /* Highlight the particle(s) involved in
       an event

       args:
       CurrentEvent - a valid Event object
    */

    var p1 = particles[CurrentEvent.p1_index];
    p1.highlight();
    if (CurrentEvent.p2_index) {
        var p2 = particles[CurrentEvent.p2_index];
        p2.highlight();
    }
}

function getWallCollisionTime(Part) {

    /* Compute the first collision time with between
       particle Part and any wall */

    // returns object with attributes
    var t    // first collision time
    var wall // wall associated with first collision

    // locals vars
    var t_side // side wall collision time
    var t_ud   // top or bottom wall collision time
    var w_side // which side wall ('r' or 'l')
    var w_ud   // top or bottom wall first? ('u' ,d')

    // side walls
    if (Part.vel.x > 0) {
	t_side = (xmax - Part.pos.x - Part.radius)/Part.vel.x;
	w_side = 'r';
    } else if (Part.vel.x < 0) {
	t_side = (0 - Part.pos.x + Part.radius)/Part.vel.x;
	w_side = 'l';
    } else {
	// particle not moving in x direction
	t_side = NaN;
	w_side = null;
    }

    // top and bottom
    if (Part.vel.y > 0) {
	t_ud = (ymax - Part.pos.y - Part.radius)/Part.vel.y;
	w_ud = 'd';
    } else if (Part.vel.y < 0) {
	t_ud = (0 - Part.pos.y + Part.radius)/Part.vel.y;
	w_ud = 'u';
    } else {
	// particle not moving in y direction
	t_ud = NaN;
	w_ud = null;
    }

    if (t_side === NaN && t_ud === NaN) {
	// part is stationary
	t = NaN;
	wall= null;
    } else if (t_side <= t_ud) {
	t = t_side;
	wall = w_side;
    } else {
	t = t_ud;
	wall = w_ud;
    }

    return {
        t: t,
        wall: wall
    };
}

function getCollisionTime(Part1, Part2) {

    /* Compute the time until collision
       between particle Part1 and Part2.

       return time as NaN if no collision
       time solution found */

    var deltaVel = p5.Vector.sub(Part1.vel,Part2.vel)
    var deltaPos = p5.Vector.sub(Part1.pos,Part2.pos)
    var minDist = Part1.radius + Part2.radius
    var a = p5.Vector.dot(deltaVel, deltaVel)
    var b = 2.0*p5.Vector.dot(deltaPos,deltaVel)
    var c = p5.Vector.dot(deltaPos,deltaPos) - minDist*minDist
    var discrim = b*b - 4*a*c

    if ((discrim > 0) && (b < 0)) {
	var t1 = (-b - Math.sqrt(discrim))/(2*a)
	return t1
    }
    return NaN
}

function getCollisionList(particles) {

    /* Returns an array of collision Event objects,
       ordered by their time attribute
       (smallest to largest, NaNs at the end)

       args:
       particles - an array of Particle objects */

    // return
    var coll_list = []

    // local vars
    var col_time;
    var i, j;
    var firstEvent;
    var wc_time;
    var wall;

    // loop through the particle array
    for (i = 0; i < particles.length; i++) {

	var wall_collision = getWallCollisionTime(particles[i]);
	firstEvent = new Event('w',wall_collision.t,i,null,wall_collision.wall);

	for (j = i+1; j < particles.length; j++) {
	    if (i != j) {
		col_time = getCollisionTime(particles[i],particles[j]);

		// Replace firstEvent if coll time is smaller than current
		// firstEvent.time
	        if (isNaN(col_time) != true) {
                    if (col_time < firstEvent.t) {
			firstEvent = new Event('p',col_time,i,j,null);
                    }
		}
            }
        }
	// Add to the collision list if event is valid
	if (firstEvent.t != NaN) {
            coll_list.push(firstEvent);
	}
    }
    // Sort the Event array and return it
    coll_list.sort(function(a,b){return a.t - b.t});
    return coll_list
}

function performCollision(event) {

    /* Apply collision operator according according to event

       args:
       event - a valid Event object
    */

    if (event.wc_log) {
	// Perform wall collision
	if (event.wall === 'r' || event.wall === 'l') {
	    particles[event.p1_index].reflect_side();
	} else if (event.wall === 'u' || event.wall === 'd') {
	    particles[event.p1_index].reflect_top();
	} else {
	    console.log("Error: performCollision: invalid event");
	    console.log(event);
	}
    } else {
	// Perform binary particle collision
	var J = impulse(particles[event.p1_index],
			particles[event.p2_index]);
	particles[event.p1_index].apply_impulse(J.x,J.y);
	particles[event.p2_index].apply_impulse(-J.x,-J.y);
    }
}

function impulse(Part1,Part2) {

    /* Compute the impulse associated with a particle-particle
       collision
       https://introcs.cs.princeton.edu/java/assignments/collisions.html

       J = 2*m1*m2*(dv*dr)/(sigma*(m1+m2))

       args:
       Part1 - valid Particle object
       Part2 - valid Particle object
    */
    var dr = createVector(Part2.pos.x - Part1.pos.x,
			  Part2.pos.y - Part1.pos.y);
    var dv = createVector(Part2.vel.x - Part1.vel.x,
			  Part2.vel.y - Part1.vel.y);
    var sigma = Part1.radius + Part2.radius;
    var hmm = 2*Part1.mass*Part2.mass/(Part1.mass + Part2.mass);
    var J = p5.Vector.dot(dv,dr)*hmm/sigma;
    return {
	x: J*dr.x/sigma,
	y: J*dr.y/sigma
    };

}

function advanceParticles(dt) {

    /* Advance the ensemble forward in time by dt
       in a straight line trajectory (no collisions) */

    for (i = 0; i < particles.length; i++) {
      particles[i].update(dt);
    }
}

function initParticles(n,r,xmax, ymax) {

    /* Intialise n particles with radius r in box with
       dimensions (xmax,ymax)
       such that there are no overlapping particles

       return:
       particle - an array of Particle objects
    */

    var parts = [];
    var dx = initialSpacing(n, xmax, ymax);
    var n_init = 0 ;
    for (i = 0; i < Math.round(xmax/dx); i++) {
	for (j = 0; j < Math.round(ymax/dx); j++) {
	    if (n_init < n) {
    		parts[n_init] = new Particle(dx*(i+0.5),dx*(j+0.5),getRadius());
	        parts[n_init].show();
		n_init = n_init + 1;
    	    };
        };
    };
    return parts
}

function initialSpacing(n, x, y) {

    /* Returns the intialise spacing
       between particles to put n particles
       on a uniform grid with limits x, y */

    var num1 = -(x+y);
    var num2sqred = Math.pow(x+y,2.0) + 4.0*x*y*(n-1);
    var num2 = Math.pow(num2sqred, 0.5);
    var den = 2.0*(n-1);
    var dx = (num1 + num2) / den;
    return dx
}

function addParticle() {

    // Add a new Particle object to the particles array
    // at the position of the mouse. If this overlaps with
    // another particle, then try another position until we
    // find a overlap free position.

    var new_part = new Particle(mouseX,mouseY,getRadius());
    var attempts = 1;
    while (overlapExists(new_part)) {
	new_part = randomMove(new_part);
	attempts = attempts + 1;
    };
    console.log("Inception attempts: ", attempts);
    particles.push(new_part);
}

function restartParticles() {
    // re-intialises the particle ensemble
    paused_log = true;
    var dimensions = getSimBoxDimensions();
    xmax = dimensions.xmax;
    ymax = dimensions.ymax;
    var part_to_init = Math.round(xmax*ymax/5000.0);
    particles = initParticles(part_to_init,getRadius(),xmax,ymax);
};

function overlapExists(part) {
    // checks the ensemble for particle overlaps
    // returns a bool
    var answer = false;
    for (i=0; i < particles.length; i++) {
	if (overlapExistsParticle(part, particles[i])) {
	    answer = true;
	    console.log("warning: overlap detected!");
	};
    };
    return answer;
}

function overlapExistsParticle(p1, p2) {
    // check if particles p1 and p2 overlap
    if (distParticles(p1,p2) < p1.radius + p2.radius) {
	return true;
    }
    console.log("particle distance = ", distParticles(p1,p2));
    return false;
};

function distParticles(p1, p2) {
    // return the distance between two particles
    var dx2 = Math.pow(p1.pos.x - p2.pos.x,2.0);
    var dy2 = Math.pow(p1.pos.y - p2.pos.y,2.0);
    console.log("dx2 =", dx2, "dy2 = ", dy2);
    return Math.pow(dx2 + dy2, 0.5);
};

function randomMove(part) {
    // translate a particle by a small random amount
    while (0 < part.pos.x - part.radius && part.pos.x + part.radius < xmax && 0 < part.pos.y - part.radius && part.pos.y + part.radius < ymax) {
	part.pos.x = part.pos.x + part.radius*Math.random();
	part.pos.y = part.pos.y + part.radius*Math.random();
    };
    return part;
}

//--------------------------------------------------------------------
//                  Visualisation functionality
//--------------------------------------------------------------------

function mouseinSimBox() {

    if (0 < mouseX && mouseX < xmax && 0 < mouseY && mouseY < ymax) {
	return true;
    };
    return false;
}

function mousePressed() {

    // Act on left mouse press
    if (mouseinSimBox()) {addParticle()};
}

function getSimBoxDimensions() {
    //get the dimension of the simbox
    var sb_ymax = $('#sim_container').outerHeight()*0.95;
    var sb_xmax = $('#sim_container').outerWidth()*0.97;
    return {
	ymax: sb_ymax,
        xmax: sb_xmax
    };
};

function getRadius() {
    return Math.random()*(r_upper-r_lower) + r_lower;
}
//--------------------------------------------------------------------
//                  UI event listners
//--------------------------------------------------------------------
// run button
$('#run').click(async function(){

    // run/pause button functionality
    console.log("You just clicked stream/pause!");
    paused_log = !(paused_log);
    if (paused_log) {
	$("#run").text('Run');
    }
    else {
	$("#run").text('Pause');
    }
});

// restart button
$('#restart').click(async function(){

    // restart button functionality
    console.log("You just clicked restart!");
    restartParticles();
    if (paused_log) {
	$("#run").text('Run');
    }
    else {
	$("#run").text('Pause');
    }
})

// full screen button
const target = $('#target')[0]; // Get DOM element from jQuery collection
$('#fullscreen').on('click', () => {
    console.log("fullscreen requested");
    if (screenfull.enabled) {
	screenfull.request(target);
    }
});
<|endoftext|>


<commit_before>#!/usr/bin/env node

var cli = require('cli'),
fs = require('fs'),
regen = require('./lib/regenerate.js'), // the file regeneration script
root = process.cwd(), // where serenity has been executed from.
convert = require('./lib/convert.js'),
config = require('./defaults.js'),
server = require('node-static'),
watchr = require('watchr'),
findit = require('findit');

cli.parse({
  port:  ['p', 'Listen on this port - overrides any config values', 'number', 4000],
  server: ['s', 'Start up a server for the static files', 'boolean', true],
  convert: ['c', 'Convert Jekyll (YAML with Liquid) site to Templr (JSON with EJS)','boolean',false]
});

var walk = function(dir,include,ignore,done) {
  var files = [];
  var finder = findit.find(root);

  finder.on('file',function(file,stat) {
    if ((!include || include.test(file)) && (!ignore || !ignore.test(file))) files.push(file);
  });
  finder.on('end',function() {
    cli.info('Finished reading directory '+dir);
    done(null,files);
  });
};

cli.main(function (args,options) {

  if (options.convert) {
    walk(root, new RegExp('.*\\.html$|.*_config\\.yml$'), new RegExp('.*/_site/.*'),function(err,list) {
      // list of all html files, not in _site
      if (err) cli.fatal('Error walking through files, please try again');
      if (list.length < 1) cli.fatal('Could not find any files to convert');
      convert.run(list);
    });
    return; // we dont want to boot up
  }

  if (options.server) {
    var file = new server.Server(root+'/_site', { cache: 1 });
    require('http').createServer(function (request, response) {
      cli.debug(request.method+': '+request.url);
      request.addListener('end', function () {
        file.serve(request, response).addListener('error', function(err) {
          cli.error('Error serving '+request.url+' - '+err.message);
        });
      });
    }).listen(options.port);
    cli.ok('Server started on port '+options.port);
  }

  // sort out config
  var usrconfig = {};
  try {
    usrconfig = require(root+'/serenity.js');
  }catch(e) {
    cli.info('Config error at '+root+'/serenity.js');
    cli.error(e);
  }

  for (var i in usrconfig) {
    if (!usrconfig.hasOwnProperty(i)) continue;
    config[i] = usrconfig[i]; // override defaults if specified
  }

  var reg = '';
  for (var i = 0; i < config.extensions.length;i++) {
    // build the extensions regex to see what files to generate
    reg+='.*\\.'+config.extensions[i]+(i<config.extensions.length-1 ? '$|' : '$');
  }
  // create the regex
  reg = new RegExp(reg);

  config.watchr.next = function(err,watchers) {
    cli.ok('Templr watching: ' + root);
  };
  config.watchr.listeners = {
    change: function(changeType,file,fileStat,oldStat) {
      cli.info('File changed, regenerating. '+file);
      walk(root,reg,null,function(err,files) {
        for (var i = 0; i < files.length; i++) {
          files[i] = files[i].replace(root,'.');
        }
        regen(files,config);
      });
    }
  };
  cli.info('Just booted. Regenerating.');
  walk(root,reg,null,function(err,files) {
    for (var i = 0; i < files.length; i++) {
      files[i] = files[i].replace(root,'.');
    }
    regen(files,config);
  });
  watchr.watch(config.watchr);

});<commit_msg>missed a rename<commit_after>#!/usr/bin/env node

var cli = require('cli'),
fs = require('fs'),
regen = require('./lib/regenerate.js'), // the file regeneration script
root = process.cwd(), // where serenity has been executed from.
convert = require('./lib/convert.js'),
config = require('./defaults.js'),
server = require('node-static'),
watchr = require('watchr'),
findit = require('findit');

cli.parse({
  port:  ['p', 'Listen on this port - overrides any config values', 'number', 4000],
  server: ['s', 'Start up a server for the static files', 'boolean', true],
  convert: ['c', 'Convert Jekyll (YAML with Liquid) site to Serenity (JSON with EJS)','boolean',false]
});

var walk = function(dir,include,ignore,done) {
  var files = [];
  var finder = findit.find(root);

  finder.on('file',function(file,stat) {
    if ((!include || include.test(file)) && (!ignore || !ignore.test(file))) files.push(file);
  });
  finder.on('end',function() {
    cli.info('Finished reading directory '+dir);
    done(null,files);
  });
};

cli.main(function (args,options) {

  if (options.convert) {
    walk(root, new RegExp('.*\\.html$|.*_config\\.yml$'), new RegExp('.*/_site/.*'),function(err,list) {
      // list of all html files, not in _site
      if (err) cli.fatal('Error walking through files, please try again');
      if (list.length < 1) cli.fatal('Could not find any files to convert');
      convert.run(list);
    });
    return; // we dont want to boot up
  }

  if (options.server) {
    var file = new server.Server(root+'/_site', { cache: 1 });
    require('http').createServer(function (request, response) {
      cli.debug(request.method+': '+request.url);
      request.addListener('end', function () {
        file.serve(request, response).addListener('error', function(err) {
          cli.error('Error serving '+request.url+' - '+err.message);
        });
      });
    }).listen(options.port);
    cli.ok('Server started on port '+options.port);
  }

  // sort out config
  var usrconfig = {};
  try {
    usrconfig = require(root+'/serenity.js');
  }catch(e) {
    cli.info('Config error at '+root+'/serenity.js');
    cli.error(e);
  }

  for (var i in usrconfig) {
    if (!usrconfig.hasOwnProperty(i)) continue;
    config[i] = usrconfig[i]; // override defaults if specified
  }

  var reg = '';
  for (var i = 0; i < config.extensions.length;i++) {
    // build the extensions regex to see what files to generate
    reg+='.*\\.'+config.extensions[i]+(i<config.extensions.length-1 ? '$|' : '$');
  }
  // create the regex
  reg = new RegExp(reg);

  config.watchr.next = function(err,watchers) {
    cli.ok('Serenity watching: ' + root);
  };
  config.watchr.listeners = {
    change: function(changeType,file,fileStat,oldStat) {
      cli.info('File changed, regenerating. '+file);
      walk(root,reg,null,function(err,files) {
        for (var i = 0; i < files.length; i++) {
          files[i] = files[i].replace(root,'.');
        }
        regen(files,config);
      });
    }
  };
  cli.info('Just booted. Regenerating.');
  walk(root,reg,null,function(err,files) {
    for (var i = 0; i < files.length; i++) {
      files[i] = files[i].replace(root,'.');
    }
    regen(files,config);
  });
  watchr.watch(config.watchr);

});<|endoftext|>


<commit_before>/**
 * Gets a quote from https://theysaidso.com/api/
 *
 * Written By: Jay Harris
 * Date Written: 22/07/2015
 */

 var wikiquote = require("./common/wikiquote.js");

// Define the 'regex' command matching criteria boolean
exports.match = function(text) {
    return text.startsWith('/quote');
};

// Give users help if they can't slaps
exports.help = function() {
    return '/quote <person>: Attempts to get a quote by said person';
};

//Gets a quote from the specified author and passes it into the callback
exports.quote = function(author, callback) {
    if (!author || author.length == 0) {
        callback("Um.. what do you expect me to do?");
        return;
    }

    wikiquote.getRandomQuote(author, function(quote) {
        callback('"' + quote.quote + '" - ' + quote.titles);
    }, function(message){
        callback("Couldn't find any quotes :'(");
    });
}

// Make the quoter do its thing
exports.run = function(api, event) {
    // Strip the command and obtain the author
    var author = event.body.substr(6);

    // get the quote
    exports.quote(author, function (result) {
        //Send the quote to Facebook
        api.sendMessage(result, event.thread_id);
    });
};
<commit_msg>Updates some of the comments<commit_after>/**
 * Gets a quote from https://theysaidso.com/api/
 *
 * Written By: Jay Harris
 * Date Written: 22/07/2015
 */

 var wikiquote = require("./common/wikiquote.js");

// Define the 'regex' command matching criteria boolean
exports.match = function(text) {
    return text.startsWith('/quote');
};

// Says surprisingly helpful things...
exports.help = function() {
    return '/quote <person>: Attempts to get a quote by said person';
};

//Gets a quote from the specified author and passes it into the callback
exports.quote = function(author, callback) {
    if (!author || author.length == 0) {
        callback("Um.. what do you expect me to do?");
        return;
    }

    wikiquote.getRandomQuote(author, function(quote) {
        callback('"' + quote.quote + '" - ' + quote.titles);
    }, function(message){
        callback("Couldn't find any quotes :'(");
    });
}

// Make the quoter do its thing
exports.run = function(api, event) {
    // Strip the command and obtain the author
    var author = event.body.substr(6);

    // get the quote
    exports.quote(author, function (result) {
        //Send the quote to Facebook
        api.sendMessage(result, event.thread_id);
    });
};
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2018 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @fileoverview Methods for dragging a bubble visually.
 * @author fenichel@google.com (Rachel Fenichel)
 */
'use strict';

goog.provide('Blockly.BubbleDragger');

/** @suppress {extraRequire} */
goog.require('Blockly.Bubble');
goog.require('Blockly.ComponentManager');
/** @suppress {extraRequire} */
goog.require('Blockly.constants');
goog.require('Blockly.Events');
/** @suppress {extraRequire} */
goog.require('Blockly.Events.CommentMove');
goog.require('Blockly.utils');
goog.require('Blockly.utils.Coordinate');

goog.requireType('Blockly.BlockDragSurfaceSvg');
goog.requireType('Blockly.IBubble');
goog.requireType('Blockly.WorkspaceSvg');

/**
 * Class for a bubble dragger.  It moves things on the bubble canvas around the
 * workspace when they are being dragged by a mouse or touch.  These can be
 * block comments, mutators, warnings, or workspace comments.
 * @param {!Blockly.IBubble} bubble The item on the bubble canvas to drag.
 * @param {!Blockly.WorkspaceSvg} workspace The workspace to drag on.
 * @constructor
 */
Blockly.BubbleDragger = function(bubble, workspace) {
  /**
   * The item on the bubble canvas that is being dragged.
   * @type {!Blockly.IBubble}
   * @private
   */
  this.draggingBubble_ = bubble;

  /**
   * The workspace on which the bubble is being dragged.
   * @type {!Blockly.WorkspaceSvg}
   * @private
   */
  this.workspace_ = workspace;

  /**
   * Which drag target the mouse pointer is over, if any.
   * @type {?Blockly.IDragTarget}
   * @private
   */
  this.dragTarget_ = null;

  /**
   * Whether the bubble would be deleted if dropped immediately.
   * @type {boolean}
   * @private
   */
  this.wouldDeleteBubble_ = false;

  /**
   * The location of the top left corner of the dragging bubble's body at the
   * beginning of the drag, in workspace coordinates.
   * @type {!Blockly.utils.Coordinate}
   * @private
   */
  this.startXY_ = this.draggingBubble_.getRelativeToSurfaceXY();

  /**
   * The drag surface to move bubbles to during a drag, or null if none should
   * be used.  Block dragging and bubble dragging use the same surface.
   * @type {Blockly.BlockDragSurfaceSvg}
   * @private
   */
  this.dragSurface_ =
      Blockly.utils.is3dSupported() && !!workspace.getBlockDragSurface() ?
      workspace.getBlockDragSurface() :
      null;
};

/**
 * Sever all links from this object.
 * @package
 * @suppress {checkTypes}
 */
Blockly.BubbleDragger.prototype.dispose = function() {
  this.draggingBubble_ = null;
  this.workspace_ = null;
  this.dragSurface_ = null;
};

/**
 * Start dragging a bubble.  This includes moving it to the drag surface.
 * @package
 */
Blockly.BubbleDragger.prototype.startBubbleDrag = function() {
  if (!Blockly.Events.getGroup()) {
    Blockly.Events.setGroup(true);
  }

  this.workspace_.setResizesEnabled(false);
  this.draggingBubble_.setAutoLayout(false);
  if (this.dragSurface_) {
    this.moveToDragSurface_();
  }

  this.draggingBubble_.setDragging && this.draggingBubble_.setDragging(true);
};

/**
 * Execute a step of bubble dragging, based on the given event.  Update the
 * display accordingly.
 * @param {!Event} e The most recent move event.
 * @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has
 *     moved from the position at the start of the drag, in pixel units.
 * @package
 */
Blockly.BubbleDragger.prototype.dragBubble = function(e, currentDragDeltaXY) {
  var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
  var newLoc = Blockly.utils.Coordinate.sum(this.startXY_, delta);
  this.draggingBubble_.moveDuringDrag(this.dragSurface_, newLoc);

  var oldDragTarget = this.dragTarget_;
  this.dragTarget_ = this.workspace_.getDragTarget(e);

  var oldWouldDeleteBubble = this.wouldDeleteBubble_;
  this.wouldDeleteBubble_ = this.shouldDelete_(this.dragTarget_);
  if (oldWouldDeleteBubble != this.wouldDeleteBubble_) {
    // Prevent unnecessary add/remove class calls.
    this.updateCursorDuringBubbleDrag_();
  }

  // Call drag enter/exit/over after wouldDeleteBlock is called in shouldDelete_
  if (this.dragTarget_ !== oldDragTarget) {
    oldDragTarget && oldDragTarget.onDragExit(this.draggingBubble_);
    this.dragTarget_ && this.dragTarget_.onDragEnter(this.draggingBubble_);
  }
  this.dragTarget_ && this.dragTarget_.onDragOver(this.draggingBubble_);
};

/**
 * Whether ending the drag would delete the bubble.
 * @param {?Blockly.IDragTarget} dragTarget The drag target that the bubblee is
 *     currently over.
 * @return {boolean} Whether dropping the bubble immediately would delete the
 *    block.
 * @private
 */
Blockly.BubbleDragger.prototype.shouldDelete_ = function(dragTarget) {
  if (dragTarget) {
    var componentManager = this.workspace_.getComponentManager();
    var isDeleteArea = componentManager.hasCapability(dragTarget.id,
        Blockly.ComponentManager.Capability.DELETE_AREA);
    if (isDeleteArea) {
      return (/** @type {!Blockly.IDeleteArea} */ (dragTarget))
          .wouldDelete(this.draggingBubble_, false);
    }
  }
  return false;
};

/**
 * Update the cursor (and possibly the trash can lid) to reflect whether the
 * dragging bubble would be deleted if released immediately.
 * @private
 */
Blockly.BubbleDragger.prototype.updateCursorDuringBubbleDrag_ = function() {
  this.draggingBubble_.setDeleteStyle(this.wouldDeleteBubble_);
};

/**
 * Finish a bubble drag and put the bubble back on the workspace.
 * @param {!Event} e The mouseup/touchend event.
 * @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has
 *     moved from the position at the start of the drag, in pixel units.
 * @package
 */
Blockly.BubbleDragger.prototype.endBubbleDrag = function(
    e, currentDragDeltaXY) {
  // Make sure internal state is fresh.
  this.dragBubble(e, currentDragDeltaXY);

  var preventMove = this.dragTarget_ &&
      this.dragTarget_.shouldPreventMove(this.draggingBubble_);
  if (preventMove) {
    var newLoc = this.startXY_;
  } else {
    var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
    var newLoc = Blockly.utils.Coordinate.sum(this.startXY_, delta);
  }
  // Move the bubble to its final location.
  this.draggingBubble_.moveTo(newLoc.x, newLoc.y);

  if (this.dragTarget_) {
    this.dragTarget_.onDrop(this.draggingBubble_);
  }

  if (this.wouldDeleteBubble_) {
    // Fire a move event, so we know where to go back to for an undo.
    this.fireMoveEvent_();
    this.draggingBubble_.dispose(false, true);
  } else {
    // Put everything back onto the bubble canvas.
    if (this.dragSurface_) {
      this.dragSurface_.clearAndHide(this.workspace_.getBubbleCanvas());
    }
    if (this.draggingBubble_.setDragging) {
      this.draggingBubble_.setDragging(false);
    }
    this.fireMoveEvent_();
  }
  this.workspace_.setResizesEnabled(true);

  Blockly.Events.setGroup(false);
};

/**
 * Fire a move event at the end of a bubble drag.
 * @private
 */
Blockly.BubbleDragger.prototype.fireMoveEvent_ = function() {
  if (this.draggingBubble_.isComment) {
    var event = new (Blockly.Events.get(Blockly.Events.COMMENT_MOVE))(
        /** @type {!Blockly.WorkspaceCommentSvg} */ (this.draggingBubble_));
    event.setOldCoordinate(this.startXY_);
    event.recordNew();
    Blockly.Events.fire(event);
  }
  // TODO (fenichel): move events for comments.
  return;
};

/**
 * Convert a coordinate object from pixels to workspace units, including a
 * correction for mutator workspaces.
 * This function does not consider differing origins.  It simply scales the
 * input's x and y values.
 * @param {!Blockly.utils.Coordinate} pixelCoord A coordinate with x and y
 *     values in CSS pixel units.
 * @return {!Blockly.utils.Coordinate} The input coordinate divided by the
 *     workspace scale.
 * @private
 */
Blockly.BubbleDragger.prototype.pixelsToWorkspaceUnits_ = function(pixelCoord) {
  var result = new Blockly.utils.Coordinate(
      pixelCoord.x / this.workspace_.scale,
      pixelCoord.y / this.workspace_.scale);
  if (this.workspace_.isMutator) {
    // If we're in a mutator, its scale is always 1, purely because of some
    // oddities in our rendering optimizations.  The actual scale is the same as
    // the scale on the parent workspace.
    // Fix that for dragging.
    var mainScale = this.workspace_.options.parentWorkspace.scale;
    result.scale(1 / mainScale);
  }
  return result;
};

/**
 * Move the bubble onto the drag surface at the beginning of a drag.  Move the
 * drag surface to preserve the apparent location of the bubble.
 * @private
 */
Blockly.BubbleDragger.prototype.moveToDragSurface_ = function() {
  this.draggingBubble_.moveTo(0, 0);
  this.dragSurface_.translateSurface(this.startXY_.x, this.startXY_.y);
  // Execute the move on the top-level SVG component.
  this.dragSurface_.setBlocksAndShow(this.draggingBubble_.getSvgRoot());
};
<commit_msg>Migrate core/bubble_dragger.js to ES6 const/let<commit_after>/**
 * @license
 * Copyright 2018 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @fileoverview Methods for dragging a bubble visually.
 * @author fenichel@google.com (Rachel Fenichel)
 */
'use strict';

goog.provide('Blockly.BubbleDragger');

/** @suppress {extraRequire} */
goog.require('Blockly.Bubble');
goog.require('Blockly.ComponentManager');
/** @suppress {extraRequire} */
goog.require('Blockly.constants');
goog.require('Blockly.Events');
/** @suppress {extraRequire} */
goog.require('Blockly.Events.CommentMove');
goog.require('Blockly.utils');
goog.require('Blockly.utils.Coordinate');

goog.requireType('Blockly.BlockDragSurfaceSvg');
goog.requireType('Blockly.IBubble');
goog.requireType('Blockly.WorkspaceSvg');

/**
 * Class for a bubble dragger.  It moves things on the bubble canvas around the
 * workspace when they are being dragged by a mouse or touch.  These can be
 * block comments, mutators, warnings, or workspace comments.
 * @param {!Blockly.IBubble} bubble The item on the bubble canvas to drag.
 * @param {!Blockly.WorkspaceSvg} workspace The workspace to drag on.
 * @constructor
 */
Blockly.BubbleDragger = function(bubble, workspace) {
  /**
   * The item on the bubble canvas that is being dragged.
   * @type {!Blockly.IBubble}
   * @private
   */
  this.draggingBubble_ = bubble;

  /**
   * The workspace on which the bubble is being dragged.
   * @type {!Blockly.WorkspaceSvg}
   * @private
   */
  this.workspace_ = workspace;

  /**
   * Which drag target the mouse pointer is over, if any.
   * @type {?Blockly.IDragTarget}
   * @private
   */
  this.dragTarget_ = null;

  /**
   * Whether the bubble would be deleted if dropped immediately.
   * @type {boolean}
   * @private
   */
  this.wouldDeleteBubble_ = false;

  /**
   * The location of the top left corner of the dragging bubble's body at the
   * beginning of the drag, in workspace coordinates.
   * @type {!Blockly.utils.Coordinate}
   * @private
   */
  this.startXY_ = this.draggingBubble_.getRelativeToSurfaceXY();

  /**
   * The drag surface to move bubbles to during a drag, or null if none should
   * be used.  Block dragging and bubble dragging use the same surface.
   * @type {Blockly.BlockDragSurfaceSvg}
   * @private
   */
  this.dragSurface_ =
      Blockly.utils.is3dSupported() && !!workspace.getBlockDragSurface() ?
      workspace.getBlockDragSurface() :
      null;
};

/**
 * Sever all links from this object.
 * @package
 * @suppress {checkTypes}
 */
Blockly.BubbleDragger.prototype.dispose = function() {
  this.draggingBubble_ = null;
  this.workspace_ = null;
  this.dragSurface_ = null;
};

/**
 * Start dragging a bubble.  This includes moving it to the drag surface.
 * @package
 */
Blockly.BubbleDragger.prototype.startBubbleDrag = function() {
  if (!Blockly.Events.getGroup()) {
    Blockly.Events.setGroup(true);
  }

  this.workspace_.setResizesEnabled(false);
  this.draggingBubble_.setAutoLayout(false);
  if (this.dragSurface_) {
    this.moveToDragSurface_();
  }

  this.draggingBubble_.setDragging && this.draggingBubble_.setDragging(true);
};

/**
 * Execute a step of bubble dragging, based on the given event.  Update the
 * display accordingly.
 * @param {!Event} e The most recent move event.
 * @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has
 *     moved from the position at the start of the drag, in pixel units.
 * @package
 */
Blockly.BubbleDragger.prototype.dragBubble = function(e, currentDragDeltaXY) {
  const delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
  const newLoc = Blockly.utils.Coordinate.sum(this.startXY_, delta);
  this.draggingBubble_.moveDuringDrag(this.dragSurface_, newLoc);

  const oldDragTarget = this.dragTarget_;
  this.dragTarget_ = this.workspace_.getDragTarget(e);

  const oldWouldDeleteBubble = this.wouldDeleteBubble_;
  this.wouldDeleteBubble_ = this.shouldDelete_(this.dragTarget_);
  if (oldWouldDeleteBubble != this.wouldDeleteBubble_) {
    // Prevent unnecessary add/remove class calls.
    this.updateCursorDuringBubbleDrag_();
  }

  // Call drag enter/exit/over after wouldDeleteBlock is called in shouldDelete_
  if (this.dragTarget_ !== oldDragTarget) {
    oldDragTarget && oldDragTarget.onDragExit(this.draggingBubble_);
    this.dragTarget_ && this.dragTarget_.onDragEnter(this.draggingBubble_);
  }
  this.dragTarget_ && this.dragTarget_.onDragOver(this.draggingBubble_);
};

/**
 * Whether ending the drag would delete the bubble.
 * @param {?Blockly.IDragTarget} dragTarget The drag target that the bubblee is
 *     currently over.
 * @return {boolean} Whether dropping the bubble immediately would delete the
 *    block.
 * @private
 */
Blockly.BubbleDragger.prototype.shouldDelete_ = function(dragTarget) {
  if (dragTarget) {
    const componentManager = this.workspace_.getComponentManager();
    const isDeleteArea = componentManager.hasCapability(dragTarget.id,
        Blockly.ComponentManager.Capability.DELETE_AREA);
    if (isDeleteArea) {
      return (/** @type {!Blockly.IDeleteArea} */ (dragTarget))
          .wouldDelete(this.draggingBubble_, false);
    }
  }
  return false;
};

/**
 * Update the cursor (and possibly the trash can lid) to reflect whether the
 * dragging bubble would be deleted if released immediately.
 * @private
 */
Blockly.BubbleDragger.prototype.updateCursorDuringBubbleDrag_ = function() {
  this.draggingBubble_.setDeleteStyle(this.wouldDeleteBubble_);
};

/**
 * Finish a bubble drag and put the bubble back on the workspace.
 * @param {!Event} e The mouseup/touchend event.
 * @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has
 *     moved from the position at the start of the drag, in pixel units.
 * @package
 */
Blockly.BubbleDragger.prototype.endBubbleDrag = function(
    e, currentDragDeltaXY) {
  // Make sure internal state is fresh.
  this.dragBubble(e, currentDragDeltaXY);

  const preventMove = this.dragTarget_ &&
      this.dragTarget_.shouldPreventMove(this.draggingBubble_);
  let newLoc;
  if (preventMove) {
    newLoc = this.startXY_;
  } else {
    const delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
    newLoc = Blockly.utils.Coordinate.sum(this.startXY_, delta);
  }
  // Move the bubble to its final location.
  this.draggingBubble_.moveTo(newLoc.x, newLoc.y);

  if (this.dragTarget_) {
    this.dragTarget_.onDrop(this.draggingBubble_);
  }

  if (this.wouldDeleteBubble_) {
    // Fire a move event, so we know where to go back to for an undo.
    this.fireMoveEvent_();
    this.draggingBubble_.dispose(false, true);
  } else {
    // Put everything back onto the bubble canvas.
    if (this.dragSurface_) {
      this.dragSurface_.clearAndHide(this.workspace_.getBubbleCanvas());
    }
    if (this.draggingBubble_.setDragging) {
      this.draggingBubble_.setDragging(false);
    }
    this.fireMoveEvent_();
  }
  this.workspace_.setResizesEnabled(true);

  Blockly.Events.setGroup(false);
};

/**
 * Fire a move event at the end of a bubble drag.
 * @private
 */
Blockly.BubbleDragger.prototype.fireMoveEvent_ = function() {
  if (this.draggingBubble_.isComment) {
    const event = new (Blockly.Events.get(Blockly.Events.COMMENT_MOVE))(
        /** @type {!Blockly.WorkspaceCommentSvg} */ (this.draggingBubble_));
    event.setOldCoordinate(this.startXY_);
    event.recordNew();
    Blockly.Events.fire(event);
  }
  // TODO (fenichel): move events for comments.
  return;
};

/**
 * Convert a coordinate object from pixels to workspace units, including a
 * correction for mutator workspaces.
 * This function does not consider differing origins.  It simply scales the
 * input's x and y values.
 * @param {!Blockly.utils.Coordinate} pixelCoord A coordinate with x and y
 *     values in CSS pixel units.
 * @return {!Blockly.utils.Coordinate} The input coordinate divided by the
 *     workspace scale.
 * @private
 */
Blockly.BubbleDragger.prototype.pixelsToWorkspaceUnits_ = function(pixelCoord) {
  const result = new Blockly.utils.Coordinate(
      pixelCoord.x / this.workspace_.scale,
      pixelCoord.y / this.workspace_.scale);
  if (this.workspace_.isMutator) {
    // If we're in a mutator, its scale is always 1, purely because of some
    // oddities in our rendering optimizations.  The actual scale is the same as
    // the scale on the parent workspace.
    // Fix that for dragging.
    const mainScale = this.workspace_.options.parentWorkspace.scale;
    result.scale(1 / mainScale);
  }
  return result;
};

/**
 * Move the bubble onto the drag surface at the beginning of a drag.  Move the
 * drag surface to preserve the apparent location of the bubble.
 * @private
 */
Blockly.BubbleDragger.prototype.moveToDragSurface_ = function() {
  this.draggingBubble_.moveTo(0, 0);
  this.dragSurface_.translateSurface(this.startXY_.x, this.startXY_.y);
  // Execute the move on the top-level SVG component.
  this.dragSurface_.setBlocksAndShow(this.draggingBubble_.getSvgRoot());
};
<|endoftext|>


<commit_before>var socketio;

function setKeydown() {
  document.addEventListener("keydown", function (e) {
    if (e.key.match(/^[a-z]$/)){
      var listeners = arguments.callee;
      socketio.emit("next");
      document.removeEventListener("keydown", listeners, false);
    }
  });
}

function showNext(result, colorize = true) {
  var state = getState(result);
  var element = document.getElementById("showNext");

  element.innerHTML = state.str;
  if (colorize){
    console.log(element.classList);
    if (element.classList.contains(state.symbol + "num") !== true){
      element.classList.remove("empty");
      element.classList.add(state.symbol + "num");
    }
  }
  else if (element.classList.contains("empty") === true){
    element.classList.add("empty");
  }
}

function roulette(result) {
  var first = window.setInterval(function() {
    showNext(Math.random() * 75 | 0 + 1, false);
  }, 50);

  var state = getState(result);
  var start = ((result - 1) / 15 | 0) * 15 + 1;
  var current = 0;

  window.setTimeout(function() {
    window.clearInterval(first);

    var second = window.setInterval(function() {
      showNext(start + current);
      current = (current + 1) % 15;
    }, 200);
    window.setTimeout(function() {
      window.clearInterval(second);
    }, 2000);
  }, 3000);

  window.setTimeout(function() {
    var third = window.setInterval(function() {
      showNext(start + current);
      if (start + current === result){
        window.clearInterval(third);
        setKeydown();
      }

      current = (current + 1) % 15;
    }, 500);
  }, 5000);
}

document.addEventListener('DOMContentLoaded', function() {
  socketio = io.connect("http://localhost:8080");

  socketio.on("overrun", function() {
    window.alert("これ以上回せません");
  });
  socketio.on("next", function(next) {
    roulette(next);
  });

  document.getElementById("next").addEventListener("click", function(ev) {
    socketio.emit("next");
  });

  document.getElementById("reset").addEventListener("click", function(ev) {
    document.getElementById("showNext").innerHTML = "";
    socketio.emit("reset");
  });

  setKeydown();
});
<commit_msg>クラスがemptyの時にempty追加してたので修正<commit_after>var socketio;

function setKeydown() {
  document.addEventListener("keydown", function (e) {
    if (e.key.match(/^[a-z]$/)){
      var listeners = arguments.callee;
      socketio.emit("next");
      document.removeEventListener("keydown", listeners, false);
    }
  });
}

function showNext(result, colorize = true) {
  var state = getState(result);
  var element = document.getElementById("showNext");

  element.innerHTML = state.str;
  if (colorize){
    console.log(element.classList);
    if (element.classList.contains(state.symbol + "num") !== true){
      element.classList.remove("empty");
      element.classList.add(state.symbol + "num");
    }
  }
  else if (element.classList.contains("empty") !== true){
    element.classList.add("empty");
  }
}

function roulette(result) {
  var first = window.setInterval(function() {
    showNext(Math.random() * 75 | 0 + 1, false);
  }, 50);

  var state = getState(result);
  var start = ((result - 1) / 15 | 0) * 15 + 1;
  var current = 0;

  window.setTimeout(function() {
    window.clearInterval(first);

    var second = window.setInterval(function() {
      showNext(start + current);
      current = (current + 1) % 15;
    }, 200);
    window.setTimeout(function() {
      window.clearInterval(second);
    }, 2000);
  }, 3000);

  window.setTimeout(function() {
    var third = window.setInterval(function() {
      showNext(start + current);
      if (start + current === result){
        window.clearInterval(third);
        setKeydown();
      }

      current = (current + 1) % 15;
    }, 500);
  }, 5000);
}

document.addEventListener('DOMContentLoaded', function() {
  socketio = io.connect("http://localhost:8080");

  socketio.on("overrun", function() {
    window.alert("これ以上回せません");
  });
  socketio.on("next", function(next) {
    roulette(next);
  });

  document.getElementById("next").addEventListener("click", function(ev) {
    socketio.emit("next");
  });

  document.getElementById("reset").addEventListener("click", function(ev) {
    document.getElementById("showNext").innerHTML = "";
    socketio.emit("reset");
  });

  setKeydown();
});
<|endoftext|>


<commit_before>var Shout = function() {
	var Loader = require('../loader.js');
	this.shouts = new Loader();
	this.shouts.load('data/shouts.json');
	this.shouts = this.shouts.data;
	this.prefixCmd = '@';
};

Shout.prototype = {
	handle: function(from, chan, message) {
		var irc = global.irc;
		var self = this;
		var userList = global.modules['userlist'];

		//match on all text block prefixed by the shout's prefix.
		var regShoutMatch = new RegExp(this.prefixCmd + '(\\S+)','gi');
		var shoutMatch;

		//Execute till the time there is a potential shouts to parse.
		while ((shoutMatch= regShoutMatch.exec(message)) !== null)
		{
			//Check if shouts exists..
			if (self.shouts[shoutMatch[1]] !== undefined)
			{
				//check if shout is directed to users x.
				var userMatch;
				if (userMatch = message.substring(regShoutMatch.lastIndex).match(/^\s+([\S]+)/i)) {
					//if userlist module is not loaded then send as a targeted shouts anyway...
					if (!(userList === undefined || userList.userExists(chan, userMatch[1]))) {
						userMatch = null;
					}
				}
				irc.client.say(chan, userMatch ?
					userMatch[1] + ": " + self.shouts[shoutMatch[1]] :
					self.shouts[shoutMatch[1]]);

			}
		}

		if (regShoutMatch.exec(message) === 'list'
		{
			for(var shout in self.shouts)
			{
				irc.client.say(chan, shout);
			}
		}
	}
};

module.exports = new Shout();
<commit_msg>Missing bracket in shouts module<commit_after>var Shout = function() {
	var Loader = require('../loader.js');
	this.shouts = new Loader();
	this.shouts.load('data/shouts.json');
	this.shouts = this.shouts.data;
	this.prefixCmd = '@';
};

Shout.prototype = {
	handle: function(from, chan, message) {
		var irc = global.irc;
		var self = this;
		var userList = global.modules['userlist'];

		//match on all text block prefixed by the shout's prefix.
		var regShoutMatch = new RegExp(this.prefixCmd + '(\\S+)','gi');
		var shoutMatch;

		//Execute till the time there is a potential shouts to parse.
		while ((shoutMatch= regShoutMatch.exec(message)) !== null)
		{
			//Check if shouts exists..
			if (self.shouts[shoutMatch[1]] !== undefined)
			{
				//check if shout is directed to users x.
				var userMatch;
				if (userMatch = message.substring(regShoutMatch.lastIndex).match(/^\s+([\S]+)/i)) {
					//if userlist module is not loaded then send as a targeted shouts anyway...
					if (!(userList === undefined || userList.userExists(chan, userMatch[1]))) {
						userMatch = null;
					}
				}
				irc.client.say(chan, userMatch ?
					userMatch[1] + ": " + self.shouts[shoutMatch[1]] :
					self.shouts[shoutMatch[1]]);

			}
		}

		if (regShoutMatch.exec(message) === 'list')
		{
			for(var shout in self.shouts)
			{
				irc.client.say(chan, shout);
			}
		}
	}
};

module.exports = new Shout();
<|endoftext|>


<commit_before>//https://github.com/visionmedia/express-resource

var checkAuthServ = require('./services/authorisations/check');

function csrf(req, res, next) {
	res.locals.token = req.session._csrf;
	next();
}

function setViewVars(req, res, next) {
	console.log('setViewVars');

	res.locals.allowAdmin = false;
	res.locals.user = req.user;

	if (req.user) {
		checkAuthServ.run(req.user, 'suggestion', 'manage', function (err, val) {
			console.log(err);
			res.locals.allowAdmin = val;
			return next();
		});
	} else {
		console.log('No user');
		return next();
	}
}

module.exports = function (app) {

	var controllers = require('./controllers/web');

	app.get('/', setViewVars, controllers.index);
	app.get('/videos', setViewVars, require('./controllers/web/videos').index);
	app.get('/videos/:video', setViewVars, require('./controllers/web/videos').show);
	app.get('/suggestions/new', csrf, setViewVars, require('./controllers/web/suggestions').new);

	app.namespace('/api/v1', function(){
		var videos =				require('./controllers/api/v1/videos');
		var suggestions =		require('./controllers/api/v1/suggestions');
		var tags =					require('./controllers/api/v1/tags');
		var urls =					require('./controllers/api/v1/urls');

		app.resource('videos', videos);
		app.get('/videos/search', videos.search);
		app.post('/videos/:video/mark_seen', videos.mark_seen);

		app.post('/suggestions', suggestions.create);
		app.patch('/suggestions/:suggestion/approve', suggestions.approve);

		app.resource('tags', tags);

		app.get('/urls', urls.show);
	});

	app.namespace('/admin', function() {
		app.get('/suggestions', setViewVars, require('./controllers/web/admin/suggestions').index);
	});

}

<commit_msg>Fixed missing route for suggestions get<commit_after>//https://github.com/visionmedia/express-resource

var checkAuthServ = require('./services/authorisations/check');

function csrf(req, res, next) {
	res.locals.token = req.session._csrf;
	next();
}

function setViewVars(req, res, next) {
	console.log('setViewVars');

	res.locals.allowAdmin = false;
	res.locals.user = req.user;

	if (req.user) {
		checkAuthServ.run(req.user, 'suggestion', 'manage', function (err, val) {
			console.log(err);
			res.locals.allowAdmin = val;
			return next();
		});
	} else {
		console.log('No user');
		return next();
	}
}

module.exports = function (app) {

	var controllers = require('./controllers/web');

	app.get('/', setViewVars, controllers.index);
	app.get('/videos', setViewVars, require('./controllers/web/videos').index);
	app.get('/videos/:video', setViewVars, require('./controllers/web/videos').show);
	app.get('/suggestions/new', csrf, setViewVars, require('./controllers/web/suggestions').new);

	app.namespace('/api/v1', function(){
		var videos =				require('./controllers/api/v1/videos');
		var suggestions =		require('./controllers/api/v1/suggestions');
		var tags =					require('./controllers/api/v1/tags');
		var urls =					require('./controllers/api/v1/urls');

		app.resource('videos', videos);
		app.get('/videos/search', videos.search);
		app.post('/videos/:video/mark_seen', videos.mark_seen);

		app.get('/suggestions', suggestions.index);
		app.post('/suggestions', suggestions.create);
		app.patch('/suggestions/:suggestion/approve', suggestions.approve);

		app.resource('tags', tags);

		app.get('/urls', urls.show);
	});

	app.namespace('/admin', function() {
		app.get('/suggestions', setViewVars, require('./controllers/web/admin/suggestions').index);
	});

}

<|endoftext|>


<commit_before>///////////////////////////////////////
//get requests
///////////////////////////////////////

app.get('/HV', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/HV.jade');
});

app.get('/GRIFFIN', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('detectors/GRIFFIN.jade');
});

app.get('/DAQ', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/DAQ.jade');
});

app.get('/PPG', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/PPG.jade');
});

app.get('/Clocks', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/Clock.jade');
});

app.get('/Filter', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/Filter.jade');
});

app.get('/MSCbuilder', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/MSCbuilder.jade');
});

///////////////////////////////////////
//post routes
///////////////////////////////////////

app.post('/postHV', function(req, res){

	spawn('odbedit', ['-c', "set /Equipment/HV-"+req.body.crateIndex+"/Variables/Demand["+req.body.chIndex+"] " + req.body.demandVoltage]);
	spawn('odbedit', ['-c', "set '/Equipment/HV-"+req.body.crateIndex+"/Settings/Ramp Up Speed["+req.body.chIndex+"]' " + req.body.voltageUp]);
	spawn('odbedit', ['-c', "set '/Equipment/HV-"+req.body.crateIndex+"/Settings/Ramp Down Speed["+req.body.chIndex+"]' " + req.body.voltageDown]);

	if(req.body.powerSwitch == 'off')
		spawn('odbedit', ['-c', "set /Equipment/HV-"+req.body.crateIndex+"/Settings/ChState["+req.body.chIndex+"] 0"]);
	else
		spawn('odbedit', ['-c', "set /Equipment/HV-"+req.body.crateIndex+"/Settings/ChState["+req.body.chIndex+"] 1"]);

	return res.redirect('/HV?crate=0&channel='+req.body.chName);
});

app.post('/registerCycle', function(req, res){
	var cycle = (req.body.cycleString) ? JSON.parse(req.body.cycleString) : null,
		i,
		steps = [],
		durations = [];

	//just load an existing cycle
	if(req.body.loadTarget != 'null'){
		spawn('odbedit', ['-c', "set /PPG/Current " + req.body.loadTarget]);
		return res.redirect('/PPG');
	}

	//delete an existing cycle
	if(req.body.deleteTarget != 'null'){
		spawn('odbedit', ['-c', "rm /PPG/Cycles/" + req.body.deleteTarget]);
		return res.redirect('/PPG');
	}

	//register a new cycle
	for(i=0; i<cycle.length; i++){
		steps[i] = parseInt(cycle[i].PPGcode, 10);
		durations[i] = parseInt(cycle[i].duration, 10);
	}

	spawn('odbedit', ['-c', "rm /PPG/Cycles/" + req.body.cycleName]);
	spawn('odbedit', ['-c', "mkdir /PPG/Cycles/" + req.body.cycleName]);

	spawn('odbedit', ['-c', "create int /PPG/Cycles/" + req.body.cycleName + "/PPGcodes[" + steps.length + "]"]);
	spawn('odbedit', ['-c', "create int /PPG/Cycles/" + req.body.cycleName + "/durations[" + steps.length + "]"]);
	for(i=0; i<cycle.length; i++){
		spawn('odbedit', ['-c', "set /PPG/Cycles/" + req.body.cycleName + "/PPGcodes["+ i +"]  " + Math.round(steps[i]) ]);
		spawn('odbedit', ['-c', "set /PPG/Cycles/" + req.body.cycleName + "/durations["+ i +"]  " + Math.round(durations[i]) ]);
	}

	if(req.body.applyCycle == 'on'){
		spawn('odbedit', ['-c', "set /PPG/Current " + req.body.cycleName]);
	}

	return res.redirect('/PPG');
});

app.post('/registerFilter', function(req, res){
	var filter = (req.body.filterString) ? JSON.parse(req.body.filterString) : null,
		odbManipulationFile = '',
		i, j,
		steps = [],
		durations = [];

	//just load an existing cycle
	if(req.body.loadTarget != 'null'){
		spawn('odbedit', ['-c', "set /Filter/Current " + req.body.loadTarget]);
		return res.redirect('/Filter');
	}

	//delete an existing cycle
	if(req.body.deleteTarget != 'null'){
		spawn('odbedit', ['-c', "rm /Filter/Filters/" + req.body.deleteTarget]);
		return res.redirect('/Filter');
	}

	//register a new filter - build file and run with execFile for most robust execution (spawn seems to create a race condition, consider removing).
	odbManipulationFile += 'odbedit -c "rm /Filter/Filters/' + req.body.filterName + '"\n';
	odbManipulationFile += 'odbedit -c "mkdir /Filter/Filters/' + req.body.filterName + '"\n';
	for(i=0; i<filter.length; i++){
		odbManipulationFile += 'odbedit -c "create string /Filter/Filters/' + req.body.filterName + '/orCondition'+i+'[' + filter[i].length + ']"\n';
		for(j=0; j<filter[i].length; j++){
			odbManipulationFile += 'odbedit -c "set /Filter/Filters/' + req.body.filterName + '/orCondition'+i + '['+j+'] ' + filter[i][j] + '"\n';
		}
	}

	fs.writeFile('odbManipulation.sh', odbManipulationFile, function(){
		fs.chmod('./odbManipulation.sh', '777', function(){
			execFile('./odbManipulation.sh', function(error, stdout, stderr){
				console.log('Writing ' + req.body.filterName + ' filter to ODB, process [error, stdout, stderr]:');
				console.log([error, stdout, stderr]);

				if(req.body.applyFilter == 'on'){
					spawn('odbedit', ['-c', "set /Filter/Current " + req.body.filterName]);
				}
			});
		});
	});

	return res.redirect('/Filter');

});

app.post('/updateClock', function(req, res){
	var ClockEnB = 0,
		powerOn,
		stepdown = parseInt(req.body.freqStepdown,10);

	//channel on / off
	for(i=0; i<6; i++){
		powerOn = req.body['eSATAtoggle' + i] == 1
		ClockEnB = ClockEnB | ((powerOn) ? (0xF << 4*i) : 0);
	}
	spawn('odbedit', ['-c', "set /Equipment/GRIF-Clk" + req.body.clockIndex + "/Variables/Output[0] " + ClockEnB]);

	//freq. stepdown
	if(stepdown && req.body.isMaster=='1'){
		for(i=0; i<8; i++){
			spawn('odbedit', ['-c', "set /Equipment/GRIF-Clk" + req.body.clockIndex + "/Variables/Output[" + (11+4*i) + "] " + stepdown]);
			spawn('odbedit', ['-c', "set /Equipment/GRIF-Clk" + req.body.clockIndex + "/Variables/Output[" + (12+4*i) + "] " + stepdown]);
		}
	}

	return res.redirect('/Clocks');
});

app.post('/toggleClock', function(req, res){
	spawn('odbedit', ['-c', "set /Equipment/GRIF-Clk" + req.body.clockIndex + "/Variables/Output[1] " + req.body['radio'+req.body.clockIndex] ]);

	return res.redirect('/Clocks');
});

app.post('/buildMSC', function(req, res){

	function configGRIFFINclover(index, suppressors){
		var names = [],
			MSC = [],
			masterChan = (index<9) ? 0 : 1,
			firstCollectorChan = ((index-1)%8)*2, //ie, collector channel of first (of 2) GRIF16s used for this clover.
			collectorChan,
			ADC,
			name, address,
			crystalPrefix = 'GRG' + ((index<10) ? '0'+index : index),
			color = ['B', 'G', 'R', 'W'],
			crystalSuffix = ['N00A', 'N00B'],
			vetoPrefix = 'GRS' + ((index<10) ? '0'+index : index),
			i,j,k;

		if(suppressors){
			//HPGe
			for(i=0; i<crystalSuffix.length; i++){
				for(j=0; j<color.length; j++){
					name = crystalPrefix + color[j] + crystalSuffix[i];

					collectorChan = firstCollectorChan + i;
					ADC = j;
					address = (masterChan << 12) | (collectorChan << 8) | ADC;

					names.push(name);
					MSC.push(address);
				}
			}

			//BGO
			for(j=0; j<color.length; j++){
				for(i=0; i<5; i++){
					name = vetoPrefix + color[j] + 'N0' + i + 'X';

					collectorChan = firstCollectorChan + ((j<2) ? 0 : 1);
					ADC = 5 + (j%2)*5+i;
					address = (masterChan << 12) | (collectorChan << 8) | ADC;

					names.push(name);
					MSC.push(address);
				}
			}

		} else{
			for(i=0; i<crystalSuffix.length; i++){
				for(j=0; j<color.length; j++){
					name = crystalPrefix + color[j] + crystalSuffix[i];

					collectorChan = firstCollectorChan;
					ADC = j + 4*i;
					address = (masterChan << 12) | (collectorChan << 8) | ADC;

					names.push(name);
					MSC.push(address);
				}
			}
		}

		return [names, MSC];
	}

	var test = configGRIFFINclover(1, true),
		i;

	for(i=0; i<test[0].length; i++){
		console.log(test[0][i] + ': ' + test[1][i].toString(16));
	}

	return res.redirect('/DAQ');

});

<commit_msg>building canonical MSC table builder<commit_after>///////////////////////////////////////
//get requests
///////////////////////////////////////

app.get('/HV', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/HV.jade');
});

app.get('/GRIFFIN', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('detectors/GRIFFIN.jade');
});

app.get('/DAQ', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/DAQ.jade');
});

app.get('/PPG', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/PPG.jade');
});

app.get('/Clocks', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/Clock.jade');
});

app.get('/Filter', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/Filter.jade');
});

app.get('/MSCbuilder', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/MSCbuilder.jade');
});

///////////////////////////////////////
//post routes
///////////////////////////////////////

app.post('/postHV', function(req, res){

	spawn('odbedit', ['-c', "set /Equipment/HV-"+req.body.crateIndex+"/Variables/Demand["+req.body.chIndex+"] " + req.body.demandVoltage]);
	spawn('odbedit', ['-c', "set '/Equipment/HV-"+req.body.crateIndex+"/Settings/Ramp Up Speed["+req.body.chIndex+"]' " + req.body.voltageUp]);
	spawn('odbedit', ['-c', "set '/Equipment/HV-"+req.body.crateIndex+"/Settings/Ramp Down Speed["+req.body.chIndex+"]' " + req.body.voltageDown]);

	if(req.body.powerSwitch == 'off')
		spawn('odbedit', ['-c', "set /Equipment/HV-"+req.body.crateIndex+"/Settings/ChState["+req.body.chIndex+"] 0"]);
	else
		spawn('odbedit', ['-c', "set /Equipment/HV-"+req.body.crateIndex+"/Settings/ChState["+req.body.chIndex+"] 1"]);

	return res.redirect('/HV?crate=0&channel='+req.body.chName);
});

app.post('/registerCycle', function(req, res){
	var cycle = (req.body.cycleString) ? JSON.parse(req.body.cycleString) : null,
		i,
		steps = [],
		durations = [];

	//just load an existing cycle
	if(req.body.loadTarget != 'null'){
		spawn('odbedit', ['-c', "set /PPG/Current " + req.body.loadTarget]);
		return res.redirect('/PPG');
	}

	//delete an existing cycle
	if(req.body.deleteTarget != 'null'){
		spawn('odbedit', ['-c', "rm /PPG/Cycles/" + req.body.deleteTarget]);
		return res.redirect('/PPG');
	}

	//register a new cycle
	for(i=0; i<cycle.length; i++){
		steps[i] = parseInt(cycle[i].PPGcode, 10);
		durations[i] = parseInt(cycle[i].duration, 10);
	}

	spawn('odbedit', ['-c', "rm /PPG/Cycles/" + req.body.cycleName]);
	spawn('odbedit', ['-c', "mkdir /PPG/Cycles/" + req.body.cycleName]);

	spawn('odbedit', ['-c', "create int /PPG/Cycles/" + req.body.cycleName + "/PPGcodes[" + steps.length + "]"]);
	spawn('odbedit', ['-c', "create int /PPG/Cycles/" + req.body.cycleName + "/durations[" + steps.length + "]"]);
	for(i=0; i<cycle.length; i++){
		spawn('odbedit', ['-c', "set /PPG/Cycles/" + req.body.cycleName + "/PPGcodes["+ i +"]  " + Math.round(steps[i]) ]);
		spawn('odbedit', ['-c', "set /PPG/Cycles/" + req.body.cycleName + "/durations["+ i +"]  " + Math.round(durations[i]) ]);
	}

	if(req.body.applyCycle == 'on'){
		spawn('odbedit', ['-c', "set /PPG/Current " + req.body.cycleName]);
	}

	return res.redirect('/PPG');
});

app.post('/registerFilter', function(req, res){
	var filter = (req.body.filterString) ? JSON.parse(req.body.filterString) : null,
		odbManipulationFile = '',
		i, j,
		steps = [],
		durations = [];

	//just load an existing cycle
	if(req.body.loadTarget != 'null'){
		spawn('odbedit', ['-c', "set /Filter/Current " + req.body.loadTarget]);
		return res.redirect('/Filter');
	}

	//delete an existing cycle
	if(req.body.deleteTarget != 'null'){
		spawn('odbedit', ['-c', "rm /Filter/Filters/" + req.body.deleteTarget]);
		return res.redirect('/Filter');
	}

	//register a new filter - build file and run with execFile for most robust execution (spawn seems to create a race condition, consider removing).
	odbManipulationFile += 'odbedit -c "rm /Filter/Filters/' + req.body.filterName + '"\n';
	odbManipulationFile += 'odbedit -c "mkdir /Filter/Filters/' + req.body.filterName + '"\n';
	for(i=0; i<filter.length; i++){
		odbManipulationFile += 'odbedit -c "create string /Filter/Filters/' + req.body.filterName + '/orCondition'+i+'[' + filter[i].length + ']"\n';
		for(j=0; j<filter[i].length; j++){
			odbManipulationFile += 'odbedit -c "set /Filter/Filters/' + req.body.filterName + '/orCondition'+i + '['+j+'] ' + filter[i][j] + '"\n';
		}
	}

	fs.writeFile('odbManipulation.sh', odbManipulationFile, function(){
		fs.chmod('./odbManipulation.sh', '777', function(){
			execFile('./odbManipulation.sh', function(error, stdout, stderr){
				console.log('Writing ' + req.body.filterName + ' filter to ODB, process [error, stdout, stderr]:');
				console.log([error, stdout, stderr]);

				if(req.body.applyFilter == 'on'){
					spawn('odbedit', ['-c', "set /Filter/Current " + req.body.filterName]);
				}
			});
		});
	});

	return res.redirect('/Filter');

});

app.post('/updateClock', function(req, res){
	var ClockEnB = 0,
		powerOn,
		stepdown = parseInt(req.body.freqStepdown,10);

	//channel on / off
	for(i=0; i<6; i++){
		powerOn = req.body['eSATAtoggle' + i] == 1
		ClockEnB = ClockEnB | ((powerOn) ? (0xF << 4*i) : 0);
	}
	spawn('odbedit', ['-c', "set /Equipment/GRIF-Clk" + req.body.clockIndex + "/Variables/Output[0] " + ClockEnB]);

	//freq. stepdown
	if(stepdown && req.body.isMaster=='1'){
		for(i=0; i<8; i++){
			spawn('odbedit', ['-c', "set /Equipment/GRIF-Clk" + req.body.clockIndex + "/Variables/Output[" + (11+4*i) + "] " + stepdown]);
			spawn('odbedit', ['-c', "set /Equipment/GRIF-Clk" + req.body.clockIndex + "/Variables/Output[" + (12+4*i) + "] " + stepdown]);
		}
	}

	return res.redirect('/Clocks');
});

app.post('/toggleClock', function(req, res){
	spawn('odbedit', ['-c', "set /Equipment/GRIF-Clk" + req.body.clockIndex + "/Variables/Output[1] " + req.body['radio'+req.body.clockIndex] ]);

	return res.redirect('/Clocks');
});

app.post('/buildMSC', function(req, res){

	function configGRIFFINclover(index, suppressors){
		var names = [],
			MSC = [],
			masterChan = (index<9) ? 0 : 1,
			firstCollectorChan = ((index-1)%8)*2, //ie, collector channel of first (of 2) GRIF16s used for this clover.
			collectorChan,
			ADC,
			name, address,
			crystalPrefix = 'GRG' + ((index<10) ? '0'+index : index),
			color = ['B', 'G', 'R', 'W'],
			crystalSuffix = ['N00A', 'N00B'],
			vetoPrefix = 'GRS' + ((index<10) ? '0'+index : index),
			i,j,k;

		if(suppressors){
			//HPGe
			for(i=0; i<crystalSuffix.length; i++){
				for(j=0; j<color.length; j++){
					name = crystalPrefix + color[j] + crystalSuffix[i];

					collectorChan = firstCollectorChan + i;
					ADC = j;
					address = (masterChan << 12) | (collectorChan << 8) | ADC;

					names.push(name);
					MSC.push(address);
				}
			}

			//BGO
			for(j=0; j<color.length; j++){
				for(i=0; i<5; i++){
					name = vetoPrefix + color[j] + 'N0' + i + 'X';

					collectorChan = firstCollectorChan + ((j<2) ? 0 : 1);
					ADC = 5 + (j%2)*5+i;
					address = (masterChan << 12) | (collectorChan << 8) | ADC;

					names.push(name);
					MSC.push(address);
				}
			}

		} else{
			for(i=0; i<crystalSuffix.length; i++){
				for(j=0; j<color.length; j++){
					name = crystalPrefix + color[j] + crystalSuffix[i];

					collectorChan = firstCollectorChan;
					ADC = j + 4*i;
					address = (masterChan << 12) | (collectorChan << 8) | ADC;

					names.push(name);
					MSC.push(address);
				}
			}
		}

		return [names, MSC];
	}

	function configSCEPTAR(US, DS, ZDS){
		var names = [],
			MSC = [],
			i;

		if(DS){
			for(i=1; i<11; i++){
				names.push('SEP' + ((i<10) ? '0'+i : i) + 'XN00X');
				MSC.push((2 << 12) | ( (4+Math.floor(i/4)) << 8) | i%4);
			}
		} else if(ZDS){
			names.push('ZDS01XN00X');
			MSC.push(0x2601);
		}

		if(US){
			for(i=11; i<21; i++){
				names.push('SEP' + i + 'XN00X');
				MSC.push((2 << 12) | ( ( 6 + Math.floor((i - 11 + 2)/4) ) << 8) | (i+3)%4);
			}
		}

		return [names, MSC];
	}

	var test = configSCEPTAR(true, true, false),
		i;

	for(i=0; i<test[0].length; i++){
		console.log(test[0][i] + ': ' + test[1][i].toString(16));
	}

	return res.redirect('/DAQ');

});

<|endoftext|>