<commit_before>var fs     = require('fs'),
    util   = require('util'),
    events = require('events'),
    Data   = require('./data.js').Data;

var rooms_dir = __dirname + '/../entities/areas/';
var l10n_dir  = __dirname + '/../l10n/scripts/rooms/';
var rooms_scripts_dir = __dirname + '/../scripts/rooms/';

var Rooms = function () {
	var self = this;
	self.areas = {};
	self.rooms = {};

	self.load = function (verbose, callback)
	{
		verbose = verbose || false;
		var log = function (message) { if (verbose) util.log(message); };
		var debug = function (message) { if (verbose) util.debug(message); };

		// Load all the areas into th game
		fs.readdir(rooms_dir, function (err, files)
		{
			if (err) {
				log('For some reason reading the entities directory failed for areas' + err);
				return;
			}

			for (i in files) {
				var file = rooms_dir + files[i];
				if (!fs.statSync(file).isDirectory()) continue;

				log("\tExamining area directory - " + file);
				var rooms = fs.readdirSync(file);

				// Check for an area manifest
				var has_manifest = false;
				for (j in rooms) {
					if (rooms[j].match(/manifest.yml/)) {
						has_manifest = true;
						break;
					}
				}

				if (!has_manifest) {
					log("\tFailed to load area - " + file + ' - No manifest');
					return;
				}

				try {
					var manifest = require('js-yaml').load(fs.readFileSync(file + '/manifest.yml').toString('utf8'));
				} catch (e) {
					log("\tError loading area manifest for " + file + ' - ' + e.message);
					return;
				}

				var areacount = 1;
				for (var area in manifest) {
					if (!areacount) {
						log("\tFound more than one area definition in the manifest for " + file + ' ... skipping');
						break;
					}

					if (!('title' in manifest[area])) {
						log("\tFailed loading area " + area + ', it has no title.');
						break;

					}
					self.areas[area] = manifest[area];
					log("\tLoading area " + self.areas[area].title + '...');
					areacount--;
				}

				// Load any room files
				for (j in rooms) {
					var room_file = file + '/' + rooms[j];
					//skip the manifest or any directories
					if (room_file.match(/manifest/)) continue;
					if (!fs.statSync(room_file).isFile()) continue;
					if (!room_file.match(/yml$/)) continue;

					// parse the room files
					try {
						var room_def = require('js-yaml').load(fs.readFileSync(room_file).toString('utf8'));
					} catch (e) {
						log("\t\tError loading room - " + room_file + ' - ' + e.message);
						continue;
					}

					// create and load the rooms
					for (var vnum in room_def) {
						var room = room_def[vnum];
						var validate = ['title', 'description', 'location'];

						var err = false;
						for (var v in validate) {
							if (!(validate[v] in room)) {
								log("\t\tError loading room in file " + room.location + ' - no ' + validate[v] + ' specified');
								err = true;
								break;
							}
						}

						if (err) {
							continue;
						}

						log("\t\tLoaded room " + room.location + '...');
						room.area = area;
						room.filename = room_file;
						room.file_index = vnum;
						room = new Room(room);
						self.rooms[room.getLocation()] = room;
					}
				}
			}

			if (callback) {
				callback();
			}
		});
	};

	/**
	 * Get a room at a specific location
	 * @param int location
	 * @return Room
	 */
	self.getAt = function (location)
	{
		return location in self.rooms ? self.rooms[location] : false;
	};

	/**
	 * Get an area
	 * @param string area
	 * @return object
	 */
	self.getArea = function (area)
	{
		return area in self.areas ? self.areas[area] : false;
	};

}

var Room = function (config)
{
	var self = this;

	self.title = '';
	self.description = '';
	self.exits = [];
	self.location = null;
	self.area = null;

	// these are only set after load, not on construction and is an array of vnums
	self.items = [];
	self.npcs  = [];
	self.filename = '';
	self.file_index = null;

	self.init = function (config)
	{
		self.title = config.title;
		self.description = config.description;
		self.location    = config.location;
		self.exits       = config.exits || [];
		self.area        = config.area;
		self.filename    = config.filename;
		self.file_index  = config.file_index;
		Data.loadListeners(config, l10n_dir, rooms_scripts_dir, Data.loadBehaviors(config, 'rooms/', self));
	};

	self.getLocation = function () { return self.location; };
	self.getArea = function () { return self.area; };
	self.getExits = function () { return self.exits; };
	self.getItems = function () { return self.items; };
	self.getNpcs = function () { return self.npcs; };

	/**
	 * Get the description, localized if possible
	 * @param string locale
	 * @return string
	 */
	self.getDescription = function (locale)
	{
		return typeof self.description === 'string' ?
			self.description :
			(locale in self.description ? self.description[locale] : 'UNTRANSLATED - Contact an admin');
	};

	/**
	 * Get the title, localized if possible
	 * @param string locale
	 * @return string
	 */
	self.getTitle = function (locale)
	{
		return typeof self.title === 'string' ?
			self.title :
			(locale in self.title ? self.title[locale] : 'UNTRANSLATED - Contact an admin');
	}

	/**
	 * Get the leave message for an exit, localized if possible
	 * @param object exit
	 * @param strign locale
	 * @return string
	 */
	self.getLeaveMessage = function (exit, locale)
	{
		return typeof exit.leave_message === 'string' ?
			self.leave_message :
			(locale in self.leave_message ? self.leave_message[locale] : 'UNTRANSLATED - Contact an admin');
	};

	/**
	 * Add an item to the quicklookup array for items
	 * @param string uid
	 */
	self.addItem = function (uid)
	{
		self.items.push(uid)
	};

	/**
	 * Remove an item from the room
	 * @param string uid
	 */
	self.removeItem = function (uid)
	{
		self.items = self.items.filter(function (i) { return i !== uid; });
	};

	/**
	 * Add an npc to the quicklookup array for npcs
	 * @param string uid
	 */
	self.addNpc = function (uid)
	{
		self.npcs.push(uid)
	};

	/**
	 * Remove an npc from the room
	 * @param string uid
	 */
	self.removeNpc = function (uid)
	{
		self.npcs = self.npcs.filter(function (i) { return i !== uid; });
	};

	/**
	 * Check to see if an npc is in the room
	 * @param string uid
	 * @return boolean
	 */
	self.hasNpc = function (uid)
	{
		return self.npcs.some(function (i) { return i === uid; });
	};

	/**
	 * Check to see if an npc is in the room
	 * @param string uid
	 * @return boolean
	 */
	self.hasItem = function (uid)
	{
		return self.items.some(function (i) { return i === uid; });
	};

	/**
	 * Flatten into a simple structure
	 * @return object
	 */
	self.flatten = function ()
	{
		return {
			title: self.getTitle('en'),
			description: self.getDescription('en'),
			exits: self.exits,
			location: self.location,
			area: self.area
		};
	};

	/**
	 * Get a full object of the room
	 * @return object
	 */
	self.stringify = function ()
	{
		return {
			title: self.title,
			description: self.description,
			exits: self.exits,
			location: self.location,
			area: self.area
		};
	};

	self.init(config);
};
util.inherits(Room, events.EventEmitter);

exports.Rooms = Rooms;
<commit_msg>Now rooms load and pull in their own area attribute or set it to the (probably ugly) area if there is none present in the roomfile.<commit_after>var fs     = require('fs'),
    util   = require('util'),
    events = require('events'),
    Data   = require('./data.js').Data;

var rooms_dir = __dirname + '/../entities/areas/';
var l10n_dir  = __dirname + '/../l10n/scripts/rooms/';
var rooms_scripts_dir = __dirname + '/../scripts/rooms/';

var Rooms = function () {
	var self = this;
	self.areas = {};
	self.rooms = {};

	self.load = function (verbose, callback)
	{
		verbose = verbose || false;
		var log = function (message) { if (verbose) util.log(message); };
		var debug = function (message) { if (verbose) util.debug(message); };

		// Load all the areas into th game
		fs.readdir(rooms_dir, function (err, files)
		{
			if (err) {
				log('For some reason reading the entities directory failed for areas' + err);
				return;
			}

			for (i in files) {
				var file = rooms_dir + files[i];
				if (!fs.statSync(file).isDirectory()) continue;

				log("\tExamining area directory - " + file);
				var rooms = fs.readdirSync(file);

				// Check for an area manifest
				var has_manifest = false;
				for (j in rooms) {
					if (rooms[j].match(/manifest.yml/)) {
						has_manifest = true;
						break;
					}
				}

				if (!has_manifest) {
					log("\tFailed to load area - " + file + ' - No manifest');
					return;
				}

				try {
					var manifest = require('js-yaml').load(fs.readFileSync(file + '/manifest.yml').toString('utf8'));
				} catch (e) {
					log("\tError loading area manifest for " + file + ' - ' + e.message);
					return;
				}

				var areacount = 1;
				for (var area in manifest) {
					if (!areacount) {
						log("\tFound more than one area definition in the manifest for " + file + ' ... skipping');
						break;
					}

					if (!('title' in manifest[area])) {
						log("\tFailed loading area " + area + ', it has no title.');
						break;

					}
					self.areas[area] = manifest[area];
					log("\tLoading area " + self.areas[area].title + '...');
					areacount--;
				}

				// Load any room files
				for (j in rooms) {
					var room_file = file + '/' + rooms[j];
					//skip the manifest or any directories
					if (room_file.match(/manifest/)) continue;
					if (!fs.statSync(room_file).isFile()) continue;
					if (!room_file.match(/yml$/)) continue;

					// parse the room files
					try {
						var room_def = require('js-yaml').load(fs.readFileSync(room_file).toString('utf8'));
					} catch (e) {
						log("\t\tError loading room - " + room_file + ' - ' + e.message);
						continue;
					}

					// create and load the rooms
					for (var vnum in room_def) {
						var room = room_def[vnum];
						var validate = ['title', 'description', 'location'];

						var err = false;
						for (var v in validate) {
							if (!(validate[v] in room)) {
								log("\t\tError loading room in file " + room.location + ' - no ' + validate[v] + ' specified');
								err = true;
								break;
							}
						}

						if (err) {
							continue;
						}

						log("\t\tLoaded room " + room.location + '...');
						room.area = room.area || area
						room.filename = room_file;
						room.file_index = vnum;
						room = new Room(room);
						self.rooms[room.getLocation()] = room;
					}
				}
			}

			if (callback) {
				callback();
			}
		});
	};

	/**
	 * Get a room at a specific location
	 * @param int location
	 * @return Room
	 */
	self.getAt = function (location)
	{
		return location in self.rooms ? self.rooms[location] : false;
	};

	/**
	 * Get an area
	 * @param string area
	 * @return object
	 */
	self.getArea = function (area)
	{
		return area in self.areas ? self.areas[area] : false;
	};

}

