<commit_before>var margin = {top: 10, right: 25, bottom: 70, left: 65}, timewidth = 250, timeheight = 400;

var x = d3.time.scale()
					.range([0, timewidth]);

var y = d3.scale.linear()
					.range([timeheight, 0]);

var xAxis = d3.svg.axis()
							.scale(x)
							.ticks(5)
							.tickFormat(d3.time.format("%Y"));

var yAxis = d3.svg.axis()
							.scale(y)
							.orient("left");		//evtl. tickFormat für Achsensplit????

var svg = d3.select("#choiceChart").append("svg")
		  .attr("width", timewidth + margin.left + margin.right)
		  .attr("height", timeheight + margin.top + margin.bottom)
		.append("g")
		  .attr("transform", "translate(50,30)");

var parseDate = d3.time.format("%Y-%m-%d").parse;
//var parseDate = d3.time.format("%d/%m/%Y").parse;
//var year = d3.time.format("%m/%Y");

d3.tsv("statsTables/filestats", function(dd) {
for (var i = 0; i < dd.length; i++)
{
	dd[i]["date"] = new Date (dd[i]["date"]);

	filestats[ dd[i]["model"] + dd[i]["versionid"]  ] = dd[i];
	//console.log(dd[0]);
}
d3.tsv("statsTables/diffstats", function(d) {
	for (var i=0; i < d.length; i++){
		d[i]["bivesinsert"] = +d[i]["bivesinsert"];
		d[i]["bivesmove"] = +d[i]["bivesmove"];
		d[i]["bivesdelete"] = +d[i]["bivesdelete"];
		d[i]["bivesupdate"] = +d[i]["bivesupdate"];
		d[i]["bives"] = +d[i]["bives"];

	}
	diffstats=d;

	console.log ("ready");
	tuwatt ();
});

});

function tuwatt ()
{
	rows=diffstats;
 	console.log (rows[0]);

	rows.sort(function(a, b) {
                return d3.ascending(a.version2id, b.version2id);
        });

	var counts = {};
	rows.forEach(function(r) {

		var datum = filestats[ r["model"] + r["version2id"]  ].date;

    if (!counts[datum]) {
        counts[datum] = 0;
    }
    counts[datum]++;
	});

	var max = 0;
	var data = [];
	Object.keys(counts).forEach(function(key) {
    data.push({
        datum: new Date(key)
		,
        count: counts[key]
    });
		if (counts[key] > max)
			max = counts[key];
	});

// 	console.log (data);

	var minVersion2 = d3.min(data, function (d){ return d.datum });
	var maxVersion2 = d3.max(data, function (d){ return d.datum });

// 	console.log (minVersion2);
// 	console.log (maxVersion2);

	y.domain([0, max]).nice();
	x.domain([minVersion2, maxVersion2]).nice();

	svg.append("g")
		    .attr("class", "y axis")
				.attr("fill", "white")
		    .call(yAxis)
		  .append("text")
				.attr("x", 25)
		    .attr("y", -20)
		    .attr("dy", ".71em")
		    .style("text-anchor", "end")
				.attr("fill", "white")
		    .text("Changes");

	svg.append("g")
		    .attr("class", "x axis")
				.attr("transform", "translate(0," + timeheight + ")")
				.attr("fill", "white")
		    .call(xAxis);

	var rects = svg.selectAll(".bar")
				  .data(data)
					.enter()
					.append("rect")
				  .attr("class", "bar")
				  .attr("x", function(d) { var meinx = x(d.datum); if (isNaN (meinx)){ console.log ("das is nan: " + meinx); /*console.log (d.datum); console.log (new Date(d.datum)); console.log (x(new Date(d.datum)));*/} return meinx; })
				  .attr("width", timewidth / data.length)
				  .attr("y", function(d) { return y(d.count) })
				  .attr("height", function(d) { return timeheight - y(d.count);})
					.attr("fill", "white");

var parseDate = d3.time.format("%Y-%m-%d").parse;
//var parseDate2 = d3.time.format("%b %d %Y").parse;
//var parseDate = d3.time.format("%d/%m/%Y").parse;
var parseDate2 = d3.time.format("%Y-%m-%d").parse;

/* var date1 = parseDate2(document.getElementById("date1").value);
var date2 = parseDate2(document.getElementById("date2").value); */

var date1 = moment(document.getElementById("date1").value);
var date2 = moment(document.getElementById("date2").value);

var brush = d3.svg.brush()
	.x(x)
	.extent([date1, date2])
	.on("brush", brushmove)
	.on("brushend", brushend);

svg.append("g")
	.attr("class", "brush")
	.call(brush)
.selectAll('rect')
	.attr('height', timeheight);

var modelType = ["BioModels", "CellML"],
    j = 0;  // Choose the rectangle as default

// Create the shape selectors
var dataset = d3.select('#choiceChart').append("dataset")
	.append("text")
	.text("Dataset");

var form = d3.select("#choiceChart").append("form");

labels = form.selectAll("label")
    .data(modelType)
    .enter()
    .append("label")
    .text(function(d) {return d;})
    .insert("input")
    .attr({
		id: function(d, i) { return d;},
        type: "checkbox",
        class: "modelType",
        name: "mode",
        value: function(d, i) {return i;}
    })
    .property("checked", function(d, i) {return i===j;});

var hold = -1;

var date1Up = document.getElementById("date1Up");
date1Up.onmouseup = function(){ hold = 0;};
date1Up.onmouseout = function(){ hold = 0;};
date1Up.onmousedown = function () { hold = -1; holdit("date1", "up");};

var date1Down = document.getElementById("date1Down");
date1Down.onmouseup = function(){ hold = 0;};
date1Down.onmouseout = function(){ hold = 0;};
date1Down.onmousedown = function () { hold = -1; holdit("date1", "down");};

var date2Up = document.getElementById("date2Up");
date2Up.onmouseup = function(){ hold = 0;};
date2Up.onmouseout = function(){ hold = 0;};
date2Up.onmousedown = function () { hold = -1; holdit("date2", "up");};

var date2Down = document.getElementById("date2Down");
date2Down.onmouseup = function(){ hold = 0;};
date2Down.onmouseout = function(){ hold = 0;};
date2Down.onmousedown = function () { hold = -1; holdit("date2", "down");};

var date1Field = document.getElementById("date1");
date1Field.addEventListener("keydown", function (e) {
	if(e.keyCode === 13){
		var newDate = Date.parse(date1Field.value);
		console.log(newDate);
		alert("jupp");
		if(newDate != null){
			if(newDate < minVersion2){
				newDate = minVersion2;
			} else if(newDate > maxVersion2){
				newDate = maxVersion2;
			}
			brush.extent([newDate, date2]);
			date1 = newDate;
			extent = brush.extent();
			brushed();
		} else {
			alert("Please enter a correct date.");
		}

	}
});

var date2Field = document.getElementById("date2");
date2Field.addEventListener("keydown", function (e) {
	if(e.keyCode === 13){
		var newDate = Date.parse(date2Field.value);
		if(newDate != null){
			if(newDate < minVersion2){
				newDate = minVersion2;
			} else if(newDate > maxVersion2){
				newDate = maxVersion2;
			}
			brush.extent([date1, newDate]);
			date2 = newDate;
			extent = brush.extent();
			brushed();
		} else {
			alert("Please enter a correct date.");
		}
	}
});

function holdit(btn, mode) {

/* 	var testDay = moment("01/01/2010");
	console.log(moment(testDay).format('DD/MM/YYYY'));
	console.log(testDay);
	testDay.add(1, 'days');
	console.log(testDay);
	console.log(moment(testDay).format('DD/MM/YYYY'));
	testDay.add(1, 'days');
	console.log(testDay);
	console.log(moment(testDay).format('DD/MM/YYYY')); */
	if (hold == -1){
		setTimeout(function(){
			if(mode === "up"){
				console.log("a " + document.getElementById(btn).value);
				var newDate = moment(document.getElementById(btn).value).add(1, 'd');
				console.log("b " + newDate);
				console.log(Date.parse(date1Field.value));
				document.getElementById(btn).value = moment(newDate).format('YYYY-MM-DD');
				console.log("c " + document.getElementById(btn).value);
				if(btn == "date2"){
					brush.extent([date1, newDate]);
					date2 = newDate;
				} else {
					brush.extent([newDate, date2]);
					date1 = newDate;
				}
				extent = brush.extent();
				brushed();
			} else {
				var newDate = moment(document.getElementById(btn).value).add(-1, 'days');
				document.getElementById(btn).value = moment(newDate).format('YYYY-MM-DD');
				if(btn == "date2"){
					brush.extent([date1, newDate]);
					date2 = newDate;
				} else {
					brush.extent([newDate, date2]);
					date1 = newDate;
				}
				extent = brush.extent();
				brushed();
			}

			holdit(btn, mode);
		}, 1);
  }
};

function brushed() {
	svg.select(".brush").call(brush);
}

function brushmove() {
	extent = brush.extent();
	date1 = moment(window.extent[0]);
	date2 = moment(window.extent[1]);
	document.getElementById("date1").value = date1.format('YYYY-MM-DD');
	document.getElementById("date2").value = date2.format('YYYY-MM-DD');
}

function brushend() {
	//alert("brushEND");
	svg.select(".brush").call(brush);
	extent = brush.extent();
}

}

<commit_msg>timespan button improvement<commit_after>var margin = {top: 10, right: 25, bottom: 70, left: 65}, timewidth = 250, timeheight = 400;

var x = d3.time.scale()
					.range([0, timewidth]);

var y = d3.scale.linear()
					.range([timeheight, 0]);

var xAxis = d3.svg.axis()
							.scale(x)
							.ticks(5)
							.tickFormat(d3.time.format("%Y"));

var yAxis = d3.svg.axis()
							.scale(y)
							.orient("left");		//evtl. tickFormat für Achsensplit????

var svg = d3.select("#choiceChart").append("svg")
		  .attr("width", timewidth + margin.left + margin.right)
		  .attr("height", timeheight + margin.top + margin.bottom)
		.append("g")
		  .attr("transform", "translate(50,30)");

var parseDate = d3.time.format("%Y-%m-%d").parse;
//var parseDate = d3.time.format("%d/%m/%Y").parse;
//var year = d3.time.format("%m/%Y");

d3.tsv("statsTables/filestats", function(dd) {
for (var i = 0; i < dd.length; i++)
{
	dd[i]["date"] = new Date (dd[i]["date"]);

	filestats[ dd[i]["model"] + dd[i]["versionid"]  ] = dd[i];
	//console.log(dd[0]);
}
d3.tsv("statsTables/diffstats", function(d) {
	for (var i=0; i < d.length; i++){
		d[i]["bivesinsert"] = +d[i]["bivesinsert"];
		d[i]["bivesmove"] = +d[i]["bivesmove"];
		d[i]["bivesdelete"] = +d[i]["bivesdelete"];
		d[i]["bivesupdate"] = +d[i]["bivesupdate"];
		d[i]["bives"] = +d[i]["bives"];

	}
	diffstats=d;

	console.log ("ready");
	tuwatt ();
});

});

