<commit_before>(function () {
	var d = document,
	w = window,
	p = parseInt,
	dd = d.documentElement,
	db = d.body,
	dc = d.compatMode == 'CSS1Compat',
	dx = dc ? dd: db,
	ec = encodeURIComponent;

	w.CHAT = {
		msgObj:d.getElementById("message"),
		screenheight:w.innerHeight ? w.innerHeight : dx.clientHeight,
		username:null,
		userid:null,
		socket:null,
		//让浏览器滚动条保持在最低部
		scrollToBottom:function(){
			w.scrollTo(0, this.msgObj.clientHeight);
		},
		//退出，本例只是一个简单的刷新
		logout:function(){
			//this.socket.disconnect();
			location.reload();
		},
		//提交聊天消息内容
		submit:function(){
			var content = d.getElementById("content").value;
			if(content != ''){
				var obj = {
					userid: this.userid,
					username: this.username,
					content: content
				};
				this.socket.emit('message', obj);
				d.getElementById("content").value = '';
			}
			return false;
		},
		genUid:function(){
			return new Date().getTime()+""+Math.floor(Math.random()*899+100);
		},
		//更新系统消息，本例中在用户加入、退出的时候调用
		updateSysMsg:function(o, action){
			//当前在线用户列表
			var onlineUsers = o.onlineUsers;
			//当前在线人数
			var onlineCount = o.onlineCount;
			//新加入用户的信息
			var user = o.user;

			//更新在线人数
			var userhtml = '';
			var separator = '';
			for(key in onlineUsers) {
		        if(onlineUsers.hasOwnProperty(key)){
					userhtml += separator+onlineUsers[key];
					separator = '、';
				}
		    }
			d.getElementById("onlinecount").innerHTML = '当前共有 '+onlineCount+' 人在线，在线列表：'+userhtml;

			//添加系统消息
			var html = '';
			html += '
';
			html += user.username;
			html += (action == 'login') ? ' 加入了聊天室' : ' 退出了聊天室';
			html += '
';
			var section = d.createElement('section');
			section.className = 'system J-mjrlinkWrap J-cutMsg';
			section.innerHTML = html;
			this.msgObj.appendChild(section);
			this.scrollToBottom();
		},
		//第一个界面用户提交用户名
		usernameSubmit:function(){
			var username = d.getElementById("username").value;
			if(username != ""){
				d.getElementById("username").value = '';
				d.getElementById("loginbox").style.display = 'none';
				d.getElementById("chatbox").style.display = 'block';
				this.init(username);
			}
			return false;
		},
		init:function(username){
			/*
			客户端根据时间和随机数生成uid,这样使得聊天室用户名称可以重复。
			实际项目中，如果是需要用户登录，那么直接采用用户的uid来做标识就可以
			*/
			this.userid = this.genUid();
			this.username = username;

			d.getElementById("showusername").innerHTML = this.username;
			this.msgObj.style.minHeight = (this.screenheight - db.clientHeight + this.msgObj.clientHeight) + "px";
			this.scrollToBottom();

			//连接websocket后端服务器
			this.socket = io.connect('ws://localhost:6027');

			//告诉服务器端有用户登录
			this.socket.emit('login', {userid:this.userid, username:this.username});

			//监听新用户登录
			this.socket.on('login', function(o){
				CHAT.updateSysMsg(o, 'login');
			});

			//监听用户退出
			this.socket.on('logout', function(o){
				CHAT.updateSysMsg(o, 'logout');
			});

			//监听消息发送
			this.socket.on('message', function(obj){
				var isme = (obj.userid == CHAT.userid) ? true : false;
				var contentDiv = '
'+obj.content+'
';
				var usernameDiv = ''+obj.username+'';

				var section = d.createElement('section');
				if(isme){
					section.className = 'user';
					section.innerHTML = contentDiv + usernameDiv;
				} else {
					section.className = 'service';
					section.innerHTML = usernameDiv + contentDiv;
				}
				CHAT.msgObj.appendChild(section);
				CHAT.scrollToBottom();
			});

		}
	};
	//通过“回车”提交用户名
	d.getElementById("username").onkeydown = function(e) {
		e = e || event;
		if (e.keyCode === 13) {
			CHAT.usernameSubmit();
		}
	};
	//通过“回车”提交信息
	d.getElementById("content").onkeydown = function(e) {
		e = e || event;
		if (e.keyCode === 13) {
			CHAT.submit();
		}
	};
})();<commit_msg>change ws server<commit_after>(function () {
	var d = document,
	w = window,
	p = parseInt,
	dd = d.documentElement,
	db = d.body,
	dc = d.compatMode == 'CSS1Compat',
	dx = dc ? dd: db,
	ec = encodeURIComponent;

	w.CHAT = {
		msgObj:d.getElementById("message"),
		screenheight:w.innerHeight ? w.innerHeight : dx.clientHeight,
		username:null,
		userid:null,
		socket:null,
		//让浏览器滚动条保持在最低部
		scrollToBottom:function(){
			w.scrollTo(0, this.msgObj.clientHeight);
		},
		//退出，本例只是一个简单的刷新
		logout:function(){
			//this.socket.disconnect();
			location.reload();
		},
		//提交聊天消息内容
		submit:function(){
			var content = d.getElementById("content").value;
			if(content != ''){
				var obj = {
					userid: this.userid,
					username: this.username,
					content: content
				};
				this.socket.emit('message', obj);
				d.getElementById("content").value = '';
			}
			return false;
		},
		genUid:function(){
			return new Date().getTime()+""+Math.floor(Math.random()*899+100);
		},
		//更新系统消息，本例中在用户加入、退出的时候调用
		updateSysMsg:function(o, action){
			//当前在线用户列表
			var onlineUsers = o.onlineUsers;
			//当前在线人数
			var onlineCount = o.onlineCount;
			//新加入用户的信息
			var user = o.user;

			//更新在线人数
			var userhtml = '';
			var separator = '';
			for(key in onlineUsers) {
		        if(onlineUsers.hasOwnProperty(key)){
					userhtml += separator+onlineUsers[key];
					separator = '、';
				}
		    }
			d.getElementById("onlinecount").innerHTML = '当前共有 '+onlineCount+' 人在线，在线列表：'+userhtml;

			//添加系统消息
			var html = '';
			html += '
';
			html += user.username;
			html += (action == 'login') ? ' 加入了聊天室' : ' 退出了聊天室';
			html += '
';
			var section = d.createElement('section');
			section.className = 'system J-mjrlinkWrap J-cutMsg';
			section.innerHTML = html;
			this.msgObj.appendChild(section);
			this.scrollToBottom();
		},
		//第一个界面用户提交用户名
		usernameSubmit:function(){
			var username = d.getElementById("username").value;
			if(username != ""){
				d.getElementById("username").value = '';
				d.getElementById("loginbox").style.display = 'none';
				d.getElementById("chatbox").style.display = 'block';
				this.init(username);
			}
			return false;
		},
		init:function(username){
			/*
			客户端根据时间和随机数生成uid,这样使得聊天室用户名称可以重复。
			实际项目中，如果是需要用户登录，那么直接采用用户的uid来做标识就可以
			*/
			this.userid = this.genUid();
			this.username = username;

			d.getElementById("showusername").innerHTML = this.username;
			this.msgObj.style.minHeight = (this.screenheight - db.clientHeight + this.msgObj.clientHeight) + "px";
			this.scrollToBottom();

			//连接websocket后端服务器
			this.socket = io.connect('ws://slxtws.bgy.com.cn:6027');

			//告诉服务器端有用户登录
			this.socket.emit('login', {userid:this.userid, username:this.username});

			//监听新用户登录
			this.socket.on('login', function(o){
				CHAT.updateSysMsg(o, 'login');
			});

			//监听用户退出
			this.socket.on('logout', function(o){
				CHAT.updateSysMsg(o, 'logout');
			});

			//监听消息发送
			this.socket.on('message', function(obj){
				var isme = (obj.userid == CHAT.userid) ? true : false;
				var contentDiv = '
'+obj.content+'
';
				var usernameDiv = ''+obj.username+'';

				var section = d.createElement('section');
				if(isme){
					section.className = 'user';
					section.innerHTML = contentDiv + usernameDiv;
				} else {
					section.className = 'service';
					section.innerHTML = usernameDiv + contentDiv;
				}
				CHAT.msgObj.appendChild(section);
				CHAT.scrollToBottom();
			});

		}
	};
	//通过“回车”提交用户名
	d.getElementById("username").onkeydown = function(e) {
		e = e || event;
		if (e.keyCode === 13) {
			CHAT.usernameSubmit();
		}
	};
	//通过“回车”提交信息
	d.getElementById("content").onkeydown = function(e) {
		e = e || event;
		if (e.keyCode === 13) {
			CHAT.submit();
		}
	};
})();
<|endoftext|>


<commit_before>	$(function () {
    $(document).ready(function() {
        Highcharts.setOptions({
            global: {
                useUTC: false
            }
        });

        var chart;
        $('#graphTemp').highcharts({
            chart: {
                type: 'spline',
                animation: Highcharts.svg, // don't animate in old IE
                marginRight: 10,
                events: {
                    load: function() {
                        // set up the updating of the chart each second
                        var series = this.series[0];
                        setInterval(function() {
                            $.ajax({
								async: false,
								url: "/Hackwaw/FluAlert/Backend/public/site/sensor?type=T",
								type: "GET",
								success: function (msg)
								{
									 var x = (new Date()).getTime(), // current time
									 y = msg.value;
									 series.addPoint([x, y], true, true);
									 $("#graphTempValue").text(FormatNumberLength(y,2));
								}
								});

                        }, 1000);
                    }
                }
            },
            title: {
                text: ''
            },
            xAxis: {
                type: 'datetime',
                tickPixelInterval: 150
            },
            yAxis: {
                title: {
                    text: 'Temp'
                },
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#c0392b'
                }]
            },
            tooltip: {
                formatter: function() {
                        return ''+ this.series.name +'
'+
                        Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) +'
'+
                        Highcharts.numberFormat(this.y, 2);
                }
            },
            legend: {
                enabled: false
            },
            exporting: {
                enabled: false
            },
            series: [{
                name: 'Temp',
				color: '#c0392b',
                data: (function() {
                    // generate an array of random data
                    var data = [],
                        time = (new Date()).getTime(),
                        i;

                    for (i = -19; i <= 0; i++) {
                        data.push({
                            x: time + i * 1000,
                            y: 36 + Math.random()
                        });
                    }
                    return data;
                })()
            }]
        });
    });

});

	$(function () {
    $(document).ready(function() {
        Highcharts.setOptions({
            global: {
                useUTC: false
            }
        });

        var chart;
        $('#graphHeartrate').highcharts({
            chart: {
                type: 'spline',
                animation: Highcharts.svg, // don't animate in old IE
                marginRight: 10,
                events: {
                    load: function() {
                        // set up the updating of the chart each second
                        var series = this.series[0];
                        setInterval(function() {
							$.ajax({
								async: false,
								url: "/Hackwaw/FluAlert/Backend/public/site/sensor?type=H",
								type: "GET",
								dataType: "json",
								contentType: "text/plain; charset=utf-8",
								success: function (msg)
								{
									 var x = (new Date()).getTime(), // current time
									 y = msg.value;
									 series.addPoint([x, y], true, true);
									 $("#graphHeartrateValue").text(FormatNumberLength(y,2));
								}
								});
                        }, 1000);
                    }
                }
            },
            title: {
                text: ''
            },
            xAxis: {
                type: 'datetime',
                tickPixelInterval: 150
            },
            yAxis: {
                title: {
                    text: 'HeartRate'
                },
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#d35400'
                }]
            },
            tooltip: {
                formatter: function() {
                        return ''+ this.series.name +'
'+
                        Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) +'
'+
                        Highcharts.numberFormat(this.y, 2);
                }
            },
            legend: {
                enabled: false
            },
            exporting: {
                enabled: false
            },
            series: [{
                name: 'HeartRate',
				color: '#d35400',
                data: (function() {
                    // generate an array of random data
                    var data = [],
                        time = (new Date()).getTime(),
                        i;

                    for (i = -19; i <= 0; i++) {
                        data.push({
                            x: time + i * 1000,
                            y: 88 + Math.random()
                        });
                    }
                    return data;
                })()
            }]
        });
    });

});

