<commit_before>/**
 * We.js database module
 *
 * This file load default database logic with sequelize
 */

var Sequelize = require('sequelize');
var async = require('async');
var _ = require('lodash');

var Database = function(we) {
  this.we = we;
  this.env = we.env;
  var db = this;

  this.defaultConnection = null;
  this.models = {};
  this.modelsConfigs = {};
  this.Sequelize = Sequelize;
  this.projectFolder = process.cwd();

  this.defaultModelDefinitionConfigs = {
    define: {
      // table configs
      timestamps: true,
      createdAt:  'createdAt',
      updatedAt:  'updatedAt',
      deletedAt:  'deletedAt',
      paranoid:   false,
      // enable we.js url alias for all models by default
      // change this config in your model to false to disable
      enableAlias: true,

      classMethods: {
        /**
         * Context loader, preload current request record and related data
         *
         * @param  {Object}   req  express.js request
         * @param  {Object}   res  express.js response
         * @param  {Function} done callback
         */
        contextLoader: function contextLoader(req, res, done) {
          if (!res.locals.id || !res.locals.loadCurrentRecord) return done();

          return this.findOne({
            where: { id: res.locals.id},
            include: [{ all: true }]
          }).then(function (record) {
            res.locals.data = record;
            if (record && record.dataValues.creatorId && req.isAuthenticated()) {
              // ser role owner
              if (record.isOwner(req.user.id)) {
                if(req.userRoleNames.indexOf('owner') == -1 ) req.userRoleNames.push('owner');
              }
            }

            return done();
          })
        }
      },
      instanceMethods: {
        /**
         * Default method to check if user is owner
         */
        isOwner: function isOwner(uid) {
          if (uid == this.creatorId) return true;
          return false;
        },

        /**
         * Function to run after send records in response
         * Overryde this function to remove private data
         *
         * @return {Object}
         */
        toJSON: function toJSON() {
          var obj = this.get();
          return obj;
        },

        /**
         * Default function to set all associated model ids changing associations from objects array to ids array
         *
         * @param  {Function} cb callback
         */
        fetchAssociatedIds: function fetchAssociatedIds(cb) {
          var modelName = this.$modelOptions.name.singular;
          var associations = db.models[modelName].associations;

          for (var associationName in associations ) {
            // get bellongs to from values id
            if ( associations[associationName].associationType == 'BelongsTo' ) {
              this.dataValues[associationName] = this.dataValues[ associations[associationName].identifier ];
            } else {
              we.log.verbose('db.connect:fetchAssociatedIds unknow join: ', associations);
            }
          }
          cb();
        },

        /**
         * Default get url path instance method
         *
         * @return {String} url path
         */
        getUrlPath: function getUrlPath() {
          return we.router.urlTo(
            this.$modelOptions.name.singular + '.findOne', [this.id]
          );
        },
        /**
         * Get url path with suport to url alias
         *
         * @return {String} url path
         */
        getUrlPathAlias: function getUrlPathAlias() {
          var p = this.getUrlPath();
          return we.router.alias.forPath(p) || p;
        },

        /**
         * return model path with request
         * Try to use the getUrlPath if possible
         *
         * @param  {Object} req express request
         * @return {String}     url path
         */
        getPath: function getPath(req) {
          if (!req) throw new Error('Request is required in record.getPath()');
          return req.we.router.urlTo(
            this.$modelOptions.name.singular + '.findOne', req.paramsArray.concat([this.id])
          );
        },
        getLink: function getLink(req) {
          if (!req) throw new Error('Request is required in record.getLink()');
          return req.we.config.hostname + this.getPath(req);
        }
      }
    }
  }
}

// var db = {

// };

/**
 * Connect in database
 *
 * @param  {object} we
 * @return {object} sequelize database connection
 */
Database.prototype.connect = function connect() {
  var dbC = this.we.config.database;
  var configs = dbC[this.env];

  this.activeConnectionConfig = configs;

  // set we.js core model definition configs
  _.merge(configs, this.defaultModelDefinitionConfigs);

  if (!configs.logging && configs.logging !== false) {
    configs.logging = this.we.log.debug;
  }

  // connect with uri or with username and pass
  // See: http://sequelize.readthedocs.org/en/latest/api/sequelize/
  if (configs.uri) {
    return new Sequelize( configs.uri, configs );
  } else {
    return new Sequelize( configs.database, configs.username, configs.password, configs );
  }
}

/**
 * we.js db define | is a alias to current sequelize connection define
 *
 * @param  {String} name    model name
 * @param  {object} configs model configs
 * @return {Object}         sequelize model
 */
Database.prototype.define = function defineModel(name, definition, options) {
  return this.defaultConnection.define(name, definition, options);
}

/**
 * Load we.js core models: system
 *
 * @return {Object} models db.models var
 */
Database.prototype.loadCoreModels = function loadCoreModels(done) {
  var log = this.we.log;
  var db = this;

  //  system / plugins table
  this.models.plugin = this.define('plugin', {
    filename: {
      comment: 'plugin.js file',
      type: Sequelize.STRING(1000),
      allowNull: false
    },
    name: {
      comment: 'plugin name',
      type: Sequelize.STRING,
      allowNull: false
    },
    type: {
      type: Sequelize.STRING(12),
      defaultValue: 'plugin',
      allowNull: false
    },
    status: {
      comment: 'status, 1 for enabled',
      type: Sequelize.INTEGER,
      defaultValue: 0,
      allowNull: false
    },
    version: {
      comment: 'last version of plugin models in database',
      type: Sequelize.STRING(10),
      defaultValue: '0.0.0',
      allowNull: false
    },
    weight: {
      comment: 'plugin weight how controll plugin load order',
      type: Sequelize.INTEGER(5),
      defaultValue: 0,
      allowNull: false
    },
    info: {
      type: Sequelize.TEXT
    }
  });

  // TODO add system config table

  async.parallel([
    function syncPluginTable(next) {
      db.models.plugin.sync()
      .then(function(){
        next();
      }).catch(function errorOnSyncCoreModels(err) {
        // database connection error
        if (err.name == 'SequelizeAccessDeniedError') {
          console.log('database access error')
          log.warn('Cannot connect to the database');
          log.warn('This behavior occurs if one of the following conditions is true:\n'+
            '\t 1. The SQL database is not running or you need to create the database.\n'+
            '\t 2. The account that is used by the project in locals/config.js file does not have '+
                'the required permissions to the database server.\n'+
            '-> Check the database documentation in http://wejs.org site');

          log.verbose('Error: ', err);

          process.exit();
        }
        // unknow error ...
        next(err);
      });
    }
  ], done);
}

/**
 * Sync all db models | create table if now exists
 *
 * @param  {Object} cd configuration optional
 * @param  {Function} cb callback optional
 */
Database.prototype.syncAllModels = function syncAllModels(cd, cb) {
  if (cd && !cb) {
    cb = cd;
    cd = null;
  }
  // cd and cb is optional
  if (!cb) cb = function(){ };

  if (this.env == 'test' || (this.env != 'prod' && cd && cd.resetAllData)) {
    this.defaultConnection.sync({force: true}).then(function(){ cb(); }).catch(cb);
  } else {
    this.defaultConnection.sync().then(function(){ cb(); }).catch(cb);
  }
}

/**
 * Set all models associations
 */
Database.prototype.setModelAllJoins = function setModelAllJoins() {
  var attrConfig;

  for ( var modelName in this.modelsConfigs) {

    for (var attributeName in this.modelsConfigs[modelName].associations) {
      attrConfig = this.modelsConfigs[modelName].associations[attributeName];
      // skip if are emberOnly
      if (attrConfig.emberOnly) continue;

      var config = {
        scope: attrConfig.scope
      };

      config.as = attributeName;

      if (attrConfig.through) {
        if (typeof attrConfig.through == 'object') {
          config.through = attrConfig.through;
          config.through.model = this.models[attrConfig.through.model];
        } else {
          config.through = attrConfig.through;
        }
      }

      if (attrConfig.onDelete) config.onDelete = attrConfig.onDelete;
      if (attrConfig.onUpdate) config.onUpdate = attrConfig.onUpdate;
      if (attrConfig.constraints === false) config.constraints = false;
      if (attrConfig.otherKey) config.otherKey = attrConfig.otherKey;
      if (attrConfig.foreignKey) config.foreignKey = attrConfig.foreignKey;

      try {
        this.models[modelName][attrConfig.type]( this.models[attrConfig.model], config);
      } catch(e) {
        console.log('Error on setModelAllJoins 2: ', attrConfig.model, this.models[attrConfig.model]);
        throw e;
      }
    }
  }
}

/**
 * Check records privacity
 *
 * @param  {Object|Array} data records
 */
Database.prototype.checkRecordsPrivacity = function checkRecordsPrivacity(data) {
  if (_.isArray(data)) {
    for (var i = data.length - 1; i >= 0; i--) {
      if (data[i].privacity) {
        this.checkPrivacity(data[i]);
      }
    }
  } else if(data.privacity) {
    this.checkPrivacity(data);
  }
}

/**
 * Check records privacity fields
 *
 * @param  {Object} data record
 */
Database.prototype.checkPrivacity = function checkPrivacity(obj) {
  for (var i = obj.privacity.length - 1; i >= 0; i--) {
    if (obj.privacity[i].privacity == 'private') {
      delete obj.dataValues[obj.privacity[i].field];
    }

    if (_.isArray(obj[i])) {
      for (var j = obj[i].length - 1; j >= 0; j--) {
        if (obj[i][j].privacity && obj[i][j].dataValues) {
          this.checkPrivacity(obj[i][j]);
        }
      }
    }
  }
}

module.exports = Database;<commit_msg>fix getUrlPathAlias without url alias plugin<commit_after>/**
 * We.js database module
 *
 * This file load default database logic with sequelize
 */

var Sequelize = require('sequelize');
var async = require('async');
var _ = require('lodash');

var Database = function(we) {
  this.we = we;
  this.env = we.env;
  var db = this;

  this.defaultConnection = null;
  this.models = {};
  this.modelsConfigs = {};
  this.Sequelize = Sequelize;
  this.projectFolder = process.cwd();

  this.defaultModelDefinitionConfigs = {
    define: {
      // table configs
      timestamps: true,
      createdAt:  'createdAt',
      updatedAt:  'updatedAt',
      deletedAt:  'deletedAt',
      paranoid:   false,
      // enable we.js url alias for all models by default
      // change this config in your model to false to disable
      enableAlias: true,

      classMethods: {
        /**
         * Context loader, preload current request record and related data
         *
         * @param  {Object}   req  express.js request
         * @param  {Object}   res  express.js response
         * @param  {Function} done callback
         */
        contextLoader: function contextLoader(req, res, done) {
          if (!res.locals.id || !res.locals.loadCurrentRecord) return done();

          return this.findOne({
            where: { id: res.locals.id},
            include: [{ all: true }]
          }).then(function (record) {
            res.locals.data = record;
            if (record && record.dataValues.creatorId && req.isAuthenticated()) {
              // ser role owner
              if (record.isOwner(req.user.id)) {
                if(req.userRoleNames.indexOf('owner') == -1 ) req.userRoleNames.push('owner');
              }
            }

            return done();
          })
        }
      },
      instanceMethods: {
        /**
         * Default method to check if user is owner
         */
        isOwner: function isOwner(uid) {
          if (uid == this.creatorId) return true;
          return false;
        },

        /**
         * Function to run after send records in response
         * Overryde this function to remove private data
         *
         * @return {Object}
         */
        toJSON: function toJSON() {
          var obj = this.get();
          return obj;
        },

        /**
         * Default function to set all associated model ids changing associations from objects array to ids array
         *
         * @param  {Function} cb callback
         */
        fetchAssociatedIds: function fetchAssociatedIds(cb) {
          var modelName = this.$modelOptions.name.singular;
          var associations = db.models[modelName].associations;

          for (var associationName in associations ) {
            // get bellongs to from values id
            if ( associations[associationName].associationType == 'BelongsTo' ) {
              this.dataValues[associationName] = this.dataValues[ associations[associationName].identifier ];
            } else {
              we.log.verbose('db.connect:fetchAssociatedIds unknow join: ', associations);
            }
          }
          cb();
        },

        /**
         * Default get url path instance method
         *
         * @return {String} url path
         */
        getUrlPath: function getUrlPath() {
          return we.router.urlTo(
            this.$modelOptions.name.singular + '.findOne', [this.id]
          );
        },
        /**
         * Get url path with suport to url alias
         *
         * @return {String} url path
         */
        getUrlPathAlias: function getUrlPathAlias() {
          if (we.router.alias) {
            // with url alias
            var p = this.getUrlPath();
            return we.router.alias.forPath(p) || p;
          } else {
            // without url alias
            return this.getUrlPath();
          }
        },
        /**
         * return model path with request
         * Try to use the getUrlPath if possible
         *
         * @param  {Object} req express request
         * @return {String}     url path
         */
        getPath: function getPath(req) {
          if (!req) throw new Error('Request is required in record.getPath()');
          return req.we.router.urlTo(
            this.$modelOptions.name.singular + '.findOne', req.paramsArray.concat([this.id])
          );
        },
        getLink: function getLink(req) {
          if (!req) throw new Error('Request is required in record.getLink()');
          return req.we.config.hostname + this.getPath(req);
        }
      }
    }
  }
}