function tuwatt ()
{
	rows=diffstats;
 	console.log (rows[0]);

	rows.sort(function(a, b) {
                return d3.ascending(a.version2id, b.version2id);
        });

	var counts = {};
	rows.forEach(function(r) {

		var datum = filestats[ r["model"] + r["version2id"]  ].date;

    if (!counts[datum]) {
        counts[datum] = 0;
    }
    counts[datum]++;
	});

	var max = 0;
	var data = [];
	Object.keys(counts).forEach(function(key) {
    data.push({
        datum: new Date(key)
		,
        count: counts[key]
    });
		if (counts[key] > max)
			max = counts[key];
	});

// 	console.log (data);

	var minVersion2 = d3.min(data, function (d){ return d.datum });
	var maxVersion2 = d3.max(data, function (d){ return d.datum });

// 	console.log (minVersion2);
// 	console.log (maxVersion2);

	y.domain([0, max]).nice();
	x.domain([minVersion2, maxVersion2]).nice();

	svg.append("g")
		    .attr("class", "y axis")
				.attr("fill", "white")
		    .call(yAxis)
		  .append("text")
				.attr("x", 25)
		    .attr("y", -20)
		    .attr("dy", ".71em")
		    .style("text-anchor", "end")
				.attr("fill", "white")
		    .text("Changes");

	svg.append("g")
		    .attr("class", "x axis")
				.attr("transform", "translate(0," + timeheight + ")")
				.attr("fill", "white")
		    .call(xAxis);

	var rects = svg.selectAll(".bar")
				  .data(data)
					.enter()
					.append("rect")
				  .attr("class", "bar")
				  .attr("x", function(d) { var meinx = x(d.datum); if (isNaN (meinx)){ console.log ("das is nan: " + meinx); /*console.log (d.datum); console.log (new Date(d.datum)); console.log (x(new Date(d.datum)));*/} return meinx; })
				  .attr("width", timewidth / data.length)
				  .attr("y", function(d) { return y(d.count) })
				  .attr("height", function(d) { return timeheight - y(d.count);})
					.attr("fill", "white");

var parseDate = d3.time.format("%Y-%m-%d").parse;
//var parseDate2 = d3.time.format("%b %d %Y").parse;
//var parseDate = d3.time.format("%d/%m/%Y").parse;
var parseDate2 = d3.time.format("%Y-%m-%d").parse;

/* var date1 = parseDate2(document.getElementById("date1").value);
var date2 = parseDate2(document.getElementById("date2").value); */

var date1 = moment(document.getElementById("date1").value);
var date2 = moment(document.getElementById("date2").value);

var brush = d3.svg.brush()
	.x(x)
	.extent([date1, date2])
	.on("brush", brushmove)
	.on("brushend", brushend);

svg.append("g")
	.attr("class", "brush")
	.call(brush)
.selectAll('rect')
	.attr('height', timeheight);

var modelType = ["BioModels", "CellML"],
    j = 0;  // Choose the rectangle as default

// Create the shape selectors
var dataset = d3.select('#choiceChart').append("dataset")
	.append("text")
	.text("Dataset");

var form = d3.select("#choiceChart").append("form");

labels = form.selectAll("label")
    .data(modelType)
    .enter()
    .append("label")
    .text(function(d) {return d;})
    .insert("input")
    .attr({
		id: function(d, i) { return d;},
        type: "checkbox",
        class: "modelType",
        name: "mode",
        value: function(d, i) {return i;}
    })
    .property("checked", function(d, i) {return i===j;});

var hold = -1; var wait = 1;

var date1Up = document.getElementById("date1Up");
date1Up.onmouseup = function(){ hold = 0;};
date1Up.onmouseout = function(){ hold = 0;};
date1Up.onmousedown = function () { wait = 1; hold = -1; holdit("date1", "up");};

var date1Down = document.getElementById("date1Down");
date1Down.onmouseup = function(){ hold = 0;};
date1Down.onmouseout = function(){ hold = 0;};
date1Down.onmousedown = function () { wait = 1; hold = -1; holdit("date1", "down");};

var date2Up = document.getElementById("date2Up");
date2Up.onmouseup = function(){ hold = 0;};
date2Up.onmouseout = function(){ hold = 0;};
date2Up.onmousedown = function () { wait = 1; hold = -1; holdit("date2", "up");};

var date2Down = document.getElementById("date2Down");
date2Down.onmouseup = function(){ hold = 0;};
date2Down.onmouseout = function(){ hold = 0;};
date2Down.onmousedown = function () { wait = 1; hold = -1; holdit("date2", "down");};

var date1Field = document.getElementById("date1");
date1Field.addEventListener("keydown", function (e) {
	if(e.keyCode === 13){
		var newDate = Date.parse(date1Field.value);
		console.log(newDate);
		alert("jupp");
		if(newDate != null){
			if(newDate < minVersion2){
				newDate = minVersion2;
			} else if(newDate > maxVersion2){
				newDate = maxVersion2;
			}
			brush.extent([newDate, date2]);
			date1 = newDate;
			extent = brush.extent();
			brushed();
		} else {
			alert("Please enter a correct date.");
		}

	}
});

var date2Field = document.getElementById("date2");
date2Field.addEventListener("keydown", function (e) {
	if(e.keyCode === 13){
		var newDate = Date.parse(date2Field.value);
		if(newDate != null){
			if(newDate < minVersion2){
				newDate = minVersion2;
			} else if(newDate > maxVersion2){
				newDate = maxVersion2;
			}
			brush.extent([date1, newDate]);
			date2 = newDate;
			extent = brush.extent();
			brushed();
		} else {
			alert("Please enter a correct date.");
		}
	}
});

function holdit(btn, mode) {
	console.log(hold, wait)
/* 	var testDay = moment("01/01/2010");
	console.log(moment(testDay).format('DD/MM/YYYY'));
	console.log(testDay);
	testDay.add(1, 'days');
	console.log(testDay);
	console.log(moment(testDay).format('DD/MM/YYYY'));
	testDay.add(1, 'days');
	console.log(testDay);
	console.log(moment(testDay).format('DD/MM/YYYY')); */
	if (hold == -1 && wait == 1){
		setTimeout(function(){
			wait = 0;
			if(mode === "up"){
				//console.log("a " + document.getElementById(btn).value);
				var newDate = moment(document.getElementById(btn).value).add(1, 'd');
				//console.log("b " + newDate);
				//console.log(Date.parse(date1Field.value));
				document.getElementById(btn).value = moment(newDate).format('YYYY-MM-DD');
				//console.log("c " + document.getElementById(btn).value);
				if(btn == "date2"){
					brush.extent([date1, newDate]);
					date2 = newDate;
				} else {
					brush.extent([newDate, date2]);
					date1 = newDate;
				}
				extent = brush.extent();
				brushed();
			} else {
				var newDate = moment(document.getElementById(btn).value).add(-1, 'days');
				document.getElementById(btn).value = moment(newDate).format('YYYY-MM-DD');
				if(btn == "date2"){
					brush.extent([date1, newDate]);
					date2 = newDate;
				} else {
					brush.extent([newDate, date2]);
					date1 = newDate;
				}
				extent = brush.extent();
				brushed();
			}

			holdit(btn, mode);
		}, 300);
	} else if (hold == -1){
		setTimeout(function(){
			wait = 0;
			if(mode === "up"){
				//console.log("a " + document.getElementById(btn).value);
				var newDate = moment(document.getElementById(btn).value).add(1, 'd');
				//console.log("b " + newDate);
				//console.log(Date.parse(date1Field.value));
				document.getElementById(btn).value = moment(newDate).format('YYYY-MM-DD');
				//console.log("c " + document.getElementById(btn).value);
				if(btn == "date2"){
					brush.extent([date1, newDate]);
					date2 = newDate;
				} else {
					brush.extent([newDate, date2]);
					date1 = newDate;
				}
				extent = brush.extent();
				brushed();
			} else {
				var newDate = moment(document.getElementById(btn).value).add(-1, 'days');
				document.getElementById(btn).value = moment(newDate).format('YYYY-MM-DD');
				if(btn == "date2"){
					brush.extent([date1, newDate]);
					date2 = newDate;
				} else {
					brush.extent([newDate, date2]);
					date1 = newDate;
				}
				extent = brush.extent();
				brushed();
			}

			holdit(btn, mode);
		}, 1);
	}
};

function brushed() {
	svg.select(".brush").call(brush);
}

function brushmove() {
	extent = brush.extent();
	date1 = moment(window.extent[0]);
	date2 = moment(window.extent[1]);
	document.getElementById("date1").value = date1.format('YYYY-MM-DD');
	document.getElementById("date2").value = date2.format('YYYY-MM-DD');
}

function brushend() {
	//alert("brushEND");
	svg.select(".brush").call(brush);
	extent = brush.extent();
}

}

<|endoftext|>


<commit_before>/*
 * Copyright 2013 Jive Software
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Private

var fs = require('fs');
var path = require('path');
var express = require('express');
var q = require('q');
var bootstrap = require('./bootstrap');
var definitionConfigurator = require('./definitionSetup');
var osAppConfigurator = require('./appSetup');
var serviceConfigurator = require('./serviceSetup');
var jive = require('../api');
var log4js = require('log4js');
var mustache = require('mustache');

var app;
var rootDir = process.cwd();
var tilesDir = rootDir + '/tiles';
var osAppsDir = rootDir + '/apps';
var cartridgesDir = rootDir + '/cartridges';
var storagesDir = rootDir + '/storages';

var _dir = function(theDir, defaultDir ) {
    theDir = theDir || defaultDir;

    if ( theDir.indexOf('/') == 0 ) {
        return rootDir + theDir;
    } else {
        return process.cwd() + '/' + theDir;
    }
};

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Public

/**
 * For managing jive communities registered with this service
 */
exports.community = jive.community;

/**
 * For managing service webhooks
 */
exports.webhooks = jive.webhooks;

/**
 * Configuration options
 */
exports.options = {};

var persistence;
/**
 * Retrieves or sets current persistence strategy, defaults to file.
 * @type {undefined}
 */
exports.persistence = function(_persistence) {

    if ( _persistence ) {
        // set persistence
        if ( !_persistence['find'] || !_persistence['findByID'] || !_persistence['remove'] || !_persistence['save'] ) {
            throw 'Unsupported persistence strategy - must implement find, findByID, remove, save methods.';
        }
        persistence = _persistence;
        jive.context['persistence'] = persistence;
    }

    // retrieve persistence
    return {
        save: function() {
            return persistence ? persistence.save(
                arguments.length > 0 ? arguments[0] : undefined,
                arguments.length > 1 ? arguments[1] : undefined,
                arguments.length > 2 ? arguments[2] : undefined,
                arguments.length > 3 ? arguments[3] : undefined,
                arguments.length > 4 ? arguments[4] : undefined,
                arguments.length > 5 ? arguments[5] : undefined
            ) : function() {
                return q.reject( new Error("persistence not defined") );
            }
        },

        find: function() {
            return persistence ? persistence.find(
                arguments.length > 0 ? arguments[0] : undefined,
                arguments.length > 1 ? arguments[1] : undefined,
                arguments.length > 2 ? arguments[2] : undefined,
                arguments.length > 3 ? arguments[3] : undefined,
                arguments.length > 4 ? arguments[4] : undefined,
                arguments.length > 5 ? arguments[5] : undefined
            ) : function() {
                return q.reject( new Error("persistence not defined") );
            }
        },

        findByID: function() {
            return persistence ? persistence.findByID(
                arguments.length > 0 ? arguments[0] : undefined,
                arguments.length > 1 ? arguments[1] : undefined,
                arguments.length > 2 ? arguments[2] : undefined,
                arguments.length > 3 ? arguments[3] : undefined,
                arguments.length > 4 ? arguments[4] : undefined,
                arguments.length > 5 ? arguments[5] : undefined
            ) : function() {
                return q.reject( new Error("persistence not defined") );
            }
        },

        remove: function() {
            return persistence ? persistence.remove(
                arguments.length > 0 ? arguments[0] : undefined,
                arguments.length > 1 ? arguments[1] : undefined,
                arguments.length > 2 ? arguments[2] : undefined,
                arguments.length > 3 ? arguments[3] : undefined,
                arguments.length > 4 ? arguments[4] : undefined,
                arguments.length > 5 ? arguments[5] : undefined
            ) : function() {
                return q.reject( new Error("persistence not defined") );
            }
        },

        close: function() {
            return persistence ? persistence.close() :  function() {
                return q.reject( new Error("persistence not defined") );
            }
        }
    }
};

