text:
/**
Handles user authorization - signup, login, forgot password, etc.

@module auth
@class auth

@toc
public methods
1. create
5. login
8. logout
9. checkLogin
10. forgotPassword
11. resetPassword
12. changePassword
1.5. createGuest
1.6. formatAlternateContact
1.7. userImport
1.8. userExists
13. socialLogin
private methods
2. checkEmail
2.5 checkPhone
3. createActual
4. createPassword
6. loginActual
6.5. updateSession
7. checkPassword
*/

'use strict';

var crypto =require('crypto');
var moment = require('moment');
var Q = require('q');
var lodash = require('lodash');
var async = require('async');

// var fs =require('fs');
var fs =require('node-fs');		//want recursive directory/folder creating
var path =require('path');
var request = require('request');

var dependency =require('../../../dependency.js');
var pathParts =dependency.buildPaths(__dirname, {});

var Emailer =require(pathParts.services+'emailer/index.js');
var StringMod =require(pathParts.services+'string/string.js');
var MongoDBMod =require(pathParts.services+'mongodb/mongodb.js');
var ArrayMod =require(pathParts.services+'array/array.js');

var UserMod =require(pathParts.controllers+'user/user.js');

//hardcoded
var imageInfo ={
	basePath: 'app',
	imgPath: 'src/common/img'
};
//end: hardcoded

//global values that will be set by passed in objects (to avoid having to require in every file)
// var db;
var self;

var defaults = {
	userFields: ['_id'],
	passwordEmail: {
		// this should be overridden
		subject: 'Password Reset Request',
		template: 'passwordReset'
	}
};

/**
@param {Object} options
	// @param {Object} db
	// @param {Object} Emailer
	// @param {Object} StringMod
	// @param {Object} MongoDBMod
*/
function Auth(options) {
	this.opts = lodash.merge({}, defaults, options||{});

	self = this;

	// db =this.opts.db;
	// Emailer = this.opts.Emailer;
	// StringMod =this.opts.StringMod;
	// MongoDBMod =this.opts.MongoDBMod;
}

/**
Creates a new user (user signup)
@toc 1.
@method create
@param {Object} data
	@param {String} email
	@param {String} password
	// @param {String} password_confirm
	@param {String} first_name
	@param {String} last_name
@param {Object} params
@return {Promise}
	@param {Object} user
**/
Auth.prototype.create = function(db, data, params)
{
	var deferred = Q.defer();
	var ret ={code:0, msg:'Auth.create '};

	// if(data.password !=data.password_confirm) {		//if passwords don't match
		ret.code =1;
		// ret.msg ='Passwords must match';
		// deferred.reject(ret);
	// }
	//check email to ensure valid (no duplicates, etc.)

	data =UserMod.fixPhoneFormat(db, data, params);

	if(data.status === undefined)
	{
		data.status = 'member';
	}
	if(data.social === undefined)
	{
		data.social = {};
	}
	if(data.signup_method === undefined)
	{
		data.signup_method = 'email';
	}
	delete data.super_admin;

	data = self.formatAlternateContact(data, {});

	if(data.email !== undefined)
	{
		data.email =data.email.toLowerCase();		//case insensitive
		var promiseEmail =checkEmail(db, data.email, {});
		promiseEmail.then(
			function()
			{
				//if valid email, create the new user
				var promiseCreate =createActual(db, data, {});
				promiseCreate.then(
					function(ret1)
					{
						//also login the user that was just created (i.e. give them an active session)
						var promiseSession =updateSession(db, ret1.user, {});
						promiseSession.then(
							function(ret2)
							{
								ret1.user =ret2.user;
								deferred.resolve(ret1);
							},
							function(err)
							{
								deferred.reject(err);
							}
						);
					},
					function(err)
					{
						deferred.reject(err);
					}
				);
			},
			function(err)
			{
				deferred.reject(err);
			}
		);
	}
	else if(data.phone !== undefined)
	{
		var promisePhone =checkPhone(db, data.phone, {});
		promisePhone.then(
			function()
			{
				//if valid phone, create the new user
				var promiseCreate =createActual(db, data, {});
				promiseCreate.then(
					function(ret1)
					{
						//also login the user that was just created (i.e. give them an active session)
						var promiseSession =updateSession(db, ret1.user, {});
						promiseSession.then(
							function(ret2)
							{
								ret1.user =ret2.user;
								deferred.resolve(ret1);
							},
							function(err)
							{
								deferred.reject(err);
							}
						);
					},
					function(err)
					{
						deferred.reject(err);
					}
				);
			},
			function(err)
			{
				deferred.reject(err);
			}
		);
	}
	else
	{
		ret.code = 2;
		ret.msg += 'Error: No Email or Phone information given ';
		deferred.reject(ret);
	}
	return deferred.promise;
};

/**
Logs in a user
@toc 5.
@method login
@param {Object} data
	@param {String} email
	@param {String} password
@param {Object} params
@return {Promise}
	@param {Object} user
**/
Auth.prototype.login = function(db, data, params) {
	var deferred = Q.defer();
	var ret ={code:0, msg:'Auth.login '};

	data.email =data.email.toLowerCase();		//case insensitive
	db.user.findOne({email:data.email}, function(err, user) {
		if(err) {
			ret.code =1;
			ret.msg +="db.user.findOne Error: "+err;
			deferred.reject(ret);
		}
		else if(!user) {
			ret.code =2;
			ret.msg ="No user with email '"+data.email+"' exists";
			deferred.reject(ret);
		}
		else {
			var promiseLogin =loginActual(db, data, user, {});
			promiseLogin.then(function(ret1) {
				deferred.resolve(ret1);
			}, function(err) {
				deferred.reject(err);
			});

			//ensure user is no longer 'guest' status
			var setObj ={
				'status':'member'
			};
			db.user.update({_id: MongoDBMod.makeIds({'id':user._id})}, {$set: setObj}, function(err, valid) {
				var dummy =1;
			});
		}
	});

	return deferred.promise;
};

/**
Logs out a user
A session / user login is stored by a key pair of the user's id and a session id that gets set on each login and is destroyed on each logout. Both are used so a random string guess alone won't work. And because the session id changes on each logout, even if a user's credentials were discovered, all the user would have to do is re login or logout and then the old ones will be invalid.
@toc 8.
@method logout
@param {Object} data
	@param {String} user_id The id of the user to logout
	@param {String} sess_id The id of user session to remove
@param {Object} params
@return {Promise}
	@param {Object} user
**/
Auth.prototype.logout = function(db, data, params) {
	var deferred = Q.defer();
	var ret ={code:0, msg:'Auth.logout '};

	db.user.update({_id: MongoDBMod.makeIds({'id': data.user_id}) }, {$pull: {sess_id: data.sess_id}}, {multi: true}, function(err, user) {
		if(err) {
			ret.code =1;
			ret.msg +='Error: '+err;
			deferred.reject(ret);
		}
		else if(!user) {
			ret.code =2;
			ret.msg +='Invalid user ';
			deferred.reject(ret);
		}
		else if(user) {
			deferred.resolve(ret);
		}
	});

	return deferred.promise;
};

/**
Checks to see if a user is already logged in
A session / user login is stored by a key pair of the user's id and a session id that gets set on each login and is destroyed on each logout. Both are used so a random string guess alone won't work. And because the session id changes on each logout, even if a user's credentials were discovered, all the user would have to do is re login or logout and then the old ones will be invalid.
@toc 9.
@method checkLogin
@param {Object} data
	@param {String} user_id The id of the user to check login for
	@param {String} sess_id The id of the session
@param {Object} params
@return {Promise}
	@param {Object} user
**/
Auth.prototype.checkLogin = function(db, data, params) {
	var deferred = Q.defer();
	var ret ={code:0, msg:'Auth.checkLogin ', user:false};

	db.user.findOne({_id: MongoDBMod.makeIds({'id':data.user_id}), sess_id: {$in: [data.sess_id] } }, function(err, user) {
		if(err) {
			ret.code =1;
			ret.msg +='Error: '+err;
			deferred.reject(ret);
		}
		else if(!user) {
			ret.code =2;
			ret.msg ="Invalid sess_id and user_id combination";
			deferred.reject(ret);
		}
		else if(user) {
			user.sess_id =data.sess_id;		//set to string of CURRENT session instead of array of all sessions
			ret.user =user;
			deferred.resolve(ret);
		}
	});

	return deferred.promise;
};

/**
Creates and emails a reset key to the user
@toc 10.
@method forgotPassword
@param {Object} data
	@param {String} email The email of the user to reset the password for
@param {Object} params
@return {Promise}
	@param {Boolean} true on success
**/
Auth.prototype.forgotPassword = function(db, data, params) {
	var deferred = Q.defer();
	var ret ={code:0, msg:'Auth.forgotPassword '};

	data.email =data.email.toLowerCase();		//case insensitive
	db.user.findOne({email: data.email}, function(err, user) {
		if(err) {
			ret.code =1;
			ret.msg +='Error: '+err;
			deferred.reject(ret);
		}
		else if(!user) {
			ret.code =2;
			ret.msg ="No user exists with this email";
			deferred.reject(ret);
		}
		else {
			var resetKey =StringMod.random(6, {'type':'readable'});
			//use "user.email" to avoid ambiguity between whether passed in value was username (_id) or email
			db.user.update({email: user.email}, {$set: {'password_reset_key':resetKey}}, function(err, valid) {
				if(err) {
					ret.code =3;
					ret.msg +='Error: '+err;
					deferred.reject(ret);
				}
				else if(!valid) {
					ret.code =4;
					ret.msg +='Not valid';
					deferred.reject(ret);
				}
				else {
					// fire and forget; this is an async call, but we're not concerned with success
					// @todo: add logging for send failures
					if(Emailer){
						var emailParams = {
							to: [
								{
									email: user.email
								}
							],
							from: 'support@'+global.cfgJson.email.domain,
							from_name: 'Support',
							subject: 'Forgot Password Reset'
						};
						var templateParams = {
							email: user.email,
							reset_key: resetKey
						};
						// Emailer.sendTemplate('passwordReset', emailParams, templateParams);
						Emailer.send({template: 'passwordReset', templateParams: templateParams, emailParams: emailParams});
						ret.msg ="Email sent with reset instructions!";
					} else {
						ret.code =5;
						ret.msg ="WARNING: Auth module cannot send email since emailer is not configured";
					}
					deferred.resolve(ret);
				}
			});
		}
	});

	return deferred.promise;
};