/**
 * Connect in database
 *
 * @param  {object} we
 * @return {object} sequelize database connection
 */
Database.prototype.connect = function connect() {
  var dbC = this.we.config.database;
  var configs = dbC[this.env];

  this.activeConnectionConfig = configs;

  // set we.js core model definition configs
  _.merge(configs, this.defaultModelDefinitionConfigs);

  if (!configs.logging && configs.logging !== false) {
    configs.logging = this.we.log.debug;
  }

  // connect with uri or with username and pass
  // See: http://sequelize.readthedocs.org/en/latest/api/sequelize/
  if (configs.uri) {
    return new Sequelize( configs.uri, configs );
  } else {
    return new Sequelize( configs.database, configs.username, configs.password, configs );
  }
}

/**
 * we.js db define | is a alias to current sequelize connection define
 *
 * @param  {String} name    model name
 * @param  {object} configs model configs
 * @return {Object}         sequelize model
 */
Database.prototype.define = function defineModel(name, definition, options) {
  return this.defaultConnection.define(name, definition, options);
}

/**
 * Load we.js core models: system
 *
 * @return {Object} models db.models var
 */
Database.prototype.loadCoreModels = function loadCoreModels(done) {
  var log = this.we.log;
  var db = this;

  //  system / plugins table
  this.models.plugin = this.define('plugin', {
    filename: {
      comment: 'plugin.js file',
      type: Sequelize.STRING(1000),
      allowNull: false
    },
    name: {
      comment: 'plugin name',
      type: Sequelize.STRING,
      allowNull: false
    },
    type: {
      type: Sequelize.STRING(12),
      defaultValue: 'plugin',
      allowNull: false
    },
    status: {
      comment: 'status, 1 for enabled',
      type: Sequelize.INTEGER,
      defaultValue: 0,
      allowNull: false
    },
    version: {
      comment: 'last version of plugin models in database',
      type: Sequelize.STRING(10),
      defaultValue: '0.0.0',
      allowNull: false
    },
    weight: {
      comment: 'plugin weight how controll plugin load order',
      type: Sequelize.INTEGER(5),
      defaultValue: 0,
      allowNull: false
    },
    info: {
      type: Sequelize.TEXT
    }
  });

  // TODO add system config table

  async.parallel([
    function syncPluginTable(next) {
      db.models.plugin.sync()
      .then(function(){
        next();
      }).catch(function errorOnSyncCoreModels(err) {
        // database connection error
        if (err.name == 'SequelizeAccessDeniedError') {
          console.log('database access error')
          log.warn('Cannot connect to the database');
          log.warn('This behavior occurs if one of the following conditions is true:\n'+
            '\t 1. The SQL database is not running or you need to create the database.\n'+
            '\t 2. The account that is used by the project in locals/config.js file does not have '+
                'the required permissions to the database server.\n'+
            '-> Check the database documentation in http://wejs.org site');

          log.verbose('Error: ', err);

          process.exit();
        }
        // unknow error ...
        next(err);
      });
    }
  ], done);
}

/**
 * Sync all db models | create table if now exists
 *
 * @param  {Object} cd configuration optional
 * @param  {Function} cb callback optional
 */
Database.prototype.syncAllModels = function syncAllModels(cd, cb) {
  if (cd && !cb) {
    cb = cd;
    cd = null;
  }
  // cd and cb is optional
  if (!cb) cb = function(){ };

  if (this.env == 'test' || (this.env != 'prod' && cd && cd.resetAllData)) {
    this.defaultConnection.sync({force: true}).then(function(){ cb(); }).catch(cb);
  } else {
    this.defaultConnection.sync().then(function(){ cb(); }).catch(cb);
  }
}

/**
 * Set all models associations
 */
Database.prototype.setModelAllJoins = function setModelAllJoins() {
  var attrConfig;

  for ( var modelName in this.modelsConfigs) {

    for (var attributeName in this.modelsConfigs[modelName].associations) {
      attrConfig = this.modelsConfigs[modelName].associations[attributeName];
      // skip if are emberOnly
      if (attrConfig.emberOnly) continue;

      var config = {
        scope: attrConfig.scope
      };

      config.as = attributeName;

      if (attrConfig.through) {
        if (typeof attrConfig.through == 'object') {
          config.through = attrConfig.through;
          config.through.model = this.models[attrConfig.through.model];
        } else {
          config.through = attrConfig.through;
        }
      }

      if (attrConfig.onDelete) config.onDelete = attrConfig.onDelete;
      if (attrConfig.onUpdate) config.onUpdate = attrConfig.onUpdate;
      if (attrConfig.constraints === false) config.constraints = false;
      if (attrConfig.otherKey) config.otherKey = attrConfig.otherKey;
      if (attrConfig.foreignKey) config.foreignKey = attrConfig.foreignKey;

      try {
        this.models[modelName][attrConfig.type]( this.models[attrConfig.model], config);
      } catch(e) {
        console.log('Error on setModelAllJoins 2: ', attrConfig.model, this.models[attrConfig.model]);
        throw e;
      }
    }
  }
}

/**
 * Check records privacity
 *
 * @param  {Object|Array} data records
 */
Database.prototype.checkRecordsPrivacity = function checkRecordsPrivacity(data) {
  if (_.isArray(data)) {
    for (var i = data.length - 1; i >= 0; i--) {
      if (data[i].privacity) {
        this.checkPrivacity(data[i]);
      }
    }
  } else if(data.privacity) {
    this.checkPrivacity(data);
  }
}

/**
 * Check records privacity fields
 *
 * @param  {Object} data record
 */
Database.prototype.checkPrivacity = function checkPrivacity(obj) {
  for (var i = obj.privacity.length - 1; i >= 0; i--) {
    if (obj.privacity[i].privacity == 'private') {
      delete obj.dataValues[obj.privacity[i].field];
    }

    if (_.isArray(obj[i])) {
      for (var j = obj[i].length - 1; j >= 0; j--) {
        if (obj[i][j].privacity && obj[i][j].dataValues) {
          this.checkPrivacity(obj[i][j]);
        }
      }
    }
  }
}

module.exports = Database;<|endoftext|>


<commit_before>window.addEventListener('message', function (event) {
	// if (originWhitelist.includes(event.origin)) {
	if (event.origin) {
		const type = event && event.data && event.data.action;
		msg(`postMessage received: ${type}`);
		return handleMessage({ event, type, connector: new OnlyKeyConnector() });
	} else {
		msg(`[ERROR: postMessage missing event.origin]`);
	}
});

function handleMessage(params = {}) {
	msg(`handleMessage params:`);
	msgObjectProps(params);

	const { event, type, connector } = params;

	if (!(event && type && connector)) {
		let err = `params event, type, and connector are required.`;
		msg(`handleMessage error: ${err}`)
		throw new ReferenceError(err);
	}

	const extensionId = event.origin.split("//")[1];
	msg(`Attempting sendMessage to extensionId ${extensionId}`);

	// Make a simple request:
	chrome.runtime.sendMessage(extensionId, { connector, type, data: event.data },
	  function(response) {
	    if (!response.success) {
	    	msg(`sendMessage response failed:`);
	    	msg(JSON.stringify(response));
	    } else {
	    	msg(`SUCCESS`);
	    }
	  });
  return;

	switch(type) {
		case 'GET_CONNECTOR':
			event.source.postMessage({ connector, type, data: event.data }, event.origin);
			msg(`Sent message to ${event.origin}`);
			break;
		default:
			// unhandled type
			break;
	}
}

const originWhitelist = [
	'https://'
];

class OnlyKeyConnector {
	constructor(params) {
		this.Sign = auth_sign;
		this.Decrypt = auth_decrypt;
	}
}

function msgObjectProps(obj) {
	if (typeof obj === 'object') {
		for (var k in obj) {
			msg(`> ${k}: ${JSON.stringify(obj[k])}`);
		}
	} else {
		msg(`[value]: ${obj}`);
	}
}
<commit_msg>updated for new extension messaging port<commit_after>window.addEventListener('message', function (event) {
	// if (originWhitelist.includes(event.origin)) {
	if (event.origin) {
		const action = event && event.data && event.data.action;
		msg(`HTML5 message received: ${action}`);
		return handleMessage({ event, action });
	} else {
		msg(`[ERROR: postMessage missing event.origin]`);
	}
});

function handleMessage(params = {}) {
	msg(`handleMessage params:`);
	msgObjectProps(params);

	const { event, action } = params;

	if (!(event && action)) {
		let err = `params event and action are required.`;
		msg(`handleMessage error: ${err}`)
		console.error(ReferenceError(err));
		return false;
	}

	const extensionId = event.origin.split("//")[1];
	if (!validExtensionId(extensionId)) {
		// don't respond to unexpected origins
		return false;
	}

	msg(`Confirmed message from valid extension ${extensionId}`);

	switch(action) {
		case 'ENCRYPT':
			auth_sign(event.data.data, respondToAction);
			break;
		case 'DECRYPT':
			// perform auth_decrypt()
			break;
		default:
			// unhandled action
			break;
	}

}

function respondToAction(data) {
	chrome.runtime.sendMessage(extensionId, { ok_sig: data },
		response => {
			if (!response.success) {
				msg(`sendMessage response failed:`);
				msg(JSON.stringify(response));
			} else {
				msg(`SUCCESS`);
			}
		});
}

const originWhitelist = [
	'https://'
];

function validExtensionId(str) {
	const re = /^[A-Za-z]{32}$/;
	const matchArr = str.match(re);
	return (matchArr && matchArr.length);
}

function msgObjectProps(obj) {
	if (typeof obj === 'object') {
		for (var k in obj) {
			msg(`> ${k}: ${JSON.stringify(obj[k])}`);
		}
	} else {
		msg(`[value]: ${obj}`);
	}
}
<|endoftext|>


