<commit_before>import mongoose from 'mongoose'
const Schema = mongoose.Schema

function filter (data) {
  return data['BUTIKEROMBUD']['BUTIKOMBUD']
}

function model (data) {
  return data.map(obj => {
    const labels = obj.labels ? obj.labels.split(';') : []
    const phone = obj.phone ? obj.phone.replace(/[\/\-]|\s/g, '') : ''

    Object.assign(obj, {
      phone,
      labels
    })

    return obj
  })
}

const mapping = {
  NR: 'nr',
  NAMN: 'name',
  TYP: 'type',
  ADDRESS1: 'address_1',
  ADDRESS2: 'address_2',
  ADDRESS3: 'address_3',
  ADDRESS4: 'address_4',
  ADDRESS5: 'address_5',
  TELEFON: 'phone',
  BUTIKSTYP: 'shop_type',
  TJANSTER: 'services',
  SOKORD: 'labels',
  OPPETTIDER: 'opening_hours',
  RT90X: 'RT90x',
  RT90Y: 'RT90y'
}

let productSchema = new Schema({
  nr: { type: String, required: true },
  name: { type: String, index: true, default: '' },
  type: { type: String, index: true, default: '' },
  address_1: { type: String, index: true, default: '' },
  address_2: { type: String, index: true, default: '' },
  address_3: { type: String, index: true, default: '' },
  address_4: { type: String, index: true, default: '' },
  address_5: { type: String, index: true, default: '' },
  phone: { type: String, default: '' },
  shop_type: { type: String, index: true, default: '' },
  services: { type: String, default: '' },
  labels: { type: Array, default: [] },
  opening_hours: { type: String, default: '' },
  RT90x: { type: Number, default: null },
  RT90y: { type: Number, default: null }
})

mongoose.model('Store', productSchema)

export { mapping, model, filter }
<commit_msg>Parse and transform opening hours<commit_after>import mongoose from 'mongoose'
const Schema = mongoose.Schema

function filter (data) {
  return data['BUTIKEROMBUD']['BUTIKOMBUD']
}

function transformOpeningHours (str) {
  let list = str ? str.split(/;;;0?\-?;/g) : []

  list = list.filter(str => {
    return str.length > 0
  })

  list = list.map(str => {
    let opening = str.replace('_*', '').split(';')
    const day = opening[0]
    const hours = `${opening[1]}-${opening[2]}`

    return `${day} ${hours}`
  })

  return list
}

function model (data) {
  return data.map(obj => {
    const labels = obj.labels ? obj.labels.split(';') : []
    const phone = obj.phone ? obj.phone.replace(/[\/\-]|\s/g, '') : ''
    let openingHours = transformOpeningHours(obj.opening_hours)

    Object.assign(obj, {
      phone,
      labels,
      opening_hours: openingHours
    })

    return obj
  })
}

const mapping = {
  NR: 'nr',
  NAMN: 'name',
  TYP: 'type',
  ADDRESS1: 'address_1',
  ADDRESS2: 'address_2',
  ADDRESS3: 'address_3',
  ADDRESS4: 'address_4',
  ADDRESS5: 'address_5',
  TELEFON: 'phone',
  BUTIKSTYP: 'shop_type',
  TJANSTER: 'services',
  SOKORD: 'labels',
  OPPETTIDER: 'opening_hours',
  RT90X: 'RT90x',
  RT90Y: 'RT90y'
}

let productSchema = new Schema({
  nr: { type: String, required: true },
  name: { type: String, index: true, default: '' },
  type: { type: String, index: true, default: '' },
  address_1: { type: String, index: true, default: '' },
  address_2: { type: String, index: true, default: '' },
  address_3: { type: String, index: true, default: '' },
  address_4: { type: String, index: true, default: '' },
  address_5: { type: String, index: true, default: '' },
  phone: { type: String, default: '' },
  shop_type: { type: String, index: true, default: '' },
  services: { type: String, default: '' },
  labels: { type: Array, default: [] },
  opening_hours: { type: Array, default: [] },
  RT90x: { type: Number, default: null },
  RT90y: { type: Number, default: null }
})

mongoose.model('Store', productSchema)

export { mapping, model, filter }
<|endoftext|>


<commit_before>/*******************************************************************************
 * bootstrap
 *
 * @author       Isaac Suttell <isaac_suttell@playstation.sony.com>
 * @file         Load application settings
 ******************************************************************************/

// Modules
var fs = require('fs');
var path = require('path');

var merge = require('../lib/merge');

/**
 * Read the config RC File
 *
 * @param     {Object}    options
 * @return    {Object}
 */
function rcConfig(file) {
	file = path.resolve(file || '.configrc');

	// Must exist
	fs.accessSync(file);

	// Read
	var rc = fs.readFileSync(file, {
		encoding: 'utf8'
	});

	// Convert to JS
	rc = JSON.parse(rc);

	return rc;
}

/**
 * Require a config file
 *
 * @param  {String} env
 * @return {Object}
 */
function requireConfig(env) {
	env = env || 'default';
	var fileName = process.cwd() + '/config/' + env + '.js';
	try {
		fs.accessSync(fileName);
		return require(fileName);
	} catch(accessError) {
		if (accessError.message.indexOf('ENOENT') === 0) {
			return {};
		} else {
			throw accessError;
		}
	}
}

/**
 * Grab the path to the machine config
 * @param    {Array<Object>}    configs
 * @return   {String}
 */
function getRCPath(configs) {
	var config = configs.find(function(conf){
		return typeof conf === 'object' && conf.rc;
	});
	return config ? path.resolve(config.rc) : void 0;
}

/**
 * Search for webpack config
 * @param    {String}    env
 * @return   {Object}
 */
function getWebpack(env) {
	var files = [process.cwd() + '/config/webpack' + env + '.js', process.cwd() + '/config/webpack.default.js', process.cwd() + '/config/webpack.config.js'];
	var index = files.length;
	while (--index > 0) {
		try {
			fs.accessSync(files[index]);
			return require(files[index]);
		} catch(accessError) {
			if (accessError.message.indexOf('ENOENT') !== 0) {
				throw accessError;
			}
		}
	}
	return {};
}

module.exports = function(cli) {
	if (typeof cli !== 'object') {
		cli = {};
	}

	// Framework defaults
	var defaultConfig = require('../../config/default');

	// Get global config
	var config = requireConfig();

	// Get the environment
	var env = [cli.env, config.env, process.env.NODE_ENV, 'production'].find(function(item){
		return typeof item === 'string';
	});

	// Get env specific config
	var envConfig = requireConfig(env);

	// listen for the port as an environmental variable. If we see it, use it.
	if (process.env.PORT) {
		envConfig.port = process.env.PORT;
	}

	// Get the location of the machine config file
	var rcPath = getRCPath([cli, envConfig, config]);

	// Get machine specific settings
	var rc = rcConfig(rcPath);

	// Merge config sources together
	config = merge({}, defaultConfig, config, envConfig, rc, cli);

	config.rc = rcPath;

	// Resolve all paths
	for (var folder in config.folders) {
		if (config.folders.hasOwnProperty(folder)) {
			config.folders[folder] = path.resolve(config.folders[folder]);
		}
	}

	config.webpackConfig = getWebpack(env);

	return config;
};
<commit_msg>fixed issue hiding config errors<commit_after>/*******************************************************************************
 * bootstrap
 *
 * @author       Isaac Suttell <isaac_suttell@playstation.sony.com>
 * @file         Load application settings
 ******************************************************************************/

// Modules
var fs = require('fs');
var path = require('path');

var merge = require('../lib/merge');

/**
 * Read the config RC File
 *
 * @param     {Object}    options
 * @return    {Object}
 */
function rcConfig(file) {
	file = path.resolve(file || '.configrc');

	// Must exist
	fs.accessSync(file);

	// Read
	var rc = fs.readFileSync(file, {
		encoding: 'utf8'
	});

	// Convert to JS
	rc = JSON.parse(rc);

	return rc;
}

/**
 * Require a config file
 *
 * @param  {String} env
 * @return {Object}
 */
function requireConfig(env) {
	env = env || 'default';
	var fileName = process.cwd() + '/config/' + env + '.js';
	try {
		fs.accessSync(fileName);
	} catch(accessError) {
    // Can't find the file
		return {};
	}
  return require(fileName);
}

/**
 * Grab the path to the machine config
 * @param    {Array<Object>}    configs
 * @return   {String}
 */
function getRCPath(configs) {
	var config = configs.find(function(conf){
		return typeof conf === 'object' && conf.rc;
	});
	return config ? path.resolve(config.rc) : void 0;
}

/**
 * Search for webpack config
 * @param    {String}    env
 * @return   {Object}
 */
function getWebpack(env) {
	var files = [process.cwd() + '/config/webpack' + env + '.js', process.cwd() + '/config/webpack.default.js', process.cwd() + '/config/webpack.config.js'];
	var index = files.length;
	while (--index > 0) {
		try {
			fs.accessSync(files[index]);
			return require(files[index]);
		} catch(accessError) {
			if (accessError.message.indexOf('ENOENT') !== 0) {
				throw accessError;
			}
		}
	}
	return {};
}

module.exports = function(cli) {
	if (typeof cli !== 'object') {
		cli = {};
	}

	// Framework defaults
	var defaultConfig = require('../../config/default');

	// Get global config
	var config = requireConfig();

	// Get the environment
	var env = [cli.env, config.env, process.env.NODE_ENV, 'production'].find(function(item){
		return typeof item === 'string';
	});

	// Get env specific config
	var envConfig = requireConfig(env);

	// listen for the port as an environmental variable. If we see it, use it.
	if (process.env.PORT) {
		envConfig.port = process.env.PORT;
	}

	// Get the location of the machine config file
	var rcPath = getRCPath([cli, envConfig, config]);

	// Get machine specific settings
	var rc = rcConfig(rcPath);

	// Merge config sources together
	config = merge({}, defaultConfig, config, envConfig, rc, cli);

	config.rc = rcPath;

	// Resolve all paths
	for (var folder in config.folders) {
		if (config.folders.hasOwnProperty(folder)) {
			config.folders[folder] = path.resolve(config.folders[folder]);
		}
	}

	config.webpackConfig = getWebpack(env);

	return config;
};
<|endoftext|>


<commit_before>/** Sample platform outline
 *  based on Sonos platform
 */
'use strict';
var types = require("HAP-NodeJS/accessories/types.js");
//var hardware = require('myHardwareSupport'); //require any additional hardware packages
var knxd = require('eibd');

function KNXPlatform(log, config){
	this.log = log;
	this.config = config;
//	this.property1 = config.property1;
//	this.property2 = config.property2;

	// initiate connection to bus for listening ==> done with first shim

};