/**
Resets password for a user. Also logs in user (gives an active session)
@toc 11.
@method resetPassword
@param {Object} data
	@param {String} email Email to identify which user to reset password for
	@param {String} reset_key To authorize user to reset password
	@param {String} password New password to set
@param {Object} params
@return {Promise}
	@param {Object} user
**/
Auth.prototype.resetPassword = function(db, data, params) {
	var deferred = Q.defer();
	var ret ={code:0, msg:'Auth.resetPassword ', user:false};

	data.email =data.email.toLowerCase();		//case insensitive
	db.user.findOne({email: data.email, password_reset_key:data.reset_key}, function(err, user) {
		if(err) {
			ret.code =1;
			ret.msg +="Error: "+err;
			deferred.reject(ret);
		}
		else if(!user) {
			ret.code =2;
			ret.msg ='Invalid email and reset key combination';
			deferred.reject(ret);
		}
		else {
			//update user password with new one
			var passFinal =createPassword(user.password_salt, data.password, {});
			var resetKey =StringMod.random(16, {});		//invalidate reset key so can't be used again
			//use "user.email" to avoid ambiguity between if params.email is username (_id) or email
			db.user.update({email: user.email}, {$set: {'password':passFinal, 'password_reset_key':resetKey}}, function(err, valid) {
				if(err) {
					ret.code =3;
					ret.msg +='Error: '+err;
					deferred.reject(ret);
				}
				else if(!valid) {
					ret.code =4;
					ret.msg +="Not valid";
					deferred.reject(ret);
				}
				else {
					//also login the user that was just created (i.e. give them an active session)
					var promiseSession =updateSession(db, user, {});
					promiseSession.then(function(retSess) {
						ret.user =retSess.user;
						deferred.resolve(ret);
					}, function(err) {
						deferred.reject(err);
					});
				}
			});
		}
	});

	return deferred.promise;
};

/**
Changes password for a user
@toc 12.
@method changePassword
@param {Object} data
	@param {String} user_id Identify user to change password for
	@param {String} current_password The user's current password (to authenticate)
	@param {String} new_password New password to set
@param {Object} params
@return {Promise}
	@param {Object} user
**/
Auth.prototype.changePassword = function(db, data, params) {
	var deferred = Q.defer();
	var ret ={code:0, msg:'Auth.changePassword ', user:false};

	db.user.findOne({ _id:MongoDBMod.makeIds({'id':data.user_id}) }, function(err, user) {
		if(err) {
			ret.code =1;
			ret.msg +='Error: '+err;
			deferred.reject(ret);
		}
		else if(!user) {
			ret.code =2;
			ret.msg +='No user - likely an invalid user_id';
			deferred.reject(ret);
		}
		else {
			var passFinal =createPassword(user.password_salt, data.new_password, {});
			db.user.update({_id:user._id}, {$set: {'password':passFinal}}, function(err, valid) {
				if(err) {
					ret.code =3;
					ret.msg +='Error: '+err;
					deferred.reject(ret);
				}
				else if(!valid) {
					ret.code =4;
					ret.msg +='Not valid';
					deferred.reject(ret);
				}
				else {
					ret.user =user;
					deferred.resolve(ret);
				}
			});
		}
	});

	return deferred.promise;
};

/**
Creates a guest user
@toc 1.5.
@method createGuest
@param {Object} guest New user object. Must contain an email field OR a social.[type].id field (which will then create a dummy/random email to keep things consistent and easy). May contain other user information.
	@param {String} email New user's email
@param {Object} params
@return {Promise}
	@param {Object} user
**/
Auth.prototype.createGuest = function(db, guest, params)
{
	var deferred =Q.defer();
	var ret = {'code': 0, 'msg': 'Auth.createGuest ', 'user': {} };

	var randStr =StringMod.random(20, {});

	//if social key, allow no email and just create a random/dummy one
	if(guest.email ===undefined && guest.social !==undefined) {
		guest.email =randStr+'@_fakeemail_.com';
	}

	guest.password = randStr;
	guest.status = 'guest';
	var creation_promise = self.create(db, guest, params);
	creation_promise.then(
		function(ret1)
		{
			ret.user = ret1.user;
			deferred.resolve(ret);
		},
		function(err)
		{
			deferred.reject(err);
		}
	);
	return deferred.promise;
};

/**
@toc 1.6.
Takes a user object. Appends the user's email to the user's email_alls and phone to phones_all, if they are defined and not already in those arrays.

@method formatAlternateContact
@param {Object} user The user object.
@return {Promise}
	@param {Object} user New, updated user object.
*/
Auth.prototype.formatAlternateContact = function(user, params)
{
	var ii;
	var found;

	if(user.email !== undefined)
	{
		user.email =user.email.toLowerCase();		//ensure lowercase

		if(user.emails_all === undefined)
		{
			user.emails_all = [ { 'email': user.email, 'confirmed': 0, 'primary': 1 } ];
		}
		else
		{
			found = false;
			for(ii = 0; ii < user.emails_all.length; ii++)
			{
				user.emails_all[ii].email =user.emails_all[ii].email.toLowerCase();		//ensure lowercase
				if(user.email == user.emails_all[ii].email)
				{
					found = true;
					ii = user.emails_all.length;
				}
			}
			if(found === false)
			{
				user.emails_all.push( { 'email': user.email, 'confirmed': 0, 'primary': 1 } );
			}
		}
	}

	if(user.phone !== undefined)
	{
		if(user.phones_all === undefined)
		{
			user.phones_all = [user.phone];
		}
		else
		{
			found = false;
			for(ii = 0; ii < user.phones_all.length; ii++)
			{
				if(user.phone.number == user.phones_all[ii].number)
				{
					found = true;
					ii = user.phones_all.length;
				}
			}
			if(found === false)
			{
				user.phones_all.push(user.phone);
			}
		}
	}

	return user;
};

/**
Checks if a user exists. If not, creates a guest user.
@toc 1.7.
@method userImport
@param {Object} data
	@param {Object} user New user object. Should have one of the following defined: '_id', 'email', 'phone', 'social.[type].id'. May contain other user information.
@param {Object} params
@return {Promise}
	@param {Object} ret
		@param {Object} user The new user object, if successfully created, or the user's existing database entry (with _id at least), if it's already there.
		@param {Boolean} already_exists True iff the given user is already in the database.
**/
Auth.prototype.userImport = function(db, data, params)
{
	var deferred =Q.defer();
	var ret = {'code': 0, 'msg': 'Auth.userImport ', 'user': {}, 'already_exists': false };

	data.user =UserMod.fixPhoneFormat(db, data.user, params);

	var exists_promise = self.userExists(db, data.user, {});
	exists_promise.then(
		function(ret1)
		{
			if(ret1.exists === true)
			{
				ret.already_exists = true;
				ret.user = ret1.user;
				deferred.resolve(ret);
			}
			else
			{
				var create_promise = self.createGuest(db, data.user, {});
				create_promise.then(
					function(ret1)
					{
						ret.already_exists = false;
						ret.user = ret1.user;
						ret.user._id = ret.user._id.toHexString();
						deferred.resolve(ret);
					},
					function(err)
					{
						ret.code = 1;
						ret.msg += err;
						deferred.reject(ret);
					}
				);
			}
		},
		function(err)
		{
			ret.code = 2;
			ret.msg += err;
			deferred.reject(ret);
		}
	);

	return deferred.promise;
};

/**
Checks if a user exists. If not, creates a guest user.
@toc 1.71.
@method userImport
@param {Object} data
	@param {String} user_id Id of the user doing the importing, if applicable.
	@param {Array} users Array of new user objects. Each must have one of the following defined: '_id', 'email', 'phone', 'social.[type].id'. May contain other user information.
	@param {Number} follow 1 iff the new users should be followed by the user doing the importing.
@param {Object} params
@return {Promise}
	@param {Object} ret
		@param {Array} users Array of the new user objects, if successfully created, or the users' existing database entries (with at least the _id field), if they're already there.
**/
Auth.prototype.usersImport = function(db, data, params)
{
	var deferred =Q.defer();
	var ret = {'code': 0, 'msg': 'Auth.usersImport ', 'users': [] };
	var FollowMod = require(pathParts.controllers+'follow/follow.js');

	async.forEach(data.users,
		function(user, callback)
		{
			var import_promise = self.userImport(db, {'user': user}, params);
			import_promise.then(
				function(ret1)
				{
					ret.users.push(ret1.user);
					callback(false);
				},
				function(ret1)
				{
					callback(true);
				}
			);
		},
		function(err)
		{
			if(err)
			{
				ret.code = 1;
				deferred.reject(ret);
			}
			else
			{
				if(data.user_id !== undefined && data.follow === 1)
				{
					var follow_promise = FollowMod.follow(db, {'user_id': data.user_id, 'followed': ret.users}, params);
					follow_promise.then(
						function(ret1)
						{
							ret.code = 0;
							ret.msg += ret1.msg;
							deferred.resolve(ret);
						},
						function(ret1)
						{
							ret.code = 1;
							ret.msg += ret1.msg;
							deferred.reject(ret);
						}
					);
				}
				else
				{
					ret.code = 1;
					deferred.resolve(ret);
				}
			}
		}
	);

	return deferred.promise;
};

/**
Check if a user exists in the database, based on the given _id, email, or phone field.
@toc 1.8.
@method userExists
@param {Object} user A user object. Should have one of the following defined: '_id', 'email', 'phone', 'social.[type].id'
@param {Object} params

@return {Object} (via Promise)
	@param {Boolean} exists True iff the member already exists
	@param {String} user The user's database object, if the user already exists
	@param {Number} code
	@param {String} msg
**/
Auth.prototype.userExists = function(db, user, params)
{
	var deferred = Q.defer();
	var ret = {code:0, msg:'Auth.userExists ', 'exists': false, 'user': {}};

	var xx, query, valid =false;

	//DRY phone checking function
	var checkPhone = function()
	{

		user =UserMod.fixPhoneFormat(db, user, params);

		var phone_promise = UserMod.searchByPhone(db, {'phone': user.phone, 'fields': {'_id': 1}}, {});
		phone_promise.then(
			function(ret1)
			{
				if(ret1.exists)
				{
					ret.exists = true;
					ret.user = ret1.user;
					ret.user._id = ret.user._id.toHexString();
					deferred.resolve(ret);
				}
				else
				{
					ret.exists = false;
					deferred.resolve(ret);
				}
			},
			function(ret1)
			{
				//Error occurred
				ret.code =1;
				console.log(ret1.msg);
				deferred.reject(ret);
			}
		);
	};

	//If the user already has an _id, it must exist. We're done.
	if(user._id !== undefined)
	{
		valid =true;
		ret.user = user;
		ret.exists = true;
		deferred.resolve(ret);
	}
	//Id may also be under the user_id field, allow both
	else if(user.user_id !== undefined)
	{
		valid =true;
		ret.user = user;
		ret.user._id = ret.user.user_id;
		ret.exists = true;
		deferred.resolve(ret);
	}
	//No _id field. Check email
	else if(user.email !== undefined)
	{
		valid =true;
		var email_promise = UserMod.searchByEmail(db, {'email': user.email, 'fields': {'_id': 1}}, {});
		email_promise.then(
			function(ret1)
			{
				if(ret1.exists)
				{
					ret.exists = true;
					ret.user = ret1.user;
					ret.user._id = ret.user._id.toHexString();
					deferred.resolve(ret);
				}
				else if(user.phone !== undefined)
				{
					checkPhone();
				}
				else
				{
					ret.exists = false;
					deferred.resolve(ret);
				}
			},
			function(ret1)
			{
				//Error occurred
				ret.code =2;
				console.log(ret1.msg);
				deferred.reject(ret);
			}
		);
	}
	else if(user.phone !== undefined)
	{
		valid =true;
		checkPhone();
	}
	else if(user.social !==undefined) {
		query ={
			$or: []
		};
		var key, curPushObj;
		for(xx in user.social) {
			if(user.social[xx].id !==undefined) {
				key ='social.'+xx+'.id';
				curPushObj ={};
				curPushObj[key] =user.social[xx].id;		//MUST set it this way otherwise will look for a 'key' field!!
				query.$or.push(curPushObj);
			}
		}
		if(query.$or.length >0) {
			valid =true;
			db.user.findOne(query, function(err, record) {
				if(err) {
					ret.code =3;
					ret.msg +=err;
					deferred.reject(ret);
				}
				else if(!record) {
					ret.exists = false;
					deferred.resolve(ret);
				}
				else {
					ret.exists = true;
					ret.user =record;
					ret.user._id = ret.user._id.toHexString();
					deferred.resolve(ret);
				}
			});
		}
	}

	if(!valid) {
		//No data given. Impossible to check if the user exists.
		ret.code =4;
		console.log("Auth.userExists: Error: No _id, email, or phone given. Cannot check if user exists");
		deferred.reject(ret);
	}

	return deferred.promise;
};

