<commit_before>define(function() {

	'use strict';

	var MIN_GAP = 500;

	function PiecemealDownload(url, ranges) {
		this.url = url;
		for (var i = ranges.length-2; i >= 0; i--) {
			if (isNaN(ranges[i].length)) {
				ranges.splice(i + 1, ranges.length - (i + 1));
			}
			else {
				if (ranges[i].offset <= ranges[i + 1].offset
						&& (ranges[i].offset + ranges[i].length + MIN_GAP) >= ranges[i + 1].offset) {
					if (isNaN(ranges[i + 1].length)) {
						delete ranges[i].length;
						ranges.splice(i + 1, ranges.length - (i + 1));
					}
					else {
						ranges[i].length = (ranges[i+1].offset + ranges[i+1].length) - ranges[i].offset;
						ranges.splice(i + 1, 1);
					}
				}
			}
		}
		this.ranges = ranges;
	}
	PiecemealDownload.prototype = {
		getRangeHeader: function() {
			var ranges = this.ranges;
			return 'bytes=' + ranges.map(function(range) {
				return range.offset + '-' +
					(isNaN(range.length) ? '' : (range.offset + range.length - 1));
			}).join(',');
		},
		onPiece: function(){},
		onRawPiece: null,
		initMonolithic: function(offset) {
			this.onRawPiece = this.onRawPiece || function(piece) {
				this.onPiece(offset, piece);
				offset += piece.length;
			};
		},
		initMultipart: function(boundary) {
			var self = this;
			var lineBuf = [];
			var offset, length = 0;
			var onLine;
			var partHeaders;
			function onLine_PartBoundary(line) {
				if (!boundary) {
					if (/^--/.test(line)) {
						boundary = line.substr(2);
						partHeaders = {};
						onLine = onLine_PartHeader;
					}
					else if (line !== '') {
						self.cancel();
						throw new Error('Invalid multipart data');
					}
				}
				else if (line === '--' + boundary) {
					partHeaders = {};
					onLine = onLine_PartHeader;
				}
				else if (line === '--' + boundary + '--') {
					// end of data
					// (not actually reached because there's no final CRLF)
				}
				else if (line !== '') { // optional CRLFs before the first part
					self.cancel();
					throw new Error('Invalid multipart data');
				}
			}
			function onLine_PartHeader(line) {
				if (line === '') {
					var range = partHeaders['content-range'];
					if (!range) {
						self.cancel();
						throw new Error('Invalid multipart data: no Content-Range part header found');
					}
					var matched = range.match(/^bytes (\d+)\-(\d+)\/(\d+)$/);
					if (!matched) {
						self.cancel();
						throw new Error('Invalid multipart Content-Range: ' + range);
					}
					offset = +matched[1];
					length = +matched[2] + 1 - offset;
					onLine = onLine_PartBoundary;
				}
				else {
					var header = line.match(/^\s*([^:\s]*)\s*:\s*(.*?)\s*$/);
					if (!header) {
						self.cancel();
						throw new Error('Invalid multipart data');
					}
					var headerName = header[1].toLowerCase();
					var headerValue = header[2];
					partHeaders[headerName] = headerValue;
				}
			}
			onLine = onLine_PartBoundary;
			this.onRawPiece = function(piece) {
				var pos = 0;
				if (length > 0) {
					var pieceLength = Math.min(length, piece.length);
					this.onPiece(offset, piece.subarray(0, pieceLength));
					offset += pieceLength;
					pos += pieceLength;
					length -= pieceLength;
				}
				while (pos < piece.length) {
					var byte = piece[pos++];
					if (byte === 10) {
						onLine(String.fromCharCode.apply(null, lineBuf));
						lineBuf.length = 0;
						var pieceLength = Math.min(length, piece.length - pos);
						if (pieceLength > 0) {
							this.onPiece(offset, piece.subarray(pos, pos + pieceLength));
							offset += pieceLength;
							pos += pieceLength;
							length -= pieceLength;
						}
					}
					else if (byte !== 13) {
						if (byte < 32 && byte !== 9) {
							this.cancel();
							throw new Error('Unexpected control character: ' + byte);
						}
						lineBuf.push(byte);
					}
				}
			};
		},
		onDone: function(){},
		startDownload: null,
		initContentHeaders: function(contentType, contentRange) {
			contentType = contentType.split(/\s*;\s*/g);
			if (/^multipart\//i.test(contentType[0])) {
				for (var i = 1; i < contentType.length; i++) {
					var param = contentType[i].match(/^\s*([^=\s]+)\s*=("(.*)"|(.*))$/);
					if (!param) {
						this.cancel();
						throw new Error('Invalid Content-Type: ' + contentType.join('; '));
					}
					if (param[1].toLowerCase() === 'boundary') {
						return this.initMultipart(param[3] || param[4]);
					}
				}
				this.cancel();
				throw new Error('Invalid Content-Type: ' + contentType);
			}
			if (!contentRange) {
				return this.initMonolithic(0);
			}
			var matched = contentRange.match(/^bytes (\d+)\-(\d+)\/(\d+)$/);
			if (!matched) {
				this.cancel();
				throw new Error('Invalid Content-Range: ' + contentRange);
			}
			this.initMonolithic(+matched[1]);
		},
		openXHR: function(forceMultipart) {
			var xhr = new XMLHttpRequest;
			xhr.open('GET', this.url, true);
			xhr.setRequestHeader('Range', this.getRangeHeader());
			var self = this;
			xhr.addEventListener('readystatechange', function() {
				if (this.readyState === 2) {
					if (forceMultipart) {
						self.initMultipart(null);
					}
					else {
						self.initContentHeaders(
							this.getResponseHeader('Content-Type'),
							this.getResponseHeader('Content-Range'));
					}
				}
			});
			xhr.addEventListener('load', function() {
				self.onDone();
				delete self.xhr;
			});
			return this.xhr = xhr;
		},
		cancel: function() {
			if ('xhr' in this) {
				this.xhr.abort();
				delete this.xhr;
			}
			else if ('reader' in this) {
				if ('cancel' in this.reader) {
					this.reader.cancel();
				}
				else {
					this.reader.abort();
				}
				delete this.reader;
			}
			this.cancelled = true;
		},
		listenToReader: function(reader) {
			var self = this;
			var pos = 0;
			reader.addEventListener('progress', function() {
				var arraybuffer = this.result;
				if (pos < arraybuffer.byteLength) {
					self.onRawPiece(new Uint8Array(arraybuffer, pos));
					pos = arraybuffer.byteLength;
				}
			});
			reader.addEventListener('load', function() {
				delete self.reader;
			});
			this.reader = reader;
		},
	};

	function tryResponseType(responseType) {
		if (!('responseType' in XMLHttpRequest.prototype)) {
			return false;
		}
		var xhr = new XMLHttpRequest;
		xhr.open('GET', '/', true);
		xhr.responseType = responseType;
		return xhr.responseType === responseType;
	}

	if ('fetch' in window && 'Response' in window && 'body' in Response.prototype) {
		PiecemealDownload.prototype.startDownload = startDownload_FetchResponseBody;
		PiecemealDownload.mode = 'chunked';
	}
	else if (tryResponseType('moz-chunked-arraybuffer')) {
		PiecemealDownload.prototype.startDownload = startDownload_MozChunked;
		PiecemealDownload.mode = 'chunked';
	}
	else if ('MSStreamReader' in window && tryResponseType('ms-stream')) {
		PiecemealDownload.prototype.startDownload = startDownload_MSStream;
		PiecemealDownload.mode = 'buffered';
	}
	else if ('overrideMimeType' in XMLHttpRequest.prototype) {
		PiecemealDownload.prototype.startDownload = startDownload_BinaryString;
		PiecemealDownload.mode = 'buffered';
	}
	else {
		PiecemealDownload.prototype.startDownload = startDownload_ManuallyChunked;
		PiecemealDownload.mode = 'simulated';
	}

	// using Streams API via fetch()
	function startDownload_FetchResponseBody() {
		var self = this;
		fetch(this.url, {headers: {Range: this.getRangeHeader()}, cache:'force-cache'})
			.then(function(response) {
				self.initContentHeaders(
					response.headers.get('Content-Type'),
					response.headers.get('Content-Range'));
				var reader = response.body.getReader();
				self.reader = reader;
				function onPiece(piece) {
					if (piece.done) {
						if (!self.cancelled) {
							self.onDone();
						}
					}
					else {
						self.onRawPiece(piece.value);
						reader.read().then(onPiece);
					}
				}
				reader.read().then(onPiece);
			});
	}

	// using Mozilla's moz-chunked-arraybuffer responseType
	function startDownload_MozChunked() {
		var xhr = this.openXHR();
		xhr.responseType = 'moz-chunked-arraybuffer';
		var self = this;
		xhr.addEventListener('progress', function() {
			self.onRawPiece(new Uint8Array(this.response));
		});
		xhr.send();
	}

	// using Microsoft's ms-stream responseType
	function startDownload_MSStream() {
		var xhr = this.openXHR();
		xhr.responseType = 'ms-stream';
		var self = this;
		xhr.addEventListener('readystatechange', function() {
			switch (this.readyState) {
				case 3: // LOADING
					var reader = new MSStreamReader;
					self.listenToReader(reader);
					reader.readAsArrayBuffer(this.response);
					break;
			}
		});
		xhr.send();
	}

	// using binary string responseText
	// TODO: limit to blocks of 1mb?
	var getStringBytes;
	function startDownload_BinaryString() {
		var xhr = this.openXHR(this.ranges.length > 1);
		xhr.overrideMimeType('text/plain; charset=ISO-8859-1');
		var pos = 0;
		var self = this;
		xhr.addEventListener('progress', function() {
			if (pos < this.responseText.length) {
				self.onRawPiece(getStringBytes(this.responseText.slice(pos)));
				pos = this.responseText.length;
			}
		});
		xhr.send();
	}

	// TextEncoder only works with UTF, not ISO-8859-1
	function getStringBytes(str) {
		var a = new Array(str.length);
		for (var i = 0; i < str.length; i++) {
			a[i] = str.charCodeAt(i);
		}
		return new Uint8Array(a);
	}

	// no true streaming available?
	// make a series of small individual downloads instead
	var MANUAL_CHUNK_SIZE = 1024 * 10;
	function startDownload_ManuallyChunked() {
		var self = this;
		var ranges = this.ranges.slice();
		function nextRange() {
			if (ranges.length === 0) {
				self.onDone();
			}
			else {
				var range = ranges.splice(0, 1)[0];
				nextChunk(range.offset, range.length);
			}
		}
		function nextChunk(offset, length) {
			var xhr = new XMLHttpRequest;
			xhr.open('GET', self.url, true);
			xhr.responseType = 'arraybuffer';
			var chunkLength = isNaN(length) || length > MANUAL_CHUNK_SIZE ? MANUAL_CHUNK_SIZE : length;
			xhr.setRequestHeader('Range', 'bytes=' + offset + '-' + (offset + chunkLength - 1));
			xhr.addEventListener('readystatechange', function() {
				if (this.readyState === 2) {
					if (xhr.status < 200 && xhr.status > 299) {
						xhr.abort();
						throw new Error('Server returned status ' + xhr.status);
					}
					if (isNaN(length)) {
						var range = xhr.getResponseHeader('Content-Range');
						if (!range) {
							xhr.abort();
							throw new Error('Server returned no Content-Range');
						}
						var match = range.match(/\/(\d+)/);
						if (!match) {
							xhr.abort();
							throw new Error('Content-Range: ' + range);
						}
						length = +match[1] - offset;
					}
				}
			});
			xhr.addEventListener('load', function() {
				self.onPiece(offset, new Uint8Array(xhr.response));
				var responseLength = xhr.response.byteLength;
				if (responseLength === length || responseLength < MANUAL_CHUNK_SIZE) {
					nextRange();
				}
				else {
					nextChunk(
						offset + xhr.response.byteLength,
						length - xhr.response.byteLength);
				}
			});
			self.xhr = xhr;
			xhr.send();
		}
		nextRange();
	}

	return PiecemealDownload;

});
<commit_msg>Add onTotalLength method when the full length is known<commit_after>define(function() {

	'use strict';

	var MIN_GAP = 500;

	function PiecemealDownload(url, ranges) {
		this.url = url;
		for (var i = ranges.length-2; i >= 0; i--) {
			if (isNaN(ranges[i].length)) {
				ranges.splice(i + 1, ranges.length - (i + 1));
			}
			else {
				if (ranges[i].offset <= ranges[i + 1].offset
						&& (ranges[i].offset + ranges[i].length + MIN_GAP) >= ranges[i + 1].offset) {
					if (isNaN(ranges[i + 1].length)) {
						delete ranges[i].length;
						ranges.splice(i + 1, ranges.length - (i + 1));
					}
					else {
						ranges[i].length = (ranges[i+1].offset + ranges[i+1].length) - ranges[i].offset;
						ranges.splice(i + 1, 1);
					}
				}
			}
		}
		this.ranges = ranges;
	}
	PiecemealDownload.prototype = {
		getRangeHeader: function() {
			var ranges = this.ranges;
			return 'bytes=' + ranges.map(function(range) {
				return range.offset + '-' +
					(isNaN(range.length) ? '' : (range.offset + range.length - 1));
			}).join(',');
		},
		onPiece: function(){},
		onTotalLength: function(){},
		onRawPiece: null,
		initMonolithic: function(offset) {
			this.onRawPiece = this.onRawPiece || function(piece) {
				this.onPiece(offset, piece);
				offset += piece.length;
			};
		},
		initMultipart: function(boundary) {
			var self = this;
			var lineBuf = [];
			var offset, length = 0;
			var onLine;
			var partHeaders;
			function onLine_PartBoundary(line) {
				if (!boundary) {
					if (/^--/.test(line)) {
						boundary = line.substr(2);
						partHeaders = {};
						onLine = onLine_PartHeader;
					}
					else if (line !== '') {
						self.cancel();
						throw new Error('Invalid multipart data');
					}
				}
				else if (line === '--' + boundary) {
					partHeaders = {};
					onLine = onLine_PartHeader;
				}
				else if (line === '--' + boundary + '--') {
					// end of data
					// (not actually reached because there's no final CRLF)
				}
				else if (line !== '') { // optional CRLFs before the first part
					self.cancel();
					throw new Error('Invalid multipart data');
				}
			}
			function onLine_PartHeader(line) {
				if (line === '') {
					var range = partHeaders['content-range'];
					if (!range) {
						self.cancel();
						throw new Error('Invalid multipart data: no Content-Range part header found');
					}
					var matched = range.match(/^bytes (\d+)\-(\d+)\/(\d+)$/);
					if (!matched) {
						self.cancel();
						throw new Error('Invalid multipart Content-Range: ' + range);
					}
					offset = +matched[1];
					length = +matched[2] + 1 - offset;
					onLine = onLine_PartBoundary;
				}
				else {
					var header = line.match(/^\s*([^:\s]*)\s*:\s*(.*?)\s*$/);
					if (!header) {
						self.cancel();
						throw new Error('Invalid multipart data');
					}
					var headerName = header[1].toLowerCase();
					var headerValue = header[2];
					partHeaders[headerName] = headerValue;
				}
			}
			onLine = onLine_PartBoundary;
			this.onRawPiece = function(piece) {
				var pos = 0;
				if (length > 0) {
					var pieceLength = Math.min(length, piece.length);
					this.onPiece(offset, piece.subarray(0, pieceLength));
					offset += pieceLength;
					pos += pieceLength;
					length -= pieceLength;
				}
				while (pos < piece.length) {
					var byte = piece[pos++];
					if (byte === 10) {
						onLine(String.fromCharCode.apply(null, lineBuf));
						lineBuf.length = 0;
						var pieceLength = Math.min(length, piece.length - pos);
						if (pieceLength > 0) {
							this.onPiece(offset, piece.subarray(pos, pos + pieceLength));
							offset += pieceLength;
							pos += pieceLength;
							length -= pieceLength;
						}
					}
					else if (byte !== 13) {
						if (byte < 32 && byte !== 9) {
							this.cancel();
							throw new Error('Unexpected control character: ' + byte);
						}
						lineBuf.push(byte);
					}
				}
			};
		},
		onDone: function(){},
		startDownload: null,
		initContentHeaders: function(contentType, contentRange) {
			contentType = contentType.split(/\s*;\s*/g);
			if (/^multipart\//i.test(contentType[0])) {
				for (var i = 1; i < contentType.length; i++) {
					var param = contentType[i].match(/^\s*([^=\s]+)\s*=("(.*)"|(.*))$/);
					if (!param) {
						this.cancel();
						throw new Error('Invalid Content-Type: ' + contentType.join('; '));
					}
					if (param[1].toLowerCase() === 'boundary') {
						return this.initMultipart(param[3] || param[4]);
					}
				}
				this.cancel();
				throw new Error('Invalid Content-Type: ' + contentType);
			}
			if (!contentRange) {
				return this.initMonolithic(0);
			}
			var matched = contentRange.match(/^bytes (\d+)\-(\d+)\/(\d+)$/);
			if (!matched) {
				this.cancel();
				throw new Error('Invalid Content-Range: ' + contentRange);
			}
			this.onTotalLength(+matched[3]);
			this.initMonolithic(+matched[1]);
		},
		openXHR: function(forceMultipart) {
			var xhr = new XMLHttpRequest;
			xhr.open('GET', this.url, true);
			xhr.setRequestHeader('Range', this.getRangeHeader());
			var self = this;
			xhr.addEventListener('readystatechange', function() {
				if (this.readyState === 2) {
					if (forceMultipart) {
						self.initMultipart(null);
					}
					else {
						self.initContentHeaders(
							this.getResponseHeader('Content-Type'),
							this.getResponseHeader('Content-Range'));
					}
				}
			});
			xhr.addEventListener('load', function() {
				self.onDone();
				delete self.xhr;
			});
			return this.xhr = xhr;
		},
		cancel: function() {
			if ('xhr' in this) {
				this.xhr.abort();
				delete this.xhr;
			}
			else if ('reader' in this) {
				if ('cancel' in this.reader) {
					this.reader.cancel();
				}
				else {
					this.reader.abort();
				}
				delete this.reader;
			}
			this.cancelled = true;
		},
		listenToReader: function(reader) {
			var self = this;
			var pos = 0;
			reader.addEventListener('progress', function() {
				var arraybuffer = this.result;
				if (pos < arraybuffer.byteLength) {
					self.onRawPiece(new Uint8Array(arraybuffer, pos));
					pos = arraybuffer.byteLength;
				}
			});
			reader.addEventListener('load', function() {
				delete self.reader;
			});
			this.reader = reader;
		},
	};

	function tryResponseType(responseType) {
		if (!('responseType' in XMLHttpRequest.prototype)) {
			return false;
		}
		var xhr = new XMLHttpRequest;
		xhr.open('GET', '/', true);
		xhr.responseType = responseType;
		return xhr.responseType === responseType;
	}

	if ('fetch' in window && 'Response' in window && 'body' in Response.prototype) {
		PiecemealDownload.prototype.startDownload = startDownload_FetchResponseBody;
		PiecemealDownload.mode = 'chunked';
	}
	else if (tryResponseType('moz-chunked-arraybuffer')) {
		PiecemealDownload.prototype.startDownload = startDownload_MozChunked;
		PiecemealDownload.mode = 'chunked';
	}
	else if ('MSStreamReader' in window && tryResponseType('ms-stream')) {
		PiecemealDownload.prototype.startDownload = startDownload_MSStream;
		PiecemealDownload.mode = 'buffered';
	}
	else if ('overrideMimeType' in XMLHttpRequest.prototype) {
		PiecemealDownload.prototype.startDownload = startDownload_BinaryString;
		PiecemealDownload.mode = 'buffered';
	}
	else {
		PiecemealDownload.prototype.startDownload = startDownload_ManuallyChunked;
		PiecemealDownload.mode = 'simulated';
	}

	// using Streams API via fetch()
	function startDownload_FetchResponseBody() {
		var self = this;
		fetch(this.url, {headers: {Range: this.getRangeHeader()}, cache:'force-cache'})
			.then(function(response) {
				self.initContentHeaders(
					response.headers.get('Content-Type'),
					response.headers.get('Content-Range'));
				var reader = response.body.getReader();
				self.reader = reader;
				function onPiece(piece) {
					if (piece.done) {
						if (!self.cancelled) {
							self.onDone();
						}
					}
					else {
						self.onRawPiece(piece.value);
						reader.read().then(onPiece);
					}
				}
				reader.read().then(onPiece);
			});
	}

	// using Mozilla's moz-chunked-arraybuffer responseType
	function startDownload_MozChunked() {
		var xhr = this.openXHR();
		xhr.responseType = 'moz-chunked-arraybuffer';
		var self = this;
		xhr.addEventListener('progress', function() {
			self.onRawPiece(new Uint8Array(this.response));
		});
		xhr.send();
	}

	// using Microsoft's ms-stream responseType
	function startDownload_MSStream() {
		var xhr = this.openXHR();
		xhr.responseType = 'ms-stream';
		var self = this;
		xhr.addEventListener('readystatechange', function() {
			switch (this.readyState) {
				case 3: // LOADING
					var reader = new MSStreamReader;
					self.listenToReader(reader);
					reader.readAsArrayBuffer(this.response);
					break;
			}
		});
		xhr.send();
	}

	// using binary string responseText
	// TODO: limit to blocks of 1mb?
	var getStringBytes;
	function startDownload_BinaryString() {
		var xhr = this.openXHR(this.ranges.length > 1);
		xhr.overrideMimeType('text/plain; charset=ISO-8859-1');
		var pos = 0;
		var self = this;
		xhr.addEventListener('progress', function() {
			if (pos < this.responseText.length) {
				self.onRawPiece(getStringBytes(this.responseText.slice(pos)));
				pos = this.responseText.length;
			}
		});
		xhr.send();
	}

	// TextEncoder only works with UTF, not ISO-8859-1
	function getStringBytes(str) {
		var a = new Array(str.length);
		for (var i = 0; i < str.length; i++) {
			a[i] = str.charCodeAt(i);
		}
		return new Uint8Array(a);
	}

	// no true streaming available?
	// make a series of small individual downloads instead
	var MANUAL_CHUNK_SIZE = 1024 * 10;
	function startDownload_ManuallyChunked() {
		var self = this;
		var ranges = this.ranges.slice();
		function nextRange() {
			if (ranges.length === 0) {
				self.onDone();
			}
			else {
				var range = ranges.splice(0, 1)[0];
				nextChunk(range.offset, range.length);
			}
		}
		function nextChunk(offset, length) {
			var xhr = new XMLHttpRequest;
			xhr.open('GET', self.url, true);
			xhr.responseType = 'arraybuffer';
			var chunkLength = isNaN(length) || length > MANUAL_CHUNK_SIZE ? MANUAL_CHUNK_SIZE : length;
			xhr.setRequestHeader('Range', 'bytes=' + offset + '-' + (offset + chunkLength - 1));
			xhr.addEventListener('readystatechange', function() {
				if (this.readyState === 2) {
					if (xhr.status < 200 && xhr.status > 299) {
						xhr.abort();
						throw new Error('Server returned status ' + xhr.status);
					}
					if (isNaN(length)) {
						var range = xhr.getResponseHeader('Content-Range');
						if (!range) {
							xhr.abort();
							throw new Error('Server returned no Content-Range');
						}
						var match = range.match(/\/(\d+)/);
						if (!match) {
							xhr.abort();
							throw new Error('Content-Range: ' + range);
						}
						length = +match[1] - offset;
					}
				}
			});
			xhr.addEventListener('load', function() {
				self.onPiece(offset, new Uint8Array(xhr.response));
				var responseLength = xhr.response.byteLength;
				if (responseLength === length || responseLength < MANUAL_CHUNK_SIZE) {
					nextRange();
				}
				else {
					nextChunk(
						offset + xhr.response.byteLength,
						length - xhr.response.byteLength);
				}
			});
			self.xhr = xhr;
			xhr.send();
		}
		nextRange();
	}

	return PiecemealDownload;

});
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PTT from '../PTT';
import Cookies from 'js-cookie';
import TimerNewButton from './TimerNewButton';
import TimerStopButton from './TimerStopButton';
import TimerNewForm from './TimerNewForm';
import LoadingIcon from '../LoadingIcon';
import $ from 'jquery'; // Import jQuery.