KNXPlatform.prototype = {
		accessories: function(callback) {
			this.log("Fetching KNX devices.");
			var that = this;

			// iterate through all devices the platform my offer
			// for each device, create an accessory

			// read accessories from file !!!!!
			var foundAccessories = this.config.accessories;

			//create array of accessories
			var myAccessories = [];

			for (var int = 0; int < foundAccessories.length; int++) {
				this.log("parsing acc " + int + " of " + foundAccessories.length);
				// instantiate and push to array
				switch (foundAccessories[int].accessory_type) {
				case "knxdevice":
					this.log("push new universal device "+foundAccessories[int].name);
					// push knxd connection setting to each device from platform
					foundAccessories[int].knxd_ip = this.config.knxd_ip;
					foundAccessories[int].knxd_port = this.config.knxd_port;
					var accConstructor = require('./../accessories/knxdevice.js');
					var acc = new accConstructor.accessory(this.log,foundAccessories[int]);
					this.log("created "+acc.name+" universal accessory");
					myAccessories.push(acc);
					break;
				case "knxlamp":
					this.log("push new lamp with "+foundAccessories[int].name	);
					foundAccessories[int].knxd_ip = this.config.knxd_ip;
					foundAccessories[int].knxd_port = this.config.knxd_port;
					var accConstructor = require('./../accessories/knxlamp.js');
					var acc = new accConstructor.accessory(this.log,foundAccessories[int]);
					this.log("created "+acc.name+" accessory");
					myAccessories.push(acc);
					break;
				case "knxthermostat":
					this.log("push new thermostat with "+foundAccessories[int].name);
					foundAccessories[int].knxd_ip = this.config.knxd_ip;
					foundAccessories[int].knxd_port = this.config.knxd_port;
					var accConstructor = require('./../accessories/knxthermostat.js');
					var acc = new accConstructor.accessory(this.log,foundAccessories[int]);
					this.log("created "+acc.name+" accessory");
					myAccessories.push(acc);
					break;
				default:
					// do something else
					this.log("unkown accessory type found")
				}

			};
			// if done, return the array to callback function
			this.log("returning "+myAccessories.length+" accessories");
			callback(myAccessories);
		}
};

/**
 * The buscallbacks module is to expose a simple function to listen on the bus and register callbacks for value changes
 * of registered addresses.
 *
 * Usage:
 *	 You can start the monitoring process at any time
	 startMonitor({host: name-ip, port: port-num });

 *	 You can add addresses to the subscriptions using

registerGA(groupAddress, callback)

 *	 groupAddress has to be an groupAddress in common knx notation string '1/2/3'
 *	 the callback has to be a
 *	 	var f = function(value) { handle value update;}
 *	 so you can do a
 *	 	registerGA('1/2/3', function(value){
 *	 		console.log('1/2/3 got a hit with '+value);
 *	 		});
 *	 but of course it is meant to be used programmatically, not literally, otherwise it has no advantage
 *
 *	 You can also use arrays of addresses if your callback is supposed to listen to many addresses:

registerGA(groupAddresses[], callback)

 *	as in
 *	 	registerGA(['1/2/3','1/0/0'], function(value){
 *	 		console.log('1/2/3 or 1/0/0 got a hit with '+value);
 *	 		});
 *  if you are having central addresses like "all lights off" or additional response objects
 *
 *
 *  callbacks can have a signature of
 *  function(value, src, dest, type) but do not have to support these parameters (order matters)
 *  src = physical address such as '1.1.20'
 *  dest = groupAddress hit (you subscribed to that address, remember?), as '1/2/3'
 *  type = Data point type, as 'DPT1'
 *
 *
 */

//array of registered addresses and their callbacks
var subscriptions = [];
//check variable to avoid running two listeners
var running;

function groupsocketlisten(opts, callback) {
	var conn = knxd.Connection();
	conn.socketRemote(opts, function() {
		conn.openGroupSocket(0, callback);
	});
}

var registerSingleGA = function registerSingleGA (groupAddress, callback) {
	subscriptions.push({address: groupAddress, callback: callback });
}

/*
 * public busMonitor.startMonitor()
 * starts listening for telegrams on KNX bus
 *
 */
var startMonitor = function startMonitor(opts) {  // using { host: name-ip, port: port-num } options object
	if (!running) {
		running = true;
	} else {
		console.log("<< knxd socket listener already running >>");
		return null;
	}
	console.log(">>> knxd groupsocketlisten starting <<<");
	groupsocketlisten(opts, function(parser) {
		//console.log("knxfunctions.read: in callback parser");
		parser.on('write', function(src, dest, type, val){
			// search the registered group addresses
			//console.log('recv: Write from '+src+' to '+dest+': '+val+' ['+type+'], listeners:' + subscriptions.length);
			for (var i = 0; i < subscriptions.length; i++) {
				// iterate through all registered addresses
				if (subscriptions[i].address === dest) {
					// found one, notify
					console.log('HIT: Write from '+src+' to '+dest+': '+val+' ['+type+']');
					subscriptions[i].callback(val, src, dest, type);
				}
			}
		});

		parser.on('response', function(src, dest, type, val) {
			// search the registered group addresses
//			console.log('recv: resp from '+src+' to '+dest+': '+val+' ['+type+']');
			for (var i = 0; i < subscriptions.length; i++) {
				// iterate through all registered addresses
				if (subscriptions[i].address === dest) {
					// found one, notify
//					console.log('HIT: Response from '+src+' to '+dest+': '+val+' ['+type+']');
					subscriptions[i].callback(val, src, dest, type);
				}
			}

		});

		//dont care about reads here
//		parser.on('read', function(src, dest) {
//		console.log('Read from '+src+' to '+dest);
//		});
		//console.log("knxfunctions.read: in callback parser at end");
	}); // groupsocketlisten parser
}; //startMonitor

/*
 *  public registerGA(groupAdresses[], callback(value))
 *  parameters
 *  	callback: function(value, src, dest, type) called when a value is sent on the bus
 *  	groupAddresses: (Array of) string(s) for group addresses
 *
 *
 *
 */
var registerGA = function (groupAddresses, callback) {
	// check if the groupAddresses is an array
	if (groupAddresses.constructor.toString().indexOf("Array") > -1) {
		// handle multiple addresses
		for (var i = 0; i < groupAddresses.length; i++) {
			if (groupAddresses[i]) { // do not bind empty addresses
				registerSingleGA (groupAddresses[i], callback);
			}
		}
	} else {
		// it's only one
		registerSingleGA (groupAddresses, callback);
	}
//	console.log("listeners now: " + subscriptions.length);
};

module.exports.platform = KNXPlatform;
module.exports.registerGA = registerGA;
module.exports.startMonitor = startMonitor;<commit_msg>cleanup of sample.json and platform shim<commit_after>/** Sample platform outline
 *  based on Sonos platform
 */
'use strict';
var types = require("HAP-NodeJS/accessories/types.js");
//var hardware = require('myHardwareSupport'); //require any additional hardware packages
var knxd = require('eibd');

function KNXPlatform(log, config){
	this.log = log;
	this.config = config;
//	this.property1 = config.property1;
//	this.property2 = config.property2;

	// initiate connection to bus for listening ==> done with first shim

};

KNXPlatform.prototype = {
		accessories: function(callback) {
			this.log("Fetching KNX devices.");
			var that = this;

			// iterate through all devices the platform my offer
			// for each device, create an accessory

			// read accessories from file !!!!!
			var foundAccessories = this.config.accessories;

			//create array of accessories
			var myAccessories = [];

			for (var int = 0; int < foundAccessories.length; int++) {
				this.log("parsing acc " + int + " of " + foundAccessories.length);
				// instantiate and push to array
				switch (foundAccessories[int].accessory_type) {
				case "knxdevice":
					this.log("push new universal device "+foundAccessories[int].name);
					// push knxd connection setting to each device from platform
					foundAccessories[int].knxd_ip = this.config.knxd_ip;
					foundAccessories[int].knxd_port = this.config.knxd_port;
					var accConstructor = require('./../accessories/knxdevice.js');
					var acc = new accConstructor.accessory(this.log,foundAccessories[int]);
					this.log("created "+acc.name+" universal accessory");
					myAccessories.push(acc);
					break;
				default:
					// do something else
					this.log("unkown accessory type found")
				}

			};
			// if done, return the array to callback function
			this.log("returning "+myAccessories.length+" accessories");
			callback(myAccessories);
		}
};

/**
 * The buscallbacks module is to expose a simple function to listen on the bus and register callbacks for value changes
 * of registered addresses.
 *
 * Usage:
 *	 You can start the monitoring process at any time
	 startMonitor({host: name-ip, port: port-num });

 *	 You can add addresses to the subscriptions using

registerGA(groupAddress, callback)

 *	 groupAddress has to be an groupAddress in common knx notation string '1/2/3'
 *	 the callback has to be a
 *	 	var f = function(value) { handle value update;}
 *	 so you can do a
 *	 	registerGA('1/2/3', function(value){
 *	 		console.log('1/2/3 got a hit with '+value);
 *	 		});
 *	 but of course it is meant to be used programmatically, not literally, otherwise it has no advantage
 *
 *	 You can also use arrays of addresses if your callback is supposed to listen to many addresses:

registerGA(groupAddresses[], callback)

 *	as in
 *	 	registerGA(['1/2/3','1/0/0'], function(value){
 *	 		console.log('1/2/3 or 1/0/0 got a hit with '+value);
 *	 		});
 *  if you are having central addresses like "all lights off" or additional response objects
 *
 *
 *  callbacks can have a signature of
 *  function(value, src, dest, type) but do not have to support these parameters (order matters)
 *  src = physical address such as '1.1.20'
 *  dest = groupAddress hit (you subscribed to that address, remember?), as '1/2/3'
 *  type = Data point type, as 'DPT1'
 *
 *
 */

//array of registered addresses and their callbacks
var subscriptions = [];
//check variable to avoid running two listeners
var running;

function groupsocketlisten(opts, callback) {
	var conn = knxd.Connection();
	conn.socketRemote(opts, function() {
		conn.openGroupSocket(0, callback);
	});
}

var registerSingleGA = function registerSingleGA (groupAddress, callback) {
	subscriptions.push({address: groupAddress, callback: callback });
}

/*
 * public busMonitor.startMonitor()
 * starts listening for telegrams on KNX bus
 *
 */
var startMonitor = function startMonitor(opts) {  // using { host: name-ip, port: port-num } options object
	if (!running) {
		running = true;
	} else {
		console.log("<< knxd socket listener already running >>");
		return null;
	}
	console.log(">>> knxd groupsocketlisten starting <<<");
	groupsocketlisten(opts, function(parser) {
		//console.log("knxfunctions.read: in callback parser");
		parser.on('write', function(src, dest, type, val){
			// search the registered group addresses
			//console.log('recv: Write from '+src+' to '+dest+': '+val+' ['+type+'], listeners:' + subscriptions.length);
			for (var i = 0; i < subscriptions.length; i++) {
				// iterate through all registered addresses
				if (subscriptions[i].address === dest) {
					// found one, notify
					console.log('HIT: Write from '+src+' to '+dest+': '+val+' ['+type+']');
					subscriptions[i].callback(val, src, dest, type);
				}
			}
		});

		parser.on('response', function(src, dest, type, val) {
			// search the registered group addresses
//			console.log('recv: resp from '+src+' to '+dest+': '+val+' ['+type+']');
			for (var i = 0; i < subscriptions.length; i++) {
				// iterate through all registered addresses
				if (subscriptions[i].address === dest) {
					// found one, notify
//					console.log('HIT: Response from '+src+' to '+dest+': '+val+' ['+type+']');
					subscriptions[i].callback(val, src, dest, type);
				}
			}

		});

		//dont care about reads here
//		parser.on('read', function(src, dest) {
//		console.log('Read from '+src+' to '+dest);
//		});
		//console.log("knxfunctions.read: in callback parser at end");
	}); // groupsocketlisten parser
}; //startMonitor

/*
 *  public registerGA(groupAdresses[], callback(value))
 *  parameters
 *  	callback: function(value, src, dest, type) called when a value is sent on the bus
 *  	groupAddresses: (Array of) string(s) for group addresses
 *
 *
 *
 */
