<commit_before>#!/usr/bin/env node
/* Copyright Ben Trask and other contributors. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE. */
if(process.argv.length < 2) {
	console.error("Usage: earthfs [repo-path]");
	process.exit();
}

var crypto = require("crypto");
var pathModule = require("path");
var urlModule = require("url");
var util = require("util");
var os = require("os");
var fs = require("fs");
var https = require("https");

var pg = require("pg");
var formidable = require("formidable");
var mkdirp = require("mkdirp");
var ioServer = require("socket.io");
var ioClient = require('socket.io-client');

var bt = require("./utilities/bt");
var fsx = require("./utilities/fsx");
var http = require("./utilities/httpx");
var sql = require("./utilities/sql");

var formatters = require("./formatters");
var querylang = require("./query-languages");

var Client = require("./classes/Client");
var query = require("./classes/query");
var Repo = require("./classes/Repo");
Repo.makeWriteable();

var CLIENT = __dirname+"/../build";

var EXT = require("./utilities/ext.json");
var MIME = require("./utilities/mime.json");
var QUERY_TYPES = ["text/html", "text/json"];

var repo = Repo.loadSync(process.argv[2]);

function has(obj, prop) {
	return Object.prototype.hasOwnProperty.call(obj, prop);
}

function componentsFromPath(path) {
	var l = path.length;
	var a = "/" === path[0] ? 1 : 0;
	var b = "/" === path[l-1] ? 1 : 0;
	if(a+b >= l) return [];
	return path.slice(a, -b || undefined).split("/").map(function(x) {
		return decodeURIComponent(x);
	});
}
function pathFromComponents(components) {
	if(!components.length) return "";
	return "/"+components.map(function(x) {
		return encodeURIComponent(x);
	}).join("/");
}
function lookup(obj, prop) {
	if(!obj || !prop) return null; // TODO: Be more robust.
	if(has(obj, prop)) return obj[prop];
	return null;
}
function first(array) {
	return array.length ? array[0] : null;
}
function rest(array) {
	return array.slice(1);
}

var server;
(function() {
	try {
		server = https.createServer({
			key: fs.readFileSync(repo.KEY),
			cert: fs.readFileSync(repo.CERT),
			honorCipherOrder: true,
		}, serve);
		server.scheme = "https";
	} catch(e) {
		server = http.createServer(serve);
		server.scheme = "http";
	}
})();
function serve(req, res) {
	var obj = urlModule.parse(req.url, true);
	var path = obj.pathname;
	var options = obj.query;
	var components = componentsFromPath(path);
	if(-1 !== components.indexOf("..")) {
		res.sendMessage(400, "Bad Request");
		return;
	}
	serve.root(req, res, {
		"path": path,
		"components": components,
		"options": options,
	});
}
serve.root = function(req, res, root) {
	var components = root.components;
	var imp = lookup(serve.root, first(components));
	if(!imp) {
		var path = CLIENT+root.path;
		fs.stat(path, function(err, stats) {
			if(err) return res.sendError(err);
			res.sendFile(stats.isDirectory() ? path+"/index.html" : path);
		});
		return;
	}
	imp(req, res, root, {
		"path": pathFromComponents(components),
		"components": rest(components),
		"options": root.options,
	});
};
serve.root.entry = function(req, res, root, entry) {
	var URN = first(entry.components);
	if(!URN) {
		res.sendMessage(400, "Bad Request");
		return;
	}
	repo.db.query(
		'SELECT e."entryID", e."hash", e."type"'+
		' FROM "entries" AS e'+
		' LEFT JOIN "URIs" AS u ON (u."entryID" = e."entryID")'+
		' WHERE u."URI" = $1', [URN],
		function(err, results) {
			if(err) {
				res.sendError(err);
				return;
			}
			if(!results.rows.length) {
				res.sendMessage(404, "Not Found");
				return;
			}
			var row = results.rows[0];
			var srcType = row.type;
			var srcPath = repo.pathForEntry(repo.DATA, row.hash, srcType);
			var dstTypes = (req.headers.accept || "*/*").split(",");
			sendFormatted(req, res, srcPath, srcType, dstTypes, row.hash);
		}
	);
};
function sendFormatted(req, res, srcPath, srcType, dstTypes, hash) {
	var obj = formatters.select(srcType, dstTypes);
	if(!obj) {
		res.sendMessage(406, "Not Acceptable");
		return;
	}
	var dstType = obj.dstType;
	var dstPath = dstType === srcType ? srcPath : repo.pathForEntry(repo.CACHE, hash, dstType);
	var format = obj.format;
	if("text/" === dstType.slice(0, 5)) dstType += "; charset=utf-8";

	function sendFile(path, stats) {
		var stream = fs.createReadStream(dstPath);
		res.writeHead(200, {
			"Content-Type": dstType,
			"Content-Length": stats.size,
		});
		stream.pipe(res);
	}

	fs.stat(dstPath, function(err, stats) {
		if(!err) {
			sendFile(dstPath, stats);
		} else if("ENOENT" === err.code) {
			if(!format) return res.sendError(err);
			mkdirp(pathModule.dirname(dstPath), function(err) {
				if(err) return res.sendError(err);
				format(srcPath, dstPath, function(err) {
					if(err) return res.sendError(err);
					fs.stat(dstPath, function(err, stats) {
						if(err) return res.sendError(err);
						sendFile(dstPath, stats);
					});
				});
			});
		} else {
			res.sendError(err);
		}
	});
}

serve.root.submit = function(req, res, root, submit) {
	if("127.0.0.1" !== req.connection.remoteAddress) {
		res.sendMessage(403, "Forbidden");
		return;
	}
	if("POST" !== req.method) {
		res.sendMessage(405, "Method Not Allowed");
		return;
	}
	function fail(err) {
		console.log(err);
		res.sendMessage(500, "Internal Server Error");
	}
	var form = new formidable.IncomingForm({
		"keepExtensions": false,
	});
	form.addListener("error", function(err) {
		fail(err);
	});
	var hashes = {};
	form.onPart = function(part) {
		if("entry" !== part.name) return; // TODO: Is skipping other parts a good idea?
		var ext = pathModule.extname(part.filename);
		var type = bt.has(MIME, ext) ? MIME[ext] : part.mime; // TODO: Keep charset if possible.
		repo.addEntryStream(part, type, function(err, primaryURN) {
			if(err) return res.sendError(err);
			res.writeHead(303, {"Location": primaryURN});
			res.end();
		});
	};
	form.parse(req);
};
repo.on("entry", function(URN, entryID) {
	Client.all.forEach(function(client) {
		var obj = client.query.SQL(2, "\t");
		sql.debug(repo.db,
			'SELECT $1 IN \n'+
				obj.query+
			'AS matches', [entryID].concat(obj.parameters),
			function(err, results) {
				if(err) console.log(err);
				if(results.rows[0].matches) client.send(URN);
			}
		);
	});
});

var ioOpts = {log: false};
ioServer.listen(server, ioOpts).sockets.on("connection", streamServe);
function streamServe(socket) {
	socket.emit("connected", function(params) {
		var str = params["q"].split("+").map(decodeURIComponent).join(" ");
		// TODO: Use some sort of global query that filters hidden posts, etc.
		querylang.parse(str, "lispish", function(err, query) {
			var client = new Client(socket, query);
			var tab, obj;
			if(params["all"]) { // TODO: I know this is really ugly.
				tab = "";
				obj = query.SQL(1, tab+"\t");
				var stream = repo.db.query(
					'SELECT e."entryID", \'urn:sha1:\' || e."hash" AS "URN"\n'+
					'FROM "entries" AS e\n'+
					'WHERE e."entryID" IN\n'+
						obj.query+
					'ORDER BY e."entryID" ASC',
					obj.parameters
				);
				stream.on("row", function(row) {
					socket.emit("entry", row.URN);
				});
				stream.on("end", function() {
					if(client.connected) Client.all.push(client);
					// Start watching for new entries.
				});
			} else {
				tab = "\t";
				obj = query.SQL(1, tab+"\t");
				repo.db.query(
					'SELECT * FROM (\n'+
						tab+'SELECT e."entryID", \'urn:sha1:\' || e."hash" AS "URN"\n'+
						tab+'FROM "entries" AS e\n'+
						tab+'WHERE e."entryID" IN\n'+
							obj.query+
						tab+'ORDER BY e."entryID" DESC LIMIT 50\n'+
					') x ORDER BY "entryID" ASC',
					obj.parameters,
					function(err, results) {
						if(err) console.log(err); // TODO
						socket.emit("entries", results.rows.map(function(row) {
							return row.URN;
						}));
						if(client.connected) Client.all.push(client);
						// Start watching for new entries.
					}
				);
			}
		});
	});
}

var PORT = repo.config.port >>> 0 || 8001;
server.listen(PORT, function() {
	console.log(""+server.scheme+"://localhost:"+PORT+"/");
	// TODO: Optionally set up NAT traversal/UPnP.
});

var Remote = require("./classes/Remote");
repo.db.query(
	'SELECT "remoteURL", "query" FROM "remotes" WHERE TRUE', [],
	function(err, results) {
		if(err) return console.log(err);
		results.rows.forEach(function(row) {
			var remote = new Remote(repo, row.remoteURL, row.query);
		});
	}
);
<commit_msg>Better Socket.IO options.<commit_after>#!/usr/bin/env node
/* Copyright Ben Trask and other contributors. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE. */
if(process.argv.length < 2) {
	console.error("Usage: earthfs [repo-path]");
	process.exit();
}

var crypto = require("crypto");
var pathModule = require("path");
var urlModule = require("url");
var util = require("util");
var os = require("os");
var fs = require("fs");
var https = require("https");

var pg = require("pg");
var formidable = require("formidable");
var mkdirp = require("mkdirp");
var ioServer = require("socket.io");
var ioClient = require('socket.io-client');

var bt = require("./utilities/bt");
var fsx = require("./utilities/fsx");
var http = require("./utilities/httpx");
var sql = require("./utilities/sql");

var formatters = require("./formatters");
var querylang = require("./query-languages");

var Client = require("./classes/Client");
var query = require("./classes/query");
var Repo = require("./classes/Repo");
Repo.makeWriteable();

var CLIENT = __dirname+"/../build";

var EXT = require("./utilities/ext.json");
var MIME = require("./utilities/mime.json");
var QUERY_TYPES = ["text/html", "text/json"];

var repo = Repo.loadSync(process.argv[2]);

function has(obj, prop) {
	return Object.prototype.hasOwnProperty.call(obj, prop);
}