function FormatNumberLength(num, length) {
    return num.toPrecision(3);
}<commit_msg>graph.js parse int<commit_after>	$(function () {
    $(document).ready(function() {
        Highcharts.setOptions({
            global: {
                useUTC: false
            }
        });

        var chart;
        $('#graphTemp').highcharts({
            chart: {
                type: 'spline',
                animation: Highcharts.svg, // don't animate in old IE
                marginRight: 10,
                events: {
                    load: function() {
                        // set up the updating of the chart each second
                        var series = this.series[0];
                        setInterval(function() {
                            $.ajax({
								async: false,
								url: "/Hackwaw/FluAlert/Backend/public/site/sensor?type=T",
								type: "GET",
								success: function (msg)
								{
									 var x = (new Date()).getTime(), // current time
									 y = msg.value;
									 series.addPoint([x, y], true, true);
									 $("#graphTempValue").text(FormatNumberLength(y,2));
								}
								});

                        }, 1000);
                    }
                }
            },
            title: {
                text: ''
            },
            xAxis: {
                type: 'datetime',
                tickPixelInterval: 150
            },
            yAxis: {
                title: {
                    text: 'Temp'
                },
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#c0392b'
                }]
            },
            tooltip: {
                formatter: function() {
                        return ''+ this.series.name +'
'+
                        Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) +'
'+
                        Highcharts.numberFormat(this.y, 2);
                }
            },
            legend: {
                enabled: false
            },
            exporting: {
                enabled: false
            },
            series: [{
                name: 'Temp',
				color: '#c0392b',
                data: (function() {
                    // generate an array of random data
                    var data = [],
                        time = (new Date()).getTime(),
                        i;

                    for (i = -19; i <= 0; i++) {
                        data.push({
                            x: time + i * 1000,
                            y: 36 + Math.random()
                        });
                    }
                    return data;
                })()
            }]
        });
    });

});

	$(function () {
    $(document).ready(function() {
        Highcharts.setOptions({
            global: {
                useUTC: false
            }
        });

        var chart;
        $('#graphHeartrate').highcharts({
            chart: {
                type: 'spline',
                animation: Highcharts.svg, // don't animate in old IE
                marginRight: 10,
                events: {
                    load: function() {
                        // set up the updating of the chart each second
                        var series = this.series[0];
                        setInterval(function() {
							$.ajax({
								async: false,
								url: "/Hackwaw/FluAlert/Backend/public/site/sensor?type=H",
								type: "GET",
								dataType: "json",
								contentType: "text/plain; charset=utf-8",
								success: function (msg)
								{
									 var x = (new Date()).getTime(), // current time
									 y = msg.value;
									 series.addPoint([x, y], true, true);
									 $("#graphHeartrateValue").text(FormatNumberLength(y,2));
								}
								});
                        }, 1000);
                    }
                }
            },
            title: {
                text: ''
            },
            xAxis: {
                type: 'datetime',
                tickPixelInterval: 150
            },
            yAxis: {
                title: {
                    text: 'HeartRate'
                },
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#d35400'
                }]
            },
            tooltip: {
                formatter: function() {
                        return ''+ this.series.name +'
'+
                        Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) +'
'+
                        Highcharts.numberFormat(this.y, 2);
                }
            },
            legend: {
                enabled: false
            },
            exporting: {
                enabled: false
            },
            series: [{
                name: 'HeartRate',
				color: '#d35400',
                data: (function() {
                    // generate an array of random data
                    var data = [],
                        time = (new Date()).getTime(),
                        i;

                    for (i = -19; i <= 0; i++) {
                        data.push({
                            x: time + i * 1000,
                            y: 88 + Math.random()
                        });
                    }
                    return data;
                })()
            }]
        });
    });

});

function FormatNumberLength(num, length) {
    return parseInt(num).toPrecision(3);
}<|endoftext|>


<commit_before>var Class = require("./utilities/class");
var Serializer = require("./utilities/serializer");
var net = require("net");
var EOT_CHAR = String.fromCharCode(4);

// @class Client: talks to the server recieving game information and sending commands to execute via TCP socket. Clients perform no game logic
var Client = Class({
	init: function(game, ai, server, port) {
		server = server || 'localhost';
		port = port || 3000;

		this.game = game;
		this.ai = ai;
		this.server = server;
		this.port = port;

		this.game.setClient(this);
		this.game.setAI(this.ai);

		console.log("connecting to: " + this.server + ":" + this.port)

		this.socket = new net.Socket();
		this.socket.setEncoding('utf8');

		(function(self) {
			self.socket.connect(self.port, self.server, function() {
				self.connected();
			});

			var buffer = "";
			self.socket.on("data", function(str) {
				buffer += str;

				var split = buffer.split(EOT_CHAR); // split on "end of text" character (basically end of transmition)

				buffer = split.pop(); // the last item will either be "" if the last char was an EOT_CHAR, or a partial data we need to buffer anyways

				for(var i = 0; i < split.length; i++) {
					self.onJsonData(split[i]);
				}
			});

			self.socket.on("close", function() {
				self.disconnected();
			});

			self.socket.on("error", function() {
				console.log("server encountered unexpected error");
			});
		})(this);
	},

	connected: function(data) {
		console.log("successfully connected to server at:", this.server + ":" + this.port);
	},

	disconnected: function() {
		console.log("Disconnected from server...");
		this.socket.destroy();
		process.exit();
	},

	onJsonData: function(json) {
		var parsed = JSON.parse(json);
		this['on' + parsed.event.capitalize()].call(this, parsed.data);
	},

	/// tells the server this player is ready to play a game
	ready: function(playerName) {
		this.sendEvent("play", {
			clientType: "JavaScript",
			playerName: playerName || this.ai.getName() || "JavaScript Player",
			gameName: this.game.name,
			gameSession: this.game.session || "*",
		});
	},

	sendEvent: function(event, data) {
		this.socket.write(
			JSON.stringify({
				sendTime: (new Date()).getTime(),
				event: event,
				data: data,
			})
			+ EOT_CHAR
		);
	},

	/// sends a command on behalf of a caller game object to the server
	sendCommand: function(caller, command, data) {
		data.caller = caller;
		data.command = command;

		this.sendEvent("command", Serializer.serialize(data));
	},

	//--- Socket on data functions ---\\

	onPlaying: function(data) {
		this.game.connected(data);
		this.ai.connected(data);
		console.log("Connection successful to game '" + this.game.name + "'' in session '" + this.game.session + "'");
	},

	onStart: function(data) {
		this.ai.start(data);
	},

	onAwaiting: function() {
		this.ai.run();
	},

	onIgnoring: function() {
		this.ai.ignoring();
	},

	onDelta: function(delta) {
		this.game.applyDeltaState(delta);
	},

	onOver: function() {
		this.ai.over();
		this.disconnected();
	},
});

module.exports = Client;
<commit_msg>sendTime -> sentTime<commit_after>var Class = require("./utilities/class");
var Serializer = require("./utilities/serializer");
var net = require("net");
var EOT_CHAR = String.fromCharCode(4);

// @class Client: talks to the server recieving game information and sending commands to execute via TCP socket. Clients perform no game logic
var Client = Class({
	init: function(game, ai, server, port) {
		server = server || 'localhost';
		port = port || 3000;

		this.game = game;
		this.ai = ai;
		this.server = server;
		this.port = port;

		this.game.setClient(this);
		this.game.setAI(this.ai);

		console.log("connecting to: " + this.server + ":" + this.port)

		this.socket = new net.Socket();
		this.socket.setEncoding('utf8');

		(function(self) {
			self.socket.connect(self.port, self.server, function() {
				self.connected();
			});

			var buffer = "";
			self.socket.on("data", function(str) {
				buffer += str;

				var split = buffer.split(EOT_CHAR); // split on "end of text" character (basically end of transmition)

				buffer = split.pop(); // the last item will either be "" if the last char was an EOT_CHAR, or a partial data we need to buffer anyways

				for(var i = 0; i < split.length; i++) {
					self.onJsonData(split[i]);
				}
			});

			self.socket.on("close", function() {
				self.disconnected();
			});

			self.socket.on("error", function() {
				console.log("server encountered unexpected error");
			});
		})(this);
	},

	connected: function(data) {
		console.log("successfully connected to server at:", this.server + ":" + this.port);
	},

	disconnected: function() {
		console.log("Disconnected from server...");
		this.socket.destroy();
		process.exit();
	},

	onJsonData: function(json) {
		var parsed = JSON.parse(json);
		this['on' + parsed.event.capitalize()].call(this, parsed.data);
	},

	/// tells the server this player is ready to play a game
	ready: function(playerName) {
		this.sendEvent("play", {
			clientType: "JavaScript",
			playerName: playerName || this.ai.getName() || "JavaScript Player",
			gameName: this.game.name,
			gameSession: this.game.session || "*",
		});
	},

	sendEvent: function(event, data) {
		this.socket.write(
			JSON.stringify({
				sentTime: (new Date()).getTime(),
				event: event,
				data: data,
			})
			+ EOT_CHAR
		);
	},

	/// sends a command on behalf of a caller game object to the server
	sendCommand: function(caller, command, data) {
		data.caller = caller;
		data.command = command;

		this.sendEvent("command", Serializer.serialize(data));
	},

	//--- Socket on data functions ---\\

	onPlaying: function(data) {
		this.game.connected(data);
		this.ai.connected(data);
		console.log("Connection successful to game '" + this.game.name + "'' in session '" + this.game.session + "'");
	},

	onStart: function(data) {
		this.ai.start(data);
	},

	onAwaiting: function() {
		this.ai.run();
	},

	onIgnoring: function() {
		this.ai.ignoring();
	},

	onDelta: function(delta) {
		this.game.applyDeltaState(delta);
	},

	onOver: function() {
		this.ai.over();
		this.disconnected();
	},
});

module.exports = Client;
<|endoftext|>


<commit_before>var EventEmitter = require('events').EventEmitter;
var util = require('util');
var heartbeats = require('heartbeats');

var routeController = require('./lib/controllers/routeController');
var connectionController = require('./lib/controllers/connectionController');
var executionController = require('./lib/controllers/executionController');

var helper = require('./lib/utils/helper');
var parser = require('./lib/utils/parser');
var middleware = require('./lib/utils/middleware');

var heart;

util.inherits(Samsaara, EventEmitter);

function Samsaara() {

    EventEmitter.call(this);

    routeController.setParser(parser);
    connectionController.initialize(this, null);
    executionController.initialize(this);
    middleware.initialize(this);
}

Samsaara.prototype.nameSpace = function(namespaceName) {
    return executionController.nameSpace(namespaceName);
};

Samsaara.prototype.createNamespace = function(namespaceName, methods) {
    return executionController.createNamespace(namespaceName, methods);
};

Samsaara.prototype.expose = function(set) {
    return executionController.expose(set);
};

Samsaara.prototype.use = function(module) {
    return middleware.use(module);
};

Samsaara.prototype.setState = function(state, cb) {
    return this.core.setState(state, cb);
};