var registerGA = function (groupAddresses, callback) {
	// check if the groupAddresses is an array
	if (groupAddresses.constructor.toString().indexOf("Array") > -1) {
		// handle multiple addresses
		for (var i = 0; i < groupAddresses.length; i++) {
			if (groupAddresses[i]) { // do not bind empty addresses
				registerSingleGA (groupAddresses[i], callback);
			}
		}
	} else {
		// it's only one
		registerSingleGA (groupAddresses, callback);
	}
//	console.log("listeners now: " + subscriptions.length);
};

module.exports.platform = KNXPlatform;
module.exports.registerGA = registerGA;
module.exports.startMonitor = startMonitor;<|endoftext|>


<commit_before>module.exports = {

	'': require('./pages/home'),
	'signup': require('./pages/signup'),
	'login': require('./pages/login'),
	'logout': require('./pages/logout'),
	'settings': require('./pages/settings'),
	'settings/language': require('./pages/settings/language'),
	'settings/photos': require('./pages/settings/photos'),
	'test1/:id': require('./pages/home/test1'),
	'test2/:id': require('./pages/home/test2')
};<commit_msg>ident<commit_after>module.exports = {
	'': require('./pages/home'),
	'signup': require('./pages/signup'),
	'login': require('./pages/login'),
	'logout': require('./pages/logout'),
	'settings': require('./pages/settings'),
	'settings/language': require('./pages/settings/language'),
	'settings/photos': require('./pages/settings/photos'),
	'test1/:id': require('./pages/home/test1'),
	'test2/:id': require('./pages/home/test2')
};<|endoftext|>


<commit_before>'use strict';
var Search = require('node-bing-api');
var request = require('request');
module.exports = function (app, db) {
	var collection = db.collection('search_history');
	app.get('/',function(req,res){
		res.render('index.html');
	});

	app.get('/history',function(req,res){
		collection.find({}).sort({'time_search': -1}).limit(10).toArray( function (err, docs) {
            if(err) throw err;

            docs.forEach( function (element, index, array) {
               res.write( 'Date: ' + element.time_search + '\nSearch: ' + element.str_search + '\n' );
            });
			res.end();
		});
	});

	app.get('/search/:str',function(req, res) {
		var str = req.params.str;
		var offset = req.query.offset || 0;
		var search = new Search({ accKey: process.env.Bing_Search_API });
		str = str.replace(/%20/g, ' ');
		collection.insert({'str_search': req.params.str, 'time_search': new Date()});
		search.images(str, {top: 5, skip: offset*5}, function(err, respond, body){
			if(err) throw err;
			res.send('hello world');
			});
	});
	function makeList(img) {
	// Construct object from the json result
		return {
		  "url": img.MediaUrl,
		  "snippet": img.Title,
		  "thumbnail": img.Thumbnail.MediaUrl,
		  "context": img.SourceUrl
		};
	}

}<commit_msg>index.js -test2<commit_after>'use strict';
var Search = require('node-bing-api');
var request = require('request');
module.exports = function (app, db) {
	var collection = db.collection('search_history');
	app.get('/',function(req,res){
		res.render('index.html');
	});

	app.get('/history',function(req,res){
		collection.find({}).sort({'time_search': -1}).limit(10).toArray( function (err, docs) {
            if(err) throw err;

            docs.forEach( function (element, index, array) {
               res.write( 'Date: ' + element.time_search + '\nSearch: ' + element.str_search + '\n' );
            });
			res.end();
		});
	});

	app.get('/search/:str',function(req, res) {
		var str = req.params.str;
		var offset = req.query.offset || 0;
		var search = new Search({ accKey: process.env.Bing_Search_API });
		str = str.replace(/%20/g, ' ');
		collection.insert({'str_search': req.params.str, 'time_search': new Date()});
		search.images(str, {top: 5, skip: offset*5}, function(err, respond, body){
			if(err) throw err;
			console.log(body.d.results.map(makeList));
			res.send(body.d.results.map(makeList));
			});
	});
	function makeList(img) {
	// Construct object from the json result
		return {
		  "url": img.MediaUrl,
		  "snippet": img.Title,
		  "thumbnail": img.Thumbnail.MediaUrl,
		  "context": img.SourceUrl
		};
	}

}<|endoftext|>


<commit_before>'use strict';

/////// DEPENDENCIES
var colors  = require('colors');
console.log('images.js entered'.cyan);

// Images routes use images controller
var Images = require('../controllers/images');

var statsTest = require('../../test/stats');

var programs = require('../programs');

/////// END DEPENDENCIES

// routes
exports.index = function(req, res){
  res.render('index', { title: 'Express' });
};

exports.landing = function(req, res){
  res.render('landing', { title: 'Represent GSAPP', programs: programs });
};

exports.statsTest = function(req, res){
  res.json(statsTest);
};

exports.fetch = function(req, res){
  console.log('fetch()');

  Images.fetchByHashtag(req, res, 'gsapp');

};

// render the carousel
exports.grid = function(req, res){
  console.log('/grid');
  var images = Images.renderAll(req, res, 'grid');
};

// render the carousel
exports.edit = function(req, res){
  console.log('/edit');
  var images = Images.renderAll(req, res, 'edit');
};

exports.stats = function(req, res){
  console.log('/api/stats');
  Images.renderStats(req, res);
}

exports.programs = function(req, res){
  console.log('/programs');
  res.render('programs', { programs: programs });
}

exports.editPublished = function(req, res){
  console.log('/edit/published');
  var images = Images.edit(req, res, 'published');
};

exports.editPending = function(req, res){
  console.log('/edit/pending');
  var images = Images.edit(req, res, 'pending');
};

exports.editHidden = function(req, res){
  console.log('/edit/hidden');
  var images = Images.edit(req, res, 'hidden');
};

exports.editFeatured = function(req, res){
  console.log('/edit/featured');
  var images = Images.edit(req, res, 'featured');
};

// api

exports.publish = function(req, res){
  console.log('/api/publish');
  var images = Images.setStatus(req, res, req.body.publish, 'published');
};

exports.pend = function(req, res){
  console.log('/api/pend');
  var images = Images.setStatus(req, res, req.body.pend, 'pending');
};

exports.hide = function(req, res){
  console.log('/api/hide');
  var images = Images.setStatus(req, res, req.body.hide, 'hidden');
};

exports.feature = function(req, res){
  console.log('/api/feature');
  var images = Images.setStatus(req, res, req.body.feature, 'featured');
};

exports.update = function(req, res){
  console.log('/api/update');
  var images = Images.update(req, res);
};

exports.getByProgram = function(req, res){
  var images = Images.getByProgram(req, res);
};

exports.getPrograms = function(req, res){
  res.json(programs);
};

exports.getFeatured = function(req, res){
  Images.getFeatured(req, res);
};

exports.updatePrograms = function(req, res){
  console.log('req.body:');
  console.dir(req.body);
  res.send(200);
}

/*

/////// INSTAGRAM
var ig = require('instagram-node').instagram();

//import Instagram secrets from json file
var instagram_secrets = require('../secrets.json').instagram;

//set up secrets for Instagram module
ig.use({ client_id: instagram_secrets.client_id,
    client_secret: instagram_secrets.client_secret });
/////// END INSTAGRAM

/////// GLOBALS
var fetched_array; //container array for all fetched Instagram images

var tags = []; //array to hold tags for all programs (eg. xrio, xbeirut)
var tag_index = 0; //counter: current city fetching from Instagram by index in tags[] array
var total_found = 0; //counter: total images found from Instagram for given city
var current_program = ''; //pointer: current city fetching from Instagram

var interval_id; //global ID for the main interval for fetching from Instagram

var FETCH_TIME = 3000; //fetch every 3 seconds
var FETCHING_FROM_INSTAGRAM_BUSY_FLAG = false; //flag if in the middle of fetching
var DOWNLOADING_FROM_INSTAGRAM_BUSY_FLAG = false; //flag if in the middle of downloading
/////// END GLOBALS

/////// HELPER FUNCTIONS
function pushArray(arr, arr2) {
    arr.push.apply(arr, arr2);
}
/////// END HELPER FUNCTIONS

/////// INITIALIZE programs ARRAY
//pull in array of programs from json file
var programs = require('../programs.json');

/////// END INITIALIZE programs ARRAY

//Initializes downloading all undownloaded images from Instagram
function initImageDownloadCycle(){
    images.downloadAll();
}

//Initializes fetching all images from Instagram and puts them in the database
//to be later downloaded then uploaded to Flickr
function initInstagramFetchCycle(){

    FETCHING_FROM_INSTAGRAM_BUSY_FLAG = true;

    fetched_array = []; //clear out container array for all fetched Instagram images
    tag_index = 0;

    current_program = tags[tag_index].substring(1);

    //start to fetch from Instagram
    fetchAllProgramsFromInstagram();
}

var instagram_handler = function(err, medias, pagination, limit) {
    if(err){
        console.log(err);
    }else{
        console.log('\nFetched ' + medias.length + ' images'.cyan + ' from tag_index: ' + tag_index + ' = city: ' + tags[tag_index] + ' with limit: ' + limit + ' and pagination:');
        console.dir(pagination);

        for(var m = 0; m < medias.length; m++){
            //set city for all fetched items
            medias[m].city = tags[tag_index].substring(1);
        }

        pushArray(fetched_array, medias);

        if(pagination.next){
            console.log('\nPAGINATION.NEXT()\n');
            pagination.next(instagram_handler);

        //no pagination, move on to next city
        }else{

            if(tag_index >= (tags.length - 1) ){ //if just finished the last city
                //report out totals
                console.log('\n\nfetched_array.length: ' + fetched_array.length); //total in fetched_array
                var all_images = images.all(); //total in database

                //set and clear state flags
                FETCHING_FROM_INSTAGRAM_BUSY_FLAG = false;
                DOWNLOADING_FROM_INSTAGRAM_BUSY_FLAG = true;

                ////all images have been fetched, start to upsert all images recursively
                //call: upsert from controllers > images
                //callback: start to download image binaries from Instagram
                images.upsertArray(fetched_array, initImageDownloadCycle);

            }else{
                console.log('\n\nmoving on to the next city\n\n');
                tag_index++; //increment city

                //iterate
                ig.tag_media_recent(tags[tag_index], instagram_handler);
            }
        }
    }
};

function fetchAllProgramsFromInstagram(){
    var images_array = [];

    console.log('searching for tag: ' + tags[tag_index]);
    console.log('tag_index: ' + tag_index);
    console.dir(tags);

    ig.tag_media_recent(tags[tag_index], instagram_handler);

}

//initInstagramFetchCycle();

module.exports = function(app) {

    app.get('/fetch', function(req, res){
        initInstagramFetchCycle();
    });

    app.all ('/callback', function(req, res){
        console.log('\n\n\nreq:');
        console.dir(req);
        console.log('\n\n\nres:');
        console.dir(res);
    });

    /*
    app.post('/articles', authorization.requiresLogin, articles.create);
    app.get('/articles/:articleId', articles.show);
    app.put('/articles/:articleId', authorization.requiresLogin, hasAuthorization, articles.update);
    app.del('/articles/:articleId', authorization.requiresLogin, hasAuthorization, articles.destroy);

    // Finish with setting up the articleId param
    app.param('articleId', articles.article);
    */

//};
<commit_msg>test manipulate new programs into array<commit_after>'use strict';

/////// DEPENDENCIES
var colors  = require('colors');
console.log('images.js entered'.cyan);