var scheduler;
/**
 * Retrieves or sets the scheduling strategy. Defaults to memory (single node). todo
 * @param _scheduler
 * @returns {*}
 */
exports.scheduler = function( _scheduler ) {
    if ( _scheduler ) {
        if ( !_scheduler['schedule'] || !_scheduler['unschedule'] || !_scheduler['getTasks'] ) {
            throw 'Unsupported scheduler strategy - must implement schedule, unschedule, isScheduled, getTasks.';
        }
        scheduler = _scheduler;

        if ( !scheduler ) {
            scheduler = new jive.scheduler.memory();
        }
        jive.context.scheduler = scheduler;
    }
    scheduler = jive.context.scheduler;
    return scheduler;
};

/**
 * @param _app
 * @param options JSON or path to options file
 * @param definitionsToAutowire optional arraylist of tile names under [app root]/tiles to autowire
 */
exports.init = function(_app, options ) {
    if (_app) {
        app = _app;
    }
    else {
        app = express();
    }
    rootDir =  rootDir || process.cwd();
    tilesDir = rootDir + '/tiles';

    // for some reason this needs to be configured earlier than later
    app.use(express.bodyParser());
    app.use(express.logger('dev'));
    app.use(express.methodOverride());
    app.use(app.router);
    app.use(express.errorHandler());

    var applyDefaults = function(config) {
        if ( !config['persistence'] ) {
            config['persistence'] = 'file';
        }
        if ( !config['scheduler'] ) {
            config['scheduler'] = 'memory';
        }
    };

   var applyOverrides = function(config) {
        // override role
        var roleFromEnv = process.env['jive_sdk_service_role'];
        if ( roleFromEnv ) {
            config['role'] = roleFromEnv;
        }
    };

    var initialPromise;
    if ( typeof options === 'object' ) {
        applyDefaults(options);
        applyOverrides(options);
        exports.options = options;
        jive.context.config = exports.options;

        initialPromise = q.fcall( function() {
            return options;
        });
    } else {
        // if no options are provided, then try getting them from
        // cmd line arguments, or from environemnt
        if ( !options ) {
            var configFileFromEnv = process.env['jive_sdk_config_file'];
            var configFilePathFromArgs = undefined;

            process.argv.forEach(function (val, index, array) {
                if ( val.indexOf('=') > -1 ) {
                    var arg = val.split(/=/);

                    if ( arg[0] == 'configFile' ) {
                        jive.logger.debug("Command line argument:"  + arg[0] + "=" + arg[1]);
                        configFilePathFromArgs = arg[1];
                    }
                }
            });

            options = configFilePathFromArgs || configFileFromEnv;

            if( !options ) {
                // assume its a file in the rootdir
                options = rootDir + "/jiveclientconfiguration.json";
            }
        }

        initialPromise = q.nfcall( fs.readFile, options, 'utf8').then( function (data) {
            var jiveConfig = JSON.parse(data);
            applyDefaults(jiveConfig);
            applyOverrides(jiveConfig);

            exports.options = jiveConfig;
            jive.context.config = exports.options;

            jive.logger.debug('Startup configuration from', options);
            jive.logger.debug(jiveConfig);

            return jiveConfig;
        });
    }

    return initialPromise
            .then(initLogger)
            .then(initPersistence)
            .then(initScheduler);
};

function initLogger(options) {
    var logfile = options['logFile'] || options['logfile'];
    var logLevel = process.env['jive_logging_level'] || options['logLevel'] || options['loglevel'] || 'INFO';
    logLevel = logLevel.toUpperCase();

    if (logfile) {
        if (logfile.indexOf('logs/') === 0) {
            if (!fs.existsSync('logs')) {
                jive.logger.warn('logs subdirectory does not exist. Creating directory now.');
                fs.mkdirSync('logs');
            }
        }
        log4js.loadAppender('file');
        log4js.addAppender(log4js.appenders.file(logfile), 'jive-sdk');
    }

    jive.logger.setLevel(logLevel);

    return options;
}

function initPersistence(options) {
    var persistence = options['persistence'];
    if ( typeof persistence === 'object' ) {
        // set persistence if the object is provided
        exports.persistence( options['persistence'] );
    }
    else if ( typeof persistence === 'string' ) {
        //If a string is provided, and it's a valid type exported in jive.persistence, then use that.
        if (jive.persistence[persistence]) {
            exports.persistence(new jive.persistence[persistence](options)); //pass options, such as location of DB for mongoDB.
        }
        else {
            jive.logger.warn('Invalid persistence option given "' + persistence + '". Must be one of ' + Object.keys(jive.persistence));
            jive.logger.warn('Defaulting to file persistence');
        }
    }
    return options;
}

function initScheduler(options) {
    var scheduler = options['scheduler'];
    if ( typeof scheduler === 'object' ) {
        // set scheduler if the object is provided
        exports.scheduler(scheduler);
    }
    else if ( typeof scheduler === 'string' ) {
        //If a string is provided, and it's a valid type exported in jive.scheduler, then use that.
        if (jive.scheduler[scheduler]) {
            exports.scheduler(new jive.scheduler[scheduler](options)); //pass options, such as location of redis for Kue.
        }
        else {
            jive.logger.warn('Invalid scheduler option given "' + scheduler + '". Must be one of ' + Object.keys(jive.scheduler));
            jive.logger.warn('Defaulting to memory scheduler');
        }
    }
    return options;
}

/**
 *
 */
exports.autowire = function(definitionsToAutowire) {
    if( definitionsToAutowire ) {

        if (definitionsToAutowire['forEach'] ) {
            var promises = [];
            definitionsToAutowire.forEach( function( definition ) {
                promises.push( definitionConfigurator.setupOneDefinition(
                    app, _dir( '/tiles/' + definition), definition
                ) );
            });
            return q.all(promises);
        } else {
            return definitionConfigurator.setupOneDefinition(
                app, _dir( '/tiles/' + definitionsToAutowire), definitionsToAutowire
            );
        }
    } else {
        // assume autowiring everything
        return definitionConfigurator.setupAllDefinitions(app, _dir( '/tiles', '/tiles'))
        .then( function () {
            return osAppConfigurator.setupAllApps( app, _dir( '/apps', '/apps'));
        })
        .then( function () {
            return serviceConfigurator.setupAllServices( app, _dir( '/services', '/services'));
        })
        .then( function () {
            return serviceConfigurator.setupAllServices( app, _dir( '/storages', '/storages'));
        });
    }
};

/**
 * Autowire a routes directory for a given definition
 * @param definitionName
 * @param definitionRouteDirectory
 */
exports.autowireDefinitionRoutes = function( definitionName, definitionRouteDirectory ) {
    return definitionConfigurator.setupDefinitionRoutes(
        app, definitionName, _dir(definitionRouteDirectory, '/tiles/' + definitionName + '/routes' )
    );
};

/**
 * Autowire a services directory for a given definition
 * @param definitionName
 * @param definitionServicesDirectory
 */
exports.autowireDefinitionServices = function( definitionName, definitionServicesDirectory ) {
    return definitionConfigurator.setupDefinitionServices(
        definitionName, _dir( definitionServicesDirectory, '/tiles/' + definitionName + '/services' )
    );
};

/**
 * Autowire definition metadata file for a given definition
 * @param definitionMetadataFile
 */
exports.autowireDefinitionMetadata = function( definitionMetadataFile ) {
    return definitionConfigurator.setupDefinitionMetadata(definitionMetadataFile);
};

/**
 * Return promise - fail or succeed
 */
exports.start = function() {
    return bootstrap.start( app, exports.options, rootDir, tilesDir, osAppsDir, cartridgesDir, storagesDir).then( function() {
        jive.logger.info("Service started in " + app['settings']['env'] + " mode");
    });
};

/**
 * Computes the full service URL for this service, taking into account
 * jiveclientconfiguration.json (clientUrl & port)
 */
exports.serviceURL = function() {
    var conf = jive.service.options;
    var url = conf['clientUrl'];

    var port = conf['port'];
    if ( port && port != 443 && port != 80 ) {
        url += ':' + port;
    }

    return url;
};

/**
 * Public service routes
 */
exports.routes = {
    'tiles' : require('../routes/tiles'),
    'jive' : require('../routes/jive'),
    'dev' : require('../routes/dev'),
    'oauth' : require('../routes/oauth')
};

/**
 * Interrogate the role of this node
 */
exports.role = {
    'isWorker' : function() {
        return !exports.options['role'] || exports.options['role'] === jive.constants.roles.WORKER;
    },
    'isPusher' : function() {
        return !exports.options['role'] || exports.options['role'] === jive.constants.roles.PUSHER;
    },
    'isHttp' : function() {
        return !exports.options['role'] || exports.options['role'] === jive.constants.roles.HTTP_HANDLER;
    }
};

exports.extensions = function() {
    return require('./extension/extension');
};

exports.getExpandedTileDefinitions = function(all) {
    var conf = exports.options;
    var host = exports.serviceURL();
    var processed = [];

    all.forEach( function( tile ) {
        if ( !tile ) {
            return;
        }
        var name = tile.name;
        var stringified = JSON.stringify(tile);
        stringified =  mustache.render(stringified, {
            host: host,
            tile_public: host + '/' + name,
            tile_route: host + '/' + name,
            clientId: conf.clientId
        });

        var processedTile = JSON.parse(stringified);

        // defaults
        if ( !processedTile['published'] ) {
            processedTile['published'] = "2013-02-28T15:12:16.768-0800";
        }
        if ( !processedTile['updated'] ) {
            processedTile['updated'] = "2013-02-28T15:12:16.768-0800";
        }
        if ( processedTile['action'] ) {
            if ( processedTile['action'].indexOf('http') != 0 ) {
                // assume its relative to host then
                processedTile['action'] = host + ( processedTile['action'].indexOf('/') == 0 ? "" : "/" ) + processedTile['action'];
            }
        }
        if ( !processedTile['config'] ) {
            processedTile['config'] = host + '/' + processedTile['definitionDirName'] + '/configure';
        } else {
            if ( processedTile['config'].indexOf('http') != 0 ) {
                // assume its relative to host then
                processedTile['config'] = host + ( processedTile['config'].indexOf('/') == 0 ? "" : "/" ) + processedTile['config'];
            }
        }
        if ( !processedTile['register'] ) {
            processedTile['register'] = host + '/registration';
        } else {
            if ( processedTile['register'].indexOf('http') != 0 ) {
                // assume its relative to host then
                processedTile['register'] = host + ( processedTile['register'].indexOf('/') == 0 ? "" : "/" ) + processedTile['register'];
            }
        }
        if ( processedTile['unregister'] && processedTile['unregister'].indexOf('http') != 0 ) {
            // assume its relative to host then
            processedTile['unregister'] = host + ( processedTile['unregister'].indexOf('/') == 0 ? "" : "/" ) + processedTile['unregister'];
        }
        if ( !processedTile['client_id'] ) {
            processedTile['client_id'] = conf.clientId;
        }
        if ( !processedTile['id'] ) {
            processedTile['id'] = '{{{definition_id}}}';
        }

        if (conf.clientId) {
            processedTile.description += ' for ' + conf.clientId;
        }
        processed.push( processedTile );
    });
    return processed;
};