Samsaara.prototype.initialize = function(opts) {
    opts = opts || {};

    heart = heartbeats.createHeart(2000, 'samsaara');
    connectionController.setTransport(opts.socketType || 'ws', true);

    this.core = connectionController.newConnection(opts.socket, 'core');
    middleware.load();

    initializeClient(this, this.core, opts);

    return this;
};

Object.defineProperty(Samsaara.prototype, 'state', {
    get: function() {
        return this.core ? this.core.state : null;
    }
});

// Initialize client instance

function initializeClient(samsaara, core, opts) {
    routeController.addRoute('INIT', initializationRouteHandler);
    exposeStateHandler(samsaara);
}

// Route Handlers

function initializationRouteHandler(connection, headerbits, incomingPacket) {
    var parsedPacket = parser.parsePacket(incomingPacket),
        connectionOwner,
        connectionRouteID,
        heartbeatInterval;

    if (typeof parsedPacket === 'object') {
        connectionOwner = parsedPacket.connectionOwner;
        connectionRouteID = parsedPacket.connectionRouteID;
        heartbeatInterval = parsedPacket.heartbeatInterval;

        helper.addReadOnlyBaseProperty(connection, 'routeID', connectionOwner);
        routeController.addRoute(connectionRouteID, executionRouteHandler);
        connection.queue.emptyToRoute(connectionOwner);
        setHeartbeats(connection, heartbeatInterval);
    }
}

function executionRouteHandler(connection, headerbits, incomingPacket) {
    var parsedPacket = parser.parsePacket(incomingPacket);

    if (parsedPacket !== undefined && parsedPacket.func !== undefined) {
        parsedPacket.sender = connection.id;
        executionController.executeFunction(connection, connection, parsedPacket);
    }
}

// State Change Handler

function exposeStateHandler(samsaara) {

    samsaara.nameSpace('internal').expose({
        setState: function(state, cb) {
            var connection = this;
            var attributeName;
            for (attributeName in state) {
                connection.state[attributeName] = state[attributeName];
            }
            samsaara.emit('stateChange', connection.state, connection);
            cb(true);
        },
        initialized: function(success) {
            samsaara.emit('initialized', success);
        }
    });
}

// Heartbeats

function setHeartbeats(connection, heartbeatInterval) {
    heart.setHeartrate(heartbeatInterval);
    heart.createEvent(1, function() {
        if (connection.outgoingPulse.missedBeats() > 0) {
            connection.socket.send('H');
        }
    });
}

module.exports = new Samsaara();
<commit_msg>Temporary fix to client initialization.<commit_after>var EventEmitter = require('events').EventEmitter;
var util = require('util');
var heartbeats = require('heartbeats');

var routeController = require('./lib/controllers/routeController');
var connectionController = require('./lib/controllers/connectionController');
var executionController = require('./lib/controllers/executionController');

var helper = require('./lib/utils/helper');
var parser = require('./lib/utils/parser');
var middleware = require('./lib/utils/middleware');

var heart;

util.inherits(Samsaara, EventEmitter);

function Samsaara() {

    EventEmitter.call(this);

    routeController.setParser(parser);
    connectionController.initialize(this, null);
    executionController.initialize(this);
    middleware.initialize(this);
}

Samsaara.prototype.nameSpace = function(namespaceName) {
    return executionController.nameSpace(namespaceName);
};

Samsaara.prototype.createNamespace = function(namespaceName, methods) {
    return executionController.createNamespace(namespaceName, methods);
};

Samsaara.prototype.expose = function(set) {
    return executionController.expose(set);
};

Samsaara.prototype.use = function(module) {
    return middleware.use(module);
};

Samsaara.prototype.setState = function(state, cb) {
    return this.core.setState(state, cb);
};

Samsaara.prototype.initialize = function(opts) {
    opts = opts || {};

    heart = heartbeats.createHeart(2000, 'samsaara');
    connectionController.setTransport(opts.socketType || 'ws', true);

    this.core = connectionController.newConnection(opts.socket, 'core');
    middleware.load();

    initializeClient(this, this.core, opts);

    return this;
};

Object.defineProperty(Samsaara.prototype, 'state', {
    get: function() {
        return this.core ? this.core.state : null;
    }
});

// Initialize client instance

function initializeClient(samsaara, core, opts) {
    routeController.addRoute('INIT', initializationRouteHandler);
    exposeStateHandler(samsaara);
}

// Route Handlers

function initializationRouteHandler(connection, headerbits, incomingPacket) {
    var parsedPacket = parser.parsePacket(incomingPacket),
        connectionOwner,
        connectionRouteID,
        heartbeatInterval;

    if (typeof parsedPacket === 'object') {
        connectionOwner = parsedPacket.connectionOwner;
        connectionRouteID = parsedPacket.connectionRouteID;
        heartbeatInterval = parsedPacket.heartbeatInterval;

        helper.addReadOnlyBaseProperty(connection, 'routeID', connectionOwner);
        routeController.addRoute(connectionRouteID, executionRouteHandler);
        connection.queue.emptyToRoute(connectionOwner);
        setHeartbeats(connection, heartbeatInterval);
    }
}

function executionRouteHandler(connection, headerbits, incomingPacket) {
    var parsedPacket = parser.parsePacket(incomingPacket);

    if (parsedPacket !== undefined && parsedPacket.func !== undefined) {
        parsedPacket.sender = connection.id;
        executionController.executeFunction(connection, connection, parsedPacket);
    }
}

// State Change Handler

function exposeStateHandler(samsaara) {

    samsaara.nameSpace('internal').expose({
        setState: function(state, cb) {
            var connection = this;
            var attributeName;
            for (attributeName in state) {
                connection.state[attributeName] = state[attributeName];
            }
            samsaara.emit('stateChange', connection.state, connection);
            cb(true);
        },
        initialized: function(success, cb) {
            samsaara.emit('initialized', success);
        }
    });
}

// Heartbeats

function setHeartbeats(connection, heartbeatInterval) {
    heart.setHeartrate(heartbeatInterval);
    heart.createEvent(1, function() {
        if (connection.outgoingPulse.missedBeats() > 0) {
            connection.socket.send('H');
        }
    });
}

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


<commit_before>//program.js
//Creates programs out of shaders and provides convenient methods for loading
//buffers attributes and uniforms

