<commit_before>// TODO(fancycode): Should load through AMD if possible.
/* global SimpleWebRTC, OC, OCA: false */

var webrtc;
var spreedMappingTable = [];

(function(OCA, OC) {
	'use strict';

	OCA.SpreedMe = OCA.SpreedMe || {};

	/**
	 * @private
	 */
	function openEventSource() {
		// Connect to the messages endpoint and pull for new messages
		var messageEventSource = new OC.EventSource(OC.generateUrl('/apps/spreed/messages'));
		var previousUsersInRoom = [];
		Array.prototype.diff = function(a) {
			return this.filter(function(i) {
				return a.indexOf(i) < 0;
			});
		};
		messageEventSource.listen('usersInRoom', function(users) {
			var currentUsersInRoom = [];
			users.forEach(function(user) {
				currentUsersInRoom.push(user['sessionId']);
				spreedMappingTable[user['sessionId']] = user['userId'];
			});

			var currentUsersNo = currentUsersInRoom.length;
			if(currentUsersNo === 0) {
				currentUsersNo = 1;
			}

			var appContentElement = $('#app-content'),
				participantsClass = 'participants-' + currentUsersNo;
			if (!appContentElement.hasClass(participantsClass)) {
				appContentElement.attr('class', '').addClass(participantsClass);
			}

			var disconnectedUsers = previousUsersInRoom.diff(currentUsersInRoom);
			disconnectedUsers.forEach(function(user) {
				console.log('XXX Remove peer', user);
				OCA.SpreedMe.webrtc.removePeers(user);
			});
			previousUsersInRoom = currentUsersInRoom;
		});

		messageEventSource.listen('message', function(message) {
			message = JSON.parse(message);
			var peers = self.webrtc.getPeers(message.from, message.roomType);
			var peer;

			if (message.type === 'offer') {
				if (peers.length) {
					peers.forEach(function(p) {
						if (p.sid === message.sid) {
							peer = p;
						}
					});
				}
				if (!peer) {
					peer = self.webrtc.createPeer({
						id: message.from,
						sid: message.sid,
						type: message.roomType,
						enableDataChannels: true,
						sharemyscreen: message.roomType === 'screen' && !message.broadcaster,
						broadcaster: message.roomType === 'screen' && !message.broadcaster ? self.connection.getSessionid() : null
					});
					OCA.SpreedMe.webrtc.emit('createdPeer', peer);
				}
				peer.handleMessage(message);
			} else if (peers.length) {
				peers.forEach(function(peer) {
					if (message.sid) {
						if (peer.sid === message.sid) {
							peer.handleMessage(message);
						}
					} else {
						peer.handleMessage(message);
					}
				});
			}
		});
		messageEventSource.listen('__internal__', function(data) {
			if (data === 'close') {
				console.log('signaling connection closed - will reopen');
				setTimeout(openEventSource, 0);
			}
		});
	}

	function initWebRTC() {
		'use strict';
		openEventSource();

		webrtc = new SimpleWebRTC({
			localVideoEl: 'localVideo',
			remoteVideosEl: '',
			autoRequestMedia: true,
			debug: false,
			media: {
				audio: true,
				video: {
					width: { max: 1280 },
					height: { max: 720 }
				}
			},
			autoAdjustMic: false,
			detectSpeakingEvents: true,
			connection: OCA.SpreedMe.XhrConnection,
			enableDataChannels: true,
			nick: OC.getCurrentUser()['displayName']
	});
		OCA.SpreedMe.webrtc = webrtc;

		var $appContent = $('#app-content');
		var spreedListofSpeakers = {};
		var latestSpeakerId = null;
		OCA.SpreedMe.speakers = {
			showStatus: function() {
				var data = [];
				for (var currentId in spreedListofSpeakers) {
					// skip loop if the property is from prototype
					if (!spreedListofSpeakers.hasOwnProperty(currentId)) {
						continue;
					}

					var currentTime = spreedListofSpeakers[currentId];
					var id = currentId.replace('\\', '');
					data.push([spreedMappingTable[id], id, currentTime]);
				}
				console.log('spreedListofSpeakers');
				console.table(data);
				console.log('spreedMappingTable');
				console.table(spreedMappingTable);
			},
			getContainerId: function(id) {
				var sanitizedId = id.replace(/[!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g, "\\$&");
				return '#container_' + sanitizedId + '_type_incoming';
			},
			switchVideoToId: function(id) {
				var videoSpeakingElement = $('#video-speaking');

				if (latestSpeakerId !== null) {
					console.log('promote: unpromote speaker "' + spreedMappingTable[latestSpeakerId] + '"');
					// move old video to new location
					var oldContainer = $(OCA.SpreedMe.speakers.getContainerId(latestSpeakerId));
					oldContainer.removeClass('speaking');
					oldContainer.parent().find('.videoContainer-dummy').remove();
				}

				// add new user to it
				var newContainer = $(OCA.SpreedMe.speakers.getContainerId(id));
				newContainer.addClass('speaking');
				newContainer.after(
					$('<div>')
						.addClass('videoContainer videoContainer-dummy')
						.append(newContainer.find('.nameIndicator'))
					);

				latestSpeakerId = id;
			},
			add: function(id) {
				if (!(typeof id === 'string' || id instanceof String)) {
					return;
				}

				var sanitizedId = OCA.SpreedMe.speakers.getContainerId(id);
				spreedListofSpeakers[sanitizedId] = (new Date()).getTime();

				if (latestSpeakerId === id) {
					console.log('promoting: latest speaker "' + spreedMappingTable[id] + '" is already promoted');
					return;
				}

				console.log('promoting: change promoted speaker to "' + spreedMappingTable[id] + '" after speaking');
				OCA.SpreedMe.speakers.switchVideoToId(id);
			},
			remove: function(id) {
				if (!(typeof id === 'string' || id instanceof String)) {
					return;
				}

				var sanitizedId = OCA.SpreedMe.speakers.getContainerId(id);
				spreedListofSpeakers[sanitizedId] = -1;

				if (latestSpeakerId !== id) {
					console.log('promoting: stopped speaker "' + spreedMappingTable[id] + '" is not promoted');
					return;
				}

				console.log('promoting: try to find better promoted speaker for "' + spreedMappingTable[id] + '"');

				var mostRecentTime = 0,
					mostRecentId = null;
				for (var currentId in spreedListofSpeakers) {
					// skip loop if the property is from prototype
					if (!spreedListofSpeakers.hasOwnProperty(currentId)) {
						continue;
					}

					// skip non-string ids
					if (!(typeof currentId === 'string' || currentId instanceof String))  continue;

					var currentTime = spreedListofSpeakers[currentId];
					if (currentTime > mostRecentTime) {
						mostRecentTime = currentTime;
						mostRecentId = currentId;
					}
				}

				if (mostRecentId !== null) {
					console.log('promoting: change promoted speaker from "' + spreedMappingTable[id] + '" to "' + spreedMappingTable[mostRecentId] + '" after speakingStopped');
					OCA.SpreedMe.speakers.switchVideoToId(mostRecentId);
				} else {
					console.log('promoting: no recent speaker to promote - keep "' + spreedMappingTable[id] + '"');
				}
			}
		};

		OCA.SpreedMe.webrtc.on('createdPeer', function (peer) {
			peer.pc.on('PeerConnectionTrace', function (event) {
				console.log('trace', event);
			});
		});

		OCA.SpreedMe.webrtc.on('localMediaError', function(error) {
			console.log('Access to microphone & camera failed', error);
			var message, messageAdditional;
			if (error.name === "NotAllowedError") {
				if (error.message && error.message.indexOf("Only secure origins") !== -1) {
					message = t('spreed', 'Access to microphone & camera is only possible with HTTPS');
					messageAdditional = t('spreed', 'Please adjust your configuration');
				} else {
					message = t('spreed', 'Access to microphone & camera was denied');
					$('#emptycontent p').hide();
				}
			} else {
				message = t('spreed', 'Error while accessing microphone & camera: {error}', {error: error.message || error.name});
				$('#emptycontent p').hide();
			}
			$('#emptycontent h2').text(message);
			$('#emptycontent p').text(messageAdditional);
		});

		OCA.SpreedMe.webrtc.on('joinedRoom', function(name) {
			$('#app-content').removeClass('icon-loading');
			$('.videoView').removeClass('hidden');
			OCA.SpreedMe.app.syncAndSetActiveRoom(name);
		});

		OCA.SpreedMe.webrtc.on('channelMessage', function (peer, label, data) {
			if(label === 'speaking') {
				OCA.SpreedMe.speakers.add(peer.id);
			} else if(label === 'stoppedSpeaking') {
				OCA.SpreedMe.speakers.remove(peer.id);
			}
		});

		OCA.SpreedMe.webrtc.on('videoAdded', function(video, peer) {
			console.log('video added', peer);
			var remotes = document.getElementById('videos');
			if (remotes) {
				// Indicator for username
				var userIndicator = document.createElement('div');
				userIndicator.className = 'nameIndicator';
				userIndicator.textContent = peer.nick;

				// Avatar for username
				var avatar = document.createElement('div');
				avatar.className = 'avatar';

				var avatarContainer = document.createElement('div');
				avatarContainer.className = 'avatar-container hidden';
				avatarContainer.appendChild(avatar);

				// Mute indicator
				var muteIndicator = document.createElement('div');
				muteIndicator.className = 'muteIndicator icon-sound-white hidden';
				muteIndicator.textContent = '';

				// Generic container
				var container = document.createElement('div');
				container.className = 'videoContainer';
				container.id = 'container_' + OCA.SpreedMe.webrtc.getDomId(peer);
				container.appendChild(video);
				container.appendChild(avatarContainer);
				container.appendChild(userIndicator);
				container.appendChild(muteIndicator);
				video.oncontextmenu = function() {
					return false;
				};

				// show the ice connection state
				if (peer && peer.pc) {
					peer.pc.on('iceConnectionStateChange', function () {
						switch (peer.pc.iceConnectionState) {
							case 'checking':
								console.log('Connecting to peer...');
								break;
							case 'connected':
							case 'completed': // on caller side
								console.log('Connection established.');
								break;
							case 'disconnected':
								// If the peer is still disconnected after 5 seconds
								// we close the video connection.
								setTimeout(function() {
									if(peer.pc.iceConnectionState === 'disconnected') {
										OCA.SpreedMe.webrtc.removePeers(peer.id);
									}
								}, 5000);
								console.log('Disconnected.');
								break;
							case 'failed':
								console.log('Connection failed.');
								break;
							case 'closed':
								console.log('Connection closed.');
								break;
						}
					});
				}

				$(container).prependTo($('#videos'));
			}

			var otherSpeakerPromoted = false;
			for (var key in spreedListofSpeakers) {
				if (spreedListofSpeakers.hasOwnProperty(key)) {
					otherSpeakerPromoted = true;
					break;
				}
			}
			if (!otherSpeakerPromoted) {
				OCA.SpreedMe.speakers.add(peer.id);
			}
		});

		OCA.SpreedMe.webrtc.on('speaking', function(){
			console.log('local speaking');
			OCA.SpreedMe.webrtc.sendDirectlyToAll('speaking');
		});
		OCA.SpreedMe.webrtc.on('stoppedSpeaking', function(){
			console.log('local stoppedSpeaking');
			OCA.SpreedMe.webrtc.sendDirectlyToAll('stoppedSpeaking');
		});

		// a peer was removed
		OCA.SpreedMe.webrtc.on('videoRemoved', function(video, peer) {
			// a removed peer can't speak anymore ;)
			OCA.SpreedMe.speakers.remove(peer);

			var remotes = document.getElementById('videos');
			var el = document.getElementById(peer ? 'container_' + OCA.SpreedMe.webrtc.getDomId(peer) : 'localScreenContainer');
			if (remotes && el) {
				remotes.removeChild(el);
			}
		});

		// Peer is muted
		OCA.SpreedMe.webrtc.on('mute', function(data) {
			var el = document.getElementById('container_' + OCA.SpreedMe.webrtc.getDomId({
					id: data.id,
					type: 'type',
					broadcaster: false
				}));
			var $el = $(el);

			if (data.name === 'video') {
				var avatar = $el.find('.avatar');
				avatar.avatar(spreedMappingTable[data.id], 256);

				var avatarContainer = $el.find('.avatar-container');
				avatarContainer.removeClass('hidden');
				avatarContainer.show();
				//$el.find('video').hide();
			} else {
				var muteIndicator = $el.find('.muteIndicator');
				muteIndicator.removeClass('hidden');
				muteIndicator.show();
			}
		});

		// Peer is umuted
		OCA.SpreedMe.webrtc.on('unmute', function(data) {
			var el = document.getElementById('container_' + OCA.SpreedMe.webrtc.getDomId({
					id: data.id,
					type: 'type',
					broadcaster: false
				}));
			var $el = $(el);

			if (data.name === 'video') {
				$el.find('.avatar-container').hide();
				//avaa$el.find('video').show();
			} else {
				$el.find('.muteIndicator').hide();
			}
		});

	}

	OCA.SpreedMe.initWebRTC = initWebRTC;

})(OCA, OC);
<commit_msg>clone name indicator<commit_after>// TODO(fancycode): Should load through AMD if possible.
/* global SimpleWebRTC, OC, OCA: false */

var webrtc;
var spreedMappingTable = [];

(function(OCA, OC) {
	'use strict';

	OCA.SpreedMe = OCA.SpreedMe || {};

	/**
	 * @private
	 */
	function openEventSource() {
		// Connect to the messages endpoint and pull for new messages
		var messageEventSource = new OC.EventSource(OC.generateUrl('/apps/spreed/messages'));
		var previousUsersInRoom = [];
		Array.prototype.diff = function(a) {
			return this.filter(function(i) {
				return a.indexOf(i) < 0;
			});
		};
		messageEventSource.listen('usersInRoom', function(users) {
			var currentUsersInRoom = [];
			users.forEach(function(user) {
				currentUsersInRoom.push(user['sessionId']);
				spreedMappingTable[user['sessionId']] = user['userId'];
			});

			var currentUsersNo = currentUsersInRoom.length;
			if(currentUsersNo === 0) {
				currentUsersNo = 1;
			}

			var appContentElement = $('#app-content'),
				participantsClass = 'participants-' + currentUsersNo;
			if (!appContentElement.hasClass(participantsClass)) {
				appContentElement.attr('class', '').addClass(participantsClass);
			}

			var disconnectedUsers = previousUsersInRoom.diff(currentUsersInRoom);
			disconnectedUsers.forEach(function(user) {
				console.log('XXX Remove peer', user);
				OCA.SpreedMe.webrtc.removePeers(user);
			});
			previousUsersInRoom = currentUsersInRoom;
		});

		messageEventSource.listen('message', function(message) {
			message = JSON.parse(message);
			var peers = self.webrtc.getPeers(message.from, message.roomType);
			var peer;

			if (message.type === 'offer') {
				if (peers.length) {
					peers.forEach(function(p) {
						if (p.sid === message.sid) {
							peer = p;
						}
					});
				}
				if (!peer) {
					peer = self.webrtc.createPeer({
						id: message.from,
						sid: message.sid,
						type: message.roomType,
						enableDataChannels: true,
						sharemyscreen: message.roomType === 'screen' && !message.broadcaster,
						broadcaster: message.roomType === 'screen' && !message.broadcaster ? self.connection.getSessionid() : null
					});
					OCA.SpreedMe.webrtc.emit('createdPeer', peer);
				}
				peer.handleMessage(message);
			} else if (peers.length) {
				peers.forEach(function(peer) {
					if (message.sid) {
						if (peer.sid === message.sid) {
							peer.handleMessage(message);
						}
					} else {
						peer.handleMessage(message);
					}
				});
			}
		});
		messageEventSource.listen('__internal__', function(data) {
			if (data === 'close') {
				console.log('signaling connection closed - will reopen');
				setTimeout(openEventSource, 0);
			}
		});
	}

	function initWebRTC() {
		'use strict';
		openEventSource();

		webrtc = new SimpleWebRTC({
			localVideoEl: 'localVideo',
			remoteVideosEl: '',
			autoRequestMedia: true,
			debug: false,
			media: {
				audio: true,
				video: {
					width: { max: 1280 },
					height: { max: 720 }
				}
			},
			autoAdjustMic: false,
			detectSpeakingEvents: true,
			connection: OCA.SpreedMe.XhrConnection,
			enableDataChannels: true,
			nick: OC.getCurrentUser()['displayName']
	});
		OCA.SpreedMe.webrtc = webrtc;

		var $appContent = $('#app-content');
		var spreedListofSpeakers = {};
		var latestSpeakerId = null;
		OCA.SpreedMe.speakers = {
			showStatus: function() {
				var data = [];
				for (var currentId in spreedListofSpeakers) {
					// skip loop if the property is from prototype
					if (!spreedListofSpeakers.hasOwnProperty(currentId)) {
						continue;
					}

					var currentTime = spreedListofSpeakers[currentId];
					var id = currentId.replace('\\', '');
					data.push([spreedMappingTable[id], id, currentTime]);
				}
				console.log('spreedListofSpeakers');
				console.table(data);
				console.log('spreedMappingTable');
				console.table(spreedMappingTable);
			},
			getContainerId: function(id) {
				var sanitizedId = id.replace(/[!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g, "\\$&");
				return '#container_' + sanitizedId + '_type_incoming';
			},
			switchVideoToId: function(id) {
				var videoSpeakingElement = $('#video-speaking');

				if (latestSpeakerId !== null) {
					console.log('promote: unpromote speaker "' + spreedMappingTable[latestSpeakerId] + '"');
					// move old video to new location
					var oldContainer = $(OCA.SpreedMe.speakers.getContainerId(latestSpeakerId));
					oldContainer.removeClass('speaking');
					oldContainer.parent().find('.videoContainer-dummy').remove();
				}

				// add new user to it
				var newContainer = $(OCA.SpreedMe.speakers.getContainerId(id));
				newContainer.addClass('speaking');
				newContainer.after(
					$('<div>')
						.addClass('videoContainer videoContainer-dummy')
						.append(newContainer.find('.nameIndicator').clone())
					);

				latestSpeakerId = id;
			},
			add: function(id) {
				if (!(typeof id === 'string' || id instanceof String)) {
					return;
				}

				var sanitizedId = OCA.SpreedMe.speakers.getContainerId(id);
				spreedListofSpeakers[sanitizedId] = (new Date()).getTime();

				if (latestSpeakerId === id) {
					console.log('promoting: latest speaker "' + spreedMappingTable[id] + '" is already promoted');
					return;
				}

				console.log('promoting: change promoted speaker to "' + spreedMappingTable[id] + '" after speaking');
				OCA.SpreedMe.speakers.switchVideoToId(id);
			},
			remove: function(id) {
				if (!(typeof id === 'string' || id instanceof String)) {
					return;
				}

				var sanitizedId = OCA.SpreedMe.speakers.getContainerId(id);
				spreedListofSpeakers[sanitizedId] = -1;

				if (latestSpeakerId !== id) {
					console.log('promoting: stopped speaker "' + spreedMappingTable[id] + '" is not promoted');
					return;
				}

				console.log('promoting: try to find better promoted speaker for "' + spreedMappingTable[id] + '"');

				var mostRecentTime = 0,
					mostRecentId = null;
				for (var currentId in spreedListofSpeakers) {
					// skip loop if the property is from prototype
					if (!spreedListofSpeakers.hasOwnProperty(currentId)) {
						continue;
					}

					// skip non-string ids
					if (!(typeof currentId === 'string' || currentId instanceof String))  continue;

					var currentTime = spreedListofSpeakers[currentId];
					if (currentTime > mostRecentTime) {
						mostRecentTime = currentTime;
						mostRecentId = currentId;
					}
				}

				if (mostRecentId !== null) {
					console.log('promoting: change promoted speaker from "' + spreedMappingTable[id] + '" to "' + spreedMappingTable[mostRecentId] + '" after speakingStopped');
					OCA.SpreedMe.speakers.switchVideoToId(mostRecentId);
				} else {
					console.log('promoting: no recent speaker to promote - keep "' + spreedMappingTable[id] + '"');
				}
			}
		};

		OCA.SpreedMe.webrtc.on('createdPeer', function (peer) {
			peer.pc.on('PeerConnectionTrace', function (event) {
				console.log('trace', event);
			});
		});

		OCA.SpreedMe.webrtc.on('localMediaError', function(error) {
			console.log('Access to microphone & camera failed', error);
			var message, messageAdditional;
			if (error.name === "NotAllowedError") {
				if (error.message && error.message.indexOf("Only secure origins") !== -1) {
					message = t('spreed', 'Access to microphone & camera is only possible with HTTPS');
					messageAdditional = t('spreed', 'Please adjust your configuration');
				} else {
					message = t('spreed', 'Access to microphone & camera was denied');
					$('#emptycontent p').hide();
				}
			} else {
				message = t('spreed', 'Error while accessing microphone & camera: {error}', {error: error.message || error.name});
				$('#emptycontent p').hide();
			}
			$('#emptycontent h2').text(message);
			$('#emptycontent p').text(messageAdditional);
		});

		OCA.SpreedMe.webrtc.on('joinedRoom', function(name) {
			$('#app-content').removeClass('icon-loading');
			$('.videoView').removeClass('hidden');
			OCA.SpreedMe.app.syncAndSetActiveRoom(name);
		});

		OCA.SpreedMe.webrtc.on('channelMessage', function (peer, label, data) {
			if(label === 'speaking') {
				OCA.SpreedMe.speakers.add(peer.id);
			} else if(label === 'stoppedSpeaking') {
				OCA.SpreedMe.speakers.remove(peer.id);
			}
		});

		OCA.SpreedMe.webrtc.on('videoAdded', function(video, peer) {
			console.log('video added', peer);
			var remotes = document.getElementById('videos');
			if (remotes) {
				// Indicator for username
				var userIndicator = document.createElement('div');
				userIndicator.className = 'nameIndicator';
				userIndicator.textContent = peer.nick;

				// Avatar for username
				var avatar = document.createElement('div');
				avatar.className = 'avatar';

				var avatarContainer = document.createElement('div');
				avatarContainer.className = 'avatar-container hidden';
				avatarContainer.appendChild(avatar);

				// Mute indicator
				var muteIndicator = document.createElement('div');
				muteIndicator.className = 'muteIndicator icon-sound-white hidden';
				muteIndicator.textContent = '';

				// Generic container
				var container = document.createElement('div');
				container.className = 'videoContainer';
				container.id = 'container_' + OCA.SpreedMe.webrtc.getDomId(peer);
				container.appendChild(video);
				container.appendChild(avatarContainer);
				container.appendChild(userIndicator);
				container.appendChild(muteIndicator);
				video.oncontextmenu = function() {
					return false;
				};

				// show the ice connection state
				if (peer && peer.pc) {
					peer.pc.on('iceConnectionStateChange', function () {
						switch (peer.pc.iceConnectionState) {
							case 'checking':
								console.log('Connecting to peer...');
								break;
							case 'connected':
							case 'completed': // on caller side
								console.log('Connection established.');
								break;
							case 'disconnected':
								// If the peer is still disconnected after 5 seconds
								// we close the video connection.
								setTimeout(function() {
									if(peer.pc.iceConnectionState === 'disconnected') {
										OCA.SpreedMe.webrtc.removePeers(peer.id);
									}
								}, 5000);
								console.log('Disconnected.');
								break;
							case 'failed':
								console.log('Connection failed.');
								break;
							case 'closed':
								console.log('Connection closed.');
								break;
						}
					});
				}

				$(container).prependTo($('#videos'));
			}

			var otherSpeakerPromoted = false;
			for (var key in spreedListofSpeakers) {
				if (spreedListofSpeakers.hasOwnProperty(key)) {
					otherSpeakerPromoted = true;
					break;
				}
			}
			if (!otherSpeakerPromoted) {
				OCA.SpreedMe.speakers.add(peer.id);
			}
		});

		OCA.SpreedMe.webrtc.on('speaking', function(){
			console.log('local speaking');
			OCA.SpreedMe.webrtc.sendDirectlyToAll('speaking');
		});
		OCA.SpreedMe.webrtc.on('stoppedSpeaking', function(){
			console.log('local stoppedSpeaking');
			OCA.SpreedMe.webrtc.sendDirectlyToAll('stoppedSpeaking');
		});

		// a peer was removed
		OCA.SpreedMe.webrtc.on('videoRemoved', function(video, peer) {
			// a removed peer can't speak anymore ;)
			OCA.SpreedMe.speakers.remove(peer);

			var remotes = document.getElementById('videos');
			var el = document.getElementById(peer ? 'container_' + OCA.SpreedMe.webrtc.getDomId(peer) : 'localScreenContainer');
			if (remotes && el) {
				remotes.removeChild(el);
			}
		});

		// Peer is muted
		OCA.SpreedMe.webrtc.on('mute', function(data) {
			var el = document.getElementById('container_' + OCA.SpreedMe.webrtc.getDomId({
					id: data.id,
					type: 'type',
					broadcaster: false
				}));
			var $el = $(el);

			if (data.name === 'video') {
				var avatar = $el.find('.avatar');
				avatar.avatar(spreedMappingTable[data.id], 256);

				var avatarContainer = $el.find('.avatar-container');
				avatarContainer.removeClass('hidden');
				avatarContainer.show();
				//$el.find('video').hide();
			} else {
				var muteIndicator = $el.find('.muteIndicator');
				muteIndicator.removeClass('hidden');
				muteIndicator.show();
			}
		});

		// Peer is umuted
		OCA.SpreedMe.webrtc.on('unmute', function(data) {
			var el = document.getElementById('container_' + OCA.SpreedMe.webrtc.getDomId({
					id: data.id,
					type: 'type',
					broadcaster: false
				}));
			var $el = $(el);

			if (data.name === 'video') {
				$el.find('.avatar-container').hide();
				//avaa$el.find('video').show();
			} else {
				$el.find('.muteIndicator').hide();
			}
		});

	}

	OCA.SpreedMe.initWebRTC = initWebRTC;

})(OCA, OC);
<|endoftext|>


<commit_before>/*!
 * wq.app 0.7.0-dev - map.js
 * Leaflet integration for app.js list & detail views
 * (c) 2013-2014, S. Andrew Sheppard
 * http://wq.io/license
 */

define(['leaflet', 'jquery', './app', './pages', './json', './spinner',
        './template', './console', 'es5-shim'],
function(L, $, app, pages, json, spin, tmpl, console) {

// module variable
var map = {};

// module configuration
map.config = {
    'maps': {}, // Auto-populated from app.config.pages where map == true
    'defaults': {
        'zoom': 0,
        'center': [0, 0],
        'autoZoom': {
            'wait': 0.5, // How long to wait before triggering autoZoom
            'sticky': true, // Start new maps in same location as old maps

            // Settings for fitBounds
            'maxZoom': 13,
            'animate': true
        },

        // Defaults to simplify creation of new icons of the same dimensions
        // as L.Icon.Default
        'icon': {
            'iconSize':    [25, 41],
            'iconAnchor':  [12, 41],
            'popupAnchor': [1, -34],
            'shadowSize':  [41, 41],
            'shadowUrl':  L.Icon.Default.imagePath + '/marker-shadow.png'
        }
    }
};

// References to generated map objects
map.maps = {};

// References to generated icons
map.icons = {
    'default': new L.Icon.Default()
};

// This should be called after app.init()
map.init = function(defaults) {
    // Auto-detect whether CRS-aware GeoJSON parser is available
    map.geoJson = L.Proj ? L.Proj.geoJson : L.geoJson;

    if (defaults)
        L.extend(map.config.defaults, defaults);

    // Define map configuration for all app pages with map=True
    for (var page in app.config.pages) {
        var pconf = L.extend({}, app.config.pages[page]);
        if (!pconf.map)
            continue;
        pconf.layers = [];
        map.config.maps[page] = pconf;

        // Register onshow events
        if (pconf.list) {
            pconf.autoLayers = true;
            _registerList(page);
            _registerDetail(page);
        } else {
            _registerOther(page);
        }
    }
};

// Register an onshow event for list views
function _registerList(page) {
    var mapconf = _getConf(page);
    var url = mapconf.url ? mapconf.url + '/' : '';
    pages.addRoute(url, 's', function() {
        map.createMap(page);
    });

    // Special handling for /[parent_list_url]/[parent_id]/[url]
    for (var ppage in app.getParents(page)) {
        var pconf = app.config.pages[ppage];
        var purl = pconf.url;
        if (url)
            purl += '/';
        purl += '<slug>/' + mapconf.url;
        pages.addRoute(purl, 's', goUrl);
        pages.addRoute(purl + '/', 's', goUrl);
    }

    function goUrl(match, ui, params) {
        // Override URL for this map's main layer to enable filter by parent
        var override = {};
        var url = match[0].substring(1).split("?")[0];
        if (params)
            url += ".geojson" + L.Util.getParamString(params);
        override[mapconf.name] = {'url': url};
        map.createMap(page, undefined, override);
    }
}

// Register an onshow event for item detail views
function _registerDetail(page) {
    var mapconf = _getConf(page);
    var url = mapconf.url ? mapconf.url + '/' : '';
    pages.addRoute(url + '<slug>', 's', function(match) {
        var itemid = match[1];
        if (itemid == 'new')
            return;
        map.createMap(page, itemid);
    });
}

// Register an onshow event for non-list single pages
function _registerOther(page) {
    var mapconf = _getConf(page);
    var url = mapconf.url;
    pages.addRoute(url, 's', function() {
        map.createMap(page);
    });
}

// Add a layer configuration (layerconf) to a map configuration
map.addLayerConf = function(page, layerconf) {
    var mapconf = _getConf(page);
    mapconf.layers.push(layerconf);
};

// Define an icon for use by list items displayed as points
map.createIcon = function(name, options) {
    options = L.extend({}, map.config.defaults.icon, options);
    map.icons[name] = L.icon(options);
};

// Load map configuration for the given page
map.getLayerConfs = function(page, itemid) {
    var mapconf = _getConf(page);
    var layers = mapconf.layers.slice();

    if (!mapconf.autoLayers)
        return layers;

    if (itemid) {
        // Automatically load geojson for the current item
        layers.push({
            'name': mapconf.name,
            'url': mapconf.url + '/' + itemid,
            'oneach': map.renderPopup(page)
        });
    } else {
        // Automatically load geojson for the entire list
        layers.push({
            'name': mapconf.name,
            'url': mapconf.url,
            'oneach': map.renderPopup(page),
            'cluster': true
        });
    }
    return layers;
};

// Internal layer loading function - override to customize
var _cache = {};
map.loadLayer = function(url, callback) {
    url = app.service + '/' + url;
    if (url.indexOf('.geojson') == -1)
        url += '.geojson';
    if (_cache[url]) {
        setTimeout(function() {
            callback(_cache[url]);
        }, 100);
        return;
    }
    spin.start();
    json.get(url, function(geojson) {
        spin.stop();
        _cache[url] = geojson;
        callback(geojson);
    });
};

// Default base maps - override to customize
map.createBaseMaps = function() {
    /* jshint maxlen: false */
    var mqcdn = "http://otile{s}.mqcdn.com/tiles/1.0.0/{type}/{z}/{x}/{y}.png";

    // Attribution (https://gist.github.com/mourner/1804938)
    var osmAttr = 'Map data © OpenStreetMap contributors, CC-BY-SA';
    var aerialAttr = 'Imagery © NASA/JPL-Caltech and U.S. Depart. of Agriculture, Farm Service Agency';
    var mqTilesAttr = 'Tiles © MapQuest ';

    return {
        "Street": L.tileLayer(mqcdn, {
            'subdomains': '1234',
            'type': 'map',
            'attribution': osmAttr + ', ' + mqTilesAttr
        }),
        "Aerial": L.tileLayer(mqcdn, {
            'subdomains': '1234',
            'type': 'sat',
            'attribution': aerialAttr + ', ' + mqTilesAttr
        })
    };
};

map.createLayerControl = function(basemaps, layers) {
    return L.control.layers(basemaps, layers);
};

// Default popup renderer for items - override to customize
// (assumes template called [page]_popup)
map.renderPopup = function(page) {
    return function(feat, layer) {
        var attrs = L.extend({'id': feat.id}, feat.properties);
        layer.bindPopup(
            tmpl.render(page + '_popup', attrs)
        );
    };
};

// Primary map routine
map.createMap = function(page, itemid, override) {
    var mapid, divid, mapconf, m, defaults,
        layerConfs, remaining, layers,
        basemaps, basemap, div;

    // Load configuration and div id
    mapconf = _getConf(page);
    defaults = map.config.defaults;

    if (mapconf.list && itemid)
        mapid = page + '-' + itemid;
    else
        mapid = page;

    if (mapconf.div)
        divid = mapconf.div;
    else
        divid = mapid + '-map';

    div = L.DomUtil.get(divid);
    if (!div) {
        // Skip map creation if the expected div doesn't exist
        console.log(divid + ' not found; skipping map creation');
        return;
    }

    // Make sure leaflet hasn't already been initialized for this map
    if (div._leaflet) {
        // This is probably an onshow event for a page that was rendered
        // and then went offscreen before coming back; refresh layout.
        m = map.maps[mapid];
        m.invalidateSize();
        if (defaults.autoZoom.sticky) {
            m.setView(defaults.center, defaults.zoom);
        }
        return;
    }

    // Create map, set default zoom and basemap
    m = map.maps[mapid] = L.map(divid);
    m.setView(defaults.center, defaults.zoom);
    basemaps = map.createBaseMaps();
    basemap = Object.keys(basemaps)[0];
    basemaps[basemap].addTo(m);

    // Load layerconfs and add empty layer groups to map
    layers = {};
    layerConfs = map.getLayerConfs(page, itemid);
    remaining = layerConfs.length;
    layerConfs.forEach(function(layerconf, i) {
        layerconf = L.extend({}, layerconf,
                             override && override[layerconf.name]);
        if (layerconf.cluster && L.MarkerClusterGroup) {
            var options = {};
            if (layerconf.clusterIcon)
                options.iconCreateFunction = layerconf.clusterIcon;
            layerconf.layer = new L.MarkerClusterGroup(options).addTo(m);
        } else {
            layerconf.layer = L.featureGroup().addTo(m);
        }
        loadLayer(layerconf);
        layers[layerconf.name] = layerconf.layer;
        layerConfs[i] = layerconf;
    });

    map.createLayerControl(basemaps, layers).addTo(m);

    // Async-load geojson for layers and add to layergroups
    function loadLayer(layerconf) {
        map.loadLayer(layerconf.url, function(geojson) {
            var options = {};
            if (layerconf.oneach)
                options.onEachFeature = layerconf.oneach;
            if (layerconf.icon)
                options.pointToLayer = _makeMarker(layerconf.icon);
            if (layerconf.style)
                options.style = layerconf.style;
            map.geoJson(geojson, options).addTo(layerconf.layer);
            remaining--;
            if (!remaining)
                autoZoom();
        });
    }

    function autoZoom() {
        if (mapconf.autoZoom !== undefined && !mapconf.autoZoom)
            return;
        if (!map.config.defaults.autoZoom)
            return;
        var bounds = layerConfs[0].layer.getBounds();
        if (layerConfs.length > 1)
            layerConfs.slice(1).forEach(function(layerconf) {
                bounds.extend(layerconf.layer.getBounds());
            });
        setTimeout(function() {
            m.fitBounds(bounds, map.config.defaults.autoZoom);
        }, map.config.defaults.autoZoom.wait * 1000);
    }

    if (map.config.defaults.autoZoom.sticky) {
        m.on('moveend', function() {
            map.config.defaults.zoom = m.getZoom();
            map.config.defaults.center = m.getCenter();
        });
    }

    // Ensure valid layout on screen
    setTimeout(function() {
        m.invalidateSize();
    }, 100);

    // Try to ensure no Leaflet widgets are enhanced by jQuery Mobile
    var $controls = $(div).find(".leaflet-control-container");
    $controls.find("input").attr("data-role", "none");

    if (mapconf.onshow)
        mapconf.onshow(m);

    return m;
};

// Internal function for creating markers (used with layerconf.icon)
function _makeMarker(icon) {
    return function pointToLayer(geojson, latlng) {
        // Define icon as a function to customize per-feature
        var key;
        if (typeof icon == 'function')
            key = icon(geojson.properties);
        else
            key = icon;
        return L.marker(latlng, {'icon': map.icons[key]});
    };
}

// Load map configuration for a given page
function _getConf(page) {
    var mapconf = map.config.maps[page];
    if (!mapconf)
        throw 'Configuration for "' + page + '" not found!';
    return mapconf;
}

return map;

});
<commit_msg>owl support for map<commit_after>/*!
 * wq.app 0.7.0-dev - map.js
 * Leaflet integration for app.js list & detail views
 * (c) 2013-2014, S. Andrew Sheppard
 * http://wq.io/license
 */

define(['leaflet', 'jquery', './app', './pages', './json', './spinner',
        './template', './console', 'es5-shim'],
function(L, $, app, pages, json, spin, tmpl, console) {

/* global require */

// module variable
var map = {};

// module configuration
map.config = {
    'maps': {}, // Auto-populated from app.config.pages where map == true
    'defaults': {
        'zoom': 0,
        'center': [0, 0],
        'autoZoom': {
            'wait': 0.5, // How long to wait before triggering autoZoom
            'sticky': true, // Start new maps in same location as old maps

            // Settings for fitBounds
            'maxZoom': 13,
            'animate': true
        },

        // Defaults to simplify creation of new icons of the same dimensions
        // as L.Icon.Default
        'icon': {
            'iconSize':    [25, 41],
            'iconAnchor':  [12, 41],
            'popupAnchor': [1, -34],
            'shadowSize':  [41, 41],
            'shadowUrl':  L.Icon.Default.imagePath + '/marker-shadow.png'
        },

        'owl': false
    }
};

// References to generated map objects
map.maps = {};

// References to generated icons
map.icons = {
    'default': new L.Icon.Default()
};

// This should be called after app.init()
map.init = function(defaults) {
    // Auto-detect whether CRS-aware GeoJSON parser is available
    map.geoJson = L.Proj ? L.Proj.geoJson : L.geoJson;

    if (defaults)
        L.extend(map.config.defaults, defaults);

    // Define map configuration for all app pages with map=True
    for (var page in app.config.pages) {
        var pconf = L.extend({}, app.config.pages[page]);
        if (!pconf.map)
            continue;
        pconf.layers = [];
        map.config.maps[page] = pconf;

        // Register onshow events
        if (pconf.list) {
            pconf.autoLayers = true;
            _registerList(page);
            _registerDetail(page);
        } else {
            _registerOther(page);
        }
    }
};

// Register an onshow event for list views
function _registerList(page) {
    var mapconf = _getConf(page);
    var url = mapconf.url ? mapconf.url + '/' : '';
    pages.addRoute(url, 's', function() {
        map.createMap(page);
    });

    // Special handling for /[parent_list_url]/[parent_id]/[url]
    for (var ppage in app.getParents(page)) {
        var pconf = app.config.pages[ppage];
        var purl = pconf.url;
        if (url)
            purl += '/';
        purl += '<slug>/' + mapconf.url;
        pages.addRoute(purl, 's', goUrl);
        pages.addRoute(purl + '/', 's', goUrl);
    }

    function goUrl(match, ui, params) {
        // Override URL for this map's main layer to enable filter by parent
        var override = {};
        var url = match[0].substring(1).split("?")[0];
        if (params)
            url += ".geojson" + L.Util.getParamString(params);
        override[mapconf.name] = {'url': url};
        map.createMap(page, undefined, override);
    }
}

// Register an onshow event for item detail views
function _registerDetail(page) {
    var mapconf = _getConf(page);
    var url = mapconf.url ? mapconf.url + '/' : '';
    pages.addRoute(url + '<slug>', 's', function(match) {
        var itemid = match[1];
        if (itemid == 'new')
            return;
        map.createMap(page, itemid);
    });
}

// Register an onshow event for non-list single pages
function _registerOther(page) {
    var mapconf = _getConf(page);
    var url = mapconf.url;
    pages.addRoute(url, 's', function() {
        map.createMap(page);
    });
}

// Add a layer configuration (layerconf) to a map configuration
map.addLayerConf = function(page, layerconf) {
    var mapconf = _getConf(page);
    mapconf.layers.push(layerconf);
};

// Define an icon for use by list items displayed as points
map.createIcon = function(name, options) {
    options = L.extend({}, map.config.defaults.icon, options);
    map.icons[name] = L.icon(options);
};

// Load map configuration for the given page
map.getLayerConfs = function(page, itemid) {
    var mapconf = _getConf(page);
    var layers = mapconf.layers.slice();

    if (!mapconf.autoLayers)
        return layers;

    if (itemid) {
        // Automatically load geojson for the current item
        layers.push({
            'name': mapconf.name,
            'url': mapconf.url + '/' + itemid,
            'oneach': map.renderPopup(page)
        });
    } else {
        // Automatically load geojson for the entire list
        layers.push({
            'name': mapconf.name,
            'url': mapconf.url,
            'oneach': map.renderPopup(page),
            'cluster': true
        });
    }
    return layers;
};

// Internal layer loading function - override to customize
var _cache = {};
map.loadLayer = function(url, callback) {
    url = app.service + '/' + url;
    if (url.indexOf('.geojson') == -1)
        url += '.geojson';
    if (_cache[url]) {
        setTimeout(function() {
            callback(_cache[url]);
        }, 100);
        return;
    }
    spin.start();
    json.get(url, function(geojson) {
        spin.stop();
        _cache[url] = geojson;
        callback(geojson);
    });
};

// Default base maps - override to customize
map.createBaseMaps = function() {
    /* jshint maxlen: false */
    var mqcdn = "http://otile{s}.mqcdn.com/tiles/1.0.0/{type}/{z}/{x}/{y}.png";

    // Attribution (https://gist.github.com/mourner/1804938)
    var osmAttr = 'Map data © OpenStreetMap contributors, CC-BY-SA';
    var aerialAttr = 'Imagery © NASA/JPL-Caltech and U.S. Depart. of Agriculture, Farm Service Agency';
    var mqTilesAttr = 'Tiles © MapQuest ';

    return {
        "Street": L.tileLayer(mqcdn, {
            'subdomains': '1234',
            'type': 'map',
            'attribution': osmAttr + ', ' + mqTilesAttr
        }),
        "Aerial": L.tileLayer(mqcdn, {
            'subdomains': '1234',
            'type': 'sat',
            'attribution': aerialAttr + ', ' + mqTilesAttr
        })
    };
};

map.createLayerControl = function(basemaps, layers) {
    return L.control.layers(basemaps, layers);
};

// Default popup renderer for items - override to customize
// (assumes template called [page]_popup)
map.renderPopup = function(page) {
    var owl = map.config.defaults.owl && require('wq/owl');
    return function(feat, layer) {
        var attrs = L.extend({'id': feat.id}, feat.properties);
        layer.bindPopup(
            tmpl.render(page + '_popup', attrs)
        );
        if (owl) {
            layer.on('click', function() {
                owl('map:layerclick', {'page': page, 'id': feat.id});
            });
        }
    };
};

// Primary map routine
map.createMap = function(page, itemid, override) {
    var mapid, divid, mapconf, m, defaults,
        layerConfs, remaining, layers,
        basemaps, basemap, div, owl;

    // Load configuration and div id
    mapconf = _getConf(page);
    defaults = map.config.defaults;
    // If defaults.owl, assume wq/owl has been async-loaded already
    owl = defaults.owl && require('wq/owl');

    if (mapconf.list && itemid)
        mapid = page + '-' + itemid;
    else
        mapid = page;

    if (mapconf.div)
        divid = mapconf.div;
    else
        divid = mapid + '-map';

    div = L.DomUtil.get(divid);
    if (!div) {
        // Skip map creation if the expected div doesn't exist
        console.log(divid + ' not found; skipping map creation');
        return;
    }

    // Make sure leaflet hasn't already been initialized for this map
    if (div._leaflet) {
        // This is probably an onshow event for a page that was rendered
        // and then went offscreen before coming back; refresh layout.
        m = map.maps[mapid];
        m.invalidateSize();
        if (defaults.autoZoom.sticky) {
            m.setView(defaults.center, defaults.zoom);
        }
        return;
    }

    // Create map, set default zoom and basemap
    m = map.maps[mapid] = L.map(divid);
    m.setView(defaults.center, defaults.zoom);
    basemaps = map.createBaseMaps();
    basemap = Object.keys(basemaps)[0];
    basemaps[basemap].addTo(m);

    // Load layerconfs and add empty layer groups to map
    layers = {};
    layerConfs = map.getLayerConfs(page, itemid);
    remaining = layerConfs.length;
    layerConfs.forEach(function(layerconf, i) {
        layerconf = L.extend({}, layerconf,
                             override && override[layerconf.name]);
        if (layerconf.cluster && L.MarkerClusterGroup) {
            var options = {};
            if (layerconf.clusterIcon)
                options.iconCreateFunction = layerconf.clusterIcon;
            layerconf.layer = new L.MarkerClusterGroup(options).addTo(m);
        } else {
            layerconf.layer = L.featureGroup().addTo(m);
        }
        loadLayer(layerconf);
        layers[layerconf.name] = layerconf.layer;
        layerConfs[i] = layerconf;
    });

    map.createLayerControl(basemaps, layers).addTo(m);

    // Async-load geojson for layers and add to layergroups
    function loadLayer(layerconf) {
        map.loadLayer(layerconf.url, function(geojson) {
            var options = {};
            if (layerconf.oneach)
                options.onEachFeature = layerconf.oneach;
            if (layerconf.icon)
                options.pointToLayer = _makeMarker(layerconf.icon);
            if (layerconf.style)
                options.style = layerconf.style;
            map.geoJson(geojson, options).addTo(layerconf.layer);
            remaining--;
            if (!remaining)
                autoZoom();
        });
    }

    function autoZoom() {
        if (mapconf.autoZoom !== undefined && !mapconf.autoZoom)
            return;
        if (!map.config.defaults.autoZoom)
            return;
        var bounds = layerConfs[0].layer.getBounds();
        if (layerConfs.length > 1)
            layerConfs.slice(1).forEach(function(layerconf) {
                bounds.extend(layerconf.layer.getBounds());
            });
        setTimeout(function() {
            m.fitBounds(bounds, map.config.defaults.autoZoom);
        }, map.config.defaults.autoZoom.wait * 1000);
    }

    if (map.config.defaults.autoZoom.sticky) {
        m.on('moveend', function() {
            map.config.defaults.zoom = m.getZoom();
            map.config.defaults.center = m.getCenter();
        });
    }
    if (owl) {
        m.on('moveend', function() {
            owl('map:moveend', {
                'zoom': m.getZoom(),
                'center': m.getCenter(),
                'bounds': m.getBounds()
            });
        });
        [
            'baselayerchange',
            'overlayadd',
            'overlayremove'
        ].forEach(_layerEvent);
    }
    function _layerEvent(name) {
        m.on(name, function(evt) {
            owl('map:' + name, {'layer': evt.name});
        });
    }

    // Ensure valid layout on screen
    setTimeout(function() {
        m.invalidateSize();
    }, 100);

    // Try to ensure no Leaflet widgets are enhanced by jQuery Mobile
    var $controls = $(div).find(".leaflet-control-container");
    $controls.find("input").attr("data-role", "none");

    if (mapconf.onshow)
        mapconf.onshow(m);

    return m;
};

// Internal function for creating markers (used with layerconf.icon)
function _makeMarker(icon) {
    return function pointToLayer(geojson, latlng) {
        // Define icon as a function to customize per-feature
        var key;
        if (typeof icon == 'function')
            key = icon(geojson.properties);
        else
            key = icon;
        return L.marker(latlng, {'icon': map.icons[key]});
    };
}

// Load map configuration for a given page
function _getConf(page) {
    var mapconf = map.config.maps[page];
    if (!mapconf)
        throw 'Configuration for "' + page + '" not found!';
    return mapconf;
}

return map;

});
<|endoftext|>


<commit_before>//BEGIN FluidDB REST LIB

fluidDB = new Object();

fluidDB.instance = {
    main : "http://fluiddb.fluidinfo.com/",
    sandbox : "http://sandbox.fluidinfo.com/"
}

fluidDB.choose = function(type){
  if(type === "main" || type === "sandbox"){
    fluidDB.baseURL = fluidDB.instance[type];
  }
}

fluidDB.choose('main'); // main instance as default

fluidDB.config = function(options) {

  // authentication credentials
  if((options.username != undefined) && (options.password != undefined)){
    fluidDB.authenticate = true;
    fluidDB.username     = options.username;
    fluidDB.password     = options.password;
    fluidDB.base64string = Base64.encode(options.username + ":" + options.password);
  }

  fluidDB.choose(options.instance);

}

fluidDB.ajax = function(options){
  if((options.username != undefined) && (options.password != undefined)){
    // we can override the authentication defaults
    var authenticate = true;
    var base64string = Base64.encode(username + ":" + password);
  }else if(fluidDB.authenticate){
    // there are no credential passed as arguments, but maybe there're in the configuration
    var authenticate = true;
    var base64string = fluidDB.base64string;
  }

  options.url  = fluidDB.baseURL+options.url;
  options.async_req    = options.async_req || true;
  options.content_type = options.content_type || "application/json";
  options.opaque_value = options.opaque_value || false;
  options.contentType  = options.content_type;
  options.beforeSend   =  function(xhrObj){
                            if(authenticate){
                                xhrObj.setRequestHeader("Authorization","Basic "+ base64string);
                            };
                            xhrObj.setRequestHeader("Content-Type", options.content_type);
                          };
  options.processData  = false;
  options.data  = options.payload;

  $.ajax(options);
}

fluidDB.ajax = function(type, url, payload, callback, async_req, username, password, content_type){
    if((username != undefined) && (password != undefined)){
      var authenticate = true;
    }

    if(async_req == undefined){
      async_req = true;
    }
    if(content_type == undefined){
      content_type = "application/json";
    }
    $.ajax({
          async: async_req,
          beforeSend: function(xhrObj){
              if(authenticate){
                  var base64string = username + ":" + password;
                  xhrObj.setRequestHeader("Authorization","Basic "+  Base64.encode(base64string));
              };
              xhrObj.setRequestHeader("Content-Type",content_type);
          },
          contentType: content_type,
          type: type,
          url: url,
          data: payload,
          processData: false,
          success: callback
    });
}

fluidDB.get = function(options){
  options.type = "GET";
  options.payload = null;

  fluidDB.ajax(options);
}

fluidDB.post = function(options){
  options.type = "POST";

  fluidDB.ajax(options);
}

fluidDB.put = function(options){
  options.type = "PUT";

  if(options.opaque){
    options.content_type = "application/vnd.fluiddb.value+json";
  }

  fluidDB.ajax(options);
}

fluidDB.delete = function(options){
  options.type = "DELETE";
  options.payload = null;

  fluidDB.ajax(options);
}

fluidDB.head = function(options){
  options.type = "HEAD";
  options.payload = null;

  fluidDB.ajax(options);
}

//END FluidDB REST LIB

//BEGIN Base64 LIB
/* Taken from http://www.webtoolkit.info/javascript-base64.html
*  eventually is going to be moved outside this file
*/

var Base64 = {

	// private property
	_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

	// public method for encoding
	encode : function (input) {
		var output = "";
		var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
		var i = 0;

		input = Base64._utf8_encode(input);

		while (i < input.length) {

			chr1 = input.charCodeAt(i++);
			chr2 = input.charCodeAt(i++);
			chr3 = input.charCodeAt(i++);

			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;

			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(chr3)) {
				enc4 = 64;
			}

			output = output +
			this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
			this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

		}

		return output;
	},

	// public method for decoding
	decode : function (input) {
		var output = "";
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;

		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

		while (i < input.length) {

			enc1 = this._keyStr.indexOf(input.charAt(i++));
			enc2 = this._keyStr.indexOf(input.charAt(i++));
			enc3 = this._keyStr.indexOf(input.charAt(i++));
			enc4 = this._keyStr.indexOf(input.charAt(i++));

			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;

			output = output + String.fromCharCode(chr1);

			if (enc3 != 64) {
				output = output + String.fromCharCode(chr2);
			}
			if (enc4 != 64) {
				output = output + String.fromCharCode(chr3);
			}

		}

		output = Base64._utf8_decode(output);

		return output;

	},

	// private method for UTF-8 encoding
	_utf8_encode : function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";

		for (var n = 0; n < string.length; n++) {

			var c = string.charCodeAt(n);

			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}

		}

		return utftext;
	},

	// private method for UTF-8 decoding
	_utf8_decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;

		while ( i < utftext.length ) {

			c = utftext.charCodeAt(i);

			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}

		}

		return string;
	}

}