exports.security = security;
<commit_msg>Accidently left in some code that I meant to remove before committing.<commit_after>/*
 * Copyright 2013 Jive Software
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Private

var fs = require('fs');
var path = require('path');
var express = require('express');
var q = require('q');
var bootstrap = require('./bootstrap');
var definitionConfigurator = require('./definitionSetup');
var osAppConfigurator = require('./appSetup');
var serviceConfigurator = require('./serviceSetup');
var jive = require('../api');
var log4js = require('log4js');
var mustache = require('mustache');

var app;
var rootDir = process.cwd();
var tilesDir = rootDir + '/tiles';
var osAppsDir = rootDir + '/apps';
var cartridgesDir = rootDir + '/cartridges';
var storagesDir = rootDir + '/storages';

var _dir = function(theDir, defaultDir ) {
    theDir = theDir || defaultDir;

    if ( theDir.indexOf('/') == 0 ) {
        return rootDir + theDir;
    } else {
        return process.cwd() + '/' + theDir;
    }
};

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Public

/**
 * For managing jive communities registered with this service
 */
exports.community = jive.community;

/**
 * For managing service webhooks
 */
exports.webhooks = jive.webhooks;

/**
 * Configuration options
 */
exports.options = {};

var persistence;
/**
 * Retrieves or sets current persistence strategy, defaults to file.
 * @type {undefined}
 */
exports.persistence = function(_persistence) {

    if ( _persistence ) {
        // set persistence
        if ( !_persistence['find'] || !_persistence['findByID'] || !_persistence['remove'] || !_persistence['save'] ) {
            throw 'Unsupported persistence strategy - must implement find, findByID, remove, save methods.';
        }
        persistence = _persistence;
        jive.context['persistence'] = persistence;
    }

    // retrieve persistence
    return {
        save: function() {
            return persistence ? persistence.save(
                arguments.length > 0 ? arguments[0] : undefined,
                arguments.length > 1 ? arguments[1] : undefined,
                arguments.length > 2 ? arguments[2] : undefined,
                arguments.length > 3 ? arguments[3] : undefined,
                arguments.length > 4 ? arguments[4] : undefined,
                arguments.length > 5 ? arguments[5] : undefined
            ) : function() {
                return q.reject( new Error("persistence not defined") );
            }
        },

        find: function() {
            return persistence ? persistence.find(
                arguments.length > 0 ? arguments[0] : undefined,
                arguments.length > 1 ? arguments[1] : undefined,
                arguments.length > 2 ? arguments[2] : undefined,
                arguments.length > 3 ? arguments[3] : undefined,
                arguments.length > 4 ? arguments[4] : undefined,
                arguments.length > 5 ? arguments[5] : undefined
            ) : function() {
                return q.reject( new Error("persistence not defined") );
            }
        },

        findByID: function() {
            return persistence ? persistence.findByID(
                arguments.length > 0 ? arguments[0] : undefined,
                arguments.length > 1 ? arguments[1] : undefined,
                arguments.length > 2 ? arguments[2] : undefined,
                arguments.length > 3 ? arguments[3] : undefined,
                arguments.length > 4 ? arguments[4] : undefined,
                arguments.length > 5 ? arguments[5] : undefined
            ) : function() {
                return q.reject( new Error("persistence not defined") );
            }
        },

        remove: function() {
            return persistence ? persistence.remove(
                arguments.length > 0 ? arguments[0] : undefined,
                arguments.length > 1 ? arguments[1] : undefined,
                arguments.length > 2 ? arguments[2] : undefined,
                arguments.length > 3 ? arguments[3] : undefined,
                arguments.length > 4 ? arguments[4] : undefined,
                arguments.length > 5 ? arguments[5] : undefined
            ) : function() {
                return q.reject( new Error("persistence not defined") );
            }
        },

        close: function() {
            return persistence ? persistence.close() :  function() {
                return q.reject( new Error("persistence not defined") );
            }
        }
    }
};

var scheduler;
/**
 * Retrieves or sets the scheduling strategy. Defaults to memory (single node). todo
 * @param _scheduler
 * @returns {*}
 */
exports.scheduler = function( _scheduler ) {
    if ( _scheduler ) {
        if ( !_scheduler['schedule'] || !_scheduler['unschedule'] || !_scheduler['getTasks'] ) {
            throw 'Unsupported scheduler strategy - must implement schedule, unschedule, isScheduled, getTasks.';
        }
        scheduler = _scheduler;

        if ( !scheduler ) {
            scheduler = new jive.scheduler.memory();
        }
        jive.context.scheduler = scheduler;
    }
    scheduler = jive.context.scheduler;
    return scheduler;
};

/**
 * @param _app
 * @param options JSON or path to options file
 * @param definitionsToAutowire optional arraylist of tile names under [app root]/tiles to autowire
 */
exports.init = function(_app, options ) {
    if (_app) {
        app = _app;
    }
    else {
        app = express();
    }
    rootDir =  rootDir || process.cwd();
    tilesDir = rootDir + '/tiles';

    // for some reason this needs to be configured earlier than later
    app.use(express.bodyParser());
    app.use(express.logger('dev'));
    app.use(express.methodOverride());
    app.use(app.router);
    app.use(express.errorHandler());

    var applyDefaults = function(config) {
        if ( !config['persistence'] ) {
            config['persistence'] = 'file';
        }
        if ( !config['scheduler'] ) {
            config['scheduler'] = 'memory';
        }
    };

   var applyOverrides = function(config) {
        // override role
        var roleFromEnv = process.env['jive_sdk_service_role'];
        if ( roleFromEnv ) {
            config['role'] = roleFromEnv;
        }
    };

    var initialPromise;
    if ( typeof options === 'object' ) {
        applyDefaults(options);
        applyOverrides(options);
        exports.options = options;
        jive.context.config = exports.options;

        initialPromise = q.fcall( function() {
            return options;
        });
    } else {
        // if no options are provided, then try getting them from
        // cmd line arguments, or from environemnt
        if ( !options ) {
            var configFileFromEnv = process.env['jive_sdk_config_file'];
            var configFilePathFromArgs = undefined;

            process.argv.forEach(function (val, index, array) {
                if ( val.indexOf('=') > -1 ) {
                    var arg = val.split(/=/);

                    if ( arg[0] == 'configFile' ) {
                        jive.logger.debug("Command line argument:"  + arg[0] + "=" + arg[1]);
                        configFilePathFromArgs = arg[1];
                    }
                }
            });

            options = configFilePathFromArgs || configFileFromEnv;

            if( !options ) {
                // assume its a file in the rootdir
                options = rootDir + "/jiveclientconfiguration.json";
            }
        }

        initialPromise = q.nfcall( fs.readFile, options, 'utf8').then( function (data) {
            var jiveConfig = JSON.parse(data);
            applyDefaults(jiveConfig);
            applyOverrides(jiveConfig);

            exports.options = jiveConfig;
            jive.context.config = exports.options;

            jive.logger.debug('Startup configuration from', options);
            jive.logger.debug(jiveConfig);

            return jiveConfig;
        });
    }

    return initialPromise
            .then(initLogger)
            .then(initPersistence)
            .then(initScheduler);
};

function initLogger(options) {
    var logfile = options['logFile'] || options['logfile'];
    var logLevel = process.env['jive_logging_level'] || options['logLevel'] || options['loglevel'] || 'INFO';
    logLevel = logLevel.toUpperCase();

    if (logfile) {
        if (logfile.indexOf('logs/') === 0) {
            if (!fs.existsSync('logs')) {
                jive.logger.warn('logs subdirectory does not exist. Creating directory now.');
                fs.mkdirSync('logs');
            }
        }
        log4js.loadAppender('file');
        log4js.addAppender(log4js.appenders.file(logfile), 'jive-sdk');
    }

    jive.logger.setLevel(logLevel);

    return options;
}

function initPersistence(options) {
    var persistence = options['persistence'];
    if ( typeof persistence === 'object' ) {
        // set persistence if the object is provided
        exports.persistence( options['persistence'] );
    }
    else if ( typeof persistence === 'string' ) {
        //If a string is provided, and it's a valid type exported in jive.persistence, then use that.
        if (jive.persistence[persistence]) {
            exports.persistence(new jive.persistence[persistence](options)); //pass options, such as location of DB for mongoDB.
        }
        else {
            jive.logger.warn('Invalid persistence option given "' + persistence + '". Must be one of ' + Object.keys(jive.persistence));
            jive.logger.warn('Defaulting to file persistence');
        }
    }
    return options;
}

function initScheduler(options) {
    var scheduler = options['scheduler'];
    if ( typeof scheduler === 'object' ) {
        // set scheduler if the object is provided
        exports.scheduler(scheduler);
    }
    else if ( typeof scheduler === 'string' ) {
        //If a string is provided, and it's a valid type exported in jive.scheduler, then use that.
        if (jive.scheduler[scheduler]) {
            exports.scheduler(new jive.scheduler[scheduler](options)); //pass options, such as location of redis for Kue.
        }
        else {
            jive.logger.warn('Invalid scheduler option given "' + scheduler + '". Must be one of ' + Object.keys(jive.scheduler));
            jive.logger.warn('Defaulting to memory scheduler');
        }
    }
    return options;
}

/**
 *
 */
exports.autowire = function(definitionsToAutowire) {
    if( definitionsToAutowire ) {

        if (definitionsToAutowire['forEach'] ) {
            var promises = [];
            definitionsToAutowire.forEach( function( definition ) {
                promises.push( definitionConfigurator.setupOneDefinition(
                    app, _dir( '/tiles/' + definition), definition
                ) );
            });
            return q.all(promises);
        } else {
            return definitionConfigurator.setupOneDefinition(
                app, _dir( '/tiles/' + definitionsToAutowire), definitionsToAutowire
            );
        }
    } else {
        // assume autowiring everything
        return definitionConfigurator.setupAllDefinitions(app, _dir( '/tiles', '/tiles'))
        .then( function () {
            return osAppConfigurator.setupAllApps( app, _dir( '/apps', '/apps'));
        })
        .then( function () {
            return serviceConfigurator.setupAllServices( app, _dir( '/services', '/services'));
        })
        .then( function () {
            return serviceConfigurator.setupAllServices( app, _dir( '/storages', '/storages'));
        });
    }
};

/**
 * Autowire a routes directory for a given definition
 * @param definitionName
 * @param definitionRouteDirectory
 */
exports.autowireDefinitionRoutes = function( definitionName, definitionRouteDirectory ) {
    return definitionConfigurator.setupDefinitionRoutes(
        app, definitionName, _dir(definitionRouteDirectory, '/tiles/' + definitionName + '/routes' )
    );
};

/**
 * Autowire a services directory for a given definition
 * @param definitionName
 * @param definitionServicesDirectory
 */
exports.autowireDefinitionServices = function( definitionName, definitionServicesDirectory ) {
    return definitionConfigurator.setupDefinitionServices(
        definitionName, _dir( definitionServicesDirectory, '/tiles/' + definitionName + '/services' )
    );
};

/**
 * Autowire definition metadata file for a given definition
 * @param definitionMetadataFile
 */
exports.autowireDefinitionMetadata = function( definitionMetadataFile ) {
    return definitionConfigurator.setupDefinitionMetadata(definitionMetadataFile);
};

/**
 * Return promise - fail or succeed
 */
exports.start = function() {
    return bootstrap.start( app, exports.options, rootDir, tilesDir, osAppsDir, cartridgesDir, storagesDir).then( function() {
        jive.logger.info("Service started in " + app['settings']['env'] + " mode");
    });
};

/**
 * Computes the full service URL for this service, taking into account
 * jiveclientconfiguration.json (clientUrl & port)
 */
exports.serviceURL = function() {
    var conf = jive.service.options;
    var url = conf['clientUrl'];

    var port = conf['port'];
    if ( port && port != 443 && port != 80 ) {
        url += ':' + port;
    }

    return url;
};

/**
 * Public service routes
 */
exports.routes = {
    'tiles' : require('../routes/tiles'),
    'jive' : require('../routes/jive'),
    'dev' : require('../routes/dev'),
    'oauth' : require('../routes/oauth')
};