var Room = function (config)
{
	var self = this;

	self.title = '';
	self.description = '';
	self.exits = [];
	self.location = null;
	self.area = null;

	// these are only set after load, not on construction and is an array of vnums
	self.items = [];
	self.npcs  = [];
	self.filename = '';
	self.file_index = null;

	self.init = function (config)
	{
		self.title = config.title;
		self.description = config.description;
		self.location    = config.location;
		self.exits       = config.exits || [];
		self.area        = config.area;
		self.filename    = config.filename;
		self.file_index  = config.file_index;
		Data.loadListeners(config, l10n_dir, rooms_scripts_dir, Data.loadBehaviors(config, 'rooms/', self));
	};

	self.getLocation = function () { return self.location; };
	self.getArea = function () { return self.area; };
	self.getExits = function () { return self.exits; };
	self.getItems = function () { return self.items; };
	self.getNpcs = function () { return self.npcs; };

	/**
	 * Get the description, localized if possible
	 * @param string locale
	 * @return string
	 */
	self.getDescription = function (locale)
	{
		return typeof self.description === 'string' ?
			self.description :
			(locale in self.description ? self.description[locale] : 'UNTRANSLATED - Contact an admin');
	};

	/**
	 * Get the title, localized if possible
	 * @param string locale
	 * @return string
	 */
	self.getTitle = function (locale)
	{
		return typeof self.title === 'string' ?
			self.title :
			(locale in self.title ? self.title[locale] : 'UNTRANSLATED - Contact an admin');
	}

	/**
	 * Get the leave message for an exit, localized if possible
	 * @param object exit
	 * @param strign locale
	 * @return string
	 */
	self.getLeaveMessage = function (exit, locale)
	{
		return typeof exit.leave_message === 'string' ?
			self.leave_message :
			(locale in self.leave_message ? self.leave_message[locale] : 'UNTRANSLATED - Contact an admin');
	};

	/**
	 * Add an item to the quicklookup array for items
	 * @param string uid
	 */
	self.addItem = function (uid)
	{
		self.items.push(uid)
	};

	/**
	 * Remove an item from the room
	 * @param string uid
	 */
	self.removeItem = function (uid)
	{
		self.items = self.items.filter(function (i) { return i !== uid; });
	};

	/**
	 * Add an npc to the quicklookup array for npcs
	 * @param string uid
	 */
	self.addNpc = function (uid)
	{
		self.npcs.push(uid)
	};

	/**
	 * Remove an npc from the room
	 * @param string uid
	 */
	self.removeNpc = function (uid)
	{
		self.npcs = self.npcs.filter(function (i) { return i !== uid; });
	};

	/**
	 * Check to see if an npc is in the room
	 * @param string uid
	 * @return boolean
	 */
	self.hasNpc = function (uid)
	{
		return self.npcs.some(function (i) { return i === uid; });
	};

	/**
	 * Check to see if an npc is in the room
	 * @param string uid
	 * @return boolean
	 */
	self.hasItem = function (uid)
	{
		return self.items.some(function (i) { return i === uid; });
	};

	/**
	 * Flatten into a simple structure
	 * @return object
	 */
	self.flatten = function ()
	{
		return {
			title: self.getTitle('en'),
			description: self.getDescription('en'),
			exits: self.exits,
			location: self.location,
			area: self.area
		};
	};

	/**
	 * Get a full object of the room
	 * @return object
	 */
	self.stringify = function ()
	{
		return {
			title: self.title,
			description: self.description,
			exits: self.exits,
			location: self.location,
			area: self.area
		};
	};

	self.init(config);
};
util.inherits(Room, events.EventEmitter);

exports.Rooms = Rooms;
<|endoftext|>


<commit_before>(function(sc) {
  "use strict";

  sc.lang = {};
  sc.libs = {};

  function SCScript(fn) {
    return sc.lang.main.run(fn);
  }

  SCScript.VERSION = sc.VERSION;

  SCScript.install = function(installer) {
    installer(sc);
    return SCScript;
  };

  SCScript.stdout = function(msg) {
    console.log(msg);
    return SCScript;
  };

  SCScript.stderr = function(msg) {
    console.error(msg);
    return SCScript;
  };

  SCScript.tokenize = function(source, opts) {
    return sc.lang.compiler.tokenize(source, opts);
  };

  SCScript.parse = function(source, opts) {
    return sc.lang.compiler.parse(source, opts);
  };

  SCScript.compile = function(source, opts) {
    return sc.lang.compiler.compile(source, opts);
  };

  global.SCScript = sc.SCScript = SCScript;
})(sc);
<commit_msg>:muscle: add namespace `sc.config`<commit_after>(function(sc) {
  "use strict";

  sc.lang = {};
  sc.libs = {};
  sc.config = {};

  function SCScript(fn) {
    return sc.lang.main.run(fn);
  }

  SCScript.VERSION = sc.VERSION;

  SCScript.install = function(installer) {
    installer(sc);
    return SCScript;
  };

  SCScript.stdout = function(msg) {
    console.log(msg);
    return SCScript;
  };

  SCScript.stderr = function(msg) {
    console.error(msg);
    return SCScript;
  };

  SCScript.tokenize = function(source, opts) {
    return sc.lang.compiler.tokenize(source, opts);
  };

  SCScript.parse = function(source, opts) {
    return sc.lang.compiler.parse(source, opts);
  };

  SCScript.compile = function(source, opts) {
    return sc.lang.compiler.compile(source, opts);
  };

  global.SCScript = sc.SCScript = SCScript;
})(sc);
<|endoftext|>


<commit_before>"use strict";

function UFOs(container,data_url){

	//scene elements, I wouldn't mess with these if you are trying to work with this
	var scene, camera, renderer, cube;
	//Mess with these if you don't want a full screen visualization
	var WIDTH  = window.innerWidth;
	var HEIGHT = window.innerHeight;

	var MAXWIDTH = 928, MAXHEIGHT = 592;
	var jsonloader = new THREE.JSONLoader();
	//SECTION INITIALIZATION
	function init(container) {
		scene = new THREE.Scene();
		initCamera();
		initRenderer();
		initCube();
		container.body.appendChild(renderer.domElement);
		addMouseHandler(renderer.domElement);
		render();
	}
	function resize(){
		WIDTH  = window.innerWidth;
		HEIGHT = window.innerHeight
		renderer.setSize(WIDTH, HEIGHT);
	}
	function initCamera() {
		camera = new THREE.PerspectiveCamera(70, WIDTH / HEIGHT, 1, 10000);
		camera.position.set(0,-500,500);
		camera.lookAt(scene.position);
	}

	function initRenderer() {
		renderer = new THREE.WebGLRenderer({ antialias: true });
		renderer.setSize(WIDTH, HEIGHT);
		window.renderer = renderer;
	}
	function initCube() {
                var loader = new THREE.TextureLoader();

                var texture = loader.load("usmap.gif");
		var material = new THREE.MeshPhongMaterial({map:texture});
		material.bumpMap =texture;

		material.bumpScale = 22;
		cube = new THREE.Mesh(new THREE.CubeGeometry(MAXWIDTH,MAXHEIGHT, 2), material);
		var light = new THREE.DirectionalLight( 0xffffff );
		light.position.set( 1, 1, 1).normalize();
		scene.add(light);
		scene.add(cube);
	}
	var ufos = [];
	var counter = 0;
      var ufo_geometry = new THREE.TorusGeometry(25,5,25,50);
      var ufo_material = new THREE.MeshBasicMaterial({
				color: 0xff0000
			});
	function addUFO(x,y){
			counter++;
      var ufo = new THREE.Mesh(ufo_geometry,ufo_material);

			ufo.name = counter.toString();
			cube.add(ufo);
		  ufo.position.set(-928/2 +x,592/2 -y,400);
			ufos.push(ufo);
	}
	function animateUFO(ufo){
			ufo.completelyAnimated = false;
			ufo.ival = setInterval(function(){
				ufo.position.z-=3;
				if(ufo.position.z <=75)
				{
					clearInterval(ufo.ival);
				}
			},20);
	}
	this.startAnimation = function(){
			ufos.forEach(function(ufo){
					animateUFO(ufo);
			});
	}
	function addUFOPercent(x,y){
			addUFO(x*MAXWIDTH, y*MAXHEIGHT);
	}

	function clearUFOs()
	{
			ufos.forEach(function(ufo){
				scene.remove(ufo);
			});
	}

	//END INITIALIZATION

	function render(){
                renderer.render(scene, camera);
                requestAnimationFrame(render);
	}

	//Function Calls

	init(container);
	this.addUFO = addUFO;
	this.clearUFOs = clearUFOs;
	this.resize = resize;
	this.addUFOPercent = addUFOPercent;

	this.destroy = function(){
			renderer.domElement.parentNode.removeChild(renderer.domElement);
	}

	var mouseDown = false,mouseX,mouseY;
	// kept all of these at the end so they're out of the way.
	function onMouseMove(e) {

        e.preventDefault();

        var deltaX = e.clientX - mouseX,
            deltaY = e.clientY - mouseY;
        mouseX = e.clientX;
        mouseY = e.clientY;

        if (mouseDown) {
			rotateScene(deltaX,deltaY);
			moveScene(deltaX, deltaY);
        }
    }
    function onMouseUp(evt) {
        evt.preventDefault();

        mouseDown = false;
    }
	function onMouseDown(evt){
		evt.preventDefault();
		mouseDown = true;
	}

    function addMouseHandler(canvas) {
    canvas.addEventListener('mousemove', function (e) {
        onMouseMove(e);
    }, false);
    canvas.addEventListener('mousedown', function (e) {
        onMouseDown(e);
    }, false);
    canvas.addEventListener('mouseup', function (e) {
        onMouseUp(e);
    }, false);
}
	function rotateScene(deltaX,deltaY){
		cube.rotation.z -= deltaX/100;
	}
    function moveScene(deltaX, deltaY) {
					camera.position.z += deltaY;
					camera.rotation.x-=deltaY/360;

	}
}
<commit_msg>random colors<commit_after>"use strict";