// Images routes use images controller
var Images = require('../controllers/images');

var statsTest = require('../../test/stats');

var programs = require('../programs');

/////// END DEPENDENCIES

// routes
exports.index = function(req, res){
  res.render('index', { title: 'Express' });
};

exports.landing = function(req, res){
  res.render('landing', { title: 'Represent GSAPP', programs: programs });
};

exports.statsTest = function(req, res){
  res.json(statsTest);
};

exports.fetch = function(req, res){
  console.log('fetch()');

  Images.fetchByHashtag(req, res, 'gsapp');

};

// render the carousel
exports.grid = function(req, res){
  console.log('/grid');
  var images = Images.renderAll(req, res, 'grid');
};

// render the carousel
exports.edit = function(req, res){
  console.log('/edit');
  var images = Images.renderAll(req, res, 'edit');
};

exports.stats = function(req, res){
  console.log('/api/stats');
  Images.renderStats(req, res);
}

exports.programs = function(req, res){
  console.log('/programs');
  res.render('programs', { programs: programs });
}

exports.editPublished = function(req, res){
  console.log('/edit/published');
  var images = Images.edit(req, res, 'published');
};

exports.editPending = function(req, res){
  console.log('/edit/pending');
  var images = Images.edit(req, res, 'pending');
};

exports.editHidden = function(req, res){
  console.log('/edit/hidden');
  var images = Images.edit(req, res, 'hidden');
};

exports.editFeatured = function(req, res){
  console.log('/edit/featured');
  var images = Images.edit(req, res, 'featured');
};

// api

exports.publish = function(req, res){
  console.log('/api/publish');
  var images = Images.setStatus(req, res, req.body.publish, 'published');
};

exports.pend = function(req, res){
  console.log('/api/pend');
  var images = Images.setStatus(req, res, req.body.pend, 'pending');
};

exports.hide = function(req, res){
  console.log('/api/hide');
  var images = Images.setStatus(req, res, req.body.hide, 'hidden');
};

exports.feature = function(req, res){
  console.log('/api/feature');
  var images = Images.setStatus(req, res, req.body.feature, 'featured');
};

exports.update = function(req, res){
  console.log('/api/update');
  var images = Images.update(req, res);
};

exports.getByProgram = function(req, res){
  var images = Images.getByProgram(req, res);
};

exports.getPrograms = function(req, res){
  res.json(programs);
};

exports.getFeatured = function(req, res){
  Images.getFeatured(req, res);
};

exports.updatePrograms = function(req, res){
  console.log('new_programs:');

  var new_programs = req.body.programs;
  if(req.body.newprogram != ""){
    new_programs.push(req.body.newprogram);
  }

  console.dir(new_programs);

  res.send(200);
}

/*

/////// INSTAGRAM
var ig = require('instagram-node').instagram();

//import Instagram secrets from json file
var instagram_secrets = require('../secrets.json').instagram;

//set up secrets for Instagram module
ig.use({ client_id: instagram_secrets.client_id,
    client_secret: instagram_secrets.client_secret });
/////// END INSTAGRAM

/////// GLOBALS
var fetched_array; //container array for all fetched Instagram images

var tags = []; //array to hold tags for all programs (eg. xrio, xbeirut)
var tag_index = 0; //counter: current city fetching from Instagram by index in tags[] array
var total_found = 0; //counter: total images found from Instagram for given city
var current_program = ''; //pointer: current city fetching from Instagram

var interval_id; //global ID for the main interval for fetching from Instagram

var FETCH_TIME = 3000; //fetch every 3 seconds
var FETCHING_FROM_INSTAGRAM_BUSY_FLAG = false; //flag if in the middle of fetching
var DOWNLOADING_FROM_INSTAGRAM_BUSY_FLAG = false; //flag if in the middle of downloading
/////// END GLOBALS

/////// HELPER FUNCTIONS
function pushArray(arr, arr2) {
    arr.push.apply(arr, arr2);
}
/////// END HELPER FUNCTIONS

/////// INITIALIZE programs ARRAY
//pull in array of programs from json file
var programs = require('../programs.json');

/////// END INITIALIZE programs ARRAY

//Initializes downloading all undownloaded images from Instagram
function initImageDownloadCycle(){
    images.downloadAll();
}

//Initializes fetching all images from Instagram and puts them in the database
//to be later downloaded then uploaded to Flickr
function initInstagramFetchCycle(){

    FETCHING_FROM_INSTAGRAM_BUSY_FLAG = true;

    fetched_array = []; //clear out container array for all fetched Instagram images
    tag_index = 0;

    current_program = tags[tag_index].substring(1);

    //start to fetch from Instagram
    fetchAllProgramsFromInstagram();
}

var instagram_handler = function(err, medias, pagination, limit) {
    if(err){
        console.log(err);
    }else{
        console.log('\nFetched ' + medias.length + ' images'.cyan + ' from tag_index: ' + tag_index + ' = city: ' + tags[tag_index] + ' with limit: ' + limit + ' and pagination:');
        console.dir(pagination);

        for(var m = 0; m < medias.length; m++){
            //set city for all fetched items
            medias[m].city = tags[tag_index].substring(1);
        }

        pushArray(fetched_array, medias);

        if(pagination.next){
            console.log('\nPAGINATION.NEXT()\n');
            pagination.next(instagram_handler);

        //no pagination, move on to next city
        }else{

            if(tag_index >= (tags.length - 1) ){ //if just finished the last city
                //report out totals
                console.log('\n\nfetched_array.length: ' + fetched_array.length); //total in fetched_array
                var all_images = images.all(); //total in database

                //set and clear state flags
                FETCHING_FROM_INSTAGRAM_BUSY_FLAG = false;
                DOWNLOADING_FROM_INSTAGRAM_BUSY_FLAG = true;

                ////all images have been fetched, start to upsert all images recursively
                //call: upsert from controllers > images
                //callback: start to download image binaries from Instagram
                images.upsertArray(fetched_array, initImageDownloadCycle);

            }else{
                console.log('\n\nmoving on to the next city\n\n');
                tag_index++; //increment city

                //iterate
                ig.tag_media_recent(tags[tag_index], instagram_handler);
            }
        }
    }
};

function fetchAllProgramsFromInstagram(){
    var images_array = [];

    console.log('searching for tag: ' + tags[tag_index]);
    console.log('tag_index: ' + tag_index);
    console.dir(tags);

    ig.tag_media_recent(tags[tag_index], instagram_handler);

}

//initInstagramFetchCycle();

module.exports = function(app) {

    app.get('/fetch', function(req, res){
        initInstagramFetchCycle();
    });

    app.all ('/callback', function(req, res){
        console.log('\n\n\nreq:');
        console.dir(req);
        console.log('\n\n\nres:');
        console.dir(res);
    });

    /*
    app.post('/articles', authorization.requiresLogin, articles.create);
    app.get('/articles/:articleId', articles.show);
    app.put('/articles/:articleId', authorization.requiresLogin, hasAuthorization, articles.update);
    app.del('/articles/:articleId', authorization.requiresLogin, hasAuthorization, articles.destroy);

    // Finish with setting up the articleId param
    app.param('articleId', articles.article);
    */

//};
<|endoftext|>


<commit_before>var log = require('../helpers/logger');

module.exports = function(app) {
  const access = require('../helpers/access');
  const marky = require('marky-markdown');
  const Config = require('../models/config');

  // Add the user to whatever template
  app.use(function(req, res, next) {
    res.locals.fullYear = new Date().getFullYear();
    res.locals.url = req.originalUrl;
    res.locals.user = req.user;
    res.locals.privilege = access.privilege;
    res.locals.moment = require('moment');
    res.locals.version = app.get('version');
    res.locals.marked = function(str) {
      return marky(str);
    };
    res.locals.isActive = function(url, undefined) {
      var isCurrent =
        url instanceof RegExp
          ? url.test(req.originalUrl)
          : url == req.originalUrl;
      return isCurrent ? 'active' : undefined;
    };
    next();
  });

  // Get the configuration
  app.use(function(req, res, next) {
    Config.getConfig(function(err, config) {
      global.CONFIGURATION = res.locals.config = config || new Config();
      next();
    });
  });

  app.use(function(req, res, next) {
    const route =
      (req.originalUrl.startsWith('/games') &&
        !req.originalUrl.endsWith('privileges')) ||
      req.originalUrl.startsWith('/archive') ||
      req.originalUrl.startsWith('/releases');
    const contents =
      req.body && typeof req.body === 'object' && 'action' in req.body;
    // if fails cases, can just pass through w/ no change
    if (route && contents) {
      // Map RESTORE keyword to PATCH action, w/ isArchived flag change
      if (req.body.action === 'RESTORE') {
        req.body.isArchived = false;
        req.method = 'PATCH';
      }
      // Set POST to PATCH / DELETE based on value in form
      else {
        req.method = req.body.action;
      }
    }
    next();
  });

  // Site pages
  app.use('/', require('./home'));
  app.use('/embed', require('./embed'));
  app.use('/docs', access.isAuthenticated, require('./docs'));
  app.use('/games/add', access.isEditor, require('./games/add'));
  app.use('/games/search', access.isAuthenticated, require('./games/search'));
  app.use('/groups/add', access.isAdmin, require('./groups/add'));
  app.use('/games', access.isAuthenticated, require('./games/index'));
  app.use('/releases', access.isEditor, require('./releases/release'));
  app.use('/archive', access.isEditor, require('./games/index'));
  app.use('/groups/group', access.isAuthenticated, require('./groups/group'));
  app.use('/groups/search', access.isAdmin, require('./groups/search'));
  app.use('/groups', access.isAdmin, require('./groups/index'));
  app.use('/users/search', require('./users/search'));
  app.use('/users/add', access.isAdmin, require('./users/add'));
  app.use('/users', access.isAdmin, require('./users/index'));
  app.use('/configuration', access.isAdmin, require('./configuration'));

  // RESTful service for releases
  app.use('/api/release', require('./api/release'));
  app.use('/api/releases', require('./api/releases'));
  app.use('/api/games', require('./api/games'));
  // Authentication Pages
  app.use('/login', access.isAnonymous, require('./login'));
  app.use('/logout', access.isAuthenticated, require('./logout'));
  // app.use('/register', access.isAnonymous, require('./register'));
  app.use('/forgot', access.isAnonymous, require('./forgot'));
  app.use('/reset', access.isAnonymous, require('./reset'));
  app.use('/profile', access.isAuthenticated, require('./profile'));
  app.use('/password', access.isAuthenticated, require('./password'));

  // All other pages default to 404
  app.all('*', function(req, res) {
    res.status(404).render('404');
  });

  // Setup the error handler. Note that this code is declared AFTER all of the other routes as per the recommendation
  // here: https://stackoverflow.com/a/32671421/10200077
  app.use(function(err, req, res, next) {
    // log the error occurring
    log.error('Uncaught error');
    log.error(err);

    // only show the stack when we're not in production
    const showStack = process.env.NODE_ENV !== 'production';

    // if it's an ajax request, respond with JSON
    if (req.xhr) {
      const response = {
        success: false,
        message: err.toString()
      };

      if (showStack) {
        response.stack = err.stack;
      }

      res.status(500).send(response);
    } else {
      // Otherwise, render our 500 view which renders the same info, but as HTML
      res.status(500).render('500', { err, showStack });
    }
  });
};
<commit_msg>removed commented out route<commit_after>var log = require('../helpers/logger');