(function() {
  //First, some privates to handle compiling/linking shaders to programs.

  //Creates a shader from a string source.
  var createShader = function(gl, shaderSource, shaderType) {
    var shader = gl.createShader(shaderType);
    if (shader == null) {
      throw "Error creating the shader with shader type: " + shaderType;
      //return false;
    }
    gl.shaderSource(shader, shaderSource);
    gl.compileShader(shader);
    var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
    if (!compiled) {
      gl.deleteShader(shader);
      throw "Error while compiling the shader " + gl.getShaderInfoLog(shader);
      //return false;
    }
    return shader;
  };

  //Creates a program from vertex and fragment shader sources.
  var createProgram = function(gl, vertexShader, fragmentShader) {
    var program = gl.createProgram();
    gl.attachShader(
        program,
        createShader(gl, vertexShader, gl.VERTEX_SHADER));
    gl.attachShader(
        program,
        createShader(gl, fragmentShader,  gl.FRAGMENT_SHADER));
    linkProgram(gl, program);
    return program;
  };

  //Link a program.
  var linkProgram = function(gl, program) {
    gl.linkProgram(program);
    var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
    if (!linked) {
      throw "Error linking the shader: " + gl.getProgramInfoLog(program);
      //return false;
    }
    return true;
  };

  //Returns a Magic Uniform Setter
  var getUniformSetter = function(program, info, isArray) {
    var name = info.name,
        loc = gl.getUniformLocation(program, name),
        type = info.type;

    if (info.size > 1 && isArray) {
      switch(type) {
        case gl.FLOAT:
          return function(val) { gl.uniform1fv(loc, new Float32Array(val)); };
        case gl.INT: case gl.BOOL:
          return function(val) { gl.uniform1iv(loc, new Uint16Array(val)); };
      }
    }

    switch (type) {
      case gl.FLOAT:
        return function(val) { gl.uniform1f(loc, val); };
      case gl.FLOAT_VEC2:
        return function(val) { gl.uniform2fv(loc, new Float32Array(val)); };
      case gl.FLOAT_VEC3:
        return function(val) { gl.uniform3fv(loc, new Float32Array(val)); };
      case gl.FLOAT_VEC4:
        return function(val) { gl.uniform4fv(loc, new Float32Array(val)); };
      case gl.INT: case gl.BOOL: case gl.SAMPLER_2D: case gl.SAMPLER_CUBE:
        return function(val) { gl.uniform1i(loc, val); };
      case gl.INT_VEC2: case gl.BOOL_VEC2:
        return function(val) { gl.uniform2iv(loc, new Uint16Array(val)); };
      case gl.INT_VEC3: case gl.BOOL_VEC3:
        return function(val) { gl.uniform3iv(loc, new Uint16Array(val)); };
      case gl.INT_VEC4: case gl.BOOL_VEC4:
        return function(val) { gl.uniform4iv(loc, new Uint16Array(val)); };
      case gl.FLOAT_MAT2:
        return function(val) { gl.uniformMatrix2fv(loc, false, val.toFloat32Array()); };
      case gl.FLOAT_MAT3:
        return function(val) { gl.uniformMatrix3fv(loc, false, val.toFloat32Array()); };
      case gl.FLOAT_MAT4:
        return function(val) { gl.uniformMatrix4fv(loc, false, val.toFloat32Array()); };
    }
    throw "Unknown type: " + type;

  };

  //Program Class: Handles loading of programs and mapping of attributes and uniforms
  var Program = function(vertexShader, fragmentShader) {
    var program = createProgram(gl, vertexShader, fragmentShader);
    if (!program) return false;

    var buffers = {},
        frameBuffers = {},
        renderBuffers = {},
        attributes = {},
        uniforms = {},
        textures = {};

    //fill attribute locations
    var len = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
    for (var i = 0; i < len; i++) {
      var info = gl.getActiveAttrib(program, i),
          name = info.name,
          index = gl.getAttribLocation(program, info.name);
      attributes[name] = index;
    }

    //create uniform setters
    len = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
    for (i = 0; i < len; i++) {
      info = gl.getActiveUniform(program, i);
      name = info.name;
      //if array name then clean the array brackets
      name = name[name.length -1] == ']' ? name.substr(0, name.length -3) : name;
      uniforms[name] = getUniformSetter(program, info, info.name != name);
    }

    this.program = program;
    //handle attributes and uniforms
    this.attributes = attributes;
    this.uniforms = uniforms;
    //handle buffers
    this.buffers = buffers;
    this.bufferMemo = {};
    //handle framebuffers
    this.frameBuffers = frameBuffers;
    this.frameBufferMemo = {};
    //handle framebuffers
    this.renderBuffers = renderBuffers;
    this.renderBufferMemo = {};
    //handle textures
    this.textures = textures;
    this.textureMemo = {};
  };

  Program.prototype = {

    '$$family': 'program',

    setState: function(program) {
      $.extend(program, {
        buffers: this.buffers,
        bufferMemo: this.bufferMemo,
        renderBuffers: this.renderBuffers,
        renderBufferMemo: this.renderBufferMemo,
        frameBuffers: this.frameBuffers,
        frameBufferMemo: this.frameBufferMemo,
        textures: this.textures,
        textureMemo: this.textureMemo
      });
      return this;
    },

    setUniform: function(name, val) {
      if (this.uniforms[name])
        this.uniforms[name](val);
      return this;
    },

    setUniforms: function(obj) {
      for (var name in obj) {
        this.uniforms[name](obj[name]);
        //this.setUniform(name, obj[name]);
      }
      return this;
    },

    setBuffer: function(name, opt) {
      //set defaults
      opt = $.merge({
        bufferType: gl.ARRAY_BUFFER,
        size: 1,
        dataType: gl.FLOAT,
        stride: 0,
        offset: 0,
        drawType: gl.STATIC_DRAW
      }, this.bufferMemo[name] || {}, opt || {});

      var attributeName = opt.attribute || name,
          bufferType = opt.bufferType,
          hasBuffer = name in this.buffers,
          buffer = hasBuffer? this.buffers[name] : gl.createBuffer(),
          hasValue = 'value' in opt,
          value = opt.value,
          size = opt.size,
          dataType = opt.dataType,
          stride = opt.stride,
          offset = opt.offset,
          drawType = opt.drawType,
          loc = this.attributes[attributeName],
          isAttribute = loc !== undefined;

      if (!hasBuffer) {
        this.buffers[name] = buffer;
        isAttribute && gl.enableVertexAttribArray(loc);
      }

      gl.bindBuffer(bufferType, buffer);

      if (hasValue) {
        gl.bufferData(bufferType, value, drawType);
      }

      isAttribute && gl.vertexAttribPointer(loc, size, dataType, false, stride, offset);

      //set default options so we don't have to next time.
      delete opt.value;
      this.bufferMemo[name] = opt;

      return this;
    },

    setBuffers: function(obj) {
      for (var name in obj) {
        this.setBuffer(name, obj[name]);
      }
      return this;
    },

    setFrameBuffer: function(name, opt) {
      //bind/unbind framebuffer
      if (typeof opt != 'object') {
        gl.bindFramebuffer(gl.FRAMEBUFFER, opt? this.frameBuffers[name] : null);
        return;
      }
      //get options
      opt = $.merge({
        width: 0,
        height: 0,
        //All texture params
        bindToTexture: false,
        textureOptions: {
          attachment: gl.COLOR_ATTACHMENT0
        },
        //All render buffer params
        bindToRenderBuffer: false,
        renderBufferOptions: {
          attachment: gl.DEPTH_ATTACHMENT
        }
      }, this.frameBufferMemo[name] || {}, opt || {});

      var bindToTexture = opt.bindToTexture,
          bindToRenderBuffer = opt.bindToRenderBuffer,
          hasBuffer = name in this.frameBuffers,
          frameBuffer = hasBuffer? this.frameBuffers[name] : gl.createFramebuffer(gl.FRAMEBUFFER);

      gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);

      if (!hasBuffer) {
        this.frameBuffers[name] = frameBuffer;
      }

      if (bindToTexture) {
        var texBindOpt = $.merge({
              data: {
                width: opt.width,
                height: opt.height
              }
            }, $.type(bindToTexture) == 'object'? bindToTexture : {}),
            texName = name + '-texture',
            texOpt = opt.textureOptions;

        this.setTexture(texName, texBindOpt);

        gl.framebufferTexture2D(gl.FRAMEBUFFER, texOpt.attachment, this.textureMemo[texName].textureType, this.textures[texName], 0);
      }

      if (bindToRenderBuffer) {
        var rbBindOpt = $.merge({
              width: opt.width,
              height: opt.height
            }, $.type(bindToRenderBuffer) == 'object'? bindToRenderBuffer : {}),
            rbName = name + '-renderbuffer',
            rbOpt = opt.renderBufferOptions;

        this.setRenderBuffer(rbName, rbBindOpt);

        gl.framebufferRenderbuffer(gl.FRAMEBUFFER, rbOpt.attachment, gl.RENDERBUFFER, this.renderBuffers[rbName]);
      }

      gl.bindTexture(gl.TEXTURE_2D, null);
      gl.bindRenderbuffer(gl.RENDERBUFFER, null);
      gl.bindFramebuffer(gl.FRAMEBUFFER, null);

      this.frameBufferMemo[name] = opt;

      return this;
    },

    setFrameBuffers: function(obj) {
      for (var name in obj) {
        this.setFrameBuffer(name, obj[name]);
      }
      return this;
    },

    setRenderBuffer: function(name, opt) {
      if (typeof opt != 'object') {
        gl.bindRenderbuffer(gl.RENDERBUFFER, opt? this.renderBufferMemo[name] : null);
        return;
      }

      opt = $.merge({
        storageType: gl.DEPTH_COMPONENT16,
        width: 0,
        height: 0
      }, this.renderBufferMemo[name] || {}, opt || {});

      var hasBuffer = name in this.renderBuffers,
          renderBuffer = hasBuffer? this.renderBuffers[name] : gl.createRenderbuffer(gl.RENDERBUFFER);

      if (!hasBuffer) {
        this.renderBuffers[name] = renderBuffer;
      }

      gl.bindRenderbuffer(gl.RENDERBUFFER, renderBuffer);

      gl.renderbufferStorage(gl.RENDERBUFFER, opt.storageType, opt.width, opt.height);

      this.renderBufferMemo[name] = opt;

      return this;
    },

    setRenderBuffers: function(obj) {
      for (var name in obj) {
        this.setRenderBuffer(name, obj[name]);
      }
      return this;
    },

    setTexture: function(name, opt) {
      //bind texture
      if (!opt || typeof opt != 'object') {
        gl.activeTexture(opt || gl.TEXTURE0);
        gl.bindTexture(this.textureMemo[name].textureType || gl.TEXTURE_2D, this.textures[name]);
        return;
      }
      //get defaults
      opt = $.merge({
        textureType: gl.TEXTURE_2D,
        pixelStore: [{
          name: gl.UNPACK_FLIP_Y_WEBGL,
          value: true
        }],
        parameters: [{
          name: gl.TEXTURE_MAG_FILTER,
          value: gl.NEAREST
        }, {
          name: gl.TEXTURE_MIN_FILTER,
          value: gl.NEAREST
        }],
        data: {
          format: gl.RGBA,
          value: false,

          width: 0,
          height: 0,
          border: 0
        }

      }, this.textureMemo[name] || {}, opt || {});

      var textureType = ('textureType' in opt)? opt.textureType : gl.TEXTURE_2D,
          hasTexture = name in this.textures,
          texture = hasTexture? this.textures[name] : gl.createTexture(),
          pixelStore = opt.pixelStore,
          parameters = opt.parameters,
          data = opt.data,
          hasValue = !!opt.data.value;

      //save texture
      if (!hasTexture) {
        this.textures[name] = texture;
      }
      gl.bindTexture(textureType, texture);
      if (!hasTexture) {
        //set texture properties
        pixelStore.forEach(function(opt) {
          opt.name = typeof opt.name == 'string'? gl[opt.name] : opt.name;
          gl.pixelStorei(opt.name, opt.value);
        });
      }
      //load texture
      if (hasValue) {
        gl.texImage2D(textureType, 0, data.format, data.format, gl.UNSIGNED_BYTE, data.value);
      } else if (data.width || data.height) {
        gl.texImage2D(textureType, 0, data.format, data.width, data.height, data.border, data.format, gl.UNSIGNED_BYTE, null);
      }
      //set texture parameters
      if (!hasTexture) {
        parameters.forEach(function(opt) {
          opt.name = gl.get(opt.name);
          opt.value = gl.get(opt.value);
          gl.texParameteri(textureType, opt.name, opt.value);
          if (opt.generateMipmap) {
            gl.generateMipmap(textureType);
          }
        });
      }
      //set default options so we don't have to next time.
      delete opt.data;
      this.textureMemo[name] = opt;

      return this;
    },

    setTextures: function(obj) {
      for (var name in obj) {
        this.setTexture(name, obj[name]);
      }
      return this;
    },

    use: function() {
      gl.useProgram(this.program);
      return this;
    }

  };

  //Get options in object or arguments
  function getOptions() {
    var opt;
    if (arguments.length == 2) {
      opt = {
        vs: arguments[0],
        fs: arguments[1]
      };
    } else {
      opt = arguments[0] || {};
    }
    return opt;
  }

  //Create a program from vertex and fragment shader node ids
  Program.fromShaderIds = function() {
    var opt = getOptions.apply({}, arguments),
        vs = $(opt.vs),
        fs = $(opt.fs);

    return new Program(vs.innerHTML, fs.innerHTML);
  };

  //Create a program from vs and fs sources
  Program.fromShaderSources = function(opt) {
    var opt = getOptions.apply({}, arguments),
        vs = opt.vs,
        fs = opt.fs;

    return new Program(opt.vs, opt.fs);
  };

  //Build program from default shaders (requires Shaders)
  Program.fromDefaultShaders = function() {
    var opt = getOptions.apply({}, arguments),
        vs = opt.vs || 'Default',
        fs = opt.fs || 'Default',
        sh = PhiloGL.Shaders;

    return PhiloGL.Program.fromShaderSources(sh.Vertex[vs],
                                              sh.Fragment[fs]);
  };

  //Implement Program.fromShaderURIs (requires IO)
  Program.fromShaderURIs = function(opt) {
    opt = $.merge({
      path: '',
      vs: '',
      fs: '',
      noCache: false,
      onSuccess: $.empty,
      onError: $.empty
    }, opt || {});

    var vertexShaderURI = opt.path + opt.vs,
        fragmentShaderURI = opt.path + opt.fs,
        XHR = PhiloGL.IO.XHR;

    new XHR({
      url: vertexShaderURI,
      noCache: opt.noCache,
      onError: function(arg) {
        opt.onError(arg);
      },
      onSuccess: function(vs) {
        new XHR({
          url: fragmentShaderURI,
          noCache: opt.noCache,
          onError: function(arg) {
            opt.onError(arg);
          },
          onSuccess: function(fs) {
            opt.onSuccess(Program.fromShaderSources(vs, fs));
          }
        }).send();
      }
    }).send();
  };

  PhiloGL.Program = Program;

})();
<commit_msg>Deleting the shader before querying for the info will return an empty string as info. Deleting the Shader after querying for the info will return the proper string with the specified error.<commit_after>//program.js
//Creates programs out of shaders and provides convenient methods for loading
//buffers attributes and uniforms