function UFOs(container,data_url){

	//scene elements, I wouldn't mess with these if you are trying to work with this
	var scene, camera, renderer, cube;
	//Mess with these if you don't want a full screen visualization
	var WIDTH  = window.innerWidth;
	var HEIGHT = window.innerHeight;

	var MAXWIDTH = 928, MAXHEIGHT = 592;
	var jsonloader = new THREE.JSONLoader();
	//SECTION INITIALIZATION
	function init(container) {
		scene = new THREE.Scene();
		initCamera();
		initRenderer();
		initCube();
		container.body.appendChild(renderer.domElement);
		addMouseHandler(renderer.domElement);
		render();
	}
	function resize(){
		WIDTH  = window.innerWidth;
		HEIGHT = window.innerHeight
		renderer.setSize(WIDTH, HEIGHT);
	}
	function initCamera() {
		camera = new THREE.PerspectiveCamera(70, WIDTH / HEIGHT, 1, 10000);
		camera.position.set(0,-500,500);
		camera.lookAt(scene.position);
	}

	function initRenderer() {
		renderer = new THREE.WebGLRenderer({ antialias: true });
		renderer.setSize(WIDTH, HEIGHT);
		window.renderer = renderer;
	}
	function initCube() {
                var loader = new THREE.TextureLoader();

                var texture = loader.load("usmap.gif");
		var material = new THREE.MeshPhongMaterial({map:texture});
		material.bumpMap =texture;

		material.bumpScale = 22;
		cube = new THREE.Mesh(new THREE.CubeGeometry(MAXWIDTH,MAXHEIGHT, 2), material);
		var light = new THREE.DirectionalLight( 0xffffff );
		light.position.set( 1, 1, 1).normalize();
		scene.add(light);
		scene.add(cube);
	}
	var ufos = [];
	var counter = 0;
      var ufo_geometry = new THREE.TorusGeometry(25,5,25,50);

	function addUFO(x,y){
			counter++;
      var ufo = new THREE.Mesh(ufo_geometry,ufo_material);
			var ufo_material = new THREE.MeshBasicMaterial({color: Math.random()%0xffffff,opacity:.6});
			ufo.name = counter.toString();
			cube.add(ufo);
		  ufo.position.set(-928/2 +x,592/2 -y,400);
			ufos.push(ufo);
	}
	function animateUFO(ufo){
			ufo.completelyAnimated = false;
			ufo.ival = setInterval(function(){
				ufo.position.z-=3;
				if(ufo.position.z <=75)
				{
					clearInterval(ufo.ival);
				}
			},20);
	}
	this.startAnimation = function(){
			ufos.forEach(function(ufo){
					animateUFO(ufo);
			});
	}
	function addUFOPercent(x,y){
			addUFO(x*MAXWIDTH, y*MAXHEIGHT);
	}

	function clearUFOs()
	{
			ufos.forEach(function(ufo){
				scene.remove(ufo);
			});
	}

	//END INITIALIZATION

	function render(){
                renderer.render(scene, camera);
                requestAnimationFrame(render);
	}

	//Function Calls

	init(container);
	this.addUFO = addUFO;
	this.clearUFOs = clearUFOs;
	this.resize = resize;
	this.addUFOPercent = addUFOPercent;

	this.destroy = function(){
			renderer.domElement.parentNode.removeChild(renderer.domElement);
	}

	var mouseDown = false,mouseX,mouseY;
	// kept all of these at the end so they're out of the way.
	function onMouseMove(e) {

        e.preventDefault();

        var deltaX = e.clientX - mouseX,
            deltaY = e.clientY - mouseY;
        mouseX = e.clientX;
        mouseY = e.clientY;

        if (mouseDown) {
			rotateScene(deltaX,deltaY);
			moveScene(deltaX, deltaY);
        }
    }
    function onMouseUp(evt) {
        evt.preventDefault();

        mouseDown = false;
    }
	function onMouseDown(evt){
		evt.preventDefault();
		mouseDown = true;
	}

    function addMouseHandler(canvas) {
    canvas.addEventListener('mousemove', function (e) {
        onMouseMove(e);
    }, false);
    canvas.addEventListener('mousedown', function (e) {
        onMouseDown(e);
    }, false);
    canvas.addEventListener('mouseup', function (e) {
        onMouseUp(e);
    }, false);
}
	function rotateScene(deltaX,deltaY){
		cube.rotation.z -= deltaX/100;
	}
    function moveScene(deltaX, deltaY) {
					camera.position.z += deltaY;
					camera.rotation.x-=deltaY/360;

	}
}
<|endoftext|>


<commit_before>/*
  Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import { Syntax } from 'estraverse';
import Map from 'es6-map';

import Reference from './reference';
import Variable from './variable';
import Definition from './definition';
import assert from 'assert';

function isStrictScope(scope, block, isMethodDefinition, useDirective) {
    var body, i, iz, stmt, expr;

    // When upper scope is exists and strict, inner scope is also strict.
    if (scope.upper && scope.upper.isStrict) {
        return true;
    }

    // ArrowFunctionExpression's scope is always strict scope.
    if (block.type === Syntax.ArrowFunctionExpression) {
        return true;
    }

    if (isMethodDefinition) {
        return true;
    }

    if (scope.type === 'class' || scope.type === 'module') {
        return true;
    }

    if (scope.type === 'block' || scope.type === 'switch') {
        return false;
    }

    if (scope.type === 'function') {
        body = block.body;
    } else if (scope.type === 'global') {
        body = block;
    } else {
        return false;
    }

    // Search 'use strict' directive.
    if (useDirective) {
        for (i = 0, iz = body.body.length; i < iz; ++i) {
            stmt = body.body[i];
            if (stmt.type !== 'DirectiveStatement') {
                break;
            }
            if (stmt.raw === '"use strict"' || stmt.raw === '\'use strict\'') {
                return true;
            }
        }
    } else {
        for (i = 0, iz = body.body.length; i < iz; ++i) {
            stmt = body.body[i];
            if (stmt.type !== Syntax.ExpressionStatement) {
                break;
            }
            expr = stmt.expression;
            if (expr.type !== Syntax.Literal || typeof expr.value !== 'string') {
                break;
            }
            if (expr.raw != null) {
                if (expr.raw === '"use strict"' || expr.raw === '\'use strict\'') {
                    return true;
                }
            } else {
                if (expr.value === 'use strict') {
                    return true;
                }
            }
        }
    }
    return false;
}

function registerScope(scopeManager, scope) {
    var scopes;

    scopeManager.scopes.push(scope);

    scopes = scopeManager.__nodeToScope.get(scope.block);
    if (scopes) {
        scopes.push(scope);
    } else {
        scopeManager.__nodeToScope.set(scope.block, [ scope ]);
    }
}

/* Special Scope types. */
const SCOPE_NORMAL = 0;
const SCOPE_MODULE = 1;
const SCOPE_FUNCTION_EXPRESSION_NAME = 2;
const SCOPE_TDZ = 3;

/**
 * @class Scope
 */
export default class Scope {
    constructor(scopeManager, upperScope, block, isMethodDefinition, scopeType) {
        /**
         * One of 'catch', 'with', 'function', 'global' or 'block'.
         * @member {String} Scope#type
         */
        this.type =
            (scopeType === SCOPE_TDZ) ? 'TDZ' :
            (scopeType === SCOPE_MODULE) ? 'module' :
            (block.type === Syntax.BlockStatement) ? 'block' :
            (block.type === Syntax.SwitchStatement) ? 'switch' :
            (block.type === Syntax.FunctionExpression || block.type === Syntax.FunctionDeclaration || block.type === Syntax.ArrowFunctionExpression) ? 'function' :
            (block.type === Syntax.CatchClause) ? 'catch' :
            (block.type === Syntax.ForInStatement || block.type === Syntax.ForOfStatement || block.type === Syntax.ForStatement) ? 'for' :
            (block.type === Syntax.WithStatement) ? 'with' :
            (block.type === Syntax.ClassExpression || block.type === Syntax.ClassDeclaration) ? 'class' : 'global';
         /**
         * The scoped {@link Variable}s of this scope, as { Variable.name
         * : Variable }.
         * @member {Map} Scope#set
         */
        this.set = new Map();
        /**
         * The tainted variables of this scope, as { Variable.name :
         * boolean }.
         * @member {Map} Scope#taints */
        this.taints = new Map();
        /**
         * Generally, through the lexical scoping of JS you can always know
         * which variable an identifier in the source code refers to. There are
         * a few exceptions to this rule. With 'global' and 'with' scopes you
         * can only decide at runtime which variable a reference refers to.
         * Moreover, if 'eval()' is used in a scope, it might introduce new
         * bindings in this or its prarent scopes.
         * All those scopes are considered 'dynamic'.
         * @member {boolean} Scope#dynamic
         */
        this.dynamic = this.type === 'global' || this.type === 'with';
        /**
         * A reference to the scope-defining syntax node.
         * @member {esprima.Node} Scope#block
         */
        this.block = block;
         /**
         * The {@link Reference|references} that are not resolved with this scope.
         * @member {Reference[]} Scope#through
         */
        this.through = [];
         /**
         * The scoped {@link Variable}s of this scope. In the case of a
         * 'function' scope this includes the automatic argument arguments as
         * its first element, as well as all further formal arguments.
         * @member {Variable[]} Scope#variables
         */
        this.variables = [];
         /**
         * Any variable {@link Reference|reference} found in this scope. This
         * includes occurrences of local variables as well as variables from
         * parent scopes (including the global scope). For local variables
         * this also includes defining occurrences (like in a 'var' statement).
         * In a 'function' scope this does not include the occurrences of the
         * formal parameter in the parameter list.
         * @member {Reference[]} Scope#references
         */
        this.references = [];

         /**
         * For 'global' and 'function' scopes, this is a self-reference. For
         * other scope types this is the variableScope value of the
         * parent scope.
         * @member {Scope} Scope#variableScope
         */
        this.variableScope =
            (this.type === 'global' || this.type === 'function' || this.type === 'module') ? this : upperScope.variableScope;
         /**
         * Whether this scope is created by a FunctionExpression.
         * @member {boolean} Scope#functionExpressionScope
         */
        this.functionExpressionScope = false;
         /**
         * Whether this is a scope that contains an 'eval()' invocation.
         * @member {boolean} Scope#directCallToEvalScope
         */
        this.directCallToEvalScope = false;
         /**
         * @member {boolean} Scope#thisFound
         */
        this.thisFound = false;

        this.__left = [];

        if (scopeType === SCOPE_FUNCTION_EXPRESSION_NAME) {
            this.__define(block.id,
                    new Definition(
                        Variable.FunctionName,
                        block.id,
                        block,
                        null,
                        null,
                        null
                    ));
            this.functionExpressionScope = true;
        } else {
            // section 9.2.13, FunctionDeclarationInstantiation.
            // NOTE Arrow functions never have an arguments objects.
            if (this.type === 'function' && this.block.type !== Syntax.ArrowFunctionExpression) {
                this.__defineArguments();
            }

            if (block.type === Syntax.FunctionExpression && block.id) {
                upperScope = scopeManager.__nestFunctionExpressionNameScope(block, isMethodDefinition);
            }
        }

         /**
         * Reference to the parent {@link Scope|scope}.
         * @member {Scope} Scope#upper
         */
        this.upper = upperScope;
         /**
         * Whether 'use strict' is in effect in this scope.
         * @member {boolean} Scope#isStrict
         */
        this.isStrict = isStrictScope(this, block, isMethodDefinition, scopeManager.__useDirective());

         /**
         * List of nested {@link Scope}s.
         * @member {Scope[]} Scope#childScopes
         */
        this.childScopes = [];
        if (this.upper) {
            this.upper.childScopes.push(this);
        }

        registerScope(scopeManager, this);
    }