/**

@toc 13.
@method socialLogin
@param {Object} data
	@param {Object} user A user object for BOTH matching (if any existing user) and setting/updating info. Can have one of the following defined for matching: '_id', 'email', 'phone', 'social.[type].id' BUT social.[type].id will be autofilled as a backup so this can be empty. Once the user is matched or created, these fields will be EXTENDED onto the user object for user update.
		@param {String} [_imageUrl] A url to a 3rd party website image for download and use
	@param {Object} socialData The social data to save, i.e.
		@param {String} [token] The social login token to save.
		@param {String} [id] The social platform user id for this user.
	@param {String} type A key to save the social data under, describing the social site. Ex: "facebook", "google", etc.
	@param {String} [pic_directory ='user'] Where to save the user image (only applicable if pass in image/imageUrl)
@param {Object} params

@return {Promise}
	@param {Object} ret
		@param {Object} user The new user object, if successfully created, or the user's existing database entry (with _id at least), if it's already there.
		@param {Boolean} already_exists True iff the given user is already in the database.
**/
Auth.prototype.socialLogin = function(db, data, params)
{
	var deferred =Q.defer();
	var ret = {'code': 0, 'msg': 'Auth.socialLogin ', 'user': {}, 'already_exists': false };

	var _imageUrl =false;
	if(data.user._imageUrl !==undefined) {
		_imageUrl =data.user._imageUrl;
		delete data.user._imageUrl;		//do NOT want to save this in database!
	}

	//add social data into user.social key
	if(data.user.social ===undefined) {
		data.user.social ={};
	}
	data.user.social[data.type] ={
		id: data.socialData.id
	};
	data.user.signup_method = data.type;

	var import_promise = self.userImport(db, {'user': data.user}, {});
	import_promise.then(
		function(ret1)
		{
			ret.already_exists = ret1.already_exists;
			ret.user =ArrayMod.copy(ret1.user);		//ensure no over-writing / funky behavior..
			// ret.user = ret1.user;		//breaks things since data.user then is equal to ret.user somehow..

			if(ret.user.social === undefined)
			{
				ret.user.social = {};
			}

			var finishLocal =function(paramsFinish) {
				//in case of update, need to re-read user to get all info (esp. sess_id)
				// ret.user.social[data.type] = data.socialData;
				UserMod.read(db, {_id: ret.user._id}, {})
				.then(function(retUser) {
					ret.user =retUser.result;
					//also need to update session
					var promiseSession =updateSession(db, ret.user, {});
					promiseSession.then(function(ret1) {
						ret.user =ret1.user;
						deferred.resolve(ret);
					}, function(err) {
						deferred.reject(err);
					});
				}, function(retErr) {
					deferred.reject(retErr);
				});
			};

			var saveImageLocal =function(paramsImage) {
				if(data.pic_directory ===undefined) {
					data.pic_directory ='user';
				}

				var imgUrl =_imageUrl;
				var imgUrlStripped =imgUrl;
				//strip url params if they're there as this may mess up things (get an ESDIR or ENOENT error since the file extension isn't at the end) or get a small version of the image and we want the larger / default one
				if(imgUrlStripped.indexOf('?') >-1) {
					imgUrlStripped =imgUrlStripped.slice(0, imgUrlStripped.indexOf('?'));
				}
				//get the file extension
				var posExt =imgUrlStripped.lastIndexOf('.');
				var ext =imgUrlStripped.slice(posExt, imgUrlStripped.length);

				var filename ='profile'+ext;
				var imgSavePath =data.pic_directory +'/'+ret1.user._id;
				var folderWritePath =path.normalize(__dirname +'../../../../' +imageInfo.imgPath +'/' +imgSavePath);		//hardcoded - 4 '../' to get from this directory back to 'app/'. Very important to use path.normalize so it works on both windows and linux!!

				//recursively create directories / folders in case they don't exist yet
				fs.mkdirSync(folderWritePath, parseInt('777', 8), true);		//0777 octal in strict mode is not allowed

				var dbSavePath =imgSavePath +'/' +filename;		//what will be stored in the database
				var imgWritePath =folderWritePath +'/' +filename;
				var picStream =fs.createWriteStream(imgWritePath);
				picStream.on('close', function() {
					if(data.user.image !==undefined) {		//image key already exists
						data.user['image.profile'] =dbSavePath;		//have to do it this way for mongo db syntax and to avoid over-writing any other keys (other than 'profile') that may exist
					}
					else {		//image key doesn't exist yet
						data.user.image ={
							profile: dbSavePath
						};
					}
					//have to call the UserMod.update function to ensure the crop version of the image gets saved properly
					UserMod.update(db, {user_id: ret1.user._id, user:data.user}, {})
					.then(function(retUserUpdate) {
						finishLocal({});
					}, function(retErr) {
						deferred.reject(retErr);
					});
				});
				request(imgUrlStripped).pipe(picStream);
			};

			var set_obj = {};
			set_obj["social." + data.type] = data.socialData;

			//update other fields (i.e. name, email) too IF not already set. //@todo - extend existing fields and/or add to emails array with new ones?
			var xx;
			for(xx in data.user) {
				if(ret.user[xx] ===undefined || !ret.user[xx]) {
					set_obj[xx] =data.user[xx];
				}
			}

			db.user.update({_id:MongoDBMod.makeIds({'id':ret1.user._id}) }, {$set: set_obj}, function(err, valid)
			{
				if(err)
				{
					ret.code = 1;
					ret.msg +='Error: '+err;
					deferred.reject(ret);
				}
				else if (!valid)
				{
					ret.code = 2;
					ret.msg +='Not valid ';
					deferred.reject(ret);
				}
				else
				{
					ret.code = 0;
					ret.msg +='User updated';

					//get image if it exists AND do not already have an image (don't overwrite if already do)
					if(_imageUrl && (ret.user.image ===undefined || ret.user.image.profile ===undefined)) {
						saveImageLocal({});
					}
					else {
						finishLocal({});
					}
				}
			});

		},
		function(err)
		{
			ret.code = 3;
			ret.msg += err;
			deferred.reject(ret);
		}
	);

	return deferred.promise;
};

/**
@toc 2.
@method checkEmail
@param {String} email The email to check (if already exists in database)
@param {Object} params
	@param {String} [user_id] In case of edit, this will allow the same email if it's this user's email already
@return {Promise}
	@param {Object} ret
		@param {Boolean} code 0 if email is okay to be used (i.e. doesn't already exist)
		@param {String} msg
*/
//Auth.prototype.checkEmail =function(email, params) {
function checkEmail(db, email, params) {
	var deferred =Q.defer();
	var ret ={code: 0, msg:'checkEmail '};

	var email_promise = UserMod.searchByEmail(db, {'email': email, 'fields': {'_id': 1} }, params);
	email_promise.then(
		function(ret1)
		{
			if(ret1.exists)
			{
				ret.code = 1;
				deferred.reject(ret);
			}
			else
			{
				ret.code = 0;
				deferred.resolve(ret);
			}
		},
		function(ret1)
		{
			console.log(ret1);
			deferred.reject(ret1);
		}
	);
	/*
	var email = data.email.toLowerCase();		//case insensitive
	db.user.findOne({email: email}, function(err, user) {
		if(err)
		{
			ret.code =2;
			ret.msg +='Error: '+err;
			deferred.reject(ret);
		}
		else if(user) {
			if(params.user_id !==undefined && user._id ==params.user_id) {		//same user = valid
				deferred.resolve(ret);
			}
			else {
				ret.code =3;
				ret.msg ="Email already exists";
				deferred.reject(ret);
			}
		}
		else {
			deferred.resolve(ret);
		}
	});
	*/
	return deferred.promise;
}

/**
@toc 2.
@method checkPhone
@param {String} phone The phone to check (if already exists in database)
@param {Object} params
	@param {String} [user_id] In case of edit, this will allow the same phone if it's this user's phone already
@return {Promise}
	@param {Object} ret
		@param {Boolean} code 0 if phone is okay to be used (i.e. doesn't already exist)
		@param {String} msg
*/
function checkPhone(db, phone, params)
{
	var deferred =Q.defer();
	var ret ={code: 0, msg:'checkPhone '};

	var phone_promise = UserMod.searchByPhone(db, {'phone': phone, 'fields': {'_id': 1} }, params);
	phone_promise.then(
		function(ret1)
		{
			if(ret1.exists)
			{
				ret.code = 1;
				deferred.reject(ret);
			}
			else
			{
				ret.code = 0;
				deferred.resolve(ret);
			}
		},
		function(ret1)
		{
			console.log(ret1);
			deferred.reject(ret1);
		}
	);

	return deferred.promise;
}

/**
@toc 3.
@method createActual
*/
function createActual(db, data, params) {
	var deferred =Q.defer();
	var ret ={code: 0, msg:'createActual ', user:false};

	data.password_salt =StringMod.random(16,{});
	data.password =createPassword(data.password_salt, data.password, {});
	delete data.password_confirm;
	var sessId =StringMod.random(16,{});
	data.sess_id =[ sessId ];
	data.signup = moment(new Date()).format('YYYY-MM-DD HH:mm:ss');
	db.user.insert(data, function(err, user) {
		if(err) {
			ret.code =1;
			ret.msg +='Error: '+err;
			deferred.reject(ret);
		}
		else {
			user =user[0];		//return value is an array but just want the one we inserted as an object
			user.sess_id =sessId;		//set to string of CURRENT session rather than array
			ret.user =user;
			deferred.resolve(ret);
		}
	});

	return deferred.promise;
}