/**
 * Display the new timer button
 */
class TimerNew extends Component {
  constructor(props) {
    super(props);

    this._construct( true );
  }

  _construct( isConstructor ) {
    const post = Cookies.getJSON( 'ptt_current_timer' );

    const message = ( post )
        ? this._timerStartedMessage( new Date( post.start ) )
        : '';

    const view = ( post )
        ? <TimerStopButton post={post.id}
                onClick={this._handleStopTimer.bind(this)} />
        : <TimerNewButton onClick={this._handleNewTimer.bind(this)} />;

    if ( isConstructor ) {
      this.state = { post, message, view };
    } else {
      this.setState({ post, message, view });
   }
  }

  render() {
    return (

{this.state.message}

        {this.state.view}

    );
  }

  // TODO handle error
  _handleNewTimer(e) {
    e.preventDefault();

    const view = <LoadingIcon />;

    this.setState({ view });

    var _this = this; // Move callback to proper functions w/ bind this!!

    // Start the timer!
    const _start = new Date();

    $.ajax({
      beforeSend: PTT.get('auth').ajaxBeforeSend,
      method: 'POST', // Create a post. 'GET' retrieves them.
      url: PTT.get('endpoint')
        + '?status=publish&title=Timer in progress create by PTT at '
        + _start.toLocaleTimeString(),
    })
    .done( function( post ) {
      // save post info in a cookie.
      Cookies.remove( 'ptt_current_timer' );
      Cookies.set( 'ptt_current_timer', {
        id: post.id,
        start: _start.getTime(),
      } );

      console.log(post);

      _this.setState( {
        post: {
          id: post.id,
          start: _start.getTime(),
        },
        view: <TimerStopButton post={post.id}
            onClick={_this._handleStopTimer.bind(_this)} />,
        message: _this._timerStartedMessage( _start ),
      });
    })
    .fail( function( err ) {
      _this.setState( {
        message:
          {err.responseJSON.message}
        ,
      });
    });
  }