<commit_before>app.controller('PostingController', ['$scope', '$routeParams' , function($scope, $routeParams) {

	/*
	 *  INIT VARS
	 */
	$scope.posting={};
	$scope.posting_functions={};
	$scope.postings={};

	$scope.wall_functions={};

	$scope.like={};
	$scope.like_functions={};
	$scope.likes = {};

	$scope.types = {};

	$scope.posting.hashtag=($routeParams.hashtag)?'#'+$routeParams.hashtag.toUpperCase():'#';

	$scope.apply 	= function() {if(!$scope.$$phase) {$scope.$apply();}};

	$scope.db.changes({
					  since:  'latest',
					  continuous: true,
					  include_docs: true,
					  onChange:  function(change) {

					  	/*
					  	 *  SET DOC.TYPE IF NOT AVAILABLE
					  	 */
					  	if($scope.types[change.id]){
						  	if($scope.types[change.id].type && !change.doc.type){
						  		change.doc.type=$scope.types[change.id].type;
						  	}
					  	}
					  	console.log(change.doc.type);
					  	switch (change.doc.type) {
						    case "POST":
						        $scope.posting_functions.onChangePosting(change);
						        break;
						    case "LIKE":
						        $scope.like_functions.onChangeLike(change);
						        break;
						};
					  },
					  complete: function(err, response) {

					  }
	});

	$scope.posting_functions.onChangePosting = function(change){
		if(change.deleted){
			angular.forEach($scope.postings, function(value, key){
				if(value.id==change.id){
					$scope.postings.splice(key, 1);
				}
			});
		}else{
			$scope.types[change.id]=({type:'POST'});
			$scope.likes[change.id]=new Array();
			$scope.postings.push(change);
		}
		$scope.apply();
	};

	$scope.posting_functions.delete = function(posting) {
		$scope.db.get(posting.id, function(err, results) {
			$scope.db.remove(results, function(err, results){});
		});
	};
	$scope.posting_functions.isPost = function(doc) {
		if(doc.type=='POST') {   emit([doc._id, 0], doc);}
		if(doc.type=='LIKE') {   emit([doc.posting, 1], doc);}
		if(doc.type=='COMMENT') {   emit([doc.posting, 2], doc);}
	};

    $scope.posting_functions.orderByCreated = function(posting) {
    	if(posting.created)
    		return posting.created;
    	else
    		return posting.doc.created;
	};

	 $scope.posting_functions.isDeletable = function(posting) {
	 	if(posting.doc.user.id == $scope.user.getId())
	 		return true;
	 	return false;
	 };

	 /*
	  *  RENAME?
	  */

	 $scope.time = function(timestamp) {timestamp=timestamp/1000;return timestamp;};
	 $scope.posting_functions.showTimestamp = function(posting) {
	 	// Set the maximum time difference for showing the date
	 	maxTimeDifferenceForToday = Math.round((new Date()).getTime() / 1000) - ageOfDayInSeconds();
	 	maxTimeDifferenceForYesterday = maxTimeDifferenceForToday - 86400;
	 	postTime = posting.doc.created/1000;
	 	if((postTime > maxTimeDifferenceForYesterday) && (postTime < maxTimeDifferenceForToday)){
	 		return 'yesterday';
	 	}
	 	else if(postTime < maxTimeDifferenceForToday){
	 		return 'older';
	 	}
	 	return 'today';
	 };

	 function ageOfDayInSeconds(){
	 	// Calculate beginning of the current day in seconds
	 	current_date = new Date();
	 	current_day_hours = current_date.getHours();
	 	current_day_minutes = current_date.getMinutes();
	 	return (current_day_hours*60*60) + (current_day_minutes*60);
	 };

	/*
	 *
	 *  GLOBAL
	 *
	 */

	$scope.wall_functions.showWall = function() {
		$scope.db.query({map: $scope.posting_functions.isPost}, {reduce: false}, function(err, response) {
			$scope.postings = [];
			$scope.likes = {};
			$scope.types = {};

			var actual_like_id=false;

			angular.forEach(response.rows, function(row, key){
				if(row.value){row.doc=row.value;delete row.value;}

				switch (row.doc.type) {
						    case "POST":
						    	$scope.types[row.id]={type:'POST'};
						    	actual_id=row.id;
						    	$scope.postings.push(row);
						    	if(!$scope.likes[row.id]){$scope.likes[row.id]=new Array();}
						        break;
						    case "LIKE":
						        $scope.types[row.id]={type:'LIKE', posting: row.doc.posting};
						        //$scope.db.remove(row.doc, function(err, results){
						        //	console.log(err || results);
						        //});
						    	if(!$scope.likes[row.doc.posting]){$scope.likes[row.doc.posting]=new Array();}
									$scope.likes[row.doc.posting].push(row);
						        break;
						    case "COMMENT":
						        $scope.types[row.id]='COMMENT';
						        // $scope.db.remove(row.doc, function(err, results){
						        //	console.log(err || results);
						        //});
						    	if(!$scope.comment[row.doc.posting]){$scope.comment[row.doc.posting]=new Array();}
									$scope.comment[row.doc.posting].push(row);
						        break;
				};
			});
			//console.log($scope.types);
			$scope.apply();
		});
    };
     function init(){
	 	stickyActionBar();
	 }
	 init();

	 /*
	  *  LIKE-Functions
	  */

	 $scope.like_functions.like = function(posting){
	 	doc={
			created : new Date().getTime(),
			posting: posting.id,
			user: {
				id : $scope.user.getId(),
				name : $scope.user.getName()
			},
			type : 'LIKE'
		};
		$scope.db.post(doc, function (err, response) {});
	 };

	  $scope.like_functions.unlike = function(like){
	  	$scope.db.get(like.id, function(err, results) {
			$scope.db.remove(results, function(err, results){});
		});
	  };

	 $scope.like_functions.onChangeLike = function(change){

	 	if(change.deleted){
	 		console.log($scope.types[change.id].posting);
	 		console.log($scope.likes);
	 		console.log($scope.likes[$scope.types[change.id].posting]);
			angular.forEach($scope.likes[$scope.types[change.id].posting], function(value, key){
				if(value.id==change.id){
					$scope.likes[$scope.types[change.id].posting].splice(key, 1);
					$scope.apply();
				}
			});
	 	}else{
	 		$scope.types[change.id]={type:'LIKE', posting:change.doc.posting};
	 		if(!$scope.likes[change.doc.posting])
	 			$scope.likes[change.doc.posting]=new Array();
	 		$scope.likes[change.doc.posting].push(change);
	 		$scope.apply();
	 	}
	 };

}]);
<commit_msg>FCTWO-232 - DONE :-)<commit_after>app.controller('PostingController', ['$scope', '$routeParams' , function($scope, $routeParams) {

	/*
	 *  INIT VARS
	 */
	$scope.posting={};
	$scope.posting_functions={};
	$scope.postings={};

	$scope.wall_functions={};

	$scope.like={};
	$scope.like_functions={};
	$scope.likes = {};

	$scope.types = {};

	$scope.posting.hashtag=($routeParams.hashtag)?'#'+$routeParams.hashtag.toUpperCase():'#';

	$scope.apply 	= function() {if(!$scope.$$phase) {$scope.$apply();}};

	$scope.db.changes({
					  since:  'latest',
					  continuous: true,
					  include_docs: true,
					  onChange:  function(change) {

					  	/*
					  	 *  SET DOC.TYPE IF NOT AVAILABLE
					  	 */
					  	if($scope.types[change.id]){
						  	if($scope.types[change.id].type && !change.doc.type){
						  		change.doc.type=$scope.types[change.id].type;
						  	}
					  	}
					  	switch (change.doc.type) {
						    case "POST":
						        $scope.posting_functions.onChangePosting(change);
						        break;
						    case "LIKE":
						        $scope.like_functions.onChangeLike(change);
						        break;
						};
					  },
					  complete: function(err, response) {

					  }
	});

	$scope.posting_functions.onChangePosting = function(change){
		if(change.deleted){
			angular.forEach($scope.postings, function(value, key){
				if(value.id==change.id){
					$scope.postings.splice(key, 1);
				}
			});
		}else{
			$scope.types[change.id]=({type:'POST'});
			$scope.likes[change.id]=new Array();
			$scope.postings.push(change);
		}
		$scope.apply();
	};

	$scope.posting_functions.delete = function(posting) {
		$scope.db.get(posting.id, function(err, results) {
			$scope.db.remove(results, function(err, results){});
		});
	};
	$scope.posting_functions.isPost = function(doc) {
		if(doc.type=='POST') {   emit([doc._id, 0], doc);}
		if(doc.type=='LIKE') {   emit([doc.posting, 1], doc);}
		if(doc.type=='COMMENT') {   emit([doc.posting, 2], doc);}
	};

    $scope.posting_functions.orderByCreated = function(posting) {
    	if(posting.created)
    		return posting.created;
    	else
    		return posting.doc.created;
	};

	 $scope.posting_functions.isDeletable = function(posting) {
	 	if(posting.doc.user.id == $scope.user.getId())
	 		return true;
	 	return false;
	 };

	 /*
	  *  RENAME?
	  */

	 $scope.time = function(timestamp) {timestamp=timestamp/1000;return timestamp;};
	 $scope.posting_functions.showTimestamp = function(posting) {
	 	// Set the maximum time difference for showing the date
	 	maxTimeDifferenceForToday = Math.round((new Date()).getTime() / 1000) - ageOfDayInSeconds();
	 	maxTimeDifferenceForYesterday = maxTimeDifferenceForToday - 86400;
	 	postTime = posting.doc.created/1000;
	 	if((postTime > maxTimeDifferenceForYesterday) && (postTime < maxTimeDifferenceForToday)){
	 		return 'yesterday';
	 	}
	 	else if(postTime < maxTimeDifferenceForToday){
	 		return 'older';
	 	}
	 	return 'today';
	 };

	 function ageOfDayInSeconds(){
	 	// Calculate beginning of the current day in seconds
	 	current_date = new Date();
	 	current_day_hours = current_date.getHours();
	 	current_day_minutes = current_date.getMinutes();
	 	return (current_day_hours*60*60) + (current_day_minutes*60);
	 };

	/*
	 *
	 *  GLOBAL
	 *
	 */

	$scope.wall_functions.showWall = function() {
		$scope.db.query({map: $scope.posting_functions.isPost}, {reduce: false}, function(err, response) {
			$scope.postings = [];
			$scope.likes = {};
			$scope.types = {};

			var actual_like_id=false;

			angular.forEach(response.rows, function(row, key){
				if(row.value){row.doc=row.value;delete row.value;}

				switch (row.doc.type) {
						    case "POST":
						    	$scope.types[row.id]={type:'POST'};
						    	actual_id=row.id;
						    	$scope.postings.push(row);
						    	if(!$scope.likes[row.id]){$scope.likes[row.id]=new Array();}
						        break;
						    case "LIKE":
						        $scope.types[row.id]={type:'LIKE', posting: row.doc.posting};
						        //$scope.db.remove(row.doc, function(err, results){
						        //	console.log(err || results);
						        //});
						    	if(!$scope.likes[row.doc.posting]){$scope.likes[row.doc.posting]=new Array();}
									$scope.likes[row.doc.posting].push(row);
						        break;
						    case "COMMENT":
						        $scope.types[row.id]='COMMENT';
						        // $scope.db.remove(row.doc, function(err, results){
						        //	console.log(err || results);
						        //});
						    	if(!$scope.comment[row.doc.posting]){$scope.comment[row.doc.posting]=new Array();}
									$scope.comment[row.doc.posting].push(row);
						        break;
				};
			});
			//console.log($scope.types);
			$scope.apply();
		});
    };
     function init(){
	 	stickyActionBar();
	 }
	 init();

	 /*
	  *  LIKE-Functions
	  */

	 $scope.like_functions.like = function(posting){
	 	doc={
			created : new Date().getTime(),
			posting: posting.id,
			user: {
				id : $scope.user.getId(),
				name : $scope.user.getName()
			},
			type : 'LIKE'
		};
		$scope.db.post(doc, function (err, response) {});
	 };

	  $scope.like_functions.unlike = function(like){
	  	$scope.db.get(like.id, function(err, results) {
			$scope.db.remove(results, function(err, results){});
		});
	  };

	 $scope.like_functions.onChangeLike = function(change){

	 	if(change.deleted){
			angular.forEach($scope.likes[$scope.types[change.id].posting], function(value, key){
				if(value.id==change.id){
					$scope.likes[$scope.types[change.id].posting].splice(key, 1);
					$scope.apply();
				}
			});
	 	}else{
	 		$scope.types[change.id]={type:'LIKE', posting:change.doc.posting};
	 		if(!$scope.likes[change.doc.posting])
	 			$scope.likes[change.doc.posting]=new Array();
	 		$scope.likes[change.doc.posting].push(change);
	 		$scope.apply();
	 	}
	 };

}]);
<|endoftext|>