module.exports = function(app) {
  const access = require('../helpers/access');
  const marky = require('marky-markdown');
  const Config = require('../models/config');

  // Add the user to whatever template
  app.use(function(req, res, next) {
    res.locals.fullYear = new Date().getFullYear();
    res.locals.url = req.originalUrl;
    res.locals.user = req.user;
    res.locals.privilege = access.privilege;
    res.locals.moment = require('moment');
    res.locals.version = app.get('version');
    res.locals.marked = function(str) {
      return marky(str);
    };
    res.locals.isActive = function(url, undefined) {
      var isCurrent =
        url instanceof RegExp
          ? url.test(req.originalUrl)
          : url == req.originalUrl;
      return isCurrent ? 'active' : undefined;
    };
    next();
  });

  // Get the configuration
  app.use(function(req, res, next) {
    Config.getConfig(function(err, config) {
      global.CONFIGURATION = res.locals.config = config || new Config();
      next();
    });
  });

  app.use(function(req, res, next) {
    const route =
      (req.originalUrl.startsWith('/games') &&
        !req.originalUrl.endsWith('privileges')) ||
      req.originalUrl.startsWith('/archive') ||
      req.originalUrl.startsWith('/releases');
    const contents =
      req.body && typeof req.body === 'object' && 'action' in req.body;
    // if fails cases, can just pass through w/ no change
    if (route && contents) {
      // Map RESTORE keyword to PATCH action, w/ isArchived flag change
      if (req.body.action === 'RESTORE') {
        req.body.isArchived = false;
        req.method = 'PATCH';
      }
      // Set POST to PATCH / DELETE based on value in form
      else {
        req.method = req.body.action;
      }
    }
    next();
  });

  // Site pages
  app.use('/', require('./home'));
  app.use('/embed', require('./embed'));
  app.use('/docs', access.isAuthenticated, require('./docs'));
  app.use('/games/add', access.isEditor, require('./games/add'));
  app.use('/games/search', access.isAuthenticated, require('./games/search'));
  app.use('/groups/add', access.isAdmin, require('./groups/add'));
  app.use('/games', access.isAuthenticated, require('./games/index'));
  app.use('/releases', access.isEditor, require('./releases/release'));
  app.use('/archive', access.isEditor, require('./games/index'));
  app.use('/groups/group', access.isAuthenticated, require('./groups/group'));
  app.use('/groups/search', access.isAdmin, require('./groups/search'));
  app.use('/groups', access.isAdmin, require('./groups/index'));
  app.use('/users/search', require('./users/search'));
  app.use('/users/add', access.isAdmin, require('./users/add'));
  app.use('/users', access.isAdmin, require('./users/index'));
  app.use('/configuration', access.isAdmin, require('./configuration'));

  // RESTful service for releases
  app.use('/api/release', require('./api/release'));
  app.use('/api/releases', require('./api/releases'));
  app.use('/api/games', require('./api/games'));
  // Authentication Pages
  app.use('/login', access.isAnonymous, require('./login'));
  app.use('/logout', access.isAuthenticated, require('./logout'));
  app.use('/forgot', access.isAnonymous, require('./forgot'));
  app.use('/reset', access.isAnonymous, require('./reset'));
  app.use('/profile', access.isAuthenticated, require('./profile'));
  app.use('/password', access.isAuthenticated, require('./password'));

  // All other pages default to 404
  app.all('*', function(req, res) {
    res.status(404).render('404');
  });

  // Setup the error handler. Note that this code is declared AFTER all of the other routes as per the recommendation
  // here: https://stackoverflow.com/a/32671421/10200077
  app.use(function(err, req, res, next) {
    // log the error occurring
    log.error('Uncaught error');
    log.error(err);

    // only show the stack when we're not in production
    const showStack = process.env.NODE_ENV !== 'production';

    // if it's an ajax request, respond with JSON
    if (req.xhr) {
      const response = {
        success: false,
        message: err.toString()
      };

      if (showStack) {
        response.stack = err.stack;
      }

      res.status(500).send(response);
    } else {
      // Otherwise, render our 500 view which renders the same info, but as HTML
      res.status(500).render('500', { err, showStack });
    }
  });
};
<|endoftext|>


<commit_before>/**
 * Event Dispatcher
 *
 * Events:
 *     * moveMade returns number removed
 *     * gameOver
 *     * preGameOver
 *     * postGameOver
 *     * newGame
 *     * preNewGame
 *
 */
dispatcher = _.extend({}, Backbone.Events);

var SliderGameCollection = MatrixCollection.extend({
    modelClass: CellModel,
    generateRandomMatrix: function() {
        var nums = _.shuffle(_.range(0,this.getHeight()*this.getWidth()));
        var mat = new Array(this.getHeight());
        for(var i=0; i<this.getHeight(); i++) {
            mat[i] = new Array(this.getWidth());
            for(var j=0; j<this.getWidth(); j++) {
                var num = nums[i*this.getWidth() + j]
                if(num != 0) {
                    mat[i][j] = new this.modelClass({
                        row: i, col: j,
                        value: num
                    });
                } else {
                    mat[i][j] = null;
                }
            }
        }
        this.models = mat;
    },
	generateOrderedMatrix: function() {
		var num = 1;
        var mat = new Array(this.getHeight());
        for(var i=0; i<this.getHeight(); i++) {
            mat[i] = new Array(this.getWidth());
            for(var j=0; j<this.getWidth(); j++) {
                if(num != this.getHeight()*this.getWidth()) {
                    mat[i][j] = new this.modelClass({
                        row: i, col: j,
                        value: num
                    });
                } else {
                    mat[i][j] = null;
                }
				num++;
            }
        }
        this.models = mat;
	}
});

var NewGameBtnView = Backbone.View.extend({
    events: {
        'click': 'btnClicked'
    },
    btnClicked: function(e) {
        this.options.dispatcher.trigger('preNewGame');
    }
});

var SliderGameApp = Backbone.View.extend({
    rows: 4, cols: 4,
    initialize: function(options) {
		var that = this;

        this.collection = new SliderGameCollection({height: this.rows, width: this.cols})
        this.collection.generateRandomMatrix();

        this.display = new CanvasDisplayView({
			el: this.el,
            collection: this.collection,
			dispatcher: this.options.dispatcher,
            rows: this.rows, cols: this.cols,
			drawCellCallback: _.bind(this.drawCell, this),
        });

		$(document).keydown(function(e) {return that.arrowHandler(e);})

		this.listenTo(this.options.dispatcher, 'preNewGame', this.newGameHandler);
		this.listenTo(this.options.dispatcher, 'cellClicked', this.clickHandler);
    },
	arrowHandler: function(e) {
		// check if key pressed is an arrow key
		if(_.contains([37, 38, 39, 40], e.keyCode)) {
			var emptyAddr = this.collection.findFirstEmptyCell().addr;

			switch(e.keyCode) {
			// left
			case 37:
				cell = this.collection.at(emptyAddr[0], emptyAddr[1]+1);
				if(cell !== undefined) {
					this.shiftHorizontal(emptyAddr[0], cell.get('col'), emptyAddr[1]);
				}
				break;
			// up
			case 38:
				cell = this.collection.at(emptyAddr[0]+1, emptyAddr[1]);
				if(cell !== undefined) {
					this.shiftVertical(emptyAddr[1], cell.get('row'), emptyAddr[0]);
				}
				break;
			// right
			case 39:
				cell = this.collection.at(emptyAddr[0], emptyAddr[1]-1);
				if(cell !== undefined) {
					this.shiftHorizontal(emptyAddr[0], cell.get('col'), emptyAddr[1]);
				}
				break;
			// down
			case 40:
				cell = this.collection.at(emptyAddr[0]-1, emptyAddr[1]);
				if(cell !== undefined) {
					this.shiftVertical(emptyAddr[1], cell.get('row'), emptyAddr[0]);
				}
				break;
			}

			this.display.draw();
		}
	},
	shiftCell: function(cell) {
		var emptyAddr = this.collection.findFirstEmptyCell().addr;
		if(cell.get('row') == emptyAddr[0]) {
			this.shiftHorizontal(cell.get('row'), cell.get('col'), emptyAddr[1]);
		} else if(cell.get('col') == emptyAddr[1]) {
			this.shiftVertical(cell.get('col'), cell.get('row'), emptyAddr[0]);
		}
	},
	shiftHorizontal: function(idx, targetIdx, emptyIdx) {
		var sign = targetIdx < emptyIdx ? -1 : 1;

		for(var i=0; i<Math.abs(targetIdx-emptyIdx); i++) {
			iIdx = emptyIdx+i*sign;
			var tmp = this.collection.at(idx, iIdx+sign);
			tmp.set('col', iIdx);
			this.collection.setAddr(idx, iIdx, tmp);
			this.collection.setAddr(idx, iIdx+sign, null);
		}
	},
	shiftVertical: function(idx, targetIdx, emptyIdx) {
		var sign = targetIdx < emptyIdx ? -1 : 1;

		for(var i=0; i<Math.abs(targetIdx-emptyIdx); i++) {
			iIdx = emptyIdx+i*sign;
			var tmp = this.collection.at(iIdx+sign, idx);
			tmp.set('row', iIdx);
			this.collection.setAddr(iIdx, idx, tmp);
			this.collection.setAddr(iIdx+sign, idx, null);
		}
	},
	clickHandler: function(click) {
		var cell = this.collection.at(click.row, click.col);
		if(cell != null) {
			this.shiftCell(cell);
		}
		this.display.draw();
	},
	newGameHandler: function() {
		this.collection.generateRandomMatrix();
		this.display._initializeCanvas();
		this.display.draw();

		this.options.dispatcher.trigger('newGame');
	},
	drawCell: function(x, y, cell, d) {
		d.$el.drawRect({
			fillStyle: '#FFF',
			x: x+d._CELL_PADDING, y: y+d._CELL_PADDING,
            width: d._CELL_WIDTH, height: d._CELL_HEIGHT,
            fromCenter: false
		});
		d.$el.drawText({
			fillStyle: "#9cf",
			strokeStyle: "#25a",
			strokeWidth: 2,
			x: x+d._calculateCellWidth()/2, y: y+d._calculateCellHeight()/2,
			fontSize: d._CELL_HEIGHT/2,
			fontFamily: "Verdana, sans-serif",
			fromCenter: true,
			text: cell.get('value').toString()
		});
	}
});

game = new SliderGameApp({el: '#game_canvas', dispatcher: dispatcher});
newGameBtnView = new NewGameBtnView({el: '.new-game', dispatcher: dispatcher});<commit_msg>added solvable game generator, game complete checker<commit_after>/**
 * Event Dispatcher
 *
 * Events:
 *     * moveMade returns number removed
 *     * gameOver
 *     * preGameOver
 *     * postGameOver
 *     * newGame
 *     * preNewGame
 *
 */
dispatcher = _.extend({}, Backbone.Events);