  _handleStopTimer(e) {
    e.preventDefault();

    const stop     = new Date();
    const diff     = Math.abs( stop.getTime() - this.state.post.start );
    const minutes  = Math.floor( diff / 60000 );
    const total    = parseFloat( minutes / 60 );
    const time     = ( Math.round(total * 4) / 4).toFixed(2);

    this.setState( {
      view: <TimerNewForm post={this.state.post.id} total={time} onSaved={this._construct.bind(this)} />,
      // message: 'Congratulations, you finished a task! Enter some information about it here to complete recording your time.',
      message: '',
    });
  }

  _timerStartedMessage( date ) {
    const time = date.toLocaleTimeString();
    return (

        Timer started at:
         {time}

    );
  }
}

export default TimerNew;
<commit_msg>new loading icon<commit_after>import React, { Component } from 'react';
import PTT from '../PTT';
import TimerNewButton from './TimerNewButton';
import TimerStopButton from './TimerStopButton';
import TimerNewForm from './TimerNewForm';
import LoadingIcon from '../LoadingIcon';
import $ from 'jquery'; // Import jQuery.
import TimerFetch from './TimerFetch';

/**
 * Display the new timer button
 */
class TimerNew extends Component {
  constructor(props) {
    super(props);

    this.state = {
      post: PTT.get('current_timer'),
      message: '',
      view: <LoadingIcon
      message="Checking if you have any timers opened.." />,
    };
  }

  componentWillMount() {
    this._construct();
  }

  _construct( isConstructor ) {
    if ( this.state.post
      && this.state.post.id ) {
      // we have a post saved in our cookies
      // lets try and verify it.
      // consle.log( this.state.post );
      TimerFetch.getPost( this.state.post.id )
      .then( r => {
        if ( r.id ) {
          // we have a post id
          // which means we have a post.
          this.setState({
            message: this._timerStartedMessage(
              new Date( this.state.post.start )
            ),
            view: <TimerStopButton post={this.state.post.id}
            onClick={this._handleStopTimer.bind(this)} />,
          });
        }
        else {
          // we do not have a post.
          // which means there will be an issue.
          this.setState({
            message: 'It looks like there was a timer saved in your cookies but we could not verify it. This usually means the post was removed or you no longer have access to it. Sorry for the inconvenience, please create a new timer.',
            view: <TimerNewButton
            onClick={this._handleNewTimer.bind(this)} />,
          });
          PTT.set('current_timer', {}); // delete post cookie
          PTT.setCookies(); // reset cookies.
        }
      });
    }
    // we do not have a post
    else {
      this.setState({
        view: <TimerNewButton
        onClick={this._handleNewTimer.bind(this)} />,
      });
    }
  }

  render() {
    return (

{this.state.message}

        {this.state.view}

    );
  }

  // TODO handle error
  _handleNewTimer(e) {
    e.preventDefault();

    const view = <LoadingIcon />;

    this.setState({
      message: '',
      view: view,
    });

    var _this = this; // Move callback to proper functions w/ bind this!!

    // Start the timer!
    const _start = new Date();

    $.ajax({
      beforeSend: PTT.get('auth').ajaxBeforeSend,
      method: 'POST', // Create a post. 'GET' retrieves them.
      url: PTT.get('endpoint')
        + '?status=publish&title=Timer in progress create by PTT at '
        + _start.toLocaleTimeString(),
    })
    .done( function( post ) {
      const _post = {
        id: post.id,
        start: _start.getTime(),
      };
      PTT.set('current_timer', _post);
      PTT.setCookies();
      console.log(post);
      _this.setState( {
        post: _post,
        view: <TimerStopButton post={_post.id}
            onClick={_this._handleStopTimer.bind(_this)} />,
        message: _this._timerStartedMessage( _start ),
      });
    })
    .fail( function( err ) {
      _this.setState( {
        message:
          {err.responseJSON.message}
        ,
      });
    });
  }

  _handleStopTimer(e) {
    e.preventDefault();

    const stop     = new Date();
    const diff     = Math.abs( stop.getTime() - this.state.post.start );
    const minutes  = Math.floor( diff / 60000 );
    const total    = parseFloat( minutes / 60 );
    const time     = ( Math.round(total * 4) / 4).toFixed(2);

    this.setState( {
      view: <TimerNewForm post={this.state.post.id} total={time} onSaved={this._construct.bind(this)} />,
      // message: 'Congratulations, you finished a task! Enter some information about it here to complete recording your time.',
      message: '',
    });
  }

  _timerStartedMessage( date ) {
    const time = date.toLocaleTimeString();
    return (

        Timer started at:
         {time}

    );
  }
}

export default TimerNew;
<|endoftext|>


<commit_before>var socket_name = 'http://' + document.domain + ':' + location.port;
var socket = io.connect(socket_name);
var gamemode = null,
    input_type = null;
var username = null;

function main() {
    // create, initiate and append game canvas
    username = window.prompt("Enter a username", "Username");
    init(); // initiate game objects
    $("#container").hidden=True;
    //$(document).keydown(keyDown); //add keylisteners
    //$(document).keyup(keyUp);
    //draw();
}

function init() {
    socket.emit('add user', username);
}

function fillNES() {
    var a_button = $('');
    var b_button = $('');
    var d_pad = $('');
    console.log("here");
    $("#button_layout").append(a_button);
    $("#button_layout").append(b_button);
    $("#button_layout").append(d_pad);
    $("#A_button").click(function() {
        socket.emit("sendInput", {
            user_input: "A"
        });
    });
    $("#B_button").click(function() {
        socket.emit("sendInput", {
            user_input: "B"
        });
    });
    $("#D_pad").click(function(e) {
        var offset = $(this).offset();
        var width = $(this).width();
        var height = $(this).height();
        var relativeX = (e.pageX - offset.left);
        var relativeY = (e.pageY - offset.top);
        var forceX = ((width/2)-relativeX);
        var forceY = ((height/2)-relativeY);
        var command = "";
        if (forceX>0 && Math.abs(forceX)>Math.abs(forceY)) {
            command = "left";
        }
        if (forceX<0 && (Math.abs(forceX))>Math.abs(forceY)) {
            command = "right";
        }
        if(forceY<0 && (Math.abs(forceY))>Math.abs(forceX)){
            command = "down";
        }
        if(forceY>0 && Math.abs(forceY)>Math.abs(forceX)){
            command="up";
        }
        socket.emit("sendInput", {
            user_input: command
        });
    });
}

function fillSNES() {
    fillNES();
    var x_button = $('');
    var y_button = $('');
    $("#button_layout").append(x_button);
    $("#button_layout").append(y_button);
}
function fillKeyboard(){

}
socket.on('initialize', function(data) {
    console.log(data);
    gamemode = data.mode ? 'chaos' : 'democracy';
    input_type = data.input_type;
    console.log(input_type);
    switch (input_type) {
        case ('NES'):
            {
                fillNES();
                break;
            }
        case ('SNES'):
            {
                fillSNES();
                break;
            }
        case ('Full Keyboard'):
            {
                fillSNES();
                break;
            }
        default:
            {
                break;
            }
    }
});
window.beforeunload = function() {
    if (username != null) socket.emit("disconnect", username);
}
main();<commit_msg>Latest Commit from sublime text<commit_after>var socket_name = 'http://' + document.domain + ':' + location.port;
var socket = io.connect(socket_name);
var gamemode = null,
    input_type = null;
var username = null;

function main() {
    // create, initiate and append game canvas
    username = window.prompt("Enter a username", "Username");
    init(); // initiate game objects
    $("#container").hide();
    //$(document).keydown(keyDown); //add keylisteners
    //$(document).keyup(keyUp);
    //draw();
}

function init() {
    socket.emit('add user', username);
}

function fillNES() {
    var a_button = $('');
    var b_button = $('');
    var d_pad = $('');
    console.log("here");
    $("#button_layout").append(a_button);
    $("#button_layout").append(b_button);
    $("#button_layout").append(d_pad);
    $("#A_button").click(function() {
        socket.emit("sendInput", {
            user_input: "A"
        });
    });
    $("#B_button").click(function() {
        socket.emit("sendInput", {
            user_input: "B"
        });
    });
    $("#D_pad").click(function(e) {
        var offset = $(this).offset();
        var width = $(this).width();
        var height = $(this).height();
        var relativeX = (e.pageX - offset.left);
        var relativeY = (e.pageY - offset.top);
        var forceX = ((width/2)-relativeX);
        var forceY = ((height/2)-relativeY);
        var command = "";
        if (forceX>0 && Math.abs(forceX)>Math.abs(forceY)) {
            command = "left";
        }
        if (forceX<0 && (Math.abs(forceX))>Math.abs(forceY)) {
            command = "right";
        }
        if(forceY<0 && (Math.abs(forceY))>Math.abs(forceX)){
            command = "down";
        }
        if(forceY>0 && Math.abs(forceY)>Math.abs(forceX)){
            command="up";
        }
        socket.emit("sendInput", {
            user_input: command
        });
    });
}