function componentsFromPath(path) {
	var l = path.length;
	var a = "/" === path[0] ? 1 : 0;
	var b = "/" === path[l-1] ? 1 : 0;
	if(a+b >= l) return [];
	return path.slice(a, -b || undefined).split("/").map(function(x) {
		return decodeURIComponent(x);
	});
}
function pathFromComponents(components) {
	if(!components.length) return "";
	return "/"+components.map(function(x) {
		return encodeURIComponent(x);
	}).join("/");
}
function lookup(obj, prop) {
	if(!obj || !prop) return null; // TODO: Be more robust.
	if(has(obj, prop)) return obj[prop];
	return null;
}
function first(array) {
	return array.length ? array[0] : null;
}
function rest(array) {
	return array.slice(1);
}

var server;
(function() {
	try {
		server = https.createServer({
			key: fs.readFileSync(repo.KEY),
			cert: fs.readFileSync(repo.CERT),
			honorCipherOrder: true,
		}, serve);
		server.scheme = "https";
	} catch(e) {
		server = http.createServer(serve);
		server.scheme = "http";
	}
})();
function serve(req, res) {
	var obj = urlModule.parse(req.url, true);
	var path = obj.pathname;
	var options = obj.query;
	var components = componentsFromPath(path);
	if(-1 !== components.indexOf("..")) {
		res.sendMessage(400, "Bad Request");
		return;
	}
	serve.root(req, res, {
		"path": path,
		"components": components,
		"options": options,
	});
}
serve.root = function(req, res, root) {
	var components = root.components;
	var imp = lookup(serve.root, first(components));
	if(!imp) {
		var path = CLIENT+root.path;
		fs.stat(path, function(err, stats) {
			if(err) return res.sendError(err);
			res.sendFile(stats.isDirectory() ? path+"/index.html" : path);
		});
		return;
	}
	imp(req, res, root, {
		"path": pathFromComponents(components),
		"components": rest(components),
		"options": root.options,
	});
};
serve.root.entry = function(req, res, root, entry) {
	var URN = first(entry.components);
	if(!URN) {
		res.sendMessage(400, "Bad Request");
		return;
	}
	repo.db.query(
		'SELECT e."entryID", e."hash", e."type"'+
		' FROM "entries" AS e'+
		' LEFT JOIN "URIs" AS u ON (u."entryID" = e."entryID")'+
		' WHERE u."URI" = $1', [URN],
		function(err, results) {
			if(err) {
				res.sendError(err);
				return;
			}
			if(!results.rows.length) {
				res.sendMessage(404, "Not Found");
				return;
			}
			var row = results.rows[0];
			var srcType = row.type;
			var srcPath = repo.pathForEntry(repo.DATA, row.hash, srcType);
			var dstTypes = (req.headers.accept || "*/*").split(",");
			sendFormatted(req, res, srcPath, srcType, dstTypes, row.hash);
		}
	);
};
function sendFormatted(req, res, srcPath, srcType, dstTypes, hash) {
	var obj = formatters.select(srcType, dstTypes);
	if(!obj) {
		res.sendMessage(406, "Not Acceptable");
		return;
	}
	var dstType = obj.dstType;
	var dstPath = dstType === srcType ? srcPath : repo.pathForEntry(repo.CACHE, hash, dstType);
	var format = obj.format;
	if("text/" === dstType.slice(0, 5)) dstType += "; charset=utf-8";

	function sendFile(path, stats) {
		var stream = fs.createReadStream(dstPath);
		res.writeHead(200, {
			"Content-Type": dstType,
			"Content-Length": stats.size,
		});
		stream.pipe(res);
	}

	fs.stat(dstPath, function(err, stats) {
		if(!err) {
			sendFile(dstPath, stats);
		} else if("ENOENT" === err.code) {
			if(!format) return res.sendError(err);
			mkdirp(pathModule.dirname(dstPath), function(err) {
				if(err) return res.sendError(err);
				format(srcPath, dstPath, function(err) {
					if(err) return res.sendError(err);
					fs.stat(dstPath, function(err, stats) {
						if(err) return res.sendError(err);
						sendFile(dstPath, stats);
					});
				});
			});
		} else {
			res.sendError(err);
		}
	});
}

serve.root.submit = function(req, res, root, submit) {
	if("127.0.0.1" !== req.connection.remoteAddress) {
		res.sendMessage(403, "Forbidden");
		return;
	}
	if("POST" !== req.method) {
		res.sendMessage(405, "Method Not Allowed");
		return;
	}
	function fail(err) {
		console.log(err);
		res.sendMessage(500, "Internal Server Error");
	}
	var form = new formidable.IncomingForm({
		"keepExtensions": false,
	});
	form.addListener("error", function(err) {
		fail(err);
	});
	var hashes = {};
	form.onPart = function(part) {
		if("entry" !== part.name) return; // TODO: Is skipping other parts a good idea?
		var ext = pathModule.extname(part.filename);
		var type = bt.has(MIME, ext) ? MIME[ext] : part.mime; // TODO: Keep charset if possible.
		repo.addEntryStream(part, type, function(err, primaryURN) {
			if(err) return res.sendError(err);
			res.writeHead(303, {"Location": primaryURN});
			res.end();
		});
	};
	form.parse(req);
};
repo.on("entry", function(URN, entryID) {
	Client.all.forEach(function(client) {
		var obj = client.query.SQL(2, "\t");
		sql.debug(repo.db,
			'SELECT $1 IN \n'+
				obj.query+
			'AS matches', [entryID].concat(obj.parameters),
			function(err, results) {
				if(err) console.log(err);
				if(results.rows[0].matches) client.send(URN);
			}
		);
	});
});

var ioOpts = {
	"browser client minification": true,
	"browser client etag": true,
	"browser client gzip": true,
	"log level": 1,
};
ioServer.listen(server, ioOpts).sockets.on("connection", streamServe);
function streamServe(socket) {
	socket.emit("connected", function(params) {
		var str = params["q"].split("+").map(decodeURIComponent).join(" ");
		// TODO: Use some sort of global query that filters hidden posts, etc.
		querylang.parse(str, "lispish", function(err, query) {
			var client = new Client(socket, query);
			var tab, obj;
			if(params["all"]) { // TODO: I know this is really ugly.
				tab = "";
				obj = query.SQL(1, tab+"\t");
				var stream = repo.db.query(
					'SELECT e."entryID", \'urn:sha1:\' || e."hash" AS "URN"\n'+
					'FROM "entries" AS e\n'+
					'WHERE e."entryID" IN\n'+
						obj.query+
					'ORDER BY e."entryID" ASC',
					obj.parameters
				);
				stream.on("row", function(row) {
					socket.emit("entry", row.URN);
				});
				stream.on("end", function() {
					if(client.connected) Client.all.push(client);
					// Start watching for new entries.
				});
			} else {
				tab = "\t";
				obj = query.SQL(1, tab+"\t");
				repo.db.query(
					'SELECT * FROM (\n'+
						tab+'SELECT e."entryID", \'urn:sha1:\' || e."hash" AS "URN"\n'+
						tab+'FROM "entries" AS e\n'+
						tab+'WHERE e."entryID" IN\n'+
							obj.query+
						tab+'ORDER BY e."entryID" DESC LIMIT 50\n'+
					') x ORDER BY "entryID" ASC',
					obj.parameters,
					function(err, results) {
						if(err) console.log(err); // TODO
						socket.emit("entries", results.rows.map(function(row) {
							return row.URN;
						}));
						if(client.connected) Client.all.push(client);
						// Start watching for new entries.
					}
				);
			}
		});
	});
}

var PORT = repo.config.port >>> 0 || 8001;
server.listen(PORT, function() {
	console.log(""+server.scheme+"://localhost:"+PORT+"/");
	// TODO: Optionally set up NAT traversal/UPnP.
});

var Remote = require("./classes/Remote");
repo.db.query(
	'SELECT "remoteURL", "query" FROM "remotes" WHERE TRUE', [],
	function(err, results) {
		if(err) return console.log(err);
		results.rows.forEach(function(row) {
			var remote = new Remote(repo, row.remoteURL, row.query);
		});
	}
);
<|endoftext|>


<commit_before>(function (window, $, undefined) {
    'use strict';

    var Telemetry;

    Telemetry = function Telemetry(cockpit) {
        console.log("Loading Telemetry plugin in the browser.");

        // Instance variables
        this.cockpit = cockpit;
	this.telemetry = new Object();
	this.rawTelemetry = ko.observableArray([]);

        // Add required UI elements
	$("#rov_status_panel").append(
                '
\

\

\
		           \
		           \

\

\

');

	var self = this;
        setInterval(function(){self.displayTelemetry();}, 1000);
        // Register the various event handlers
        this.listen();
	ko.applyBindings(this,$("#rov_status_panel")[0]);

    };

    //This pattern will hook events in the cockpit and pull them all back
    //so that the reference to this instance is available for further processing
    Telemetry.prototype.listen = function listen() {
        var self = this;

	this.cockpit.socket.on('status', function(data) {
            self.logStatusData(data);
        });

    };

    Telemetry.prototype.logStatusData = function logStatusData(data){
	for (var i in data){
	  this.telemetry[i] = data[i];
	};
   };

    Telemetry.prototype.displayTelemetry = function displayTelemetry(){
	this.rawTelemetry([]);
	for (var item in this.telemetry){
	  if (this.telemetry.hasOwnProperty(item)) {
	    this.rawTelemetry().push({ key: item, value: this.telemetry[item] });
	  }
	};

	this.rawTelemetry.valueHasMutated();
   };

    window.Cockpit.plugins.push(Telemetry);

}(window, jQuery));
<commit_msg>fixed #158: Swapped knockout bindings for document fragment approach for telemtry updates to improve rendering speed.<commit_after>(function (window, $, undefined) {
    'use strict';

    var Telemetry;

    Telemetry = function Telemetry(cockpit) {
        console.log("Loading Telemetry plugin in the browser.");

        // Instance variables
        this.cockpit = cockpit;
	this.telemetry = new Object();
	this.rawTelemetry = ko.observableArray([]);

        // Add required UI elements
	$("#rov_status_panel").append(
                '
\

\

\

\

\

');

/*
        // Add required UI elements
	$("#rov_status_panel").append(
                '
\

\

\
		           \
		           \

\

\

');
*/
	var self = this;
        setInterval(function(){self.displayTelemetry();}, 1000);
        // Register the various event handlers
        this.listen();
	ko.applyBindings(this,$("#rov_status_panel")[0]);

    };

    //This pattern will hook events in the cockpit and pull them all back
    //so that the reference to this instance is available for further processing
    Telemetry.prototype.listen = function listen() {
        var self = this;

	this.cockpit.socket.on('status', function(data) {
            self.logStatusData(data);
        });

    };

    Telemetry.prototype.logStatusData = function logStatusData(data){
	for (var i in data){
	  this.telemetry[i] = data[i];
	};
   };

/*  var div = document.getElementsByTagName("div");

var fragment = document.createDocumentFragment();
for ( var e = 0; e < elems.length; e++ ) {
    fragment.appendChild( elems[e] );
}

for ( var i = 0; i < div.length; i++ ) {
    div[i].appendChild( fragment.cloneNode(true) );
} */

    Telemetry.prototype.displayTelemetry = function displayTelemetry(){
	this.rawTelemetry([]);
	var fragment = document.createDocumentFragment();

	for (var item in this.telemetry){
	  if (this.telemetry.hasOwnProperty(item)) {
	    //this.rawTelemetry().push({ key: item, value: this.telemetry[item] });
	    var li = document.createElement("LI");
	    li.appendChild(document.createElement("SPAN").appendChild(document.createTextNode(item+" ")));
	    li.appendChild(document.createElement("SPAN").appendChild(document.createTextNode(this.telemetry[item])));
	    fragment.appendChild(li);
	  }
	}
	$('#TelemetryList').empty();
	$('#TelemetryList')[0].appendChild(fragment.cloneNode(true));

	//this.rawTelemetry.valueHasMutated();
   };

    window.Cockpit.plugins.push(Telemetry);

}(window, jQuery));
<|endoftext|>