//END Base64 LIB
<commit_msg>adding possibility to directly pass authentication token (to make @ntoll happy)<commit_after>//BEGIN FluidDB REST LIB

fluidDB = new Object();

fluidDB.instance = {
    main : "http://fluiddb.fluidinfo.com/",
    sandbox : "http://sandbox.fluidinfo.com/"
}

fluidDB.choose = function(type){
  if(type === "main" || type === "sandbox"){
    fluidDB.baseURL = fluidDB.instance[type];
  }
}

fluidDB.choose('main'); // main instance as default

fluidDB.config = function(options) {

  // authentication credentials
  if((options.username != undefined) && (options.password != undefined)){
    fluidDB.authenticate = true;
    fluidDB.username     = options.username;
    fluidDB.password     = options.password;
    fluidDB.base64string = Base64.encode(options.username + ":" + options.password);
  }else if(options.auth_token){
    fluidDB.authenticate = true;
    fluidDB.base64string = options.auth_token;
  }

  fluidDB.choose(options.instance);

}

fluidDB.ajax = function(options){
  if((options.username != undefined) && (options.password != undefined)){
    // we can override the authentication defaults
    var authenticate = true;
    var base64string = Base64.encode(options.username + ":" + options.password);
  }else if(options.auth_token){
    var authenticate = true;
    var base64string = options.auth_token;
  }
  }else if(fluidDB.authenticate){
    // there are no credential passed as arguments, but maybe there're in the configuration
    var authenticate = true;
    var base64string = fluidDB.base64string;
  }

  options.url  = fluidDB.baseURL+options.url;
  options.async_req    = options.async_req || true;
  options.content_type = options.content_type || "application/json";
  options.opaque_value = options.opaque_value || false;
  options.contentType  = options.content_type;
  options.beforeSend   =  function(xhrObj){
                            if(authenticate){
                                xhrObj.setRequestHeader("Authorization","Basic "+ base64string);
                            };
                            xhrObj.setRequestHeader("Content-Type", options.content_type);
                          };
  options.processData  = false;
  options.data  = options.payload;

  $.ajax(options);
}