<commit_before>// @require: OpenLayers/Util.js
/**
* @class
*
*
*/

OpenLayers.Map = Class.create();
OpenLayers.Map.prototype = {
    // Hash: base z-indexes for different classes of thing
    Z_INDEX_BASE: { Layer: 100, Popup: 200, Control: 1000 },

    // Array: supported application event types
    EVENT_TYPES: [
        "addlayer", "removelayer", "movestart", "move", "moveend",
        "zoomend", "layerchanged", "popupopen", "popupclose",
        "addmarker", "removemarker", "clearmarkers", "mouseover",
        "mouseout", "mousemove", "dragstart", "drag", "dragend" ],

    // int: zoom levels, used to draw zoom dragging control and limit zooming
    maxZoomLevel: 16,

    // OpenLayers.Bounds
    maxExtent: new OpenLayers.Bounds(-180, -90, 180, 90),

    /* projection */
    projection: "EPSG:4326",

    /** @type OpenLayers.Size */
    size: null,

    // float
    maxResolution: 1.40625, // degrees per pixel
                            // Default is whole world in 256 pixels, from GMaps

    // DOMElement: the div that our map lives in
    div: null,

    // HTMLDivElement: the map's view port
    viewPortDiv: null,

    // HTMLDivElement: the map's layer container
    layerContainerDiv: null,

    // Array(OpenLayers.Layer): ordered list of layers in the map
    layers: null,

    // Array(OpenLayers.Control)
    controls: null,

    // Array(OpenLayers.Popup)
    popups: null,

    // OpenLayers.LonLat
    center: null,

    // int
    zoom: null,

    // OpenLayers.Events
    events: null,

    // OpenLayers.Pixel
    mouseDragStart: null,

    /**
    * @param {DOMElement} div
    */
    initialize: function (div, options) {
        Object.extend(this, options);

        this.div = div = $(div);

        // the viewPortDiv is the outermost div we modify
        var id = div.id + "_OpenLayers_ViewPort";
        this.viewPortDiv = OpenLayers.Util.createDiv(id, null, null, null,
                                                     "relative", null,
                                                     "hidden");
        this.viewPortDiv.style.width = "100%";
        this.viewPortDiv.style.height = "100%";
        this.div.appendChild(this.viewPortDiv);

        // the layerContainerDiv is the one that holds all the layers
        id = div.id + "_OpenLayers_Container";
        this.layerContainerDiv = OpenLayers.Util.createDiv(id);
        this.viewPortDiv.appendChild(this.layerContainerDiv);

        this.events = new OpenLayers.Events(this, div, this.EVENT_TYPES);

        this.updateSize();
        // make the entire maxExtent fix in zoom level 0 by default
        if (this.maxResolution == null || this.maxResolution == "auto") {
            this.maxResolution = Math.max(
                this.maxExtent.getWidth()  / this.size.w,
                this.maxExtent.getHeight() / this.size.h );
        }
        // update the internal size register whenever the div is resized
        this.events.register("resize", this, this.updateSize);

        this.layers = [];

        if (!this.controls) {
            this.controls = [];
            this.addControl(new OpenLayers.Control.MouseDefaults());
            this.addControl(new OpenLayers.Control.PanZoom());
        }

        this.popups = new Array();

        // always call map.destroy()
        Event.observe(window, 'unload',
            this.destroy.bindAsEventListener(this));
    },

    /**
    */
    destroy:function() {
        if (this.layers != null) {
            for(var i=0; i< this.layers.length; i++) {
                this.layers[i].destroy();
            }
            this.layers = null;
        }
        if (this.controls != null) {
            for(var i=0; i< this.controls.length; i++) {
                this.controls[i].destroy();
            }
            this.controls = null;
        }
    },

    /**
    * @param {OpenLayers.Layer} layer
    */
    addLayer: function (layer, zIndex) {
        layer.setMap(this);
        layer.div.style.overflow = "";
        if (zIndex) {
            layer.div.style.zIndex = zIndex;
        } else {
            layer.div.style.zIndex = this.Z_INDEX_BASE['Layer'] + this.layers.length;
        }

        if (layer.viewPortLayer) {
            this.viewPortDiv.appendChild(layer.div);
        } else {
            this.layerContainerDiv.appendChild(layer.div);
        }
        this.layers.push(layer);
        this.events.triggerEvent("addlayer");
    },

    /** Removes a layer from the map by removing its visual element (the
     *   layer.div property), then removing it from the map's internal list
     *   of layers, setting the layer's map property to null.
     *
     *   a "removelayer" event is triggered.
     *
     *   very worthy of mention is that simply removing a layer from a map
     *   will not cause the removal of any popups which may have been created
     *   by the layer. this is due to the fact that it was decided at some
     *   point that popups would not belong to layers. thus there is no way
     *   for us to know here to which layer the popup belongs.
     *
     *     A simple solution to this is simply to call destroy() on the layer.
     *     the default OpenLayers.Layer class's destroy() function
     *     automatically takes care to remove itself from whatever map it has
     *     been attached to.
     *
     *     The correct solution is for the layer itself to register an
     *     event-handler on "removelayer" and when it is called, if it
     *     recognizes itself as the layer being removed, then it cycles through
     *     its own personal list of popups, removing them from the map.
     *
     * @param {OpenLayers.Layer} layer
     */
    removeLayer: function(layer) {
        this.layerContainerDiv.removeChild(layer.div);
        this.layers.remove(layer);
        layer.map = null;
        this.events.triggerEvent("removelayer");
    },

    /**
    * @param {Array(OpenLayers.Layer)} layers
    */
    addLayers: function (layers) {
        for (var i = 0; i <  layers.length; i++) {
            this.addLayer(layers[i]);
        }
    },

    /**
    * @param {OpenLayers.Control} control
    * @param {OpenLayers.Pixel} px
    */
    addControl: function (control, px) {
        control.map = this;
        this.controls.push(control);
        var div = control.draw(px);
        if (div) {
            div.style.zIndex = this.Z_INDEX_BASE['Control'] +
                                this.controls.length;
            this.viewPortDiv.appendChild( div );
        }
    },

    /**
    * @param {OpenLayers.Popup} popup
    */
    addPopup: function(popup) {
        popup.map = this;
        this.popups.push(popup);
        var popupDiv = popup.draw();
        if (popupDiv) {
            popupDiv.style.zIndex = this.Z_INDEX_BASE['Popup'] +
                                    this.popups.length;
            this.layerContainerDiv.appendChild(popupDiv);
        }
    },

    /**
    * @param {OpenLayers.Popup} popup
    */
    removePopup: function(popup) {
        this.popups.remove(popup);
        if (popup.div) {
            this.layerContainerDiv.removeChild(popup.div);
        }
        popup.map = null;
    },

    /**
    * @return {float}
    */
    getResolution: function () {
        // return degrees per pixel
        return this.maxResolution / Math.pow(2, this.zoom);
    },

    /**
    * @return {int}
    */
    getZoom: function () {
        return this.zoom;
    },

    /**
    * @returns {OpenLayers.Size}
    */
    getSize: function () {
        return this.size;
    },

    updateSize: function() {
        this.size = new OpenLayers.Size(
                    this.div.clientWidth, this.div.clientHeight);
        this.events.div.offsets = null;
        // Workaround for the fact that hidden elements return 0 for size.
        if (this.size.w == 0 && this.size.h == 0) {
            var dim = Element.getDimensions(this.div);
            this.size.w = dim.width;
            this.size.h = dim.height;
        }
    },
    /**
    * @return {OpenLayers.LonLat}
    */
    getCenter: function () {
        return this.center;
    },

    /**
    * @return {OpenLayers.Bounds}
    */
    getExtent: function () {
        if (this.center) {
            var res = this.getResolution();
            var size = this.getSize();
            var w_deg = size.w * res;
            var h_deg = size.h * res;
            return new OpenLayers.Bounds(
                this.center.lon - w_deg / 2,
                this.center.lat - h_deg / 2,
                this.center.lon + w_deg / 2,
                this.center.lat + h_deg / 2);
        } else {
            return null;
        }
    },

    /**
    * @return {OpenLayers.Bounds}
    */
    getFullExtent: function () {
        return this.maxExtent;
    },

    getZoomLevels: function() {
        return this.maxZoomLevel;
    },

    /**
    * @param {OpenLayers.Bounds} bounds
    *
    * @return {int}
    */
    getZoomForExtent: function (bounds) {
        var size = this.getSize();
        var width = bounds.getWidth();
        var height = bounds.getHeight();
        var deg_per_pixel = (width > height ? width / size.w : height / size.h);
        var zoom = Math.log(this.maxResolution / deg_per_pixel) / Math.log(2);
        return Math.floor(Math.min(Math.max(zoom, 0), this.getZoomLevels()));
    },

    /**
     * @param {OpenLayers.Pixel} layerPx
     *
     * @returns px translated into view port pixel coordinates
     * @type OpenLayers.Pixel
     */
    getViewPortPxFromLayerPx:function(layerPx) {
        var viewPortPx = layerPx.copyOf();

        viewPortPx.x += parseInt(this.layerContainerDiv.style.left);
        viewPortPx.y += parseInt(this.layerContainerDiv.style.top);

        return viewPortPx;
    },

    /**
     * @param {OpenLayers.Pixel} viewPortPx
     *
     * @returns px translated into view port pixel coordinates
     * @type OpenLayers.Pixel
     */
    getLayerPxFromViewPortPx:function(viewPortPx) {
        var layerPx = viewPortPx.copyOf();

        layerPx.x -= parseInt(this.layerContainerDiv.style.left);
        layerPx.y -= parseInt(this.layerContainerDiv.style.top);

        return layerPx;
    },

    /**
    * @param {OpenLayers.Pixel} px
    *
    * @return {OpenLayers.LonLat}
    */
    getLonLatFromLayerPx: function (px) {
       //adjust for displacement of layerContainerDiv
       px = this.getViewPortPxFromLayerPx(px);
       return this.getLonLatFromViewPortPx(px);
    },

    /**
    * @param {OpenLayers.Pixel} viewPortPx
    *
    * @returns An OpenLayers.LonLat which is the passed-in view port
    *          OpenLayers.Pixel, translated into lon/lat given the
    *          current extent and resolution
    * @type OpenLayers.LonLat
    */
    getLonLatFromViewPortPx: function (viewPortPx) {
        var center = this.getCenter();        //map center lon/lat
        var res  = this.getResolution();
        var size = this.getSize();

        var delta_x = viewPortPx.x - (size.w / 2);
        var delta_y = viewPortPx.y - (size.h / 2);

        return new OpenLayers.LonLat(center.lon + delta_x * res ,
                                     center.lat - delta_y * res);
    },

    /**
    * @param {OpenLayers.LonLat} lonlat
    *
    * @returns An OpenLayers.Pixel which is the passed-in OpenLayers.LonLat,
    *          translated into layer pixels given the current extent
    *          and resolution
    * @type OpenLayers.Pixel
    */
    getLayerPxFromLonLat: function (lonlat) {
       //adjust for displacement of layerContainerDiv
       var px = this.getViewPortPxFromLonLat(lonlat);
       return this.getLayerPxFromViewPortPx(px);
    },

    /**
    * @param {OpenLayers.LonLat} lonlat
    *
    * @returns An OpenLayers.Pixel which is the passed-in OpenLayers.LonLat,
    *          translated into view port pixels given the current extent
    *          and resolution
    * @type OpenLayers.Pixel
    */
    getViewPortPxFromLonLat: function (lonlat) {
        var resolution = this.getResolution();
        var extent = this.getExtent();
        return new OpenLayers.Pixel(
                       Math.round(1/resolution * (lonlat.lon - extent.left)),
                       Math.round(1/resolution * (extent.top - lonlat.lat))
                       );
    },

    /**
    * @param {OpenLayers.LonLat} lonlat
    * @param {int} zoom
    */
    setCenter: function (lonlat, zoom, minor) {
        if (this.center) { // otherwise there's nothing to move yet
            this.moveLayerContainer(lonlat);
        }
        this.center = lonlat.copyOf();
        var zoomChanged = null;
        if (zoom != null && zoom != this.zoom
            && zoom >= 0 && zoom <= this.getZoomLevels()) {
            zoomChanged = (this.zoom == null ? 0 : this.zoom);
            this.zoom = zoom;
        }

        if (!minor) this.events.triggerEvent("movestart");
        this.moveToNewExtent(zoomChanged);
        if (!minor) this.events.triggerEvent("moveend");
    },

    /**
     * ZOOM TO BOUNDS FUNCTION
     */

    moveToNewExtent: function (zoomChanged) {
        if (zoomChanged != null) { // reset the layerContainerDiv's location
            this.layerContainerDiv.style.left = "0px";
            this.layerContainerDiv.style.top  = "0px";

            //redraw popups
            for (var i = 0; i < this.popups.length; i++) {
                this.popups[i].updatePosition();
            }

        }
        var bounds = this.getExtent();
        for (var i = 0; i < this.layers.length; i++) {
            this.layers[i].moveTo(bounds, (zoomChanged != null));
        }
        this.events.triggerEvent("move");
        if (zoomChanged != null)
            this.events.triggerEvent("zoomend",
                {oldZoom: zoomChanged, newZoom: this.zoom});
    },

    /**
     * zoomIn
     * Increase zoom level by one.
     */
    zoomIn: function() {
        if (this.zoom != null && this.zoom <= this.getZoomLevels()) {
            this.zoomTo( this.zoom += 1 );
        }

    },

    /**
     * zoomTo
     * Set Zoom To int
     */
    zoomTo: function(zoom) {
       if (zoom >= 0 && zoom <= this.getZoomLevels()) {
            var oldZoom = this.zoom;
            this.zoom = zoom;
            this.moveToNewExtent(oldZoom);
       }
    },

    /**
     * zoomOut
     * Decrease zoom level by one.
     */
    zoomOut: function() {
        if (this.zoom != null && this.zoom > 0) {
            this.zoomTo( this.zoom - 1 );
        }
    },

    zoomExtent: function() {
        var fullExtent = this.getFullExtent();
        var oldZoom = this.zoom;
        this.setCenter(
          new OpenLayers.LonLat((fullExtent.left+fullExtent.right)/2,
                                (fullExtent.bottom+fullExtent.top)/2),
                                0
                               );
    },

    /**
    * @param {OpenLayers.LonLat} lonlat
    */
    moveLayerContainer: function (lonlat) {
        var container = this.layerContainerDiv;
        var resolution = this.getResolution();

        var deltaX = Math.round((this.center.lon - lonlat.lon) / resolution);
        var deltaY = Math.round((this.center.lat - lonlat.lat) / resolution);

        var offsetLeft = parseInt(container.style.left);
        var offsetTop  = parseInt(container.style.top);

        container.style.left = (offsetLeft + deltaX) + "px";
        container.style.top  = (offsetTop  - deltaY) + "px";
    },

    CLASS_NAME: "OpenLayers.Map"
};
<commit_msg>give Map the concept of a base layer<commit_after>// @require: OpenLayers/Util.js
/**
* @class
*
*
*/