(function() {
  //First, some privates to handle compiling/linking shaders to programs.

  //Creates a shader from a string source.
  var createShader = function(gl, shaderSource, shaderType) {
    var shader = gl.createShader(shaderType);
    if (shader == null) {
      throw "Error creating the shader with shader type: " + shaderType;
      //return false;
    }
    gl.shaderSource(shader, shaderSource);
    gl.compileShader(shader);
    var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
    if (!compiled) {
      var info = gl.getShaderInfoLog(shader);
      gl.deleteShader(shader);
      throw "Error while compiling the shader " + info;
      //return false;
    }
    return shader;
  };

  //Creates a program from vertex and fragment shader sources.
  var createProgram = function(gl, vertexShader, fragmentShader) {
    var program = gl.createProgram();
    gl.attachShader(
        program,
        createShader(gl, vertexShader, gl.VERTEX_SHADER));
    gl.attachShader(
        program,
        createShader(gl, fragmentShader,  gl.FRAGMENT_SHADER));
    linkProgram(gl, program);
    return program;
  };

  //Link a program.
  var linkProgram = function(gl, program) {
    gl.linkProgram(program);
    var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
    if (!linked) {
      throw "Error linking the shader: " + gl.getProgramInfoLog(program);
      //return false;
    }
    return true;
  };

  //Returns a Magic Uniform Setter
  var getUniformSetter = function(program, info, isArray) {
    var name = info.name,
        loc = gl.getUniformLocation(program, name),
        type = info.type;

    if (info.size > 1 && isArray) {
      switch(type) {
        case gl.FLOAT:
          return function(val) { gl.uniform1fv(loc, new Float32Array(val)); };
        case gl.INT: case gl.BOOL:
          return function(val) { gl.uniform1iv(loc, new Uint16Array(val)); };
      }
    }

    switch (type) {
      case gl.FLOAT:
        return function(val) { gl.uniform1f(loc, val); };
      case gl.FLOAT_VEC2:
        return function(val) { gl.uniform2fv(loc, new Float32Array(val)); };
      case gl.FLOAT_VEC3:
        return function(val) { gl.uniform3fv(loc, new Float32Array(val)); };
      case gl.FLOAT_VEC4:
        return function(val) { gl.uniform4fv(loc, new Float32Array(val)); };
      case gl.INT: case gl.BOOL: case gl.SAMPLER_2D: case gl.SAMPLER_CUBE:
        return function(val) { gl.uniform1i(loc, val); };
      case gl.INT_VEC2: case gl.BOOL_VEC2:
        return function(val) { gl.uniform2iv(loc, new Uint16Array(val)); };
      case gl.INT_VEC3: case gl.BOOL_VEC3:
        return function(val) { gl.uniform3iv(loc, new Uint16Array(val)); };
      case gl.INT_VEC4: case gl.BOOL_VEC4:
        return function(val) { gl.uniform4iv(loc, new Uint16Array(val)); };
      case gl.FLOAT_MAT2:
        return function(val) { gl.uniformMatrix2fv(loc, false, val.toFloat32Array()); };
      case gl.FLOAT_MAT3:
        return function(val) { gl.uniformMatrix3fv(loc, false, val.toFloat32Array()); };
      case gl.FLOAT_MAT4:
        return function(val) { gl.uniformMatrix4fv(loc, false, val.toFloat32Array()); };
    }
    throw "Unknown type: " + type;

  };

  //Program Class: Handles loading of programs and mapping of attributes and uniforms
  var Program = function(vertexShader, fragmentShader) {
    var program = createProgram(gl, vertexShader, fragmentShader);
    if (!program) return false;

    var buffers = {},
        frameBuffers = {},
        renderBuffers = {},
        attributes = {},
        uniforms = {},
        textures = {};

    //fill attribute locations
    var len = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
    for (var i = 0; i < len; i++) {
      var info = gl.getActiveAttrib(program, i),
          name = info.name,
          index = gl.getAttribLocation(program, info.name);
      attributes[name] = index;
    }

    //create uniform setters
    len = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
    for (i = 0; i < len; i++) {
      info = gl.getActiveUniform(program, i);
      name = info.name;
      //if array name then clean the array brackets
      name = name[name.length -1] == ']' ? name.substr(0, name.length -3) : name;
      uniforms[name] = getUniformSetter(program, info, info.name != name);
    }

    this.program = program;
    //handle attributes and uniforms
    this.attributes = attributes;
    this.uniforms = uniforms;
    //handle buffers
    this.buffers = buffers;
    this.bufferMemo = {};
    //handle framebuffers
    this.frameBuffers = frameBuffers;
    this.frameBufferMemo = {};
    //handle framebuffers
    this.renderBuffers = renderBuffers;
    this.renderBufferMemo = {};
    //handle textures
    this.textures = textures;
    this.textureMemo = {};
  };

  Program.prototype = {

    '$$family': 'program',

    setState: function(program) {
      $.extend(program, {
        buffers: this.buffers,
        bufferMemo: this.bufferMemo,
        renderBuffers: this.renderBuffers,
        renderBufferMemo: this.renderBufferMemo,
        frameBuffers: this.frameBuffers,
        frameBufferMemo: this.frameBufferMemo,
        textures: this.textures,
        textureMemo: this.textureMemo
      });
      return this;
    },

    setUniform: function(name, val) {
      if (this.uniforms[name])
        this.uniforms[name](val);
      return this;
    },

    setUniforms: function(obj) {
      for (var name in obj) {
        this.uniforms[name](obj[name]);
        //this.setUniform(name, obj[name]);
      }
      return this;
    },

    setBuffer: function(name, opt) {
      //set defaults
      opt = $.merge({
        bufferType: gl.ARRAY_BUFFER,
        size: 1,
        dataType: gl.FLOAT,
        stride: 0,
        offset: 0,
        drawType: gl.STATIC_DRAW
      }, this.bufferMemo[name] || {}, opt || {});

      var attributeName = opt.attribute || name,
          bufferType = opt.bufferType,
          hasBuffer = name in this.buffers,
          buffer = hasBuffer? this.buffers[name] : gl.createBuffer(),
          hasValue = 'value' in opt,
          value = opt.value,
          size = opt.size,
          dataType = opt.dataType,
          stride = opt.stride,
          offset = opt.offset,
          drawType = opt.drawType,
          loc = this.attributes[attributeName],
          isAttribute = loc !== undefined;

      if (!hasBuffer) {
        this.buffers[name] = buffer;
        isAttribute && gl.enableVertexAttribArray(loc);
      }

      gl.bindBuffer(bufferType, buffer);

      if (hasValue) {
        gl.bufferData(bufferType, value, drawType);
      }

      isAttribute && gl.vertexAttribPointer(loc, size, dataType, false, stride, offset);

      //set default options so we don't have to next time.
      delete opt.value;
      this.bufferMemo[name] = opt;

      return this;
    },

    setBuffers: function(obj) {
      for (var name in obj) {
        this.setBuffer(name, obj[name]);
      }
      return this;
    },

    setFrameBuffer: function(name, opt) {
      //bind/unbind framebuffer
      if (typeof opt != 'object') {
        gl.bindFramebuffer(gl.FRAMEBUFFER, opt? this.frameBuffers[name] : null);
        return;
      }
      //get options
      opt = $.merge({
        width: 0,
        height: 0,
        //All texture params
        bindToTexture: false,
        textureOptions: {
          attachment: gl.COLOR_ATTACHMENT0
        },
        //All render buffer params
        bindToRenderBuffer: false,
        renderBufferOptions: {
          attachment: gl.DEPTH_ATTACHMENT
        }
      }, this.frameBufferMemo[name] || {}, opt || {});

      var bindToTexture = opt.bindToTexture,
          bindToRenderBuffer = opt.bindToRenderBuffer,
          hasBuffer = name in this.frameBuffers,
          frameBuffer = hasBuffer? this.frameBuffers[name] : gl.createFramebuffer(gl.FRAMEBUFFER);

      gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);

      if (!hasBuffer) {
        this.frameBuffers[name] = frameBuffer;
      }

      if (bindToTexture) {
        var texBindOpt = $.merge({
              data: {
                width: opt.width,
                height: opt.height
              }
            }, $.type(bindToTexture) == 'object'? bindToTexture : {}),
            texName = name + '-texture',
            texOpt = opt.textureOptions;

        this.setTexture(texName, texBindOpt);

        gl.framebufferTexture2D(gl.FRAMEBUFFER, texOpt.attachment, this.textureMemo[texName].textureType, this.textures[texName], 0);
      }

      if (bindToRenderBuffer) {
        var rbBindOpt = $.merge({
              width: opt.width,
              height: opt.height
            }, $.type(bindToRenderBuffer) == 'object'? bindToRenderBuffer : {}),
            rbName = name + '-renderbuffer',
            rbOpt = opt.renderBufferOptions;

        this.setRenderBuffer(rbName, rbBindOpt);

        gl.framebufferRenderbuffer(gl.FRAMEBUFFER, rbOpt.attachment, gl.RENDERBUFFER, this.renderBuffers[rbName]);
      }

      gl.bindTexture(gl.TEXTURE_2D, null);
      gl.bindRenderbuffer(gl.RENDERBUFFER, null);
      gl.bindFramebuffer(gl.FRAMEBUFFER, null);

      this.frameBufferMemo[name] = opt;

      return this;
    },

    setFrameBuffers: function(obj) {
      for (var name in obj) {
        this.setFrameBuffer(name, obj[name]);
      }
      return this;
    },

    setRenderBuffer: function(name, opt) {
      if (typeof opt != 'object') {
        gl.bindRenderbuffer(gl.RENDERBUFFER, opt? this.renderBufferMemo[name] : null);
        return;
      }

      opt = $.merge({
        storageType: gl.DEPTH_COMPONENT16,
        width: 0,
        height: 0
      }, this.renderBufferMemo[name] || {}, opt || {});

      var hasBuffer = name in this.renderBuffers,
          renderBuffer = hasBuffer? this.renderBuffers[name] : gl.createRenderbuffer(gl.RENDERBUFFER);

      if (!hasBuffer) {
        this.renderBuffers[name] = renderBuffer;
      }

      gl.bindRenderbuffer(gl.RENDERBUFFER, renderBuffer);

      gl.renderbufferStorage(gl.RENDERBUFFER, opt.storageType, opt.width, opt.height);

      this.renderBufferMemo[name] = opt;

      return this;
    },

    setRenderBuffers: function(obj) {
      for (var name in obj) {
        this.setRenderBuffer(name, obj[name]);
      }
      return this;
    },

    setTexture: function(name, opt) {
      //bind texture
      if (!opt || typeof opt != 'object') {
        gl.activeTexture(opt || gl.TEXTURE0);
        gl.bindTexture(this.textureMemo[name].textureType || gl.TEXTURE_2D, this.textures[name]);
        return;
      }
      //get defaults
      opt = $.merge({
        textureType: gl.TEXTURE_2D,
        pixelStore: [{
          name: gl.UNPACK_FLIP_Y_WEBGL,
          value: true
        }],
        parameters: [{
          name: gl.TEXTURE_MAG_FILTER,
          value: gl.NEAREST
        }, {
          name: gl.TEXTURE_MIN_FILTER,
          value: gl.NEAREST
        }],
        data: {
          format: gl.RGBA,
          value: false,

          width: 0,
          height: 0,
          border: 0
        }

      }, this.textureMemo[name] || {}, opt || {});

      var textureType = ('textureType' in opt)? opt.textureType : gl.TEXTURE_2D,
          hasTexture = name in this.textures,
          texture = hasTexture? this.textures[name] : gl.createTexture(),
          pixelStore = opt.pixelStore,
          parameters = opt.parameters,
          data = opt.data,
          hasValue = !!opt.data.value;

      //save texture
      if (!hasTexture) {
        this.textures[name] = texture;
      }
      gl.bindTexture(textureType, texture);
      if (!hasTexture) {
        //set texture properties
        pixelStore.forEach(function(opt) {
          opt.name = typeof opt.name == 'string'? gl[opt.name] : opt.name;
          gl.pixelStorei(opt.name, opt.value);
        });
      }
      //load texture
      if (hasValue) {
        gl.texImage2D(textureType, 0, data.format, data.format, gl.UNSIGNED_BYTE, data.value);
      } else if (data.width || data.height) {
        gl.texImage2D(textureType, 0, data.format, data.width, data.height, data.border, data.format, gl.UNSIGNED_BYTE, null);
      }
      //set texture parameters
      if (!hasTexture) {
        parameters.forEach(function(opt) {
          opt.name = gl.get(opt.name);
          opt.value = gl.get(opt.value);
          gl.texParameteri(textureType, opt.name, opt.value);
          if (opt.generateMipmap) {
            gl.generateMipmap(textureType);
          }
        });
      }
      //set default options so we don't have to next time.
      delete opt.data;
      this.textureMemo[name] = opt;

      return this;
    },

    setTextures: function(obj) {
      for (var name in obj) {
        this.setTexture(name, obj[name]);
      }
      return this;
    },

    use: function() {
      gl.useProgram(this.program);
      return this;
    }

  };

  //Get options in object or arguments
  function getOptions() {
    var opt;
    if (arguments.length == 2) {
      opt = {
        vs: arguments[0],
        fs: arguments[1]
      };
    } else {
      opt = arguments[0] || {};
    }
    return opt;
  }

  //Create a program from vertex and fragment shader node ids
  Program.fromShaderIds = function() {
    var opt = getOptions.apply({}, arguments),
        vs = $(opt.vs),
        fs = $(opt.fs);

    return new Program(vs.innerHTML, fs.innerHTML);
  };

  //Create a program from vs and fs sources
  Program.fromShaderSources = function(opt) {
    var opt = getOptions.apply({}, arguments),
        vs = opt.vs,
        fs = opt.fs;

    return new Program(opt.vs, opt.fs);
  };

  //Build program from default shaders (requires Shaders)
  Program.fromDefaultShaders = function() {
    var opt = getOptions.apply({}, arguments),
        vs = opt.vs || 'Default',
        fs = opt.fs || 'Default',
        sh = PhiloGL.Shaders;

    return PhiloGL.Program.fromShaderSources(sh.Vertex[vs],
                                              sh.Fragment[fs]);
  };

  //Implement Program.fromShaderURIs (requires IO)
  Program.fromShaderURIs = function(opt) {
    opt = $.merge({
      path: '',
      vs: '',
      fs: '',
      noCache: false,
      onSuccess: $.empty,
      onError: $.empty
    }, opt || {});

    var vertexShaderURI = opt.path + opt.vs,
        fragmentShaderURI = opt.path + opt.fs,
        XHR = PhiloGL.IO.XHR;

    new XHR({
      url: vertexShaderURI,
      noCache: opt.noCache,
      onError: function(arg) {
        opt.onError(arg);
      },
      onSuccess: function(vs) {
        new XHR({
          url: fragmentShaderURI,
          noCache: opt.noCache,
          onError: function(arg) {
            opt.onError(arg);
          },
          onSuccess: function(fs) {
            opt.onSuccess(Program.fromShaderSources(vs, fs));
          }
        }).send();
      }
    }).send();
  };

  PhiloGL.Program = Program;

})();
<|endoftext|>