<commit_before>// var requireDir = require('require-dir');
// var gulp = require('gulp');

var less = require('./dist/tasks/less');
var sass = require('./dist/tasks/sass');
var eslint = require('./dist/tasks/eslint');
var stylus = require('./dist/tasks/stylus');
var clean = require('./dist/tasks/clean');
var copy = require('./dist/tasks/copy');
var bump = require('./dist/tasks/bump');
var serve = require('./dist/tasks/serve');
var karma = require('./dist/tasks/karma');

var sequence = require('./dist/tasks/sequence');
var gulpWatch = require('./dist/tasks/watch');

less({name: 'less', src: 'test/src/*.less', dest: 'test/dist/'});
sass({name: 'sass', src: 'test/src/*.scss', dest: 'test/dist/'});
stylus({name: 'stylus', src: 'test/src/*.styl', dest: 'test/dist/'});
eslint({name: 'eslint', src: 'test/src/*.js' });
clean({name: 'clean', paths: ['test/dist']});
copy({name: 'copy', src: 'test/src/**/*.js', dest: 'test/dist'});
bump({ name: 'bump' });
karma({ name: 'karma', config: 'test/karma.conf.js' });
serve({
    port: 9000,
    startPath: 'test/src',
    files: [ 'test/src/*.*' ],
    server: {
        baseDir: ['./'],
        middleware: function middleWare(req, res, next) {
            res.setHeader('Access-Control-Allow-Origin', '*');
            next();
        }
    }
});

gulpWatch({ name: 'watch', watchers: [
    { path: 'test/src/test.styl', tasks: ['stylus'] },
    { path: 'test/src/test.js', tasks: ['eslint'] }
]});

sequence('default', ['clean', [ 'stylus', 'eslint' ], 'watch']);

// Karma
// Git tag
// Create release
<commit_msg>update gulpfile with comments to explain basic usage<commit_after>
/* Include all the types of tasks that you need in your project */
/* These are just a few examples */
var eslint = require('./dist/tasks/eslint');
var stylus = require('./dist/tasks/stylus');
var clean = require('./dist/tasks/clean');

var sequence = require('./dist/tasks/sequence');
var gulpWatch = require('./dist/tasks/watch');

/**
 * To set up a task, simply call the method and include an object with options.
 * Read instructions for each task to find required and optional options.
 */
eslint({name: 'eslint', src: 'test/src/*.js' });
stylus({
    name: 'stylus',
    src: 'test/src/*.styl',
    dest: 'test/dist/',
    stylus: {
        use: nib(),
        compress: false
    }
});

/**
 * It is recommended to give each task a name, but if you omit that property the
 * task will be given the same name as the task constructor. In the example below,
 * the name will be clean.
 */
clean({paths: ['test/dist']});

/**
 * Gulp watch is a special task that sets up a task with watchers. Each entry in
 * the watchers object will be added as a gulp.watch.
 */
gulpWatch({ name: 'watch', watchers: [
    { path: 'test/src/test.styl', tasks: ['stylus'] },
    { path: 'test/src/test.js', tasks: ['eslint'] }
]});

/**
 * Sequence is the other special type of task. A sequence task will run all tasks
 * given as the second argument.
 * Tasks will be run in series, except if they are enclosed in a second array, in
 * which case they will run in parallell.
 *
 * @example
 * [ 'task1', 'task2', [ 'task3', 'task4' ], 'task5' ];
 *
 * Task 1 will run first. When it completes
 * Task 2 will run. When it completes
 * Task3 and Task4 will run in parallel. When they have both completed
 * Task 5 will run
 */
sequence('default', [[ 'stylus', 'eslint' ], 'watch']);
<|endoftext|>