    __close(scopeManager) {
        var i, iz, ref, current, implicit, info;

        // Because if this is global environment, upper is null
        if (!this.dynamic || scopeManager.__isOptimistic()) {
            // static resolve
            for (i = 0, iz = this.__left.length; i < iz; ++i) {
                ref = this.__left[i];
                if (!this.__resolve(ref)) {
                    this.__delegateToUpperScope(ref);
                }
            }
        } else {
            // this is "global" / "with" / "function with eval" environment
            if (this.type === 'with') {
                for (i = 0, iz = this.__left.length; i < iz; ++i) {
                    ref = this.__left[i];
                    ref.tainted = true;
                    this.__delegateToUpperScope(ref);
                }
            } else {
                for (i = 0, iz = this.__left.length; i < iz; ++i) {
                    // notify all names are through to global
                    ref = this.__left[i];
                    current = this;
                    do {
                        current.through.push(ref);
                        current = current.upper;
                    } while (current);
                }
            }
        }

        this.__left = null;
        return this.upper;
    }

    __resolve(ref) {
        var variable, name;
        name = ref.identifier.name;
        if (this.set.has(name)) {
            variable = this.set.get(name);
            variable.references.push(ref);
            variable.stack = variable.stack && ref.from.variableScope === this.variableScope;
            if (ref.tainted) {
                variable.tainted = true;
                this.taints.set(variable.name, true);
            }
            ref.resolved = variable;
            return true;
        }
        return false;
    }

    __delegateToUpperScope(ref) {
        if (this.upper) {
            this.upper.__left.push(ref);
        }
        this.through.push(ref);
    }

    __defineGeneric(name, set, variables, node, def) {
        var variable;

        variable = set.get(name);
        if (!variable) {
            variable = new Variable(name, this);
            set.set(name, variable);
            variables.push(variable);
        }

        if (def) {
            variable.defs.push(def);
        }
        if (node) {
            variable.identifiers.push(node);
        }
    }

    __defineArguments() {
        this.__defineGeneric(
                'arguments',
                this.set,
                this.variables,
                null,
                null);
        this.taints.set('arguments', true);
    }

    __defineImplicit(node, def) {
        if (node && node.type === Syntax.Identifier) {
            this.__defineGeneric(
                    node.name,
                    this.implicit.set,
                    this.implicit.variables,
                    node,
                    def);
        }
    }

    __define(node, def) {
        if (node && node.type === Syntax.Identifier) {
            this.__defineGeneric(
                    node.name,
                    this.set,
                    this.variables,
                    node,
                    def);
        }
    }

    __referencing(node, assign, writeExpr, maybeImplicitGlobal, partial) {
        var ref;
        // because Array element may be null
        if (node && node.type === Syntax.Identifier) {
            ref = new Reference(node, this, assign || Reference.READ, writeExpr, maybeImplicitGlobal, !!partial);
            this.references.push(ref);
            this.__left.push(ref);
        }
    }

    __detectEval() {
        var current;
        current = this;
        this.directCallToEvalScope = true;
        do {
            current.dynamic = true;
            current = current.upper;
        } while (current);
    }

    __detectThis() {
        this.thisFound = true;
    }

    isClosed() {
        return this.__left === null;
    }

    /**
     * returns resolved {Reference}
     * @method Scope#resolve
     * @param {Esprima.Identifier} ident - identifier to be resolved.
     * @return {Reference}
     */
    resolve(ident) {
        var ref, i, iz;
        assert(this.__isClosed(), 'Scope should be closed.');
        assert(ident.type === Syntax.Identifier, 'Target should be identifier.');
        for (i = 0, iz = this.references.length; i < iz; ++i) {
            ref = this.references[i];
            if (ref.identifier === ident) {
                return ref;
            }
        }
        return null;
    }

    /**
     * returns this scope is static
     * @method Scope#isStatic
     * @return {boolean}
     */
    isStatic() {
        return !this.dynamic;
    }

    /**
     * returns this scope has materialized arguments
     * @method Scope#isArgumentsMaterialized
     * @return {boolean}
     */
    isArgumentsMaterialized() {
        // TODO(Constellation)
        // We can more aggressive on this condition like this.
        //
        // function t() {
        //     // arguments of t is always hidden.
        //     function arguments() {
        //     }
        // }
        var variable;

        // This is not function scope
        if (this.type !== 'function') {
            return true;
        }

        if (this.functionExpressionScope) {
            return false;
        }

        if (this.block.type === Syntax.ArrowFunctionExpression) {
            return false;
        }

        if (!this.isStatic()) {
            return true;
        }

        variable = this.set.get('arguments');
        assert(variable, 'Always have arguments variable.');
        return variable.tainted || variable.references.length  !== 0;
    }

    /**
     * returns this scope has materialized `this` reference
     * @method Scope#isThisMaterialized
     * @return {boolean}
     */
    isThisMaterialized() {
        // This is not function scope
        if (this.type !== 'function') {
            return true;
        }
        if (!this.isStatic()) {
            return true;
        }
        return this.thisFound;
    }

    isUsedName(name) {
        if (this.set.has(name)) {
            return true;
        }
        for (var i = 0, iz = this.through.length; i < iz; ++i) {
            if (this.through[i].identifier.name === name) {
                return true;
            }
        }
        return false;
    }
}

export class GlobalScope extends Scope {
    constructor(scopeManager, block) {
        super(scopeManager, null, block, false, Scope.SCOPE_NORMAL);
        this.implicit = {
            set: new Map(),
            variables: [],
            /**
            * List of {@link Reference}s that are left to be resolved (i.e. which
            * need to be linked to the variable they refer to).
            * @member {Reference[]} Scope#implicit#left
            */
            left: []
        };
    }

    __close(scopeManager) {
        let implicit = [];
        for (let i = 0, iz = this.__left.length; i < iz; ++i) {
            let ref = this.__left[i];
            if (ref.__maybeImplicitGlobal && !this.set.has(ref.identifier.name)) {
                implicit.push(ref.__maybeImplicitGlobal);
            }
        }

        // create an implicit global variable from assignment expression
        for (let i = 0, iz = implicit.length; i < iz; ++i) {
            let info = implicit[i];
            this.__defineImplicit(info.pattern,
                    new Definition(
                        Variable.ImplicitGlobalVariable,
                        info.pattern,
                        info.node,
                        null,
                        null,
                        null
                    ));

        }

        this.implicit.left = this.__left;

        return super.__close(scopeManager);
    }
}

Scope.SCOPE_NORMAL = SCOPE_NORMAL;
Scope.SCOPE_MODULE = SCOPE_MODULE;
Scope.SCOPE_FUNCTION_EXPRESSION_NAME = SCOPE_FUNCTION_EXPRESSION_NAME;
Scope.SCOPE_TDZ = SCOPE_TDZ;

/* vim: set sw=4 ts=4 et tw=80 : */
<commit_msg>Fix __isClosed member<commit_after>/*
  Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import { Syntax } from 'estraverse';
import Map from 'es6-map';

import Reference from './reference';
import Variable from './variable';
import Definition from './definition';
import assert from 'assert';

function isStrictScope(scope, block, isMethodDefinition, useDirective) {
    var body, i, iz, stmt, expr;

    // When upper scope is exists and strict, inner scope is also strict.
    if (scope.upper && scope.upper.isStrict) {
        return true;
    }

    // ArrowFunctionExpression's scope is always strict scope.
    if (block.type === Syntax.ArrowFunctionExpression) {
        return true;
    }

    if (isMethodDefinition) {
        return true;
    }

    if (scope.type === 'class' || scope.type === 'module') {
        return true;
    }

    if (scope.type === 'block' || scope.type === 'switch') {
        return false;
    }

    if (scope.type === 'function') {
        body = block.body;
    } else if (scope.type === 'global') {
        body = block;
    } else {
        return false;
    }

    // Search 'use strict' directive.
    if (useDirective) {
        for (i = 0, iz = body.body.length; i < iz; ++i) {
            stmt = body.body[i];
            if (stmt.type !== 'DirectiveStatement') {
                break;
            }
            if (stmt.raw === '"use strict"' || stmt.raw === '\'use strict\'') {
                return true;
            }
        }
    } else {
        for (i = 0, iz = body.body.length; i < iz; ++i) {
            stmt = body.body[i];
            if (stmt.type !== Syntax.ExpressionStatement) {
                break;
            }
            expr = stmt.expression;
            if (expr.type !== Syntax.Literal || typeof expr.value !== 'string') {
                break;
            }
            if (expr.raw != null) {
                if (expr.raw === '"use strict"' || expr.raw === '\'use strict\'') {
                    return true;
                }
            } else {
                if (expr.value === 'use strict') {
                    return true;
                }
            }
        }
    }
    return false;
}

function registerScope(scopeManager, scope) {
    var scopes;

    scopeManager.scopes.push(scope);

    scopes = scopeManager.__nodeToScope.get(scope.block);
    if (scopes) {
        scopes.push(scope);
    } else {
        scopeManager.__nodeToScope.set(scope.block, [ scope ]);
    }
}

/* Special Scope types. */
const SCOPE_NORMAL = 0;
const SCOPE_MODULE = 1;
const SCOPE_FUNCTION_EXPRESSION_NAME = 2;
const SCOPE_TDZ = 3;

/**
 * @class Scope
 */