function fillSNES() {
    fillNES();
    var x_button = $('');
    var y_button = $('');
    $("#button_layout").append(x_button);
    $("#button_layout").append(y_button);
}
function fillKeyboard(){

}
socket.on('initialize', function(data) {
    console.log(data);
    gamemode = data.mode ? 'chaos' : 'democracy';
    input_type = data.input_type;
    console.log(input_type);
    switch (input_type) {
        case ('NES'):
            {
                fillNES();
                break;
            }
        case ('SNES'):
            {
                fillSNES();
                break;
            }
        case ('Full Keyboard'):
            {
                fillSNES();
                break;
            }
        default:
            {
                break;
            }
    }
});
window.beforeunload = function() {
    if (username != null) socket.emit("disconnect", username);
}
main();<|endoftext|>


<commit_before>var Types                        = require('../constants/types');
var Charsets                     = require('../constants/charsets');
var Field                        = require('./Field');
var IEEE_754_BINARY_64_PRECISION = Math.pow(2, 53);

module.exports = RowDataPacket;
function RowDataPacket() {
}

Object.defineProperty(RowDataPacket.prototype, 'parse', {
  configurable: true,
  enumerable: false,
  value: parse
});

Object.defineProperty(RowDataPacket.prototype, '_typeCast', {
  configurable: true,
  enumerable: false,
  value: typeCast
});

function parse(parser, fieldPackets, typeCast, nestTables, connection) {
  var self = this;
  var next = function () {
    return self._typeCast(fieldPacket, parser, connection.config.timezone, connection.config.supportBigNumbers, connection.config.bigNumberStrings, connection.config.dateStrings);
  };

  for (var i = 0; i < fieldPackets.length; i++) {
    var fieldPacket = fieldPackets[i];
    var value;

    if (typeof typeCast == "function") {
      value = typeCast.apply(connection, [ new Field({ packet: fieldPacket, parser: parser }), next ]);
    } else {
      value = (typeCast)
        ? this._typeCast(fieldPacket, parser, connection.config.timezone, connection.config.supportBigNumbers, connection.config.bigNumberStrings, connection.config.dateStrings)
        : ( (fieldPacket.charsetNr === Charsets.BINARY)
          ? parser.parseLengthCodedBuffer()
          : parser.parseLengthCodedString() );
    }

    if (typeof nestTables == "string" && nestTables.length) {
      this[fieldPacket.table + nestTables + fieldPacket.name] = value;
    } else if (nestTables) {
      this[fieldPacket.table] = this[fieldPacket.table] || {};
      this[fieldPacket.table][fieldPacket.name] = value;
    } else {
      this[fieldPacket.name] = value;
    }
  }
}

function typeCast(field, parser, timeZone, supportBigNumbers, bigNumberStrings, dateStrings) {
  var numberString;

  switch (field.type) {
    case Types.TIMESTAMP:
    case Types.DATE:
    case Types.DATETIME:
    case Types.NEWDATE:
      var dateString = parser.parseLengthCodedString();
      if (dateStrings) {
          return dateString;
      }
      var dt;

      if (dateString === null) {
        return null;
      }

      var originalString = dateString;
      if (field.type === Types.DATE) {
        dateString += ' 00:00:00';
      }

      if (timeZone !== 'local') {
        dateString += ' ' + timeZone;
      }

      dt = new Date(dateString);
      if (isNaN(dt.getTime())) {
        return originalString;
      }

      return dt;
    case Types.TINY:
    case Types.SHORT:
    case Types.LONG:
    case Types.INT24:
    case Types.YEAR:
    case Types.FLOAT:
    case Types.DOUBLE:
      numberString = parser.parseLengthCodedString();
      return (numberString === null || (field.zeroFill && numberString[0] == "0"))
        ? numberString : Number(numberString);
    case Types.NEWDECIMAL:
    case Types.LONGLONG:
      numberString = parser.parseLengthCodedString();
      return (numberString === null || (field.zeroFill && numberString[0] == "0"))
        ? numberString
        : ((supportBigNumbers && (bigNumberStrings || (Number(numberString) > IEEE_754_BINARY_64_PRECISION)))
          ? numberString
          : Number(numberString));
    case Types.BIT:
      return parser.parseLengthCodedBuffer();
    case Types.STRING:
    case Types.VAR_STRING:
    case Types.TINY_BLOB:
    case Types.MEDIUM_BLOB:
    case Types.LONG_BLOB:
    case Types.BLOB:
      return (field.charsetNr === Charsets.BINARY)
        ? parser.parseLengthCodedBuffer()
        : parser.parseLengthCodedString();
    case Types.GEOMETRY:
      return parser.parseGeometryValue();
    default:
      return parser.parseLengthCodedString();
  }
}
<commit_msg>When using subqueries in select statements, there's no table which means the data would be omitted if using nestTables. This fix only appends data to table objects if there is a table name, otherwise it's appended to the root object.<commit_after>var Types                        = require('../constants/types');
var Charsets                     = require('../constants/charsets');
var Field                        = require('./Field');
var IEEE_754_BINARY_64_PRECISION = Math.pow(2, 53);

module.exports = RowDataPacket;
function RowDataPacket() {
}

Object.defineProperty(RowDataPacket.prototype, 'parse', {
  configurable: true,
  enumerable: false,
  value: parse
});

Object.defineProperty(RowDataPacket.prototype, '_typeCast', {
  configurable: true,
  enumerable: false,
  value: typeCast
});

function parse(parser, fieldPackets, typeCast, nestTables, connection) {
  var self = this;
  var next = function () {
    return self._typeCast(fieldPacket, parser, connection.config.timezone, connection.config.supportBigNumbers, connection.config.bigNumberStrings, connection.config.dateStrings);
  };

  for (var i = 0; i < fieldPackets.length; i++) {
    var fieldPacket = fieldPackets[i];
    var value;

    if (typeof typeCast == "function") {
      value = typeCast.apply(connection, [ new Field({ packet: fieldPacket, parser: parser }), next ]);
    } else {
      value = (typeCast)
        ? this._typeCast(fieldPacket, parser, connection.config.timezone, connection.config.supportBigNumbers, connection.config.bigNumberStrings, connection.config.dateStrings)
        : ( (fieldPacket.charsetNr === Charsets.BINARY)
          ? parser.parseLengthCodedBuffer()
          : parser.parseLengthCodedString() );
    }

    if (typeof nestTables == "string" && nestTables.length) {
      this[fieldPacket.table + nestTables + fieldPacket.name] = value;
    } else if (nestTables && fieldPacket.table !== '') {
      this[fieldPacket.table] = this[fieldPacket.table] || {};
      this[fieldPacket.table][fieldPacket.name] = value;
    } else {
      this[fieldPacket.name] = value;
    }
  }
}

function typeCast(field, parser, timeZone, supportBigNumbers, bigNumberStrings, dateStrings) {
  var numberString;

  switch (field.type) {
    case Types.TIMESTAMP:
    case Types.DATE:
    case Types.DATETIME:
    case Types.NEWDATE:
      var dateString = parser.parseLengthCodedString();
      if (dateStrings) {
          return dateString;
      }
      var dt;

      if (dateString === null) {
        return null;
      }

      var originalString = dateString;
      if (field.type === Types.DATE) {
        dateString += ' 00:00:00';
      }

      if (timeZone !== 'local') {
        dateString += ' ' + timeZone;
      }

      dt = new Date(dateString);
      if (isNaN(dt.getTime())) {
        return originalString;
      }

      return dt;
    case Types.TINY:
    case Types.SHORT:
    case Types.LONG:
    case Types.INT24:
    case Types.YEAR:
    case Types.FLOAT:
    case Types.DOUBLE:
      numberString = parser.parseLengthCodedString();
      return (numberString === null || (field.zeroFill && numberString[0] == "0"))
        ? numberString : Number(numberString);
    case Types.NEWDECIMAL:
    case Types.LONGLONG:
      numberString = parser.parseLengthCodedString();
      return (numberString === null || (field.zeroFill && numberString[0] == "0"))
        ? numberString
        : ((supportBigNumbers && (bigNumberStrings || (Number(numberString) > IEEE_754_BINARY_64_PRECISION)))
          ? numberString
          : Number(numberString));
    case Types.BIT:
      return parser.parseLengthCodedBuffer();
    case Types.STRING:
    case Types.VAR_STRING:
    case Types.TINY_BLOB:
    case Types.MEDIUM_BLOB:
    case Types.LONG_BLOB:
    case Types.BLOB:
      return (field.charsetNr === Charsets.BINARY)
        ? parser.parseLengthCodedBuffer()
        : parser.parseLengthCodedString();
    case Types.GEOMETRY:
      return parser.parseGeometryValue();
    default:
      return parser.parseLengthCodedString();
  }
}
<|endoftext|>


<commit_before>// takes data in form of selector -> html
// replaces selector with html
function rewrite(data) {
    for (var key in data) {
        if (data.hasOwnProperty(key)) {
            $(key).replaceWith(data[key]);
        }
    }
}

function get_url(url) {
    var base = window.location.pathname;
    if ( base.endsWith("/") ) {
        return base + url;
    }
    else {
        return base + "/" + url;
    }
}

function alertWarning(target) {
    var html =
        '
 \
          <button type="button" class="close" data-dismiss="alert">×</button> \
            Oops! Your session expired. Please refresh the page or click here. \

';
    $(target).after(html);
}

function alertDanger(target) {
    var html =
        '
 \
          <button type="button" class="close" data-dismiss="alert">×</button> \
            Uh oh! Something went wrong. You can try refreshing the page or click here. \
            If that doesn\'t work try contacting your system administrator. \

';
    $(target).after(html);
}

function alertBox(target) {
    return function (jqXHR) {
        if (jqXHR.status == 400) {
            alertWarning(target);
        }
        else {
            alertDanger(target);
        }
    }
}

// Login Button
$("body").on('submit','#login-form', function(e){
    e.preventDefault();
    $(this).children("button").html('');
    $.ajax({
        type: "POST",
        url: get_url("login"),
        data: $("#login-form").serialize(),
        success: rewrite,
        error: alertBox("#login-wrapper"),
        dataType: "json"
    });
});

// Logout Link
$("body").on('click','#logout-link', function(e){
    e.preventDefault();
    $.ajax({
        type: "POST",
        url: get_url("logout"),
        success: rewrite,
        error: alertBox("#search-wrapper"),
        dataType: "json"
    });
});

// Student Search Button
$("body").on('submit','#add-student-form', function(e){
    e.preventDefault();
    $(this).children("button").html('');
    $.ajax({
        type: "POST",
        url: get_url("add"),
        data: $("#add-student-form").serialize(),
        success: rewrite,
        error: alertBox("#search-wrapper"),
        dataType: "json"
    });
});

// Student Selection Add Button
$("body").on('click','.selection-button', function(e){
    e.preventDefault();
    var orig = encodeURIComponent($("#add-student-form input[name='search']").val());
    var data = {
        "csrf_token": $("#add-student-form input[name='csrf_token']").val(),
        "search": $(this).data("username"),
        "original": $("#add-student-form input[name='search']").val()
    };
    $(this).html('');
    $.ajax({
        type: "POST",
        url: get_url("add"),
        data: data,
        success: rewrite,
        error: alertBox("#search-wrapper"),
        dataType: "json"
    });
});