fluidDB.ajax = function(type, url, payload, callback, async_req, username, password, content_type){
    if((username != undefined) && (password != undefined)){
      var authenticate = true;
    }

    if(async_req == undefined){
      async_req = true;
    }
    if(content_type == undefined){
      content_type = "application/json";
    }
    $.ajax({
          async: async_req,
          beforeSend: function(xhrObj){
              if(authenticate){
                  var base64string = username + ":" + password;
                  xhrObj.setRequestHeader("Authorization","Basic "+  Base64.encode(base64string));
              };
              xhrObj.setRequestHeader("Content-Type",content_type);
          },
          contentType: content_type,
          type: type,
          url: url,
          data: payload,
          processData: false,
          success: callback
    });
}

fluidDB.get = function(options){
  options.type = "GET";
  options.payload = null;

  fluidDB.ajax(options);
}

fluidDB.post = function(options){
  options.type = "POST";

  fluidDB.ajax(options);
}

fluidDB.put = function(options){
  options.type = "PUT";

  if(options.opaque){
    options.content_type = "application/vnd.fluiddb.value+json";
  }

  fluidDB.ajax(options);
}

fluidDB.delete = function(options){
  options.type = "DELETE";
  options.payload = null;

  fluidDB.ajax(options);
}

fluidDB.head = function(options){
  options.type = "HEAD";
  options.payload = null;

  fluidDB.ajax(options);
}

