<commit_before>import { expect, request } from 'chai';

import api from '../../src/server';
import Pin from '../../src/models/pin';
import Article from '../../src/models/article';
import Episode from '../../src/models/episode';
import { loadFixture, withLogin, dropDBs } from '../utils';

describe('Pin controller', () => {
	let pin;
	let article;
	let episode;

	before(async () => {
		await dropDBs();
		await loadFixture('initial-data', 'pins');

		pin = await Pin.findOne({});
		article = await Article.findOne({});
		episode = await Episode.findOne({});
	});

	describe('get', () => {
		it('should return all pins', async () => {
			const res = await withLogin(
				request(api).get('/pins')
			);
			expect(res).to.have.status(200);
		});
	});

	describe('get', () => {
		it('should return the a single pin via /pins/:pinId', async () => {
			const res = await withLogin(
				request(api).get(`/pins/${pin._id}`)
			);
			expect(res).to.have.status(200);
		});
	});

	describe('get', () => {
		it('should return a limited number of pins', async () => {
			const res = await withLogin(
				request(api).get('/pins').query({ limit: 1 })
			);
			expect(res).to.have.status(200);
			expect(res.body).to.be.an('array');
		});
	});

	describe('post', () => {
		it('should create an article pin', async () => {
			const res = await withLogin(
				request(api).post('/pins').send({ article: article._id })
			);
			expect(res).to.have.status(200);
		});
	});

	describe('post', () => {
		it('should create an episode pin', async () => {
			const res = await withLogin(
				request(api).post('/pins').send({ episode: episode._id })
			);
			expect(res).to.have.status(200);
		});
	});

	describe('delete', () => {
		it('should delete a pin', async () => {
			const res = await withLogin(
				request(api).delete(`/pins/${pin._id}`)
			);
			expect(res).to.have.status(204);
		});
	});
});
<commit_msg>Tests for updated POST /pins endpoint<commit_after>import { expect, request } from 'chai';

import api from '../../src/server';
import Pin from '../../src/models/pin';
import Article from '../../src/models/article';
import Episode from '../../src/models/episode';
import { loadFixture, withLogin, dropDBs } from '../utils';

describe('Pin controller', () => {
	let pin;
	let article;
	let episode;

	before(async () => {
		await dropDBs();
		await loadFixture('initial-data', 'pins');

		pin = await Pin.findOne({});
		article = await Article.findOne({});
		episode = await Episode.findOne({});
	});

	describe('get', () => {
		it('should return all pins', async () => {
			const res = await withLogin(request(api).get('/pins'));
			expect(res).to.have.status(200);
		});
	});

	describe('get', () => {
		it('should return the a single pin via /pins/:pinId', async () => {
			const res = await withLogin(request(api).get(`/pins/${pin._id}`));
			expect(res).to.have.status(200);
		});
	});

	describe('get', () => {
		it('should return a limited number of pins', async () => {
			const res = await withLogin(
				request(api)
					.get('/pins')
					.query({ limit: 1 }),
			);
			expect(res).to.have.status(200);
			expect(res.body).to.be.an('array');
		});
	});

	describe('post', () => {
		it('should create an article pin and return the hydrated article', async () => {
			const res = await withLogin(
				request(api)
					.post('/pins')
					.send({ article: article._id }),
			);
			expect(res).to.have.status(200);
			expect(res.body).to.have.property('article');
		});
	});

	describe('post', () => {
		it('should create an episode pin and return a hydrated episode', async () => {
			const res = await withLogin(
				request(api)
					.post('/pins')
					.send({ episode: episode._id }),
			);
			expect(res).to.have.status(200);
			expect(res.body).to.have.property('episode');
		});
	});

	describe('delete', () => {
		it('should delete a pin', async () => {
			const res = await withLogin(request(api).delete(`/pins/${pin._id}`));
			expect(res).to.have.status(204);
		});
	});
});
<|endoftext|>


<commit_before>(function() {
	function Exchng(marketId, eventHandler) {
		this.marketId = marketId;
		this.eventHandler = eventHandler;
		this.products = {};
		this._fetching = false;
	}
	Exchng.prototype.fetchData = function() {
		this._fetching = true;
		var exchng = this;
		$.get('ts/market_snapshot', {
			'key': 'A8b04F3',
			'market_id': this.marketId,
			'_r': new Date().getTime()
		}, function(data, textStatus) {
			if(textStatus == 'success') {
				var snapshot = data['snapshot'];
				var market = snapshot['market'];
				var products = {};
				$.each(snapshot['products'], function() {
					products[this['id']] = {
						'id': this['id'],
						'symbol': this['symbol'],
						'orders': {
							'offers': [],
							'bids': []
						}
					};
				});
			    $.each(snapshot['orders'], function(i, order) {
				    var side = order['side'];
				    if (side == 'buy') {
					side = 'bid';
  				    }else if (side == 'sell') {
					side = 'offer';
				    }
					products[order['product_id']]['orders'][side + 's'].push({
						'id': order['id'],
						'price': order['price'],
						'quantity': order['quantity']
					});
				});
				exchng.products = {};
			    $.each(products, function(k, product) {
				exchng.products[k] = new Exchng.Product(product['id'], product['symbol'], product['orders']);
				});
				exchng.eventHandler({
					'name': 'fetch-complete'
				});
			}
			exchng._fetching = false;
		}, 'json');
	};
	Exchng.prototype.beginPoll = function(callback) {
	    var exchgn = this;
	    var poll = function () {
		if (!exchng._fetching) {
		    exchng._fetching = true;
		    $.ajax({
			//url: '/market_update.json?'+(new Date()).getTime(),
			url: 'ts/market_update',
			dataType: 'json',
			success: function(data) {
			    exchng._fetching = false;
			    callback(data);
			},
			error: function (error) {
			    exchng._fetching = false;
			    log("error polling", error.statusText);
			}
		    });
		}
	    }

	    setInterval(poll, 10000);
	};
    Exchng.prototype.removeOrder = function (target_id) {
	var exchng = this;
	// TODO this walk isn't the prettiest thing out there
	// might also turn out to be slow when the market is big
	// should probably maintain some sort of order_id hashmap
	$.each(exchng.products, function (i, product) {
	    $.each(product.orders, function (side, orders) {
		$.each(product.orders[side], function (i, order) {
		    if (order.id == target_id) {
			product.orders[side].splice(i, 1);
		    }
		});
	    });
	});
    };
	Exchng.Product = function(id, symbol, orders) {
		var product = this;
		this['id'] = id;
		this['symbol'] = symbol;
		this['orders'] = {
			'offers': orders['offers'].slice(0),
			'bids': orders['bids'].slice(0)
		};
		this.sortOrders();
	};
	Exchng.Product.prototype.addOrder = function(order) {
		var orders = this['orders'];
	        var side = order['side'];
	        if (side == 'buy') {
		    side = 'bid';
  	        }else if (side == 'sell') {
		    side = 'offer';
	        }

		orders[side + 's'].push({
						'id': order['id'],
						'price': order['price'],
						'quantity': order['quantity']
					});
	};
	Exchng.Product.prototype.sortOrders = function() {
		var orders = this['orders'];
		var product = this;
		orders['offers'].sort(function(a, b) {
			return a['price'] < b['price'];
		});
		orders['bids'].sort(function(a, b) {
			return a['price'] < b['price'];
		});
		this['details'] = [];
		$.each(orders['offers'], function() {
			if(product['details'].length == 0 || product['details'][product['details'].length - 1]['offer'] != this['price']) {
				product['details'].push({
					'offer': this['price'],
					'offer_quantity': this['quantity']
				});
			} else {
				product['details'][product['details'].length - 1]['offer_quantity'] += this['quantity'];
			}
		});
		$.each(orders['bids'], function() {
			if(product['details'].length == 0) {
				product['details'].push({
					'bid': this['price'],
					'bid_quantity': this['quantity']
				});
				product['details'][product['details'].length - 1]['best'] = true;
			} else if('bid' in product['details'][product['details'].length - 1]) {
				if(product['details'][product['details'].length - 1]['bid'] != this['price']) {
					product['details'].push({
						'bid': this['price'],
						'bid_quantity': this['quantity']
					});
				} else {
					product['details'][product['details'].length - 1]['bid_quantity'] += this['quantity'];
				}
			} else {
				product['details'][product['details'].length - 1]['best'] = true;
				product['details'][product['details'].length - 1]['bid'] = this['price'];
				product['details'][product['details'].length - 1]['bid_quantity'] = this['quantity'];
			}
		});
	};
	window['Exchng'] = Exchng;
})();
<commit_msg>small improvement in code quality for sortOrders<commit_after>(function() {
	function Exchng(marketId, eventHandler) {
		this.marketId = marketId;
		this.eventHandler = eventHandler;
		this.products = {};
		this._fetching = false;
	}
	Exchng.prototype.fetchData = function() {
		this._fetching = true;
		var exchng = this;
		$.get('ts/market_snapshot', {
			'key': 'A8b04F3',
			'market_id': this.marketId,
			'_r': new Date().getTime()
		}, function(data, textStatus) {
			if(textStatus == 'success') {
				var snapshot = data['snapshot'];
				var market = snapshot['market'];
				var products = {};
				$.each(snapshot['products'], function() {
					products[this['id']] = {
						'id': this['id'],
						'symbol': this['symbol'],
						'orders': {
							'offers': [],
							'bids': []
						}
					};
				});
			    $.each(snapshot['orders'], function(i, order) {
				    var side = order['side'];
				    if (side == 'buy') {
					side = 'bid';
  				    }else if (side == 'sell') {
					side = 'offer';
				    }
					products[order['product_id']]['orders'][side + 's'].push({
						'id': order['id'],
						'price': order['price'],
						'quantity': order['quantity']
					});
				});
				exchng.products = {};
			    $.each(products, function(k, product) {
				exchng.products[k] = new Exchng.Product(product['id'], product['symbol'], product['orders']);
				});
				exchng.eventHandler({
					'name': 'fetch-complete'
				});
			}
			exchng._fetching = false;
		}, 'json');
	};
	Exchng.prototype.beginPoll = function(callback) {
	    var exchgn = this;
	    var poll = function () {
		if (!exchng._fetching) {
		    exchng._fetching = true;
		    $.ajax({
			//url: '/market_update.json?'+(new Date()).getTime(),
			url: 'ts/market_update',
			dataType: 'json',
			success: function(data) {
			    exchng._fetching = false;
			    callback(data);
			},
			error: function (error) {
			    exchng._fetching = false;
			    log("error polling", error.statusText);
			}
		    });
		}
	    }

	    setInterval(poll, 10000);
	};
    Exchng.prototype.removeOrder = function (target_id) {
	var exchng = this;
	// TODO this walk isn't the prettiest thing out there
	// might also turn out to be slow when the market is big
	// should probably maintain some sort of order_id hashmap
	$.each(exchng.products, function (i, product) {
	    $.each(product.orders, function (side, orders) {
		$.each(product.orders[side], function (i, order) {
		    if (order.id == target_id) {
			product.orders[side].splice(i, 1);
		    }
		});
	    });
	});
    };
	Exchng.Product = function(id, symbol, orders) {
		var product = this;
		this['id'] = id;
		this['symbol'] = symbol;
		this['orders'] = {
			'offers': orders['offers'].slice(0),
			'bids': orders['bids'].slice(0)
		};
		this.sortOrders();
	};
	Exchng.Product.prototype.addOrder = function(order) {
		var orders = this['orders'];
	        var side = order['side'];
	        if (side == 'buy') {
		    side = 'bid';
  	        }else if (side == 'sell') {
		    side = 'offer';
	        }

		orders[side + 's'].push({
						'id': order['id'],
						'price': order['price'],
						'quantity': order['quantity']
					});
	};
	Exchng.Product.prototype.sortOrders = function() {
		var orders = this['orders'];
		var product = this;
		orders['offers'].sort(function(a, b) {
			return a['price'] < b['price'];
		});
		orders['bids'].sort(function(a, b) {
			return a['price'] < b['price'];
		});
	    var details = [];
	    $.each(orders['offers'], function(i, offer) {
		if(details.length == 0 || details[details.length - 1]['offer'] != offer['price']) {
		    details.push({
			'offer': offer['price'],
			'offer_quantity': offer['quantity']
		    });
		} else {
		    details[details.length - 1]['offer_quantity'] += offer['quantity'];
		}
	    });
	    $.each(orders['bids'], function(i, bid) {
		if(details.length == 0) {
		    details.push({
			'bid': bid['price'],
			'bid_quantity': bid['quantity']
		    });
		    details[details.length - 1]['best'] = true;
		} else if('bid' in details[details.length - 1]) {
		    if(details[details.length - 1]['bid'] != bid['price']) {
			details.push({
			    'bid': bid['price'],
			    'bid_quantity': bid['quantity']
			});
		    } else {
			details[details.length - 1]['bid_quantity'] += this['quantity'];
		    }
		} else {
		    details[details.length - 1]['best'] = true;
		    details[details.length - 1]['bid'] = bid['price'];
		    details[details.length - 1]['bid_quantity'] = bid['quantity'];
		}
	    });

	    product.details = details;
	};
	window['Exchng'] = Exchng;
})();
<|endoftext|>