// Student Delete Button
$("body").on('click','.student-button', function(e){
    e.preventDefault();
    var data = {
        "csrf_token": $("#student-wrapper input[name='csrf_token']").val(),
        "username": $(this).data("username")
    };
    $(this).html('');
    $.ajax({
        type: "POST",
        url: get_url("delete"),
        data: data,
        success: rewrite,
        error: alertBox("#search-wrapper"),
        dataType: "json"
    });
});

// Hover Danger
function setDanger(item) {
    $(item).removeClass("btn-primary");
    $(item).addClass("btn-danger");
}

function unsetDanger(item) {
    $(item).removeClass("btn-danger");
    $(item).addClass("btn-primary");
}

$("body").on('mouseenter','.student-button', function(){setDanger(this);});
$("body").on('mouseleave','.student-button', function(){unsetDanger(this);});

// Student Delete All Button
$("body").on('click','#delete-all-button', function(e){
    e.preventDefault();
    var data = {
        "csrf_token": $("#student-wrapper input[name='csrf_token']").val(),
        "username": "all"
    };
    $("#delete-all-modal").modal("hide");
    $("#student-delete-all-button").html('');
    $.ajax({
        type: "POST",
        url: get_url("delete"),
        data: data,
        success: rewrite,
        error: alertBox("#search-wrapper"),
        dataType: "json"
    });
});

// Help Buttons
$("body").on('click','.help', function(e){
    var name = $(this).attr("id").split("-")[1];
    $("#help-modal .modal-body div").addClass("hide");
    $("#help-text-"+name).removeClass("hide");
    $("#help-modal").modal("show");
});
<commit_msg>fixed help button spinning<commit_after>// takes data in form of selector -> html
// replaces selector with html
function rewrite(data) {
    for (var key in data) {
        if (data.hasOwnProperty(key)) {
            $(key).replaceWith(data[key]);
        }
    }
}

function get_url(url) {
    var base = window.location.pathname;
    if ( base.endsWith("/") ) {
        return base + url;
    }
    else {
        return base + "/" + url;
    }
}

function alertWarning(target) {
    var html =
        '
 \
          <button type="button" class="close" data-dismiss="alert">×</button> \
            Oops! Your session expired. Please refresh the page or click here. \

';
    $(target).after(html);
}

function alertDanger(target) {
    var html =
        '
 \
          <button type="button" class="close" data-dismiss="alert">×</button> \
            Uh oh! Something went wrong. You can try refreshing the page or click here. \
            If that doesn\'t work try contacting your system administrator. \

';
    $(target).after(html);
}

function alertBox(target) {
    return function (jqXHR) {
        if (jqXHR.status == 400) {
            alertWarning(target);
        }
        else {
            alertDanger(target);
        }
    }
}

// Login Button
$("body").on('submit','#login-form', function(e){
    e.preventDefault();
    $(this).children("#login-button").html('');
    $.ajax({
        type: "POST",
        url: get_url("login"),
        data: $("#login-form").serialize(),
        success: rewrite,
        error: alertBox("#login-wrapper"),
        dataType: "json"
    });
});

// Logout Link
$("body").on('click','#logout-link', function(e){
    e.preventDefault();
    $.ajax({
        type: "POST",
        url: get_url("logout"),
        success: rewrite,
        error: alertBox("#search-wrapper"),
        dataType: "json"
    });
});

// Student Search Button
$("body").on('submit','#add-student-form', function(e){
    e.preventDefault();
    $(this).children("#add-student-button").html('');
    $.ajax({
        type: "POST",
        url: get_url("add"),
        data: $("#add-student-form").serialize(),
        success: rewrite,
        error: alertBox("#search-wrapper"),
        dataType: "json"
    });
});

// Student Selection Add Button
$("body").on('click','.selection-button', function(e){
    e.preventDefault();
    var orig = encodeURIComponent($("#add-student-form input[name='search']").val());
    var data = {
        "csrf_token": $("#add-student-form input[name='csrf_token']").val(),
        "search": $(this).data("username"),
        "original": $("#add-student-form input[name='search']").val()
    };
    $(this).html('');
    $.ajax({
        type: "POST",
        url: get_url("add"),
        data: data,
        success: rewrite,
        error: alertBox("#search-wrapper"),
        dataType: "json"
    });
});

// Student Delete Button
$("body").on('click','.student-button', function(e){
    e.preventDefault();
    var data = {
        "csrf_token": $("#student-wrapper input[name='csrf_token']").val(),
        "username": $(this).data("username")
    };
    $(this).html('');
    $.ajax({
        type: "POST",
        url: get_url("delete"),
        data: data,
        success: rewrite,
        error: alertBox("#search-wrapper"),
        dataType: "json"
    });
});

// Hover Danger
function setDanger(item) {
    $(item).removeClass("btn-primary");
    $(item).addClass("btn-danger");
}

function unsetDanger(item) {
    $(item).removeClass("btn-danger");
    $(item).addClass("btn-primary");
}

$("body").on('mouseenter','.student-button', function(){setDanger(this);});
$("body").on('mouseleave','.student-button', function(){unsetDanger(this);});

// Student Delete All Button
$("body").on('click','#delete-all-button', function(e){
    e.preventDefault();
    var data = {
        "csrf_token": $("#student-wrapper input[name='csrf_token']").val(),
        "username": "all"
    };
    $("#delete-all-modal").modal("hide");
    $("#student-delete-all-button").html('');
    $.ajax({
        type: "POST",
        url: get_url("delete"),
        data: data,
        success: rewrite,
        error: alertBox("#search-wrapper"),
        dataType: "json"
    });
});

// Help Buttons
$("body").on('click','.help', function(e){
    var name = $(this).attr("id").split("-")[1];
    $("#help-modal .modal-body div").addClass("hide");
    $("#help-text-"+name).removeClass("hide");
    $("#help-modal").modal("show");
});
<|endoftext|>