<commit_before>var curry = require('./curry')
var slice = require('./slice')
var each = require('./each')

var time = module.exports = timeWithBase(1) // millisecond

function inMilliseconds() { return timeWithBase(time.milliseconds) }
function inSeconds() { return timeWithBase(time.seconds) }
function inMinutes() { return timeWithBase(time.minutes) }
function inHours() { return timeWithBase(time.hours) }
function inDays() { return timeWithBase(time.days) }
function inWeeks() { return timeWithBase(time.weeks) }

function timeWithBase(base) {
	var time = {
		now: now,
		ago: ago,
		// for creating instances of time in a different base
		inMilliseconds: inMilliseconds,
		inSeconds: inSeconds,
		inMinutes: inMinutes,
		inHours: inHours,
		inDays: inDays,
		inWeeks: inWeeks
	}

	time.millisecond = 1 / base
	time.second = time.seconds = 1000 * time.millisecond
	time.minute = time.minutes = 60 * time.second
	time.hour = time.hours = 60 * time.minute
	time.day = time.days = 24 * time.hour
	time.week = time.weeks = 7 * time.day

	function now(_base) { return Math.round(new Date().getTime() / (_base || base)) }

	function ago(ts, yield) { return ago.stepFunction(ts, yield) }
	ago.stepFunction = _stepFunction(
		10 * time.second, 'just now', null,
		time.minute, 'less than a minute ago', null,
		2 * time.minute, 'one minute ago', null,
		time.hour, '%N minutes ago', [time.minute],
		2 * time.hour, 'one hour ago', null,
		time.day, '%N hours ago', [time.hour],
		time.day * 2, 'one day ago', null,
		time.week, '%N days ago', [time.day],
		2 * time.week, '1 week ago', [time.week],
		Infinity, '%N weeks ago', [time.week])

	ago.precise = _stepFunction(
		time.minute, '%N seconds ago', [time.second],
		time.hour, '%N minutes, %N seconds ago', [time.minute, time.second],
		time.day, '%N hours, %N minutes ago', [time.hour, time.minute],
		time.week, '%N days, %N hours ago', [time.day, time.hour],
		Infinity, '%N weeks, %N days ago', [time.week, time.day])

	ago.brief = _stepFunction(
		20 * time.second, 'now', null,
		time.minute, '1 min', null,
		time.hour, '%N min', [time.minute],
		2 * time.hour, '1 hr', null,
		time.day, '%N hrs', [time.hour],
		time.day * 2, '1 day', null,
		time.week, '%N days', [time.day],
		2 * time.week, '1 week', null,
		30 * time.day, '%N weeks', [time.week],
		60 * time.day, '1 month', null,
		Infinity, '%N months', [time.day * 30])

	var MAX_TIMEOUT_VALUE = 2147483647
	function _stepFunction() {
		var steps = arguments
		var stepFn = function(unbasedTimestamp, yield) {
			var millisecondsAgo = (now(time.milliseconds) - unbasedTimestamp)
			for (var i=0; i < steps.length; i+=3) {
				if (millisecondsAgo > steps[i]) { continue }
				var result = _getStepResult(millisecondsAgo, steps, i)
				if (yield) {
					yield(result.payload)
					if (result.smallestGranularity) {
						var timeoutIn = Math.min(result.smallestGranularity - (millisecondsAgo % result.smallestGranularity), MAX_TIMEOUT_VALUE)
						setTimeout(curry(stepFn, unbasedTimestamp, yield), timeoutIn * base)
					}
				}
				return result.payload
			}
			return _getStepResult(millisecondsAgo, steps, i - 3).payload // the last one
		}
		return stepFn
	}

	function _getStepResult(millisecondsAgo, steps, i) {
		var stepSize = steps[i]
		var stepPayload = steps[i+1]
		var stepGranularities = steps[i+2]
		var smallestGranularity = stepSize
		var untakenTime = millisecondsAgo
		each(stepGranularities, function(granularity) {
			var granAmount = Math.floor(untakenTime / granularity)
			untakenTime -= granAmount * granularity
			stepPayload = stepPayload.replace('%N', granAmount)
			if (granularity < smallestGranularity) {
				smallestGranularity = granularity
			}
		})
		return { payload:stepPayload, smallestGranularity:smallestGranularity }
	}

	return time
}
<commit_msg>add time.milliseconds<commit_after>var curry = require('./curry')
var slice = require('./slice')
var each = require('./each')

var time = module.exports = timeWithBase(1) // millisecond

function inMilliseconds() { return timeWithBase(time.milliseconds) }
function inSeconds() { return timeWithBase(time.seconds) }
function inMinutes() { return timeWithBase(time.minutes) }
function inHours() { return timeWithBase(time.hours) }
function inDays() { return timeWithBase(time.days) }
function inWeeks() { return timeWithBase(time.weeks) }

function timeWithBase(base) {
	var time = {
		now: now,
		ago: ago,
		// for creating instances of time in a different base
		inMilliseconds: inMilliseconds,
		inSeconds: inSeconds,
		inMinutes: inMinutes,
		inHours: inHours,
		inDays: inDays,
		inWeeks: inWeeks
	}

	time.millisecond = time.milliseconds = 1 / base
	time.second = time.seconds = 1000 * time.millisecond
	time.minute = time.minutes = 60 * time.second
	time.hour = time.hours = 60 * time.minute
	time.day = time.days = 24 * time.hour
	time.week = time.weeks = 7 * time.day

	function now(_base) { return Math.round(new Date().getTime() / (_base || base)) }

	function ago(ts, yield) { return ago.stepFunction(ts, yield) }
	ago.stepFunction = _stepFunction(
		10 * time.second, 'just now', null,
		time.minute, 'less than a minute ago', null,
		2 * time.minute, 'one minute ago', null,
		time.hour, '%N minutes ago', [time.minute],
		2 * time.hour, 'one hour ago', null,
		time.day, '%N hours ago', [time.hour],
		time.day * 2, 'one day ago', null,
		time.week, '%N days ago', [time.day],
		2 * time.week, '1 week ago', [time.week],
		Infinity, '%N weeks ago', [time.week])

	ago.precise = _stepFunction(
		time.minute, '%N seconds ago', [time.second],
		time.hour, '%N minutes, %N seconds ago', [time.minute, time.second],
		time.day, '%N hours, %N minutes ago', [time.hour, time.minute],
		time.week, '%N days, %N hours ago', [time.day, time.hour],
		Infinity, '%N weeks, %N days ago', [time.week, time.day])

	ago.brief = _stepFunction(
		20 * time.second, 'now', null,
		time.minute, '1 min', null,
		time.hour, '%N min', [time.minute],
		2 * time.hour, '1 hr', null,
		time.day, '%N hrs', [time.hour],
		time.day * 2, '1 day', null,
		time.week, '%N days', [time.day],
		2 * time.week, '1 week', null,
		30 * time.day, '%N weeks', [time.week],
		60 * time.day, '1 month', null,
		Infinity, '%N months', [time.day * 30])

	var MAX_TIMEOUT_VALUE = 2147483647
	function _stepFunction() {
		var steps = arguments
		var stepFn = function(unbasedTimestamp, yield) {
			var millisecondsAgo = (now(time.milliseconds) - unbasedTimestamp)
			for (var i=0; i < steps.length; i+=3) {
				if (millisecondsAgo > steps[i]) { continue }
				var result = _getStepResult(millisecondsAgo, steps, i)
				if (yield) {
					yield(result.payload)
					if (result.smallestGranularity) {
						var timeoutIn = Math.min(result.smallestGranularity - (millisecondsAgo % result.smallestGranularity), MAX_TIMEOUT_VALUE)
						setTimeout(curry(stepFn, unbasedTimestamp, yield), timeoutIn * base)
					}
				}
				return result.payload
			}
			return _getStepResult(millisecondsAgo, steps, i - 3).payload // the last one
		}
		return stepFn
	}

	function _getStepResult(millisecondsAgo, steps, i) {
		var stepSize = steps[i]
		var stepPayload = steps[i+1]
		var stepGranularities = steps[i+2]
		var smallestGranularity = stepSize
		var untakenTime = millisecondsAgo
		each(stepGranularities, function(granularity) {
			var granAmount = Math.floor(untakenTime / granularity)
			untakenTime -= granAmount * granularity
			stepPayload = stepPayload.replace('%N', granAmount)
			if (granularity < smallestGranularity) {
				smallestGranularity = granularity
			}
		})
		return { payload:stepPayload, smallestGranularity:smallestGranularity }
	}

	return time
}
<|endoftext|>


<commit_before><commit_msg>Create imt-to-svg.js<commit_after><|endoftext|>


<commit_before><commit_msg>fix script execution<commit_after><|endoftext|>


<commit_before><commit_msg>cantina: enabling Kjelhuset, although there aren't any dinner info there yet<commit_after><|endoftext|>


<commit_before><commit_msg>Opening closed tab sessions works<commit_after><|endoftext|>


<commit_before>/** @jsx React.DOM */