<commit_before>// ==UserScript==
// @name          Hacker News: New Comments
// @namespace     http://mschade.me/userscripts
// @description   Make new comments on Hacker News more noticeable. Created by Michael Schade (@michaelschade, http://mschade.me/)
// @match         http://news.ycombinator.com/item?id=*
// @include       http://news.ycombinator.com/item?id=*
// ==/UserScript==

// URL to jQuery Library
var jqURL = "http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js";

function main() {
    /* Add ability to compute difference between two arrays.

       Snippet via http://stackoverflow.com/q/4026828
     */
    Array.prototype.diff = function(a) {
        return this.filter(function(i) {return !(a.indexOf(i) > -1);});
    };

    /* Strips the prefix of query string to retrieve the intended id. */
    function getId(s) {
        return s.replace("item", "").replace("?id=", "");
    }

    /* Modifies a Hacker News comment header to mark it as a new comment. */
    function markComment(comment) {
        comment.css('background-color', 'yellow');
    }

    /* Processes the comments on page to determine which, if any, are new,
       marking the new comments accordingly.
     */
    function processComments() {
        var   post        = getId(window.location.search)
            , comments    = []
            , oldComments = []
            , comheads    = {}
            ;

        // Populate comments
        $(".comhead a:last-child").each(function(index) {
            var cid = getId($(this).attr('href'));
            comments.push(cid);
            comheads[cid] = $(this).parent();
        });

        // Try to retrieve existing set of comments for this page
        if (post in localStorage) {
            oldComments = JSON.parse(localStorage.getItem(post));

            // Determine new comments and mark them visually
            var newComments = comments.diff(oldComments);
            $.each(newComments, function(index, cid) {
                markComment(comheads[cid]);
            });

            /* If appropriate, update page to reflect number of new comments */
            // New comment notification text
            var ncomm = newComments.length ? newComments.length : "No";
            ncomm    += " new comment";
            if (newComments.length != 1) {
                ncomm+= 's';
            }

            // Update page
            var nspot = $("center > table > tbody > tr > td > br:first");
            var ntext = '
'
                      + '
' + ncomm + '

'
                      ;
            nspot.replaceWith(ntext);
        }

        // Save to browser storage
        localStorage.setItem(post, JSON.stringify(comments));
    }

    function processPosts() {
    }

    processComments();
}

/* Injects jQuery into the page and makes useable from the below Greasemonkey
   script.

   Snippet via
   http://erikvold.com/blog/index.cfm/2010/6/14/using-jquery-with-a-user-script
 */
function addJQuery(callback) {
    var script = document.createElement("script");
    script.setAttribute("src", jqURL);
    script.addEventListener('load', function() {
            var script = document.createElement("script");
            script.textContent = "(" + callback.toString() + ")();";
            document.body.appendChild(script);
            }, false);
    document.body.appendChild(script);
}

addJQuery(main);
<commit_msg>Remove markComment function, inline code.<commit_after>// ==UserScript==
// @name          Hacker News: New Comments
// @namespace     http://mschade.me/userscripts
// @description   Make new comments on Hacker News more noticeable. Created by Michael Schade (@michaelschade, http://mschade.me/)
// @match         http://news.ycombinator.com/item?id=*
// @include       http://news.ycombinator.com/item?id=*
// ==/UserScript==

// URL to jQuery Library
var jqURL = "http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js";

function main() {
    /* Add ability to compute difference between two arrays.

       Snippet via http://stackoverflow.com/q/4026828
     */
    Array.prototype.diff = function(a) {
        return this.filter(function(i) {return !(a.indexOf(i) > -1);});
    };

    /* Strips the prefix of query string to retrieve the intended id. */
    function getId(s) {
        return s.replace("item", "").replace("?id=", "");
    }

    /* Processes the comments on page to determine which, if any, are new,
       marking the new comments accordingly.
     */
    function processComments() {
        var   post        = getId(window.location.search)
            , comments    = []
            , oldComments = []
            , comheads    = {}
            ;

        // Populate comments
        $(".comhead a:last-child").each(function(index) {
            var cid = getId($(this).attr('href'));
            comments.push(cid);
            comheads[cid] = $(this).parent();
        });

        // Try to retrieve existing set of comments for this page
        if (post in localStorage) {
            oldComments = JSON.parse(localStorage.getItem(post));

            // Determine new comments and mark them visually
            var newComments = comments.diff(oldComments);
            $.each(newComments, function(index, cid) {
                comheads[cid].css('background-color', 'yellow');
            });

            /* If appropriate, update page to reflect number of new comments */
            // New comment notification text
            var ncomm = newComments.length ? newComments.length : "No";
            ncomm    += " new comment";
            if (newComments.length != 1) {
                ncomm+= 's';
            }

            // Update page
            var nspot = $("center > table > tbody > tr > td > br:first");
            var ntext = '
'
                      + '
' + ncomm + '

'
                      ;
            nspot.replaceWith(ntext);
        }

        // Save to browser storage
        localStorage.setItem(post, JSON.stringify(comments));
    }

    function processPosts() {
    }

    processComments();
}

/* Injects jQuery into the page and makes useable from the below Greasemonkey
   script.

   Snippet via
   http://erikvold.com/blog/index.cfm/2010/6/14/using-jquery-with-a-user-script
 */
function addJQuery(callback) {
    var script = document.createElement("script");
    script.setAttribute("src", jqURL);
    script.addEventListener('load', function() {
            var script = document.createElement("script");
            script.textContent = "(" + callback.toString() + ")();";
            document.body.appendChild(script);
            }, false);
    document.body.appendChild(script);
}

addJQuery(main);
<|endoftext|>


<commit_before>var filterFcns = {};

/* Filter Function entry object type:
{
  function fcn;
  {} filters;
  int elemIndex
  int elemCount
}
*/

// TODO Fix Filter-Elem id's to be classes -- currently only unique within column