<commit_before>module.exports = {

	//---------------------------------------------------------------------
	// Action Name
	//
	// This is the name of the action displayed in the editor.
	//---------------------------------------------------------------------

	name: "Weather",

	//---------------------------------------------------------------------
	// Action Section
	//
	// This is the section the action will fall into.
	//---------------------------------------------------------------------

	section: "Other Stuff",

	//---------------------------------------------------------------------
	// Action Subtitle
	//
	// This function generates the subtitle displayed next to the name.
	//---------------------------------------------------------------------

	subtitle: function (data) {
		const info = ['Temperature', 'Weather Text', 'Date', 'City', 'Country', 'Region', 'Wind Speed', 'Wind Chill', 'Wind Direction', 'Humidity', 'Pressure', 'Atmosphere Visibility', 'Sunrise Time', 'Sunset Time'];
		return `${info[parseInt(data.info)]}`;
	},

	//---------------------------------------------------------------------
	// DBM Mods Manager Variables (Optional but nice to have!)
	//
	// These are variables that DBM Mods Manager uses to show information
	// about the mods for people to see in the list.
	//---------------------------------------------------------------------

	// Who made the mod (If not set, defaults to "DBM Mods")
	author: "EGGSY",

	// The version of the mod (Defaults to 1.0.0)
	version: "1.8.7",

	// A short description to show on the mod line for this mod (Must be on a single line)
	short_description: "Stores weather informations with node module.",

	// If it depends on any other mods by name, ex: WrexMODS if the mod uses something from WrexMods

	//---------------------------------------------------------------------

	//---------------------------------------------------------------------
	// Action Storage Function
	//
	// Stores the relevant variable info for the editor.
	//---------------------------------------------------------------------

	variableStorage: function (data, varType) {
		const type = parseInt(data.storage);
		if (type !== varType) return;
		const info = parseInt(data.info);
		let dataType = 'Unknown Weather Type';
		switch (info) {
			case 0:
				dataType = "Temperature";
				break;
			case 1:
				dataType = "Weather - Text";
				break;
			case 2:
				dataType = "Date";
				break;
			case 3:
				dataType = "Weather - City";
				break;
			case 4:
				dataType = "Weather - Country";
				break;
			case 5:
				dataType = "Weather - Region";
				break;
			case 6:
				dataType = "Wind Speed";
				break;
			case 7:
				dataType = "Wind Chill";
				break;
			case 8:
				dataType = "Wind Direction";
				break;
			case 9:
				dataType = "Atmosphere Humidty";
				break;
			case 10:
				dataType = "Atmosphere Pressure";
				break;
			case 11:
				dataType = "Atmosphere Visibility";
				break;
			case 12:
				dataType = "Weather - Sunrise";
				break;
			case 13:
				dataType = "Weather - Sunset";
				break;
		}
		return ([data.varName, dataType]);
	},

	//---------------------------------------------------------------------
	// Action Fields
	//
	// These are the fields for the action. These fields are customized
	// by creating elements with corresponding IDs in the HTML. These
	// are also the names of the fields stored in the action's JSON data.
	//---------------------------------------------------------------------

	fields: ["city", "degreeType", "info", "storage", "varName"],

	//---------------------------------------------------------------------
	// Command HTML
	//
	// This function returns a string containing the HTML used for
	// editting actions.
	//
	// The "isEvent" parameter will be true if this action is being used
	// for an event. Due to their nature, events lack certain information,
	// so edit the HTML to reflect this.
	//
	// The "data" parameter stores constants for select elements to use.
	// Each is an array: index 0 for commands, index 1 for events.
	// The names are: sendTargets, members, roles, channels,
	//                messages, servers, variables
	//---------------------------------------------------------------------

	html: function (isEvent, data) {
		return `

				Mod Info:

				Created by EGGSY!

		Source City:

		<input id="city" class="round" type="text">

	 	Degree Type:

	 	<select id="degreeType" class="round">
			<option value="F">F</option>
			<option value="C">C</option>
		</select>

		Source Info:

		<select id="info" class="round">
			<option value="0">Temperature</option>
			<option value="1">Weather Text</option>
			<option value="2">Date</option>
			<option value="3">City</option>
			<option value="4">Country</option>
			<option value="5">Region</option>
			<option value="6">Wind Speed</option>
			<option value="7">Wind Chill</option>
			<option value="8">Wind Direction</option>
			<option value="9">Humidity</option>
			<option value="10">Pressure</option>
			<option value="11">Atmosphere Visibility</option>
			<option value="12">Sunrise Time</option>
			<option value="13">Sunset Time</option>
		</select>

			Store In:

			<select id="storage" class="round" onchange="glob.variableChange(this, 'varNameContainer')">
				${data.variables[0]}
			</select>

			Variable Name:

			<input id="varName" class="round" type="text">

`
	},

	//---------------------------------------------------------------------
	// Action Editor Init Code
	//
	// When the HTML is first applied to the action editor, this code
	// is also run. This helps add modifications or setup reactionary
	// functions for the DOM elements.
	//---------------------------------------------------------------------

	init: function () {
		const { glob, document } = this;
		glob.variableChange(document.getElementById('storage'), 'varNameContainer');
	},

	//---------------------------------------------------------------------
	// Action Bot Function
	//
	// This is the function for the action within the Bot's Action class.
	// Keep in mind event calls won't have access to the "msg" parameter,
	// so be sure to provide checks for variable existance.
	//---------------------------------------------------------------------

	action: function (cache) {
		const data = cache.actions[cache.index];
		const info = parseInt(data.info);
		const city = this.evalMessage(data.city, cache);
		const degreeType2 = this.evalMessage(data.degreeType, cache);

		// Check if everything is ok:
		if (!city) return console.log("Please specify a city to get weather informations.");

		// Main code:
		const WrexMODS = this.getWrexMods(); // as always.
		const weather = WrexMODS.require('yahoo-weather'); // WrexMODS'll automatically try to install the module if you run it with CMD/PowerShell.

		weather(`${city}`, `${degreeType2}`).then(response => {
			switch (info) {
				case 0:
					result = response.item.condition.temp;
					break;
				case 1:
					result = response.item.condition.text;
					break;
				case 2:
					result = response.item.condition.date;
					break;
				case 3:
					result = response.location.city;
					break;
				case 4:
					result = response.location.country;
					break;
				case 5:
					result = response.location.region;
					break;
				case 6:
					result = response.wind.speed;
					break;
				case 7:
					result = response.wind.chill;
					break;
				case 8:
					result = response.wind.direction;
					break;
				case 9:
					result = response.atmosphere.humidity;
					break;
				case 10:
					result = response.atmosphere.pressure;
					break;
				case 11:
					result = response.atmosphere.visibility;
					break;
				case 12:
					result = response.astronomy.sunrise;
					break;
				case 13:
					result = response.astronomy.sunset;
					break;
				case 14:
					result = response.image.url;
					break;
				default:
					break;
			}
			if (result !== undefined) {
				const storage = parseInt(data.storage);
				const varName2 = this.evalMessage(data.varName, cache);
				this.storeValue(result, storage, varName2, cache);
			}
			this.callNextAction(cache);
		}).catch(err => {
			console.log("ERROR:", err)
		});
	},

	//---------------------------------------------------------------------
	// Action Bot Mod
	//
	// Upon initialization of the bot, this code is run. Using the bot's
	// DBM namespace, one can add/modify existing functions if necessary.
	// In order to reduce conflictions between mods, be sure to alias
	// functions you wish to overwrite.
	//---------------------------------------------------------------------

	mod: function (DBM) { }

}; // End of module
<commit_msg>A little bug fix for "Weather MOD"!<commit_after>module.exports = {

	//---------------------------------------------------------------------
	// Action Name
	//
	// This is the name of the action displayed in the editor.
	//---------------------------------------------------------------------

	name: "Weather",

	//---------------------------------------------------------------------
	// Action Section
	//
	// This is the section the action will fall into.
	//---------------------------------------------------------------------

	section: "Other Stuff",

	//---------------------------------------------------------------------
	// Action Subtitle
	//
	// This function generates the subtitle displayed next to the name.
	//---------------------------------------------------------------------

	subtitle: function (data) {
		const info = ['Temperature', 'Weather Text', 'Date', 'City', 'Country', 'Region', 'Wind Speed', 'Wind Chill', 'Wind Direction', 'Humidity', 'Pressure', 'Atmosphere Visibility', 'Sunrise Time', 'Sunset Time'];
		return `${info[parseInt(data.info)]}`;
	},

	//---------------------------------------------------------------------
	// DBM Mods Manager Variables (Optional but nice to have!)
	//
	// These are variables that DBM Mods Manager uses to show information
	// about the mods for people to see in the list.
	//---------------------------------------------------------------------

	// Who made the mod (If not set, defaults to "DBM Mods")
	author: "EGGSY",

	// The version of the mod (Defaults to 1.0.0)
	version: "1.8.7",

	// A short description to show on the mod line for this mod (Must be on a single line)
	short_description: "Stores weather informations with node module.",

	// If it depends on any other mods by name, ex: WrexMODS if the mod uses something from WrexMods

	//---------------------------------------------------------------------

	//---------------------------------------------------------------------
	// Action Storage Function
	//
	// Stores the relevant variable info for the editor.
	//---------------------------------------------------------------------

	variableStorage: function (data, varType) {
		const type = parseInt(data.storage);
		if (type !== varType) return;
		const info = parseInt(data.info);
		let dataType = 'Unknown Weather Type';
		switch (info) {
			case 0:
				dataType = "Temperature";
				break;
			case 1:
				dataType = "Weather - Text";
				break;
			case 2:
				dataType = "Date";
				break;
			case 3:
				dataType = "Weather - City";
				break;
			case 4:
				dataType = "Weather - Country";
				break;
			case 5:
				dataType = "Weather - Region";
				break;
			case 6:
				dataType = "Wind Speed";
				break;
			case 7:
				dataType = "Wind Chill";
				break;
			case 8:
				dataType = "Wind Direction";
				break;
			case 9:
				dataType = "Atmosphere Humidty";
				break;
			case 10:
				dataType = "Atmosphere Pressure";
				break;
			case 11:
				dataType = "Atmosphere Visibility";
				break;
			case 12:
				dataType = "Weather - Sunrise";
				break;
			case 13:
				dataType = "Weather - Sunset";
				break;
		}
		return ([data.varName, dataType]);
	},

	//---------------------------------------------------------------------
	// Action Fields
	//
	// These are the fields for the action. These fields are customized
	// by creating elements with corresponding IDs in the HTML. These
	// are also the names of the fields stored in the action's JSON data.
	//---------------------------------------------------------------------

	fields: ["city", "degreeType", "info", "storage", "varName"],

	//---------------------------------------------------------------------
	// Command HTML
	//
	// This function returns a string containing the HTML used for
	// editting actions.
	//
	// The "isEvent" parameter will be true if this action is being used
	// for an event. Due to their nature, events lack certain information,
	// so edit the HTML to reflect this.
	//
	// The "data" parameter stores constants for select elements to use.
	// Each is an array: index 0 for commands, index 1 for events.
	// The names are: sendTargets, members, roles, channels,
	//                messages, servers, variables
	//---------------------------------------------------------------------

	html: function (isEvent, data) {
		return `

				Mod Info:

				Created by EGGSY!

		Source City:

		<input id="city" class="round" type="text">

	 	Degree Type:

	 	<select id="degreeType" class="round">
			<option value="F">F</option>
			<option value="C">C</option>
		</select>

		Source Info:

		<select id="info" class="round">
			<option value="0">Temperature</option>
			<option value="1">Weather Text</option>
			<option value="2">Date</option>
			<option value="3">City</option>
			<option value="4">Country</option>
			<option value="5">Region</option>
			<option value="6">Wind Speed</option>
			<option value="7">Wind Chill</option>
			<option value="8">Wind Direction</option>
			<option value="9">Humidity</option>
			<option value="10">Pressure</option>
			<option value="11">Atmosphere Visibility</option>
			<option value="12">Sunrise Time</option>
			<option value="13">Sunset Time</option>
		</select>

			Store In:

			<select id="storage" class="round" onchange="glob.variableChange(this, 'varNameContainer')">
				${data.variables[0]}
			</select>

			Variable Name:

			<input id="varName" class="round" type="text">

`
	},

	//---------------------------------------------------------------------
	// Action Editor Init Code
	//
	// When the HTML is first applied to the action editor, this code
	// is also run. This helps add modifications or setup reactionary
	// functions for the DOM elements.
	//---------------------------------------------------------------------

	init: function () {
		const { glob, document } = this;
		glob.variableChange(document.getElementById('storage'), 'varNameContainer');
	},

	//---------------------------------------------------------------------
	// Action Bot Function
	//
	// This is the function for the action within the Bot's Action class.
	// Keep in mind event calls won't have access to the "msg" parameter,
	// so be sure to provide checks for variable existance.
	//---------------------------------------------------------------------

	action: function (cache) {
		const data = cache.actions[cache.index];
		const info = parseInt(data.info);
		const city = this.evalMessage(data.city, cache);
		const degreeType2 = this.evalMessage(data.degreeType, cache);

		// Check if everything is ok:
		if (!city) return console.log("Please specify a city to get weather informations.");

		// Main code:
		const WrexMODS = this.getWrexMods(); // as always.
		const weather = WrexMODS.require('yahoo-weather'); // WrexMODS'll automatically try to install the module if you run it with CMD/PowerShell.

		weather(`${city}`, `${degreeType2}`).then(response => {
			switch (info) {
				case 0:
					result = response.item.condition.temp;
					break;
				case 1:
					result = response.item.condition.text;
					break;
				case 2:
					result = response.item.condition.date;
					break;
				case 3:
					result = response.location.city;
					break;
				case 4:
					result = response.location.country;
					break;
				case 5:
					result = response.location.region;
					break;
				case 6:
					result = response.wind.speed;
					break;
				case 7:
					result = response.wind.chill;
					break;
				case 8:
					result = response.wind.direction;
					break;
				case 9:
					result = response.atmosphere.humidity;
					break;
				case 10:
					result = response.atmosphere.pressure;
					break;
				case 11:
					result = response.atmosphere.visibility;
					break;
				case 12:
					result = response.astronomy.sunrise;
					break;
				case 13:
					result = response.astronomy.sunset;
					break;
				default:
					break;
			}
			if (result !== undefined) {
				const storage = parseInt(data.storage);
				const varName2 = this.evalMessage(data.varName, cache);
				this.storeValue(result, storage, varName2, cache);
			}
			this.callNextAction(cache);
		}).catch(err => {
			console.log("ERROR:", err)
		});
	},

	//---------------------------------------------------------------------
	// Action Bot Mod
	//
	// Upon initialization of the bot, this code is run. Using the bot's
	// DBM namespace, one can add/modify existing functions if necessary.
	// In order to reduce conflictions between mods, be sure to alias
	// functions you wish to overwrite.
	//---------------------------------------------------------------------

	mod: function (DBM) { }

}; // End of module
<|endoftext|>


<commit_before>import React from 'react';
import Page from '../components/page';

export default () => (
  <Page title="documentation">

Packages

        // TODO: write docs

          @vx/annotation

LinePath

          @vx/axis

              /axis

Axis

AxisBottom

AxisLeft

AxisRight

AxisTop

              /constants

orientation

              /utils

center

identity

isHorizontal

isLeft

          @vx/curve

basis

basisClose

basisOpen

step

stepAfter

stepBefore

bundle

linear

linearClosed

monotoneX

monotoneY

cardinal

cardinalClosed

cardinalOpen

catmullRom

catmullRomClosed

catmullRomOpen

natural

          @vx/glyph

Dot

Glyph

          @vx/grid

Grid

Columns

Rows

          @vx/group

Group

          @vx/marker

Marker

          @vx/mock-data

              /generators

genDateValue

              /mocks

appleStock

letterFrequency

          @vx/pattern

Circles

Hexagons

Lines

Path

Pattern

Waves

          @vx/point

Point

          @vx/responsive

              /components

ScaleSVG

              /enhancers

withScreenSize

          @vx/scale

scaleBand

scalePoint

scaleLinear

scaleTime

scaleLog

scalePower

          @vx/shape

AreaClosed

AreaStack

Bar

Line

LinePath

          @vx/text

TextBackground

TextOutline

TextWrap

  </Page>
)
<commit_msg>[docs] update docs layout<commit_after>import React from 'react';
import Page from '../components/page';