//END FluidDB REST LIB

//BEGIN Base64 LIB
/* Taken from http://www.webtoolkit.info/javascript-base64.html
*  eventually is going to be moved outside this file
*/

var Base64 = {

	// private property
	_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

	// public method for encoding
	encode : function (input) {
		var output = "";
		var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
		var i = 0;

		input = Base64._utf8_encode(input);

		while (i < input.length) {

			chr1 = input.charCodeAt(i++);
			chr2 = input.charCodeAt(i++);
			chr3 = input.charCodeAt(i++);

			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;

			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(chr3)) {
				enc4 = 64;
			}

			output = output +
			this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
			this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

		}

		return output;
	},

	// public method for decoding
	decode : function (input) {
		var output = "";
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;

		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

		while (i < input.length) {

			enc1 = this._keyStr.indexOf(input.charAt(i++));
			enc2 = this._keyStr.indexOf(input.charAt(i++));
			enc3 = this._keyStr.indexOf(input.charAt(i++));
			enc4 = this._keyStr.indexOf(input.charAt(i++));

			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;

			output = output + String.fromCharCode(chr1);

			if (enc3 != 64) {
				output = output + String.fromCharCode(chr2);
			}
			if (enc4 != 64) {
				output = output + String.fromCharCode(chr3);
			}

		}

		output = Base64._utf8_decode(output);

		return output;

	},

	// private method for UTF-8 encoding
	_utf8_encode : function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";

		for (var n = 0; n < string.length; n++) {

			var c = string.charCodeAt(n);

			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}

		}

		return utftext;
	},

	// private method for UTF-8 decoding
	_utf8_decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;

		while ( i < utftext.length ) {

			c = utftext.charCodeAt(i);

			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}

		}

		return string;
	}

}