/**
Creates an encrypted password from a salt and (user input / plain text) password
@toc 4.
@method createPassword
@param {String} salt
@param {String} password
@return {String} encrypted password
*/
function createPassword(salt, password, params) {
	var pass1 =crypto.createHash('sha1').update(salt+password).digest('hex');
	//console.log(salt+" "+password+" "+pass1);
	return pass1;
}

/**
Takes a user (looked up from the database) and user input password and then encrypts and compares that user input password to the actual password in the database. If a match, logs in the user and returns the user object
@toc 6.
@method loginActual
@param {Object} data
	@param {String} password User input NON-ENCRYPTED password (to encrypt with salt check against user password)
@param {Object} user User looked up from db (matched to email or other field to identify this user)
	@param {String} password ENCRYPTED form of password
	@param {String} password_salt Used to encrypt data.password for matching against user.password
@return {Promise}
	@param {Object} user User info IF successful login
*/
function loginActual(db, data, user, params) {
	var deferred =Q.defer();
	var ret ={code:0, msg:'loginActual: ', user:false};
	var validPass =checkPassword(data, user, params);
	if(!validPass) {
		ret.code =1;
		ret.msg ="Invalid password";
		deferred.reject(ret);
	}
	else {
		var promiseSession =updateSession(db, user, {});
		promiseSession.then(function(ret1) {
			deferred.resolve(ret1);
		}, function(err) {
			deferred.reject(err);
		});
	}
	return deferred.promise;
}

/**
@toc 6.5.
@method updateSession
@param {Object} user User looked up from db (matched to email or other field to identify this user)
	@param {String} email Email of user to log in and update session
@return {Promise}
	@param {Object} user User info now with active session id (and last_login is updated as well)
*/
function updateSession(db, user, params) {
	var deferred =Q.defer();
	var ret ={code:0, msg:'updateSession: ', user:false};
	//update session info in database
	var sessId =StringMod.random(16,{});
	user.last_login =moment(new Date()).format('YYYY-MM-DD HH:mm:ss');

	//may not have email so need to check by _id too
	var valid =true;
	var query ={};
	if(user.email !==undefined) {
		query.email =user.email;
	}
	else if(user._id !==undefined) {
		query._id =MongoDBMod.makeIds({'id': user._id});
	}
	else {
		valid =false;
		ret.code =1;
		ret.msg +='A valid user email or _id must be specified ';
		deferred.reject(ret);
	}
	if(valid) {
		db.user.update(query, {$set: {last_login:user.last_login}, $push:{sess_id: sessId } }, function(err, valid) {
			if(err) {
				ret.code =2;
				ret.msg +='Error: '+err;
				deferred.reject(ret);
			}
			else if(!valid) {
				ret.code =3;
				ret.msg +='Invalid query ';
				deferred.reject(ret);
			}
			else {
				user.sess_id =sessId;		//set to string of CURRENT session rather than array of all sessions
				ret.user =user;
				deferred.resolve(ret);
			}
		});
	}
	return deferred.promise;
}

/**
@toc 7.
@method checkPassword
@param {Object} data
	@param {String} password User input NON-ENCRYPTED password (to encrypt with salt check against user password)
@param {Object} user User looked up from db (matched to email or other field to identify this user)
	@param {String} password ENCRYPTED form of password
	@param {String} password_salt Used to encrypt data.password for matching against user.password
@return {Boolean} True if passwords match
*/
function checkPassword(data, user, params) {
	var password =crypto.createHash('sha1').update(user.password_salt+data.password).digest('hex');
	if(password ==user.password) {		//match
		return true;
	}
	else {
		return false;
	}
}

module.exports = new Auth({});


text:
#include <algorithm>
#include <memory>
#include <vector>

#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/call/bitrate_allocator.h"
#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"

using testing::NiceMock;

namespace webrtc {

class MockLimitObserver : public BitrateAllocator::LimitObserver {
 public:
  MOCK_METHOD2(OnAllocationLimitsChanged,
               void(uint32_t min_send_bitrate_bps,
                    uint32_t max_padding_bitrate_bps));
};

class TestBitrateObserver : public BitrateAllocatorObserver {
 public:
  TestBitrateObserver()
      : last_bitrate_bps_(0), last_fraction_loss_(0), last_rtt_ms_(0) {}

  void OnBitrateUpdated(uint32_t bitrate_bps,
                        uint8_t fraction_loss,
                        int64_t rtt) override {
    last_bitrate_bps_ = bitrate_bps;
    last_fraction_loss_ = fraction_loss;
    last_rtt_ms_ = rtt;
  }
  uint32_t last_bitrate_bps_;
  uint8_t last_fraction_loss_;
  int64_t last_rtt_ms_;
};

class BitrateAllocatorTest : public ::testing::Test {
 protected:
  BitrateAllocatorTest() : allocator_(new BitrateAllocator(&limit_observer_)) {
    allocator_->OnNetworkChanged(300000u, 0, 0);
  }
  ~BitrateAllocatorTest() {}

  NiceMock<MockLimitObserver> limit_observer_;
  std::unique_ptr<BitrateAllocator> allocator_;
};

TEST_F(BitrateAllocatorTest, UpdatingBitrateObserver) {
  TestBitrateObserver bitrate_observer;
  const uint32_t kMinSendBitrateBps = 100000;
  const uint32_t kPadUpToBitrateBps = 50000;

  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(kMinSendBitrateBps,
                                                         kPadUpToBitrateBps));
  allocator_->AddObserver(&bitrate_observer, kMinSendBitrateBps, 1500000,
                          kPadUpToBitrateBps, true);
  EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer));
  allocator_->OnNetworkChanged(200000, 0, 0);
  EXPECT_EQ(200000, allocator_->GetStartBitrate(&bitrate_observer));

  // TODO(pbos): Expect capping to 1.5M instead of 3M when not boosting the max
  // bitrate for FEC/retransmissions (see todo in BitrateAllocator).
  allocator_->OnNetworkChanged(4000000, 0, 0);
  EXPECT_EQ(3000000, allocator_->GetStartBitrate(&bitrate_observer));

  // Expect |max_padding_bitrate_bps| to change to 0 if the observer is updated.
  EXPECT_CALL(limit_observer_,
              OnAllocationLimitsChanged(kMinSendBitrateBps, 0));
  allocator_->AddObserver(&bitrate_observer, kMinSendBitrateBps, 4000000, 0,
                          true);
  EXPECT_EQ(4000000, allocator_->GetStartBitrate(&bitrate_observer));

  EXPECT_CALL(limit_observer_,
              OnAllocationLimitsChanged(kMinSendBitrateBps, 0));
  allocator_->AddObserver(&bitrate_observer, kMinSendBitrateBps, 1500000, 0,
                          true);
  EXPECT_EQ(3000000, allocator_->GetStartBitrate(&bitrate_observer));
  EXPECT_EQ(3000000u, bitrate_observer.last_bitrate_bps_);
  allocator_->OnNetworkChanged(1500000, 0, 0);
  EXPECT_EQ(1500000u, bitrate_observer.last_bitrate_bps_);
}

TEST_F(BitrateAllocatorTest, TwoBitrateObserversOneRtcpObserver) {
  TestBitrateObserver bitrate_observer_1;
  TestBitrateObserver bitrate_observer_2;
  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(100000, 0));
      allocator_->AddObserver(&bitrate_observer_1, 100000, 300000, 0, true);
      EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_1));
      EXPECT_CALL(limit_observer_,
                  OnAllocationLimitsChanged(100000 + 200000, 0));
      allocator_->AddObserver(&bitrate_observer_2, 200000, 300000, 0, true);
      EXPECT_EQ(200000, allocator_->GetStartBitrate(&bitrate_observer_2));

      // Test too low start bitrate, hence lower than sum of min. Min bitrates
      // will
      // be allocated to all observers.
      allocator_->OnNetworkChanged(200000, 0, 50);
      EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_);
      EXPECT_EQ(0, bitrate_observer_1.last_fraction_loss_);
      EXPECT_EQ(50, bitrate_observer_1.last_rtt_ms_);
      EXPECT_EQ(200000u, bitrate_observer_2.last_bitrate_bps_);
      EXPECT_EQ(0, bitrate_observer_2.last_fraction_loss_);
      EXPECT_EQ(50, bitrate_observer_2.last_rtt_ms_);

      // Test a bitrate which should be distributed equally.
      allocator_->OnNetworkChanged(500000, 0, 50);
      const uint32_t kBitrateToShare = 500000 - 200000 - 100000;
      EXPECT_EQ(100000u + kBitrateToShare / 2,
                bitrate_observer_1.last_bitrate_bps_);
      EXPECT_EQ(200000u + kBitrateToShare / 2,
                bitrate_observer_2.last_bitrate_bps_);

      // Limited by 2x max bitrates since we leave room for FEC and
      // retransmissions.
      allocator_->OnNetworkChanged(1500000, 0, 50);
      EXPECT_EQ(600000u, bitrate_observer_1.last_bitrate_bps_);
      EXPECT_EQ(600000u, bitrate_observer_2.last_bitrate_bps_);

      // Verify that if the bandwidth estimate is set to zero, the allocated
      // rate is
      // zero.
      allocator_->OnNetworkChanged(0, 0, 50);
      EXPECT_EQ(0u, bitrate_observer_1.last_bitrate_bps_);
      EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_bps_);
}

TEST_F(BitrateAllocatorTest, RemoveObserverTriggersLimitObserver) {
  TestBitrateObserver bitrate_observer;
  const uint32_t kMinSendBitrateBps = 100000;
  const uint32_t kPadUpToBitrateBps = 50000;

  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(kMinSendBitrateBps,
                                                         kPadUpToBitrateBps));
  allocator_->AddObserver(&bitrate_observer, kMinSendBitrateBps, 1500000,
                          kPadUpToBitrateBps, true);
  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(0, 0));
  allocator_->RemoveObserver(&bitrate_observer);
}

class BitrateAllocatorTestNoEnforceMin : public ::testing::Test {
 protected:
  BitrateAllocatorTestNoEnforceMin()
      : allocator_(new BitrateAllocator(&limit_observer_)) {
    allocator_->OnNetworkChanged(300000u, 0, 0);
  }
  ~BitrateAllocatorTestNoEnforceMin() {}

  NiceMock<MockLimitObserver> limit_observer_;
  std::unique_ptr<BitrateAllocator> allocator_;
};