OpenLayers.Map = Class.create();
OpenLayers.Map.prototype = {
    // Hash: base z-indexes for different classes of thing
    Z_INDEX_BASE: { Layer: 100, Popup: 200, Control: 1000 },

    // Array: supported application event types
    EVENT_TYPES: [
        "addlayer", "removelayer", "movestart", "move", "moveend",
        "zoomend", "layerchanged", "popupopen", "popupclose",
        "addmarker", "removemarker", "clearmarkers", "mouseover",
        "mouseout", "mousemove", "dragstart", "drag", "dragend" ],

    // int: zoom levels, used to draw zoom dragging control and limit zooming
    maxZoomLevel: 16,

    // OpenLayers.Bounds
    maxExtent: new OpenLayers.Bounds(-180, -90, 180, 90),

    /* projection */
    projection: "EPSG:4326",

    /** @type OpenLayers.Size */
    size: null,

    // float
    maxResolution: 1.40625, // degrees per pixel
                            // Default is whole world in 256 pixels, from GMaps

    // DOMElement: the div that our map lives in
    div: null,

    // HTMLDivElement: the map's view port
    viewPortDiv: null,

    // HTMLDivElement: the map's layer container
    layerContainerDiv: null,

    // Array(OpenLayers.Layer): ordered list of layers in the map
    layers: null,

    // Array(OpenLayers.Control)
    controls: null,

    // Array(OpenLayers.Popup)
    popups: null,

    // OpenLayers.LonLat
    center: null,

    // int
    zoom: null,

    // OpenLayers.Events
    events: null,

    // OpenLayers.Pixel
    mouseDragStart: null,

    /** @type OpenLayers.Layer */
    baseLayer: null,

    /**
    * @param {DOMElement} div
    */
    initialize: function (div, options) {
        Object.extend(this, options);

        this.div = div = $(div);

        // the viewPortDiv is the outermost div we modify
        var id = div.id + "_OpenLayers_ViewPort";
        this.viewPortDiv = OpenLayers.Util.createDiv(id, null, null, null,
                                                     "relative", null,
                                                     "hidden");
        this.viewPortDiv.style.width = "100%";
        this.viewPortDiv.style.height = "100%";
        this.div.appendChild(this.viewPortDiv);

        // the layerContainerDiv is the one that holds all the layers
        id = div.id + "_OpenLayers_Container";
        this.layerContainerDiv = OpenLayers.Util.createDiv(id);
        this.viewPortDiv.appendChild(this.layerContainerDiv);

        this.events = new OpenLayers.Events(this, div, this.EVENT_TYPES);

        this.updateSize();
        // make the entire maxExtent fix in zoom level 0 by default
        if (this.maxResolution == null || this.maxResolution == "auto") {
            this.maxResolution = Math.max(
                this.maxExtent.getWidth()  / this.size.w,
                this.maxExtent.getHeight() / this.size.h );
        }
        // update the internal size register whenever the div is resized
        this.events.register("resize", this, this.updateSize);

        this.layers = [];

        if (!this.controls) {
            this.controls = [];
            this.addControl(new OpenLayers.Control.MouseDefaults());
            this.addControl(new OpenLayers.Control.PanZoom());
        }

        this.popups = new Array();

        // always call map.destroy()
        Event.observe(window, 'unload',
            this.destroy.bindAsEventListener(this));
    },

    /**
    */
    destroy:function() {
        if (this.layers != null) {
            for(var i=0; i< this.layers.length; i++) {
                this.layers[i].destroy();
            }
            this.layers = null;
        }
        if (this.controls != null) {
            for(var i=0; i< this.controls.length; i++) {
                this.controls[i].destroy();
            }
            this.controls = null;
        }
    },

    /**
    * @param {OpenLayers.Layer} layer
    */
    addLayer: function (layer, zIndex) {
        layer.setMap(this);
        layer.div.style.overflow = "";
        if (zIndex) {
            layer.div.style.zIndex = zIndex;
        } else {
            layer.div.style.zIndex = this.Z_INDEX_BASE['Layer'] + this.layers.length;
        }

        if (layer.viewPortLayer) {
            this.viewPortDiv.appendChild(layer.div);
        } else {
            this.layerContainerDiv.appendChild(layer.div);
        }
        this.layers.push(layer);

        if (layer.isBaseLayer()) {
            this.baseLayer = layer;
        }
        this.events.triggerEvent("addlayer");
    },

    /** Removes a layer from the map by removing its visual element (the
     *   layer.div property), then removing it from the map's internal list
     *   of layers, setting the layer's map property to null.
     *
     *   a "removelayer" event is triggered.
     *
     *   very worthy of mention is that simply removing a layer from a map
     *   will not cause the removal of any popups which may have been created
     *   by the layer. this is due to the fact that it was decided at some
     *   point that popups would not belong to layers. thus there is no way
     *   for us to know here to which layer the popup belongs.
     *
     *     A simple solution to this is simply to call destroy() on the layer.
     *     the default OpenLayers.Layer class's destroy() function
     *     automatically takes care to remove itself from whatever map it has
     *     been attached to.
     *
     *     The correct solution is for the layer itself to register an
     *     event-handler on "removelayer" and when it is called, if it
     *     recognizes itself as the layer being removed, then it cycles through
     *     its own personal list of popups, removing them from the map.
     *
     * @param {OpenLayers.Layer} layer
     */
    removeLayer: function(layer) {
        this.layerContainerDiv.removeChild(layer.div);
        this.layers.remove(layer);
        layer.map = null;
        this.events.triggerEvent("removelayer");
    },

    /**
    * @param {Array(OpenLayers.Layer)} layers
    */
    addLayers: function (layers) {
        for (var i = 0; i <  layers.length; i++) {
            this.addLayer(layers[i]);
        }
    },

    /**
    * @param {OpenLayers.Control} control
    * @param {OpenLayers.Pixel} px
    */
    addControl: function (control, px) {
        control.map = this;
        this.controls.push(control);
        var div = control.draw(px);
        if (div) {
            div.style.zIndex = this.Z_INDEX_BASE['Control'] +
                                this.controls.length;
            this.viewPortDiv.appendChild( div );
        }
    },

    /**
    * @param {OpenLayers.Popup} popup
    */
    addPopup: function(popup) {
        popup.map = this;
        this.popups.push(popup);
        var popupDiv = popup.draw();
        if (popupDiv) {
            popupDiv.style.zIndex = this.Z_INDEX_BASE['Popup'] +
                                    this.popups.length;
            this.layerContainerDiv.appendChild(popupDiv);
        }
    },

    /**
    * @param {OpenLayers.Popup} popup
    */
    removePopup: function(popup) {
        this.popups.remove(popup);
        if (popup.div) {
            this.layerContainerDiv.removeChild(popup.div);
        }
        popup.map = null;
    },

    /**
    * @return {float}
    */
    getResolution: function () {
        // return degrees per pixel
        return this.maxResolution / Math.pow(2, this.zoom);
    },

    /**
    * @return {int}
    */
    getZoom: function () {
        return this.zoom;
    },

    /**
    * @returns {OpenLayers.Size}
    */
    getSize: function () {
        return this.size;
    },

    updateSize: function() {
        this.size = new OpenLayers.Size(
                    this.div.clientWidth, this.div.clientHeight);
        this.events.div.offsets = null;
        // Workaround for the fact that hidden elements return 0 for size.
        if (this.size.w == 0 && this.size.h == 0) {
            var dim = Element.getDimensions(this.div);
            this.size.w = dim.width;
            this.size.h = dim.height;
        }
    },
    /**
    * @return {OpenLayers.LonLat}
    */
    getCenter: function () {
        return this.center;
    },

    /**
    * @return {OpenLayers.Bounds}
    */
    getExtent: function () {
        if (this.center) {
            var res = this.getResolution();
            var size = this.getSize();
            var w_deg = size.w * res;
            var h_deg = size.h * res;
            return new OpenLayers.Bounds(
                this.center.lon - w_deg / 2,
                this.center.lat - h_deg / 2,
                this.center.lon + w_deg / 2,
                this.center.lat + h_deg / 2);
        } else {
            return null;
        }
    },

    /**
    * @return {OpenLayers.Bounds}
    */
    getFullExtent: function () {
        return this.maxExtent;
    },

    getZoomLevels: function() {
        return this.maxZoomLevel;
    },

    /**
    * @param {OpenLayers.Bounds} bounds
    *
    * @return {int}
    */
    getZoomForExtent: function (bounds) {
        var size = this.getSize();
        var width = bounds.getWidth();
        var height = bounds.getHeight();
        var deg_per_pixel = (width > height ? width / size.w : height / size.h);
        var zoom = Math.log(this.maxResolution / deg_per_pixel) / Math.log(2);
        return Math.floor(Math.min(Math.max(zoom, 0), this.getZoomLevels()));
    },

    /**
     * @param {OpenLayers.Pixel} layerPx
     *
     * @returns px translated into view port pixel coordinates
     * @type OpenLayers.Pixel
     */
    getViewPortPxFromLayerPx:function(layerPx) {
        var viewPortPx = layerPx.copyOf();

        viewPortPx.x += parseInt(this.layerContainerDiv.style.left);
        viewPortPx.y += parseInt(this.layerContainerDiv.style.top);

        return viewPortPx;
    },

    /**
     * @param {OpenLayers.Pixel} viewPortPx
     *
     * @returns px translated into view port pixel coordinates
     * @type OpenLayers.Pixel
     */
    getLayerPxFromViewPortPx:function(viewPortPx) {
        var layerPx = viewPortPx.copyOf();

        layerPx.x -= parseInt(this.layerContainerDiv.style.left);
        layerPx.y -= parseInt(this.layerContainerDiv.style.top);

        return layerPx;
    },

    /**
    * @param {OpenLayers.Pixel} px
    *
    * @return {OpenLayers.LonLat}
    */
    getLonLatFromLayerPx: function (px) {
       //adjust for displacement of layerContainerDiv
       px = this.getViewPortPxFromLayerPx(px);
       return this.getLonLatFromViewPortPx(px);
    },

    /**
    * @param {OpenLayers.Pixel} viewPortPx
    *
    * @returns An OpenLayers.LonLat which is the passed-in view port
    *          OpenLayers.Pixel, translated into lon/lat given the
    *          current extent and resolution
    * @type OpenLayers.LonLat
    */
    getLonLatFromViewPortPx: function (viewPortPx) {
        var center = this.getCenter();        //map center lon/lat
        var res  = this.getResolution();
        var size = this.getSize();

        var delta_x = viewPortPx.x - (size.w / 2);
        var delta_y = viewPortPx.y - (size.h / 2);

        return new OpenLayers.LonLat(center.lon + delta_x * res ,
                                     center.lat - delta_y * res);
    },

    /**
    * @param {OpenLayers.LonLat} lonlat
    *
    * @returns An OpenLayers.Pixel which is the passed-in OpenLayers.LonLat,
    *          translated into layer pixels given the current extent
    *          and resolution
    * @type OpenLayers.Pixel
    */
    getLayerPxFromLonLat: function (lonlat) {
       //adjust for displacement of layerContainerDiv
       var px = this.getViewPortPxFromLonLat(lonlat);
       return this.getLayerPxFromViewPortPx(px);
    },

    /**
    * @param {OpenLayers.LonLat} lonlat
    *
    * @returns An OpenLayers.Pixel which is the passed-in OpenLayers.LonLat,
    *          translated into view port pixels given the current extent
    *          and resolution
    * @type OpenLayers.Pixel
    */
    getViewPortPxFromLonLat: function (lonlat) {
        var resolution = this.getResolution();
        var extent = this.getExtent();
        return new OpenLayers.Pixel(
                       Math.round(1/resolution * (lonlat.lon - extent.left)),
                       Math.round(1/resolution * (extent.top - lonlat.lat))
                       );
    },

    /**
    * @param {OpenLayers.LonLat} lonlat
    * @param {int} zoom
    */
    setCenter: function (lonlat, zoom, minor) {
        if (this.center) { // otherwise there's nothing to move yet
            this.moveLayerContainer(lonlat);
        }
        this.center = lonlat.copyOf();
        var zoomChanged = null;
        if (zoom != null && zoom != this.zoom
            && zoom >= 0 && zoom <= this.getZoomLevels()) {
            zoomChanged = (this.zoom == null ? 0 : this.zoom);
            this.zoom = zoom;
        }

        if (!minor) this.events.triggerEvent("movestart");
        this.moveToNewExtent(zoomChanged);
        if (!minor) this.events.triggerEvent("moveend");
    },

    /**
     * ZOOM TO BOUNDS FUNCTION
     */

    moveToNewExtent: function (zoomChanged) {
        if (zoomChanged != null) { // reset the layerContainerDiv's location
            this.layerContainerDiv.style.left = "0px";
            this.layerContainerDiv.style.top  = "0px";

            //redraw popups
            for (var i = 0; i < this.popups.length; i++) {
                this.popups[i].updatePosition();
            }

        }
        var bounds = this.getExtent();
        for (var i = 0; i < this.layers.length; i++) {
            this.layers[i].moveTo(bounds, (zoomChanged != null));
        }
        this.events.triggerEvent("move");
        if (zoomChanged != null)
            this.events.triggerEvent("zoomend",
                {oldZoom: zoomChanged, newZoom: this.zoom});
    },

    /**
     * zoomIn
     * Increase zoom level by one.
     */
    zoomIn: function() {
        if (this.zoom != null && this.zoom <= this.getZoomLevels()) {
            this.zoomTo( this.zoom += 1 );
        }

    },

    /**
     * zoomTo
     * Set Zoom To int
     */
    zoomTo: function(zoom) {
       if (zoom >= 0 && zoom <= this.getZoomLevels()) {
            var oldZoom = this.zoom;
            this.zoom = zoom;
            this.moveToNewExtent(oldZoom);
       }
    },

    /**
     * zoomOut
     * Decrease zoom level by one.
     */
    zoomOut: function() {
        if (this.zoom != null && this.zoom > 0) {
            this.zoomTo( this.zoom - 1 );
        }
    },

    zoomExtent: function() {
        var fullExtent = this.getFullExtent();
        var oldZoom = this.zoom;
        this.setCenter(
          new OpenLayers.LonLat((fullExtent.left+fullExtent.right)/2,
                                (fullExtent.bottom+fullExtent.top)/2),
                                0
                               );
    },

    /**
    * @param {OpenLayers.LonLat} lonlat
    */
    moveLayerContainer: function (lonlat) {
        var container = this.layerContainerDiv;
        var resolution = this.getResolution();

        var deltaX = Math.round((this.center.lon - lonlat.lon) / resolution);
        var deltaY = Math.round((this.center.lat - lonlat.lat) / resolution);

        var offsetLeft = parseInt(container.style.left);
        var offsetTop  = parseInt(container.style.top);

        container.style.left = (offsetLeft + deltaX) + "px";
        container.style.top  = (offsetTop  - deltaY) + "px";
    },

    CLASS_NAME: "OpenLayers.Map"
};
<|endoftext|>