function printClasses (classes) {
  var classesContent = "";
  if (_.values(filterFcns).length > 0) {
    for (var i = 0; i < classes.length; i ++) {
      if (classes[i].present) {
        classesContent += "" +
        "" + classes[i].subject + " " + classes[i].code + ": " + classes[i].title  + "
" +
        "" + classes[i].description + "
" + "";
        if (classes[i].minUnits === classes[i].maxUnits)
          classesContent += classes[i].minUnits;
        else
          classesContent += classes[i].minUnits + "-" + classes[i].maxUnits;
        classesContent += " Units | " + classes[i].termsOffered.join(', ') + "
";
        classesContent += "
";
      }
    }
  }
  $("#filteredClasses").empty().html(classesContent);
  hideLoader();
};

function printCurrentQuery () {
  var currentQuery = 'Currently querying for ';
  var queries = [];
  for (fcn in filterFcns) {
    var filters = _.values(filterFcns[fcn].filters);
    if (filters.length > 0)
      queries.push(filterFcns[fcn].type + _.values(filterFcns[fcn].filters).join(' or '));
  }

  if (queries.length > 0)
    currentQuery += 'classes ' + queries.join(' and ') + '.';
  else
    currentQuery += 'nothing. Click here for a sample query.';

  $("#currentQuery").html(currentQuery);
};

/* Create a new copy of the classes list and apply every filter to it. */
function filterClasses () {
  showLoader();
  for (var i = 0; i < classes.length; i++)
    classes[i].present = true;
  for (x in filterFcns) {
    filterFcns[x].fcn(classes, filterFcns[x].filters);
  }
  printClasses(classes);
  printCurrentQuery();
}

function showLoader() {
  $('#filteredClasses').hide();
  $('#loader').show();
}

function hideLoader() {
  $('#loader').hide();
  $('#filteredClasses').show();
}

function buildKeywordFilter (id) {
  filterFcns[id] = {
    fcn: function (classes, filters) {
      var regex = new RegExp(arrayFromObject(filters).join("|"), "i");
      for (var i = 0; i < classes.length; i ++) {
        var matched = false;
        if (regex.test(_.values(classes[i]).join('')) || regex.test(_.values(classes[i]).join(' ')))
          matched = true;
        if (!matched) {
          classes[i].present = false;
        }
      }
    },
    filters: {},
    type: 'using the keyword ',
    elemIndex: 0
  };
}

function buildSubjectFilter(id) {
  filterFcns[id] = {
    fcn: function (classes, filters) {
      var regex = new RegExp("^(" + arrayFromObject(filters).join("|") + ")$");
      for (var i = 0; i < classes.length; i ++) {
        if (!regex.test(classes[i].subject)) {
          classes[i].present = false;
        }
      }
    },
    filters: {},
    type: 'where the subject is ',
    elemIndex: 0
  };
}

function buildGERFilter(id) {
  filterFcns[id] = {
    fcn: function (classes, filters) {
      var regex = new RegExp("(GER:)?(" + arrayFromObject(filters).map(function(elem)
        {
          return elem.replace(":", "");
        }).join("|") + ")");
      for (var i = 0; i < classes.length; i ++) {
        var matched = false;
        for (var x = 0; x < classes[i]['gers'].length; x++) {
          if (regex.test(classes[i]['gers'][x])) {
            matched = true;
            break;
          }
        }
        if (!matched) {
          classes[i].present = false;
        }
      }
    },
    filters: {},
    type: 'which satisfy the ger ',
    elemIndex: 0
  };
}

function buildUnitsFilter (id) {
  filterFcns[id] = {
    fcn: function(classes, filters) {
      for (var i = 0; i < classes.length; ++i) {
        var matched = false;
        for (var x in filters) {
          if ((filters[x] == '>5' && classes[i].maxUnits > 5) || (classes[i].maxUnits >= filters[x] && classes[i].minUnits <= filters[x]))
            matched = true;
            break;
        }
        if (!matched)
          classes[i].present = false;
      }
    },
    filters: {},
    type: 'which have a unit count of ',
    elemIndex: 0
  };
};

function buildTermFilter (id) {
  filterFcns[id] = {
    fcn: function(classes, filters) {
      for (var i = 0; i < classes.length; ++i) {
        var matched = false;
        for (var x in filters) {
          if (classes[i].termsOffered.indexOf(filters[x]) > -1) {
            matched = true;
            break;
          }
        }
        if (!matched)
          classes[i].present = false;
      }
    },
    filters: {},
    type: 'where the term is ',
    elemIndex: 0
  };
};

function buildSubjectSelector (index) {
  var toReturn =
    '
\
      <button class="close" onClick="onElemRemoved(this);">×</button>\
      Subject:
\
      <select onChange="onElemValueChanged(this)" class="selector">\
        <option value=""></option>\
      </select>\

\

\
    Add OR Filter
';
  return toReturn;
}

function buildGERSelector (index) {
  var toReturn =
    '
\
      <button class="close" onClick="onElemRemoved(this);">×</button>\
      GER:
\
      <select onChange="onElemValueChanged(this)" class="selector">\
        <option value=""></option>\
      </select>\

\

\
    Add OR Filter
';
  return toReturn;
}

function buildKeywordInput (index) {
  var toReturn =
    '
\
      <button class="close" onClick="onElemRemoved(this);">×</button>\
      Keyword:
\
      <input onFocusOut="onElemValueChanged(this);"></input>
\
      <button style="float:right;">Search</button>\

\

\
    Add OR Filter
';
  return toReturn;
}

function buildUnitsSelector(index) {
  var toReturn =
    '
\
      <button class="close" onClick="onElemRemoved(this);">×</button>\
      Units:
\
      <select onChange="onElemValueChanged(this)" class="selector">\
        <option value=""></option>\
      </select>\

\

\
    Add OR Filter
';
  return toReturn;
}

function buildTermSelector(index) {
  var toReturn =
    '
\
      <button class="close" onClick="onElemRemoved(this);">×</button>\
      Term:
\
      <select onChange="onElemValueChanged(this)" class="selector">\
        <option value=""></option>\
      </select>\

\

\
    Add OR Filter
';
  return toReturn;
}

function buildOrElem (elem, elemBuilder) {
  var parent = $(elem).parent();
  var id = parent.attr('id');
  var index = filterFcns[id].elemIndex ++;
  filterFcns[id].elemCount ++;
  $("#" + id).append(elemBuilder(index));
  elem.remove();
  return {"id": id, "index": index};
}

function buildOrSelector (elem, builder, arr) {
  var newElem = buildOrElem(elem, builder);
  populateSelectorDropdown(newElem.id, newElem.index, arr);
}

var filterSelectorBuilders = {
  subject: function () {
    var id = buildFilterElem(buildSubjectFilter, buildSubjectSelector);
    populateSelectorDropdown(id, 0, subjectCodes);
    return id;
  },
  keyword: function () {
    buildFilterElem(buildKeywordFilter, buildKeywordInput);
    return id;
  },
  gers: function () {
    var id = buildFilterElem(buildGERFilter, buildGERSelector);
    populateSelectorDropdown(id, 0, gers);
    return id;
  },
  units: function() {
    var id = buildFilterElem(buildUnitsFilter, buildUnitsSelector);
    populateSelectorDropdown(id, 0, units);
    return id;
  },
  term: function() {
    var id = buildFilterElem(buildTermFilter, buildTermSelector);
    populateSelectorDropdown(id, 0, terms);
    return id;
  }
};