var FireStateMixin = {
	propTypes: {
		firebasePointer: React.PropTypes.object.isRequired,
	},

	version: 0,

	getInitialState: function() { return {
		hackToLetStateBeEmpty: true,
	}},

    componentDidMount: function() {
    	var self = this;
    	this.props.firebasePointer.on("value", function(snapshot) {
    		var snapshotVal = snapshot.val();
    		if (snapshotVal == null) {
    			console.warn("Null version: ", self);
    			return
    		}
    		var snapshotVersion = snapshotVal.version;
    		delete snapshotVal.version;
    		if (self.isMounted() && snapshotVersion > self.version) {
    			console.log("updating version: ", snapshotVersion);
    			self.version = snapshotVersion;
    			self.needsPersist = false;
    			self.setState(snapshotVal);
    			if (snapshotVal == null) {
    				var publics = publicVals(this.state);
    				console.warn("snapshut is null, what should I do?", publics);
    			}
    			//self.replaceState(self.ensureAllValuesPresent(snapshotVal));
    		}
    	});
    },

    // DEAD CODE
    ensureAllValuesPresent: function(stateSnapshot) {
    	var privates = this.privateVals(this.state);
    	var withInitial = React.addons.update(this.getInitialState(), {$merge: stateSnapshot});
    	return React.addons.update(withInitial, {$merge: privates});
    },

    privateVals: function(state) {
    	return _.pick(state, function(value, key) {
    		return key.indexOf("_") == 0;
    	});
    },

    publicVals: function(state) {
    	return _.pick(state, function(value, key) {
    		return !key.indexOf("_") == 0;
    	});
    },

    componentDidUpdate: function(prevProps, prevState) {

    	if (_.isEqual(prevState, this.state)) {
    		console.log("states equal");
    		return;
    	}

    	if (this.readOnly) {
    		console.log("read only")
    		return;
    	}
    	if (!this.needsPersist) {
    		this.needsPersist = true;
    		return;
    	}
    	var stateToSerialize = this.publicVals(this.state);
    	this.version += 1;
    	var newState = React.addons.update(stateToSerialize, {version: {$set: this.version}});
   		var self = this;
    	console.log(newState.version, this.version);
		this.props.firebasePointer.transaction(function(currentState) {
			console.log("running a tx", currentState.version, newState.version);
			if (newState.version > currentState.version) {
				console.log("persisting", newState);
				return newState;
			} else {
				console.warn("Tried to update a stale version");
				return currentState;
			}
		});

	},

	incrementVersion: function() {
		this.props.firebasePointer.child("version").transaction(function(version) {
			return (version || 0) + 1;
		})
	}
}

var App = React.createClass({
	//mixins: [FireStateMixin],
	componentDidMount: function() {

	},

	getInitialState: function() {
		return {
			isLoggedIn: this.props.firebasePointer.getAuth()
			// TODO: separate react component for login
		}
	},

	onLogin: function(authInfo) {
		this.setState({isLoggedIn: true});
	},

	render: function() {
		if (this.state.isLoggedIn) {
			return

						<NotesPane firebasePointer={this.props.firebasePointer.child("notes-pane")} />

						<TodoPane firebasePointer={this.props.firebasePointer.child("todo-pane")} />

;
		} else {
			return <Login firebasePointer={this.props.firebasePointer} onLogin={this.onLogin} />
		}
	}
});

var TodoPane = React.createClass({
	mixins: [FireStateMixin],

	getInitialState: function() {
		return { todos: [], _todo: "" };
	},

	todoChange: function(event) {
		this.setState({_todo: event.target.value});
	},

    parseTags: function(todoText) {
        var tags = todoText.split(",");
        return _.map(tags, function(tag){
            return tag.trim();
        });
    },

	addTodo: function() {
        var todoArray = this.parseTags(this.state._todo);
		this.state.todos.push({
            done: false,
            text: todoArray.shift(), // Removes + returns first item of array
            tags: todoArray
        });
		this.setState({todos: this.state.todos, _todo: ""});
	},

	crossOff: function(index) {
		var self = this;
		return function() {
			var indexUpdate = {}
			indexUpdate[index] = {done: {$apply: function(v) { return !v; }}};
			var newState = React.addons.update(self.state, {todos: indexUpdate});
			console.log(newState);
			self.setState(newState);
		};
	},

	remove: function(index) {
		var self = this;
		return function() {
			var withItemRemoved = React.addons.update(self.state.todos, {$splice: [[index,1]]});
			console.log("with item removed:", withItemRemoved);
			//self.state.todos.splice(index, 1);
			//self.forceUpdate();
			self.setState({todos: withItemRemoved});
		};
	},

	handleKeyDown: function(e) {
		if (e.key === 'Enter') {
    		this.addTodo();
    	}
	},

	render: function() {
		//console.log("rendering todo.", this.state.todos.length);
		var self = this;
		var todoDivs = this.state.todos.map(function(todo, index) {
			var className = todo.done ? "todo-done" : "";
			var doneText = todo.done ? "Undone" : "Done";
            var tagsText = todo.tags? todo.tags.join(', ') : "";
			return

                        <input type="checkbox" checked={todo.done} onClick={self.crossOff(index)}/>
                        {todo.text}

{tagsText}

Remove

;
		});
		return

			<input type="text" className="todo-input" placeholder="Todo?" value={this.state._todo} onChange={this.todoChange} onKeyDown={this.handleKeyDown} />
			<button onClick={this.addTodo} className="add-button btn btn-success">Add</button>

				{todoDivs}

;
	}
});

var NotesPane = React.createClass({

	mixins: [FireStateMixin],
	readOnly: true,

	getInitialState: function() {
		return {
			notes: {},
			_selectedNote: null,
			_title: ""
		};
	},

	addNote: function(name) {
		var name = this.state._title;
		var id = Math.random().toString(36).substring(7);
		this.state.notes[id] = {name: name, text: ""};
		this.setState({notes: this.state.notes, _title: "", _selectedNote: id});
		//debugger;
		var updatedData = {}
		updatedData[id] = {name: name, text: "", version: 1}
		this.props.firebasePointer.child("notes").update(updatedData);
		this.incrementVersion();
	},

	deleteNote: function() {
		var index = this.state._selectedNote;
		this.setState({_selectedNote: null});
		this.props.firebasePointer.child("notes").child(index).update({"deleted": true});
		this.incrementVersion();
	},

	selectNote: function(noteId) {
		var self = this;
		return function() {
			console.log("clicked");
			self.setState({_selectedNote: noteId});
		};
	},

	titleChange: function(event) {
		this.setState({_title: event.target.value});
	},

	render: function() {
		var self = this;
		var nonDeletedNotes = _.pick(this.state.notes, function(note, noteId) {
			return !note.deleted;
		});

		//debugger;
		var notes = _.map(nonDeletedNotes, function(note, noteId) {
			if (noteId == self.state._selectedNote) {
				return

{note.name}

Delete

;
			} else {
				return
{note.name}
;
			}
		});

		var noteId = this.state._selectedNote;
		console.log("noteid: ", noteId);
		var selectedNote = noteId != null ? <NoteEditor key={noteId} noteId={noteId}
			firebasePointer={this.props.firebasePointer.child("notes/" + noteId)} /> :

;

		return

						<input type="text" placeholder="Title" className="note-title" value={this.state._title} onChange={this.titleChange} />
						<button className="btn btn-success add-button" onClick={this.addNote}>Add</button>
						{notes}

						{selectedNote}

;
	}
});

var NoteEditor = React.createClass({
	mixins: [FireStateMixin],
	propTypes: {
		noteId: React.PropTypes.string.isRequired
	},

	getInitialState: function() {
		return {name: "", text: "", _fullScreen: false};
	},

	onTextUpdate: function(text) {
		this.setState({text: text});
	},

	toggleFullscreen: function() {
		this.setState({_fullScreen: true});
	},

	leaveFullscreen: function() {
		this.setState({_fullScreen: false});
	},

	render: function() {
		console.log("parent", this.state._fullScreen);
		return

			{this.state.name}|Fullscreen

				<AceEditor onChange={this.onTextUpdate} startingText={this.state.text}
				fullScreen={this.state._fullScreen}
				exitFullScreen={this.leaveFullscreen}
				/>

;
	}
});
<commit_msg>Made TodoItem its own React component<commit_after>/** @jsx React.DOM */

var FireStateMixin = {
	propTypes: {
		firebasePointer: React.PropTypes.object.isRequired,
	},

	version: 0,

	getInitialState: function() { return {
		hackToLetStateBeEmpty: true,
	}},

    componentDidMount: function() {
    	var self = this;
    	this.props.firebasePointer.on("value", function(snapshot) {
    		var snapshotVal = snapshot.val();
    		if (snapshotVal == null) {
    			console.warn("Null version: ", self);
    			return
    		}
    		var snapshotVersion = snapshotVal.version;
    		delete snapshotVal.version;
    		if (self.isMounted() && snapshotVersion > self.version) {
    			console.log("updating version: ", snapshotVersion);
    			self.version = snapshotVersion;
    			self.needsPersist = false;
    			self.setState(snapshotVal);
    			if (snapshotVal == null) {
    				var publics = publicVals(this.state);
    				console.warn("snapshut is null, what should I do?", publics);
    			}
    			//self.replaceState(self.ensureAllValuesPresent(snapshotVal));
    		}
    	});
    },

    // DEAD CODE
    ensureAllValuesPresent: function(stateSnapshot) {
    	var privates = this.privateVals(this.state);
    	var withInitial = React.addons.update(this.getInitialState(), {$merge: stateSnapshot});
    	return React.addons.update(withInitial, {$merge: privates});
    },

    privateVals: function(state) {
    	return _.pick(state, function(value, key) {
    		return key.indexOf("_") == 0;
    	});
    },

    publicVals: function(state) {
    	return _.pick(state, function(value, key) {
    		return !key.indexOf("_") == 0;
    	});
    },

    componentDidUpdate: function(prevProps, prevState) {

    	if (_.isEqual(prevState, this.state)) {
    		console.log("states equal");
    		return;
    	}

    	if (this.readOnly) {
    		console.log("read only")
    		return;
    	}
    	if (!this.needsPersist) {
    		this.needsPersist = true;
    		return;
    	}
    	var stateToSerialize = this.publicVals(this.state);
    	this.version += 1;
    	var newState = React.addons.update(stateToSerialize, {version: {$set: this.version}});
   		var self = this;
    	console.log(newState.version, this.version);
		this.props.firebasePointer.transaction(function(currentState) {
			console.log("running a tx", currentState.version, newState.version);
			if (newState.version > currentState.version) {
				console.log("persisting", newState);
				return newState;
			} else {
				console.warn("Tried to update a stale version");
				return currentState;
			}
		});

	},

	incrementVersion: function() {
		this.props.firebasePointer.child("version").transaction(function(version) {
			return (version || 0) + 1;
		})
	}
}

var App = React.createClass({
	//mixins: [FireStateMixin],
	componentDidMount: function() {

	},

	getInitialState: function() {
		return {
			isLoggedIn: this.props.firebasePointer.getAuth()
			// TODO: separate react component for login
		}
	},

	onLogin: function(authInfo) {
		this.setState({isLoggedIn: true});
	},

	render: function() {
		if (this.state.isLoggedIn) {
			return

						<NotesPane firebasePointer={this.props.firebasePointer.child("notes-pane")} />

						<TodoPane firebasePointer={this.props.firebasePointer.child("todo-pane")} />

;
		} else {
			return <Login firebasePointer={this.props.firebasePointer} onLogin={this.onLogin} />
		}
	}
});

var TodoPane = React.createClass({
	mixins: [FireStateMixin],

	getInitialState: function() {
		return { todos: [], _todo: "" };
	},

	todoChange: function(event) {
		this.setState({_todo: event.target.value});
	},

    parseTags: function(todoText) {
        var tags = todoText.split(",");
        return _.map(tags, function(tag){
            return tag.trim();
        });
    },

	addTodo: function() {
        var todoArray = this.parseTags(this.state._todo);
		this.state.todos.push({
            done: false,
            text: todoArray.shift(), // Removes + returns first item of array
            tags: todoArray
        });
		this.setState({todos: this.state.todos, _todo: ""});
	},

	crossOff: function(index) {
		var self = this;
		return function() {
			var indexUpdate = {}
			indexUpdate[index] = {done: {$apply: function(v) { return !v; }}};
			var newState = React.addons.update(self.state, {todos: indexUpdate});
			console.log(newState);
			self.setState(newState);
		};
	},

	remove: function(index) {
		var self = this;
		return function() {
			var withItemRemoved = React.addons.update(self.state.todos, {$splice: [[index,1]]});
			console.log("with item removed:", withItemRemoved);
			//self.state.todos.splice(index, 1);
			//self.forceUpdate();
			self.setState({todos: withItemRemoved});
		};
	},

	handleKeyDown: function(e) {
		if (e.key === 'Enter') {
    		this.addTodo();
    	}
	},

	render: function() {
		//console.log("rendering todo.", this.state.todos.length);
		var self = this;
		var todoDivs = this.state.todos.map(function(todo, index) {
            return <TodoItem done={todo.done} text={todo.text} tags={todo.tags} index={index}
                      crossOff={self.crossOff} remove={self.remove} key={index} />
        });
		return

			<input type="text" className="todo-input" placeholder="Todo?" value={this.state._todo} onChange={this.todoChange} onKeyDown={this.handleKeyDown} />
			<button onClick={this.addTodo} className="add-button btn btn-success">Add</button>

				{todoDivs}

;
	}
});