export default class Scope {
    constructor(scopeManager, upperScope, block, isMethodDefinition, scopeType) {
        /**
         * One of 'catch', 'with', 'function', 'global' or 'block'.
         * @member {String} Scope#type
         */
        this.type =
            (scopeType === SCOPE_TDZ) ? 'TDZ' :
            (scopeType === SCOPE_MODULE) ? 'module' :
            (block.type === Syntax.BlockStatement) ? 'block' :
            (block.type === Syntax.SwitchStatement) ? 'switch' :
            (block.type === Syntax.FunctionExpression || block.type === Syntax.FunctionDeclaration || block.type === Syntax.ArrowFunctionExpression) ? 'function' :
            (block.type === Syntax.CatchClause) ? 'catch' :
            (block.type === Syntax.ForInStatement || block.type === Syntax.ForOfStatement || block.type === Syntax.ForStatement) ? 'for' :
            (block.type === Syntax.WithStatement) ? 'with' :
            (block.type === Syntax.ClassExpression || block.type === Syntax.ClassDeclaration) ? 'class' : 'global';
         /**
         * The scoped {@link Variable}s of this scope, as { Variable.name
         * : Variable }.
         * @member {Map} Scope#set
         */
        this.set = new Map();
        /**
         * The tainted variables of this scope, as { Variable.name :
         * boolean }.
         * @member {Map} Scope#taints */
        this.taints = new Map();
        /**
         * Generally, through the lexical scoping of JS you can always know
         * which variable an identifier in the source code refers to. There are
         * a few exceptions to this rule. With 'global' and 'with' scopes you
         * can only decide at runtime which variable a reference refers to.
         * Moreover, if 'eval()' is used in a scope, it might introduce new
         * bindings in this or its prarent scopes.
         * All those scopes are considered 'dynamic'.
         * @member {boolean} Scope#dynamic
         */
        this.dynamic = this.type === 'global' || this.type === 'with';
        /**
         * A reference to the scope-defining syntax node.
         * @member {esprima.Node} Scope#block
         */
        this.block = block;
         /**
         * The {@link Reference|references} that are not resolved with this scope.
         * @member {Reference[]} Scope#through
         */
        this.through = [];
         /**
         * The scoped {@link Variable}s of this scope. In the case of a
         * 'function' scope this includes the automatic argument arguments as
         * its first element, as well as all further formal arguments.
         * @member {Variable[]} Scope#variables
         */
        this.variables = [];
         /**
         * Any variable {@link Reference|reference} found in this scope. This
         * includes occurrences of local variables as well as variables from
         * parent scopes (including the global scope). For local variables
         * this also includes defining occurrences (like in a 'var' statement).
         * In a 'function' scope this does not include the occurrences of the
         * formal parameter in the parameter list.
         * @member {Reference[]} Scope#references
         */
        this.references = [];

         /**
         * For 'global' and 'function' scopes, this is a self-reference. For
         * other scope types this is the variableScope value of the
         * parent scope.
         * @member {Scope} Scope#variableScope
         */
        this.variableScope =
            (this.type === 'global' || this.type === 'function' || this.type === 'module') ? this : upperScope.variableScope;
         /**
         * Whether this scope is created by a FunctionExpression.
         * @member {boolean} Scope#functionExpressionScope
         */
        this.functionExpressionScope = false;
         /**
         * Whether this is a scope that contains an 'eval()' invocation.
         * @member {boolean} Scope#directCallToEvalScope
         */
        this.directCallToEvalScope = false;
         /**
         * @member {boolean} Scope#thisFound
         */
        this.thisFound = false;

        this.__left = [];

        if (scopeType === SCOPE_FUNCTION_EXPRESSION_NAME) {
            this.__define(block.id,
                    new Definition(
                        Variable.FunctionName,
                        block.id,
                        block,
                        null,
                        null,
                        null
                    ));
            this.functionExpressionScope = true;
        } else {
            // section 9.2.13, FunctionDeclarationInstantiation.
            // NOTE Arrow functions never have an arguments objects.
            if (this.type === 'function' && this.block.type !== Syntax.ArrowFunctionExpression) {
                this.__defineArguments();
            }

            if (block.type === Syntax.FunctionExpression && block.id) {
                upperScope = scopeManager.__nestFunctionExpressionNameScope(block, isMethodDefinition);
            }
        }

         /**
         * Reference to the parent {@link Scope|scope}.
         * @member {Scope} Scope#upper
         */
        this.upper = upperScope;
         /**
         * Whether 'use strict' is in effect in this scope.
         * @member {boolean} Scope#isStrict
         */
        this.isStrict = isStrictScope(this, block, isMethodDefinition, scopeManager.__useDirective());

         /**
         * List of nested {@link Scope}s.
         * @member {Scope[]} Scope#childScopes
         */
        this.childScopes = [];
        if (this.upper) {
            this.upper.childScopes.push(this);
        }

        registerScope(scopeManager, this);
    }

    __close(scopeManager) {
        var i, iz, ref, current, implicit, info;

        // Because if this is global environment, upper is null
        if (!this.dynamic || scopeManager.__isOptimistic()) {
            // static resolve
            for (i = 0, iz = this.__left.length; i < iz; ++i) {
                ref = this.__left[i];
                if (!this.__resolve(ref)) {
                    this.__delegateToUpperScope(ref);
                }
            }
        } else {
            // this is "global" / "with" / "function with eval" environment
            if (this.type === 'with') {
                for (i = 0, iz = this.__left.length; i < iz; ++i) {
                    ref = this.__left[i];
                    ref.tainted = true;
                    this.__delegateToUpperScope(ref);
                }
            } else {
                for (i = 0, iz = this.__left.length; i < iz; ++i) {
                    // notify all names are through to global
                    ref = this.__left[i];
                    current = this;
                    do {
                        current.through.push(ref);
                        current = current.upper;
                    } while (current);
                }
            }
        }

        this.__left = null;
        return this.upper;
    }

    __resolve(ref) {
        var variable, name;
        name = ref.identifier.name;
        if (this.set.has(name)) {
            variable = this.set.get(name);
            variable.references.push(ref);
            variable.stack = variable.stack && ref.from.variableScope === this.variableScope;
            if (ref.tainted) {
                variable.tainted = true;
                this.taints.set(variable.name, true);
            }
            ref.resolved = variable;
            return true;
        }
        return false;
    }

    __delegateToUpperScope(ref) {
        if (this.upper) {
            this.upper.__left.push(ref);
        }
        this.through.push(ref);
    }

    __defineGeneric(name, set, variables, node, def) {
        var variable;

        variable = set.get(name);
        if (!variable) {
            variable = new Variable(name, this);
            set.set(name, variable);
            variables.push(variable);
        }

        if (def) {
            variable.defs.push(def);
        }
        if (node) {
            variable.identifiers.push(node);
        }
    }

    __defineArguments() {
        this.__defineGeneric(
                'arguments',
                this.set,
                this.variables,
                null,
                null);
        this.taints.set('arguments', true);
    }

    __defineImplicit(node, def) {
        if (node && node.type === Syntax.Identifier) {
            this.__defineGeneric(
                    node.name,
                    this.implicit.set,
                    this.implicit.variables,
                    node,
                    def);
        }
    }

    __define(node, def) {
        if (node && node.type === Syntax.Identifier) {
            this.__defineGeneric(
                    node.name,
                    this.set,
                    this.variables,
                    node,
                    def);
        }
    }

    __referencing(node, assign, writeExpr, maybeImplicitGlobal, partial) {
        var ref;
        // because Array element may be null
        if (node && node.type === Syntax.Identifier) {
            ref = new Reference(node, this, assign || Reference.READ, writeExpr, maybeImplicitGlobal, !!partial);
            this.references.push(ref);
            this.__left.push(ref);
        }
    }

    __detectEval() {
        var current;
        current = this;
        this.directCallToEvalScope = true;
        do {
            current.dynamic = true;
            current = current.upper;
        } while (current);
    }

    __detectThis() {
        this.thisFound = true;
    }

    __isClosed() {
        return this.__left === null;
    }

    /**
     * returns resolved {Reference}
     * @method Scope#resolve
     * @param {Esprima.Identifier} ident - identifier to be resolved.
     * @return {Reference}
     */
    resolve(ident) {
        var ref, i, iz;
        assert(this.__isClosed(), 'Scope should be closed.');
        assert(ident.type === Syntax.Identifier, 'Target should be identifier.');
        for (i = 0, iz = this.references.length; i < iz; ++i) {
            ref = this.references[i];
            if (ref.identifier === ident) {
                return ref;
            }
        }
        return null;
    }

    /**
     * returns this scope is static
     * @method Scope#isStatic
     * @return {boolean}
     */
    isStatic() {
        return !this.dynamic;
    }

    /**
     * returns this scope has materialized arguments
     * @method Scope#isArgumentsMaterialized
     * @return {boolean}
     */
    isArgumentsMaterialized() {
        // TODO(Constellation)
        // We can more aggressive on this condition like this.
        //
        // function t() {
        //     // arguments of t is always hidden.
        //     function arguments() {
        //     }
        // }
        var variable;

        // This is not function scope
        if (this.type !== 'function') {
            return true;
        }

        if (this.functionExpressionScope) {
            return false;
        }

        if (this.block.type === Syntax.ArrowFunctionExpression) {
            return false;
        }

        if (!this.isStatic()) {
            return true;
        }

        variable = this.set.get('arguments');
        assert(variable, 'Always have arguments variable.');
        return variable.tainted || variable.references.length  !== 0;
    }

    /**
     * returns this scope has materialized `this` reference
     * @method Scope#isThisMaterialized
     * @return {boolean}
     */
    isThisMaterialized() {
        // This is not function scope
        if (this.type !== 'function') {
            return true;
        }
        if (!this.isStatic()) {
            return true;
        }
        return this.thisFound;
    }

    isUsedName(name) {
        if (this.set.has(name)) {
            return true;
        }
        for (var i = 0, iz = this.through.length; i < iz; ++i) {
            if (this.through[i].identifier.name === name) {
                return true;
            }
        }
        return false;
    }
}

export class GlobalScope extends Scope {
    constructor(scopeManager, block) {
        super(scopeManager, null, block, false, Scope.SCOPE_NORMAL);
        this.implicit = {
            set: new Map(),
            variables: [],
            /**
            * List of {@link Reference}s that are left to be resolved (i.e. which
            * need to be linked to the variable they refer to).
            * @member {Reference[]} Scope#implicit#left
            */
            left: []
        };
    }

    __close(scopeManager) {
        let implicit = [];
        for (let i = 0, iz = this.__left.length; i < iz; ++i) {
            let ref = this.__left[i];
            if (ref.__maybeImplicitGlobal && !this.set.has(ref.identifier.name)) {
                implicit.push(ref.__maybeImplicitGlobal);
            }
        }

        // create an implicit global variable from assignment expression
        for (let i = 0, iz = implicit.length; i < iz; ++i) {
            let info = implicit[i];
            this.__defineImplicit(info.pattern,
                    new Definition(
                        Variable.ImplicitGlobalVariable,
                        info.pattern,
                        info.node,
                        null,
                        null,
                        null
                    ));

        }

        this.implicit.left = this.__left;

        return super.__close(scopeManager);
    }
}

Scope.SCOPE_NORMAL = SCOPE_NORMAL;
Scope.SCOPE_MODULE = SCOPE_MODULE;
Scope.SCOPE_FUNCTION_EXPRESSION_NAME = SCOPE_FUNCTION_EXPRESSION_NAME;
Scope.SCOPE_TDZ = SCOPE_TDZ;

/* vim: set sw=4 ts=4 et tw=80 : */
<|endoftext|>


<commit_before> // Load a user using the QuickUser class
user = new QuickUser();

// Read the user ID that was assigned
var id = user.get("id");
var hits = user.get("hits");
var registered = user.get("registered");

// Assign the register function to the onClick event of the register button
$('#registerButton').click( function() { register(); } );

$('.build').html(hits);

// If this user has been here several times ask them to register
if (hits >= 3) {
    // If they are not registered
    if (registered != true) {
        // Ask them to register
        $('.register').show();
    }
}

// Register the app
function register() {
    // Set the user value to registered
    user.set("registered", true);
    // If the email address is not blank
    if ($("#email").val() != '') {
        // Set the users email address
        user.set("email", $('#email').val() );
    }
    // Submit the email address to the API
    $.get('http://joeldare.com/register/', {from: 'Random Riff', os: 'iOS', email: $('#email').val()});
    // Hide the dialog
    $('.register').hide();
}<commit_msg>Adjusted the registration to pass navigator.platform.<commit_after> // Load a user using the QuickUser class
user = new QuickUser();

// Read the user ID that was assigned
var id = user.get("id");
var hits = user.get("hits");
var registered = user.get("registered");

// Assign the register function to the onClick event of the register button
$('#registerButton').click( function() { register(); } );