var SliderGameCollection = MatrixCollection.extend({
    modelClass: CellModel,
	shiftCell: function(cell) {
		var emptyAddr = this.findFirstEmptyCell().addr;
		if(cell.get('row') == emptyAddr[0]) {
			this.shiftHorizontal(cell.get('row'), cell.get('col'), emptyAddr[1]);
		} else if(cell.get('col') == emptyAddr[1]) {
			this.shiftVertical(cell.get('col'), cell.get('row'), emptyAddr[0]);
		}
	},
	shiftHorizontal: function(idx, targetIdx, emptyIdx) {
		var sign = targetIdx < emptyIdx ? -1 : 1;

		for(var i=0; i<Math.abs(targetIdx-emptyIdx); i++) {
			iIdx = emptyIdx+i*sign;
			var tmp = this.at(idx, iIdx+sign);
			tmp.set('col', iIdx);
			this.setAddr(idx, iIdx, tmp);
			this.setAddr(idx, iIdx+sign, null);
		}
	},
	shiftVertical: function(idx, targetIdx, emptyIdx) {
		var sign = targetIdx < emptyIdx ? -1 : 1;

		for(var i=0; i<Math.abs(targetIdx-emptyIdx); i++) {
			iIdx = emptyIdx+i*sign;
			var tmp = this.at(iIdx+sign, idx);
			tmp.set('row', iIdx);
			this.setAddr(iIdx, idx, tmp);
			this.setAddr(iIdx+sign, idx, null);
		}
	},
	shiftEmptyUp: function() {
		var emptyAddr = this.findFirstEmptyCell().addr;
		var cell = this.at(emptyAddr[0]-1, emptyAddr[1]);
		if(cell !== undefined) {
			this.shiftVertical(emptyAddr[1], cell.get('row'), emptyAddr[0]);
		}
	},
	shiftEmptyDown: function() {
		var emptyAddr = this.findFirstEmptyCell().addr;
		var cell = this.at(emptyAddr[0]+1, emptyAddr[1]);
		if(cell !== undefined) {
			this.shiftVertical(emptyAddr[1], cell.get('row'), emptyAddr[0]);
		}
	},
	shiftEmptyLeft: function() {
		var emptyAddr = this.findFirstEmptyCell().addr;
		var cell = this.at(emptyAddr[0], emptyAddr[1]-1);
		if(cell !== undefined) {
			this.shiftHorizontal(emptyAddr[0], cell.get('col'), emptyAddr[1]);
		}
	},
	shiftEmptyRight: function() {
		var emptyAddr = this.findFirstEmptyCell().addr;
		var cell = this.at(emptyAddr[0], emptyAddr[1]+1);
		if(cell !== undefined) {
			this.shiftHorizontal(emptyAddr[0], cell.get('col'), emptyAddr[1]);
		}
	},

    generateRandomMatrix: function() {
        var nums = _.shuffle(_.range(0,this.getHeight()*this.getWidth()));
        var mat = new Array(this.getHeight());
        for(var i=0; i<this.getHeight(); i++) {
            mat[i] = new Array(this.getWidth());
            for(var j=0; j<this.getWidth(); j++) {
                var num = nums[i*this.getWidth() + j]
                if(num != 0) {
                    mat[i][j] = new this.modelClass({
                        row: i, col: j,
                        value: num
                    });
                } else {
                    mat[i][j] = null;
                }
            }
        }
        this.models = mat;
    },
	generateOrderedMatrix: function() {
		var num = 1;
        var mat = new Array(this.getHeight());
        for(var i=0; i<this.getHeight(); i++) {
            mat[i] = new Array(this.getWidth());
            for(var j=0; j<this.getWidth(); j++) {
                if(num != this.getHeight()*this.getWidth()) {
                    mat[i][j] = new this.modelClass({
                        row: i, col: j,
                        value: num
                    });
                } else {
                    mat[i][j] = null;
                }
				num++;
            }
        }
        this.models = mat;
	},
	generateSolvableMatrix: function() {
		var that = this;
		this.generateOrderedMatrix();

		// move empty cell to middle(ish)
		this.shiftCell(this.at(this.getHeight()-1, Math.round(this.getWidth()/2)));
		this.shiftCell(this.at(Math.round(this.getHeight()/2), Math.round(this.getWidth()/2)));

		// do 250 moves
		_.times(250, function(n) {
			var rand = _.random(0, 3);
			switch(rand) {
			case 0:
				that.shiftEmptyUp();
				break;
			case 1:
				that.shiftEmptyDown();
				break;
			case 2:
				that.shiftEmptyLeft();
				break;
			case 3:
				that.shiftEmptyRight();
				break;
			}
		});
	}
});

var NewGameBtnView = Backbone.View.extend({
    events: {
        'click': 'btnClicked'
    },
    btnClicked: function(e) {
        this.options.dispatcher.trigger('preNewGame');
    }
});

var SliderGameApp = Backbone.View.extend({
    rows: 4, cols: 4,
    initialize: function(options) {
		var that = this;

        this.collection = new SliderGameCollection({height: this.rows, width: this.cols})
        this.collection.generateSolvableMatrix();

        this.display = new CanvasDisplayView({
			el: this.el,
            collection: this.collection,
			dispatcher: this.options.dispatcher,
            rows: this.rows, cols: this.cols,
			drawCellCallback: _.bind(this.drawCell, this),
        });

		$(document).keydown(function(e) {return that.arrowHandler(e);})

		this.listenTo(this.options.dispatcher, 'preNewGame', this.newGameHandler);
		this.listenTo(this.options.dispatcher, 'cellClicked', this.clickHandler);
		this.listenTo(this.options.dispatcher, 'moveMade', this.moveMadeHandler);
    },
	arrowHandler: function(e) {
		// check if key pressed is an arrow key
		if(_.contains([37, 38, 39, 40], e.keyCode)) {
			switch(e.keyCode) {
			// left
			case 37:
				this.collection.shiftEmptyRight();
				break;
			// up
			case 38:
				this.collection.shiftEmptyDown();
				break;
			// right
			case 39:
				this.collection.shiftEmptyLeft();
				break;
			// down
			case 40:
				this.collection.shiftEmptyUp();
				break;
			}

			this.display.draw();
			this.options.dispatcher.trigger('moveMade');
		}
	},
	clickHandler: function(click) {
		var cell = this.collection.at(click.row, click.col);
		if(cell != null) {
			this.collection.shiftCell(cell);
			this.display.draw();
			this.options.dispatcher.trigger('moveMade');
		}
	},
	checkGameComplete: function() {
		var that = this;
		var n = 1;
		var matches = true;
		// bails out early if finds non-matching cell
		this.collection.find(function(cell) {
			if(n < that.rows*that.cols) {
				if(cell == null) {
					matches = false;
					return true;
				} else if(n != cell.get('value')) {
					matches = false;
					return true;
				}
			}
			n++;
		});
		return matches;
	},
	moveMadeHandler: function() {
		if(this.checkGameComplete()) {
			alert('Game Complete!');
		}
	},
	newGameHandler: function() {
		this.collection.generateSolvableMatrix();
		this.display._initializeCanvas();
		this.display.draw();

		this.options.dispatcher.trigger('newGame');
	},
	drawCell: function(x, y, cell, d) {
		d.$el.drawRect({
			fillStyle: '#FFF',
			x: x+d._CELL_PADDING, y: y+d._CELL_PADDING,
            width: d._CELL_WIDTH, height: d._CELL_HEIGHT,
            fromCenter: false
		});
		d.$el.drawText({
			fillStyle: "#9cf",
			strokeStyle: "#25a",
			strokeWidth: 2,
			x: x+d._calculateCellWidth()/2, y: y+d._calculateCellHeight()/2,
			fontSize: d._CELL_HEIGHT/2,
			fontFamily: "Verdana, sans-serif",
			fromCenter: true,
			text: cell.get('value').toString()
		});
	}
});

game = new SliderGameApp({el: '#game_canvas', dispatcher: dispatcher});
newGameBtnView = new NewGameBtnView({el: '.new-game', dispatcher: dispatcher});<|endoftext|>


<commit_before>(function () {
  'use strict';

  // Check to make sure service workers are supported in the current browser,
  // and that the current page is accessed from a secure origin. Using a
  // service worker from an insecure origin will trigger JS console errors. See
  // http://www.chromium.org/Home/chromium-security/prefer-secure-origins-for-powerful-new-features
  if ('serviceWorker' in navigator &&
      (window.location.protocol === 'https:' ||
       window.location.hostname === 'localhost' ||
       window.location.hostname.indexOf('127.') === 0)) {
    navigator.serviceWorker.register('/service-worker.js', {
      scope: './'
    }).then(function (registration) {
      // Check to see if there's an updated version of service-worker.js with
      // new files to cache:
      // https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#service-worker-registration-update-method
      if (typeof registration.update === 'function') {
        registration.update();
      }

      // updatefound is fired if service-worker.js changes.
      registration.onupdatefound = function () {
        // updatefound is also fired the very first time the SW is installed,
        // and there's no need to prompt for a reload at that point.
        // So check here to see if the page is already controlled,
        // i.e. whether there's an existing service worker.
        if (navigator.serviceWorker.controller) {
          // The updatefound event implies that registration.installing is set:
          // https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#service-worker-container-updatefound-event
          var installingWorker = registration.installing;

          installingWorker.onstatechange = function () {
            switch (installingWorker.state) {
              case 'installed':
                // At this point, the old content will have been purged and the
                // fresh content will have been added to the cache.
                // It's the perfect time to display a "New content is
                // available; please refresh." message in the page's interface.
                break;

              case 'redundant':
                throw new Error(
                  'The installing service worker became redundant.'
                );
            }
          };
        }
      };
    }).catch(function (e) {
      console.error('Error during service worker registration:', e);
    });
  }
})();
<commit_msg>Fix lint error<commit_after>(function () {
  'use strict';

  // Check to make sure service workers are supported in the current browser,
  // and that the current page is accessed from a secure origin. Using a
  // service worker from an insecure origin will trigger JS console errors. See
  // http://www.chromium.org/Home/chromium-security/prefer-secure-origins-for-powerful-new-features
  if ('serviceWorker' in navigator &&
      (window.location.protocol === 'https:' ||
       window.location.hostname === 'localhost' ||
       window.location.hostname.indexOf('127.') === 0)) {
    navigator.serviceWorker.register('/service-worker.js', {
      scope: './'
    }).then(function (registration) {
      // Check to see if there's an updated version of service-worker.js with
      // new files to cache:
      // https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#service-worker-registration-update-method
      if (typeof registration.update === 'function') {
        registration.update();
      }

      // updatefound is fired if service-worker.js changes.
      registration.onupdatefound = function () {
        // updatefound is also fired the very first time the SW is installed,
        // and there's no need to prompt for a reload at that point.
        // So check here to see if the page is already controlled,
        // i.e. whether there's an existing service worker.
        if (navigator.serviceWorker.controller) {
          // The updatefound event implies that registration.installing is set:
          // https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#service-worker-container-updatefound-event
          var installingWorker = registration.installing;

          installingWorker.onstatechange = function () {
            switch (installingWorker.state) {
            case 'installed':
              // At this point, the old content will have been purged and the
              // fresh content will have been added to the cache.
              // It's the perfect time to display a "New content is
              // available; please refresh." message in the page's interface.
              break;

            case 'redundant':
              throw new Error(
                'The installing service worker became redundant.'
              );
            }
          };
        }
      };
    }).catch(function (e) {
      console.error('Error during service worker registration:', e);
    });
  }
})();
<|endoftext|>


<commit_before>/*global require*/
'use strict';