// The following three tests verify enforcing a minimum bitrate works as
// intended.
TEST_F(BitrateAllocatorTestNoEnforceMin, OneBitrateObserver) {
  TestBitrateObserver bitrate_observer_1;
  // Expect OnAllocationLimitsChanged with |min_send_bitrate_bps| = 0 since
  // AddObserver is called with |enforce_min_bitrate| = false.
  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(0, 0));
      allocator_->AddObserver(&bitrate_observer_1, 100000, 400000, 0, false);
      EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_1));

      // High BWE.
      allocator_->OnNetworkChanged(150000, 0, 0);
      EXPECT_EQ(150000u, bitrate_observer_1.last_bitrate_bps_);

      // Low BWE.
      allocator_->OnNetworkChanged(10000, 0, 0);
      EXPECT_EQ(0u, bitrate_observer_1.last_bitrate_bps_);

      EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(0, 0));
      allocator_->RemoveObserver(&bitrate_observer_1);
}

TEST_F(BitrateAllocatorTestNoEnforceMin, ThreeBitrateObservers) {
  TestBitrateObserver bitrate_observer_1;
  TestBitrateObserver bitrate_observer_2;
  TestBitrateObserver bitrate_observer_3;
  // Set up the observers with min bitrates at 100000, 200000, and 300000.
  allocator_->AddObserver(&bitrate_observer_1, 100000, 400000, 0, false);
  EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_1));

  allocator_->AddObserver(&bitrate_observer_2, 200000, 400000, 0, false);
  EXPECT_EQ(200000, allocator_->GetStartBitrate(&bitrate_observer_2));
  EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_);

  allocator_->AddObserver(&bitrate_observer_3, 300000, 400000, 0, false);
  EXPECT_EQ(0, allocator_->GetStartBitrate(&bitrate_observer_3));
  EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_);
  EXPECT_EQ(200000u, bitrate_observer_2.last_bitrate_bps_);

  // High BWE. Make sure the controllers get a fair share of the surplus (i.e.,
  // what is left after each controller gets its min rate).
  allocator_->OnNetworkChanged(690000, 0, 0);
  // Verify that each observer gets its min rate (sum of min rates is 600000),
  // and that the remaining 90000 is divided equally among the three.
  uint32_t bitrate_to_share = 690000u - 100000u - 200000u - 300000u;
  EXPECT_EQ(100000u + bitrate_to_share / 3,
            bitrate_observer_1.last_bitrate_bps_);
  EXPECT_EQ(200000u + bitrate_to_share / 3,
            bitrate_observer_2.last_bitrate_bps_);
  EXPECT_EQ(300000u + bitrate_to_share / 3,
            bitrate_observer_3.last_bitrate_bps_);

  // BWE below the sum of observer's min bitrate.
  allocator_->OnNetworkChanged(300000, 0, 0);
  EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_);  // Min bitrate.
  EXPECT_EQ(200000u, bitrate_observer_2.last_bitrate_bps_);  // Min bitrate.
  EXPECT_EQ(0u, bitrate_observer_3.last_bitrate_bps_);  // Nothing.

  // Increased BWE, but still below the sum of configured min bitrates for all
  // observers and too little for observer 3. 1 and 2 will share the rest.
  allocator_->OnNetworkChanged(500000, 0, 0);
  EXPECT_EQ(200000u, bitrate_observer_1.last_bitrate_bps_);  // Min + split.
  EXPECT_EQ(300000u, bitrate_observer_2.last_bitrate_bps_);  // Min + split.
  EXPECT_EQ(0u, bitrate_observer_3.last_bitrate_bps_);  // Nothing.

  // Below min for all.
  allocator_->OnNetworkChanged(10000, 0, 0);
  EXPECT_EQ(0u, bitrate_observer_1.last_bitrate_bps_);
  EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_bps_);
  EXPECT_EQ(0u, bitrate_observer_3.last_bitrate_bps_);

  // Verify that zero estimated bandwidth, means that that all gets zero,
  // regardless of set min bitrate.
  allocator_->OnNetworkChanged(0, 0, 0);
  EXPECT_EQ(0u, bitrate_observer_1.last_bitrate_bps_);
  EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_bps_);
  EXPECT_EQ(0u, bitrate_observer_3.last_bitrate_bps_);

  allocator_->RemoveObserver(&bitrate_observer_1);
  allocator_->RemoveObserver(&bitrate_observer_2);
  allocator_->RemoveObserver(&bitrate_observer_3);
}

TEST_F(BitrateAllocatorTest, ThreeBitrateObserversLowBweEnforceMin) {
  TestBitrateObserver bitrate_observer_1;
  TestBitrateObserver bitrate_observer_2;
  TestBitrateObserver bitrate_observer_3;

  allocator_->AddObserver(&bitrate_observer_1, 100000, 400000, 0, true);
  EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_1));

  allocator_->AddObserver(&bitrate_observer_2, 200000, 400000, 0, true);
  EXPECT_EQ(200000, allocator_->GetStartBitrate(&bitrate_observer_2));
  EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_);

      allocator_->AddObserver(&bitrate_observer_3, 300000, 400000, 0, true);
      EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_3));
      EXPECT_EQ(100000, static_cast<int>(bitrate_observer_1.last_bitrate_bps_));
      EXPECT_EQ(200000, static_cast<int>(bitrate_observer_2.last_bitrate_bps_));

      // Low BWE. Verify that all observers still get their respective min
      // bitrate.
      allocator_->OnNetworkChanged(1000, 0, 0);
      EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_);  // Min cap.
      EXPECT_EQ(200000u, bitrate_observer_2.last_bitrate_bps_);  // Min cap.
      EXPECT_EQ(300000u, bitrate_observer_3.last_bitrate_bps_);  // Min cap.

      allocator_->RemoveObserver(&bitrate_observer_1);
      allocator_->RemoveObserver(&bitrate_observer_2);
      allocator_->RemoveObserver(&bitrate_observer_3);
}

TEST_F(BitrateAllocatorTest, AddObserverWhileNetworkDown) {
  TestBitrateObserver bitrate_observer_1;
  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(50000, 0));

  allocator_->AddObserver(&bitrate_observer_1, 50000, 400000, 0, true);
  EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_1));

  // Set network down, ie, no available bitrate.
  allocator_->OnNetworkChanged(0, 0, 0);

  EXPECT_EQ(0u, bitrate_observer_1.last_bitrate_bps_);

  TestBitrateObserver bitrate_observer_2;
  // Adding an observer while the network is down should not affect the limits.
  EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(50000 + 50000, 0));
  allocator_->AddObserver(&bitrate_observer_2, 50000, 400000, 0, true);

  // Expect the start_bitrate to be set as if the network was still up but that
  // the new observer have been notified that the network is down.
  EXPECT_EQ(300000 / 2, allocator_->GetStartBitrate(&bitrate_observer_2));
  EXPECT_EQ(0u, bitrate_observer_1.last_bitrate_bps_);
  EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_bps_);

  // Set network back up.
  allocator_->OnNetworkChanged(1500000, 0, 50);
  EXPECT_EQ(750000u, bitrate_observer_1.last_bitrate_bps_);
  EXPECT_EQ(750000u, bitrate_observer_2.last_bitrate_bps_);
}

TEST_F(BitrateAllocatorTest, MixedEnforecedConfigs) {
  TestBitrateObserver enforced_observer;
      allocator_->AddObserver(&enforced_observer, 6000, 30000, 0, true);
      EXPECT_EQ(60000, allocator_->GetStartBitrate(&enforced_observer));

      TestBitrateObserver not_enforced_observer;
      allocator_->AddObserver(&not_enforced_observer, 30000, 2500000, 0, false);
      EXPECT_EQ(270000, allocator_->GetStartBitrate(&not_enforced_observer));
      EXPECT_EQ(30000u, enforced_observer.last_bitrate_bps_);

      allocator_->OnNetworkChanged(36000, 0, 50);
      EXPECT_EQ(6000u, enforced_observer.last_bitrate_bps_);
      EXPECT_EQ(30000u, not_enforced_observer.last_bitrate_bps_);

      allocator_->OnNetworkChanged(35000, 0, 50);
      EXPECT_EQ(30000u, enforced_observer.last_bitrate_bps_);
      EXPECT_EQ(0u, not_enforced_observer.last_bitrate_bps_);

      allocator_->OnNetworkChanged(5000, 0, 50);
      EXPECT_EQ(6000u, enforced_observer.last_bitrate_bps_);
      EXPECT_EQ(0u, not_enforced_observer.last_bitrate_bps_);

      allocator_->OnNetworkChanged(36000, 0, 50);
      EXPECT_EQ(30000u, enforced_observer.last_bitrate_bps_);
      EXPECT_EQ(0u, not_enforced_observer.last_bitrate_bps_);

      allocator_->OnNetworkChanged(55000, 0, 50);
      EXPECT_EQ(30000u, enforced_observer.last_bitrate_bps_);
      EXPECT_EQ(0u, not_enforced_observer.last_bitrate_bps_);

      allocator_->OnNetworkChanged(56000, 0, 50);
      EXPECT_EQ(6000u, enforced_observer.last_bitrate_bps_);
      EXPECT_EQ(50000u, not_enforced_observer.last_bitrate_bps_);

      allocator_->OnNetworkChanged(56000, 0, 50);
      EXPECT_EQ(16000u, enforced_observer.last_bitrate_bps_);
      EXPECT_EQ(40000u, not_enforced_observer.last_bitrate_bps_);

      allocator_->RemoveObserver(&enforced_observer);
      allocator_->RemoveObserver(&not_enforced_observer);
}

TEST_F(BitrateAllocatorTest, AvoidToggleAbsolute) {
  TestBitrateObserver observer;
      allocator_->AddObserver(&observer, 30000, 300000, 0, false);
      EXPECT_EQ(300000, allocator_->GetStartBitrate(&observer));

      allocator_->OnNetworkChanged(30000, 0, 50);
      EXPECT_EQ(30000u, observer.last_bitrate_bps_);

      allocator_->OnNetworkChanged(20000, 0, 50);
      EXPECT_EQ(0u, observer.last_bitrate_bps_);

      allocator_->OnNetworkChanged(30000, 0, 50);
      EXPECT_EQ(0u, observer.last_bitrate_bps_);

      allocator_->OnNetworkChanged(49000, 0, 50);
      EXPECT_EQ(0u, observer.last_bitrate_bps_);

      allocator_->OnNetworkChanged(50000, 0, 50);
      EXPECT_EQ(50000u, observer.last_bitrate_bps_);

      allocator_->OnNetworkChanged(30000, 0, 50);
      EXPECT_EQ(30000u, observer.last_bitrate_bps_);

      allocator_->RemoveObserver(&observer);
}