export default () => (
  <Page title="documentation">

Packages

        // TODO: write docs

          @vx/annotation

LinePath

          @vx/axis

              /axis

Axis

AxisBottom

AxisLeft

AxisRight

AxisTop

              /constants

orientation

              /utils

center

identity

isHorizontal

isLeft

          @vx/curve

basis

basisClose

basisOpen

step

stepAfter

stepBefore

bundle

linear

linearClosed

monotoneX

monotoneY

cardinal

cardinalClosed

cardinalOpen

catmullRom

catmullRomClosed

catmullRomOpen

natural

          @vx/glyph

Dot

Glyph

          @vx/grid

Grid

Columns

Rows

          @vx/group

Group

          @vx/marker

Marker

          @vx/mock-data

              /generators

genDateValue

              /mocks

appleStock

browserUsage

groupDateValue

letterFrequency

          @vx/pattern

Circles

Hexagons

Lines

Path

Pattern

Waves

          @vx/point

Point

          @vx/responsive

              /components

ScaleSVG

              /enhancers

withScreenSize

          @vx/scale

scaleBand

scalePoint

scaleLinear

scaleTime

scaleLog

scalePower

          @vx/shape

AreaClosed

AreaStack

Bar

Line

LinePath

          @vx/text

TextBackground

TextOutline

TextWrap

  </Page>
)
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import Relay from 'react-relay';
import TeamMembers from './TeamMembers'
import TeamActivities from './TeamActivities'
import TeamProjects from './TeamProjects'
import Tags from './Tags'
import SocialProfiles from './SocialProfiles'
import { Link } from 'react-router';
import FontAwesome from 'react-fontawesome';
import UpdateTeamMutation from '../../relay/UpdateTeamMutation';
import Message from '../Message';
import CreateContactMutation from '../../relay/CreateContactMutation';
import UpdateContactMutation from '../../relay/UpdateContactMutation';

class TeamComponent extends Component {

  constructor(props) {
    super(props);
    this.state = {
      isEditingNameAndDescription: false
    };
  }

  cancelEditTeam(e) {
     e.preventDefault();
     this.setState({isEditingNameAndDescription: false});
  }

  editTeamInfo(){
    var that = this,
         name = document.getElementById('team__name-container').value;
    var description = document.getElementById('team__description-container').value;

    var onFailure = (transaction) => {

        transaction.getError().json().then(function(json) {
          var message = 'Sorry, could not edit the team';
          if (json.error) {
            message = json.error;
          }
          that.setState({ message: message });
        });

        this.setState({isEditingNameAndDescription: false});

    };

    var onSuccess = (response) => {
     //  var tid = response.createTeam.team.id;
     //  var decodedId = base64.decode(tid);
     //  this.props.history.push('/' + decodedId);
      this.setState({ message: null });
      this.setState({isEditingNameAndDescription: false});

    };

    Relay.Store.commitUpdate(
      new UpdateTeamMutation({
       name: name,
       description: description,
       id: this.props.team.id
     }),
     { onSuccess, onFailure }
   );
  }

  updateTeamContacts(){
    var that = this,
         location = document.getElementById('team__location-container').value,
         link = document.getElementById('team__link-container').value,
         contact = this.props.team.contacts.edges[0];
    console.log("create team start");
    var onFailure = (transaction) => {

        transaction.getError().json().then(function(json) {
          var message = 'Sorry, could not edit the team';
          if (json.error) {
            message = json.error;
          }
          that.setState({ message: message });
        });

        this.setState({isEditingNameAndDescription: false});

        console.log("create team fail");

    };

    var onSuccess = (response) => {
     //  var tid = response.createTeam.team.id;
     //  var decodedId = base64.decode(tid);
     //  this.props.history.push('/' + decodedId);
      this.setState({ message: null });
      this.setState({isEditingNameAndDescription: false});
      console.log("create team sucess");

    };

    Relay.Store.commitUpdate(
      new UpdateContactMutation({
       location: location,
       web: link,
       id: contact.node.id,
     }),
     { onSuccess, onFailure }
   );
  }
  createTeamContacts(){
    var that = this,
    location = document.getElementById('team__location-container').value,
    link = document.getElementById('team__link-container').value;
    console.log("create team start");
    var onFailure = (transaction) => {

        transaction.getError().json().then(function(json) {
          var message = 'Sorry, could not edit the team';
          if (json.error) {
            message = json.error;
          }
          that.setState({ message: message });
        });

        this.setState({isEditingNameAndDescription: false});

        console.log("create team fail");

    };

    var onSuccess = (response) => {
     //  var tid = response.createTeam.team.id;
     //  var decodedId = base64.decode(tid);
     //  this.props.history.push('/' + decodedId);
      this.setState({ message: null });
      this.setState({isEditingNameAndDescription: false});
      console.log("create team sucess");

    };

    Relay.Store.commitUpdate(
      new CreateContactMutation({
       location: location,
       web: link,
       team_id: this.props.team.dbid,
       parent_id: this.props.team.id,
       parent_type: "team"
     }),
     { onSuccess, onFailure }
   );
  }

  handleEditTeam(e) {
     e.preventDefault();
     this.editTeamInfo();
     if (this.props.team.contacts.edges[0]) {
       this.createTeamContacts();
     } else {
       this.updateTeamContacts();
     }
  }
  handleEntreEditTeamNameAndDescription(e) {
    e.preventDefault();
    this.setState({isEditingNameAndDescription: true});
  }
  render() {
    const team = this.props.team;
    const isEditing = this.state.isEditingNameAndDescription;
    const contact =this.props.team.contacts.edges[0];
    return (

        <Message message={this.state.message} />

          {(() => {
            if (isEditing) {
              return (

                  <button onClick={this.cancelEditTeam.bind(this)} className='team__cancel-button'>Cancel</button>
                  <button onClick={this.handleEditTeam.bind(this)} className='team__save-button'>Save</button>

              );
            } else {
              return (

                  <button onClick={this.handleEntreEditTeamNameAndDescription.bind(this)} className='team__edit-button'>
                    <FontAwesome className='team__edit-icon' name='pencil'/> Edit profile
                  </button>

              );
            }
          })()}

          {(() => {
            if (this.state.isEditingNameAndDescription) {

              return (

                    <input type='text'  id='team__name-container' className='team__name-input' defaultValue={team.name}/>

                    <input type='text' id='team__description-container' className='team__description-input' defaultValue={team.description}/>

);
            } else {
              return (

                    <Link to='#' className='team__name-link'>{team.name}</Link>

{team.description}

);
            }
          })()}

            {/* location: show this span if location entered, hide if not; always show when isEditing */}

              {(() => {
                if (isEditing) {
                  return (<FontAwesome name='map-marker' className='team__location-icon' />
                          <input type='text' id='team__location-container' className='team__location-name-input'/>);
                } else {
                  if(contact)
                  {
                    return (
                      <FontAwesome name='map-marker' className='team__location-icon' />
                      {this.props.team.contacts.edges[0].node.location});

                  }else {
                    return ();

                  }
                }
              })()}

            {/* link: iterate through all contact info links user has added; switch spans to inputs on isEditing */}
            {(() => {
              if (isEditing) {
                return (

                  <FontAwesome name='link' className='team__link-icon' />
                  <input id='team__link-container' type='text' className='team__link-name-input'/>
                  );

              } else {
                if(contact)
                {
                  return (
                    <Link  to= {this.props.team.contacts.edges[0].node.web} className='team__link'>
                      <FontAwesome name='link' className='team__link-icon' />
                      {this.props.team.contacts.edges[0].node.web}
                    </Link>
                  );
                }else {
                  return (

                  );
                }

              }
            })()}

            {/* add link: show whenever is editing; clicking adds a new link input ^
            <button className='team__add-link'>
              <FontAwesome name='plus' className='team__add-link-icon' />Add link...
            </button>
            */}

          {/* controls: probably should only be visible to team members/admins/etc. */}
          <select className='team__permissions' name='teamPermissions'>
            <option value='public'>Public</option>
            <option value='private'>Private</option>
          </select>

            28 reports
            4 projects

            {(() => {
            })()}

    );
  }
}

export default TeamComponent;
<commit_msg>setting location/link as defaultValue while editing contact<commit_after>import React, { Component, PropTypes } from 'react';
import Relay from 'react-relay';
import TeamMembers from './TeamMembers'
import TeamActivities from './TeamActivities'
import TeamProjects from './TeamProjects'
import Tags from './Tags'
import SocialProfiles from './SocialProfiles'
import { Link } from 'react-router';
import FontAwesome from 'react-fontawesome';
import UpdateTeamMutation from '../../relay/UpdateTeamMutation';
import Message from '../Message';
import CreateContactMutation from '../../relay/CreateContactMutation';
import UpdateContactMutation from '../../relay/UpdateContactMutation';

class TeamComponent extends Component {

  constructor(props) {
    super(props);
    this.state = {
      isEditingNameAndDescription: false
    };
  }

  cancelEditTeam(e) {
     e.preventDefault();
     this.setState({isEditingNameAndDescription: false});
  }

  editTeamInfo(){
    var that = this,
         name = document.getElementById('team__name-container').value;
    var description = document.getElementById('team__description-container').value;

    var onFailure = (transaction) => {

        transaction.getError().json().then(function(json) {
          var message = 'Sorry, could not edit the team';
          if (json.error) {
            message = json.error;
          }
          that.setState({ message: message });
        });

        this.setState({isEditingNameAndDescription: false});

    };

    var onSuccess = (response) => {
     //  var tid = response.createTeam.team.id;
     //  var decodedId = base64.decode(tid);
     //  this.props.history.push('/' + decodedId);
      this.setState({ message: null });
      this.setState({isEditingNameAndDescription: false});

    };

    Relay.Store.commitUpdate(
      new UpdateTeamMutation({
       name: name,
       description: description,
       id: this.props.team.id
     }),
     { onSuccess, onFailure }
   );
  }