//END Base64 LIB
<|endoftext|>


<commit_before>"use strict";

const defs    = require('./defs.js');
const CT      = defs.constant_types;

const LUAC_DATA    = "\x19\x93\r\n\x1a\n";
const LUAC_INT     = 0x5678;
const LUAC_NUM     = 370.5;
const LUAC_VERSION = Number.parseInt(defs.LUA_VERSION_MAJOR) * 16 + Number.parseInt(defs.LUA_VERSION_MINOR);
const LUAC_FORMAT  = 0;   /* this is the official format */

class DumpState {
    constructor() {
        this.L = null;
        this.write = null;
        this.data = null;
        this.strip = NaN;
        this.status = NaN;
    }
}

const DumpBlock = function(b, size, D) {
    if (D.status === 0 && size > 0)
        D.status = D.writer(D.L, b, size, D.data);
};

const DumpLiteral = function(s, D) {
    s = defs.to_luastring(s);
    DumpBlock(s, s.length, D);
};

const DumpByte = function(y, D) {
    DumpBlock([y], 1, D);
};

const DumpInt = function(x, D) {
    let dv = new DataView(new ArrayBuffer(4));
    dv.setInt32(0, x, true);
    let t = [];
    for (let i = 0; i < 4; i++)
        t.push(dv.getUint8(i, true));

    DumpBlock(t, 4, D);
};