TEST_F(BitrateAllocatorTest, AvoidTogglePercent) {
  TestBitrateObserver observer;
      allocator_->AddObserver(&observer, 300000, 600000, 0, false);
      EXPECT_EQ(300000, allocator_->GetStartBitrate(&observer));

      allocator_->OnNetworkChanged(300000, 0, 50);
      EXPECT_EQ(300000u, observer.last_bitrate_bps_);

      allocator_->OnNetworkChanged(200000, 0, 50);
      EXPECT_EQ(0u, observer.last_bitrate_bps_);

      allocator_->OnNetworkChanged(300000, 0, 50);
      EXPECT_EQ(0u, observer.last_bitrate_bps_);

      allocator_->OnNetworkChanged(329000, 0, 50);
      EXPECT_EQ(0u, observer.last_bitrate_bps_);

      allocator_->OnNetworkChanged(330000, 0, 50);
      EXPECT_EQ(330000u, observer.last_bitrate_bps_);

      allocator_->OnNetworkChanged(300000, 0, 50);
      EXPECT_EQ(300000u, observer.last_bitrate_bps_);

      allocator_->RemoveObserver(&observer);
}

}  // namespace webrtc

redpajama_set_name: RedPajamaGithub


text:
require 'rspec'
require 'spec_helper'
require 'yaml'

RSpec.describe 'UserServiceTest' do
  config = YAML.load_file('./spec/test_config.yml')
  access_token = config['access_token']
  target = UserService.new(access_token)

  display_name = 'teratail'

  it '#find_allが200で返ってくること' do
    actual = target.find_all
    expect(actual['meta']['message']).to eq 'success'
  end

  it '#find_by_nameが200で返ってくること' do
    actual = target.find_by_name(display_name)
    expect(actual['meta']['message']).to eq 'success'
  end

  it '#find_oneが200で返ってくること' do
    actual = target.find_one(display_name)
    expect(actual['meta']['message']).to eq 'success'
  end

  it '#find_by_my_tagsが200で返ってくること' do
    actual = target.find_my_tags(display_name)
    expect(actual['meta']['message']).to eq 'success'
  end

  it '#find_clipped_questionが200で返ってくること' do
    actual = target.find_clipped_question(display_name)
    expect(actual['meta']['message']).to eq 'success'
  end

  it '#find_questionsが200で返ってくること' do
    actual = target.find_questions(display_name)
    expect(actual['meta']['message']).to eq 'success'
  end

  it '#find_repliesが200で返ってくること' do
    actual = target.find_replies(display_name)
    expect(actual['meta']['message']).to eq 'success'
  end

  it '#find_followerが200で返ってくること' do
    actual = target.get_follower(display_name)
    expect(actual['meta']['message']).to eq 'success'
  end

  it '#find_followingが200で返ってくること' do
    actual = target.get_following(display_name)
    expect(actual['meta']['message']).to eq 'success'
  end
end


text:
package de.alexanderkohout.seriesreminder;

import android.app.Application;

import uk.co.chrisjenx.calligraphy.CalligraphyConfig;

/**
 * The main application class.
 */
public class SeriesReminderApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        // Initialize the Postface font as default typeface for the fontPath
        // attribute
        CalligraphyConfig.initDefault(
                "fonts/Postface.otf",
                R.attr.fontPath);
    }
}


text:
      <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">

      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.6.2/jquery.contextMenu.min.css">

      <link rel="stylesheet" href="main.css">

Preview Mode

Page Settings

Toggle Snap

Get Config Url

        Profile:

1

2

3

        Not Connected

      This is your overlay, copy this URL and paste it into the Browser Source URL in OBS.  It will not change.
      <input type="text" id="urlText" style="width:400px" />

      <input type="button" id="copyUrl" value="Copy URL to Clipboard" />

      Someone want your layout setup?  Send them this:
      <input type="text" id="tinyUrlText" style="width:400px" />

      <input type="button" id="copyTinyUrl" value="Copy Export URL to Clipboard" />

Scale:<input type="text" id="scale" />

Hide Icon When Missing:<input type="checkbox" id="hideWhenMissing" />

Flourish:<select id="flourish">
          <option value="none">None</option>
          <option value="topLeft">Top Left</option>
          <option value="topRight">Top Right</option>
        </select>

Grow From:<select id="growDirection">
          <option value="Left">Left To Right</option>
          <option value="Right">Right To Left</option>
        </select>

Page Width:<input type="text" id="pageWidth" />

Page Height:<input type="text" id="pageHeight" />

        Hey There!  Looks like you've never setup the Hollow Knight OBS Overlay before (or this is the first time since the big 2.0 release of the overlay).  To get started, lets set a few things up.  If you're seeing this message in OBS, take the URL for this page and go over to Chrome/FireFox/IE and go through the setup. Once done you'll be given a new URL for OBS that contains your setup.

        For Page Width and Height, this should be the size, in pixels, that you normally capture HK with in OBS.  Common values are 1920x1080 & 1080x720.

        Next you'll be given the ability to move stuff around the page.  The green border signifies the area that you'll be displaying in OBS.  Icons can be moved from container to container or reordered within the container.  Icons moved into the Red/Disabled container will be hidden even if you pick them up.

        For more information go to: https://github.com/iamwyza/HollowKnightRandomizerTracker

Page Width:<input type="text" id="setupPageWidth" value="1920" />

Page Height:<input type="text" id="setupPageHeight" value="1080" />

Enabled:<input type="checkbox" id="miscEnabled" />

Font Size:<input type="text" id="miscFontSize" />

Color:<input type="text" id="miscFontColor" />

        Looks like you're loading in a config from the URL.  This might be because you've just added the profile feature in Overlay 2.1.  If so, just select profile 1.

        If you're importing a layout from another runner, but don't want to overwrite your current layout, pick a profile you haven't used before.

        <select id="importProfileSelect">
          <option value="1">Profile 1</option>
          <option value="2">Profile 2</option>
          <option value="3">Profile 3</option>
        </select>


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<title>All Classes</title>
<meta name="date" content="2015-07-06">
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">

All Classes

AABB

ArrayBitmap

ArrayBitmap.IVisitor

AudioComponent

BaseButton

BaseButton.Command

ButtonAxis

ColliderComponent

CollisionComponent

Color

CompoundAxis

CompoundButton

Config

CoreEngine

Debug

Delay

Dither

DoublePair

Entity

EntityComponent

FadeRemove

Grid

IAudioDevice

IAxis

IButton

IDAssigner

IDisplay

IEntityVisitor

IInput

IMenuHandler

IRenderContext

IRenderDevice

IRenderDevice.BlendMode

ISpatialObject

ISpatialStructure

JoystickAxis

JoystickButton

JSON

JSONArray

JSONLiteral

JSONNumber

JSONObject

JSONString

JSONValue

KeyButton

LightComponent

LightMap

LightMapFactory

LinkComponent

Main

Menu

MenuStack

MouseButton

OpenALAudioDevice

OpenGLDisplay

OpenGLInput

OpenGLRenderDevice

QuadTree

RemoveComponent

RenderContext

RenderTarget

Scene

Sound

SoundData

SoundFactory

SpriteComponent

SpriteSheet

SpriteSheetBorderMaker

SpriteSheetFactory

Texture

TextureFactory

TokenReader

Util


text:
from __future__ import with_statement
from copy import deepcopy
import re
import sys

from django.core.cache import cache
from django.conf import settings
from django.contrib.auth.models import Permission
from django.core.urlresolvers import clear_url_caches
from django.http import Http404
from django.template import Variable
from django.test.utils import override_settings

from cms.api import create_page, create_title, publish_page
from cms.apphook_pool import apphook_pool
from cms.models import PagePermission, UserSettings, Placeholder
from cms.page_rendering import _handle_no_page
from cms.test_utils.testcases import CMSTestCase
from cms.test_utils.util.fuzzy_int import FuzzyInt
from cms.utils.compat import DJANGO_1_7
from cms.utils.conf import get_cms_setting
from cms.views import details
from menus.menu_pool import menu_pool

APP_NAME = 'SampleApp'
APP_MODULE = "cms.test_utils.project.sampleapp.cms_app"