require.config({
  shim: {
      underscore: {
        exports: '_'
      },
      backbone: {
        deps: [
          'underscore',
          'jquery'
        ],
        exports: 'Backbone'
      },
      jqueryui: {
        deps: [ 'jquery' ],
        exports: 'jqueryui'
      },
      bootstrap: {
        deps: ['jquery'],
        exports: 'jquery'
      },
      qtip: {
        deps: ['jquery'],
        exports: 'qtip',
      },
    },
    paths: {
      jquery: '../bower_components/jquery/jquery',
      jqueryui: '../bower_components/jquery-ui/ui/minified/jquery-ui.min',
      backbone: '../bower_components/backbone/backbone',
      underscore: '../bower_components/underscore/underscore',
      handlebars: '../bower_components/handlebars/handlebars',
      qtip: '../bower_components/qtip2/jquery.qtip.min',

      bootstrap: 'vendor/bootstrap',
      dragscroll: 'vendor/jquery.scrollview',

      text: '../bower_components/requirejs-text/text',
      templates: '../templates',
    }
});

require([
  'backbone',
  'models/Game',
  'models/Gold',
  'collections/Elements',
  'views/index',
  'resources/index',
  'handlebars',
  'jqueryui',
  'bootstrap',
  'qtip',
], function (
    Backbone,
    GameModel,
    Gold,
    Elements,
    Views,
    Resources
) {
  console.log('TAG2013!');
  var Elements = new Elements(Resources.elements);
	Elements.each(function(item){
		item.set('status', 'unlocked');
		item.set('count', 5);
			})
  //var Achievements = new Views.Achievements({collection: Resources.achievements});
  //var Recipes = new Views.Recipes({collection: Resources.recipes});

  var Game = new Views.Game({
    collection: Elements,
    model: new GameModel(),
    gold: new Gold(),
  });

  Backbone.history.start();

  //ry debugging
  //Game.table.slots.add(Game.collection.get('earth'));
  //Game.table.slots.add(Game.collection.get('fire'));

  //Game.table.craft();
});
<commit_msg>reverted main.js<commit_after>/*global require*/
'use strict';

require.config({
  shim: {
      underscore: {
        exports: '_'
      },
      backbone: {
        deps: [
          'underscore',
          'jquery'
        ],
        exports: 'Backbone'
      },
      jqueryui: {
        deps: [ 'jquery' ],
        exports: 'jqueryui'
      },
      bootstrap: {
        deps: ['jquery'],
        exports: 'jquery'
      },
      qtip: {
        deps: ['jquery'],
        exports: 'qtip',
      },
    },
    paths: {
      jquery: '../bower_components/jquery/jquery',
      jqueryui: '../bower_components/jquery-ui/ui/minified/jquery-ui.min',
      backbone: '../bower_components/backbone/backbone',
      underscore: '../bower_components/underscore/underscore',
      handlebars: '../bower_components/handlebars/handlebars',
      qtip: '../bower_components/qtip2/jquery.qtip.min',

      bootstrap: 'vendor/bootstrap',
      dragscroll: 'vendor/jquery.scrollview',

      text: '../bower_components/requirejs-text/text',
      templates: '../templates',
    }
});

require([
  'backbone',
  'models/Game',
  'models/Gold',
  'collections/Elements',
  'views/index',
  'resources/index',
  'handlebars',
  'jqueryui',
  'bootstrap',
  'qtip',
], function (
    Backbone,
    GameModel,
    Gold,
    Elements,
    Views,
    Resources
) {
  console.log('TAG2013!');
  var Elements = new Elements(Resources.elements);
  //var Achievements = new Views.Achievements({collection: Resources.achievements});
  //var Recipes = new Views.Recipes({collection: Resources.recipes});

  var Game = new Views.Game({
    collection: Elements,
    model: new GameModel(),
    gold: new Gold(),
  });

  Backbone.history.start();

  //ry debugging
  //Game.table.slots.add(Game.collection.get('earth'));
  //Game.table.slots.add(Game.collection.get('fire'));

  //Game.table.craft();
});
<|endoftext|>


<commit_before>'use strict';

window.Rplus.ready(function () {

  var Rplus = window.Rplus;

  Rplus.hasClass = function ($ele, $className) {
    if ($ele.classList) {
      return $ele.classList.contains($className);
    } else {
      return new RegExp('(^| )' + $className + '( |$)', 'gi').test($ele.className);
    }
  };

  Rplus.removeClass = function ($el, $className) {
    var _classReg = new RegExp('\\b' + $className + '\\b', 'g');
    $el.className = $el.className.replace(_classReg, '');
  };

  // load font: limited char
  (function () {
    var googleFontSource = document.getElementById('js-google-font').firstChild.data.match(/href="(.+?)"/)[1];
    var googleFontUsed = document.querySelectorAll('.wf-inactive')[0];
    var googleFontText = (googleFontUsed.textContent || googleFontUsed.innerText).trim();
    var googleFontURL = googleFontSource + '&text=' + encodeURIComponent(googleFontText);

    var shwoWFText = function () {
      Rplus.removeClass(googleFontUsed, 'wf-inactive');
    };

    // for web font load slowly, it'll remove the .wf-inactive class for showing the text
    var webfontLoaderTimeout;

    (function () {
      webfontLoaderTimeout = setTimeout(shwoWFText, 3000);
    })();

    var _link = document.createElement('link');
    _link.rel = 'stylesheet';
    _link.href = googleFontURL;
    _link.addEventListener('load', function () {
      shwoWFText();
      clearTimeout(webfontLoaderTimeout);
    });
    Rplus.ele.body.insertBefore(_link, Rplus.ele.body.childNodes[0]);
  })();

  // init svg icons
  (function () {
    if (Rplus.hasClass(Rplus.ele.html, 'inlinesvg')) {
      Rplus.injectInline({
        tag: 'img',
        src: './images/inject-svg/svgstore.svg'
      });
    } else {
      Rplus.injectInline( Rplus.getFBInfo(document.getElementById('js-icons-fallback')) );
    }
  })();

});
<commit_msg>若無 cache，在 document ready 後進行 main style 的 cache<commit_after>'use strict';

window.Rplus.ready(function () {

  var Rplus = window.Rplus;

  Rplus.hasClass = function ($ele, $className) {
    if ($ele.classList) {
      return $ele.classList.contains($className);
    } else {
      return new RegExp('(^| )' + $className + '( |$)', 'gi').test($ele.className);
    }
  };

  Rplus.removeClass = function ($el, $className) {
    var _classReg = new RegExp('\\b' + $className + '\\b', 'g');
    $el.className = $el.className.replace(_classReg, '');
  };

  // load font: limited char
  (function () {
    var googleFontSource = document.getElementById('js-google-font').firstChild.data.match(/href="(.+?)"/)[1];
    var googleFontUsed = document.querySelectorAll('.wf-inactive')[0];
    var googleFontText = (googleFontUsed.textContent || googleFontUsed.innerText).trim();
    var googleFontURL = googleFontSource + '&text=' + encodeURIComponent(googleFontText);

    var shwoWFText = function () {
      Rplus.removeClass(googleFontUsed, 'wf-inactive');
    };

    // for web font load slowly, it'll remove the .wf-inactive class for showing the text
    var webfontLoaderTimeout;

    (function () {
      webfontLoaderTimeout = setTimeout(shwoWFText, 3000);
    })();

    var _link = document.createElement('link');
    _link.rel = 'stylesheet';
    _link.href = googleFontURL;
    _link.addEventListener('load', function () {
      shwoWFText();
      clearTimeout(webfontLoaderTimeout);
    });
    Rplus.ele.body.insertBefore(_link, Rplus.ele.body.childNodes[0]);
  })();

  // init svg icons
  (function () {
    if (Rplus.hasClass(Rplus.ele.html, 'inlinesvg')) {
      Rplus.injectInline({
        tag: 'img',
        src: './images/inject-svg/svgstore.svg'
      });
    } else {
      Rplus.injectInline( Rplus.getFBInfo(document.getElementById('js-icons-fallback')) );
    }
  })();

  // cache main.css if no-cache
  (function () {
    if (!Rplus.hasCache) {
      Rplus.injectInline(Rplus.getFBInfo(document.getElementById('js-main-style')), {cacheOnly: true});
    }
  })();

});
<|endoftext|>