const DumpInteger = function(x, D) {
    let dv = new DataView(new ArrayBuffer(4));
    dv.setInt32(0, x, true);
    let t = [];
    for (let i = 0; i < 4; i++)
        t.push(dv.getUint8(i, true));
    DumpBlock(t, 4, D);
};

const DumpNumber = function(x, D) {
    let dv = new DataView(new ArrayBuffer(8));
    dv.setFloat64(0, x, true);
    let t = [];
    for (let i = 0; i < 8; i++)
        t.push(dv.getUint8(i, true));

    DumpBlock(t, 8, D);
};

const DumpString = function(s, D) {
    if (s === null)
        DumpByte(0, D);
    else {
        let size = s.tsslen() + 1;
        let str = s.getstr();
        if (size < 0xFF)
            DumpByte(size, D);
        else {
            DumpByte(0xFF, D);
            DumpInteger(size, D);
        }
        DumpBlock(str, size - 1, D);  /* no need to save '\0' */
    }
};

const DumpCode = function(f, D) {
    let s = f.code.map(e => e.code);
    DumpInt(s.length, D);

    for (let i = 0; i < s.length; i++)
        DumpInt(s[i], D);
};

const DumpConstants = function(f, D) {
    let n = f.k.length;
    DumpInt(n, D);
    for (let i = 0; i < n; i++) {
        let o = f.k[i];
        DumpByte(o.ttype(), D);
        switch (o.ttype()) {
            case CT.LUA_TNIL:
                break;
            case CT.LUA_TBOOLEAN:
                DumpByte(o.value ? 1 : 0, D);
                break;
            case CT.LUA_TNUMFLT:
                DumpNumber(o.value, D);
                break;
            case CT.LUA_TNUMINT:
                DumpInteger(o.value, D);
                break;
            case CT.LUA_TSHRSTR:
            case CT.LUA_TLNGSTR:
                DumpString(o.tsvalue(), D);
                break;
        }
    }
};