/**
 * Interrogate the role of this node
 */
exports.role = {
    'isWorker' : function() {
        return !exports.options['role'] || exports.options['role'] === jive.constants.roles.WORKER;
    },
    'isPusher' : function() {
        return !exports.options['role'] || exports.options['role'] === jive.constants.roles.PUSHER;
    },
    'isHttp' : function() {
        return !exports.options['role'] || exports.options['role'] === jive.constants.roles.HTTP_HANDLER;
    }
};

exports.extensions = function() {
    return require('./extension/extension');
};

exports.getExpandedTileDefinitions = function(all) {
    var conf = exports.options;
    var host = exports.serviceURL();
    var processed = [];

    all.forEach( function( tile ) {
        if ( !tile ) {
            return;
        }
        var name = tile.name;
        var stringified = JSON.stringify(tile);
        stringified =  mustache.render(stringified, {
            host: host,
            tile_public: host + '/' + name,
            tile_route: host + '/' + name,
            clientId: conf.clientId
        });

        var processedTile = JSON.parse(stringified);

        // defaults
        if ( !processedTile['published'] ) {
            processedTile['published'] = "2013-02-28T15:12:16.768-0800";
        }
        if ( !processedTile['updated'] ) {
            processedTile['updated'] = "2013-02-28T15:12:16.768-0800";
        }
        if ( processedTile['action'] ) {
            if ( processedTile['action'].indexOf('http') != 0 ) {
                // assume its relative to host then
                processedTile['action'] = host + ( processedTile['action'].indexOf('/') == 0 ? "" : "/" ) + processedTile['action'];
            }
        }
        if ( !processedTile['config'] ) {
            processedTile['config'] = host + '/' + processedTile['definitionDirName'] + '/configure';
        } else {
            if ( processedTile['config'].indexOf('http') != 0 ) {
                // assume its relative to host then
                processedTile['config'] = host + ( processedTile['config'].indexOf('/') == 0 ? "" : "/" ) + processedTile['config'];
            }
        }
        if ( !processedTile['register'] ) {
            processedTile['register'] = host + '/registration';
        } else {
            if ( processedTile['register'].indexOf('http') != 0 ) {
                // assume its relative to host then
                processedTile['register'] = host + ( processedTile['register'].indexOf('/') == 0 ? "" : "/" ) + processedTile['register'];
            }
        }
        if ( processedTile['unregister'] && processedTile['unregister'].indexOf('http') != 0 ) {
            // assume its relative to host then
            processedTile['unregister'] = host + ( processedTile['unregister'].indexOf('/') == 0 ? "" : "/" ) + processedTile['unregister'];
        }
        if ( !processedTile['client_id'] ) {
            processedTile['client_id'] = conf.clientId;
        }
        if ( !processedTile['id'] ) {
            processedTile['id'] = '{{{definition_id}}}';
        }

        if (conf.clientId) {
            processedTile.description += ' for ' + conf.clientId;
        }
        processed.push( processedTile );
    });
    return processed;
};
<|endoftext|>


<commit_before><commit_msg>Logic syntax setter method<commit_after>//setter methods

console.log("Syntax: ");
console.log("The set syntax binds an object property to a function \n to be called when there is an attempt to set that property.");
console.log("{set prop(val) { ... } }");
console.log("{set [expression](val) { ... } }");<|endoftext|>


<commit_before>(function($){
	if(!$){
		throw 'jQuery is not defined';
	}
	function definePlugin(name, pluginPrototypeDefinition) {
		'use strict';
		var Plugin = (new Function('return ' + definePlugin.tpl.replace(/\$\$\$/gm, name)))();
		if (!Plugin.name) {
			Plugin.name = name;
		}
		Plugin.prototype = pluginPrototypeDefinition();
		Plugin.prototype.constructor = Plugin;
		Plugin.prototype.triggerChangeEvent = function(data){
			this.$el.trigger(name + '.change', data);
		}

		var missingFunction = ['getValue', 'setValue', 'init', 'getDefaults', 'bindEvents'].filter(function (key) {
			return typeof Plugin.prototype[key] !== 'function';
		});

		if (missingFunction.length) {
			throw new Error('Plugin: ' + name + ' must implement: "' + missingFunction.join(', ') + '"');
		}

		definePlugin.registerAsJqueryPlugin(name, Plugin);

		return Plugin;
	}

	definePlugin.registerAsJqueryPlugin = function (name, Plugin) {
		if (window.jQuery && window.jQuery.fn) {
			window.jQuery.fn[name] = function (options) {
				return this.each(function () {
					if (!$.data(this, 'plugin_' + name)) {
						$.data(this, 'plugin_' + name, new Plugin(this, options));
					}
				});
			};
		}
	}

	definePlugin.tpl = function $$$(el, options) {
		'use strict';
		if (!(this instanceof $$$)) {
			throw new Error('Plugin: $$$ must called with the "new" keyword');
		}
		this.$el = window.jQuery(el);
		this.options = window.jQuery.extend({}, this.getDefaults(), options);
		this.init();
		return this;
	}.toString();

	$.fn.definePlugin = definePlugin;

}(jQuery))

<commit_msg>define plugin pass the name of the plugin into the definition function<commit_after>(function($){
	if(!$){
		throw 'jQuery is not defined';
	}
	function definePlugin(name, pluginPrototypeDefinition) {
		'use strict';
		var Plugin = (new Function('return ' + definePlugin.tpl.replace(/\$\$\$/gm, name)))();
		if (!Plugin.name) {
			Plugin.name = name;
		}
		Plugin.prototype = pluginPrototypeDefinition(name);
		Plugin.prototype.constructor = Plugin;
		Plugin.prototype.triggerChangeEvent = function(data){
			this.$el.trigger(name + '.change', data);
		}

		var missingFunction = ['getValue', 'setValue', 'init', 'getDefaults', 'bindEvents'].filter(function (key) {
			return typeof Plugin.prototype[key] !== 'function';
		});

		if (missingFunction.length) {
			throw new Error('Plugin: ' + name + ' must implement: "' + missingFunction.join(', ') + '"');
		}

		definePlugin.registerAsJqueryPlugin(name, Plugin);

		return Plugin;
	}

	definePlugin.registerAsJqueryPlugin = function (name, Plugin) {
		if (window.jQuery && window.jQuery.fn) {
			window.jQuery.fn[name] = function (options) {
				return this.each(function () {
					if (!$.data(this, 'plugin_' + name)) {
						$.data(this, 'plugin_' + name, new Plugin(this, options));
					}
				});
			};
		}
	}

	definePlugin.tpl = function $$$(el, options) {
		'use strict';
		if (!(this instanceof $$$)) {
			throw new Error('Plugin: $$$ must called with the "new" keyword');
		}
		this.$el = window.jQuery(el);
		this.options = window.jQuery.extend({}, this.getDefaults(), options);
		this.init();
		return this;
	}.toString();

	$.fn.definePlugin = definePlugin;

}(jQuery))

<|endoftext|>


<commit_before>
//can be positive or negative. if high enough, can
//turn into romance in a quadrant.
function Relationship(initial_value, target_player){
	this.value = initial_value;
	this.target = target_player;
	this.saved_type = "";
	this.drama = false; //drama is set to true if type of relationship changes.
	this.old_type = "";
	//wish class variables were a thing.
	this.neutral = "Ambivalent"
	this.goodMild = "Friends";
	this.goodBig = "Totally In Love";
	this.badMild = "Rivals";
	this.badBig = "Enemies";
	this.heart = "Matesprits"
	this.diamond = "Moirallegiance"
	this.clubs = "Auspisticism"
	this.spades = "Kismesissitude";

	this.nounDescription = function(){
		if(this.saved_type = this.diamond) return "moirail"
		if(this.saved_type = this.goodBig) return "crush"
		if(this.saved_type = this.badBig) return "black crush"
		if(this.saved_type = this.badMild) return "rival"
		if(this.saved_type = this.goodMild) return "friend"
		if(this.saved_type = this.clubs) return "auspistice"
		if(this.saved_type = this.spades) return "kismesis"
		if(this.saved_type = this.neutral) return "friend"
	}

	//eventually, when i adapt this to be SGRUB, have 2d relationships.  feel good or bad, feel concupiscient or not.
	//also trolls are rivals unless value is at least 5 (more likely to be enemies than friends)
	this.changeType = function(){
		if(this.value > 20){ //used to be -10 to 10, but too many crushes.
			return this.goodBig;
		}else if(this.value < -20){
			return this.badBig;
		}else if(this.value > 0){
			return this.goodMild;
		}else if (this.value == 0){
			return this.neutral;
		}else{
			return this.badMild;
		}
	}
	//can't do this before function is written. so dumb.
	this.saved_type = this.changeType();
	//for most interactions, the relationship will grow along it's current trajectory.
	this.moreOfSame = function(){
		if(this.value >= 0){
			this.increase();
		}else{
			this.decrease();
		}
	}

	this.increase = function(){
		this.value ++;
	}

	this.decrease = function(){
		this.value += -1;
	}

	//the only way to fill your quadrants.
	this.setOfficialRomance = function(type){
		//don't generate any extra drama, the event that led to this was ALREADY drama.
		this.saved_type = type;
		this.old_type = type;
	}

	this.type = function(){
		//official relationships are different.
		if(this.saved_type == this.heart || this.saved_type == this.spades || this.saved_type == this.diamond || this.saved_type == this.clubs){
			return this.saved_type; //break up in own scene, not here.
		}
		if(this.saved_type == "" ){
			this.drama = false;
			this.saved_type = this.changeType();
			this.old_type = this.saved_type;
			//if it's big drama, you can have your scene
			if(this.saved_type == this.goodBig || this.saved_type == this.badBig){
				this.drama = true;
				this.old_type = this.goodMild;
			}
			return this.saved_type;
		}

		if(Math.seededRandom() > 0.25){
			//enter or leave a relationship, or vaccilate.
			this.old_type = this.saved_type;
			this.saved_type = this.changeType();
		}

		if(this.old_type != this.saved_type){
			this.drama = true;
		}else{
			this.drama = false;
		}
		return this.saved_type;
	}

	this.description = function(){
		return this.saved_type + " with the " + this.target.htmlTitle();
	}

}

function getRelationshipFlavorGreeting(r1, r2, me, you){
	var ret = "";
	if(r1.type() == r1.goodBig && r2.type() == r2.goodBig){
		ret += " Hey! ";
	}else if(r2.type() == r2.goodBig){
		ret += "Hey.";
	}else if(r1.type() == r1.goodBig){
		ret += " Uh, hey!";
	}else if(r1.type() == r1.badBig && r2.type() == r2.badBig){
		ret += " Hey, asshole.";
	}else if(r2.type() == r2.badBig){
		ret += "Er...hey?"
	}else if(r1.type() == r2.badBig){
		ret += "I'll make this quick. ";
	}else{
		ret += "Hey."
	}
	return ret;

}

function getRelationshipFlavorText(r1, r2, me, you){
	var ret = "";
	if(r1.type() == r1.goodBig && r2.type() == r2.goodBig){
		ret += " The two flirt a bit. ";
	}else if(r2.type() == r2.goodBig){
		ret += " The" + you.htmlTitle() + " is flustered around the " + me.htmlTitle()+ ". ";
	}else if(r1.type() == r1.goodBig){
		ret += " The" + me.htmlTitle() + " is flustered around the " + you.htmlTitle()+ ". ";
	}else if(r1.type() == r1.badBig && r2.type() == r2.badBig){
		ret += " The two are just giant assholes to each other. ";
	}else if(r2.type() == r2.badBig){
		ret += you.htmlTitle() + " is irritable around the " + me.htmlTitle() + ". ";
	}else if(r1.type() == r2.badBig){
		ret += " The" + me.htmlTitle() + " is irritable around the " + you.htmlTitle() + ". ";
	}
	return ret;
}