function buildFilterElem (buildFilterFcn, buildFilterElemFcn) {
  var id = (new Date()).getTime();
    buildFilterFcn(id);
    var index = filterFcns[id].elemIndex ++;
    $("#filters").append(
      '
\
        ' + buildFilterElemFcn(index) + '\

');
    filterFcns[id].elemCount = 1;
    recalculateWidth();
    return id;
}

function onElemValueChanged (elem) {
  var id = $(elem).parent().parent().attr('id');
  var index = $(elem).parent().attr('id');
  filterFcns[id].filters[index] = $(elem).val();
  filterClasses();
}

function onElemRemoved (elem) {
  var id = $(elem).parent().parent().attr('id');
  var index = $(elem).parent().attr('id');
  delete filterFcns[id].filters[index];
  if (--filterFcns[id].elemCount == 0) {
    $(elem).parent().parent().remove();
    delete filterFcns[id];
    recalculateWidth();
  }
  else {
    $(elem).parent().next().remove();
    $(elem).parent().remove();
  }
  filterClasses();
}

function populateSelectorDropdown (id, index, arr) {
  var elem = $("#" + id).children("#" + index).children(".selector");
  for (var i = 0; i < arr.length; i ++) {
    elem.append("<option value='" + arr[i] + "'>" + arr[i] + "</option>");
  }
}

/* Recalculates width of the filters block. This should never wrap, even if it forces scrolling. */
function recalculateWidth () {
  var width = 0;
  $("#filters").children().each(function() {
    width += $(this).outerWidth(true);
  });
//  if (width > 940)
    $("#container").width(width);
}

/* Helper function that creates an array with the values in the object. */
function arrayFromObject (obj) {
  var i = 0;
  var toReturn = [];
  for (x in obj)
    toReturn[i++] = obj[x];
  return toReturn;
}

function sampleQuery () {
  var gerElemId = filterSelectorBuilders['gers']();
  $("#" + gerElemId + " select").val('DB-Hum').change();
  var ecElemId = filterSelectorBuilders['gers']();
  $("#" + ecElemId + " select").val('EC-Gender').change();
  $("#" + ecElemId + " .filter-elem").click();
  $("#" + ecElemId + " #1 select").val('EC-AmerCul').change();
  $("#" + ecElemId + " .filter-elem").click();
  $("#" + ecElemId + " #2 select").val('EC-EthicReas').change();
  var termElemId = filterSelectorBuilders['term']();
  $("#" + termElemId + " select").val('Spring').change();
}
<commit_msg>Shows GERs now<commit_after>var filterFcns = {};

/* Filter Function entry object type:
{
  function fcn;
  {} filters;
  int elemIndex
  int elemCount
}
*/

// TODO Fix Filter-Elem id's to be classes -- currently only unique within column

function printClasses (classes) {
  var classesContent = "";
  if (_.values(filterFcns).length > 0) {
    for (var i = 0; i < classes.length; i ++) {
      if (classes[i].present) {
        classesContent += "" +
        "" + classes[i].subject + " " + classes[i].code + ": " + classes[i].title  + "
" +
        "" + classes[i].description + "
" + "";
        if (classes[i].minUnits === classes[i].maxUnits)
          classesContent += classes[i].minUnits;
        else
          classesContent += classes[i].minUnits + "-" + classes[i].maxUnits;
        classesContent += " Units | " + classes[i].termsOffered.join(', ');
        if (classes[i]['gers'].join().length > 0) // This is a hack b/c gers never has length 0 for some reason which I'm currently too lazy to investigate
          classesContent += " | " + classes[i]['gers'].join (', ');
        classesContent += "
";
        classesContent += "
";
      }
    }
  }
  $("#filteredClasses").empty().html(classesContent);
  hideLoader();
};

function printCurrentQuery () {
  var currentQuery = 'Currently querying for ';
  var queries = [];
  for (fcn in filterFcns) {
    var filters = _.values(filterFcns[fcn].filters);
    if (filters.length > 0)
      queries.push(filterFcns[fcn].type + _.values(filterFcns[fcn].filters).join(' or '));
  }

  if (queries.length > 0)
    currentQuery += 'classes ' + queries.join(' and ') + '.';
  else
    currentQuery += 'nothing. Click here for a sample query.';

  $("#currentQuery").html(currentQuery);
};

/* Create a new copy of the classes list and apply every filter to it. */
function filterClasses () {
  showLoader();
  for (var i = 0; i < classes.length; i++)
    classes[i].present = true;
  for (x in filterFcns) {
    filterFcns[x].fcn(classes, filterFcns[x].filters);
  }
  printClasses(classes);
  printCurrentQuery();
}

function showLoader() {
  $('#filteredClasses').hide();
  $('#loader').show();
}

function hideLoader() {
  $('#loader').hide();
  $('#filteredClasses').show();
}

function buildKeywordFilter (id) {
  filterFcns[id] = {
    fcn: function (classes, filters) {
      var regex = new RegExp(arrayFromObject(filters).join("|"), "i");
      for (var i = 0; i < classes.length; i ++) {
        var matched = false;
        if (regex.test(_.values(classes[i]).join('')) || regex.test(_.values(classes[i]).join(' ')))
          matched = true;
        if (!matched) {
          classes[i].present = false;
        }
      }
    },
    filters: {},
    type: 'using the keyword ',
    elemIndex: 0
  };
}

function buildSubjectFilter(id) {
  filterFcns[id] = {
    fcn: function (classes, filters) {
      var regex = new RegExp("^(" + arrayFromObject(filters).join("|") + ")$");
      for (var i = 0; i < classes.length; i ++) {
        if (!regex.test(classes[i].subject)) {
          classes[i].present = false;
        }
      }
    },
    filters: {},
    type: 'where the subject is ',
    elemIndex: 0
  };
}

function buildGERFilter(id) {
  filterFcns[id] = {
    fcn: function (classes, filters) {
      var regex = new RegExp("(GER:)?(" + arrayFromObject(filters).map(function(elem)
        {
          return elem.replace(":", "");
        }).join("|") + ")");
      for (var i = 0; i < classes.length; i ++) {
        var matched = false;
        for (var x = 0; x < classes[i]['gers'].length; x++) {
          if (regex.test(classes[i]['gers'][x])) {
            matched = true;
            break;
          }
        }
        if (!matched) {
          classes[i].present = false;
        }
      }
    },
    filters: {},
    type: 'which satisfy the ger ',
    elemIndex: 0
  };
}

function buildUnitsFilter (id) {
  filterFcns[id] = {
    fcn: function(classes, filters) {
      for (var i = 0; i < classes.length; ++i) {
        var matched = false;
        for (var x in filters) {
          if ((filters[x] == '>5' && classes[i].maxUnits > 5) || (classes[i].maxUnits >= filters[x] && classes[i].minUnits <= filters[x]))
            matched = true;
            break;
        }
        if (!matched)
          classes[i].present = false;
      }
    },
    filters: {},
    type: 'which have a unit count of ',
    elemIndex: 0
  };
};

function buildTermFilter (id) {
  filterFcns[id] = {
    fcn: function(classes, filters) {
      for (var i = 0; i < classes.length; ++i) {
        var matched = false;
        for (var x in filters) {
          if (classes[i].termsOffered.indexOf(filters[x]) > -1) {
            matched = true;
            break;
          }
        }
        if (!matched)
          classes[i].present = false;
      }
    },
    filters: {},
    type: 'where the term is ',
    elemIndex: 0
  };
};

function buildSubjectSelector (index) {
  var toReturn =
    '
\
      <button class="close" onClick="onElemRemoved(this);">×</button>\
      Subject:
\
      <select onChange="onElemValueChanged(this)" class="selector">\
        <option value=""></option>\
      </select>\

\

\
    Add OR Filter
';
  return toReturn;
}

function buildGERSelector (index) {
  var toReturn =
    '
\
      <button class="close" onClick="onElemRemoved(this);">×</button>\
      GER:
\
      <select onChange="onElemValueChanged(this)" class="selector">\
        <option value=""></option>\
      </select>\

\

\
    Add OR Filter
';
  return toReturn;
}

function buildKeywordInput (index) {
  var toReturn =
    '
\
      <button class="close" onClick="onElemRemoved(this);">×</button>\
      Keyword:
\
      <input onFocusOut="onElemValueChanged(this);"></input>
\
      <button style="float:right;">Search</button>\

\

\
    Add OR Filter
';
  return toReturn;
}

function buildUnitsSelector(index) {
  var toReturn =
    '
\
      <button class="close" onClick="onElemRemoved(this);">×</button>\
      Units:
\
      <select onChange="onElemValueChanged(this)" class="selector">\
        <option value=""></option>\
      </select>\

\

\
    Add OR Filter
';
  return toReturn;
}

function buildTermSelector(index) {
  var toReturn =
    '
\
      <button class="close" onClick="onElemRemoved(this);">×</button>\
      Term:
\
      <select onChange="onElemValueChanged(this)" class="selector">\
        <option value=""></option>\
      </select>\

\

\
    Add OR Filter
';
  return toReturn;
}

function buildOrElem (elem, elemBuilder) {
  var parent = $(elem).parent();
  var id = parent.attr('id');
  var index = filterFcns[id].elemIndex ++;
  filterFcns[id].elemCount ++;
  $("#" + id).append(elemBuilder(index));
  elem.remove();
  return {"id": id, "index": index};
}

function buildOrSelector (elem, builder, arr) {
  var newElem = buildOrElem(elem, builder);
  populateSelectorDropdown(newElem.id, newElem.index, arr);
}

var filterSelectorBuilders = {
  subject: function () {
    var id = buildFilterElem(buildSubjectFilter, buildSubjectSelector);
    populateSelectorDropdown(id, 0, subjectCodes);
    return id;
  },
  keyword: function () {
    buildFilterElem(buildKeywordFilter, buildKeywordInput);
    return id;
  },
  gers: function () {
    var id = buildFilterElem(buildGERFilter, buildGERSelector);
    populateSelectorDropdown(id, 0, gers);
    return id;
  },
  units: function() {
    var id = buildFilterElem(buildUnitsFilter, buildUnitsSelector);
    populateSelectorDropdown(id, 0, units);
    return id;
  },
  term: function() {
    var id = buildFilterElem(buildTermFilter, buildTermSelector);
    populateSelectorDropdown(id, 0, terms);
    return id;
  }
};

function buildFilterElem (buildFilterFcn, buildFilterElemFcn) {
  var id = (new Date()).getTime();
    buildFilterFcn(id);
    var index = filterFcns[id].elemIndex ++;
    $("#filters").append(
      '
\
        ' + buildFilterElemFcn(index) + '\

');
    filterFcns[id].elemCount = 1;
    recalculateWidth();
    return id;
}

function onElemValueChanged (elem) {
  var id = $(elem).parent().parent().attr('id');
  var index = $(elem).parent().attr('id');
  filterFcns[id].filters[index] = $(elem).val();
  filterClasses();
}

function onElemRemoved (elem) {
  var id = $(elem).parent().parent().attr('id');
  var index = $(elem).parent().attr('id');
  delete filterFcns[id].filters[index];
  if (--filterFcns[id].elemCount == 0) {
    $(elem).parent().parent().remove();
    delete filterFcns[id];
    recalculateWidth();
  }
  else {
    $(elem).parent().next().remove();
    $(elem).parent().remove();
  }
  filterClasses();
}

function populateSelectorDropdown (id, index, arr) {
  var elem = $("#" + id).children("#" + index).children(".selector");
  for (var i = 0; i < arr.length; i ++) {
    elem.append("<option value='" + arr[i] + "'>" + arr[i] + "</option>");
  }
}

/* Recalculates width of the filters block. This should never wrap, even if it forces scrolling. */
function recalculateWidth () {
  var width = 0;
  $("#filters").children().each(function() {
    width += $(this).outerWidth(true);
  });
//  if (width > 940)
    $("#container").width(width);
}

/* Helper function that creates an array with the values in the object. */
function arrayFromObject (obj) {
  var i = 0;
  var toReturn = [];
  for (x in obj)
    toReturn[i++] = obj[x];
  return toReturn;
}

function sampleQuery () {
  var gerElemId = filterSelectorBuilders['gers']();
  $("#" + gerElemId + " select").val('DB-Hum').change();
  var ecElemId = filterSelectorBuilders['gers']();
  $("#" + ecElemId + " select").val('EC-Gender').change();
  $("#" + ecElemId + " .filter-elem").click();
  $("#" + ecElemId + " #1 select").val('EC-AmerCul').change();
  $("#" + ecElemId + " .filter-elem").click();
  $("#" + ecElemId + " #2 select").val('EC-EthicReas').change();
  var termElemId = filterSelectorBuilders['term']();
  $("#" + termElemId + " select").val('Spring').change();
}
<|endoftext|>


<commit_before>var HyperdeckCore = require("./hyperdeck-core.js");
var Promise = require('promise');

var Hyperdeck = function(ip) {
  //Start by connecting to Hyperdeck via HypderdeckCore
  var Core = new HyperdeckCore(ip);

  //Publicise functions from Core
  this.getNotifier = Core.getNotifier();
  this.makeRequest = Core.makeRequest();
  this.onConnected = Core.onConnected();

  //make Easy Access commands
  this.play = function(speed) {
    var commandString;
    if (!speed) {
      commandString = "play";
    } else {
      commandString = "play speed: " + speed.toString();
    }
    return new Promise(function(fulfill, reject) {
      Core.makeRequest(commandString).then(function(response) {
        fulfill(response);
      }).catch(function(errResponse) {
        reject(errResponse.code);
      });
    });
  };
  this.stop = function() {
    return new Promise(function(fulfill, reject) {
      Core.makeRequest("stop").then(function(response) {
        fulfill(response);
      }).catch(function(errResponse) {
        reject(errResponse.code);
      });
    });
  };

  this.record = function() {
    return new Promise(function(fulfill, reject) {
      Core.makeRequest("record").then(function(response) {
        fulfill(response);
      }).catch(function(errResponse) {
        reject(errResponse.code);
      });
    });
  };

};

module.exports = Hyperdeck;
<commit_msg>Fix requirements on play speed<commit_after>var HyperdeckCore = require("./hyperdeck-core.js");
var Promise = require('promise');

var Hyperdeck = function(ip) {
  //Start by connecting to Hyperdeck via HypderdeckCore
  var Core = new HyperdeckCore(ip);

  //Publicise functions from Core
  this.getNotifier = Core.getNotifier();
  this.makeRequest = Core.makeRequest();
  this.onConnected = Core.onConnected();

  //make Easy Access commands
  this.play = function(speed) {
    var commandString;
    if (speed<=1600 || speed >= -1600) {
      commandString = "play";
    } else {
      commandString = "play speed: " + speed;
    }
    return new Promise(function(fulfill, reject) {
      Core.makeRequest(commandString).then(function(response) {
        fulfill(response);
      }).catch(function(errResponse) {
        reject(errResponse.code);
      });
    });
  };
  this.stop = function() {
    return new Promise(function(fulfill, reject) {
      Core.makeRequest("stop").then(function(response) {
        fulfill(response);
      }).catch(function(errResponse) {
        reject(errResponse.code);
      });
    });
  };

  this.record = function() {
    return new Promise(function(fulfill, reject) {
      Core.makeRequest("record").then(function(response) {
        fulfill(response);
      }).catch(function(errResponse) {
        reject(errResponse.code);
      });
    });
  };

};

module.exports = Hyperdeck;
<|endoftext|>


<commit_before>'use strict'

import Request from 'superagent/lib/client'
import { pushPath } from 'redux-simple-router'

import * as authActions from '../constants'

/**
 * This function performs  the login
 *
 * @param data Must be an object of the following form:
 * { username: <username>, password: <password>, callback_url:<callback_url> }
 * the callback_url property is optional
 */
export default function login (data) {
  return (dispatch) => {
    dispatch({type: authActions.LOGIN_REQUEST})

    // @hack for now
    data.appkey = 'concorda'

    Request
      .post('/api/v1/auth/login')
      .type('json')
      .send(data)
      .end((err, resp) => {

        var unauthorized = false
        var niceError = 'Wrong username or password'
        if (err || resp.unauthorized) {
          unauthorized = true
        }

        if (resp.body && resp.body.ok === false){
          unauthorized = true
          if (resp.body.why){
            niceError = resp.body.why
          }

          if (resp.body.code === 2){
            dispatch(pushPath('/changePassword'))
            return
          }
        }

        if (unauthorized){
          return dispatch({
            type: authActions.LOGIN_RESPONSE,
            niceError: niceError,
            hasError: true,
            isLoggedIn: false
          })
        }
        window.localStorage.setItem('isLoggedIn', true)

        dispatch({
          type: authActions.LOGIN_RESPONSE,
          isLoggedIn: true,
          hasError: false
        })

        dispatch(pushPath('/'))
      })
  }
}
<commit_msg>changed redirect url for reset password<commit_after>'use strict'

import Request from 'superagent/lib/client'
import { pushPath } from 'redux-simple-router'

import * as authActions from '../constants'

/**
 * This function performs  the login
 *
 * @param data Must be an object of the following form:
 * { username: <username>, password: <password>, callback_url:<callback_url> }
 * the callback_url property is optional
 */
export default function login (data) {
  return (dispatch) => {
    dispatch({type: authActions.LOGIN_REQUEST})

    // @hack for now
    data.appkey = 'concorda'

    Request
      .post('/api/v1/auth/login')
      .type('json')
      .send(data)
      .end((err, resp) => {

        var unauthorized = false
        var niceError = 'Wrong username or password'
        if (err || resp.unauthorized) {
          unauthorized = true
        }
        if (resp.body && resp.body.ok === false){
          unauthorized = true
          if (resp.body.why){
            niceError = resp.body.why
          }

          if (resp.body.code === 2){
            dispatch(pushPath('/password_reset/' + (resp.body.token || 'none')))
            return
          }
        }

        if (unauthorized){
          return dispatch({
            type: authActions.LOGIN_RESPONSE,
            niceError: niceError,
            hasError: true,
            isLoggedIn: false
          })
        }
        window.localStorage.setItem('isLoggedIn', true)

        dispatch({
          type: authActions.LOGIN_RESPONSE,
          isLoggedIn: true,
          hasError: false
        })

        dispatch(pushPath('/'))
      })
  }
}
<|endoftext|>


<commit_before>jQuery(function($){

// helper functions
//
var twoDArrayGenerate = function(width, height, isBolean){
  var result = [];
  for(var i = 0; i < height; i++){
    result[i] = [];
    for(var j = 0; j < width ; j++){
      result[i][j] = (isBolean ? false : 0);
    };
  };
  return result;
}
var modulus = function(i, j){
  return (((i%j)+j)%j);
}
var f = Math.floor;

// initial vars
//
var $pool = $('#pool');
var $play = $('#play');
var $next = $('#next');

var viewportWidth = window.innerWidth;
var viewportHeight = window.innerHeight;
var unitSide = 30; // same as (#pool td{width} + #pool td{border-width}) on stijl.css
var panelHeight = 70; // same as #panel{height} on stijl.css
var poolCols = f(viewportWidth / unitSide);
var poolRows = f((viewportHeight - panelHeight) / unitSide);
var isClicking = false;
var flow;

var trStart = '
';
var trEnd = '
';
var td = '	';
var tdLife = '	';

var currentGen = twoDArrayGenerate(poolCols, poolRows, true);
var nextGen = twoDArrayGenerate(nextGen, poolCols, poolRows, true);

// calculating next generation
//
var nextGenCalc = function(array){

  var prevGen = array;
  var minefield = twoDArrayGenerate(poolCols, poolRows, false);

  // calculating influence of each cell towards its neighbours
  //
  for(var i = 0; i < prevGen.length; i++){
    for(var j = 0; j < prevGen[i].length; j++){
      if(prevGen[i][j]){
        for(var n = f(i)-1; n <= f(i)+1; n++){
          for(var m = f(j)-1; m <= f(j)+1; m++){
            var na = modulus(n, poolRows);
            var ma = modulus(m, poolCols);
            minefield[na][ma] += 1;
          }
        }
        minefield[i][j] -= 1;
      }
    }
  }

  // http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life#Rules
  // applying CGF rules, mapping influence to an array that holds the future generation
  //
  for(var i = 0; i <  minefield.length; i++){
    for(var j = 0; j < minefield[i].length; j++){
      if(minefield[i][j] <= 1){
        nextGen[i][j] = false;
      }
      if(minefield[i][j] === 2){
        if(prevGen[i][j]){
          nextGen[i][j] = true;
        } else {
          nextGen[i][j] = false;
        }
      }
      if(minefield[i][j] === 3){
        nextGen[i][j] = true;
      }
      if(minefield[i][j] >= 4){
        nextGen[i][j] = false;
      }
    }
  }

  return nextGen;
}

// rendering html of a generation and injecting
//
var render = function(gen){
  var newPool = '';

  for(var i = 0; i < gen.length; i++){
    newPool += trStart;
    for(var j = 0; j < gen[i].length; j++){
      if(gen[i][j]){
        newPool += tdLife;
      } else {
        newPool += td;
      }
    }
    newPool += trEnd;
  }

  $('#pool').empty().append(newPool);
}

// execution and rendering of a step
//
var advanceGen = function(){
  var nextGen = nextGenCalc(currentGen);
  render(nextGen);
  currentGen = nextGen;
}

// first rendering of empty board
//
render(currentGen);

// user drawing and recording states
//
var lifeOrDeath = function(elementum, eventum){
  var xPos = eventum.currentTarget.cellIndex;
  var yPos = eventum.currentTarget.parentElement.rowIndex;
  var life = currentGen[yPos][xPos];

  if(!life){
    elementum.addClass('life');
    currentGen[yPos][xPos] = true;
  } else {
    elementum.removeClass('life');
    currentGen[yPos][xPos] = false;
  }
}

$pool.on('mousedown', 'td', function(i){
  isClicking = true;
  var I = $(this);
  lifeOrDeath(I, i);
});

$pool.on('mouseup', 'td', function(i){
  isClicking = false;
});

$pool.on('mouseenter', 'td', function(i){
  var I = $(this);
  if(isClicking){
    lifeOrDeath(I, i);
  }
});

// triggering calculation
//
$next.on('click', function(i){
  i.preventDefault();
  advanceGen();
})

$play.toggle(
  function(i){
    i.preventDefault();
    $play.text('pause');
    $next.attr('disabled', 'disabled')
    flow = setInterval(advanceGen, 50)
  },
  function(i){
    i.preventDefault();
    $play.text('play');
    $next.removeAttr('disabled')
    clearInterval(flow)
  }
)

});
<commit_msg>Remove most of jQuery use<commit_after>document.addEventListener("DOMContentLoaded", function(docEvent) {

// helper functions
//
var twoDArrayGenerate = function(width, height, isBolean){
  var result = [];
  for(var i = 0; i < height; i++){
    result[i] = [];
    for(var j = 0; j < width ; j++){
      result[i][j] = (isBolean ? false : 0);
    };
  };
  return result;
}
var modulus = function(i, j){
  return (((i%j)+j)%j);
}
var f = Math.floor;

// initial vars
//
var $pool = document.getElementById('pool');
var $play = document.getElementById('play');
var $next = document.getElementById('next');

var viewportWidth = window.innerWidth;
var viewportHeight = window.innerHeight;
var unitSide = 30; // same as (#pool td{width} + #pool td{border-width}) on stijl.css
var panelHeight = 70; // same as #panel{height} on stijl.css
var poolCols = f(viewportWidth / unitSide);
var poolRows = f((viewportHeight - panelHeight) / unitSide);
var isClicking = false;
var isPlaying = false;
var flow;

var trStart = '
';
var trEnd = '
';
var td = '	';
var tdLife = '	';

var currentGen = twoDArrayGenerate(poolCols, poolRows, true);
var nextGen = twoDArrayGenerate(nextGen, poolCols, poolRows, true);

// calculating next generation
//
var nextGenCalc = function(array){

  var prevGen = array;
  var minefield = twoDArrayGenerate(poolCols, poolRows, false);

  // calculating influence of each cell towards its neighbours
  //
  for(var i = 0; i < prevGen.length; i++){
    for(var j = 0; j < prevGen[i].length; j++){
      if(prevGen[i][j]){
        for(var n = f(i)-1; n <= f(i)+1; n++){
          for(var m = f(j)-1; m <= f(j)+1; m++){
            var na = modulus(n, poolRows);
            var ma = modulus(m, poolCols);
            minefield[na][ma] += 1;
          }
        }
        minefield[i][j] -= 1;
      }
    }
  }

  // http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life#Rules
  // applying CGF rules, mapping influence to an array that holds the future generation
  //
  for(var i = 0; i <  minefield.length; i++){
    for(var j = 0; j < minefield[i].length; j++){
      if(minefield[i][j] <= 1){
        nextGen[i][j] = false;
      }
      if(minefield[i][j] === 2){
        if(prevGen[i][j]){
          nextGen[i][j] = true;
        } else {
          nextGen[i][j] = false;
        }
      }
      if(minefield[i][j] === 3){
        nextGen[i][j] = true;
      }
      if(minefield[i][j] >= 4){
        nextGen[i][j] = false;
      }
    }
  }

  return nextGen;
}

// rendering html of a generation and injecting
//
var render = function(gen){
  var newPool = '';

  for(var i = 0; i < gen.length; i++){
    newPool += trStart;
    for(var j = 0; j < gen[i].length; j++){
      if(gen[i][j]){
        newPool += tdLife;
      } else {
        newPool += td;
      }
    }
    newPool += trEnd;
  }

  $('#pool').empty().append(newPool);
}

// execution and rendering of a step
//
var advanceGen = function(){
  var nextGen = nextGenCalc(currentGen);
  render(nextGen);
  currentGen = nextGen;
}

// first rendering of empty board
//
render(currentGen);

// user drawing and recording states
//
var lifeOrDeath = function(el){
  var xPos = el.cellIndex;
  var yPos = el.parentElement.rowIndex;
  var life = currentGen[yPos][xPos];

  if(!life){
    el.setAttribute('class', 'life');
    currentGen[yPos][xPos] = true;
  } else {
    el.removeAttribute('class');
    currentGen[yPos][xPos] = false;
  }
}

$pool.addEventListener('mousedown', function(e){
  if(e.target && e.target.nodeName == "TD"){
    isClicking = true;
    lifeOrDeath(e.target);
  }
});

$pool.addEventListener('mouseup', function(e){
  if(e.target && e.target.nodeName == "TD"){
    isClicking = false;
  }
});

$pool.addEventListener('mouseover', function(e){
  if(e.target && e.target.nodeName == "TD"){
    if(isClicking){
      lifeOrDeath(e.target);
    }
  }
});

// triggering calculation
//
$play.addEventListener('click', function(e){
  e.preventDefault();
  if(isPlaying){
    $play.textContent = 'play';
    $next.removeAttribute('disabled');
    clearInterval(flow)
    isPlaying = false;
  }
  else{
    $play.textContent = 'pause';
    $next.setAttribute('disabled', 'disabled');
    flow = setInterval(advanceGen, 50);
    isPlaying = true;
  }
});

$next.addEventListener('click', function(e){
  e.preventDefault();
  advanceGen();
});

}, false);
<|endoftext|>


<commit_before>$(function(){

var $injectee = $('#stories')
  , $structure = $('#structure')
  , $structureHtml = $structure.html()
  , jsonPath = 'http://api.ihackernews.com/page'
  , jsonPathMock = 'http://mcdlr.com/hacker-news-updated/jsonMock.json'

$.ajax({
  url : jsonPath,
  dataType : 'jsonp',
  data : {
    format : 'jsonp'
  },
  timeout: 1277,
  success : function(resp){
    templateAndInject(resp);
  },
  error : function(){
    inCaseOfEmergency();
  }
});

var inCaseOfEmergency = function(){
  $.ajax({
    url : jsonPathMock,
    dataType : 'json',
    success : function(resp){
      templateAndInject(resp);
    }
  });
}

var templateAndInject = function(content){
  var compiledContent = _.template($structureHtml, {story: content.items})
  $injectee.html(compiledContent);
}

});
<commit_msg>timeout increased for JSONP request<commit_after>$(function(){

var $injectee = $('#stories')
  , $structure = $('#structure')
  , $structureHtml = $structure.html()
  , jsonPath = 'http://api.ihackernews.com/page'
  , jsonPathMock = 'http://mcdlr.com/hacker-news-updated/jsonMock.json'

$.ajax({
  url : jsonPath,
  dataType : 'jsonp',
  data : {
    format : 'jsonp'
  },
  timeout: 4000,
  success : function(resp){
    templateAndInject(resp);
  },
  error : function(){
    inCaseOfEmergency();
  }
});

var inCaseOfEmergency = function(){
  $.ajax({
    url : jsonPathMock,
    dataType : 'json',
    success : function(resp){
      templateAndInject(resp);
    }
  });
}

var templateAndInject = function(content){
  var compiledContent = _.template($structureHtml, {story: content.items})
  $injectee.html(compiledContent);
}

});
<|endoftext|>


<commit_before>'use strict';

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

const Exchange = require ('./base/Exchange');
const { ExchangeError } = require ('./base/errors');

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

module.exports = class gemini extends Exchange {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'gemini',
            'name': 'Gemini',
            'countries': 'US',
            'rateLimit': 1500, // 200 for private API
            'version': 'v1',
            'has': {
                'fetchDepositAddress': false,
                'CORS': false,
                'fetchBidsAsks': false,
                'fetchTickers': false,
                'fetchMyTrades': true,
                'fetchOrder': false,
                'fetchOrders': false,
                'fetchOpenOrders': false,
                'fetchClosedOrders': false,
                'withdraw': true,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/27816857-ce7be644-6096-11e7-82d6-3c257263229c.jpg',
                'api': 'https://api.gemini.com',
                'www': 'https://gemini.com',
                'doc': [
                    'https://docs.gemini.com/rest-api',
                    'https://docs.sandbox.gemini.com',
                ],
                'test': 'https://api.sandbox.gemini.com',
                'fees': [
                    'https://gemini.com/fee-schedule/',
                    'https://gemini.com/transfer-fees/',
                ],
            },
            'api': {
                'public': {
                    'get': [
                        'symbols',
                        'pubticker/{symbol}',
                        'book/{symbol}',
                        'trades/{symbol}',
                        'auction/{symbol}',
                        'auction/{symbol}/history',
                    ],
                },
                'private': {
                    'post': [
                        'order/new',
                        'order/cancel',
                        'order/cancel/session',
                        'order/cancel/all',
                        'order/status',
                        'orders',
                        'mytrades',
                        'tradevolume',
                        'balances',
                        'deposit/{currency}/newAddress',
                        'withdraw/{currency}',
                        'heartbeat',
                    ],
                },
            },
            'fees': {
                'trading': {
                    'taker': 0.0025,
                },
            },
        });
    }

    async fetchMarkets () {
        let markets = await this.publicGetSymbols ();
        let result = [];
        for (let p = 0; p < markets.length; p++) {
            let id = markets[p];
            let market = id;
            let uppercase = market.toUpperCase ();
            let base = uppercase.slice (0, 3);
            let quote = uppercase.slice (3, 6);
            let symbol = base + '/' + quote;
            result.push ({
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'info': market,
            });
        }
        return result;
    }

    async fetchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let orderbook = await this.publicGetBookSymbol (this.extend ({
            'symbol': this.marketId (symbol),
        }, params));
        return this.parseOrderBook (orderbook, undefined, 'bids', 'asks', 'price', 'amount');
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let ticker = await this.publicGetPubtickerSymbol (this.extend ({
            'symbol': market['id'],
        }, params));
        let timestamp = ticker['volume']['timestamp'];
        let baseVolume = market['base'];
        let quoteVolume = market['quote'];
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': undefined,
            'low': undefined,
            'bid': parseFloat (ticker['bid']),
            'ask': parseFloat (ticker['ask']),
            'vwap': undefined,
            'open': undefined,
            'close': undefined,
            'first': undefined,
            'last': parseFloat (ticker['last']),
            'change': undefined,
            'percentage': undefined,
            'average': undefined,
            'baseVolume': parseFloat (ticker['volume'][baseVolume]),
            'quoteVolume': parseFloat (ticker['volume'][quoteVolume]),
            'info': ticker,
        };
    }

    parseTrade (trade, market) {
        let timestamp = trade['timestampms'];
        let order = undefined;
        if ('orderId' in trade)
            order = trade['orderId'].toString ();
        let fee = this.safeFloat (trade, 'fee_amount');
        if (typeof fee !== 'undefined') {
            let currency = this.safeString (trade, 'fee_currency');
            if (typeof currency !== 'undefined') {
                if (currency in this.currencies_by_id)
                    currency = this.currencies_by_id[currency]['code'];
                currency = this.commonCurrencyCode (currency);
            }
            fee = {
                'cost': parseFloat (trade['fee_amount']),
                'currency': currency,
            };
        }
        let price = parseFloat (trade['price']);
        let amount = parseFloat (trade['amount']);
        return {
            'id': trade['tid'].toString (),
            'order': order,
            'info': trade,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'type': undefined,
            'side': trade['type'],
            'price': price,
            'cost': price * amount,
            'amount': amount,
            'fee': fee,
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.publicGetTradesSymbol (this.extend ({
            'symbol': market['id'],
        }, params));
        return this.parseTrades (response, market, since, limit);
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        let balances = await this.privatePostBalances ();
        let result = { 'info': balances };
        for (let b = 0; b < balances.length; b++) {
            let balance = balances[b];
            let currency = balance['currency'];
            let account = {
                'free': parseFloat (balance['available']),
                'used': 0.0,
                'total': parseFloat (balance['amount']),
            };
            account['used'] = account['total'] - account['free'];
            result[currency] = account;
        }
        return this.parseBalance (result);
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets ();
        if (type === 'market')
            throw new ExchangeError (this.id + ' allows limit orders only');
        let nonce = this.nonce ();
        let order = {
            'client_order_id': nonce.toString (),
            'symbol': this.marketId (symbol),
            'amount': amount.toString (),
            'price': price.toString (),
            'side': side,
            'type': 'exchange limit', // gemini allows limit orders only
        };
        let response = await this.privatePostOrderNew (this.extend (order, params));
        return {
            'info': response,
            'id': response['order_id'],
        };
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        return await this.privatePostOrderCancel ({ 'order_id': id });
    }

    async fetchMyTrades (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        if (typeof symbol === 'undefined')
            throw new ExchangeError (this.id + ' fetchMyTrades requires a symbol argument');
        await this.loadMarkets ();
        let market = this.market (symbol);
        let request = {
            'symbol': market['id'],
        };
        if (typeof limit !== 'undefined')
            request['limit'] = limit;
        let response = await this.privatePostMytrades (this.extend (request, params));
        return this.parseTrades (response, market, since, limit);
    }

    async withdraw (code, amount, address, tag = undefined, params = {}) {
        this.checkAddress (address);
        await this.loadMarkets ();
        let currency = this.currency (code);
        let response = await this.privatePostWithdrawCurrency (this.extend ({
            'currency': currency['id'],
            'amount': amount,
            'address': address,
        }, params));
        return {
            'info': response,
            'id': this.safeString (response, 'txHash'),
        };
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = '/' + this.version + '/' + this.implodeParams (path, params);
        let query = this.omit (params, this.extractParams (path));
        if (api === 'public') {
            if (Object.keys (query).length)
                url += '?' + this.urlencode (query);
        } else {
            this.checkRequiredCredentials ();
            let nonce = this.nonce ();
            let request = this.extend ({
                'request': url,
                'nonce': nonce,
            }, query);
            let payload = this.json (request);
            payload = this.stringToBase64 (this.encode (payload));
            let signature = this.hmac (payload, this.encode (this.secret), 'sha384');
            headers = {
                'Content-Type': 'text/plain',
                'X-GEMINI-APIKEY': this.apiKey,
                'X-GEMINI-PAYLOAD': this.decode (payload),
                'X-GEMINI-SIGNATURE': signature,
            };
        }
        url = this.urls['api'] + url;
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let response = await this.fetch2 (path, api, method, params, headers, body);
        if ('result' in response)
            if (response['result'] === 'error')
                throw new ExchangeError (this.id + ' ' + this.json (response));
        return response;
    }
};
<commit_msg>gemini fetchTicker consistency<commit_after>'use strict';

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