  updateTeamContacts(){
    var that = this,
         location = document.getElementById('team__location-container').value,
         link = document.getElementById('team__link-container').value,
         contact = this.props.team.contacts.edges[0];
    console.log("create team start");
    var onFailure = (transaction) => {

        transaction.getError().json().then(function(json) {
          var message = 'Sorry, could not edit the team';
          if (json.error) {
            message = json.error;
          }
          that.setState({ message: message });
        });

        this.setState({isEditingNameAndDescription: false});

        console.log("create team fail");

    };

    var onSuccess = (response) => {
     //  var tid = response.createTeam.team.id;
     //  var decodedId = base64.decode(tid);
     //  this.props.history.push('/' + decodedId);
      this.setState({ message: null });
      this.setState({isEditingNameAndDescription: false});
      console.log("create team sucess");

    };

    Relay.Store.commitUpdate(
      new UpdateContactMutation({
       location: location,
       web: link,
       id: contact.node.id,
     }),
     { onSuccess, onFailure }
   );
  }
  createTeamContacts(){
    var that = this,
    location = document.getElementById('team__location-container').value,
    link = document.getElementById('team__link-container').value;
    console.log("create team contacccc start");
    var onFailure = (transaction) => {

        transaction.getError().json().then(function(json) {
          var message = 'Sorry, could not edit the team';
          if (json.error) {
            message = json.error;
          }
          that.setState({ message: message });
        });

        this.setState({isEditingNameAndDescription: false});

        console.log("create team fail");

    };

    var onSuccess = (response) => {
     //  var tid = response.createTeam.team.id;
     //  var decodedId = base64.decode(tid);
     //  this.props.history.push('/' + decodedId);
      this.setState({ message: null });
      this.setState({isEditingNameAndDescription: false});
      console.log("create team sucess");

    };

    Relay.Store.commitUpdate(
      new CreateContactMutation({
       location: location,
       web: link,
       team_id: this.props.team.dbid,
       parent_id: this.props.team.id,
       parent_type: "team"
     }),
     { onSuccess, onFailure }
   );
  }

  handleEditTeam(e) {
     e.preventDefault();
     this.editTeamInfo();
     if (this.props.team.contacts.edges[0]) {
       this.updateTeamContacts();

     } else {
       this.createTeamContacts();
          }
  }
  handleEntreEditTeamNameAndDescription(e) {
    e.preventDefault();
    this.setState({isEditingNameAndDescription: true});
  }
  render() {
    const team = this.props.team;
    const isEditing = this.state.isEditingNameAndDescription;
    const contact =this.props.team.contacts.edges[0];
    return (

        <Message message={this.state.message} />

          {(() => {
            if (isEditing) {
              return (

                  <button onClick={this.cancelEditTeam.bind(this)} className='team__cancel-button'>Cancel</button>
                  <button onClick={this.handleEditTeam.bind(this)} className='team__save-button'>Save</button>

              );
            } else {
              return (

                  <button onClick={this.handleEntreEditTeamNameAndDescription.bind(this)} className='team__edit-button'>
                    <FontAwesome className='team__edit-icon' name='pencil'/> Edit profile
                  </button>

              );
            }
          })()}

          {(() => {
            if (this.state.isEditingNameAndDescription) {

              return (

                    <input type='text'  id='team__name-container' className='team__name-input' defaultValue={team.name}/>

                    <input type='text' id='team__description-container' className='team__description-input' defaultValue={team.description}/>

);
            } else {
              return (

                    <Link to='#' className='team__name-link'>{team.name}</Link>

{team.description}

);
            }
          })()}

            {/* location: show this span if location entered, hide if not; always show when isEditing */}

              {(() => {
                if (isEditing) {
                  if (contact) {
                    return (<FontAwesome name='map-marker' className='team__location-icon' />
                            <input type='text' id='team__location-container' defaultValue={this.props.team.contacts.edges[0].node.location} className='team__location-name-input'/>
                            );
                  }else {

                    return (<FontAwesome name='map-marker' className='team__location-icon' />
                            <input type='text' id='team__location-container' className='team__location-name-input'/>
                            );
                  }
                } else {
                  if(contact)
                  {
                    return (
                      <FontAwesome name='map-marker' className='team__location-icon' />
                      {this.props.team.contacts.edges[0].node.location});

                  }else {
                    return ();

                  }
                }
              })()}

            {/* link: iterate through all contact info links user has added; switch spans to inputs on isEditing */}
            {(() => {
              if (isEditing) {
                if (contact) {
                  return (

                    <FontAwesome name='link' className='team__link-icon' />
                    <input id='team__link-container' defaultValue={this.props.team.contacts.edges[0].node.web} type='text' className='team__link-name-input'/>
                    );

                }else {
                  return (

                    <FontAwesome name='link' className='team__link-icon' />
                    <input id='team__link-container' type='text' className='team__link-name-input'/>
                    );

                }

              } else {
                if(contact)
                {
                  return (
                    <Link  to= {this.props.team.contacts.edges[0].node.web} className='team__link'>
                      <FontAwesome name='link' className='team__link-icon' />
                      {this.props.team.contacts.edges[0].node.web}
                    </Link>
                  );
                }else {
                  return (

                  );
                }

              }
            })()}

            {/* add link: show whenever is editing; clicking adds a new link input ^
            <button className='team__add-link'>
              <FontAwesome name='plus' className='team__add-link-icon' />Add link...
            </button>
            */}

          {/* controls: probably should only be visible to team members/admins/etc. */}
          <select className='team__permissions' name='teamPermissions'>
            <option value='public'>Public</option>
            <option value='private'>Private</option>
          </select>

            28 reports
            4 projects

            {(() => {
            })()}

    );
  }
}

export default TeamComponent;
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react'
import { Container, Content, Hero, HeroBody, HeroFoot, Title, Subtitle, Icon, Image, Columns, Column, Box, LevelLeft, Section, Button, Heading } from 're-bulma'
import reactKeydown from 'react-keydown'
import 'whatwg-fetch'
import 'tracking'

import dimensions from './components/Dimensions'
import Webcam from './components/Webcam'
import RecentCardList from './components/RecentCardList'
import Menu from './components/Menu/'

import mascot from './img/mascot.svg'
import brand from './img/textOnly.svg'
import cardUdon from './img/card_template/udon.png'
import cardUbon from './img/card_template/ubon.jpg'
import cardSaat from './img/card_template/SAAT.png'
import imgCamera from './img/camera.png'
import './data/face.js'
import './App.css'
import { defaultStyle, styleForMacbook, style, webfont, macbookWidth } from './config/style'