function cloneRelationship(relationship){
	var clone = new Relationship();
	for(var propertyName in relationship) {
		clone[propertyName] = relationship[propertyName];
	}
	return clone;
}

//when i am cloning players, i need to make sure they don't have a reference to the same relationships the original player does.
//if i fail to do this step, i accidentally give the players the Capgras delusion.
//this HAS to happen before transferFeelingsToClones.
function cloneRelationshipsStopgap(relationships){
		//console.log("clone relationships stopgap")
		var ret = [];
		for(var i = 0; i<relationships.length; i++){
			var r = relationships[i]
			ret.push(cloneRelationship(r));
		}
		return ret;
}

//when i clone alien players on arival, i need their cloned relationships to be about the other clones
//not the original players.
//also, I <3 this method name. i <3 this sim.
function transferFeelingsToClones(player, clones){
	//console.log("transfer feelings to clones")
	for(var i =0; i<player.relationships.length; i++){
			var r = player.relationships[i];
			var clone = findClaspectPlayer(clones, r.target.class_name, r.target.aspect);
			//if i can't find a clone, it's probably a dead player that didn't come to the new session.
			//may as well keep the original relationship
			if(clone){
				r.target = clone;
			}

	}
}

function makeHeart(player1, player2){
	var r1 = player1.getRelationshipWith(player2)
	r1.setOfficialRomance(r1.heart)
	var r2 = player2.getRelationshipWith(player1)
	r2.setOfficialRomance(r2.heart)
}

function makeSpades(player1, player2){
	var r1 = player1.getRelationshipWith(player2)
	r1.setOfficialRomance(r1.spades)
	var r2 = player2.getRelationshipWith(player1)
	r2.setOfficialRomance(r2.spades)
}

function makeDiamonds(player1, player2){
	var r1 = player1.getRelationshipWith(player2)
	if(r1.value < 0){
		r1.value = 1;  //like you at least a little
	}
	r1.setOfficialRomance(r1.diamond)
	var r2 = player2.getRelationshipWith(player1)
	if(r2.value < 0){
		r2.value = 1;
	}
	r2.setOfficialRomance(r2.diamond)
}

//clubs, why you so cray cray?
function makeClubs(middleLeaf, asshole1, asshole2){
	var rmid1 = middleLeaf.getRelationshipWith(asshole1);
	var rmid2 = middleLeaf.getRelationshipWith(asshole2);

	var rass1mid = asshole1.getRelationshipWith(middleLeaf);
	var rass12 =   asshole1.getRelationshipWith(asshole2);

	var rass2mid = asshole2.getRelationshipWith(middleLeaf);
	var rass21 =   asshole2.getRelationshipWith(asshole1);

	if(rmid1.value > 0){
		rmid1.value = -1;  //hate you at least a little
	}

	if(rmid2.value > 0){
		rmid2.value = -1;  //hate you at least a little
	}

	rmid1.setOfficialRomance(rmid1.clubs)
	rmid2.setOfficialRomance(rmid1.clubs)
	rass1mid.setOfficialRomance(rmid1.clubs)
	rass12.setOfficialRomance(rmid1.clubs)
	rass2mid.setOfficialRomance(rmid1.clubs)
	rass21.setOfficialRomance(rmid1.clubs)
}

function randomBlandRelationship(targetPlayer){
	return new Relationship(1, targetPlayer);
}

function randomRelationship(targetPlayer){
	var r = new Relationship(getRandomInt(-21,21), targetPlayer);

	return r;
}

//go through every pair of relationships. if both have same type AND they are lucky, be in quadrant.   (clover was VERY 'lucky' in love.)
//high is flushed or pale (if one player much more triggered than other). low is spades. no clubs for now.
//yes, claspect boosts might alter relationships from 'initial' value, but that just means they characters are likelyt o break up. realism.
function decideInitialQuadrants(players){
	for(var i =0; i<players.length; i++){
		var player = players[i];
		var relationships = player.relationships;
		for(var j = 0; j<relationships.length; j++){
			var r = relationships[j];
			var roll = player.rollForLuck();
			if(roll > 50){
				if(r.type() == r.goodBig){
					var difference = Math.abs(player.triggerLevel - r.target.triggerLevel)
					if(difference > 2){ //pale
						makeDiamonds(player, r.target);
					}else{
						makeHeart(player, r.target);
					}
				}else if(r.type() == r.badBig){
					if(player.triggerLevel > 2 || r.target.triggerLevel > 2){ //likely to murder each other
						var ausp = getRandomElementFromArray(players);
						if(ausp && ausp != player && ausp != r.target){
							makeClubs(ausp, player, r.target);
						}
					}else{
						makeSpades(player, r.target);
					}
				}
			}
		}
	}
}

function getRandomInt(min, max) {
    return Math.floor(Math.seededRandom() * (max - min + 1)) + min;
}
<commit_msg>coding feelings jams<commit_after>
//can be positive or negative. if high enough, can
//turn into romance in a quadrant.
function Relationship(initial_value, target_player){
	this.value = initial_value;
	this.target = target_player;
	this.saved_type = "";
	this.drama = false; //drama is set to true if type of relationship changes.
	this.old_type = "";
	//wish class variables were a thing.
	this.neutral = "Ambivalent"
	this.goodMild = "Friends";
	this.goodBig = "Totally In Love";
	this.badMild = "Rivals";
	this.badBig = "Enemies";
	this.heart = "Matesprits"
	this.diamond = "Moirallegiance"
	this.clubs = "Auspisticism"
	this.spades = "Kismesissitude";

	this.nounDescription = function(){
		if(this.saved_type == this.diamond) return "moirail"
		if(this.saved_type == this.goodBig) return "crush"
		if(this.saved_type == this.badBig) return "black crush"
		if(this.saved_type == this.badMild) return "rival"
		if(this.saved_type == this.goodMild) return "friend"
		if(this.saved_type == this.clubs) return "auspistice"
		if(this.saved_type == this.spades) return "kismesis"
		if(this.saved_type == this.neutral) return "friend"
	}

	//eventually, when i adapt this to be SGRUB, have 2d relationships.  feel good or bad, feel concupiscient or not.
	//also trolls are rivals unless value is at least 5 (more likely to be enemies than friends)
	this.changeType = function(){
		if(this.value > 20){ //used to be -10 to 10, but too many crushes.
			return this.goodBig;
		}else if(this.value < -20){
			return this.badBig;
		}else if(this.value > 0){
			return this.goodMild;
		}else if (this.value == 0){
			return this.neutral;
		}else{
			return this.badMild;
		}
	}
	//can't do this before function is written. so dumb.
	this.saved_type = this.changeType();
	//for most interactions, the relationship will grow along it's current trajectory.
	this.moreOfSame = function(){
		if(this.value >= 0){
			this.increase();
		}else{
			this.decrease();
		}
	}

	this.increase = function(){
		this.value ++;
	}

	this.decrease = function(){
		this.value += -1;
	}

	//the only way to fill your quadrants.
	this.setOfficialRomance = function(type){
		//don't generate any extra drama, the event that led to this was ALREADY drama.
		this.saved_type = type;
		this.old_type = type;
	}

	this.type = function(){
		//official relationships are different.
		if(this.saved_type == this.heart || this.saved_type == this.spades || this.saved_type == this.diamond || this.saved_type == this.clubs){
			return this.saved_type; //break up in own scene, not here.
		}
		if(this.saved_type == "" ){
			this.drama = false;
			this.saved_type = this.changeType();
			this.old_type = this.saved_type;
			//if it's big drama, you can have your scene
			if(this.saved_type == this.goodBig || this.saved_type == this.badBig){
				this.drama = true;
				this.old_type = this.goodMild;
			}
			return this.saved_type;
		}

		if(Math.seededRandom() > 0.25){
			//enter or leave a relationship, or vaccilate.
			this.old_type = this.saved_type;
			this.saved_type = this.changeType();
		}

		if(this.old_type != this.saved_type){
			this.drama = true;
		}else{
			this.drama = false;
		}
		return this.saved_type;
	}

	this.description = function(){
		return this.saved_type + " with the " + this.target.htmlTitle();
	}

}

function getRelationshipFlavorGreeting(r1, r2, me, you){
	var ret = "";
	if(r1.type() == r1.goodBig && r2.type() == r2.goodBig){
		ret += " Hey! ";
	}else if(r2.type() == r2.goodBig){
		ret += "Hey.";
	}else if(r1.type() == r1.goodBig){
		ret += " Uh, hey!";
	}else if(r1.type() == r1.badBig && r2.type() == r2.badBig){
		ret += " Hey, asshole.";
	}else if(r2.type() == r2.badBig){
		ret += "Er...hey?"
	}else if(r1.type() == r2.badBig){
		ret += "I'll make this quick. ";
	}else{
		ret += "Hey."
	}
	return ret;

}

function getRelationshipFlavorText(r1, r2, me, you){
	var ret = "";
	if(r1.type() == r1.goodBig && r2.type() == r2.goodBig){
		ret += " The two flirt a bit. ";
	}else if(r2.type() == r2.goodBig){
		ret += " The" + you.htmlTitle() + " is flustered around the " + me.htmlTitle()+ ". ";
	}else if(r1.type() == r1.goodBig){
		ret += " The" + me.htmlTitle() + " is flustered around the " + you.htmlTitle()+ ". ";
	}else if(r1.type() == r1.badBig && r2.type() == r2.badBig){
		ret += " The two are just giant assholes to each other. ";
	}else if(r2.type() == r2.badBig){
		ret += you.htmlTitle() + " is irritable around the " + me.htmlTitle() + ". ";
	}else if(r1.type() == r2.badBig){
		ret += " The" + me.htmlTitle() + " is irritable around the " + you.htmlTitle() + ". ";
	}
	return ret;
}

function cloneRelationship(relationship){
	var clone = new Relationship();
	for(var propertyName in relationship) {
		clone[propertyName] = relationship[propertyName];
	}
	return clone;
}

//when i am cloning players, i need to make sure they don't have a reference to the same relationships the original player does.
//if i fail to do this step, i accidentally give the players the Capgras delusion.
//this HAS to happen before transferFeelingsToClones.
function cloneRelationshipsStopgap(relationships){
		//console.log("clone relationships stopgap")
		var ret = [];
		for(var i = 0; i<relationships.length; i++){
			var r = relationships[i]
			ret.push(cloneRelationship(r));
		}
		return ret;
}

//when i clone alien players on arival, i need their cloned relationships to be about the other clones
//not the original players.
//also, I <3 this method name. i <3 this sim.
function transferFeelingsToClones(player, clones){
	//console.log("transfer feelings to clones")
	for(var i =0; i<player.relationships.length; i++){
			var r = player.relationships[i];
			var clone = findClaspectPlayer(clones, r.target.class_name, r.target.aspect);
			//if i can't find a clone, it's probably a dead player that didn't come to the new session.
			//may as well keep the original relationship
			if(clone){
				r.target = clone;
			}

	}
}

function makeHeart(player1, player2){
	var r1 = player1.getRelationshipWith(player2)
	r1.setOfficialRomance(r1.heart)
	var r2 = player2.getRelationshipWith(player1)
	r2.setOfficialRomance(r2.heart)
}

function makeSpades(player1, player2){
	var r1 = player1.getRelationshipWith(player2)
	r1.setOfficialRomance(r1.spades)
	var r2 = player2.getRelationshipWith(player1)
	r2.setOfficialRomance(r2.spades)
}