const Exchange = require ('./base/Exchange');
const { ExchangeError } = require ('./base/errors');

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

module.exports = class gemini extends Exchange {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'gemini',
            'name': 'Gemini',
            'countries': 'US',
            'rateLimit': 1500, // 200 for private API
            'version': 'v1',
            'has': {
                'fetchDepositAddress': false,
                'CORS': false,
                'fetchBidsAsks': false,
                'fetchTickers': false,
                'fetchMyTrades': true,
                'fetchOrder': false,
                'fetchOrders': false,
                'fetchOpenOrders': false,
                'fetchClosedOrders': false,
                'withdraw': true,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/27816857-ce7be644-6096-11e7-82d6-3c257263229c.jpg',
                'api': 'https://api.gemini.com',
                'www': 'https://gemini.com',
                'doc': [
                    'https://docs.gemini.com/rest-api',
                    'https://docs.sandbox.gemini.com',
                ],
                'test': 'https://api.sandbox.gemini.com',
                'fees': [
                    'https://gemini.com/fee-schedule/',
                    'https://gemini.com/transfer-fees/',
                ],
            },
            'api': {
                'public': {
                    'get': [
                        'symbols',
                        'pubticker/{symbol}',
                        'book/{symbol}',
                        'trades/{symbol}',
                        'auction/{symbol}',
                        'auction/{symbol}/history',
                    ],
                },
                'private': {
                    'post': [
                        'order/new',
                        'order/cancel',
                        'order/cancel/session',
                        'order/cancel/all',
                        'order/status',
                        'orders',
                        'mytrades',
                        'tradevolume',
                        'balances',
                        'deposit/{currency}/newAddress',
                        'withdraw/{currency}',
                        'heartbeat',
                    ],
                },
            },
            'fees': {
                'trading': {
                    'taker': 0.0025,
                },
            },
        });
    }

    async fetchMarkets () {
        let markets = await this.publicGetSymbols ();
        let result = [];
        for (let p = 0; p < markets.length; p++) {
            let id = markets[p];
            let market = id;
            let uppercase = market.toUpperCase ();
            let base = uppercase.slice (0, 3);
            let quote = uppercase.slice (3, 6);
            let symbol = base + '/' + quote;
            result.push ({
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'info': market,
            });
        }
        return result;
    }

    async fetchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let orderbook = await this.publicGetBookSymbol (this.extend ({
            'symbol': this.marketId (symbol),
        }, params));
        return this.parseOrderBook (orderbook, undefined, 'bids', 'asks', 'price', 'amount');
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let ticker = await this.publicGetPubtickerSymbol (this.extend ({
            'symbol': market['id'],
        }, params));
        let timestamp = ticker['volume']['timestamp'];
        let baseVolume = market['base'];
        let quoteVolume = market['quote'];
        let last = parseFloat (ticker['last']);
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': undefined,
            'low': undefined,
            'bid': parseFloat (ticker['bid']),
            'bidVolume': undefined,
            'ask': parseFloat (ticker['ask']),
            'askVolume': undefined,
            'vwap': undefined,
            'open': undefined,
            'close': last,
            'last': last,
            'previousClose': undefined,
            'change': undefined,
            'percentage': undefined,
            'average': undefined,
            'baseVolume': parseFloat (ticker['volume'][baseVolume]),
            'quoteVolume': parseFloat (ticker['volume'][quoteVolume]),
            'info': ticker,
        };
    }

    parseTrade (trade, market) {
        let timestamp = trade['timestampms'];
        let order = undefined;
        if ('orderId' in trade)
            order = trade['orderId'].toString ();
        let fee = this.safeFloat (trade, 'fee_amount');
        if (typeof fee !== 'undefined') {
            let currency = this.safeString (trade, 'fee_currency');
            if (typeof currency !== 'undefined') {
                if (currency in this.currencies_by_id)
                    currency = this.currencies_by_id[currency]['code'];
                currency = this.commonCurrencyCode (currency);
            }
            fee = {
                'cost': parseFloat (trade['fee_amount']),
                'currency': currency,
            };
        }
        let price = parseFloat (trade['price']);
        let amount = parseFloat (trade['amount']);
        return {
            'id': trade['tid'].toString (),
            'order': order,
            'info': trade,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'type': undefined,
            'side': trade['type'],
            'price': price,
            'cost': price * amount,
            'amount': amount,
            'fee': fee,
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.publicGetTradesSymbol (this.extend ({
            'symbol': market['id'],
        }, params));
        return this.parseTrades (response, market, since, limit);
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        let balances = await this.privatePostBalances ();
        let result = { 'info': balances };
        for (let b = 0; b < balances.length; b++) {
            let balance = balances[b];
            let currency = balance['currency'];
            let account = {
                'free': parseFloat (balance['available']),
                'used': 0.0,
                'total': parseFloat (balance['amount']),
            };
            account['used'] = account['total'] - account['free'];
            result[currency] = account;
        }
        return this.parseBalance (result);
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets ();
        if (type === 'market')
            throw new ExchangeError (this.id + ' allows limit orders only');
        let nonce = this.nonce ();
        let order = {
            'client_order_id': nonce.toString (),
            'symbol': this.marketId (symbol),
            'amount': amount.toString (),
            'price': price.toString (),
            'side': side,
            'type': 'exchange limit', // gemini allows limit orders only
        };
        let response = await this.privatePostOrderNew (this.extend (order, params));
        return {
            'info': response,
            'id': response['order_id'],
        };
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        return await this.privatePostOrderCancel ({ 'order_id': id });
    }

    async fetchMyTrades (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        if (typeof symbol === 'undefined')
            throw new ExchangeError (this.id + ' fetchMyTrades requires a symbol argument');
        await this.loadMarkets ();
        let market = this.market (symbol);
        let request = {
            'symbol': market['id'],
        };
        if (typeof limit !== 'undefined')
            request['limit'] = limit;
        let response = await this.privatePostMytrades (this.extend (request, params));
        return this.parseTrades (response, market, since, limit);
    }

    async withdraw (code, amount, address, tag = undefined, params = {}) {
        this.checkAddress (address);
        await this.loadMarkets ();
        let currency = this.currency (code);
        let response = await this.privatePostWithdrawCurrency (this.extend ({
            'currency': currency['id'],
            'amount': amount,
            'address': address,
        }, params));
        return {
            'info': response,
            'id': this.safeString (response, 'txHash'),
        };
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = '/' + this.version + '/' + this.implodeParams (path, params);
        let query = this.omit (params, this.extractParams (path));
        if (api === 'public') {
            if (Object.keys (query).length)
                url += '?' + this.urlencode (query);
        } else {
            this.checkRequiredCredentials ();
            let nonce = this.nonce ();
            let request = this.extend ({
                'request': url,
                'nonce': nonce,
            }, query);
            let payload = this.json (request);
            payload = this.stringToBase64 (this.encode (payload));
            let signature = this.hmac (payload, this.encode (this.secret), 'sha384');
            headers = {
                'Content-Type': 'text/plain',
                'X-GEMINI-APIKEY': this.apiKey,
                'X-GEMINI-PAYLOAD': this.decode (payload),
                'X-GEMINI-SIGNATURE': signature,
            };
        }
        url = this.urls['api'] + url;
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let response = await this.fetch2 (path, api, method, params, headers, body);
        if ('result' in response)
            if (response['result'] === 'error')
                throw new ExchangeError (this.id + ' ' + this.json (response));
        return response;
    }
};
<|endoftext|>