class App extends Component {
  constructor() {
    super()
    this.state = {
      index: 0,
      cardTemplateList: [
        {
          name: 'ส.บ.ม.ท.',
          src: cardSaat,
          captureSize: { width: 115, height: (115 / 3) * 4 },
          capturePosition: { x: 12, y: 67 },
        },
        {
          name: 'โรงเรียนอุบล',
          src: cardUbon,
          captureSize: { width: 98, height: (98 / 3) * 4 },
          capturePosition: { x: 15, y: 83 },
        },
        {
          name: 'โรงเรียนอุดร',
          src: cardUdon,
          captureSize: { width: 90, height: 120 },
          capturePosition: { x: 17, y: 86 },
        },
      ],
      currentCardTemplate: cardUbon,
      faceDetectList: [],
      cardGenerateList: [],
      current: {},
      videoSize: {
        width: 640,
        height: 480,
      },
      imageSize: {
        width: 320,
        height: 240,
      },
      cardTeamplateSize: {
        width: 1,
        height: 1,
      },
      // cardSize: {
      //   width: 400,
      //   height: 251,
      // },
      cardSize: {
        width: 952,
        height: 597,
      },
      captureSize: { width: 0, height: 0 },
      capturePosition: { x: 0, y: 0 },
    }
    this.capture = this.capture.bind(this)
    this.onImgLoad = this.onImgLoad.bind(this)
  }
  componentDidMount() {
    this.setCardTemplate(0)
    const self = this
    const video = this.elementVideo
    const tracker = new window.tracking.ObjectTracker(['face'])
    tracker.setInitialScale(4)
    tracker.setStepSize(2)
    tracker.setEdgesDensity(0.01)
    window.tracking.track(video, tracker, { camera: true })
    tracker.on('track', (event) => {
      if (event.data.length !== 0) {
        self.setState({ faceDetectList: event.data })
        const max = event.data.reduce((a, b) => (a.width > b.width ? a : b))
        self.setState({ current: max })
        const context = self.elementTempVideo.getContext('2d')
        context.clearRect(0, 0, self.state.imageSize.width, self.state.imageSize.height)
        context.drawImage(video, 0, 0, self.state.videoSize.width, self.state.videoSize.height, 0, 0, self.state.imageSize.width, self.state.imageSize.height)
      }
    })
  }
  componentWillReceiveProps({ keydown }) {
    if (keydown.event && keydown.event.which === 13) {
      // Enter key
      this.capture()
    } else if (keydown.event && keydown.event.which === 39) {
      // Left key
      this.handleNextCard()
    } else if (keydown.event && keydown.event.which === 37) {
      // Right key
      this.handlePreviusCard()
    }
  }
  componentDidUpdate() {
    const context = this.elementCardTemplate.getContext('2d')
    context.clearRect(0, 0, this.state.cardSize.width, this.state.cardSize.height)
    // Add Card
    context.drawImage(this.elementRawTemplate, 0, 0, this.state.cardTeamplateSize.width, this.state.cardTeamplateSize.height, 0, 0, this.state.cardSize.width, this.state.cardSize.height)
    // Add Background
    context.beginPath()
    context.rect(this.state.capturePosition.x, this.state.capturePosition.y, this.state.captureSize.width, this.state.captureSize.height)
    context.fillStyle = 'white'
    context.fill()
    context.drawImage(
      this.elementTempVideo,
      this.state.current.x - ((this.state.current.width * 20) / 100),
      this.state.current.y - ((this.state.current.width * 30) / 100),
      this.state.current.width + ((this.state.current.width * 40) / 100),
      ((this.state.current.height + ((this.state.current.width * 40) / 100)) / 3) * 4,
      this.state.capturePosition.x,
      this.state.capturePosition.y,
      this.state.captureSize.width,
      this.state.captureSize.height
    )
  }
  onImgLoad({ target: img }) {
    this.setState({
      cardTeamplateSize: {
        width: img.offsetWidth,
        height: img.offsetHeight,
      },
    })
  }
  setCardTemplate(index) {
    const rawWidth = 400
    const rawHeight = 251
    const cardWidthRatio = this.state.cardSize.width / rawWidth
    const cardHeightRatio = this.state.cardSize.height / rawHeight
    const tempwidth = this.state.cardTemplateList[index].captureSize.width * cardWidthRatio
    const tempheight = this.state.cardTemplateList[index].captureSize.height * cardHeightRatio
    const tempX = this.state.cardTemplateList[index].capturePosition.x * cardWidthRatio
    const tempY = this.state.cardTemplateList[index].capturePosition.y * cardHeightRatio
    const captureSize = {
      width: tempwidth,
      height: tempheight,
    }
    const capturePosition = {
      x: tempX,
      y: tempY,
    }
    this.setState({
      index,
      currentCardTemplate: this.state.cardTemplateList[index].src,
      captureSize,
      capturePosition,
    })
  }
  dataURItoBlob(dataURI) {
    let byteString
    if (dataURI.split(',')[0].indexOf('base64') >= 0) {
      byteString = atob(dataURI.split(',')[1])
    } else {
      byteString = unescape(dataURI.split(',')[1])
    }
    const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
    const ia = new Uint8Array(byteString.length)
    for (let i = 0; i < byteString.length; i += 1) {
      ia[i] = byteString.charCodeAt(i)
    }
    return new Blob([ia], { type: mimeString })
  }
  handleNextCard() {
    let index = this.state.index
    index += 1
    if (index >= this.state.cardTemplateList.length) {
      index = 0
    }
    this.setCardTemplate(index)
  }
  handlePreviusCard() {
    let index = this.state.index
    index -= 1
    if (index < 0) {
      index = this.state.cardTemplateList.length - 1
    }
    this.setCardTemplate(index)
  }
  capture() {
    const cardGenerateList = this.state.cardGenerateList
    if (cardGenerateList.length >= 6) {
      cardGenerateList.splice(5, 1) // delete card over length
    }
    cardGenerateList.unshift({
      date: new Date(),
      name: 'ทดสอบชื่อ',
      lastname: 'ทดสอบนามสกุล',
      canvas: this.elementCardTemplate,
      imgPath: this.elementCardTemplate.toDataURL('image/jpeg'),
      blob: this.dataURItoBlob(this.elementCardTemplate.toDataURL('image/jpeg')),
    })
    this.sendData(cardGenerateList)
    this.setState({ cardGenerateList })
  }
  sendData(params) {
    const data = new FormData()
    params.forEach((objectData) => {
      Object.keys(objectData).forEach((key) => {
        if (objectData && Object.prototype.hasOwnProperty.call(objectData, key)) {
          data.append(key, objectData[key])
        }
      })
    })
    fetch('http://localhost:3030/upload', {
      method: 'POST',
      header: { 'Access-Control-Allow-Origin': '*' },
      body: data,
    })
  }
  render() {
    if (this.props.containerWidth === macbookWidth) {
      defaultStyle.cameraSize = styleForMacbook.cameraSize
      defaultStyle.cameraPosition = styleForMacbook.cameraPosition
      defaultStyle.headerStyle = { display: 'none' }
      defaultStyle.cardMarginTop = styleForMacbook.cardMarginTop
      defaultStyle.mascotHeight = styleForMacbook.mascotHeight
      defaultStyle.brandWidth = styleForMacbook.brandWidth
    }
    const webcamStyle = {
      position: 'absolute',
      top: defaultStyle.cameraPosition.top,
      left: defaultStyle.cameraPosition.left,
    }
    return (

        <Menu />
        <Hero size="isFullheight">

            <Container isFluid>
              <Heading>

              </Heading>
            </Container>

          <HeroBody style={{ padding: '40px 20px 0' }}>
            <Container hasTextCentered isFluid>
              <Columns style={defaultStyle.headerStyle}>
                <Column size="is12" style={style}>
                  <Title size="is1" style={defaultStyle.headerStyle}>ถ่ายรูปทำบัตรด่วน!</Title>
                </Column>
              </Columns>
              <Columns isMultiline>
                <Column size="is6" style={style}>
                  <Image src={imgCamera} alt="Camera" className="App-camera" style={{ marginBottom: '5px', zIndex: 10 }} />
                  <Webcam audio={false} width={defaultStyle.cameraSize.width} height={defaultStyle.cameraSize.height} className="webcam" style={webcamStyle} />
                  <video ref={(element) => { this.elementVideo = element }} width={this.state.imageSize.width} style={{ visibility: 'hidden', position: 'fixed' }} height={this.state.imageSize.height} preload autoPlay loop muted />
                  <canvas ref={(element) => { this.elementTempVideo = element }} width={this.state.imageSize.width} style={{ display: 'none' }} height={this.state.imageSize.height} />
                   { this.elementRawTemplate = element }} style={{ visibility: 'hidden', position: 'fixed', left: 0, top: 0 }} alt="" />
                </Column>
                <Column size="is6" style={style} is-fullheight>
                  <Hero>
                    <HeroBody style={{ padding: '40px 20px 0' }}>
                      <Container>
                        <canvas
                          className="App-card"
                          ref={(element) => { this.elementCardTemplate = element }}
                          width={this.state.cardSize.width}
                          height={this.state.cardSize.height}
                          style={{ marginTop: defaultStyle.cardMarginTop, marginBottom: '5px' }}
                        />
                      </Container>
                    </HeroBody>
                  </Hero>
                </Column>
                <Column size="is12" style={style}>
                  <Button icon="fa fa-camera" buttonStyle="isOutlined" color="isDanger" onClick={this.capture}>ถ่ายรูป</Button>
                </Column>
              </Columns>
              <Columns>
                <Column size="is12" style={style}>
                  <Box>
                    <LevelLeft>
                      <Subtitle size="is3" style={webfont}>รายการบัตรล่าสุด</Subtitle>
                    </LevelLeft>
                    <RecentCardList cards={this.state.cardGenerateList} />
                  </Box>
                </Column>
              </Columns>
            </Container>
          </HeroBody>
          <HeroFoot>
            <Container>
              <Content>

                  made with <Icon icon="fa fa-heart" size="isSmall" style={{ color: 'red' }} /> by Nextgensoft

              </Content>
            </Container>
          </HeroFoot>
        </Hero>

    )
  }
}

App.propTypes = {
  containerWidth: PropTypes.number,
}

export default reactKeydown(dimensions()(App))
<commit_msg>fixbug support photoBoothServer<commit_after>import React, { Component, PropTypes } from 'react'
import { Container, Content, Hero, HeroBody, HeroFoot, Title, Subtitle, Icon, Image, Columns, Column, Box, LevelLeft, Section, Button, Heading } from 're-bulma'
import reactKeydown from 'react-keydown'
import 'whatwg-fetch'
import 'tracking'

import dimensions from './components/Dimensions'
import Webcam from './components/Webcam'
import RecentCardList from './components/RecentCardList'
import Menu from './components/Menu/'

import mascot from './img/mascot.svg'
import brand from './img/textOnly.svg'
import cardUdon from './img/card_template/udon.png'
import cardUbon from './img/card_template/ubon.jpg'
import cardSaat from './img/card_template/SAAT.png'
import imgCamera from './img/camera.png'
import './data/face.js'
import './App.css'
import { defaultStyle, styleForMacbook, style, webfont, macbookWidth } from './config/style'