$('.build').html(hits);

// If this user has been here several times ask them to register
if (hits >= 3) {
    // If they are not registered
    if (registered != true) {
        // Ask them to register
        $('.register').show();
    }
}

// Register the app
function register() {
    // Set the user value to registered
    user.set("registered", true);
    // If the email address is not blank
    if ($("#email").val() != '') {
        // Set the users email address
        user.set("email", $('#email').val() );
    }
    // Submit the email address to the API
    $.get('http://joeldare.com/register/', {from: 'Random Riff', os: navigator.platform, email: $('#email').val()});
    // Hide the dialog
    $('.register').hide();
}<|endoftext|>


<commit_before>var fs = require('fs');
var rangeCheck = require('range_check');

exports.isInt = function (value) {
    var er = /^-?[0-9]+$/;
    return er.test(value);
};

//http://stackoverflow.com/questions/21194934/node-how-to-create-a-directory-if-doesnt-exist
exports.ensureExists = function(path, mask, cb) {
    if (typeof mask == 'function') { // allow the `mask` parameter to be optional
        cb = mask;
        mask = 0777;
    }
    fs.mkdir(path, mask, function(err) {
        if (err) {
            if (err.code == 'EEXIST') cb(null); // ignore the error if the folder already exists
            else cb(err); // something else went wrong
        } else cb(null); // successfully created folder
    });
}

exports.ipInRange = function(config,ip){
    var config = config;
    if(!config){
        config = {};
        config.authorizedRanges = []; //empty range means any client allowed
    }
    var result = false; //something needs to turn this true for access to be provided

    // if config is not defining a cidr mask list
    if(config.authorizedRanges.length==0){
        result = true;
    }

    // iterate throught the mask list looking for a reason to allow
    for(var i=0;i<config.authorizedRanges.length;i++){
        if(rangeCheck.inRange(ip, config.authorizedRanges[i])){
            result = true;
        }
    }
    return result;
}

exports.markConnection = function(request){
    if (!request.connection.usageCount) {  // mark the http connection with the client action
        request.connection.usageCount = 1; // we're staying away from session (cookies) - not all clients are browsers
    } else {                              // this count informs (assuming http keep-alive) client 'session' activity
        request.connection.usageCount++;   // on the http connection
    }
}

exports.convertFormDataToJSON = function(payload){ // expecting application/x-www-form-urlencoded data like fingerprint=3971884212&latency=3.4&download=63051&upload=23012
    var payloadObject = {fingerprint: "",latency: -1,download: -1,upload: -1}; // sets our types
    var parts = payload.split("&");
    for(var i=0;i<parts.length;i++){
        var pair = parts[i].split("=");
        if((payloadObject[pair[0]]=="" || payloadObject[pair[0]]==-1) && !isNaN(pair[1]+1-1)){ // if our template is looking for this name
            console.log(payloadObject[pair[0]]);
            payloadObject[pair[0]] = (payloadObject[pair[0]]=="")? pair[1] : Number(pair[1]);
        }
    }
    return payloadObject;
}

<commit_msg>remove console statement<commit_after>var fs = require('fs');
var rangeCheck = require('range_check');

exports.isInt = function (value) {
    var er = /^-?[0-9]+$/;
    return er.test(value);
};

//http://stackoverflow.com/questions/21194934/node-how-to-create-a-directory-if-doesnt-exist
exports.ensureExists = function(path, mask, cb) {
    if (typeof mask == 'function') { // allow the `mask` parameter to be optional
        cb = mask;
        mask = 0777;
    }
    fs.mkdir(path, mask, function(err) {
        if (err) {
            if (err.code == 'EEXIST') cb(null); // ignore the error if the folder already exists
            else cb(err); // something else went wrong
        } else cb(null); // successfully created folder
    });
}

exports.ipInRange = function(config,ip){
    var config = config;
    if(!config){
        config = {};
        config.authorizedRanges = []; //empty range means any client allowed
    }
    var result = false; //something needs to turn this true for access to be provided

    // if config is not defining a cidr mask list
    if(config.authorizedRanges.length==0){
        result = true;
    }

    // iterate throught the mask list looking for a reason to allow
    for(var i=0;i<config.authorizedRanges.length;i++){
        if(rangeCheck.inRange(ip, config.authorizedRanges[i])){
            result = true;
        }
    }
    return result;
}

exports.markConnection = function(request){
    if (!request.connection.usageCount) {  // mark the http connection with the client action
        request.connection.usageCount = 1; // we're staying away from session (cookies) - not all clients are browsers
    } else {                              // this count informs (assuming http keep-alive) client 'session' activity
        request.connection.usageCount++;   // on the http connection
    }
}

exports.convertFormDataToJSON = function(payload){ // expecting application/x-www-form-urlencoded data like fingerprint=3971884212&latency=3.4&download=63051&upload=23012
    var payloadObject = {fingerprint: "",latency: -1,download: -1,upload: -1}; // sets our types
    var parts = payload.split("&");
    for(var i=0;i<parts.length;i++){
        var pair = parts[i].split("=");
        if((payloadObject[pair[0]]=="" || payloadObject[pair[0]]==-1) && !isNaN(pair[1]+1-1)){ // if our template is looking for this name
            payloadObject[pair[0]] = (payloadObject[pair[0]]=="")? pair[1] : Number(pair[1]);
        }
    }
    return payloadObject;
}

<|endoftext|>


<commit_before>import c from './config'
import _request from 'request-promise'
import {run, createChannel} from 'yacol'
import {login, getInfo} from './alza'
import WS from 'ws'

const API = 'https://slack.com/api/'

const request = _request.defaults({})

const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'EUR',
  minimumFractionDigits: 2,
});

let state = {}

function* apiCall(name, token, data={}) {
  return JSON.parse(yield request.post(`${API}${name}`, {form: {...data, token}}))
}

export function* connect(token) {
  const response = yield run(apiCall, 'rtm.connect', token)
  state = {
    team: response.team,
    bot: response.self,
    token,
    channels: {},
    pendingActions: {},
    actionsCount: 0,
  }

  const connection = new WS(response.url)
  const channel = createChannel()
  connection.on('message', (data) => channel.put(JSON.parse(data)))
  return channel
}

function nextUUID() {
  return (`${Date.now()}#${state.actionsCount++}`)
}

function amIMentioned(event) {
  if (event.user === state.bot.id) return false
  if (event.channel[0] === 'D') return true
  if (event.text.match(`<@${state.bot.id}>`)) return true
  return false
}

function channelForUser(userId) {
  if (state.channels[userId] == null) {
    state.channels[userId] = createChannel()
    run(listenUser, state.channels[userId], userId)
  }
  return state.channels[userId]
}

export function* listen(channel) {
  while (true) {
    const event = yield channel.take()
    if (event.type === 'message' && event.subtype == null && amIMentioned(event)) {
      channelForUser(event.user).put(event)
    }
    if (event.type === 'action') {
      state.pendingActions[event.callback_id].put(event)
    }
  }
}

function* listenUser(channel, user) {
  const newOrder = () => ({
    id: null,
    items: [],
    orderConfirmation: null,
  })

  function setId(order, newId) {
    if (order.id) delete state.pendingActions[order.id]
    if (newId) state.pendingActions[newId] = channel
    return {...order, id: newId}
  }

  function destroyOrder(order) {
    setId(order, null)
  }

  while (true) {
    let order = newOrder()

    while (true) {
      const event = yield channel.take()

      if (event.type === 'action') {
        yield run(finnishOrder, order, event.actions[0].name, user)
        break
      }

      if (event.type === 'message') {
        order = setId(order, nextUUID())
        order = yield run(updateOrder, order, event, user)
      }
    }

    destroyOrder(order)
  }
}

function* finnishOrder(order, action, user) {
  const {channel, ts, message: {attachments: [attachment]}} = order.orderConfirmation

  if (action === 'cancel') {
    yield run(apiCall, 'chat.update', state.token, {
      channel, ts, as_user: true, attachments: JSON.stringify([{...attachment,
        pretext: `:no_entry_sign: Order canceled:`,
        color: 'danger',
        actions: [],
      }])
    })
  }

  if (action === 'personal' || action === 'company') {
    yield run(apiCall, 'chat.update', state.token, {
      channel, ts, as_user: true, attachments: JSON.stringify([{...attachment,
        pretext: `:white_check_mark: Order finnished:`,
        color: 'good',
        actions: [],
      }])
    })
  }
}

function* updateOrder(order, event, user) {
  const items = [...order.items, ...parseOrder(event.text)]

  if (order.orderConfirmation) {
    const {channel, ts} = order.orderConfirmation
    yield run(apiCall, 'chat.delete', state.token, {channel, ts})
  }

  const orderAttachment = orderToAttachment(yield run(orderInfo, items), order.id)

  const orderConfirmation = yield run(apiCall, 'chat.postMessage', state.token, {
      channel: user,
      attachments: JSON.stringify([orderAttachment]),
      as_user: true,
  })

  return {...order, items, orderConfirmation}
}

function orderToAttachment(order, id) {
  const fields = order.items.map((item) => {
    const itemSum = formatter.format(item.count * item.price)
    const itemPrice = formatter.format(item.price)
    return {
      title: `${item.count} x ${item.name}`,
      value: `<${item.url}|${itemSum} (${item.count} x ${itemPrice})>`,
      short: true,
    }
  })

  return {
    title: `Total value: ${formatter.format(order.totalPrice)}`,
    pretext: `Please confirm your order:`,
    fields,
    callback_id: id,
    actions: [
      {name: 'personal', text: 'Make Personal Order', type: 'button', value: 'personal'},
      {name: 'company', text: 'Make Company Order', type: 'button', value: 'company'},
      {name: 'cancel', text: 'Cancel Order', type: 'button', value: 'cancel', style: 'danger'},
    ],
  }

}

function parseOrder(text) {
  const re = /\s*(\d*)\s*<(http[^\s]+)>/g
  let matches
  let goods = []
  while ((matches = re.exec(text)) !== null) {
    if (matches[1] === '') matches[1] = '1'
    goods.push({url: matches[2], count: parseInt(matches[1])})
  }
  return goods
}

function* orderInfo(items) {
  let info = []
  let totalPrice = 0
  yield run(login, c.alza.credentials)
  for (let item of items) {
    const itemInfo = yield run(getInfo, item.url)
    info.push({...itemInfo, count: item.count, url: item.url})
    totalPrice += itemInfo.price * item.count
  }
  return {items: info, totalPrice}
}
<commit_msg>Make apiCall take token from global state.<commit_after>import c from './config'
import _request from 'request-promise'
import {run, createChannel} from 'yacol'
import {login, getInfo} from './alza'
import WS from 'ws'

const API = 'https://slack.com/api/'

const request = _request.defaults({})

const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'EUR',
  minimumFractionDigits: 2,
});

let state = {}

function* apiCall(name, data={}) {
  return JSON.parse(yield request.post(`${API}${name}`, {form: {...data, token: state.token}}))
}