<commit_before>"use strict";

var xhr = new XMLHttpRequest();
var wng_server;
var wng_game;
var wng_website;
var commits=[];

if (xhr) {
  xhr.onreadystatechange=function()
  {
  if (this.readyState==4 && this.status==200)
    {
    //document.getElementById("github").innerHTML=this.responseText;
    wng_server = JSON.parse(this.responseText);
    console.log(wng_server);
    next();
    }
  }
  xhr.open("GET","https://api.github.com/repos/wiggles-nextgen/wng-server/commits",true);
  xhr.send(null);
}

function next() {
  xhr.onreadystatechange=function()
  {
  if (this.readyState==4 && this.status==200)
    {
    wng_game = JSON.parse(this.responseText);
    console.log(wng_game);
    next2();
    }
  }
  xhr.open("GET","https://api.github.com/repos/wiggles-nextgen/wng-game/commits",true);
  xhr.send(null);
}

function next2() {
  xhr.onreadystatechange=function()
  {
  if (this.readyState==4 && this.status==200)
    {
    wng_website = JSON.parse(this.responseText);
    console.log(wng_game);
    combine();
    }
  }
  xhr.open("GET","https://api.github.com/repos/wiggles-nextgen/Wiggles-nextGen.github.io/commits",true);
  xhr.send(null);
}