class App extends Component {
  constructor() {
    super()
    this.state = {
      index: 0,
      cardTemplateList: [
        {
          name: 'ส.บ.ม.ท.',
          src: cardSaat,
          captureSize: { width: 115, height: (115 / 3) * 4 },
          capturePosition: { x: 12, y: 67 },
        },
        {
          name: 'โรงเรียนอุบล',
          src: cardUbon,
          captureSize: { width: 98, height: (98 / 3) * 4 },
          capturePosition: { x: 15, y: 83 },
        },
        {
          name: 'โรงเรียนอุดร',
          src: cardUdon,
          captureSize: { width: 90, height: 120 },
          capturePosition: { x: 17, y: 86 },
        },
      ],
      currentCardTemplate: cardUbon,
      faceDetectList: [],
      cardGenerateList: [],
      current: {},
      videoSize: {
        width: 640,
        height: 480,
      },
      imageSize: {
        width: 320,
        height: 240,
      },
      cardTeamplateSize: {
        width: 1,
        height: 1,
      },
      // cardSize: {
      //   width: 400,
      //   height: 251,
      // },
      cardSize: {
        width: 952,
        height: 597,
      },
      captureSize: { width: 0, height: 0 },
      capturePosition: { x: 0, y: 0 },
    }
    this.capture = this.capture.bind(this)
    this.onImgLoad = this.onImgLoad.bind(this)
  }
  componentDidMount() {
    this.setCardTemplate(0)
    const self = this
    const video = this.elementVideo
    const tracker = new window.tracking.ObjectTracker(['face'])
    tracker.setInitialScale(4)
    tracker.setStepSize(2)
    tracker.setEdgesDensity(0.01)
    window.tracking.track(video, tracker, { camera: true })
    tracker.on('track', (event) => {
      if (event.data.length !== 0) {
        self.setState({ faceDetectList: event.data })
        const max = event.data.reduce((a, b) => (a.width > b.width ? a : b))
        self.setState({ current: max })
        const context = self.elementTempVideo.getContext('2d')
        context.clearRect(0, 0, self.state.imageSize.width, self.state.imageSize.height)
        context.drawImage(video, 0, 0, self.state.videoSize.width, self.state.videoSize.height, 0, 0, self.state.imageSize.width, self.state.imageSize.height)
      }
    })
  }
  componentWillReceiveProps({ keydown }) {
    if (keydown.event && keydown.event.which === 13) {
      // Enter key
      this.capture()
    } else if (keydown.event && keydown.event.which === 39) {
      // Left key
      this.handleNextCard()
    } else if (keydown.event && keydown.event.which === 37) {
      // Right key
      this.handlePreviusCard()
    }
  }
  componentDidUpdate() {
    const context = this.elementCardTemplate.getContext('2d')
    context.clearRect(0, 0, this.state.cardSize.width, this.state.cardSize.height)
    // Add Card
    context.drawImage(this.elementRawTemplate, 0, 0, this.state.cardTeamplateSize.width, this.state.cardTeamplateSize.height, 0, 0, this.state.cardSize.width, this.state.cardSize.height)
    // Add Background
    context.beginPath()
    context.rect(this.state.capturePosition.x, this.state.capturePosition.y, this.state.captureSize.width, this.state.captureSize.height)
    context.fillStyle = 'white'
    context.fill()
    context.drawImage(
      this.elementTempVideo,
      this.state.current.x - ((this.state.current.width * 20) / 100),
      this.state.current.y - ((this.state.current.width * 30) / 100),
      this.state.current.width + ((this.state.current.width * 40) / 100),
      ((this.state.current.height + ((this.state.current.width * 40) / 100)) / 3) * 4,
      this.state.capturePosition.x,
      this.state.capturePosition.y,
      this.state.captureSize.width,
      this.state.captureSize.height
    )
  }
  onImgLoad({ target: img }) {
    this.setState({
      cardTeamplateSize: {
        width: img.offsetWidth,
        height: img.offsetHeight,
      },
    })
  }
  setCardTemplate(index) {
    const rawWidth = 400
    const rawHeight = 251
    const cardWidthRatio = this.state.cardSize.width / rawWidth
    const cardHeightRatio = this.state.cardSize.height / rawHeight
    const tempwidth = this.state.cardTemplateList[index].captureSize.width * cardWidthRatio
    const tempheight = this.state.cardTemplateList[index].captureSize.height * cardHeightRatio
    const tempX = this.state.cardTemplateList[index].capturePosition.x * cardWidthRatio
    const tempY = this.state.cardTemplateList[index].capturePosition.y * cardHeightRatio
    const captureSize = {
      width: tempwidth,
      height: tempheight,
    }
    const capturePosition = {
      x: tempX,
      y: tempY,
    }
    this.setState({
      index,
      currentCardTemplate: this.state.cardTemplateList[index].src,
      captureSize,
      capturePosition,
    })
  }
  dataURItoBlob(dataURI) {
    let byteString
    if (dataURI.split(',')[0].indexOf('base64') >= 0) {
      byteString = atob(dataURI.split(',')[1])
    } else {
      byteString = unescape(dataURI.split(',')[1])
    }
    const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
    const ia = new Uint8Array(byteString.length)
    for (let i = 0; i < byteString.length; i += 1) {
      ia[i] = byteString.charCodeAt(i)
    }
    return new Blob([ia], { type: mimeString })
  }
  handleNextCard() {
    let index = this.state.index
    index += 1
    if (index >= this.state.cardTemplateList.length) {
      index = 0
    }
    this.setCardTemplate(index)
  }
  handlePreviusCard() {
    let index = this.state.index
    index -= 1
    if (index < 0) {
      index = this.state.cardTemplateList.length - 1
    }
    this.setCardTemplate(index)
  }
  capture() {
    const cardGenerateList = this.state.cardGenerateList
    if (cardGenerateList.length >= 6) {
      cardGenerateList.splice(5, 1) // delete card over length
    }
    const cardGenerate = {
      date: new Date(),
      name: 'ทดสอบชื่อ',
      lastname: 'ทดสอบนามสกุล',
      canvas: this.elementCardTemplate,
      imgPath: this.elementCardTemplate.toDataURL('image/jpeg'),
      blob: this.dataURItoBlob(this.elementCardTemplate.toDataURL('image/jpeg')),
    }
    cardGenerateList.unshift(cardGenerate)
    this.sendData(cardGenerate)
    this.setState({ cardGenerateList })
  }
  sendData(objectData) {
    const data = new FormData()
    const tempObjectData = objectData
    delete tempObjectData.imgPath
    Object.keys(tempObjectData).forEach((key) => {
      if (tempObjectData && Object.prototype.hasOwnProperty.call(tempObjectData, key)) {
        data.append(key, tempObjectData[key])
      }
    })
    fetch('http://localhost:3030/upload', {
      method: 'POST',
      header: { 'Access-Control-Allow-Origin': '*' },
      body: data,
    })
  }
  render() {
    if (this.props.containerWidth === macbookWidth) {
      defaultStyle.cameraSize = styleForMacbook.cameraSize
      defaultStyle.cameraPosition = styleForMacbook.cameraPosition
      defaultStyle.headerStyle = { display: 'none' }
      defaultStyle.cardMarginTop = styleForMacbook.cardMarginTop
      defaultStyle.mascotHeight = styleForMacbook.mascotHeight
      defaultStyle.brandWidth = styleForMacbook.brandWidth
    }
    const webcamStyle = {
      position: 'absolute',
      top: defaultStyle.cameraPosition.top,
      left: defaultStyle.cameraPosition.left,
    }
    return (

        <Menu />
        <Hero size="isFullheight">

            <Container isFluid>
              <Heading>

              </Heading>
            </Container>

          <HeroBody style={{ padding: '40px 20px 0' }}>
            <Container hasTextCentered isFluid>
              <Columns style={defaultStyle.headerStyle}>
                <Column size="is12" style={style}>
                  <Title size="is1" style={defaultStyle.headerStyle}>ถ่ายรูปทำบัตรด่วน!</Title>
                </Column>
              </Columns>
              <Columns isMultiline>
                <Column size="is6" style={style}>
                  <Image src={imgCamera} alt="Camera" className="App-camera" style={{ marginBottom: '5px', zIndex: 10 }} />
                  <Webcam audio={false} width={defaultStyle.cameraSize.width} height={defaultStyle.cameraSize.height} className="webcam" style={webcamStyle} />
                  <video ref={(element) => { this.elementVideo = element }} width={this.state.imageSize.width} style={{ visibility: 'hidden', position: 'fixed' }} height={this.state.imageSize.height} preload autoPlay loop muted />
                  <canvas ref={(element) => { this.elementTempVideo = element }} width={this.state.imageSize.width} style={{ display: 'none' }} height={this.state.imageSize.height} />
                   { this.elementRawTemplate = element }} style={{ visibility: 'hidden', position: 'fixed', left: 0, top: 0 }} alt="" />
                </Column>
                <Column size="is6" style={style} is-fullheight>
                  <Hero>
                    <HeroBody style={{ padding: '40px 20px 0' }}>
                      <Container>
                        <canvas
                          className="App-card"
                          ref={(element) => { this.elementCardTemplate = element }}
                          width={this.state.cardSize.width}
                          height={this.state.cardSize.height}
                          style={{ marginTop: defaultStyle.cardMarginTop, marginBottom: '5px' }}
                        />
                      </Container>
                    </HeroBody>
                  </Hero>
                </Column>
                <Column size="is12" style={style}>
                  <Button icon="fa fa-camera" buttonStyle="isOutlined" color="isDanger" onClick={this.capture}>ถ่ายรูป</Button>
                </Column>
              </Columns>
              <Columns>
                <Column size="is12" style={style}>
                  <Box>
                    <LevelLeft>
                      <Subtitle size="is3" style={webfont}>รายการบัตรล่าสุด</Subtitle>
                    </LevelLeft>
                    <RecentCardList cards={this.state.cardGenerateList} />
                  </Box>
                </Column>
              </Columns>
            </Container>
          </HeroBody>
          <HeroFoot>
            <Container>
              <Content>

                  made with <Icon icon="fa fa-heart" size="isSmall" style={{ color: 'red' }} /> by Nextgensoft

              </Content>
            </Container>
          </HeroFoot>
        </Hero>

    )
  }
}

App.propTypes = {
  containerWidth: PropTypes.number,
}

export default reactKeydown(dimensions()(App))
<|endoftext|>


<commit_before>CATARSE.ProjectsNewView = Backbone.View.extend({
  el: 'body',

  initialize: function() {
    verify_permalink = function() {
      if(/^(\w|-)*$/.test($('#project_permalink').val()))
      {
        if($('#project_permalink').val() == ''){
          $('#project_permalink').addClass("error").removeClass("ok")
        }
        else {
        $.get('/projects/check_slug/?permalink='+$('#project_permalink').val(),
            function(r) {
              if(r.available){
                $('#project_permalink').addClass("ok").removeClass("error")
              } else {
                $('#project_permalink').addClass("error").removeClass("ok")
              }
        })
        }

      } else {
        $('#project_permalink').addClass("error").removeClass("ok")
      }
    }

    $('#project_permalink').timedKeyup(verify_permalink)

    $('#project_goal').numeric(false)
    $('input,textarea,select').on('focus', null, function(){
      $('p.inline-hints').hide()
      $(this).next('p.inline-hints').show()
    })

    $('#project_permalink').focus()
    $('textarea').maxlength()
    $('#project_goal').on('input', function(){
      var amount = this.value
      var discount = 0
      if(isNaN(amount) || amount == '') {
        $('.discount-text').remove()
      }
      else {
        discount = amount * 0.86
        discount = discount.toFixed(0)
        discount = discount.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1.")
        $('#discount-hidden-text').find('.discount').html(discount)
        if($('.discount-text').length){
          $('.discount-text').html($('#discount-hidden-text').html())
        }
        else{
          $(this).after("
" +$('#discount-hidden-text').html()+ "
")
        }
      }
    })
  }
})
<commit_msg>Added project goal verification<commit_after>CATARSE.ProjectsNewView = Backbone.View.extend({
  el: 'body',

  initialize: function() {
    verify_permalink = function() {
      if(/^(\w|-)*$/.test($('#project_permalink').val()))
      {
        if($('#project_permalink').val() == ''){
          $('#project_permalink').addClass("error").removeClass("ok")
        }
        else {
        $.get('/projects/check_slug/?permalink='+$('#project_permalink').val(),
            function(r) {
              if(r.available){
                $('#project_permalink').addClass("ok").removeClass("error")
              } else {
                $('#project_permalink').addClass("error").removeClass("ok")
              }
        })
        }

      } else {
        $('#project_permalink').addClass("error").removeClass("ok")
      }
    }

    $('#project_permalink').timedKeyup(verify_permalink)

    $('#project_goal').timedKeyup(function(){
      if(this.val < gon.partial_goal){
        $(this).addClass('error').removeClass('ok')
      }
      else{
        $(this).addClass('ok').removeClass('error')
      }
    });

    $('#project_goal').numeric(false)

    $('#project_goal').on('input', function(){
      var amount = this.value
      var discount = 0
      if(isNaN(amount) || amount == '') {
        $('.discount-text').remove()
      }
      else {
        discount = amount * 0.86
        discount = discount.toFixed(0)
        discount = discount.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1.")
        $('#discount-hidden-text').find('.discount').html(discount)
        if($('.discount-text').length){
          $('.discount-text').html($('#discount-hidden-text').html())
        }
        else{
          $(this).after("
" +$('#discount-hidden-text').html()+ "
")
        }
      }
    })

    $('input,textarea,select').on('focus', null, function(){
      $('p.inline-hints').hide()
      $(this).next('p.inline-hints').show()
    })

    $('textarea').maxlength()
  }
})
<|endoftext|>