<commit_before>$(document).ready(function () {

	/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
	/* # Variables globales */
	/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
	lastNumberAssigned = 0;

	pipePlayers ={ "actions" : [
			{
				"kind" : "drinks",
				"prepare" : [],
				"price" : []
			}
		]
	}
	pipePlayers = {};

	/* # Initialisation de la partie */
	gameInit();

	/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
	/* # Gestionnaires d'événements */
	/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

	/* # Rejoindre une partie */
	$( "#formGameJoin" ).submit(function( event ) {
	  event.preventDefault();

	  /* # le joueur rejoin la partie */
	  var name = $('#name').val();
	  gameRejoin(name);

	  /* # liste de joueur */
	  getPlayers();

	});

	/* # Ajouter une recette dans le panier du joueur */
	$( "#formproduction" ).submit(function( event ) {
	  event.preventDefault();

	  var recette = $('#recettadd').val();
	  var prixu = $('#prixunitaire').text()
	  var quantite = parseInt($('#quantity').val());
	  var prixvente = parseFloat($('#prixvente').val());

	  if(Number.isInteger(quantite)){
	  	addPlayerPipe(recette,prixu,quantite,prixvente);
	  }

	});

	/* # raffraichir les données */
	$('#btnRefreshGameInfo').click(function() {
		getMetrology();
	})

	/* # Choix d'une recette */
	if($('#recettadd') != undefined){
		$('#recettadd').change(function() {
			getRepiceByName($(this).val())
		})
	}

	/* # maj données de la liste du joueur */
	$('#btnaddrecette').click(function() {
		valAction();
	})

	/* # maj actions du joueur */
	$('#valAction').click(function() {
		valAction();
	})

	/* # supprimer une recette dans le pipe */
	callbackDelPlayerPipe()

	/* # Mise à jour du timstamp */
	setTimeout(function() {
	      getMetrology ();
	}, 6000);

	/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
	/* # Les fonctions */
	/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

	var rand = function() {
	    return Math.random().toString(36).substr(2); // remove `0.`
	};

	var token = function() {
	    return rand() + rand(); // to make it longer
	};

	/**
	*
	*/
	function addPlayerPipe(recette,prixu,quantite,prixvente) {
		$.ajax({
			url: "/recipe/"+recette,
			type: "GET",
			contentType: 'application/json',
			success: function(result){
				var token = lastNumberAssigned++;
				var elemTr = $('

');

				elemTr.append($('	').html(result.recipe[0].rec_nom));
				elemTr.append($('	').html(prixu));
				elemTr.append($('	').html(prixvente));
				elemTr.append($('	').html(quantite));
				elemTr.append($('	').html(quantite*prixu));
				elemTr.append($('	').html(quantite*prixvente));
				elemTr.append($('	').html($('')));
				$('#playerpipe').append(elemTr);

				/* # Event : supprimer une recette dans le pipe */
				callbackDelPlayerPipe()

				/* # Ajout dans la liste pipePlayers */
				var tmp1 = {};
				var tmp2 = {};
				tmp1[recette] = quantite;
				tmp2[recette] = prixvente;

				pipePlayers.prepare.push(tmp1);
				pipePlayers.price.push(tmp2);

				console.log(pipePlayers)
	    	}
		});

	}

	/**
	*
	*/
	function getMetrology () {
		$.ajax({
			url: "/metrology",
			type: "GET",
			contentType: 'application/json',
			success: function(result){

				$('#timer').html(result.timestamp);
				$.each(result.weather, function( index, value ) {
					if(value['dfn'] == 0)
						$('#weatherToday').html(value['weather']);
	        		else
	        			$('#weatherTomorrow').html(value['weather']);
				});
	    	}
		});
	}

	/**
	*
	*/
	function getPlayers() {
		$.ajax({
			url: "/players",
			type: "GET",
			contentType: 'application/json',
			success: function(result){

				if(result.players.length > 0){
					var item = $('

');

					$('#playerList').html("");
					for (var i = 0; i < result.players.length; i++) {
						item.append($('
'+ result.players[i].pl_pseudo +'
'))
					};
					$('#playerList').append(item);
				}else{
					$('#playerList').html("Liste vide :(");
				}
	    	}
		});
	}

	function getRepices() {
		$.ajax({
			url: "/recipes",
			type: "GET",
			contentType: 'application/json',
			success: function(result){

				$.each(result.recipes, function( index, value ) {
					//console.log(value)
					$('#recettadd').append($('<option value="'+ value['rec_id'] +'">'+ value['rec_nom'] +'</option>'))
				});
	    	}
		});
	}

	function getRepiceByName(rc_id) {
		$.ajax({
			url: "/recipe/"+rc_id,
			type: "GET",
			contentType: 'application/json',
			success: function(result){

				var totalCost = 0;
				$.each(result.ingredients, function( index, value ) {
					totalCost += value['ing_prix'];
				});
				$('#prixunitaire').html(totalCost)
	    	}
		});
	}

	/**
	*
	*/
	function gameRejoin(name) {
		var data = {"name": name}
		$.ajax({
			url: "/players",
			data : JSON.stringify(data),
			type: "POST",
			contentType: 'application/json',
			success: function(result){
	        	resetFormGameJoin()
	    	}
		});
	}

	/**
	*
	*/
	function resetFormGameJoin () {
		$('#name').val("");
	}

	/**
	*
	*/
	function gameInit () {

		$('#playgamebloc').addClass("hidden");
		$('#mapbloc').removeClass("col-md-7");
		$('#mapbloc').addClass("col-md-12");

		/* # récupération de la météo */
	  	getMetrology ();

	  	/* # Liste de joueurs */
	  	getPlayers();

	  	if($('#blocSimul') != undefined)
	 		getRepices();
	}

	function callbackDelPlayerPipe () {
		/* # supprimer une recette dans le pipe */
		$('.btnSuppRecette').click(function (event) {
			var tmp  = '#'+event.target.id.split("-")[0];
			$(tmp).remove()

			$.each(pipePlayers.prepare, function( index, value ) {
				//if(index == event.target.id.split("-")[0])
				console.log(value[0])
			});

			/*jQuery.grep(pipePlayers.prepare, function(n,i) {
				console.log(n)
			  return n == event.target.id.split("-")[0];
			});
			console.log(pipePlayers)*/

		})
	}

	/**
	*
	*/
	$("#valAction").on("click",function(){
      $.ajax("/order",{
      	url: "/actions/<name>",
        method: 'POST',
        contentType: 'application/json',
        pipePlayers : JSON.stringify(pipePlayers),
        success : function(pipePlayers){
        	console.log('OK')
        }
      })
      })

	/**
	*
	*/
	function sendAction() {
		$.ajax({
			url: "/actions/<name>",
			pipePlayers : JSON.stringify(pipePlayers),
			type: "POST",
			contentType: 'application/json',
			success: function(pipePlayers){
				console.log('OK')
	    	}
		});
	}

})
<commit_msg>interface graphique 2<commit_after>$(document).ready(function () {

	/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
	/* # Variables globales */
	/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
	lastNumberAssigned = 0;

	pipePlayers ={ "actions" : [
			{
				"kind" : "drinks",
				"prepare" : [],
				"price" : []
			}
		]
	}
	pipePlayers = {};

	/* # Initialisation de la partie */
	gameInit();

	/* # Mise à jour du timstamp */
	setTimeout(getMetrology, 1000);

	/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
	/* # Gestionnaires d'événements */
	/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

	/* # Rejoindre une partie */
	$( "#formGameJoin" ).submit(function( event ) {
	  event.preventDefault();

	  /* # le joueur rejoin la partie */
	  var name = $('#name').val();
	  gameRejoin(name);

	  /* # liste de joueur */
	  getPlayers();

	});

	/* # Ajouter une recette dans le panier du joueur */
	$( "#formproduction" ).submit(function( event ) {
	  event.preventDefault();

	  var recette = $('#recettadd').val();
	  var prixu = $('#prixunitaire').text()
	  var quantite = parseInt($('#quantity').val());
	  var prixvente = parseFloat($('#prixvente').val());

	  if(Number.isInteger(quantite)){
	  	addPlayerPipe(recette,prixu,quantite,prixvente);
	  }

	});

	/* # raffraichir les données */
	$('#btnRefreshGameInfo').click(function() {
		getMetrology();
	})

	/* # Choix d'une recette */
	if($('#recettadd') != undefined){
		$('#recettadd').change(function() {
			getRepiceByName($(this).val())
		})
	}

	/* # maj données de la liste du joueur */
	$('#btnaddrecette').click(function() {
		valAction();
	})

	/* # maj actions du joueur */
	$('#valAction').click(function() {
		valAction();
	})

	/* # supprimer une recette dans le pipe */
	callbackDelPlayerPipe()

	/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
	/* # Les fonctions */
	/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

	var rand = function() {
	    return Math.random().toString(36).substr(2); // remove `0.`
	};

	var token = function() {
	    return rand() + rand(); // to make it longer
	};

	/**
	*
	*/
	function addPlayerPipe(recette,prixu,quantite,prixvente) {
		$.ajax({
			url: "/recipe/"+recette,
			type: "GET",
			contentType: 'application/json',
			success: function(result){
				var token = lastNumberAssigned++;
				var elemTr = $('

');

				elemTr.append($('	').html(result.recipe[0].rec_nom));
				elemTr.append($('	').html(prixu));
				elemTr.append($('	').html(prixvente));
				elemTr.append($('	').html(quantite));
				elemTr.append($('	').html(quantite*prixu));
				elemTr.append($('	').html(quantite*prixvente));
				elemTr.append($('	').html($('')));
				$('#playerpipe').append(elemTr);

				/* # Event : supprimer une recette dans le pipe */
				callbackDelPlayerPipe()

				/* # Ajout dans la liste pipePlayers */
				var tmp1 = {};
				var tmp2 = {};
				tmp1[recette] = quantite;
				tmp2[recette] = prixvente;

				pipePlayers.prepare.push(tmp1);
				pipePlayers.price.push(tmp2);

				console.log(pipePlayers)
	    	}
		});

	}

	/**
	*
	*/
	function getMetrology () {
		$.ajax({
			url: "/metrology",
			type: "GET",
			contentType: 'application/json',
			success: function(result){

				$('#timer').html(result.timestamp);
				$.each(result.weather, function( index, value ) {
					if(value['dfn'] == 0)
						$('#weatherToday').html(value['weather']);
	        		else
	        			$('#weatherTomorrow').html(value['weather']);
				});
	    	}
		});
	}

	/**
	*
	*/
	function getPlayers() {
		$.ajax({
			url: "/players",
			type: "GET",
			contentType: 'application/json',
			success: function(result){

				if(result.players.length > 0){
					var item = $('

');

					$('#playerList').html("");
					for (var i = 0; i < result.players.length; i++) {
						item.append($('
'+ result.players[i].pl_pseudo +'
'))
					};
					$('#playerList').append(item);
				}else{
					$('#playerList').html("Liste vide :(");
				}
	    	}
		});
	}

	function getRepices() {
		$.ajax({
			url: "/recipes",
			type: "GET",
			contentType: 'application/json',
			success: function(result){

				$.each(result.recipes, function( index, value ) {
					//console.log(value)
					$('#recettadd').append($('<option value="'+ value['rec_id'] +'">'+ value['rec_nom'] +'</option>'))
				});
	    	}
		});
	}

	function getRepiceByName(rc_id) {
		$.ajax({
			url: "/recipe/"+rc_id,
			type: "GET",
			contentType: 'application/json',
			success: function(result){

				var totalCost = 0;
				$.each(result.ingredients, function( index, value ) {
					totalCost += value['ing_prix'];
				});
				$('#prixunitaire').html(totalCost)
	    	}
		});
	}

	/**
	*
	*/
	function gameRejoin(name) {
		var data = {"name": name}
		$.ajax({
			url: "/players",
			data : JSON.stringify(data),
			type: "POST",
			contentType: 'application/json',
			success: function(result){
	        	resetFormGameJoin()
	    	}
		});
	}

	/**
	*
	*/
	function resetFormGameJoin () {
		$('#name').val("");
	}

	/**
	*
	*/
	function gameInit () {

		$('#playgamebloc').addClass("hidden");
		$('#mapbloc').removeClass("col-md-7");
		$('#mapbloc').addClass("col-md-12");

		/* # récupération de la météo */
	  	getMetrology ();

	  	/* # Liste de joueurs */
	  	getPlayers();

	  	if($('#blocSimul') != undefined)
	 		getRepices();
	}

	function callbackDelPlayerPipe () {
		/* # supprimer une recette dans le pipe */
		$('.btnSuppRecette').click(function (event) {
			var tmp  = '#'+event.target.id.split("-")[0];
			$(tmp).remove()

			$.each(pipePlayers.prepare, function( index, value ) {
				//if(index == event.target.id.split("-")[0])
				console.log(value[0])
			});

			/*jQuery.grep(pipePlayers.prepare, function(n,i) {
				console.log(n)
			  return n == event.target.id.split("-")[0];
			});
			console.log(pipePlayers)*/

		})
	}

	/**
	*
	*/
	$("#valAction").on("click",function(){
      $.ajax("/order",{
      	url: "/actions/<name>",
        method: 'POST',
        contentType: 'application/json',
        pipePlayers : JSON.stringify(pipePlayers),
        success : function(pipePlayers){
        	console.log('OK')
        }
      })
      })

	/**
	*
	*/
	function sendAction() {
		$.ajax({
			url: "/actions/<name>",
			pipePlayers : JSON.stringify(pipePlayers),
			type: "POST",
			contentType: 'application/json',
			success: function(pipePlayers){
				console.log('OK')
	    	}
		});
	}

})
<|endoftext|>


<commit_before>/*jshint laxcomma: true, smarttabs: true, node: true*/
'use strict';
/**
 * Default querystring parameter validator for API Endpoints
 * @module tastypie/lib/resource/validator/querystring
 * @author Eric Satterwhite
 * @since 0.0.1
 * @requires joi
 */

var joi = require( 'joi' );

module.exports = joi.object({
	/**
	 * @readonly
	 * @memberof module:tastypie/lib/resource/validator/querystring
	 * @property {Number} limit Limits the number for results per page of data. Default is `25`
	 **/
	limit:joi.number().min(0).default(25).description("the number of records to return"),
	/**
	 * @readonly
	 * @memberof module:tastypie/lib/resource/validator/querystring
	 * @property {Number} offset starting page number for listing endpoints Default is `0`
	 **/
	offset:joi.number().min(0).default(0).description("the starting page number"),
	/**
     * @readonly
     * @memberof module:tastypie/lib/resource/validator/querystring
     * @property {String}  format ad hoc serialization formats. Allows `json`, `xml`, `jsonp`
     **/
	format:joi.string().alphanum().allow('json','xml','jsonp'),
	/**
     * @readonly
     * @memberof module:tastypie/lib/resource/validator/querystring
     * @property {String}  callback Used for jsonp callback methods
	**/
	callback:joi.string().alphanum().description('query parameter used to force a jsonp response'),

	/**
     * @readonly
     * @memberof module:tastypie/lib/resource/validator/querystring
     * @property {String}  order used to sort collections of resources
     **/
	order: joi.string().optional().description('name of a field to sort the results by')
});
<commit_msg>fixup the ordering validator to match the implementation<commit_after>/*jshint laxcomma: true, smarttabs: true, node: true*/
'use strict';
/**
 * Default querystring parameter validator for API Endpoints
 * @module tastypie/lib/resource/validator/querystring
 * @author Eric Satterwhite
 * @since 0.0.1
 * @requires joi
 */

var joi = require( 'joi' );

module.exports = joi.object({
	/**
	 * @readonly
	 * @memberof module:tastypie/lib/resource/validator/querystring
	 * @property {Number} limit Limits the number for results per page of data. Default is `25`
	 **/
	limit:joi.number().min(0).default(25).description("the number of records to return"),
	/**
	 * @readonly
	 * @memberof module:tastypie/lib/resource/validator/querystring
	 * @property {Number} offset starting page number for listing endpoints Default is `0`
	 **/
	offset:joi.number().min(0).default(0).description("the starting page number"),
	/**
	 * @readonly
	 * @memberof module:tastypie/lib/resource/validator/querystring
	 * @property {String}  format ad hoc serialization formats. Allows `json`, `xml`, `jsonp`
	 **/
	format:joi.string().alphanum().allow('json','xml','jsonp'),
	/**
	 * @readonly
	 * @memberof module:tastypie/lib/resource/validator/querystring
	 * @property {String}  callback Used for jsonp callback methods
	**/
	callback:joi.string().alphanum().description('query parameter used to force a jsonp response'),

	/**
	 * @readonly
	 * @memberof module:tastypie/lib/resource/validator/querystring
	 * @property {String}  order used to sort collections of resources
	 **/
	orderby: joi.alternatives().try(
		joi.string().optional().description('name of a field to sort the results by')
		,joi.array(  ).items( joi.string() ).optional().description('name of a field to sort the results by')
	)
});
<|endoftext|>


<commit_before>import { updateApp } from "./update-app";

import {
    DEMO_INFORMATION,
    UNWEIGHTED_DEMO_PATH,
    WEIGHTED_DEMO_PATH,
    SCHADE_INPUT_PATH,
    SCHADE_OUTPUT_PATH,
    WEIGHTED_DEMO_NAME,
    UNWEIGHTED_DEMO_NAME,
    SCHADE_INPUT_NAME,
    SCHADE_OUTPUT_NAME,
} from "./constants";
import { grnState } from "./grnstate";

const demoFiles = [UNWEIGHTED_DEMO_PATH, WEIGHTED_DEMO_PATH, SCHADE_INPUT_PATH, SCHADE_OUTPUT_PATH];

const submittedFilename = $upload => {
    let path = $upload.val();
    let fakePathCheck = path.search("\\\\") + 1;

    while (fakePathCheck) {
        path = path.substring(fakePathCheck);
        fakePathCheck = path.search("\\\\") + 1;
    }

    return path;
};

const createFileForm = $upload => {
    const formData = new FormData();
    formData.append("file", $upload[0].files[0]);
    return formData;
};

const uploadEpilogue = event => {
    if (window.ga) {
        window.ga("send", "pageview", {
            page: "/GRNsight/upload",
            sessionControl: "start"
        });
    }

    $("a.upload > input[type=file]").val("");
    event.preventDefault();
};
const disableUpload = state => {
    $(".upload").attr("disabled", state);
    $(".upload-sif").attr("disabled", state);
    $(".upload-graphml").attr("disabled", state);
};

const uploadHandler = (uploader) => {
    return function (event) { // Must be `function` due to use of `this`.
        const $upload = $(this);
        const filename = submittedFilename($upload); // TODO: remove before master release (beta@4.0.6)
        if ($upload[0].files[0].size < 2000000) {
            // disable upload button to prevent multiple uploads
            disableUpload(true);
            const formData = createFileForm($upload);
            uploader(filename, formData);
            uploadEpilogue(event);
        } else {
            let errorString = "The file uploaded is too large. Please try again with a file smaller than 1 MB.";
            $("#error").html(errorString);
            $("#errorModal").modal("show");
        }
    };
};

const workbookErrorDisplayer = xhr => {
    // re-enable upload button
    disableUpload(false);
    // Deleted status, error for argument because it was never used
    const err = JSON.parse(xhr.responseText);
    let errorString = "Your graph failed to load.

";

    if (!err.errors) { // will be falsy if an error was thrown before the workbook was generated
        errorString += err;
    } else {
        errorString = err.errors.reduce(
            (currentErrorString, currentError) =>
                `${currentErrorString}${currentError.possibleCause} ${currentError.suggestedFix}<br><br>`,

            errorString
        );
    }

    $("#error").html(errorString);
    $("#errorModal").modal("show");
};

let reloader = () => { };

const returnUploadRoute = filename => {
    if (demoFiles.indexOf(filename) !== -1) {
        console.log(filename)
        return filename;
    } else if (filename.includes(".xlsx")) {
        return "upload";
    } else if (filename.includes(".sif")) {
        return "upload-sif";
    } else if (filename.includes(".graphml")) {
        return "upload-graphml";
    // } else if (filename.includes("Custom Workbook:")) {
    //     return filename
    }
};

export const setupLoadAndImportHandlers = grnState => {
    const loadGrn = (name, formData, ) => {
        const uploadRoute = returnUploadRoute(name);
        const fullUrl = [ $(".service-root").val(), uploadRoute ].join("/");
        // The presence of formData is taken to indicate a POST.
        console.log(fullUrl)
        (formData ?
            $.ajax({
                url: fullUrl,
                data: formData,
                processData: false,
                contentType: false,
                type: "POST",
                crossDomain: true
            }) :
            $.getJSON(fullUrl)
            ).done((workbook, textStatus, jqXhr) => {
                grnState.name = name || jqXhr.getResponseHeader("X-GRNsight-Filename");
                if (demoFiles.indexOf(name) > -1) {
                    switch (name) {
                    case WEIGHTED_DEMO_PATH:
                        grnState.name = WEIGHTED_DEMO_NAME;
                        break;
                    case UNWEIGHTED_DEMO_PATH:
                        grnState.name = UNWEIGHTED_DEMO_NAME;
                        break;
                    case SCHADE_INPUT_PATH:
                        grnState.name = SCHADE_INPUT_NAME;
                        break;
                    case SCHADE_OUTPUT_PATH:
                        grnState.name = SCHADE_OUTPUT_NAME;
                    }
                }
                grnState.workbook = workbook;
                if (uploadRoute !== "upload") {
                    grnState.annotateLinks();
                }
                reloader = () => loadGrn(name, formData);
                // re-enable upload button
                disableUpload(false);
                updateApp(grnState);
                // displayStatistics(workbook);

            }).error(workbookErrorDisplayer);
    };
    /*
     * Thanks to http://stackoverflow.com/questions/6974684/how-to-send-formdata-objects-with-ajax-requests-in-jquery
     * for helping to resolve this.
     */

    // $(".upload").change(uploadHandler(loadGrn));
    $("body").on("change", ".upload", uploadHandler(loadGrn));
    const loadDemo = (url, value) => {
        $("#demoSourceDropdown option[value='" + value.substring(1) + "']").prop("selected", true);
        loadGrn(url);
        reloader = () => loadGrn(url);

        $("a.upload > input[type=file]").val("");
    };

    const initializeDemoFile = (demoClass, demoPath, demoName) => {
        // Deleted parameter `event`
        console.log(demoClass);
        $(demoClass).on("click", () => {
            loadDemo(demoPath, demoClass, demoName);
        });

        $("#demoSourceDropdown").on("change", () => {
            loadDemo(demoPath, demoClass, demoName);
        });
    };

    DEMO_INFORMATION.forEach(demoInfo => initializeDemoFile.apply(null, demoInfo));

    $("body").on("click", ".reload", function () {
        // Deleted `event` parameter but need `function` because of `this`.
        if (!$(this).parent().hasClass("disabled")) {
            if ($.isFunction(reloader)) {
                reloader();
            }
        }
    });
};

export const createAndLoadCustomWorkbook = (response, grnState) => {
    const createCustomWorkbook = () => {
        let genes = []
        let genesByIndex = {}
        let links = []
        let positiveWeights = []
        let i = 0
        for (let gene in grnState.customWorkbook.genes){
            genes.push({name : grnState.customWorkbook.genes[gene]});
            genesByIndex[gene] = i;
            i++;
        }
        console.log(genesByIndex)
        console.log(genes)
        console.log(grnState.customWorkbook.genes)
        for (let regulator in grnState.customWorkbook.links) {
            for (let target of grnState.customWorkbook.links[regulator]){
                console.log("regulator: ",regulator, ", ",  genesByIndex[regulator])
                console.log("target", target, ", ",
                genesByIndex[target]
            )
                links.push({
                    source: genesByIndex[regulator],
                    target: genesByIndex[target],
                    value:1,
                    type:"arrowhead",
                    stroke: "black"
                });
                positiveWeights.push(1);
            }
        }
        return  {
            genes,
            links,
            errors: [],
            warnings: [],
            positiveWeights,
            negativeWeights: [],
            sheetType: "unweighted",
            network: {
                genes,
                links,
                errors: [],
                warnings: [],
                positiveWeights,
            },
            meta: {
                data: {
                    species: "Saccharomyces cerevisiae",
                    taxon_id: 559292
                }
            },
            test: {
            },
            expression: {
            }
        };
    }

    grnState.customWorkbook.links = response.regulatoryConnections;
    let workbook = createCustomWorkbook();
    let genesAmount = Object.keys(grnState.customWorkbook.genes).length;
    let edgesAmount = Object.keys(grnState.customWorkbook.links).length;
    grnState.workbook = workbook;
    grnState.newWorkbook = true;
    grnState.name = `Custom Workbook: UnweightedGRN(${genesAmount} genes, ${edgesAmount} edges)`;
    updateApp(grnState);

    reloader = () => {
        createCustomWorkbook();
        updateApp(grnState);
    }
}
<commit_msg>small changes<commit_after>import { updateApp } from "./update-app";

import {
    DEMO_INFORMATION,
    UNWEIGHTED_DEMO_PATH,
    WEIGHTED_DEMO_PATH,
    SCHADE_INPUT_PATH,
    SCHADE_OUTPUT_PATH,
    WEIGHTED_DEMO_NAME,
    UNWEIGHTED_DEMO_NAME,
    SCHADE_INPUT_NAME,
    SCHADE_OUTPUT_NAME,
} from "./constants";
import { grnState } from "./grnstate";

const demoFiles = [UNWEIGHTED_DEMO_PATH, WEIGHTED_DEMO_PATH, SCHADE_INPUT_PATH, SCHADE_OUTPUT_PATH];

const submittedFilename = $upload => {
    let path = $upload.val();
    let fakePathCheck = path.search("\\\\") + 1;

    while (fakePathCheck) {
        path = path.substring(fakePathCheck);
        fakePathCheck = path.search("\\\\") + 1;
    }

    return path;
};

const createFileForm = $upload => {
    const formData = new FormData();
    formData.append("file", $upload[0].files[0]);
    return formData;
};

const uploadEpilogue = event => {
    if (window.ga) {
        window.ga("send", "pageview", {
            page: "/GRNsight/upload",
            sessionControl: "start"
        });
    }

    $("a.upload > input[type=file]").val("");
    event.preventDefault();
};
const disableUpload = state => {
    $(".upload").attr("disabled", state);
    $(".upload-sif").attr("disabled", state);
    $(".upload-graphml").attr("disabled", state);
};

const uploadHandler = (uploader) => {
    return function (event) { // Must be `function` due to use of `this`.
        const $upload = $(this);
        const filename = submittedFilename($upload); // TODO: remove before master release (beta@4.0.6)
        if ($upload[0].files[0].size < 2000000) {
            // disable upload button to prevent multiple uploads
            disableUpload(true);
            const formData = createFileForm($upload);
            uploader(filename, formData);
            uploadEpilogue(event);
        } else {
            let errorString = "The file uploaded is too large. Please try again with a file smaller than 1 MB.";
            $("#error").html(errorString);
            $("#errorModal").modal("show");
        }
    };
};

const workbookErrorDisplayer = xhr => {
    // re-enable upload button
    disableUpload(false);
    // Deleted status, error for argument because it was never used
    const err = JSON.parse(xhr.responseText);
    let errorString = "Your graph failed to load.

";

    if (!err.errors) { // will be falsy if an error was thrown before the workbook was generated
        errorString += err;
    } else {
        errorString = err.errors.reduce(
            (currentErrorString, currentError) =>
                `${currentErrorString}${currentError.possibleCause} ${currentError.suggestedFix}<br><br>`,

            errorString
        );
    }

    $("#error").html(errorString);
    $("#errorModal").modal("show");
};

let reloader = () => { };

const returnUploadRoute = filename => {
    if (demoFiles.indexOf(filename) !== -1) {
        console.log(filename)
        return filename;
    } else if (filename.includes(".xlsx")) {
        return "upload";
    } else if (filename.includes(".sif")) {
        return "upload-sif";
    } else if (filename.includes(".graphml")) {
        return "upload-graphml";
    // } else if (filename.includes("Custom Workbook:")) {
    //     return filename
    }
};

export const setupLoadAndImportHandlers = grnState => {
    const loadGrn = (name, formData, customWorkbook) => {
        const uploadRoute = returnUploadRoute(name);
        const fullUrl = [ $(".service-root").val(), uploadRoute ].join("/");
        // The presence of formData is taken to indicate a POST.
        console.log(fullUrl)
        (formData ?
            $.ajax({
                url: fullUrl,
                data: formData,
                processData: false,
                contentType: false,
                type: "POST",
                crossDomain: true
            }) :
            $.getJSON(fullUrl)
            ).done((workbook, textStatus, jqXhr) => {
                grnState.name = name || jqXhr.getResponseHeader("X-GRNsight-Filename");
                if (demoFiles.indexOf(name) > -1) {
                    switch (name) {
                    case WEIGHTED_DEMO_PATH:
                        grnState.name = WEIGHTED_DEMO_NAME;
                        break;
                    case UNWEIGHTED_DEMO_PATH:
                        grnState.name = UNWEIGHTED_DEMO_NAME;
                        break;
                    case SCHADE_INPUT_PATH:
                        grnState.name = SCHADE_INPUT_NAME;
                        break;
                    case SCHADE_OUTPUT_PATH:
                        grnState.name = SCHADE_OUTPUT_NAME;
                    }
                } else if (customWorkbook !== null) {
                    // case if it's a custom workbook
                }
                grnState.workbook = workbook;
                if (uploadRoute !== "upload") {
                    grnState.annotateLinks();
                }
                reloader = () => loadGrn(name, formData);
                // re-enable upload button
                disableUpload(false);
                updateApp(grnState);
                // displayStatistics(workbook);

            }).error(workbookErrorDisplayer);
    };
    /*
     * Thanks to http://stackoverflow.com/questions/6974684/how-to-send-formdata-objects-with-ajax-requests-in-jquery
     * for helping to resolve this.
     */

    // $(".upload").change(uploadHandler(loadGrn));
    $("body").on("change", ".upload", uploadHandler(loadGrn));
    const loadDemo = (url, value) => {
        $("#demoSourceDropdown option[value='" + value.substring(1) + "']").prop("selected", true);
        loadGrn(url);
        reloader = () => loadGrn(url);

        $("a.upload > input[type=file]").val("");
    };

    const initializeDemoFile = (demoClass, demoPath, demoName) => {
        // Deleted parameter `event`
        console.log(demoClass);
        $(demoClass).on("click", () => {
            loadDemo(demoPath, demoClass, demoName);
        });

        $("#demoSourceDropdown").on("change", () => {
            loadDemo(demoPath, demoClass, demoName);
        });
    };

    DEMO_INFORMATION.forEach(demoInfo => initializeDemoFile.apply(null, demoInfo));

    $("body").on("click", ".reload", function () {
        // Deleted `event` parameter but need `function` because of `this`.
        if (!$(this).parent().hasClass("disabled")) {
            if ($.isFunction(reloader)) {
                reloader();
            }
        }
    });
};

export const createAndLoadCustomWorkbook = (response, grnState) => {
    const createCustomWorkbook = () => {
        let genes = []
        let genesByIndex = {}
        let links = []
        let positiveWeights = []
        let i = 0
        for (let gene in grnState.customWorkbook.genes){
            genes.push({name : grnState.customWorkbook.genes[gene]});
            genesByIndex[gene] = i;
            i++;
        }
        console.log(genesByIndex)
        console.log(genes)
        console.log(grnState.customWorkbook.genes)
        for (let regulator in grnState.customWorkbook.links) {
            for (let target of grnState.customWorkbook.links[regulator]){
                console.log("regulator: ",regulator, ", ",  genesByIndex[regulator])
                console.log("target", target, ", ",
                genesByIndex[target]
            )
                links.push({
                    source: genesByIndex[regulator],
                    target: genesByIndex[target],
                    value:1,
                    type:"arrowhead",
                    stroke: "black"
                });
                positiveWeights.push(1);
            }
        }
        return  {
            genes,
            links,
            errors: [],
            warnings: [],
            positiveWeights,
            negativeWeights: [],
            sheetType: "unweighted",
            network: {
                genes,
                links,
                errors: [],
                warnings: [],
                positiveWeights,
            },
            meta: {
                data: {
                    species: "Saccharomyces cerevisiae",
                    taxon_id: 559292
                }
            },
            test: {
            },
            expression: {
            }
        };
    }

    grnState.customWorkbook.links = response.regulatoryConnections;
    let workbook = createCustomWorkbook();
    let genesAmount = Object.keys(grnState.customWorkbook.genes).length;
    let edgesAmount = Object.keys(grnState.customWorkbook.links).length;
    grnState.workbook = workbook;
    grnState.newWorkbook = true;
    grnState.name = `Custom Workbook: UnweightedGRN(${genesAmount} genes, ${edgesAmount} edges)`;
    updateApp(grnState);

    reloader = () => {
        createCustomWorkbook();
        updateApp(grnState);
    }
}
<|endoftext|>


<commit_before>var logger = require( 'pelias-logger' ).get( 'openaddresses' );
var peliasConfig = require( 'pelias-config' ).generate();
var adminLookupStream = require('./streams/adminLookupStream');
var deduplicatorStream = require('./streams/deduplicatorStream');
var recordStream = require('./streams/recordStream');
var model = require( 'pelias-model' );
var peliasDbclient = require( 'pelias-dbclient' );
var isUSorCAHouseNumberZero = require( './streams/isUSorCAHouseNumberZero' );

/**
 * Import all OpenAddresses CSV files in a directory into Pelias elasticsearch.
 *
 * @param {array of string} files An array of the absolute file-paths to import.
 * @param {object} opts Options to configure the import. Supports the following
 *    keys:
 *
 *      deduplicate: Pass address object through `address-deduplicator-stream`
 *        to perform deduplication. See the documentation:
 *        https://github.com/pelias/address-deduplicator-stream
 *
 *      adminValues: Add admin values to each address object (since
 *        OpenAddresses doesn't contain any) using `admin-lookup`. See the
 *        documentation: https://github.com/pelias/admin-lookup
 */
function createFullImportPipeline( files, opts, finalStream ){
  logger.info( 'Importing %s files.', files.length );

  finalStream = finalStream || peliasDbclient();

  recordStream.create(files, opts.dirPath)
    .pipe(deduplicatorStream.create(opts.deduplicate))
    .pipe(adminLookupStream.create(opts.adminValues, peliasConfig))
    .pipe(isUSorCAHouseNumberZero.create())
    .pipe(model.createDocumentMapperStream())
    .pipe(finalStream);
}

module.exports = {
  create: createFullImportPipeline
};
<commit_msg>added `removeLeadingZeroes` to import pipeline<commit_after>var logger = require( 'pelias-logger' ).get( 'openaddresses' );
var peliasConfig = require( 'pelias-config' ).generate();
var adminLookupStream = require('./streams/adminLookupStream');
var deduplicatorStream = require('./streams/deduplicatorStream');
var recordStream = require('./streams/recordStream');
var model = require( 'pelias-model' );
var peliasDbclient = require( 'pelias-dbclient' );
var isUSorCAHouseNumberZero = require( './streams/isUSorCAHouseNumberZero' );
var removeLeadingZeroes = require('./streams/removeLeadingZeroes');

/**
 * Import all OpenAddresses CSV files in a directory into Pelias elasticsearch.
 *
 * @param {array of string} files An array of the absolute file-paths to import.
 * @param {object} opts Options to configure the import. Supports the following
 *    keys:
 *
 *      deduplicate: Pass address object through `address-deduplicator-stream`
 *        to perform deduplication. See the documentation:
 *        https://github.com/pelias/address-deduplicator-stream
 *
 *      adminValues: Add admin values to each address object (since
 *        OpenAddresses doesn't contain any) using `admin-lookup`. See the
 *        documentation: https://github.com/pelias/admin-lookup
 */
function createFullImportPipeline( files, opts, finalStream ){
  logger.info( 'Importing %s files.', files.length );

  finalStream = finalStream || peliasDbclient();

  recordStream.create(files, opts.dirPath)
    .pipe(deduplicatorStream.create(opts.deduplicate))
    .pipe(adminLookupStream.create(opts.adminValues, peliasConfig))
    .pipe(isUSorCAHouseNumberZero.create())
    .pipe(removeLeadingZeroes.create())
    .pipe(model.createDocumentMapperStream())
    .pipe(finalStream);
}

module.exports = {
  create: createFullImportPipeline
};
<|endoftext|>


<commit_before><commit_msg>affichage de liste de recettes - test 4<commit_after><|endoftext|>


<commit_before>/*
 * include-folder
 * https://github.com/parroit/include-folder
 *
 * Copyright (c) 2013 parroit
 * Licensed under the MIT license.
 */

'use strict';

var _ = require("lodash"),
    fs = require("fs");

function includeFolder(folderName) {
    if ( folderName.charAt(folderName.length-1) != "/")
        folderName += "/";
    var source = includeFolder._testHook.buildSource(folderName);

    return (new Function("require", "__dirname", source))(require, folderName);

}

function normalize(name) {
    var chars = [];
    var nextUpper = false;
    var i = 0,
        l = name.length;

    for (; i < l; i++) {
        var c = name.charAt(i);
        if (/\w/.test(c)) {
            chars.push(nextUpper ? c.toUpperCase() : c);
            nextUpper = false;
        } else {
            nextUpper = true;
        }
    }
    name = chars.join("");
    return name;
}

function stripExtension(fileName) {
    return fileName.replace(/\.[^/.]+$/, "");
}

function buildSource(folderName) {
    var files = fs.readdirSync(folderName);
    var allProps = {};
    var fields = _.map(files, function (fileName) {
        var name = normalize(stripExtension(fileName));

        if (name in allProps) {
            allProps[name]++;
            name += "_" + allProps[name];
        } else {
            allProps[name] = 0;
        }

        return 'self.' + name + ' = fs.readFileSync(__dirname + "' + fileName + '","utf8");'
    });

    return "var self={}," +
        "fs = require('fs');\n" +
        fields.join("\n") +
        "\nreturn self";
}

includeFolder._testHook = {
    buildSource: buildSource
};

module.exports = includeFolder;
<commit_msg>improve climate<commit_after>/*
 * include-folder
 * https://github.com/parroit/include-folder
 *
 * Copyright (c) 2013 parroit
 * Licensed under the MIT license.
 */

'use strict';

var _ = require("lodash"),
    fs = require("fs");

function includeFolder(folderName) {
    if (folderName.charAt(folderName.length - 1) !== "/") {
        folderName += "/";
    }
    var source = includeFolder._testHook.buildSource(folderName);

    return (new Function("require", "__dirname", source))(require, folderName);

}

function normalize(name) {
    var chars = [];
    var nextUpper = false;
    var i = 0,
        l = name.length;

    for (; i < l; i++) {
        var c = name.charAt(i);
        if (/\w/.test(c)) {
            chars.push(nextUpper ? c.toUpperCase() : c);
            nextUpper = false;
        } else {
            nextUpper = true;
        }
    }
    name = chars.join("");
    return name;
}

function stripExtension(fileName) {
    return fileName.replace(/\.[^/.]+$/, "");
}

function buildSource(folderName) {
    var files = fs.readdirSync(folderName);
    var allProps = {};
    var fields = _.map(files, function (fileName) {
        var name = normalize(stripExtension(fileName));

        if (name in allProps) {
            allProps[name]++;
            name += "_" + allProps[name];
        } else {
            allProps[name] = 0;
        }

        return 'self.' + name + ' = fs.readFileSync(__dirname + "' + fileName + '","utf8");';
    });

    return "var self={}," +
        "fs = require('fs');\n" +
        fields.join("\n") +
        "\nreturn self";
}

includeFolder._testHook = {
    buildSource: buildSource
};

module.exports = includeFolder;
<|endoftext|>


<commit_before>exports.autoLoader = require('./AutoLoader');

<commit_msg>Remove another spurious index.js<commit_after><|endoftext|>