function combine() {
  var i=0;
  for (var g in wng_game) {
    commits[i]={};
    commits[i].date=new Date(wng_game[g].commit.author.date);
    commits[i].type="game";
    commits[i].message=wng_game[g].commit.message;
    commits[i].author=wng_game[g].author.login;
    i++;
  }
  for (var s in wng_server) {
    commits[i]={};
    commits[i].date=new Date(wng_server[s].commit.author.date);
    commits[i].type="server";
    commits[i].message=wng_server[s].commit.message;
    commits[i].author=wng_server[s].author.login;
    i++;
  }
  for (var w in wng_website) {
    commits[i]={};
    commits[i].date=new Date(wng_website[w].commit.author.date);
    commits[i].type="website";
    commits[i].message=wng_website[w].commit.message;
    commits[i].author=wng_website[w].author.login;
    i++;
  }
  commits = commits.sort(function(a,b) {
    return a.date  ";
    document.getElementById("github").innerHTML+=commits[d].type;
    document.getElementById("github").innerHTML+=" ( "+commits[d].message + " ) / ";
    if (date == 0) {
      date=Math.floor((today-commits[d].date) / (1000*60*60));
      document.getElementById("github").innerHTML+="vor "+date + " Std
";
    } else {
      document.getElementById("github").innerHTML+="vor "+date + " Tagen
";
    }
  }
}
<commit_msg>added basic format<commit_after>"use strict";

var xhr = new XMLHttpRequest();
var wng_server;
var wng_game;
var wng_website;
var commits=[];

if (xhr) {
  xhr.onreadystatechange=function()
  {
  if (this.readyState==4 && this.status==200)
    {
    //document.getElementById("github").innerHTML=this.responseText;
    wng_server = JSON.parse(this.responseText);
    console.log(wng_server);
    next();
    }
  }
  xhr.open("GET","https://api.github.com/repos/wiggles-nextgen/wng-server/commits",true);
  xhr.send(null);
}

function next() {
  xhr.onreadystatechange=function()
  {
  if (this.readyState==4 && this.status==200)
    {
    wng_game = JSON.parse(this.responseText);
    console.log(wng_game);
    next2();
    }
  }
  xhr.open("GET","https://api.github.com/repos/wiggles-nextgen/wng-game/commits",true);
  xhr.send(null);
}

function next2() {
  xhr.onreadystatechange=function()
  {
  if (this.readyState==4 && this.status==200)
    {
    wng_website = JSON.parse(this.responseText);
    console.log(wng_website);
    combine();
    }
  }
  xhr.open("GET","https://api.github.com/repos/wiggles-nextgen/Wiggles-nextGen.github.io/commits",true);
  xhr.send(null);
}

function combine() {
  var i=0;
  for (var id in wng_game) {
    commits[i]={};
    commits[i].date=new Date(wng_game[id].commit.author.date);
    commits[i].type="game";
    commits[i].message=wng_game[id].commit.message;
    commits[i].author=wng_game[id].author.login;
    commits[i].sha=wng_game[id].sha;
    commits[i].pic=wng_game[id].author.avatar_url;
    i++;
  }
  for (var id in wng_server) {
    commits[i]={};
    commits[i].date=new Date(wng_server[id].commit.author.date);
    commits[i].type="server";
    commits[i].message=wng_server[id].commit.message;
    commits[i].author=wng_server[id].author.login;
    commits[i].sha=wng_server[id].sha;
    commits[i].pic=wng_server[id].author.avatar_url;
    i++;
  }
  for (var id in wng_website) {
    commits[i]={};
    commits[i].date=new Date(wng_website[id].commit.author.date);
    commits[i].type="website";
    commits[i].message=wng_website[id].commit.message;
    commits[i].author=wng_website[id].author.login;
    commits[i].sha=wng_website[id].sha;
    commits[i].pic=wng_website[id].author.avatar_url;
    i++;
  }
  commits = commits.sort(function(a,b) {
    return a.date < b.date;
  });
  drawCommits();
}

function drawCommits() {
  var today = new Date();
  console.log(commits);
  for (var d in commits){
    var date=Math.floor((today-commits[d].date) / (1000*60*60*24));
    document.getElementById("github").innerHTML+="";
    document.getElementById("github").innerHTML+=commits[d].author + " -> ";
    document.getElementById("github").innerHTML+=commits[d].type;
    document.getElementById("github").innerHTML+=" ( "+commits[d].message + " ) / ";
    if (date == 0) {
      date=Math.floor((today-commits[d].date) / (1000*60*60));
      if (date == 0) {
        date=Math.floor((today-commits[d].date) / (1000*60));
        if (date == 0) {
          date=Math.floor((today-commits[d].date) / (1000));
          document.getElementById("github").innerHTML+="vor "+date + " Sec";
        } else {
          document.getElementById("github").innerHTML+="vor "+date + " Min";
        }
      } else {
        document.getElementById("github").innerHTML+="vor "+date + " Std";
      }
    } else {
      document.getElementById("github").innerHTML+="vor "+date + " Tagen";
    }
    document.getElementById("github").innerHTML+=" [ "+commits[d].sha + " ]
";
  }
}
<|endoftext|>