@override_settings(
    CMS_PERMISSION=True,
    ROOT_URLCONF='cms.test_utils.project.urls',
)
class ViewTests(CMSTestCase):

    def setUp(self):
        clear_url_caches()

    def test_handle_no_page(self):
        """
        Test handle nopage correctly works with DEBUG=True
        """
        request = self.get_request('/')
        slug = ''
        self.assertRaises(Http404, _handle_no_page, request, slug)
        with self.settings(DEBUG=True):
            request = self.get_request('/en/')
            slug = ''
            response = _handle_no_page(request, slug)
            self.assertEqual(response.status_code, 200)

    def test_apphook_not_hooked(self):
        """
        Test details view when apphook pool has apphooks, but they're not
        actually hooked
        """
        if APP_MODULE in sys.modules:
            del sys.modules[APP_MODULE]
        apphooks = (
            '%s.%s' % (APP_MODULE, APP_NAME),
        )
        create_page("page2", "nav_playground.html", "en", published=True)
        with self.settings(CMS_APPHOOKS=apphooks):
            apphook_pool.clear()
            response = self.client.get('/en/')
            self.assertEqual(response.status_code, 200)
            apphook_pool.clear()

    def test_external_redirect(self):
        # test external redirect
        redirect_one = 'https://www.django-cms.org/'
        one = create_page("one", "nav_playground.html", "en", published=True,
                          redirect=redirect_one)
        url = one.get_absolute_url()
        request = self.get_request(url)
        response = details(request, one.get_path("en"))
        self.assertEqual(response.status_code, 302)
        self.assertEqual(response['Location'], redirect_one)

    def test_internal_neutral_redirect(self):
        # test internal language neutral redirect
        redirect_one = 'https://www.django-cms.org/'
        redirect_two = '/'
        one = create_page("one", "nav_playground.html", "en", published=True,
                          redirect=redirect_one)
        two = create_page("two", "nav_playground.html", "en", parent=one,
                          published=True, redirect=redirect_two)
        url = two.get_absolute_url()
        request = self.get_request(url)
        response = details(request, two.get_path())
        self.assertEqual(response.status_code, 302)
        self.assertEqual(response['Location'], '/en/')

    def test_internal_forced_redirect(self):
        # test internal forced language redirect
        redirect_one = 'https://www.django-cms.org/'
        redirect_three = '/en/'
        one = create_page("one", "nav_playground.html", "en", published=True,
                          redirect=redirect_one)
        three = create_page("three", "nav_playground.html", "en", parent=one,
                            published=True, redirect=redirect_three)
        url = three.get_slug()
        request = self.get_request(url)
        response = details(request, url.strip('/'))
        self.assertEqual(response.status_code, 302)
        self.assertEqual(response['Location'], redirect_three)

    def test_redirect_to_self(self):
        one = create_page("one", "nav_playground.html", "en", published=True,
                          redirect='/')
        url = one.get_absolute_url()
        request = self.get_request(url)
        response = details(request, one.get_path())
        self.assertEqual(response.status_code, 200)

    def test_redirect_to_self_with_host(self):
        one = create_page("one", "nav_playground.html", "en", published=True,
                          redirect='http://testserver/en/')
        url = one.get_absolute_url()
        request = self.get_request(url)
        response = details(request, one.get_path())
        self.assertEqual(response.status_code, 200)

    def test_redirect_with_toolbar(self):
        create_page("one", "nav_playground.html", "en", published=True,
                    redirect='/en/page2')
        superuser = self.get_superuser()
        with self.login_user_context(superuser):
            response = self.client.get('/en/?%s' % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON'))
            self.assertEqual(response.status_code, 200)

    def test_login_required(self):
        create_page("page", "nav_playground.html", "en", published=True,
                    login_required=True)
        plain_url = '/accounts/'
        login_rx = re.compile("%s\?(signin=|next=/en/)&" % plain_url)
        with self.settings(LOGIN_URL=plain_url + '?signin'):
            request = self.get_request('/en/')
            response = details(request, '')
            self.assertEqual(response.status_code, 302)
            self.assertTrue(login_rx.search(response['Location']))
        login_rx = re.compile("%s\?(signin=|next=/)&" % plain_url)
        with self.settings(USE_I18N=False, LOGIN_URL=plain_url + '?signin'):
            request = self.get_request('/')
            response = details(request, '')
            self.assertEqual(response.status_code, 302)
            self.assertTrue(login_rx.search(response['Location']))

    def test_edit_permission(self):
        page = create_page("page", "nav_playground.html", "en", published=True)
        # Anon user
        response = self.client.get("/en/?%s" % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON'))
        self.assertNotContains(response, "cms_toolbar-item-switch-save-edit", 200)

        # Superuser
        user = self.get_superuser()
        with self.login_user_context(user):
            response = self.client.get("/en/?%s" % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON'))
        self.assertContains(response, "cms-toolbar-item-switch-save-edit", 1, 200)

        # Admin but with no permission
        user = self.get_staff_user_with_no_permissions()
        user.user_permissions.add(Permission.objects.get(codename='change_page'))

        with self.login_user_context(user):
            response = self.client.get("/en/?%s" % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON'))
        self.assertNotContains(response, "cms-toolbar-item-switch-save-edit", 200)

        PagePermission.objects.create(can_change=True, user=user, page=page)
        with self.login_user_context(user):
            response = self.client.get("/en/?%s" % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON'))
        self.assertContains(response, "cms-toolbar-item-switch-save-edit", 1, 200)

    def test_toolbar_switch_urls(self):
        user = self.get_superuser()
        user_settings = UserSettings(language="en", user=user)
        placeholder = Placeholder(slot="clipboard")
        placeholder.save()
        user_settings.clipboard = placeholder
        user_settings.save()

        page = create_page("page", "nav_playground.html", "en", published=True)
        create_title("fr", "french home", page)
        publish_page(page, user, "fr")

        with self.login_user_context(user):
            response = self.client.get("/fr/?%s" % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON'))
            self.assertContains(response, "/fr/?%s" % get_cms_setting('CMS_TOOLBAR_URL__EDIT_OFF'), 1, 200)
            response = self.client.get("/fr/?%s" % get_cms_setting('CMS_TOOLBAR_URL__EDIT_OFF'))
            self.assertContains(response, "/fr/?%s" % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON'), 1, 200)

@override_settings(ROOT_URLCONF='cms.test_utils.project.urls')
class ContextTests(CMSTestCase):

    def test_context_current_page(self):
        """
        Asserts the number of queries triggered by
        `cms.context_processors.cms_settings` and `cms.middleware.page`
        """
        from django.template import context

        page_template = "nav_playground.html"
        if DJANGO_1_7:
            original_context = {'TEMPLATE_CONTEXT_PROCESSORS': settings.TEMPLATE_CONTEXT_PROCESSORS}
            override = {'TEMPLATE_CONTEXT_PROCESSORS': list(settings.TEMPLATE_CONTEXT_PROCESSORS)}
            override['TEMPLATE_CONTEXT_PROCESSORS'].remove("cms.context_processors.cms_settings")
        else:
            original_context = {'TEMPLATES': settings.TEMPLATES}
            override = {'TEMPLATES': deepcopy(settings.TEMPLATES)}
            override['TEMPLATES'][0]['OPTIONS']['context_processors'].remove("cms.context_processors.cms_settings")
        page = create_page("page", page_template, "en", published=True)
        page_2 = create_page("page-2", page_template, "en", published=True,
                             parent=page)

        # Tests for standard django applications
        # 1 query is executed in get_app_patterns(), not related
        # to cms.context_processors.cms_settings.
        # Executing this oputside queries assertion context ensure
        # repetability
        self.client.get("/en/plain_view/")

        cache.clear()
        menu_pool.clear()
        context._standard_context_processors = None
        # Number of queries when context processors is not enabled
        with self.settings(**override):
            with self.assertNumQueries(FuzzyInt(0, 12)) as context:
                response = self.client.get("/en/plain_view/")
                num_queries = len(context.captured_queries)
                self.assertFalse('CMS_TEMPLATE' in response.context)
        cache.clear()
        menu_pool.clear()
        # Number of queries when context processor is enabled
        with self.settings(**original_context):
            # no extra query is run when accessing urls managed by standard
            # django applications
            with self.assertNumQueries(FuzzyInt(0, num_queries)):
                response = self.client.get("/en/plain_view/")
            # One query when determining current page
            with self.assertNumQueries(FuzzyInt(0, 1)):
                self.assertFalse(response.context['request'].current_page)
                self.assertFalse(response.context['request']._current_page_cache)
            # Zero more queries when determining the current template
            with self.assertNumQueries(0):
                # Template is the first in the CMS_TEMPLATES list
                template = Variable('CMS_TEMPLATE').resolve(response.context)
                self.assertEqual(template, get_cms_setting('TEMPLATES')[0][0])
        cache.clear()
        menu_pool.clear()

        # Number of queries when context processors is not enabled
        with self.settings(**override):
            # Baseline number of queries
            with self.assertNumQueries(FuzzyInt(13, 19)) as context:
                response = self.client.get("/en/page-2/")
                num_queries_page = len(context.captured_queries)
        cache.clear()
        menu_pool.clear()

        # Number of queries when context processors is enabled
        with self.settings(**original_context):
            # Exactly the same number of queries are executed with and without
            # the context_processor
            with self.assertNumQueries(num_queries_page):
                response = self.client.get("/en/page-2/")
                template = Variable('CMS_TEMPLATE').resolve(response.context)
                self.assertEqual(template, page_template)
        cache.clear()
        menu_pool.clear()
        page_2.template = 'INHERIT'
        page_2.save()
        page_2.publish('en')
        with self.settings(**original_context):
            # One query more triggered as page inherits template from ancestor
            with self.assertNumQueries(num_queries_page + 1):
                response = self.client.get("/en/page-2/")
                template = Variable('CMS_TEMPLATE').resolve(response.context)
                self.assertEqual(template, page_template)


text:
var _ = require('lodash');
var config = require('cabrel-config')();
var hapi = require('hapi');
var internals = { properties: {} };
var NodeUtil = require('util');

var cluster = require('cluster');
var numCPUs = require('os').cpus().length;

var Q = require('q');

var winston = require('winston');
require('cabrel-winston-redis').Redis;

var session = require('cabrel-hapi-session');

Q.all([
  config.get('logging', 'host'),
  config.get('logging', 'port'),
  config.get('logging', 'db'),
  config.get('logging', 'facility'),
  config.get('server', 'host'),
  config.get('server', 'port'),
  config.get('hapi', 'config', true),
  config.get('hapi', 'plugins', true),
  config.get('crypt', 'cookies'),
  config.get('crypt', 'iron')
]).then(function(result) {
  internals.properties['loghost'] = result[0];
  internals.properties['logport'] = Number(result[1]);
  internals.properties['logdb'] = Number(result[2]);
  internals.properties['logfacility'] = result[3];
  internals.properties['hostname'] = result[4];
  internals.properties['port'] = Number(result[5]);
  internals.properties['hapiconfig'] = result[6];
  internals.properties['plugins'] = result[7];
  internals.properties['cookies'] = result[8];
  internals.properties['iron'] = result[9];

  winston.add(winston.transports.Redis, {
    'host': internals.properties.loghost,
    'port': internals.properties.logport,
    'db': internals.properties.logdb,
    'container': internals.properties.logfacility
  });

  winston.remove(winston.transports.Console);
  winston.add(winston.transports.File, { filename: '/var/log/node-seed.log', maxsize: (1024 * 1024) * 2 });

}).then(function() {
  internals.pack = new hapi.Pack();
  internals.pack.server(internals.properties.host, internals.properties.port, internals.properties.hapiconfig);
  internals.server = internals.pack._servers[0];

  internals.server.app.iron = { password: internals.properties.iron };
  internals.server.app.cookies = { password: internals.properties.cookies };

}).then(function() {
  internals.pack.allow({ext: true}).require('good', internals.properties.plugins.good, function(err) {
    if (err) {
      console.log(err);
    }
  });

}).then(function() {
  // configure the server authentication
  internals.server.auth('session',
      session.cookie(internals.properties.cookies, '/folders', internals.properties.iron));

}).then(function() {
  var httpEndpoints = require('./api/example');

  Object.keys(httpEndpoints).forEach(function(ep) {
    internals.server.addRoute(httpEndpoints[ep]);
  });
}).done(function() {
  if (cluster.isMaster) {
    for (var i = 0; i < numCPUs; i++) {
      cluster.fork();
    }

    cluster.on('exit', function(worker, code, signal) {
      winston.info('cluster worker %s died', worker.process.pid);
    });

    cluster.on('online', function(worker) {
      winston.info('cluster worker %s is online', worker.process.pid);
    });

  } else {
    internals.pack.start(function() {
      console.log('Server started @ %s', internals.server.info.uri);
      internals.server.on('log', function(event, tags) {
        if (tags.error) {
          winston.error('Hapi log event', { 'data': event.data, 'tags': tags });
        }
      });

      internals.server.on('internal error', function(request, error) {
        winston.error('Hapi internal error for: ' + request.id, {
          'error': error,
          'info': request.info,
          'auth': request.auth || {}
        });
      });
    });
  }
}, function(error) {
  console.log(error);
  winston.error('internal error', { 'msg': JSON.stringify(error.message) });
});


text:
/**
 * Created by USRDEL on 22/7/17.
 */
/**
 * Created by USRDEL on 19/6/17.
 */
//    localhost:1337/Usuario/metodos
module.exports = {
    eliminarUsuario: function (req, res) {
        var params = req.allParams();
        sails.log.info("Parametros", params);
        if (req.method == "POST" && params.id) {
            Usuario.destroy({
                id: params.id
            }).exec(function (err, usuarioBorrado) {
                if (err)
                    return res.serverError(err);
                return res.redirect("/");
            });
        }
        else {
            return res.badRequest();
        }
    },
    editarUsuario: function (req, res) {
        var parametros = req.allParams();
        if (parametros.nombres &&
            parametros.apellidos &&
            parametros.correo &&
            parametros.id) {
            Usuario.update({
                id: parametros.id
            }, {
                nombres: parametros.nombres,
                apellidos: parametros.apellidos,
                correo: parametros.correo
            })
                .exec(function (err, usuarioEditado) {
                if (err)
                    return res.serverError(err);
                if (usuarioEditado) {
                    //Si encontro
                    return res.redirect("/");
                }
                else {
                    //No encontro
                    return res.notFound();
                }
            });
        }
        else {
            return res.badRequest();
        }
    }
};


text:
/*
 This test is meant to reproduce the following error:

 - The machine or current user has a German locale.
 - This esp. means that stream IO expects the decimal separator as a comma: ","
 - DICOM files use a point "." as the decimal separator to be locale independent
 - The parser used by MITK (ITK's GDCM) seems to use the current locale instead of the "C" or "POSIX" locale
 - This leads to spacings (and probably other numbers) being trimmed/rounded,
   e.g. the correct spacing of 0.314 is read as 1.0 etc.

*/

#include "mitkDicomSeriesReader.h"
#include "mitkIOUtil.h"
#include "mitkImage.h"
#include "mitkStandardFileLocations.h"

#include "mitkTestFixture.h"
#include "mitkTestingMacros.h"

#include <list>
#include <locale.h>
#include <locale>

class mitkDICOMLocaleTestSuite : public mitk::TestFixture
{
  CPPUNIT_TEST_SUITE(mitkDICOMLocaleTestSuite);
  CPPUNIT_TEST_SUITE_ADD_CUSTOM_TESTS(addDICOMLocaleWithReferenceImageTests);
  CPPUNIT_TEST_SUITE_END();

private:
  // A custom method for adding a combination of filename and locale tests
  static void addDICOMLocaleWithReferenceImageTests(TestSuiteBuilderContextType &context)
  {
    std::vector<std::string> fileArgs;
    fileArgs.push_back("spacing-ok-ct.dcm");
    fileArgs.push_back("spacing-ok-mr.dcm");
    fileArgs.push_back("spacing-ok-sc.dcm");

    // load a reference DICOM file with German locales being set
    std::vector<std::string> localeArgs;
    localeArgs.push_back("C");
    localeArgs.push_back("de_DE");
    localeArgs.push_back("de_DE.utf8");
    localeArgs.push_back("de_DE.UTF8");
    localeArgs.push_back("de_DE@euro");
    localeArgs.push_back("German_Germany");

    for (std::size_t fileIndex = 0; fileIndex < fileArgs.size(); ++fileIndex)
    {
      for (std::size_t localeIndex = 0; localeIndex < localeArgs.size(); ++localeIndex)
      {
        MITK_PARAMETERIZED_TEST_2(testLocaleWithReferenceImage, fileArgs[fileIndex], localeArgs[localeIndex]);
      }
    }
  }

private:
  std::string m_FileName;
  std::string m_Locale;
  bool m_SkipImageTest;

  char *m_OldLocale;

  void SetTestParameter()
  {
    std::vector<std::string> parameter = GetTestParameter();
    CPPUNIT_ASSERT(parameter.size() == 2);
    m_FileName = GetTestDataFilePath(parameter[0]);
    m_Locale = parameter[1];
  }

public:
  mitkDICOMLocaleTestSuite() : m_OldLocale(NULL), m_SkipImageTest(false) {}
  // Change the current locale to m_Locale
  void setUp() override
  {
    m_SkipImageTest = false;
    m_OldLocale = NULL;
    SetTestParameter();

    try
    {
      m_OldLocale = setlocale(LC_ALL, NULL);
      MITK_TEST_OUTPUT(<< " ** Changing locale from " << m_OldLocale << " to '" << m_Locale << "'")
      setlocale(LC_ALL, m_Locale.c_str());
      std::cin.imbue(std::locale(m_Locale.c_str()));
    }
    catch (...)
    {
      MITK_TEST_OUTPUT(<< "Could not activate locale " << m_Locale)
      m_SkipImageTest = true;
    }
  }

  void tearDown() override
  {
    if (m_OldLocale)
    {
      setlocale(LC_ALL, m_OldLocale);
      std::cin.imbue(std::locale(m_OldLocale));
    }
  }

  void testLocaleWithReferenceImage()
  {
    if (m_SkipImageTest)
      return;

    mitk::Image::Pointer image = mitk::IOUtil::LoadImage(m_FileName);
    CPPUNIT_ASSERT(image.IsNotNull());

    // note importance of minor differences in spacings:
    // DICOM has order y-spacing, x-spacing, while in MITK we assume x-spacing, y-spacing (both meant for 0 and 1 index
    // in array)
    CPPUNIT_ASSERT_MESSAGE("incorrect x spacing", mitk::Equal(image->GetGeometry()->GetSpacing()[0], 0.3141592));
    CPPUNIT_ASSERT_MESSAGE("incorrect y spacing ", mitk::Equal(image->GetGeometry()->GetSpacing()[1], 0.3411592));
  }
};

MITK_TEST_SUITE_REGISTRATION(mitkDICOMLocale)


text:
cmd-clip
========

Simple command repository with direct clipboard access. Replacement for a text file, f***ing about with the mouse/cursors and then cmd-c-alt-tab-cmd-v

Project Requirements
====================

* Must be easy to set-up. Adding new commands should be done by adding the to a text file.
* Must be quick to paste a command using keyboard.
* Should use system clipboard to maximise comapability with other apps.
* Should support multiple contexts so command lists can be kept short and related to specific activities.
* Should support MacOS and Linux.
* May support Windows.
* May have minimal gui for more complex tasks (i.e. switching context) and feedback (i.e. displaying hints).

File Structure
==============

    ~/.cmd-clip
     |
     +- My Task
        |
        +- clip.txt


text:
/* globals describe, it, before, after */
"use strict";

var _ = require('lodash');
var should = require("chai").should();
var Model = require("../model");
var Collection = require("../collection");
var Mongo = require("../mongo");

// TODO FIX TESTS
return;

describe("Collections", function() {

  // Local variables
  var savedId;

  // Before
  // Connect to mongodb

  before(function(done) {
    var db = new Mongo("mongodb://localhost:27017/test");
    db.connect();
    db.on("connect", function(url) {
      Model.prototype.db = db;
      Model.prototype.urlRoot = "tests";
      Collection.prototype.db = db;
      Collection.prototype.db.eraseCollection("tests");
      done();
    });
  });

  before(function(done) {
    var modelOne = new Model({
      cid: 1,
      name: "Pedro Sanchez"
    });

    modelOne.save(null, {
      success: function(modelOne, resp, options) {
        var modelTwo = new Model({
          cid: 2,
          name: "Jack Dagnels"
        });

        modelTwo.save(null, {
          success: function(modelTwo, resp, options) {
            done();
          }
        });
      }
    });

  });

  // Fetch

  it("should fetch", function(done) {
    var collection = new Collection();
    collection.fetch({
      success: function(collection, resp, options) {
        collection.length.should.equal(2);
        (collection.at(0) instanceof Model).should.be.true;
        (collection.at(1) instanceof Model).should.be.true;
        collection.at(0).get("name").should.equal("Pedro Sanchez");
        collection.at(1).get("name").should.equal("Jack Dagnels");

        done();
      }
    });
  });

  it("should fetch with promise", function(done) {
    var collection = new Collection();
    collection.fetch()
      .then(function(resp) {
        collection.length.should.equal(2);
        (collection.at(0) instanceof Model).should.be.true;
        (collection.at(1) instanceof Model).should.be.true;
        collection.at(0).get("name").should.equal("Pedro Sanchez");
        collection.at(1).get("name").should.equal("Jack Dagnels");
        done();
      })
      .catch(function(err) {
        done();
      });
  });

  it("should fetch with limit and skip", function(done) {
    var collection = new Collection();
    collection.fetch({
      limit: 1,
      skip: 1,
      success: function(collection, resp, options) {
        collection.length.should.equal(1);
        (collection.at(0) instanceof Model).should.be.true;
        collection.at(0).get("name").should.equal("Jack Dagnels");

        done();
      }
    });
  });

  it("should fetch with sort desc", function(done) {
    var collection = new Collection();
    collection.fetch({
      sort: [
        ["cid", "desc"]
      ],
      success: function(collection, resp, options) {
        collection.length.should.equal(2);
        collection.at(0).get("name").should.equal("Jack Dagnels");

        done();
      }
    });
  });

  it("should fetch with sort asc", function(done) {
    var collection = new Collection();
    collection.fetch({
      sort: [
        ["cid", "asc"]
      ],
      success: function(collection, resp, options) {
        collection.length.should.equal(2);
        collection.at(0).get("name").should.equal("Pedro Sanchez");

        done();
      }
    });
  });

  it("should fetch with query and regex", function(done) {
    var collection = new Collection();
    collection.fetch({
      query: {
        name: /pedro sanchez/i
      },
      success: function(collection, resp, options) {
        collection.length.should.equal(1);
        (collection.at(0) instanceof Model).should.be.true;

        done();
      }
    });
  });

  // Count

  it("should count", function(done) {
    var collection = new Collection();
    collection.count({
      success: function(resp) {
        resp.should.equal(2);
        done();
      }
    });
  });

  it("should count with promise", function(done) {
    var collection = new Collection();
    collection.count()
      .then(function(resp) {
        resp.should.equal(2);
        done();
      })
      .catch(function(err) {
        done();
      });
  });

  // After

  after(function(done) {
    done();
  });

});


text:
import numpy as np
from sklearn.preprocessing import Imputer
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
import pandas as pd

veri = pd.read_csv("data.data")

veri=veri.replace('?', -222, inplace='true')
veri=veri.drop(['id'], axis=1)

y = veri.benormal
x = veri.drop(['benormal'], axis=1)

imp = Imputer(missing_values=-222, strategy="mean",axis=0)
x = imp.fit_transform(x)

tahmin = KNeighborsClassifier(n_neighbors=4, weights='uniform', algorithm='auto', leaf_size=30, p=2, metric='euclidean', metric_params=None, n_jobs=1)
tahmin.fit(x,y)
ytahmin = tahmin.predict(x)

basari = accuracy_score(y, ytahmin, normalize=True, sample_weight=None)
print("Yüzde",basari*100," oranında:" )

print(tahmin.predict([1,1,1,1,1,1,1,1,1,1]))