<commit_before>$(function() {
    var unreadCount = 0;
    var $chatWindow = $('#chat');
    var $roomList = $('#room_list');
    var roomList = [];

    var websocket = scheme + "://" + location.hostname + ":" + port + "/ws";

    if (window.WebSocket) {
        ws = new WebSocket(websocket);
    }
    else if (window.MozWebSocket) {
        ws = MozWebSocket(websocket);
    }
    else {
        console.log('WebSocket Not Supported');
        return;
    }

    function updateChatWindow() {
        $(window).scrollTop($(window).height());

        // Prevent the window from getting too full and slowing everything down.
        if ($chatWindow.children().length > 200) {
            $chatWindow.children()[0].remove();
            $chatWindow.children()[1].remove(); //We will removed 2 items to preserve odd row highlighting
        }

        unreadCount++;
        updateTitle();
    }

    function addMessageToChat(msg) {
        var text = msg.data;
        text = linkify(text);

        // TODO: Move into ChatWindow class, add different categories of messages: info, say, event, etc.
        var date = new Date();
        var time = date.toLocaleTimeString();

        if (($chatWindow.children().length % 2) == 1)
        {
            $chatWindow.append("
[" + time + "] " +  msg.username + ": " + text + "
");
        }
        else
        {
            $chatWindow.append("
[" + time + "] " +  msg.username + ": " + text + "
");
        }

        updateChatWindow();
    }

    function addEventToChat(msg) {
        $chatWindow.append("
" + msg + "
");
        updateChatWindow();
    }

    function updateTitle() {
        var title = "MockingJay";
        if (unreadCount > 0) {
            title += " (" + unreadCount + ")";
        }

        document.title = title;
    }

    window.onbeforeunload = function(e) {
        addEventToChat('Bye bye...');

        msg = {
            type: 'EVENT',
            event: 'SIGN_OFF',
            username: username
        }

        ws.send(JSON.stringify(msg));
        ws.close(1000, username + " left the chat..");

        if(!e) e = window.event;
        e.stopPropagation();
        e.preventDefault();
    };

    window.onmousemove = function(e) {
        unreadCount = 0;
        updateTitle();
    };

    ws.onmessage = function (evt) {
        msg = JSON.parse(evt.data);
        console.log(msg)
        if (msg.type == "EVENT") {
            if (msg.event == "FIRST_SIGN_ON") {
                username = msg.username;
                addEventToChat("Welcome, " + username + " if you would like to change your name type '/nick [username]' into the chat box below.");
            } else if (msg.event == "SIGN_ON") {
                addEventToChat(msg.username + " signed on");
            } else if (msg.event == "SIGN_OFF") {
                addEventToChat(msg.username + " signed off");
            } else  if (msg.event == "NAME_CHANGED") {
                if (msg.username == username) {
                    username = msg.new_name;
                    window.localStorage['username'] = username;
                }
                addEventToChat(msg.username + " changed name to " + msg.new_name);
            }
        } else if (msg.type == "INFO") {
            if (msg.info == "ROOM_LIST") {
                roomList = msg.data
                $roomList.empty()
                for(var i = 0;i<roomList.length;i++) {
                    $roomList.append("
"+ roomList[i] + "
");
                }
            }
        } else {
            addMessageToChat(msg);
        }
    };

    ws.onopen = function() {
        msg = {
            type: 'EVENT',
            event: 'FIRST_SIGN_ON'
        };

        if (window.localStorage['username']) {
            msg.username = window.localStorage['username'];
        }

        ws.send(JSON.stringify(msg));
    };

    ws.onclose = function(evt) {
        addEventToChat('Connection closed by server: ' + evt.code + ' \"' + evt.reason);
    };

    function sendMessage() {
        var $message = $('#message');
        var value = $message.val();

        // TODO: move this into a parser class
        if (value[0] == '/') {
            if(value.substring(0,5) == '/nick') {
                var newUsername = value.substring(6,value.length);
                ws.send(JSON.stringify({username: username, type: "CMD", command: "NAME_CHANGE", new_name: newUsername}))
                // TODO: save this to local storage as a preference
            }
        } else {
            ws.send(JSON.stringify({username: username, type: "MSG", data: value}))
        }

        $message.val("");
        return false;
    }

    $('#send').click(function() {
        return sendMessage();
    });

    $('#message').keypress(function(e) {
        unreadCount = 0;
        updateTitle();
        if (e.which == 13) {
            return sendMessage();
        }
    });

});
<commit_msg>Chime when someone says your name<commit_after>$(function() {
    var unreadCount = 0;
    var $chatWindow = $('#chat');
    var $roomList = $('#room_list');
    var roomList = [];

    var websocket = scheme + "://" + location.hostname + ":" + port + "/ws";

    //this bit can probably be moved to html
    var chime = document.createElement('audio');
    chime.setAttribute('src', 'data:audio/wav;base64,UklGRi4IAABXQVZFZm10IBAAAAABAAEAESsAABErAAABAAgAZGF0YakHAACAgIGBgYKEh4qLjIyNjY2LioqJh4aGio2QkZGRkI6Lh4B3cXJ0dnp/g4aHiImDdm1pZmVnbHR6fYGLlZuhpKOgnp2dnJGCdWldU0pEPjgyOktaaHR+homLjZWYjn9wYFJNSUZCPkNadYuitMXU2+Dn7uXRv7KnoaCkqKagpLO8wsfJyMG7uLetlYBzaF5ZVFNVVFFWYmt1fH58dm9pZl9NOy4hFQsEBAgKDRwyQ1NldICIi4+Xm5iVkId/eHR0dHN0gZWnuMna6fX6/P/979/Ova+knpybmJWZoaOlp6elopuVk4t7bF9SSUNAP0JGR0xZZXB8g4eLjod6aVdJPjEjHyUwPUlSXnKEiYF0aF1SQjIvOEdZa3iJnaqspp6WlZOLipSlus7d5vD17t/Qv7Oup5+cpbPCztHT1dTFrZN6ZVhLPjo/SVRcW1xiZFtKNiQYEAgAAg4fMkBIUV5mZV9ZVVpjZ218kanB0tzl7Ori2M/IyMrIydDd6vX49fHt4cy0nYd5cGVdXWJpb29pZmZhVEIuHRIMBQAEDhonMTY9RkxMSkVCRk9UWWV3ip6uusPLzcrFwLu7wMPFy9fj7/j6+PTs38y4o5OJgXhzdnuAhYR/endvYU87KiAaEw8SGyYxO0BGTlJQS0VAQEZKTllrf5WsvcHBwcC8s62xvcfT4+/z9vn359PEuayhm5iTi4J3alpQTkxFPjovIRYNBQIKHC0+UGFkXltbWFRXaX+UqsPZ4+fq6uHUzs7LyMvT19HGt5+Da19YVFJWW1ZNRTwvJis2QElVX1tRS05QUmF8mbHK5vn79e7j0b60rqqorLjCv7WnkHFVRDYtKzE2NDAvLysnLDlDTVpna2NdYmptdYqlu9Dn+v/68+zeyLavq6eor7i+vbeslnZcTkAzLS0uKiUmJiIdIzE6PkRMTUQ8P0ZLU2mJpLrT7Pv8+fXs28rEwr67v8vW1Mm/uLCllHdeVlJHNichIy5AXH2NjYuKhXpsaHJ6eHFoXFVWYHF2bWFVR0FETFdbV1piZ25/l7TM1tnZ0MfDwcPN1NTKtZ6Uj4iEgHRlU0I+RElSW1tZV1NTXGp/m662uLGloKCls8DCuaaMd2lgX2JeU0Y2KyszP0xSUFBQTlJfc4uisr/Hw7y8wMfS2NTHr5OAdGtpa2pmXlNNUFVaX15bWlhWW2RziJ2uvcbGwsC+wMXHw7ikjXpsY2JmZ2ZhV05LTE5RT0lFRUVKU2Fzhpajr7Owr66usrW0rqGNe25kXl9gX1xVTUtMT1RYWFdZXGFqdYSVpbG7wsK+vLm5vL26sqibj4d/enp5dW9mXFZTUFBQS0dGR0pSYHWGjY2RnK7Ayse3opOSmJaGbFFFSVRWTDwyPVd2iIh8cHWKqr++pouAh5idjGtLP0hdZ1xGOENkj6+2rKCmwOP589aznp+rq5RrQzI7UWBbSDU2T3eaqJ+NhpOwy9G/n4eDjpaIZDodGSk8PzMgGCdLdI+XkIuWstXq5syunaGtr5p0TTg6SlZTRTc3TnWarayhnarH5fPpzK6en6SehmJBMjVCRz4sHiE5X4CRj4WBjqnH1c62npOVmpV/YEU7QlBXTjwtLUJkhZeZk5GbscnVzrunnZ6jnolpSz1BUl9fUkRATmqKoKejnqCsvsnEspyNjJOWinFUPjhATVJMQDg8TmiAjZGSl6S5zNTMu6mhpKqpm4BjT0pPWFpTS0ZNXHGAh4aDhIydrbOsnIyGipSZkoFwYVZQUVRZYGdpa25sZWNpdoynur65rqKZlpaVl56ioJmLdV9SS09bZmZcTj4xMjtIU1xbVFJWWFdZXmp/ma24vbispaixvMza39rQwK6gl4yCgYOCfHBcRzs7QEpXW1ZOR0A9Q09gdo2eqK+xqZ+Zl5qltL/AuKaOeWxlYmVrbWpjWk5HRklOVl1fXVxbV1ZbZ3eMn6y0ubq1sK6vsLa9wsTAtqaViH52c3V1cWpgVU5MTk9RVFNQUVNUVVpganeIlZ6kpaGbl5eYm6Glp6ahmY2De3JtbG5vbmpiWlVWWV1jZmZjY2VnbHJ5gImSmqCmqaijn5ybnaKmqKahmZCKhYF9enh0cW5qZmRiYmJkZmdnaGhoaWtvdX2EiYyOkZKSkZGQj5CRkpOSkIqFgHt3dXNyc3R1dnl9gYOBfXh1c3Fta2xvcnV3e4CEhoaGhoiIhoSEhomNkJSan6GhnpuZlpGMiIaGhYOCg4WGhoOBfXp1cGtnZ2dnZ2hrbm9ubGtqaWdmZmltcHN2eXx9fHp6ent7e3x/g4iMj5KWmZqamZeWlJGOi4qJiYmJiouNjY2LioiFgn98e3p5eXl5ent7e3p6enp6enp6e3x8fH19fX19fn5+fn5+f39/f39/f3+AgICAgICAgICBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgABMSVNUWAAAAElORk9JQ09QHwAAAENvcHlyaWdodCCpIENpbmVtYXRyb25pY3MgMTk5NQAASVBSRCMAAABNaWNyb3NvZnQgUGx1cyEgriBmb3IgV2luZG93cyA5NSCuAAA=');
    chime.load();

    if (window.WebSocket) {
        ws = new WebSocket(websocket);
    }
    else if (window.MozWebSocket) {
        ws = MozWebSocket(websocket);
    }
    else {
        console.log('WebSocket Not Supported');
        return;
    }

    function updateChatWindow() {
        $(window).scrollTop($(window).height());

        // Prevent the window from getting too full and slowing everything down.
        if ($chatWindow.children().length > 200) {
            $chatWindow.children()[0].remove();
            $chatWindow.children()[1].remove(); //We will removed 2 items to preserve odd row highlighting
        }

        unreadCount++;
        updateTitle();
    }

    function addMessageToChat(msg) {
        var text = msg.data;
        text = linkify(text);

        // TODO: Move into ChatWindow class, add different categories of messages: info, say, event, etc.
        var date = new Date();
        var time = date.toLocaleTimeString();

        if (text.indexOf(username) != -1)
        {
            chime.play()
        }

        if (($chatWindow.children().length % 2) == 1)
        {
            $chatWindow.append("
[" + time + "] " +  msg.username + ": " + text + "
");
        }
        else
        {
            $chatWindow.append("
[" + time + "] " +  msg.username + ": " + text + "
");
        }

        updateChatWindow();
    }

    function addEventToChat(msg) {
        $chatWindow.append("
" + msg + "
");
        updateChatWindow();
    }

    function updateTitle() {
        var title = "MockingJay";
        if (unreadCount > 0) {
            title += " (" + unreadCount + ")";
        }

        document.title = title;
    }

    window.onbeforeunload = function(e) {
        addEventToChat('Bye bye...');

        msg = {
            type: 'EVENT',
            event: 'SIGN_OFF',
            username: username
        }

        ws.send(JSON.stringify(msg));
        ws.close(1000, username + " left the chat..");

        if(!e) e = window.event;
        e.stopPropagation();
        e.preventDefault();
    };

    window.onmousemove = function(e) {
        unreadCount = 0;
        updateTitle();
    };

    ws.onmessage = function (evt) {
        msg = JSON.parse(evt.data);
        console.log(msg)
        if (msg.type == "EVENT") {
            if (msg.event == "FIRST_SIGN_ON") {
                username = msg.username;
                addEventToChat("Welcome, " + username + " if you would like to change your name type '/nick [username]' into the chat box below.");
            } else if (msg.event == "SIGN_ON") {
                addEventToChat(msg.username + " signed on");
            } else if (msg.event == "SIGN_OFF") {
                addEventToChat(msg.username + " signed off");
            } else  if (msg.event == "NAME_CHANGED") {
                if (msg.username == username) {
                    username = msg.new_name;
                    window.localStorage['username'] = username;
                }
                addEventToChat(msg.username + " changed name to " + msg.new_name);
            }
        } else if (msg.type == "INFO") {
            if (msg.info == "ROOM_LIST") {
                roomList = msg.data
                $roomList.empty()
                for(var i = 0;i<roomList.length;i++) {
                    $roomList.append("
"+ roomList[i] + "
");
                }
            }
        } else {
            addMessageToChat(msg);
        }
    };

    ws.onopen = function() {
        msg = {
            type: 'EVENT',
            event: 'FIRST_SIGN_ON'
        };

        if (window.localStorage['username']) {
            msg.username = window.localStorage['username'];
        }

        ws.send(JSON.stringify(msg));
    };

    ws.onclose = function(evt) {
        addEventToChat('Connection closed by server: ' + evt.code + ' \"' + evt.reason);
    };

    function sendMessage() {
        var $message = $('#message');
        var value = $message.val();

        // TODO: move this into a parser class
        if (value[0] == '/') {
            if(value.substring(0,5) == '/nick') {
                var newUsername = value.substring(6,value.length);
                ws.send(JSON.stringify({username: username, type: "CMD", command: "NAME_CHANGE", new_name: newUsername}))
                // TODO: save this to local storage as a preference
            }
        } else {
            ws.send(JSON.stringify({username: username, type: "MSG", data: value}))
        }

        $message.val("");
        return false;
    }

    $('#send').click(function() {
        return sendMessage();
    });

    $('#message').keypress(function(e) {
        unreadCount = 0;
        updateTitle();
        if (e.which == 13) {
            return sendMessage();
        }
    });

});
<|endoftext|>