var TodoItem = React.createClass({
    propTypes: {
        done: React.PropTypes.bool,
        text: React.PropTypes.string,
        tags: React.PropTypes.array,
        index: React.PropTypes.number,
        crossOff: React.PropTypes.func,
        remove: React.PropTypes.func,
    },

    render: function() {
        var className = this.props.done ? "todo-done" : "";
        var doneText = this.props.done ? "Undone" : "Done";
        var tagsText = this.props.tags? this.props.tags.join(', ') : "";
        return

                    <input type="checkbox" defaultChecked={this.props.done} onClick={this.props.crossOff(this.props.index)}/>
                    {this.props.text}

{tagsText}

Remove

;

    }
});

var NotesPane = React.createClass({

	mixins: [FireStateMixin],
	readOnly: true,

	getInitialState: function() {
		return {
			notes: {},
			_selectedNote: null,
			_title: ""
		};
	},

	addNote: function(name) {
		var name = this.state._title;
		var id = Math.random().toString(36).substring(7);
		this.state.notes[id] = {name: name, text: ""};
		this.setState({notes: this.state.notes, _title: "", _selectedNote: id});
		//debugger;
		var updatedData = {}
		updatedData[id] = {name: name, text: "", version: 1}
		this.props.firebasePointer.child("notes").update(updatedData);
		this.incrementVersion();
	},

	deleteNote: function() {
		var index = this.state._selectedNote;
		this.setState({_selectedNote: null});
		this.props.firebasePointer.child("notes").child(index).update({"deleted": true});
		this.incrementVersion();
	},

	selectNote: function(noteId) {
		var self = this;
		return function() {
			console.log("clicked");
			self.setState({_selectedNote: noteId});
		};
	},

	titleChange: function(event) {
		this.setState({_title: event.target.value});
	},

	render: function() {
		var self = this;
		var nonDeletedNotes = _.pick(this.state.notes, function(note, noteId) {
			return !note.deleted;
		});

		var notes = _.map(nonDeletedNotes, function(note, noteId) {
			if (noteId == self.state._selectedNote) {
				return

{note.name}

Delete

;
			} else {
				return
{note.name}
;
			}
		});

		var noteId = this.state._selectedNote;
		console.log("noteid: ", noteId);
		var selectedNote = noteId != null ? <NoteEditor key={noteId} noteId={noteId}
			firebasePointer={this.props.firebasePointer.child("notes/" + noteId)} /> :

;

		return

						<input type="text" placeholder="Title" className="note-title" value={this.state._title} onChange={this.titleChange} />
						<button className="btn btn-success add-button" onClick={this.addNote}>Add</button>
						{notes}

						{selectedNote}

;
	}
});

var NoteEditor = React.createClass({
	mixins: [FireStateMixin],
	propTypes: {
		noteId: React.PropTypes.string.isRequired
	},

	getInitialState: function() {
		return {name: "", text: "", _fullScreen: false};
	},

	onTextUpdate: function(text) {
		this.setState({text: text});
	},

	toggleFullscreen: function() {
		this.setState({_fullScreen: true});
	},

	leaveFullscreen: function() {
		this.setState({_fullScreen: false});
	},

	render: function() {
		console.log("parent", this.state._fullScreen);
		return

			{this.state.name}|Fullscreen

				<AceEditor onChange={this.onTextUpdate} startingText={this.state.text}
				fullScreen={this.state._fullScreen}
				exitFullScreen={this.leaveFullscreen}
				/>

;
	}
});
<|endoftext|>


<commit_before>//query backend API

var getUrlParam = function GetURLParameter(sParam) {
    var sPageURL = window.location.search.substring(1);
    var sURLVariables = sPageURL.split('&');
    for (var i = 0; i < sURLVariables.length; i++)
    {
        var sParameterName = sURLVariables[i].split('=');
        if (sParameterName[0] == sParam)
        {
            return sParameterName[1];
        }
    }
}

var fromLoc = "ithaca"
var to = getUrlParam('loc');
var howlong = getUrlParam('time');

if($("#thisshouldonlybeavailableonplan").length) {
	$("#thisshouldonlybeavailableonplan").ready(function() {

		$.ajax({
			type: "GET",
			url: "https://aggregate.gogogogo.co/yolo/yolo/"+howlong+"/"+fromLoc+"/"+to,
			//url: "https://aggregate.gogogogo.co/yolo/yolo/5/rochester/pittsburgh",
			success: function(r) {
				console.log(r);
				$("div#header").html("Your trip from " + r.from + " to " + r.to + "!");
				var inboundtrip = r.flights.inbound[0].tripSegment;
				$("#tag_holder div:nth-of-type(1)").ready(function() {
					$("p#flightId").html(inboundtrip[0][0].flightID);
					$("p#airline").html(inboundtrip[0][0].airline);
					$("p#fltno").html(inboundtrip[0][0].fltno);
					$("p#depart").html(inboundtrip[0][0].depart);
					$("p#arrival").html(inboundtrip[1][0].arrival);

				});
				var hotel = r.hotel;
				$("#tag_holder div:nth-of-type(2)").ready(function() {
					$("p#name").html(hotel.name);
					$("p#overallRating").html(hotel.overallRating);
					$("p#addressLine1").html(hotel.address.addressLine1);
					$("p#cityName").html(hotel.address.cityName);
					$("p#stateCode").html(hotel.address.stateCode);
				});
				var eat = r.places.food[0];
				$("#tag_holder div:nth-of-type(3)").ready(function() {
					$("p#fname").html(eat.name);
					$("p#faddress").html(eat.address);
				});

				var poi = r.places.poi[0];
				$("#tag_holder div:nth-of-type(4)").ready(function() {
					$("p#pname").html(poi.name);
					$("p#paddress").html(poi.address);
				});

				var eat2 = r.places.food[1];
				$("#tag_holder div:nth-of-type(6)").ready(function() {
					$("p#fname1").html(eat2.name);
					$("p#faddress1").html(eat2.address);
				});

				var poi2 = r.places.poi[1];
				$("#tag_holder div:nth-of-type(7)").ready(function() {
					$("p#pname1").html(poi2.name);
					$("p#paddress1").html(poi2.address);
				});

				var eat3 = r.places.food[2];
				$("#tag_holder div:nth-of-type(8)").ready(function() {
					$("p#fname2").html(eat3.name);
					$("p#faddress2").html(eat3.address);
				});
				var outboundtrip = r.flights.outbound[0].tripSegment;
				$("#tag_holder div:nth-of-type(9)").ready(function() {
					$("p#flightId").html(outboundtrip[0][0].flightID);
					$("p#airline").html(outboundtrip[0][0].airline);
					$("p#fltno").html(outboundtrip[0][0].fltno);
					$("p#depart").html(outboundtrip[0][0].depart);
					$("p#arrival").html(outboundtrip[1][0].arrival);
				var cost = r.totalCost;
				$("p#price").ready(function() {
					$("p#price").html(cost);
				})

			},
			error: function(xhr, textStatus, errorThrown) {
				return textStatus;
			}
		});
	});
};

<commit_msg>brackets<commit_after>//query backend API

var getUrlParam = function GetURLParameter(sParam) {
    var sPageURL = window.location.search.substring(1);
    var sURLVariables = sPageURL.split('&');
    for (var i = 0; i < sURLVariables.length; i++)
    {
        var sParameterName = sURLVariables[i].split('=');
        if (sParameterName[0] == sParam)
        {
            return sParameterName[1];
        }
    }
}

var fromLoc = "ithaca"
var to = getUrlParam('loc');
var howlong = getUrlParam('time');

if($("#thisshouldonlybeavailableonplan").length) {
	$("#thisshouldonlybeavailableonplan").ready(function() {

		$.ajax({
			type: "GET",
			url: "https://aggregate.gogogogo.co/yolo/yolo/"+howlong+"/"+fromLoc+"/"+to,
			//url: "https://aggregate.gogogogo.co/yolo/yolo/5/rochester/pittsburgh",
			success: function(r) {
				console.log(r);
				$("div#header").html("Your trip from " + r.from + " to " + r.to + "!");
				var inboundtrip = r.flights.inbound[0].tripSegment;
				$("#tag_holder div:nth-of-type(1)").ready(function() {
					$("p#flightId").html(inboundtrip[0][0].flightID);
					$("p#airline").html(inboundtrip[0][0].airline);
					$("p#fltno").html(inboundtrip[0][0].fltno);
					$("p#depart").html(inboundtrip[0][0].depart);
					$("p#arrival").html(inboundtrip[1][0].arrival);

				});
				var hotel = r.hotel;
				$("#tag_holder div:nth-of-type(2)").ready(function() {
					$("p#name").html(hotel.name);
					$("p#overallRating").html(hotel.overallRating);
					$("p#addressLine1").html(hotel.address.addressLine1);
					$("p#cityName").html(hotel.address.cityName);
					$("p#stateCode").html(hotel.address.stateCode);
				});
				var eat = r.places.food[0];
				$("#tag_holder div:nth-of-type(3)").ready(function() {
					$("p#fname").html(eat.name);
					$("p#faddress").html(eat.address);
				});

				var poi = r.places.poi[0];
				$("#tag_holder div:nth-of-type(4)").ready(function() {
					$("p#pname").html(poi.name);
					$("p#paddress").html(poi.address);
				});

				var eat2 = r.places.food[1];
				$("#tag_holder div:nth-of-type(6)").ready(function() {
					$("p#fname1").html(eat2.name);
					$("p#faddress1").html(eat2.address);
				});

				var poi2 = r.places.poi[1];
				$("#tag_holder div:nth-of-type(7)").ready(function() {
					$("p#pname1").html(poi2.name);
					$("p#paddress1").html(poi2.address);
				});

				var eat3 = r.places.food[2];
				$("#tag_holder div:nth-of-type(8)").ready(function() {
					$("p#fname2").html(eat3.name);
					$("p#faddress2").html(eat3.address);
				});
				var outboundtrip = r.flights.outbound[0].tripSegment;
				$("#tag_holder div:nth-of-type(9)").ready(function() {
					$("p#flightId").html(outboundtrip[0][0].flightID);
					$("p#airline").html(outboundtrip[0][0].airline);
					$("p#fltno").html(outboundtrip[0][0].fltno);
					$("p#depart").html(outboundtrip[0][0].depart);
					$("p#arrival").html(outboundtrip[1][0].arrival);
				});
				var cost = r.totalCost;
				$("p#price").ready(function() {
					$("p#price").html(cost);
				})

			},
			error: function(xhr, textStatus, errorThrown) {
				return textStatus;
			}
		});
	});
};

<|endoftext|>


<commit_before><commit_msg>Hitbtc2: Add BadSymbol exception<commit_after><|endoftext|>