<commit_before>const initialState = {
  gettingList     : false,
  list            : [],
  gettingStatuses : false,
  statuses        : []
};

export default function listsReducer (state = initialState, action) {
  switch (action.type) {
    case 'SYSTEM_ERROR':
      return {
        ...state,
        gettingList     : false,
        gettingStatuses : false
      };

    case 'REQUEST_GET_LIST':
      return {
        ...state,
        gettingList     : true
      };

    case 'SUCCESS_GET_LIST':
      return {
        ...state,
        gettingList : false,
        list : action.payload.data
      };

    case 'FAILURE_GET_LIST':
      return {
        ...state,
        gettingList : false
      };

    case 'REQUEST_GET_LISTS_STATUSES':
      return {
        ...state,
        gettingStatuses : true
      };

    case 'SUCCESS_GET_LISTS_STATUSES':
      return {
        ...state,
        gettingStatuses : false,
        statuses : action.payload.data
      };

    case 'FAILURE_GET_LISTS_STATUSES':
      return {
        ...state,
        gettingStatuses : false
      };

    case 'SUCCESS_STREAM_SITE':
      return {
        ...state,
        statuses : [
          action.payload.data,
          ...state.statuses
        ]
      };

    case 'RESET_TIMELINE':
      return {
        ...state,
        list : [],
        statuses : []
      };

    default:
      break;
  }
  return state;
};
<commit_msg>[fix] list favorite bug<commit_after>const initialState = {
  gettingList     : false,
  list            : [],
  gettingStatuses : false,
  statuses        : []
};

export default function listsReducer (state = initialState, action) {
  switch (action.type) {
    case 'SYSTEM_ERROR':
      return {
        ...state,
        gettingList     : false,
        gettingStatuses : false
      };

    case 'REQUEST_GET_LIST':
      return {
        ...state,
        gettingList     : true
      };

    case 'SUCCESS_GET_LIST':
      return {
        ...state,
        gettingList : false,
        list : action.payload.data
      };

    case 'FAILURE_GET_LIST':
      return {
        ...state,
        gettingList : false
      };

    case 'REQUEST_GET_LISTS_STATUSES':
      return {
        ...state,
        gettingStatuses : true
      };

    case 'SUCCESS_GET_LISTS_STATUSES':
      return {
        ...state,
        gettingStatuses : false,
        statuses : action.payload.data
      };

    case 'FAILURE_GET_LISTS_STATUSES':
      return {
        ...state,
        gettingStatuses : false
      };

    case 'SUCCESS_POST_FAVORITES_CREATE':
      return {
        ...state,
        statuses : state.statuses.map((tweet) => {
          if (tweet.id_str === action.payload.id) {
            return Object.assign({}, tweet, {
              favorite_count : tweet.favorite_count + 1,
              favorited : true
            });
          }
          return tweet;
        })
      };

    case 'SUCCESS_POST_FAVORITES_DESTROY':
      return {
        ...state,
        statuses : state.statuses.map((tweet) => {
          if (tweet.id_str === action.payload.id) {
            return Object.assign({}, tweet, {
              favorite_count : tweet.favorite_count - 1,
              favorited : false
            });
          }
          return tweet;
        })
      };

    case 'SUCCESS_STREAM_SITE':
      return {
        ...state,
        statuses : [
          action.payload.data,
          ...state.statuses
        ]
      };

    case 'RESET_TIMELINE':
      return {
        ...state,
        list : [],
        statuses : []
      };

    default:
      break;
  }
  return state;
};
<|endoftext|>


<commit_before>import moment from 'moment';
import filter from 'lodash/filter';
import { LOAD } from 'redux-storage';
import {
  ADD_AD_HOC_RACE,
  ADD_RACES,
  REMOVE_RACE,
  CHANGE_RACE_ORDER,
  START_RACE,
  RESTART_RACE,
  END_ONGOING_RACE,
  UPDATE_RACE,
  FINISH_RACER,
  FINISH_ONGOING_RACE
} from '../actions/race';

window.newRaceId = null;