export function* connect(token) {
  state = {
    token,
    channels: {},
    pendingActions: {},
    actionsCount: 0,
  }

  const response = yield run(apiCall, 'rtm.connect')

  state = {
    ...state,
    team: response.team,
    bot: response.self,
  }

  const connection = new WS(response.url)
  const channel = createChannel()
  connection.on('message', (data) => channel.put(JSON.parse(data)))
  return channel
}

function nextUUID() {
  return (`${Date.now()}#${state.actionsCount++}`)
}

function amIMentioned(event) {
  if (event.user === state.bot.id) return false
  if (event.channel[0] === 'D') return true
  if (event.text.match(`<@${state.bot.id}>`)) return true
  return false
}

function channelForUser(userId) {
  if (state.channels[userId] == null) {
    state.channels[userId] = createChannel()
    run(listenUser, state.channels[userId], userId)
  }
  return state.channels[userId]
}

export function* listen(channel) {
  while (true) {
    const event = yield channel.take()
    if (event.type === 'message' && event.subtype == null && amIMentioned(event)) {
      channelForUser(event.user).put(event)
    }
    if (event.type === 'action') {
      state.pendingActions[event.callback_id].put(event)
    }
  }
}

function* listenUser(channel, user) {
  const newOrder = () => ({
    id: null,
    items: [],
    orderConfirmation: null,
  })

  function setId(order, newId) {
    if (order.id) delete state.pendingActions[order.id]
    if (newId) state.pendingActions[newId] = channel
    return {...order, id: newId}
  }

  function destroyOrder(order) {
    setId(order, null)
  }

  while (true) {
    let order = newOrder()

    while (true) {
      const event = yield channel.take()

      if (event.type === 'action') {
        yield run(finnishOrder, order, event.actions[0].name, user)
        break
      }

      if (event.type === 'message') {
        order = setId(order, nextUUID())
        order = yield run(updateOrder, order, event, user)
      }
    }

    destroyOrder(order)
  }
}

function* finnishOrder(order, action, user) {
  const {channel, ts, message: {attachments: [attachment]}} = order.orderConfirmation

  if (action === 'cancel') {
    yield run(apiCall, 'chat.update', {
      channel, ts, as_user: true, attachments: JSON.stringify([{...attachment,
        pretext: `:no_entry_sign: Order canceled:`,
        color: 'danger',
        actions: [],
      }])
    })
  }

  if (action === 'personal' || action === 'company') {
    yield run(apiCall, 'chat.update', {
      channel, ts, as_user: true, attachments: JSON.stringify([{...attachment,
        pretext: `:white_check_mark: Order finnished:`,
        color: 'good',
        actions: [],
      }])
    })
  }
}

function* updateOrder(order, event, user) {
  const items = [...order.items, ...parseOrder(event.text)]

  if (order.orderConfirmation) {
    const {channel, ts} = order.orderConfirmation
    yield run(apiCall, 'chat.delete', {channel, ts})
  }

  const orderAttachment = orderToAttachment(yield run(orderInfo, items), order.id)

  const orderConfirmation = yield run(apiCall, 'chat.postMessage', {
      channel: user,
      attachments: JSON.stringify([orderAttachment]),
      as_user: true,
  })

  return {...order, items, orderConfirmation}
}

function orderToAttachment(order, id) {
  const fields = order.items.map((item) => {
    const itemSum = formatter.format(item.count * item.price)
    const itemPrice = formatter.format(item.price)
    return {
      title: `${item.count} x ${item.name}`,
      value: `<${item.url}|${itemSum} (${item.count} x ${itemPrice})>`,
      short: true,
    }
  })

  return {
    title: `Total value: ${formatter.format(order.totalPrice)}`,
    pretext: `Please confirm your order:`,
    fields,
    callback_id: id,
    actions: [
      {name: 'personal', text: 'Make Personal Order', type: 'button', value: 'personal'},
      {name: 'company', text: 'Make Company Order', type: 'button', value: 'company'},
      {name: 'cancel', text: 'Cancel Order', type: 'button', value: 'cancel', style: 'danger'},
    ],
  }

}

function parseOrder(text) {
  const re = /\s*(\d*)\s*<(http[^\s]+)>/g
  let matches
  let goods = []
  while ((matches = re.exec(text)) !== null) {
    if (matches[1] === '') matches[1] = '1'
    goods.push({url: matches[2], count: parseInt(matches[1])})
  }
  return goods
}

function* orderInfo(items) {
  let info = []
  let totalPrice = 0
  yield run(login, c.alza.credentials)
  for (let item of items) {
    const itemInfo = yield run(getInfo, item.url)
    info.push({...itemInfo, count: item.count, url: item.url})
    totalPrice += itemInfo.price * item.count
  }
  return {items: info, totalPrice}
}
<|endoftext|>


<commit_before>//     uuid.js
//
//     Copyright (c) 2010-2012 Robert Kieffer
//     MIT License - http://opensource.org/licenses/mit-license.php

/*global window, require, define */
(function(_window) {
  'use strict';

  // Unique ID creation requires a high quality random # generator.  We feature
  // detect to determine the best RNG source, normalizing to a function that
  // returns 128-bits of randomness, since that's what's usually required
  var _rng, _mathRNG, _nodeRNG, _whatwgRNG;

  // Allow for MSIE11 msCrypto
  var _crypto = _window.crypto || _window.msCrypto;

  // Node.js crypto-based RNG - http://nodejs.org/docs/v0.6.2/api/crypto.html
  //
  // Moderately fast, high quality
  if ('undefined' === typeof window && 'function' === typeof require) {
    try {
      var _rb = require('crypto').randomBytes;
      _nodeRNG = _rng = _rb && function() {return _rb(16);};
      _rng();
    } catch(e) {}
  }

  if (!_rng && _crypto && _crypto.getRandomValues) {
    // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto
    //
    // Moderately fast, high quality
    try {
      var _rnds8 = new Uint8Array(16);
      _whatwgRNG = _rng = function whatwgRNG() {
        _crypto.getRandomValues(_rnds8);
        return _rnds8;
      };
      _rng();
    } catch(e) {}
  }

  if (!_rng) {
    // Math.random()-based (RNG)
    //
    // If all else fails, use Math.random().  It's fast, but is of unspecified
    // quality.
    var  _rnds = new Array(16);
    _mathRNG = _rng = function() {
      for (var i = 0, r; i < 16; i++) {
        if ((i & 0x03) === 0) { r = Math.random() * 0x100000000; }
        _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
      }

      return _rnds;
    };
    if ('undefined' !== typeof console && console.warn) {
      console.warn("[SECURITY] node-uuid: crypto not usable, falling back to insecure Math.random()");
    }
  }

  // Buffer class to use
  var BufferClass = ('function' === typeof Buffer) ? Buffer : Array;

  // Maps for number <-> hex string conversion
  var _byteToHex = [];
  var _hexToByte = {};
  for (var i = 0; i < 256; i++) {
    _byteToHex[i] = (i + 0x100).toString(16).substr(1);
    _hexToByte[_byteToHex[i]] = i;
  }

  // **`parse()` - Parse a UUID into it's component bytes**
  function parse(s, buf, offset) {
    var i = (buf && offset) || 0, ii = 0;

    buf = buf || [];
    s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) {
      if (ii < 16) { // Don't overflow!
        buf[i + ii++] = _hexToByte[oct];
      }
    });

    // Zero out remaining bytes if string was short
    while (ii < 16) {
      buf[i + ii++] = 0;
    }

    return buf;
  }

  // **`unparse()` - Convert UUID byte array (ala parse()) into a string**
  function unparse(buf, offset) {
    var i = offset || 0, bth = _byteToHex;
    return  bth[buf[i++]] + bth[buf[i++]] +
            bth[buf[i++]] + bth[buf[i++]] + '-' +
            bth[buf[i++]] + bth[buf[i++]] + '-' +
            bth[buf[i++]] + bth[buf[i++]] + '-' +
            bth[buf[i++]] + bth[buf[i++]] + '-' +
            bth[buf[i++]] + bth[buf[i++]] +
            bth[buf[i++]] + bth[buf[i++]] +
            bth[buf[i++]] + bth[buf[i++]];
  }

  // **`v1()` - Generate time-based UUID**
  //
  // Inspired by https://github.com/LiosK/UUID.js
  // and http://docs.python.org/library/uuid.html

  // random #'s we need to init node and clockseq
  var _seedBytes = _rng();

  // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
  var _nodeId = [
    _seedBytes[0] | 0x01,
    _seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5]
  ];

  // Per 4.2.2, randomize (14 bit) clockseq
  var _clockseq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff;

  // Previous uuid creation time
  var _lastMSecs = 0, _lastNSecs = 0;

  // See https://github.com/broofa/node-uuid for API details
  function v1(options, buf, offset) {
    var i = buf && offset || 0;
    var b = buf || [];

    options = options || {};

    var clockseq = (options.clockseq != null) ? options.clockseq : _clockseq;

    // UUID timestamps are 100 nano-second units since the Gregorian epoch,
    // (1582-10-15 00:00).  JSNumbers aren't precise enough for this, so
    // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'
    // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.
    var msecs = (options.msecs != null) ? options.msecs : new Date().getTime();

    // Per 4.2.1.2, use count of uuid's generated during the current clock
    // cycle to simulate higher resolution clock
    var nsecs = (options.nsecs != null) ? options.nsecs : _lastNSecs + 1;

    // Time since last uuid creation (in msecs)
    var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;

    // Per 4.2.1.2, Bump clockseq on clock regression
    if (dt < 0 && options.clockseq == null) {
      clockseq = clockseq + 1 & 0x3fff;
    }

    // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new
    // time interval
    if ((dt < 0 || msecs > _lastMSecs) && options.nsecs == null) {
      nsecs = 0;
    }

    // Per 4.2.1.2 Throw error if too many uuids are requested
    if (nsecs >= 10000) {
      throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec');
    }

    _lastMSecs = msecs;
    _lastNSecs = nsecs;
    _clockseq = clockseq;

    // Per 4.1.4 - Convert from unix epoch to Gregorian epoch
    msecs += 12219292800000;

    // `time_low`
    var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
    b[i++] = tl >>> 24 & 0xff;
    b[i++] = tl >>> 16 & 0xff;
    b[i++] = tl >>> 8 & 0xff;
    b[i++] = tl & 0xff;

    // `time_mid`
    var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;
    b[i++] = tmh >>> 8 & 0xff;
    b[i++] = tmh & 0xff;

    // `time_high_and_version`
    b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
    b[i++] = tmh >>> 16 & 0xff;

    // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)
    b[i++] = clockseq >>> 8 | 0x80;

    // `clock_seq_low`
    b[i++] = clockseq & 0xff;

    // `node`
    var node = options.node || _nodeId;
    for (var n = 0; n < 6; n++) {
      b[i + n] = node[n];
    }

    return buf ? buf : unparse(b);
  }

  // **`v4()` - Generate random UUID**

  // See https://github.com/broofa/node-uuid for API details
  function v4(options, buf, offset) {
    // Deprecated - 'format' argument, as supported in v1.2
    var i = buf && offset || 0;

    if (typeof(options) === 'string') {
      buf = (options === 'binary') ? new BufferClass(16) : null;
      options = null;
    }
    options = options || {};

    var rnds = options.random || (options.rng || _rng)();

    // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
    rnds[6] = (rnds[6] & 0x0f) | 0x40;
    rnds[8] = (rnds[8] & 0x3f) | 0x80;

    // Copy bytes to buffer, if provided
    if (buf) {
      for (var ii = 0; ii < 16; ii++) {
        buf[i + ii] = rnds[ii];
      }
    }

    return buf || unparse(rnds);
  }

  // Export public API
  var uuid = v4;
  uuid.v1 = v1;
  uuid.v4 = v4;
  uuid.parse = parse;
  uuid.unparse = unparse;
  uuid.BufferClass = BufferClass;
  uuid._rng = _rng;
  uuid._mathRNG = _mathRNG;
  uuid._nodeRNG = _nodeRNG;
  uuid._whatwgRNG = _whatwgRNG;

  if (typeof(module) != 'undefined' && module.exports) {
    // Publish as node.js module
    module.exports = uuid;
  } else  if (typeof define === 'function' && define.amd) {
    // Publish as AMD module
    define(function() {return uuid;});

  } else {
    // Publish as global (in browsers)
    var _previousRoot = _window.uuid;

    // **`noConflict()` - (browser only) to reset global 'uuid' var**
    uuid.noConflict = function() {
      _window.uuid = _previousRoot;
      return uuid;
    };

    _window.uuid = uuid;
  }
})('undefined' !== typeof window ? window : {});
<commit_msg>more workaround for #126<commit_after>//     uuid.js
//
//     Copyright (c) 2010-2012 Robert Kieffer
//     MIT License - http://opensource.org/licenses/mit-license.php