function makeDiamonds(player1, player2){
	var r1 = player1.getRelationshipWith(player2)
	if(r1.value < 0){
		r1.value = 1;  //like you at least a little
	}
	r1.setOfficialRomance(r1.diamond)
	var r2 = player2.getRelationshipWith(player1)
	if(r2.value < 0){
		r2.value = 1;
	}
	r2.setOfficialRomance(r2.diamond)
}

//clubs, why you so cray cray?
function makeClubs(middleLeaf, asshole1, asshole2){
	var rmid1 = middleLeaf.getRelationshipWith(asshole1);
	var rmid2 = middleLeaf.getRelationshipWith(asshole2);

	var rass1mid = asshole1.getRelationshipWith(middleLeaf);
	var rass12 =   asshole1.getRelationshipWith(asshole2);

	var rass2mid = asshole2.getRelationshipWith(middleLeaf);
	var rass21 =   asshole2.getRelationshipWith(asshole1);

	if(rmid1.value > 0){
		rmid1.value = -1;  //hate you at least a little
	}

	if(rmid2.value > 0){
		rmid2.value = -1;  //hate you at least a little
	}

	rmid1.setOfficialRomance(rmid1.clubs)
	rmid2.setOfficialRomance(rmid1.clubs)
	rass1mid.setOfficialRomance(rmid1.clubs)
	rass12.setOfficialRomance(rmid1.clubs)
	rass2mid.setOfficialRomance(rmid1.clubs)
	rass21.setOfficialRomance(rmid1.clubs)
}

function randomBlandRelationship(targetPlayer){
	return new Relationship(1, targetPlayer);
}

function randomRelationship(targetPlayer){
	var r = new Relationship(getRandomInt(-21,21), targetPlayer);

	return r;
}

//go through every pair of relationships. if both have same type AND they are lucky, be in quadrant.   (clover was VERY 'lucky' in love.)
//high is flushed or pale (if one player much more triggered than other). low is spades. no clubs for now.
//yes, claspect boosts might alter relationships from 'initial' value, but that just means they characters are likelyt o break up. realism.
function decideInitialQuadrants(players){
	for(var i =0; i<players.length; i++){
		var player = players[i];
		var relationships = player.relationships;
		for(var j = 0; j<relationships.length; j++){
			var r = relationships[j];
			var roll = player.rollForLuck();
			if(roll > 50){
				if(r.type() == r.goodBig){
					var difference = Math.abs(player.triggerLevel - r.target.triggerLevel)
					if(difference > 2){ //pale
						makeDiamonds(player, r.target);
					}else{
						makeHeart(player, r.target);
					}
				}else if(r.type() == r.badBig){
					if(player.triggerLevel > 2 || r.target.triggerLevel > 2){ //likely to murder each other
						var ausp = getRandomElementFromArray(players);
						if(ausp && ausp != player && ausp != r.target){
							makeClubs(ausp, player, r.target);
						}
					}else{
						makeSpades(player, r.target);
					}
				}
			}
		}
	}
}

function getRandomInt(min, max) {
    return Math.floor(Math.seededRandom() * (max - min + 1)) + min;
}
<|endoftext|>


<commit_before>function loadMeals(displayPast){
	var printAll = displayPast || false;
	var upcomingMeals = document.getElementById('upcomingMeals');
	if(meals.length > 0){
		meals.sort(function(a, b){
			return sortMealsByTimestamp(a, b);
		});
		upcomingMeals.innerHTML = "";
		for(var m = 0; m < meals.length; m++){
			if(meals[m].timestamp > new Date().getTime() || printAll){
				upcomingMeals.innerHTML += meals[m].toHTML();
			}
		}
	}
	else{
		upcomingMeals.innerHTML += '
No meals are currently listed. Host your own!
';
	}
}

function loadMealOptions(){
	var mealSelector = document.getElementById('mealSelector');
	if(meals.length > 0){
		meals.sort(function(a, b){
			return sortMealsByTimestamp(a, b);
		});
		mealSelector.innerHTML = '<option value="newMeal">Add New Meal</option>';
		for(var m = 0; m < meals.length; m++){
			if(meals[m].timestamp > new Date().getTime()){
				mealSelector.innerHTML += meals[m].toOption();
			}
		}
	}
}

function Meal(snapshot){
	this.name = snapshot.name;
	this.id = snapshot.id;
	this.chef = snapshot.chef;
	this.timestamp = snapshot.timestamp;
	this.location = snapshot.location;
	this.img = snapshot.img;
	this.price = snapshot.price;
	this.capacity = snapshot.capacity;
}

Meal.prototype.toString = function(){
	return this.name + " by " + this.chef + ": " + moment(this.timestamp).calendar() + " for " + this.capacity + " people at " + money(this.price) + " each.";
}

Meal.prototype.toHTML = function(){
	var html = '';
	//html += '
';
	html += '
';
		html += '
';
			html += '
';
			html += '
Join us at ' + this.location + ' ' + moment(this.timestamp).calendar() + ' for this meal.
';
			html += this.getHTMLPayButton();
			html += '
';
			html += '
$' + this.price + ' per person
';
			html += '
' + this.capacity + ' spots left
';
			html += '
' + moment(this.timestamp).format('MM/DD h:mm A') + '
';
		html += '
';
		html += '
';
			html += '
' + this.name + '
';
			html += '
' + this.chef + '
';
		html += '
';
	html += '
';
	return html;
}

Meal.prototype.getHTMLPayButton = function(){
	/*CODE FOR DWOLLA BUTTON:
		var button = '';
			button += '';
				button += 'Pay and Join';
				button += '';
			button += '';
		return button;*/
	var button = '';
		button += '<form class="paypalForm" method="post" action="https://www.paypal.com/cgi-bin/webscr" class="paypal-button" target="_top">';
			button += '

';
			button += '<input type="hidden" name="button" value="buynow">';
			button += '<input type="hidden" name="item_name" value="EcoEats Meal: ' + this.name + '">';
			button += '<input type="hidden" name="amount" value="' + this.price + '">';
			button += '<input type="hidden" name="cmd" value="_xclick">';
			button += '<input type="hidden" name="business" value="QWZMVF8ZHS2P4">';
			button += '<input type="hidden" name="bn" value="JavaScriptButton_buynow">';
			button += '<input type="hidden" name="env" value="www">';
			button += '<button type="submit" id="' + this.id + '" onclick="togglePayButton('' + this.id + '');" class="paypal-button large">Pay Now</button>';
		button += '</form>';
	return button;
}

function money(value){
	return "$" + value.toFixed(2);
}

function sortMealsByTimestamp(meal1, meal2){
	return meal1.timestamp - meal2.timestamp;
}

/*function viewMeal(id){
	alert(id + "");
}*/<commit_msg>Added Meal.toOption()<commit_after>function loadMeals(displayPast){
	var printAll = displayPast || false;
	var upcomingMeals = document.getElementById('upcomingMeals');
	if(meals.length > 0){
		meals.sort(function(a, b){
			return sortMealsByTimestamp(a, b);
		});
		upcomingMeals.innerHTML = "";
		for(var m = 0; m < meals.length; m++){
			if(meals[m].timestamp > new Date().getTime() || printAll){
				upcomingMeals.innerHTML += meals[m].toHTML();
			}
		}
	}
	else{
		upcomingMeals.innerHTML += '
No meals are currently listed. Host your own!
';
	}
}

function loadMealOptions(){
	var mealSelector = document.getElementById('mealSelector');
	if(meals.length > 0){
		meals.sort(function(a, b){
			return sortMealsByTimestamp(a, b);
		});
		mealSelector.innerHTML = '<option value="newMeal">Add: New Meal</option>';
		for(var m = 0; m < meals.length; m++){
			if(meals[m].timestamp > new Date().getTime()){
				mealSelector.innerHTML += meals[m].toOption();
			}
		}
	}
}

function Meal(snapshot){
	this.name = snapshot.name;
	this.id = snapshot.id;
	this.chef = snapshot.chef;
	this.timestamp = snapshot.timestamp;
	this.location = snapshot.location;
	this.img = snapshot.img;
	this.price = snapshot.price;
	this.capacity = snapshot.capacity;
}

Meal.prototype.toString = function(){
	return this.name + " by " + this.chef + ": " + moment(this.timestamp).calendar() + " for " + this.capacity + " people at " + money(this.price) + " each.";
}

Meal.prototype.toHTML = function(){
	var html = '';
	//html += '
';
	html += '
';
		html += '
';
			html += '
';
			html += '
Join us at ' + this.location + ' ' + moment(this.timestamp).calendar() + ' for this meal.
';
			html += this.getHTMLPayButton();
			html += '
';
			html += '
$' + this.price + ' per person
';
			html += '
' + this.capacity + ' spots left
';
			html += '
' + moment(this.timestamp).format('MM/DD h:mm A') + '
';
		html += '
';
		html += '
';
			html += '
' + this.name + '
';
			html += '
' + this.chef + '
';
		html += '
';
	html += '
';
	return html;
}

Meal.prototype.getHTMLPayButton = function(){
	/*CODE FOR DWOLLA BUTTON:
		var button = '';
			button += '';
				button += 'Pay and Join';
				button += '';
			button += '';
		return button;*/
	var button = '';
		button += '<form class="paypalForm" method="post" action="https://www.paypal.com/cgi-bin/webscr" class="paypal-button" target="_top">';
			button += '

';
			button += '<input type="hidden" name="button" value="buynow">';
			button += '<input type="hidden" name="item_name" value="EcoEats Meal: ' + this.name + '">';
			button += '<input type="hidden" name="amount" value="' + this.price + '">';
			button += '<input type="hidden" name="cmd" value="_xclick">';
			button += '<input type="hidden" name="business" value="QWZMVF8ZHS2P4">';
			button += '<input type="hidden" name="bn" value="JavaScriptButton_buynow">';
			button += '<input type="hidden" name="env" value="www">';
			button += '<button type="submit" id="' + this.id + '" onclick="togglePayButton('' + this.id + '');" class="paypal-button large">Pay Now</button>';
		button += '</form>';
	return button;
}

Meal.prototype.toOption = function(){
	var html = '';
		html += '<option value="' + this.id + '">Edit: ' + this.name + '</option>';
	return html;
}

function money(value){
	return "$" + value.toFixed(2);
}

function sortMealsByTimestamp(meal1, meal2){
	return meal1.timestamp - meal2.timestamp;
}

/*function viewMeal(id){
	alert(id + "");
}*/<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc service
 * @name passmanApp.ShareService
 * @description
 * # ShareService
 * Service in the passmanApp.
 */