export default function races(state = [], action) {
  switch (action.type) {
    case LOAD: {
      // update all races to not be current
      const savedRaces = action.payload.races;
      if (window.newRaceId === null) {
        window.newRaceId = savedRaces.length > 0 ? (savedRaces.map(race => race.id).reduce(
          (idA, idB) => (idA > idB ? idA : idB)
        ) + 1) : 0;
      }
      return state.map(race => ({ ...race, current: false }));
    }
    case ADD_AD_HOC_RACE: {
      const race = {
        id: (window.newRaceId += 1),
        bikeRacerMap: {},
        createdDate: moment(),
        results: new Array(action.bikes.length).fill(null),
      };
      action.bikes.forEach((_, i) => {
        race.bikeRacerMap[i] = -1;
      });

      return [
        race,
        ...state
      ];
    }
    case ADD_RACES: {
      const newRaces = [];
      const numOfBikes = action.bikes.length;
      for (let i = 0; i < Math.ceil(action.racerIds.length / action.bikes.length); i += 1) {
        const bikeRacerMap = {};
        action.racerIds.slice(i * numOfBikes,
          Math.min((i + 1) * numOfBikes, action.racerIds.length)
        )
          .forEach((racerId, index) => {
            bikeRacerMap[index] = racerId;
          });
        newRaces.push({
          id: window.newRaceId += 1,
          bikeRacerMap,
          createdDate: moment(),
          results: new Array(numOfBikes).fill(null)
        });
      }
      return [
        ...state,
        ...newRaces
      ];
    }

    case UPDATE_RACE:
      return state.map((race) => {
        if (race.id === action.race.id) {
          return action.race;
        }
        return race;
      });

    case REMOVE_RACE:
      return state.map((race) => {
        if (race.id === action.id) {
          return Object.assign({}, race, { deleted: true, deletedDate: moment() });
        }
        return race;
      });

    case CHANGE_RACE_ORDER: {
      const raceOne = state.filter(race => race.id === action.id)[0];
      const raceTwo = state.filter(race => race.id === action.secondId)[0];
      return state.map((race) => {
        if (race.id === action.id) {
          return raceTwo;
        }
        if (race.id === action.secondId) {
          return raceOne;
        }
        return race;
      });
    }

    case START_RACE:
      return state.map((race) => {
        if (race.id === action.id) {
          return Object.assign({}, race, { startTime: moment(), current: true });
        }
        return race;
      });

    case RESTART_RACE:
      return state.map((race) => {
        if (race.id === action.id) {
          const newRace = Object.assign({}, race);
          delete newRace.startTime;
          delete newRace.finishTime;
          newRace.results = new Array(newRace.results.length).fill(null);
          return newRace;
        }
        return race;
      });

    case FINISH_RACER:
      return state.map((race) => {
        if (race.current) {
          if (race.results[action.bikeIndex] !== null) {
            return race;
          }
          const nextRace = { ...race };
          nextRace.results[action.bikeIndex] = getPlace(nextRace);

          return nextRace;
        }
        return race;
      });
    case FINISH_ONGOING_RACE:
      return state.map((race) => {
        if (race.current) {
          return { ...race,
            current: false,
            finished: true,
            finishedDate: moment(),
          };
        }
        return race;
      });
    case END_ONGOING_RACE:
      return state.map((race) => {
        if (race.id === action.race.id) {
          const results = [...action.race.results];
          results.forEach((_, i) => {
            if (!action.race.results[i]) {
              results[i] = { place: -1 };
            }
          });
          return {
            ...action.race,
            finishedDate: moment(),
            current: false,
            results
          };
        }
        return race;
      });

    default:
      return state;
  }
}

function getPlace(state) {
  const place = { finishTime: moment() };
  // what place are they?
  place.place = filter(state.results, 'place').length + 1;
  return place;
}
<commit_msg>Formatting fixes<commit_after>import moment from 'moment';
import filter from 'lodash/filter';
import { LOAD } from 'redux-storage';
import {
  ADD_AD_HOC_RACE,
  ADD_RACES,
  REMOVE_RACE,
  CHANGE_RACE_ORDER,
  START_RACE,
  RESTART_RACE,
  END_ONGOING_RACE,
  UPDATE_RACE,
  FINISH_RACER,
  FINISH_ONGOING_RACE
} from '../actions/race';

window.newRaceId = null;

export default function races(state = [], action) {
  switch (action.type) {
    case LOAD: {
      // update all races to not be current
      const savedRaces = action.payload.races;
      if (window.newRaceId === null) {
        window.newRaceId = savedRaces.length > 0 ? (savedRaces.map(race => race.id).reduce(
          (idA, idB) => (idA > idB ? idA : idB)
        ) + 1) : 0;
      }
      return state.map(race => ({ ...race, current: false }));
    }
    case ADD_AD_HOC_RACE: {
      const race = {
        id: (window.newRaceId += 1),
        bikeRacerMap: {},
        createdDate: moment(),
        results: new Array(action.bikes.length).fill(null),
      };

      action.bikes.forEach((_, i) => {
        race.bikeRacerMap[i] = -1;
      });

      return [
        race,
        ...state
      ];
    }
    case ADD_RACES: {
      const newRaces = [];
      const numOfBikes = action.bikes.length;
      for (let i = 0; i < Math.ceil(action.racerIds.length / action.bikes.length); i += 1) {
        const bikeRacerMap = {};
        action.racerIds.slice(i * numOfBikes,
          Math.min((i + 1) * numOfBikes, action.racerIds.length)
        )
          .forEach((racerId, index) => {
            bikeRacerMap[index] = racerId;
          });
        newRaces.push({
          id: window.newRaceId += 1,
          bikeRacerMap,
          createdDate: moment(),
          results: new Array(numOfBikes).fill(null)
        });
      }
      return [
        ...state,
        ...newRaces
      ];
    }

    case UPDATE_RACE:
      return state.map((race) => {
        if (race.id === action.race.id) {
          return action.race;
        }
        return race;
      });

    case REMOVE_RACE:
      return state.map((race) => {
        if (race.id === action.id) {
          return Object.assign({}, race, { deleted: true, deletedDate: moment() });
        }
        return race;
      });

    case CHANGE_RACE_ORDER: {
      const raceOne = state.filter(race => race.id === action.id)[0];
      const raceTwo = state.filter(race => race.id === action.secondId)[0];
      return state.map((race) => {
        if (race.id === action.id) {
          return raceTwo;
        }
        if (race.id === action.secondId) {
          return raceOne;
        }
        return race;
      });
    }

    case START_RACE:
      return state.map((race) => {
        if (race.id === action.id) {
          return Object.assign({}, race, { startTime: moment(), current: true });
        }
        return race;
      });

    case RESTART_RACE:
      return state.map((race) => {
        if (race.id === action.id) {
          const newRace = Object.assign({}, race);
          delete newRace.startTime;
          delete newRace.finishTime;
          newRace.results = new Array(newRace.results.length).fill(null);
          return newRace;
        }
        return race;
      });

    case FINISH_RACER:
      return state.map((race) => {
        if (race.current) {
          if (race.results[action.bikeIndex] !== null) {
            return race;
          }
          const nextRace = { ...race };
          nextRace.results[action.bikeIndex] = getPlace(nextRace);

          return nextRace;
        }
        return race;
      });
    case FINISH_ONGOING_RACE:
      return state.map((race) => {
        if (race.current) {
          return {
            ...race,
            current: false,
            finished: true,
            finishedDate: moment()
          };
        }
        return race;
      });
    case END_ONGOING_RACE:
      return state.map((race) => {
        if (race.id === action.race.id) {
          const results = [...action.race.results];
          results.forEach((_, i) => {
            if (!action.race.results[i]) {
              results[i] = { place: -1 };
            }
          });
          return {
            ...action.race,
            finishedDate: moment(),
            current: false,
            results
          };
        }
        return race;
      });

    default:
      return state;
  }
}

function getPlace(state) {
  const place = { finishTime: moment() };
  // what place are they?
  place.place = filter(state.results, 'place').length + 1;
  return place;
}
<|endoftext|>


<commit_before>const express = require('express');
const router  = express.Router();
const Evento  = require('../models/evento');
const middlewareAuth = require('../utils/middlewareAuth');
const moment = require('moment');

router.post('/', middlewareAuth, function(req, res) {
  let evento = new Evento(req.body);
  evento.save(function(err) {

    if (err) {
      res.send(err);
    }
    res.json({
      message: 'Event created',
      event: evento
    });

  });
});

router.get('/', function(req, res) {
  let filtro = {};
  const formatos = [
    "YYYY-MM-DD",
    "DD-MM-YYYY"
  ];

  if (req.query.passados) {

    filtro['data.inicio'] = {
      $lte: moment().startOf('day').format()
    }

  } else {

    let intervalo = {};

    if (req.query.after && moment(req.query.after, formatos).isValid()) {
      intervalo.$gte = moment(req.query.after, formatos).startOf('day').format();
    }

    if (req.query.before && moment(req.query.before, formatos).isValid()) {
      intervalo.$lte = moment(req.query.before, formatos).endOf('day').format();
    }

    filtro['data.inicio'] = intervalo;

  }

  if (Object.keys(filtro).length === 0) {
    filtro['data.inicio'] = {
      $gte: moment().startOf('day').format()
    };
  }

  Evento
    .find(filtro, function(err, eventos) {
      if (err) {
        res.send(err);
      }
      res.json(eventos);
    })
    .sort('data.inicio')
  ;
});

router.get('/:id', function(req, res) {
  Evento.findById(req.params.id, function(err, evento) {
    if (err) {
      res.send(err);
    }
    res.json(evento);
  });
});

router.put('/:id', middlewareAuth, function(req, res) {
  Evento.findOneAndUpdate({
    _id: req.params.id
  }, req.body, { new: true }, function(err, evento) {

    if (err) {
      res.send(err);
    }
    res.send({
      message:"Event updated",
      event: evento
    });

  });
});

router.delete('/:id', middlewareAuth, function(req, res) {
  Evento.remove({ _id: req.params.id }, function(err) {
    if (err) {
      res.send(err);
    }
    res.json({ message: 'Event removed' });
  });
});

module.exports = router;
<commit_msg>organizando e corrigindo bugs<commit_after>const express = require('express');
const router  = express.Router();
const Evento  = require('../models/evento');
const middlewareAuth = require('../utils/middlewareAuth');
const moment = require('moment');

router.post('/', middlewareAuth, function(req, res) {
  let evento = new Evento(req.body);
  evento.save(function(err) {

    if (err) {
      res.send(err);
    }
    res.json({
      message: 'Event created',
      event: evento
    });

  });
});

router.get('/', function(req, res) {
  let filtro = {};
  const formatos = [
    "YYYY-MM-DD",
    "DD-MM-YYYY"
  ];

  let intervalo = {};

  if (req.query.after && moment(req.query.after, formatos).isValid()) {
    intervalo.$gte = moment(req.query.after, formatos).startOf('day').format();
  }

  if (req.query.before && moment(req.query.before, formatos).isValid()) {
    intervalo.$lte = moment(req.query.before, formatos).endOf('day').format();
  }

  filtro['data.inicio'] = (Object.keys(intervalo).length === 0)
    ? { $gte: moment().startOf('day').format() }
    : intervalo
  ;

  Evento
    .find(filtro, function(err, eventos) {
      if (err) {
        res.send(err);
      }
      res.json(eventos);
    })
    .sort('data.inicio')
  ;
});

router.get('/passados', function(req, res) {
  Evento
    .find({
      'data.inicio': { $lte: moment().startOf('day').format() }
    }, function(err, eventos) {
      if (err) {
        res.send(err);
      }
      res.json(eventos);
    })
    .sort('data.inicio')
  ;
});

router.get('/:id', function(req, res) {
  Evento.findById(req.params.id, function(err, evento) {
    if (err) {
      res.send(err);
    }
    res.json(evento);
  });
});

router.put('/:id', middlewareAuth, function(req, res) {
  Evento.findOneAndUpdate({
    _id: req.params.id
  }, req.body, { new: true }, function(err, evento) {

    if (err) {
      res.send(err);
    }
    res.send({
      message:"Event updated",
      event: evento
    });

  });
});

router.delete('/:id', middlewareAuth, function(req, res) {
  Evento.remove({ _id: req.params.id }, function(err) {
    if (err) {
      res.send(err);
    }
    res.json({ message: 'Event removed' });
  });
});

module.exports = router;
<|endoftext|>


<commit_before>var Estate = new Backbone.Marionette.Application();

Estate.addRegions({
  agency: '#agency',
  listings: '#listings'
});

Estate.addInitializer(function() {
  new Router();
});

Estate.on('initialize:after', function() {
  Backbone.history.start();
});

var Listing = Backbone.Model.extend();

var Listings = Backbone.Collection.extend({
  model: Listing,
  urlRoot: 'http://api.emlakabc.com/2013-08-30/agencies',

  url: function() {
    return this.urlRoot + '/' + this.id + '/listings';
  },

  parse: function(res) {
    return res.listings;
  },

  initialize: function(id) {
    this.id = id;
  }
});

var ListingView = Backbone.Marionette.ItemView.extend({
  template: "#listing-template",
  tagName: 'tr',

  events: { },

  initialize: function() {}
});

var ListingsView = Backbone.Marionette.CollectionView.extend({
  tagName: "table",
  id: "listings",
  template: "#listings-template",
  itemView: ListingView,

  initialize: function() {
  },
});