const DumpProtos = function(f, D) {
    let n = f.p.length;
    DumpInt(n, D);
    for (let i = 0; i < n; i++)
        DumpFunction(f.p[i], f.source, D);
};

const DumpUpvalues = function(f, D) {
    let n = f.upvalues.length;
    DumpInt(n, D);
    for (let i = 0; i < n; i++) {
        DumpByte(f.upvalues[i].instack ? 1 : 0, D);
        DumpByte(f.upvalues[i].idx, D);
    }
};

const DumpDebug = function(f, D) {
    let n = D.strip ? 0 : f.lineinfo.length;
    DumpInt(n, D);
    for (let i = 0; i < n; i++)
        DumpInt(f.lineinfo[i], D);
    n = D.strip ? 0 : f.locvars.length;
    DumpInt(n, D);
    for (let i = 0; i < n; i++) {
        DumpString(f.locvars[i].varname, D);
        DumpInt(f.locvars[i].startpc, D);
        DumpInt(f.locvars[i].endpc, D);
    }
    n = D.strip ? 0 : f.upvalues.length;
    DumpInt(n, D);
    for (let i = 0; i < n; i++)
        DumpString(f.upvalues[i].name, D);
};

const DumpFunction = function(f, psource, D) {
    if (D.strip || f.source === psource)
        DumpString(null, D);  /* no debug info or same source as its parent */
    else
        DumpString(f.source, D);
    DumpInt(f.linedefined, D);
    DumpInt(f.lastlinedefined, D);
    DumpByte(f.numparams, D);
    DumpByte(f.is_vararg?1:0, D);
    DumpByte(f.maxstacksize, D);
    DumpCode(f, D);
    DumpConstants(f, D);
    DumpUpvalues(f, D);
    DumpProtos(f, D);
    DumpDebug(f, D);
};

const DumpHeader = function(D) {
    DumpLiteral(defs.LUA_SIGNATURE, D);
    DumpByte(LUAC_VERSION, D);
    DumpByte(LUAC_FORMAT, D);
    let cdata = LUAC_DATA.split('').map(e => e.charCodeAt(0));
    DumpBlock(cdata, cdata.length, D);
    DumpByte(4, D); // intSize
    DumpByte(4, D); // size_tSize
    DumpByte(4, D); // instructionSize
    DumpByte(4, D); // integerSize
    DumpByte(8, D); // numberSize
    DumpInteger(LUAC_INT, D);
    DumpNumber(LUAC_NUM, D);
};