angular.module('passmanApp')
	.service('ShareService', ['$http', 'VaultService', 'EncryptService', 'CredentialService', function ($http, VaultService, EncryptService, CredentialService) {
		// Setup sjcl random engine to max paranoia level and start collecting data
		var paranoia_level = 10;
		sjcl.random.setDefaultParanoia(paranoia_level);
		sjcl.random.startCollectors();

		return {
			search: function (string) {
				var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/search');
				return $http.post(queryUrl, {search: string}).then(function (response) {
					if (response.data) {
						return response.data;
					} else {
						return response;
					}
				});
			},
			shareWithUser: function (credential, target_user_data) {
				var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/share');
				return $http.post(queryUrl,
					{
						item_id: credential.credential_id,
						item_guid: credential.guid,
						permissions: target_user_data.accessLevel,
						vaults: target_user_data.vaults,
					}
				);
			},
			getVaultsByUser: function (userId) {
				var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/vaults/' + userId);
				return $http.get(queryUrl, {search: userId}).then(function (response) {
					if (response.data) {
						for (var i = 0; i < response.data.length; i++) {
							response.data[i].public_sharing_key = forge.pki.publicKeyFromPem(response.data[i].public_sharing_key);
						}
						return response.data;
					} else {
						return response;
					}
				});
			},
			getPendingRequests: function () {
				var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/pending');
				return $http.get(queryUrl).then(function (response) {
					if (response.data) {
						return response.data;
					}
				});
			},
			saveSharingRequest: function (request, crypted_shared_key) {
				var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/save');
				return $http.post(queryUrl, {
					item_guid: request.item_guid,
					target_vault_guid: request.target_vault_guid,
					final_shared_key: crypted_shared_key
				}).then(function (response) {
					return response.data;
				})
			},
			unshareCredential: function (credential) {
				var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/unshare/' + credential.guid);
				return $http.delete(queryUrl).then(function (response) {
					return response.data;
				})
			},
			getPublicSharedCredential: function (credential_guid) {
				var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/credential/' + credential_guid);
				return $http.get(queryUrl).then(function (response) {
						if (response.data) {
							return response;
						} else {
							return response;
						}
					},
					function (result) {
						return result;
					})
			},
			getCredendialsSharedWithUs: function (vault_guid) {
				var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/vault/' + vault_guid + '/get');
				return $http.get(queryUrl).then(function (response) {
					if (response.data) {
						return response.data;
					}
				});
			},
			encryptSharedCredential: function (credential, sharedKey) {
				var _credential = angular.copy(credential);
				_credential.shared_key = EncryptService.encryptString(sharedKey);
				var encrypted_fields = CredentialService.getEncryptedFields();
				for (var i = 0; i < encrypted_fields.length; i++) {
					var field = encrypted_fields[i];
					var fieldValue = angular.copy(credential[field]);
					_credential[field] = EncryptService.encryptString(JSON.stringify(fieldValue), sharedKey);
				}
				return _credential;
			},
			decryptSharedCredential: function (credential, sharedKey) {
				var _credential = angular.copy(credential);
				var encrypted_fields = CredentialService.getEncryptedFields();
				for (var i = 0; i < encrypted_fields.length; i++) {
					var field = encrypted_fields[i];
					var fieldValue = angular.copy(_credential[field]);
					if (_credential.hasOwnProperty(field)) {
						try {
							var field_decrypted_value = EncryptService.decryptString(fieldValue, sharedKey);
						} catch (e) {
							console.log(e);
							throw e
						}
						try {
							_credential[field] = JSON.parse(field_decrypted_value);
						} catch (e) {
							console.log('Field' + field + ' in ' + _credential.label + ' could not be parsed! Value:' + fieldValue)
							throw e
						}
					}
				}
				return _credential;
			},

			generateRSAKeys: function (key_length, progress, callback) {
				var p = new C_Promise(function () {
					var state = forge.pki.rsa.createKeyPairGenerationState(key_length, 0x10001);
					var step = function () {
						// run for 100 ms
						if (!forge.pki.rsa.stepKeyPairGenerationState(state, 100)) {
							// console.log(state);
							if (state.p !== null) {
								// progress(50);
								this.call_progress(50);
							}
							else {
								// progress(0);
								this.call_progress(0);
							}
							setTimeout(step.bind(this), 1);
						}
						else {
							// callback(state.keys);
							this.call_then(state.keys);
						}
					};
					setTimeout(step.bind(this), 100);
				});
				return p;
			},
			generateSharedKey: function (size) {
				size = size || 20;
				return new C_Promise(function () {
					var t = this;
					CRYPTO.PASSWORD.generate(size,
						function (pass) {
							t.call_then(pass);
						},
						function (progress) {
							t.call_progress(progress);
						}
					);
				})
			},
			rsaKeyPairToPEM: function (keypair) {
				return {
					'publicKey': forge.pki.publicKeyToPem(keypair.publicKey),
					'privateKey': forge.pki.privateKeyToPem(keypair.privateKey)
				};
			},
			getSharingKeys: function () {
				var vault = VaultService.getActiveVault();
				return {
					'private_sharing_key': EncryptService.decryptString(angular.copy(vault.private_sharing_key)),
					'public_sharing_key': vault.public_sharing_key
				};
			},
			rsaPrivateKeyFromPEM: function (private_pem) {
				return forge.pki.privateKeyFromPem(private_pem);
			},
			rsaPublicKeyFromPEM: function (public_pem) {
				return forge.pki.publicKeyFromPem(public_pem);
			},
			/**
			 * Cyphers an array of string in a non-blocking way
			 * @param vaults[]    An array of vaults with the processed public keys
			 * @param string    The string to cypher
			 */
			cypherRSAStringWithPublicKeyBulkAsync: function (vaults, string) {
				var workload = function () {
					if (this.current_index < this.vaults.length > 0 && this.vaults.length > 0) {
						var _vault = angular.copy(this.vaults[this.current_index]);
						_vault.key = forge.util.encode64(
							_vault.public_sharing_key.encrypt(this.string)
						);
						this.data.push(
							_vault
						);
						this.current_index++;

						this.call_progress(this.current_index);
						setTimeout(workload.bind(this), 1);
					}
					else {
						this.call_then(this.data);
					}
				};
				return new C_Promise(function () {
					this.data = [];
					this.vaults = vaults;
					this.string = string;
					this.current_index = 0;

					setTimeout(workload.bind(this), 0);
				});
			}
		}
	}]);
<commit_msg>Update endpoint<commit_after>'use strict';

/**
 * @ngdoc service
 * @name passmanApp.ShareService
 * @description
 * # ShareService
 * Service in the passmanApp.
 */
angular.module('passmanApp')
	.service('ShareService', ['$http', 'VaultService', 'EncryptService', 'CredentialService', function ($http, VaultService, EncryptService, CredentialService) {
		// Setup sjcl random engine to max paranoia level and start collecting data
		var paranoia_level = 10;
		sjcl.random.setDefaultParanoia(paranoia_level);
		sjcl.random.startCollectors();

		return {
			search: function (string) {
				var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/search');
				return $http.post(queryUrl, {search: string}).then(function (response) {
					if (response.data) {
						return response.data;
					} else {
						return response;
					}
				});
			},
			shareWithUser: function (credential, target_user_data) {
				var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/share');
				return $http.post(queryUrl,
					{
						item_id: credential.credential_id,
						item_guid: credential.guid,
						permissions: target_user_data.accessLevel,
						vaults: target_user_data.vaults,
					}
				);
			},
			getVaultsByUser: function (userId) {
				var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/vaults/' + userId);
				return $http.get(queryUrl, {search: userId}).then(function (response) {
					if (response.data) {
						for (var i = 0; i < response.data.length; i++) {
							response.data[i].public_sharing_key = forge.pki.publicKeyFromPem(response.data[i].public_sharing_key);
						}
						return response.data;
					} else {
						return response;
					}
				});
			},
			getPendingRequests: function () {
				var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/pending');
				return $http.get(queryUrl).then(function (response) {
					if (response.data) {
						return response.data;
					}
				});
			},
			saveSharingRequest: function (request, crypted_shared_key) {
				var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/save');
				return $http.post(queryUrl, {
					item_guid: request.item_guid,
					target_vault_guid: request.target_vault_guid,
					final_shared_key: crypted_shared_key
				}).then(function (response) {
					return response.data;
				})
			},
			unshareCredential: function (credential) {
				var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/unshare/' + credential.guid);
				return $http.delete(queryUrl).then(function (response) {
					return response.data;
				})
			},
			getPublicSharedCredential: function (credential_guid) {
				var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/public/credential/' + credential_guid);
				return $http.get(queryUrl).then(function (response) {
						if (response.data) {
							return response;
						} else {
							return response;
						}
					},
					function (result) {
						return result;
					})
			},
			getCredendialsSharedWithUs: function (vault_guid) {
				var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/vault/' + vault_guid + '/get');
				return $http.get(queryUrl).then(function (response) {
					if (response.data) {
						return response.data;
					}
				});
			},
			encryptSharedCredential: function (credential, sharedKey) {
				var _credential = angular.copy(credential);
				_credential.shared_key = EncryptService.encryptString(sharedKey);
				var encrypted_fields = CredentialService.getEncryptedFields();
				for (var i = 0; i < encrypted_fields.length; i++) {
					var field = encrypted_fields[i];
					var fieldValue = angular.copy(credential[field]);
					_credential[field] = EncryptService.encryptString(JSON.stringify(fieldValue), sharedKey);
				}
				return _credential;
			},
			decryptSharedCredential: function (credential, sharedKey) {
				var _credential = angular.copy(credential);
				var encrypted_fields = CredentialService.getEncryptedFields();
				for (var i = 0; i < encrypted_fields.length; i++) {
					var field = encrypted_fields[i];
					var fieldValue = angular.copy(_credential[field]);
					if (_credential.hasOwnProperty(field)) {
						try {
							var field_decrypted_value = EncryptService.decryptString(fieldValue, sharedKey);
						} catch (e) {
							console.log(e);
							throw e
						}
						try {
							_credential[field] = JSON.parse(field_decrypted_value);
						} catch (e) {
							console.log('Field' + field + ' in ' + _credential.label + ' could not be parsed! Value:' + fieldValue)
							throw e
						}
					}
				}
				return _credential;
			},

			generateRSAKeys: function (key_length, progress, callback) {
				var p = new C_Promise(function () {
					var state = forge.pki.rsa.createKeyPairGenerationState(key_length, 0x10001);
					var step = function () {
						// run for 100 ms
						if (!forge.pki.rsa.stepKeyPairGenerationState(state, 100)) {
							// console.log(state);
							if (state.p !== null) {
								// progress(50);
								this.call_progress(50);
							}
							else {
								// progress(0);
								this.call_progress(0);
							}
							setTimeout(step.bind(this), 1);
						}
						else {
							// callback(state.keys);
							this.call_then(state.keys);
						}
					};
					setTimeout(step.bind(this), 100);
				});
				return p;
			},
			generateSharedKey: function (size) {
				size = size || 20;
				return new C_Promise(function () {
					var t = this;
					CRYPTO.PASSWORD.generate(size,
						function (pass) {
							t.call_then(pass);
						},
						function (progress) {
							t.call_progress(progress);
						}
					);
				})
			},
			rsaKeyPairToPEM: function (keypair) {
				return {
					'publicKey': forge.pki.publicKeyToPem(keypair.publicKey),
					'privateKey': forge.pki.privateKeyToPem(keypair.privateKey)
				};
			},
			getSharingKeys: function () {
				var vault = VaultService.getActiveVault();
				return {
					'private_sharing_key': EncryptService.decryptString(angular.copy(vault.private_sharing_key)),
					'public_sharing_key': vault.public_sharing_key
				};
			},
			rsaPrivateKeyFromPEM: function (private_pem) {
				return forge.pki.privateKeyFromPem(private_pem);
			},
			rsaPublicKeyFromPEM: function (public_pem) {
				return forge.pki.publicKeyFromPem(public_pem);
			},
			/**
			 * Cyphers an array of string in a non-blocking way
			 * @param vaults[]    An array of vaults with the processed public keys
			 * @param string    The string to cypher
			 */
			cypherRSAStringWithPublicKeyBulkAsync: function (vaults, string) {
				var workload = function () {
					if (this.current_index < this.vaults.length > 0 && this.vaults.length > 0) {
						var _vault = angular.copy(this.vaults[this.current_index]);
						_vault.key = forge.util.encode64(
							_vault.public_sharing_key.encrypt(this.string)
						);
						this.data.push(
							_vault
						);
						this.current_index++;

						this.call_progress(this.current_index);
						setTimeout(workload.bind(this), 1);
					}
					else {
						this.call_then(this.data);
					}
				};
				return new C_Promise(function () {
					this.data = [];
					this.vaults = vaults;
					this.string = string;
					this.current_index = 0;

					setTimeout(workload.bind(this), 0);
				});
			}
		}
	}]);
<|endoftext|>