var Router = Backbone.Router.extend({
  routes: {
    ':id': 'getListings'
  },
  getListings: function(id) {
    listings = new Listings(id);
    listings.fetch({
      success: function() {
        console.log(listings);
        listingsView = new ListingsView({
          collection: listings
        });
        Estate.listings.show(listingsView);
      },
      error:function(e) {
          alert(' Service request failure: ' + e);
      }
    });
  }
});
<commit_msg>minifix<commit_after>var Estate = new Backbone.Marionette.Application();

Estate.addRegions({
  agency: '#agency',
  listings: '#listings'
});

Estate.addInitializer(function() {
  new Router();
  Backbone.history.start();
});

var Listing = Backbone.Model.extend();

var Listings = Backbone.Collection.extend({
  model: Listing,
  urlRoot: 'http://api.emlakabc.com/2013-08-30/agencies',

  url: function() {
    return this.urlRoot + '/' + this.id + '/listings?page=' + this.page;
  },

  parse: function(res) {
    return res.listings;
  },

  initialize: function(id, page) {
    this.id = id;
    this.page = page || 1;
  }
});

var ListingView = Backbone.Marionette.ItemView.extend({
  template: "#listing-template",
  tagName: 'tr',
});

var ListingsView = Backbone.Marionette.CollectionView.extend({
  tagName: "table",
  id: "listings",
  template: "#listings-template",
  itemView: ListingView,
});

var Router = Backbone.Router.extend({
  routes: {
    ':id': 'getListings',
    ':id/:page': 'getListings'
  },

  getListings: function(id, page) {
    listings = new Listings(id, page);
    listings.fetch({
      success: function() {
        listingsView = new ListingsView({
          collection: listings
        });
        Estate.listings.show(listingsView);
      },
      error:function(e) {
          alert(' Service request failure: ' + e);
      }
    });
  }
});
<|endoftext|>


<commit_before>'use strict';
(function() {
    /**
     * 基本配置
     * */
    var BaseConf = {
        DEBUG: true,
        BSU: "../erp_server/gateway.php?s=/",
        Prefix: "ones"
    };

    angular.module("ones.configModule", [])
            .factory("ones.config", [function() {
                    try{
                        var localValue = angular.fromJson(localStorage.getItem("ones.config"));
                        if (localValue) {
                            return localValue;
                        }
                    } catch(err) {
                        return BaseConf;
                    }

                    return BaseConf;
                }])
            .run(["$rootScope", "$http", "$injector", "$location", function($rootScope, $http, $injector, $location) {
                    var loginHash = uriParamsGet('hash');
                    if ($location.url() && !loginHash) {
                        window.location.href = 'index.html';
                    }

                    $http.defaults.headers.common["sessionHash"] = loginHash;
                    $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
                    $http.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";

                    try {
                        var configRes = $injector.get("ConfigRes");
                        /**
                         * 加载配置
                         * */
                        configRes.query({
                            queryAll: true
                        }).$promise.then(function(data) {
                            angular.forEach(data, function(item) {
                                BaseConf[item.alias] = item.value;
                            });
                            localStorage.setItem("ones.config", angular.toJson(BaseConf));
                        });
                    } catch (err) {

                    }

                    /**
                     * 加载语言包
                     * */
                    $rootScope.i18n = angular.fromJson(localStorage.getItem(BaseConf.Prefix + "i18n"));
                    if (BaseConf.DEBUG || !$rootScope.i18n) {
                        $http.get("scripts/i18n/zh-cn.json").success(function(data) {
                            $rootScope.i18n = data;
                            localStorage.setItem(BaseConf.Prefix + "i18n", angular.toJson(data));
                        });
                    }
                }])
            ;
})();
<commit_msg>no message<commit_after>'use strict';
(function() {
    /**
     * 基本配置
     * */
    var BaseConf = {
        DEBUG: false,
        BSU: "../erp_server/gateway.php?s=/",
        Prefix: "ones"
    };

    angular.module("ones.configModule", [])
            .factory("ones.config", [function() {
                    try{
                        var localValue = angular.fromJson(localStorage.getItem("ones.config"));
                        if (localValue) {
                            return localValue;
                        }
                    } catch(err) {
                        return BaseConf;
                    }

                    return BaseConf;
                }])
            .run(["$rootScope", "$http", "$injector", "$location", function($rootScope, $http, $injector, $location) {
                    var loginHash = uriParamsGet('hash');
                    if ($location.url() && !loginHash) {
                        window.location.href = 'index.html';
                    }

                    $http.defaults.headers.common["sessionHash"] = loginHash;
                    $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
                    $http.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";

                    try {
                        var configRes = $injector.get("ConfigRes");
                        /**
                         * 加载配置
                         * */
                        configRes.query({
                            queryAll: true
                        }).$promise.then(function(data) {
                            angular.forEach(data, function(item) {
                                BaseConf[item.alias] = item.value;
                            });
                            localStorage.setItem("ones.config", angular.toJson(BaseConf));
                        });
                    } catch (err) {

                    }

                    /**
                     * 加载语言包
                     * */
                    $rootScope.i18n = angular.fromJson(localStorage.getItem(BaseConf.Prefix + "i18n"));
                    if (BaseConf.DEBUG || !$rootScope.i18n) {
                        $http.get("scripts/i18n/zh-cn.json").success(function(data) {
                            $rootScope.i18n = data;
                            localStorage.setItem(BaseConf.Prefix + "i18n", angular.toJson(data));
                        });
                    }
                }])
            ;
})();
<|endoftext|>


<commit_before>define(['d3', 'lib/knockout', 'scripts/Utils', 'dagre-d3', 'jquery', 'jquery.tipsy'],
  function (d3, ko, Utils, dagreD3, $) {
    'use strict';
    function renderPage(skills_data) {
      var g = new dagreD3.graphlib.Graph().setGraph({});

      ko.utils.arrayForEach(skills_data.skills, function (skill) {
        var value = skill;
        value.label = skill.name;
        value.rx = value.ry = 5;
        g.setNode(skill.name, value);
      });

      ko.utils.arrayForEach(skills_data.skills, function (skill) {
        var skill_id = skill.id;
        if (skill.depends) {
          ko.utils.arrayForEach(skill.depends, function (id) {
	          var dependents_name = skills_data.skills[id - 1].name;
	          var skill_name = skills_data.skills[skill_id - 1].name;
            g.setEdge(dependents_name, skill_name, {label: ""});
          });
        }
      });

      var render = new dagreD3.render();

      var svg = d3.select("svg"),
        inner = svg.append("g");

      var zoom = d3.behavior.zoom().on("zoom", function () {
        inner.attr("transform", "translate(" + d3.event.translate + ")" +
        "scale(" + d3.event.scale + ")");
      });
      svg.call(zoom);

      var styleTooltip = function (name, description) {
        return "
" + name + "

" + description + "
";
      };

      render(inner, g);

      inner.selectAll("g.node")
        .attr("title", function (v) {
          return styleTooltip(v, g.node(v).description)
        })
        .each(function (v) {
          $(this).tipsy({gravity: "w", opacity: 1, html: true});
        });

      var initialScale = 1;
      zoom
        .translate([(svg.attr("width") - g.graph().width * initialScale) / 2, 120])
        .scale(initialScale)
        .event(svg);
      svg.attr('height', g.graph().height * initialScale + 120);
    }

    return {
      renderPage: renderPage
    };
  });
<commit_msg>change tipsy gravity<commit_after>define(['d3', 'lib/knockout', 'scripts/Utils', 'dagre-d3', 'jquery', 'jquery.tipsy'],
  function (d3, ko, Utils, dagreD3, $) {
    'use strict';
    function renderPage(skills_data) {
      var g = new dagreD3.graphlib.Graph().setGraph({});

      ko.utils.arrayForEach(skills_data.skills, function (skill) {
        var value = skill;
        value.label = skill.name;
        value.rx = value.ry = 5;
        g.setNode(skill.name, value);
      });

      ko.utils.arrayForEach(skills_data.skills, function (skill) {
        var skill_id = skill.id;
        if (skill.depends) {
          ko.utils.arrayForEach(skill.depends, function (id) {
	          var dependents_name = skills_data.skills[id - 1].name;
	          var skill_name = skills_data.skills[skill_id - 1].name;
            g.setEdge(dependents_name, skill_name, {label: ""});
          });
        }
      });

      var render = new dagreD3.render();

      var svg = d3.select("svg"),
        inner = svg.append("g");

      var zoom = d3.behavior.zoom().on("zoom", function () {
        inner.attr("transform", "translate(" + d3.event.translate + ")" +
        "scale(" + d3.event.scale + ")");
      });
      svg.call(zoom);

      var styleTooltip = function (name, description) {
        return "
" + name + "

" + description + "
";
      };

      render(inner, g);

      inner.selectAll("g.node")
        .attr("title", function (v) {
          return styleTooltip(v, g.node(v).description)
        })
        .each(function (v) {
          $(this).tipsy({gravity: "s", opacity: 1, html: true});
        });

      var initialScale = 1;
      zoom
        .translate([(svg.attr("width") - g.graph().width * initialScale) / 2, 120])
        .scale(initialScale)
        .event(svg);
      svg.attr('height', g.graph().height * initialScale + 120);
    }

    return {
      renderPage: renderPage
    };
  });
<|endoftext|>


<commit_before>var blue = ["rgba( 47, 64,115,1)", "rgba(121,134,172,1", "rgba( 80, 96,143,1)", "rgba( 22, 38, 86,1)", "rgba(  6, 19, 57,1)"];
var green = ["rgba( 98,152, 51,1)","rgba(188,228,152,1)","rgba(140,190, 95,1)","rgba( 64,114, 19,1)","rgba( 36, 76,  0,1)"]
var red = ["rgba(170, 57, 57,1)","rgba(255,170,170,1)","rgba(212,106,106,1)","rgba(128, 21, 21,1)","rgba( 85,  0,  0,1)"];

export default {
  Fill:  [blue[0],green[0],red[0]],
  Stroke:  [blue[1],green[1],red[1]],
  HighlightFill:  [blue[2],green[2],red[2]],
  HighlightStroke:  [blue[3],green[3],red[3]]
}
<commit_msg>Added more colors<commit_after>var blue = ["rgba( 47, 64,115,1)", "rgba(121,134,172,1", "rgba( 80, 96,143,1)", "rgba( 22, 38, 86,1)", "rgba(  6, 19, 57,1)"];
var green = ["rgba( 98,152, 51,1)","rgba(188,228,152,1)","rgba(140,190, 95,1)","rgba( 64,114, 19,1)","rgba( 36, 76,  0,1)"];
var red = ["rgba(170, 57, 57,1)","rgba(255,170,170,1)","rgba(212,106,106,1)","rgba(128, 21, 21,1)","rgba( 85,  0,  0,1)"];
var peach = ["rgba(170,108, 57,1)","rgba(255,209,170,1)","rgba(212,154,106,1)","rgba(128, 69, 21,1)","rgba( 85, 39,  0,1)"];
var lightgreen = ["rgba(134,161, 54,1)","rgba(221,242,161,1)","rgba(176,202,101,1)","rgba( 95,121, 20,1)","rgba( 60, 81,  0,1)"]
var purple = ["rgba( 88, 42,114,1)","rgba(151,117,170,1)","rgba(118, 75,142,1)","rgba( 61, 18, 85,1)","rgba( 38,  3, 57,1)"];
var teal = ["rgba( 34,102,102,1)","rgba(102,153,153,1)","rgba( 64,127,127,1)","rgba( 13, 77, 77,1)","rgba(  0, 51, 51,1)"];
var olive = ["rgba(170,157, 57,1)","rgba(255,245,170,1)","rgba(212,201,106,1)","rgba(128,116, 21,1)","rgba( 85, 75,  0,1)"];

export default {
  Fill:  [blue[0],green[0],red[0]],
  Stroke:  [blue[1],green[1],red[1]],
  HighlightFill:  [blue[2],green[2],red[2]],
  HighlightStroke:  [blue[3],green[3],red[3]]
}
<|endoftext|>