/*
** dump Lua function as precompiled chunk
*/
const luaU_dump = function(L, f, w, data, strip) {
    let D = new DumpState();
    D.L = L;
    D.writer = w;
    D.data = data;
    D.strip = strip;
    D.status = 0;
    DumpHeader(D);
    DumpByte(f.upvalues.length, D);
    DumpFunction(f, null, D);
    return D.status;
};

module.exports.luaU_dump = luaU_dump;
<commit_msg>src/ldump.js: Keep LUAC_DATA in array form<commit_after>"use strict";

const defs    = require('./defs.js');
const CT      = defs.constant_types;

const LUAC_DATA    = [25, 147, 13, 10, 26, 10];
const LUAC_INT     = 0x5678;
const LUAC_NUM     = 370.5;
const LUAC_VERSION = Number.parseInt(defs.LUA_VERSION_MAJOR) * 16 + Number.parseInt(defs.LUA_VERSION_MINOR);
const LUAC_FORMAT  = 0;   /* this is the official format */

class DumpState {
    constructor() {
        this.L = null;
        this.write = null;
        this.data = null;
        this.strip = NaN;
        this.status = NaN;
    }
}

const DumpBlock = function(b, size, D) {
    if (D.status === 0 && size > 0)
        D.status = D.writer(D.L, b, size, D.data);
};

const DumpLiteral = function(s, D) {
    s = defs.to_luastring(s);
    DumpBlock(s, s.length, D);
};

const DumpByte = function(y, D) {
    DumpBlock([y], 1, D);
};

const DumpInt = function(x, D) {
    let dv = new DataView(new ArrayBuffer(4));
    dv.setInt32(0, x, true);
    let t = [];
    for (let i = 0; i < 4; i++)
        t.push(dv.getUint8(i, true));

    DumpBlock(t, 4, D);
};

const DumpInteger = function(x, D) {
    let dv = new DataView(new ArrayBuffer(4));
    dv.setInt32(0, x, true);
    let t = [];
    for (let i = 0; i < 4; i++)
        t.push(dv.getUint8(i, true));
    DumpBlock(t, 4, D);
};

const DumpNumber = function(x, D) {
    let dv = new DataView(new ArrayBuffer(8));
    dv.setFloat64(0, x, true);
    let t = [];
    for (let i = 0; i < 8; i++)
        t.push(dv.getUint8(i, true));

    DumpBlock(t, 8, D);
};

const DumpString = function(s, D) {
    if (s === null)
        DumpByte(0, D);
    else {
        let size = s.tsslen() + 1;
        let str = s.getstr();
        if (size < 0xFF)
            DumpByte(size, D);
        else {
            DumpByte(0xFF, D);
            DumpInteger(size, D);
        }
        DumpBlock(str, size - 1, D);  /* no need to save '\0' */
    }
};

const DumpCode = function(f, D) {
    let s = f.code.map(e => e.code);
    DumpInt(s.length, D);

    for (let i = 0; i < s.length; i++)
        DumpInt(s[i], D);
};

const DumpConstants = function(f, D) {
    let n = f.k.length;
    DumpInt(n, D);
    for (let i = 0; i < n; i++) {
        let o = f.k[i];
        DumpByte(o.ttype(), D);
        switch (o.ttype()) {
            case CT.LUA_TNIL:
                break;
            case CT.LUA_TBOOLEAN:
                DumpByte(o.value ? 1 : 0, D);
                break;
            case CT.LUA_TNUMFLT:
                DumpNumber(o.value, D);
                break;
            case CT.LUA_TNUMINT:
                DumpInteger(o.value, D);
                break;
            case CT.LUA_TSHRSTR:
            case CT.LUA_TLNGSTR:
                DumpString(o.tsvalue(), D);
                break;
        }
    }
};

const DumpProtos = function(f, D) {
    let n = f.p.length;
    DumpInt(n, D);
    for (let i = 0; i < n; i++)
        DumpFunction(f.p[i], f.source, D);
};

const DumpUpvalues = function(f, D) {
    let n = f.upvalues.length;
    DumpInt(n, D);
    for (let i = 0; i < n; i++) {
        DumpByte(f.upvalues[i].instack ? 1 : 0, D);
        DumpByte(f.upvalues[i].idx, D);
    }
};

const DumpDebug = function(f, D) {
    let n = D.strip ? 0 : f.lineinfo.length;
    DumpInt(n, D);
    for (let i = 0; i < n; i++)
        DumpInt(f.lineinfo[i], D);
    n = D.strip ? 0 : f.locvars.length;
    DumpInt(n, D);
    for (let i = 0; i < n; i++) {
        DumpString(f.locvars[i].varname, D);
        DumpInt(f.locvars[i].startpc, D);
        DumpInt(f.locvars[i].endpc, D);
    }
    n = D.strip ? 0 : f.upvalues.length;
    DumpInt(n, D);
    for (let i = 0; i < n; i++)
        DumpString(f.upvalues[i].name, D);
};

const DumpFunction = function(f, psource, D) {
    if (D.strip || f.source === psource)
        DumpString(null, D);  /* no debug info or same source as its parent */
    else
        DumpString(f.source, D);
    DumpInt(f.linedefined, D);
    DumpInt(f.lastlinedefined, D);
    DumpByte(f.numparams, D);
    DumpByte(f.is_vararg?1:0, D);
    DumpByte(f.maxstacksize, D);
    DumpCode(f, D);
    DumpConstants(f, D);
    DumpUpvalues(f, D);
    DumpProtos(f, D);
    DumpDebug(f, D);
};

const DumpHeader = function(D) {
    DumpLiteral(defs.LUA_SIGNATURE, D);
    DumpByte(LUAC_VERSION, D);
    DumpByte(LUAC_FORMAT, D);
    DumpBlock(LUAC_DATA, LUAC_DATA.length, D);
    DumpByte(4, D); // intSize
    DumpByte(4, D); // size_tSize
    DumpByte(4, D); // instructionSize
    DumpByte(4, D); // integerSize
    DumpByte(8, D); // numberSize
    DumpInteger(LUAC_INT, D);
    DumpNumber(LUAC_NUM, D);
};

/*
** dump Lua function as precompiled chunk
*/
const luaU_dump = function(L, f, w, data, strip) {
    let D = new DumpState();
    D.L = L;
    D.writer = w;
    D.data = data;
    D.strip = strip;
    D.status = 0;
    DumpHeader(D);
    DumpByte(f.upvalues.length, D);
    DumpFunction(f, null, D);
    return D.status;
};

module.exports.luaU_dump = luaU_dump;
<|endoftext|>


<commit_before>var LUCKY_NUMBER = 7;
var MAX_WHITE_BALL = 59;
var MAX_POWER_BALL = 39;
var calculateResult = function (whiteBalls, powerBall) {
  var index;
  for(index = 0; index < 5; index++){
    if((whiteBalls[index] < 1) || (whiteBalls[index] > MAX_WHITE_BALL)) {
      return -1;
    }
  }
  if((powerBall < 1) || (powerBall > MAX_POWER_BALL)) {
    return -1;
  }
  return 0;
};
var lottery = function () {
  var powerBall, whiteBalls, index, result;
  if(process.argv.length !== 8){
    console.log("Error. Usage: node " + process.argv[1] + " (5 white balls) power_ball");
    return -1;
  }
  powerBall = parseInt(process.argv[7], 10);
  whiteBalls = [];
  for(index = 0; index < 5; index++){
    whiteBalls[index] = parseInt(process.argv[2+index]);
  }
  result = calculateResult(whiteBalls, powerBall);

  if(result < 0) {
    console.log('Invalid arguments.');
    return -1;
  }

  if(powerBall === LUCKY_NUMBER){
    result = result * 2;
  }

  console.log( result + ' percent chance of winning.');
  return 0;
};
lottery();
<commit_msg>sorting whiteballs<commit_after>var LUCKY_NUMBER = 7;
var MAX_WHITE_BALL = 59;
var MAX_POWER_BALL = 39;
var calculateResult = function (whiteBalls, powerBall) {
  var index;
  whiteBalls.sort();
  for(index = 0; index < 5; index++){
    if((whiteBalls[index] < 1) || (whiteBalls[index] > MAX_WHITE_BALL)) {
      return -1;
    }
  }
  if((powerBall < 1) || (powerBall > MAX_POWER_BALL)) {
    return -1;
  }
  return 0;
};
var lottery = function () {
  var powerBall, whiteBalls, index, result;
  if(process.argv.length !== 8){
    console.log("Error. Usage: node " + process.argv[1] + " (5 white balls) power_ball");
    return -1;
  }
  powerBall = parseInt(process.argv[7], 10);
  whiteBalls = [];
  for(index = 0; index < 5; index++){
    whiteBalls[index] = parseInt(process.argv[2+index]);
  }

  result = calculateResult(whiteBalls, powerBall);

  if(result < 0) {
    console.log('Invalid arguments.');
    return -1;
  }

  if(powerBall === LUCKY_NUMBER){
    result = result * 2;
  }

  console.log( result + ' percent chance of winning.');
  return 0;
};
lottery();
<|endoftext|>