/*global window, require, define */
(function(_window) {
  'use strict';

  // Unique ID creation requires a high quality random # generator.  We feature
  // detect to determine the best RNG source, normalizing to a function that
  // returns 128-bits of randomness, since that's what's usually required
  var _rng, _mathRNG, _nodeRNG, _whatwgRNG, _previousRoot;

  function setupBrowser() {
    // Allow for MSIE11 msCrypto
    var _crypto = _window.crypto || _window.msCrypto;

    if (!_rng && _crypto && _crypto.getRandomValues) {
      // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto
      //
      // Moderately fast, high quality
      try {
        var _rnds8 = new Uint8Array(16);
        _whatwgRNG = _rng = function whatwgRNG() {
          _crypto.getRandomValues(_rnds8);
          return _rnds8;
        };
        _rng();
      } catch(e) {}
    }

    if (!_rng) {
      // Math.random()-based (RNG)
      //
      // If all else fails, use Math.random().  It's fast, but is of unspecified
      // quality.
      var  _rnds = new Array(16);
      _mathRNG = _rng = function() {
        for (var i = 0, r; i < 16; i++) {
          if ((i & 0x03) === 0) { r = Math.random() * 0x100000000; }
          _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
        }

        return _rnds;
      };
      if ('undefined' !== typeof console && console.warn) {
        console.warn("[SECURITY] node-uuid: crypto not usable, falling back to insecure Math.random()");
      }
    }
  }

  function setupNode() {
    // Node.js crypto-based RNG - http://nodejs.org/docs/v0.6.2/api/crypto.html
    //
    // Moderately fast, high quality
    if ('function' === typeof require) {
      try {
        var _rb = require('crypto').randomBytes;
        _nodeRNG = _rng = _rb && function() {return _rb(16);};
        _rng();
      } catch(e) {}
    }
  }

  if (_window) {
    setupBrowser();
  } else {
    setupNode();
  }

  // Buffer class to use
  var BufferClass = ('function' === typeof Buffer) ? Buffer : Array;

  // Maps for number <-> hex string conversion
  var _byteToHex = [];
  var _hexToByte = {};
  for (var i = 0; i < 256; i++) {
    _byteToHex[i] = (i + 0x100).toString(16).substr(1);
    _hexToByte[_byteToHex[i]] = i;
  }

  // **`parse()` - Parse a UUID into it's component bytes**
  function parse(s, buf, offset) {
    var i = (buf && offset) || 0, ii = 0;

    buf = buf || [];
    s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) {
      if (ii < 16) { // Don't overflow!
        buf[i + ii++] = _hexToByte[oct];
      }
    });

    // Zero out remaining bytes if string was short
    while (ii < 16) {
      buf[i + ii++] = 0;
    }

    return buf;
  }

  // **`unparse()` - Convert UUID byte array (ala parse()) into a string**
  function unparse(buf, offset) {
    var i = offset || 0, bth = _byteToHex;
    return  bth[buf[i++]] + bth[buf[i++]] +
            bth[buf[i++]] + bth[buf[i++]] + '-' +
            bth[buf[i++]] + bth[buf[i++]] + '-' +
            bth[buf[i++]] + bth[buf[i++]] + '-' +
            bth[buf[i++]] + bth[buf[i++]] + '-' +
            bth[buf[i++]] + bth[buf[i++]] +
            bth[buf[i++]] + bth[buf[i++]] +
            bth[buf[i++]] + bth[buf[i++]];
  }

  // **`v1()` - Generate time-based UUID**
  //
  // Inspired by https://github.com/LiosK/UUID.js
  // and http://docs.python.org/library/uuid.html

  // random #'s we need to init node and clockseq
  var _seedBytes = _rng();

  // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
  var _nodeId = [
    _seedBytes[0] | 0x01,
    _seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5]
  ];

  // Per 4.2.2, randomize (14 bit) clockseq
  var _clockseq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff;

  // Previous uuid creation time
  var _lastMSecs = 0, _lastNSecs = 0;

  // See https://github.com/broofa/node-uuid for API details
  function v1(options, buf, offset) {
    var i = buf && offset || 0;
    var b = buf || [];

    options = options || {};

    var clockseq = (options.clockseq != null) ? options.clockseq : _clockseq;

    // UUID timestamps are 100 nano-second units since the Gregorian epoch,
    // (1582-10-15 00:00).  JSNumbers aren't precise enough for this, so
    // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'
    // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.
    var msecs = (options.msecs != null) ? options.msecs : new Date().getTime();

    // Per 4.2.1.2, use count of uuid's generated during the current clock
    // cycle to simulate higher resolution clock
    var nsecs = (options.nsecs != null) ? options.nsecs : _lastNSecs + 1;

    // Time since last uuid creation (in msecs)
    var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;

    // Per 4.2.1.2, Bump clockseq on clock regression
    if (dt < 0 && options.clockseq == null) {
      clockseq = clockseq + 1 & 0x3fff;
    }

    // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new
    // time interval
    if ((dt < 0 || msecs > _lastMSecs) && options.nsecs == null) {
      nsecs = 0;
    }

    // Per 4.2.1.2 Throw error if too many uuids are requested
    if (nsecs >= 10000) {
      throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec');
    }

    _lastMSecs = msecs;
    _lastNSecs = nsecs;
    _clockseq = clockseq;

    // Per 4.1.4 - Convert from unix epoch to Gregorian epoch
    msecs += 12219292800000;

    // `time_low`
    var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
    b[i++] = tl >>> 24 & 0xff;
    b[i++] = tl >>> 16 & 0xff;
    b[i++] = tl >>> 8 & 0xff;
    b[i++] = tl & 0xff;

    // `time_mid`
    var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;
    b[i++] = tmh >>> 8 & 0xff;
    b[i++] = tmh & 0xff;

    // `time_high_and_version`
    b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
    b[i++] = tmh >>> 16 & 0xff;

    // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)
    b[i++] = clockseq >>> 8 | 0x80;

    // `clock_seq_low`
    b[i++] = clockseq & 0xff;

    // `node`
    var node = options.node || _nodeId;
    for (var n = 0; n < 6; n++) {
      b[i + n] = node[n];
    }

    return buf ? buf : unparse(b);
  }

  // **`v4()` - Generate random UUID**

  // See https://github.com/broofa/node-uuid for API details
  function v4(options, buf, offset) {
    // Deprecated - 'format' argument, as supported in v1.2
    var i = buf && offset || 0;

    if (typeof(options) === 'string') {
      buf = (options === 'binary') ? new BufferClass(16) : null;
      options = null;
    }
    options = options || {};

    var rnds = options.random || (options.rng || _rng)();

    // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
    rnds[6] = (rnds[6] & 0x0f) | 0x40;
    rnds[8] = (rnds[8] & 0x3f) | 0x80;

    // Copy bytes to buffer, if provided
    if (buf) {
      for (var ii = 0; ii < 16; ii++) {
        buf[i + ii] = rnds[ii];
      }
    }

    return buf || unparse(rnds);
  }

  // Export public API
  var uuid = v4;
  uuid.v1 = v1;
  uuid.v4 = v4;
  uuid.parse = parse;
  uuid.unparse = unparse;
  uuid.BufferClass = BufferClass;
  uuid._rng = _rng;
  uuid._mathRNG = _mathRNG;
  uuid._nodeRNG = _nodeRNG;
  uuid._whatwgRNG = _whatwgRNG;

  if (('undefined' !== typeof module) && module.exports) {
    // Publish as node.js module
    module.exports = uuid;
  } else if (typeof define === 'function' && define.amd) {
    // Publish as AMD module
    define(function() {return uuid;});

  } else {
    // Publish as global (in browsers)
    _previousRoot = _window.uuid;

    // **`noConflict()` - (browser only) to reset global 'uuid' var**
    uuid.noConflict = function() {
      _window.uuid = _previousRoot;
      return uuid;
    };

    _window.uuid = uuid;
  }
})('undefined' !== typeof window ? window : null);
<|endoftext|>


<commit_before>$(document).ready(function(){
  // $(document).on('click', function(){
  //   for (var i=0; i<6; i++) {
  //     $('#column-0').append('

');
  //   };

  // })
  $(document).on("click", function(){
    $("#player2").toggle();
    $("#player1").toggle();
  })
})
<commit_msg>Add more JQ Functionality<commit_after>$(document).ready(function(){
  // $(document).on('click', function(){
  //   for (var i=0; i<6; i++) {
  //     $('#column-0').append('

');
  //   };

  // })
  $(document).on("click", function(){
    $("#player2").toggle();
    $("#player1").toggle();
  })
  $("#board").children().on("click", function(event){
    if($("#player1").is(":visible")){
      if( $(event.target).hasClass("cell")) $(event.target).css("background-color", "red");
      else {
        $(event.target).children().css("background-color", "red");
      };
    }
    else{
      if( $(event.target).hasClass("cell")) $(event.target).css("background-color", "black");
      else {
        $(event.target).children().css("background-color", "black");
      };
    };
  });
});
<|endoftext|>