<commit_before>/** @license MIT License (c) copyright 2010-2013 original author or authors */

/**
 * Licensed under the MIT License at:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * @author: Brian Cavalier
 * @author: John Hann
 */

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

module.exports = Stream;

Stream.of = of;
Stream.empty = empty;

function Stream(emitter) {
	this._emitter = emitter;
}

function of(x) {
	return new Stream(function (next, end) {
		try {
			next(x);
			end();
		} catch (e) {
			end(e);
		}

		return noop;
	});
}

function empty() {
	return new Stream(emptyEmitter);
}

var proto = Stream.prototype = {};

proto.constructor = Stream;

/**
 * Start consuming items in the stream.
 * @param {function} next called once for each item in the stream
 * @param {function?} end called once when either:
 *  1. the stream is ended, that is, when it has no more items, *or*
 *  2. when a fatal error has occurred in the stream. In this case, the error
 *     will be passed to end.
 *  In either case, neither next nor end will ever be called again.
 *  If end is not provided, and an error occurs, it will be rethrown to the host
 *  environment.
 * @returns {function} function to unsubscribe from the stream. After calling
 *  this, next and end will never be called again.
 */
proto.each = function(next, end) {
	var done, unsubscribe, self = this;

	if(typeof end !== 'function') {
		end = fatal;
	}

	async(function() {
		unsubscribe = self._emitter(safeNext, safeEnd);
	});

	function safeUnsubscribe() {
		if(done) {
			return;
		}

		done = true;

		if(typeof unsubscribe === 'function') {
			unsubscribe();
		} else {
			async(function() {
				unsubscribe();
			});
		}
	}

	function safeNext(x) {
		if(done) {
			return;
		}
		next(x);
	}

	function safeEnd(e) {
		if(done) {
			return;
		}
		done = true;
		end.apply(void 0, arguments);
	}

	return safeUnsubscribe;
};

proto.map = function(f) {
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(function(x) {
			next(f(x));
		}, end);
	});
};

proto.ap = function(stream2) {
	return this.flatMap(function(f) {
		return stream2.map(f);
	});
};

proto.flatMap = function(f) {
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(function(x) {
			f(x)._emitter(next, end);
		}, end);
	});
};

proto.flatten = function() {
	return this.flatMap(identity);
};

proto.filter = function(predicate) {
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(function(x) {
			predicate(x) && next(x);
		}, end);
	});
};

proto.merge = function(other) {
	// TODO: Should this accept an array?  a stream of streams?
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(next, end);
		other._emitter(next, end);
	});
};

proto.concat = function(other) {
	// TODO: Should this accept an array?  a stream of streams?
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(next, function(e) {
			e ? end(e) : other._emitter(next, end);
		});
	});
};

proto.tap = function(f) {
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(function(x) {
			f(x);
			next(x);
		}, end);
	});
};

proto.drop = function(m) {
	var dropped = 0;
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(function(x) {
			(dropped >= m) ? next(x) : dropped++;
		}, end);
	});
};

proto.dropWhile = function(predicate) {
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(function(x) {
			if (predicate != null) {
				if (predicate(x)) {
					return;
				}
				predicate = null;
			}
			next(x);
		}, end);
	});
};

proto.take = function(m) {
	var taken = 0;
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(function(x) {
			if (taken < m) {
				next(x);
				taken++;
			}
		}, end);
	});
};

proto.takeWhile = function(predicate) {
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(function(x) {
			if (predicate != null) {
				if(predicate(x)) {
					next(x);
				} else {
					predicate = null;
				}
			}
		}, end);
	});
};

proto.buffer = function(windower) {
	var stream = this._emitter;
	return new Stream(function(next, end) {
		var buffer;
		stream(function(x) {
			buffer = windower(next, x, buffer||[]);
		}, end);
	});
};

proto.bufferCount = function(n) {
	return this.buffer(createCountBuffer(n));
};

proto.bufferTime = function(interval) {
	return this.buffer(createTimeBuffer(interval));
};

proto.delay = function(ms) {
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(function(x) {
			setTimeout(function() {
				next(x);
			}, ms||0);
		}, end);
	});
};

proto.debounce = function(interval) {
	var nextEventTime = interval;
	var stream = this._emitter;

	return new Stream(function(next, end) {
		stream(function(x) {
			var now = Date.now();
			if(now >= nextEventTime) {
				nextEventTime = now + interval;
				next(x);
			}
		}, end);
	});
};

proto.throttle = function(interval) {
	var cachedEvent, throttled;
	var stream = this._emitter;

	return new Stream(function(next, end) {
		stream(function(x) {
			cachedEvent = x;

			if(!throttled) {
				throttled = setTimeout(function() {
					throttled = void 0;
					next(x);
				}, interval);
			}
		}, end);
	});
};

proto['catch'] = function(f) {
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(next, function(e1) {
			var error;
			if(e1 != null) {
				try {
					next(f(e1));
				} catch(e2) {
					error = e2;
				}
			}

			if(error != null) {
				end(error);
			}
		});
	});
};

proto.reduce = function(f, initial) {
	var stream = this._emitter;
	return new Stream(function(next, end) {
		var value = initial;
		stream(function(x) {
			value = f(value, x);
		}, function(e) {
			if(e == null) {
				next(value);
			}

			end(e);
		});
	});
};

proto.scan = function(f, initial) {
	return this.map(function(x) {
		return initial = f(initial, x);
	});
};

function emptyEmitter(_, end) {
	async(end);
}

function createTimeBuffer(interval) {
	var buffered;
	return function(next, x, buffer) {
		if(!buffered) {
			buffered = true;
			buffer = [x];

			setTimeout(function() {
				next(buffer.slice());
				buffered = false;
			}, interval);
		} else {
			buffer.push(x);
		}

		return buffer;
	}
}

function createCountBuffer(n) {
	return function (next, x, buffer) {
		buffer && buffer.push(x) || (buffer = [x]);

		if(buffer.length >= n) {
			next(buffer);
			buffer = void 0;
		}

		return buffer;
	};
}

function fatal(e) {
	if(e != null) {
		throw e;
	}
}

function identity(x) {
	return x;
}

function noop() {}<commit_msg>More cleaning<commit_after>/** @license MIT License (c) copyright 2010-2013 original author or authors */

/**
 * Licensed under the MIT License at:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * @author: Brian Cavalier
 * @author: John Hann
 */

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

module.exports = Stream;

Stream.of = of;
Stream.empty = empty;

function Stream(emitter) {
	this._emitter = emitter;
}

function of(x) {
	return new Stream(function (next, end) {
		try {
			next(x);
			end();
		} catch (e) {
			end(e);
		}

		return noop;
	});
}

function empty() {
	return new Stream(emptyEmitter);
}

var proto = Stream.prototype = {};

proto.constructor = Stream;

/**
 * Start consuming items in the stream.
 * @param {function} next called once for each item in the stream
 * @param {function?} end called once when either:
 *  1. the stream is ended, that is, when it has no more items, *or*
 *  2. when a fatal error has occurred in the stream. In this case, the error
 *     will be passed to end.
 *  In either case, neither next nor end will ever be called again.
 *  If end is not provided, and an error occurs, it will be rethrown to the host
 *  environment.
 * @returns {function} function to unsubscribe from the stream. After calling
 *  this, next and end will never be called again.
 */
proto.each = function(next, end) {
	var done, unsubscribe, self = this;

	if(typeof end !== 'function') {
		end = fatal;
	}

	async(function() {
		unsubscribe = self._emitter(safeNext, safeEnd);
	});

	function safeUnsubscribe() {
		if(done) {
			return;
		}

		done = true;

		if(typeof unsubscribe === 'function') {
			unsubscribe();
		} else {
			async(function() {
				unsubscribe();
			});
		}
	}

	function safeNext(x) {
		if(done) {
			return;
		}
		next(x);
	}

	function safeEnd(e) {
		if(done) {
			return;
		}
		done = true;
		end.apply(void 0, arguments);
	}

	return safeUnsubscribe;
};

proto.map = function(f) {
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(function(x) {
			next(f(x));
		}, end);
	});
};

proto.ap = function(stream2) {
	return this.flatMap(function(f) {
		return stream2.map(f);
	});
};

proto.flatMap = function(f) {
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(function(x) {
			f(x)._emitter(next, end);
		}, end);
	});
};

proto.flatten = function() {
	return this.flatMap(identity);
};

proto.filter = function(predicate) {
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(function(x) {
			predicate(x) && next(x);
		}, end);
	});
};

proto.merge = function(other) {
	// TODO: Should this accept an array?  a stream of streams?
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(next, end);
		other._emitter(next, end);
	});
};

proto.concat = function(other) {
	// TODO: Should this accept an array?  a stream of streams?
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(next, function(e) {
			e ? end(e) : other._emitter(next, end);
		});
	});
};

proto.tap = function(f) {
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(function(x) {
			f(x);
			next(x);
		}, end);
	});
};

proto.drop = function(m) {
	var dropped = 0;
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(function(x) {
			(dropped >= m) ? next(x) : dropped++;
		}, end);
	});
};

proto.dropWhile = function(predicate) {
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(function(x) {
			if (predicate != null) {
				if (predicate(x)) {
					return;
				}
				predicate = null;
			}
			next(x);
		}, end);
	});
};

proto.take = function(m) {
	var taken = 0;
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(function(x) {
			if (taken < m) {
				next(x);
				taken++;
			}
		}, end);
	});
};

proto.takeWhile = function(predicate) {
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(function(x) {
			if (predicate != null) {
				predicate(x) ? next(x) : predicate = null;
			}
		}, end);
	});
};

proto.buffer = function(windower) {
	var stream = this._emitter;
	return new Stream(function(next, end) {
		var buffer;
		stream(function(x) {
			buffer = windower(next, x, buffer||[]);
		}, end);
	});
};

proto.bufferCount = function(n) {
	return this.buffer(createCountBuffer(n));
};

proto.bufferTime = function(interval) {
	return this.buffer(createTimeBuffer(interval));
};

proto.delay = function(ms) {
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(function(x) {
			setTimeout(function() {
				next(x);
			}, ms||0);
		}, end);
	});
};

proto.debounce = function(interval) {
	var nextEventTime = interval;
	var stream = this._emitter;

	return new Stream(function(next, end) {
		stream(function(x) {
			var now = Date.now();
			if(now >= nextEventTime) {
				nextEventTime = now + interval;
				next(x);
			}
		}, end);
	});
};

proto.throttle = function(interval) {
	var cachedEvent, throttled;
	var stream = this._emitter;

	return new Stream(function(next, end) {
		stream(function(x) {
			cachedEvent = x;

			if(!throttled) {
				throttled = setTimeout(function() {
					throttled = void 0;
					next(x);
				}, interval);
			}
		}, end);
	});
};

proto['catch'] = function(f) {
	var stream = this._emitter;
	return new Stream(function(next, end) {
		stream(next, function(e1) {
			var error;
			if(e1 != null) {
				try {
					next(f(e1));
				} catch(e2) {
					error = e2;
				}
			}

			if(error != null) {
				end(error);
			}
		});
	});
};

proto.reduce = function(f, initial) {
	var stream = this._emitter;
	return new Stream(function(next, end) {
		var value = initial;
		stream(function(x) {
			value = f(value, x);
		}, function(e) {
			if(e == null) {
				next(value);
			}

			end(e);
		});
	});
};

proto.scan = function(f, initial) {
	return this.map(function(x) {
		return initial = f(initial, x);
	});
};

function emptyEmitter(_, end) {
	async(end);
}

function createTimeBuffer(interval) {
	var buffered;
	return function(next, x, buffer) {
		if(!buffered) {
			buffered = true;
			buffer = [x];

			setTimeout(function() {
				next(buffer.slice());
				buffered = false;
			}, interval);
		} else {
			buffer.push(x);
		}

		return buffer;
	}
}

function createCountBuffer(n) {
	return function (next, x, buffer) {
		buffer && buffer.push(x) || (buffer = [x]);

		if(buffer.length >= n) {
			next(buffer);
			buffer = void 0;
		}

		return buffer;
	};
}

function fatal(e) {
	if(e != null) {
		throw e;
	}
}

function identity(x) {
	return x;
}

function noop() {}<|endoftext|>


<commit_before>// Use this module when you have a form with input fields and an optional submit button.
// It supplies an Input component used for all types of form fields (e.g. text fields,
// drop-downs, etc.).

"use strict";
import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';

var _ = require('underscore');

var FormComponent = module.exports.FormComponent = React.createClass({
    formValues: {},

    // Do not call; called by React.
    getInitialState() {
        this.formValues = {};
        return {
            formErrors: {},
            isValid: true
        };
    },

    // Create a map of traversed inputs and register inputs from the children
    componentWillMount() {
        this.formValues = {};
        this.inputs = {};
        this.registerInputs(this.props.children);
    },

    // Add 'id' property to any Input elements. Make it a copy of the Input's ref. Run through all children
    // of the form, and any children of those children, recursively.
    registerInputs(children) {
        let processedChildren = React.Children.map(children, child => {
            if (child) {
                let props = {};

                if (child.ref) {
                    // Copy ref to new id property.
                    props.id = child.ref;
                    // Attach a method for the input to register itself to the form
                    props.attachToForm = this.attachToForm;
                    // Attach a method for the input to detach itself from the form
                    props.detachFromForm = this.detachFromForm;

                    props.getFormError = this.getFormError;
                    props.clrFormErrors = this.clrFormErrors;
                    props.validateDefault = this.validateDefault;
                }

                // If the current child has children, process them recursively and assign the result to the new children property
                if (child.props && child.props.children) {
                    props.children = this.registerInputs(child.props.children);
                }

                // If we made new properties, clone the child and assign the properties to the clone
                return Object.keys(props).length ? React.cloneElement(child, props) : child;
            }
            return null;

        });
        return processedChildren;
    },

    // All methods defined are bound to the component by React JS, so it is safe to use "this"
    // even though we did not bind it. Add the input component to our inputs map.
    attachToForm: function (component) {
        this.inputs[component.ref] = component;

        // We add the value from the component to our model, using the
        // name of the component as the key. This ensures that we
        // grab the initial value of the input
        this.formValues[component.ref] = component.state.value;
    },

    // Remove the input component from the inputs map
    detachFromForm: function (component) {
        delete this.inputs[component.ref];

        // We of course have to delete the model property
        // if the component is removed
        delete this.formValues[component.ref];
    },

    // Retrieves the saved value of the Input with the given 'ref' value. saveFormValue
    // must already have been called with this Input's value.
    getFormValue(ref) {
        return this.formValues[ref];
    },

    // Retrieves the saved value of the Input with the given 'ref' value, and the Input
    // value must be numeric. If the Input had no entered value at all, the empty string is
    // returned. If the Input had an entered value but it wasn't numeric, null is returned.
    // If the Input had a proper numberic value, a Javascript 'number' type is returned
    // with the entered value.
    getFormValueNumber(ref) {
        var value = this.getFormValue(ref);
        if (value) {
            var numericValue = value.match(/^\s*(\d*)\s*$/);
            if (numericValue) {
                return parseInt(numericValue[1], 10);
            }
            return null;
        }
        return '';
    },

    // Normally used after the submit button is clicked. Call this to save the value
    // from the Input with the given 'ref' value and the value itself. This does
    // NOT modify the form input values; it just saves them for later processing.
    saveFormValue(ref, value) {
        this.formValues[ref] = value;
    },

    // Call this to avoid calling 'saveFormValue' for every form item. It goes through all the
    // form items with refs (should be all of them) and saves a formValue property with the
    // corresponding value from the DOM.
    saveAllFormValues() {
        if (this.refs && Object.keys(this.refs).length) {
            Object.keys(this.refs).map(ref => {
                this.saveFormValue(ref, this.refs[ref].getValue());
            });
        }
    },

    resetAllFormValues() {
        if (this.refs && Object.keys(this.refs).length) {
            Object.keys(this.refs).map(ref => {
                this.refs[ref].resetValue();
            });
        }
        this.formValues = {};
    },

    // Get the saved form error for the Input with the given 'ref' value.
    getFormError(ref) {
        return this.state.formErrors[ref];
    },

    // Save a form error for the given Input's 'ref' value for later retrieval with getFormError.
    // The message that should be displayed to the user is passed in 'msg'.
    setFormErrors(ref, msg) {
        var formErrors = this.state.formErrors;
        formErrors[ref] = msg;
        this.setState({formErrors: formErrors});
    },

    // Clear error state from the Input with the given 'ref' value. This should be passed to
    // Input components in the 'clearError' property so that it can be called when an Input's
    // value changes.
    clrFormErrors(ref) {
        var errors = this.state.formErrors;
        errors[ref] = '';
        this.setState({formErrors: errors});
    },

    // Clear errors at multiple Inputs at the same time
    // When data entered in one Input, error messages in all related Inputs will be cleared.
    clrMultiFormErrors(refs) {
        var errors = this.state.formErrors;
        refs.forEach(function(ref){
            errors[ref] = '';
        });
        this.setState({formErrors: errors});
    },

    // clears errors form all form inputs
    clrAllFormErrors() {
        var errors = this.state.formErrors;
        if (this.refs && Object.keys(this.refs).length) {
            Object.keys(this.refs).map(ref => {
                errors[ref] = '';
            });
        }
        this.setState({formErrors: errors});
    },

    // Return true if the form's current state shows any Input errors. Return false if no
    // errors are indicated. This should be called in the render function so that the submit
    // form function will have had a chance to record any errors.
    anyFormErrors() {
        var formErrors = Object.keys(this.state.formErrors);

        if (formErrors.length) {
            return _(formErrors).any(errKey => {
                return this.state.formErrors[errKey];
            });
        }
        return false;
    },

    // Do form validation on the required fields. Each field checked must have a unique ref,
    // and the boolean 'required' field set if it's required. All the Input's values must
    // already have been collected with saveFormValue. Returns true if all required fields
    // have values, or false if any do not. It also sets any empty required Inputs error
    // to the 'Required' message so it's displayed on the next render.
    validateDefault(component) {
        if (!component.props.validations) {
            return;
        }
        let valid = true;
        var props = component.props;
        var val = this.getFormValue(component);
        val = (props.type === 'select' && val === 'none') ? null : val;
        if (props.required && !val) {
            // Required field has no value. Set error state to render
            // error, and remember to return false.
            this.setFormErrors(component, 'Required');
            valid = false;
        } else if (props.type === 'number') {
            // Validate that type="number" fields have a valid number in them
            var numVal = this.getFormValueNumber(component);
            if (numVal === null) {
                if (props.inputClassName && props.inputClassName === 'integer-only') {
                    this.setFormErrors(component, 'Non-decimal values only');
                    valid = false;
                } else if (!this.getFormValue(component).match(/^\d+\.\d+$/)) {
                    this.setFormErrors(component, 'Number only');
                    valid = false;
                }
            } else if (numVal !== '' && ((props.minVal && numVal < props.minVal) || (props.maxVal && numVal > props.maxVal))) {
                valid = false;
                if (props.minVal && props.maxVal) {
                    this.setFormErrors(component, 'The range of allowed values is ' + props.minVal + ' to ' + props.maxVal);
                } else if (props.minVal) {
                    this.setFormErrors(component, 'The minimum allowed value is ' + props.minVal);
                } else {
                    this.setFormErrors(component, 'The maximum allowed value is ' + props.maxVal);
                }
            }
        }
        component.setState({isValid: valid});
    },

    submit(e) {
        e.preventDefault(); e.stopPropagation(); // Don't run through HTML submit handler

        // Save all form values from the DOM.
        this.saveAllFormValues();

        // Start with default validation; indicate errors on form if not, then bail
        if (this.state.isValid) {
            this.props.submitHandler();
        }
    },

    render() {
        // Before rendering, copy any refs on any elements in the form to each element's id property
        var children = this.registerInputs(this.props.children);
        return (
            <form onSubmit={this.submit} className={this.props.formClassName}>
                {children}
            </form>
        );
    }
});

// Handles most form inputs, like text fields and dropdowns. The different Bootstrap styles of
// inputs can be handled through the labelClassName, groupClassName, and wrapperClassName properties.
var InputComponent = module.exports.InputComponent = React.createClass({
    propTypes: {
        type: PropTypes.string.isRequired, // Type of input
        label: PropTypes.oneOfType([ //  for input; string or another React component
            PropTypes.string,
            PropTypes.object
        ]),
        placeholder: PropTypes.string, // <input> placeholder text
        maxLength: PropTypes.string, // maxlength for labels
        error: PropTypes.string, // Error message to display below input
        labelClassName: PropTypes.string, // CSS classes to add to labels
        groupClassName: PropTypes.string, // CSS classes to add to control groups (label/input wrapper div)
        wrapperClassName: PropTypes.string, // CSS classes to add to wrapper div around inputs
        inputClassName: PropTypes.string, // CSS classes to add to input elements themselves
        rows: PropTypes.string, // Number of rows in textarea
        value: PropTypes.oneOfType([ // Value to pre-fill input with
            PropTypes.string,
            PropTypes.number
        ]),
        defaultValue: PropTypes.string, // Default value for <select>
        required: PropTypes.bool, // T to make this a required field
        clickHandler: PropTypes.func, // Called to handle button click
        submitHandler: PropTypes.func, // Called to handle submit button click
        cancelHandler: PropTypes.func, // Called to handle cancel button click
        submitBusy: PropTypes.bool, //
        onBlur: PropTypes.func,
        minVal: PropTypes.number, // Minimum value for a number formatted input
        maxVal: PropTypes.number // Maximum value for a number formatted input
    },

    getInitialState: function() {
        return {
            value: this.props.value || ''
        };
    },

    componentWillMount: function () {
        this.props.attachToForm(this); // Attaching the component to the form
    },

    componentWillUnmount: function () {
        this.props.detachFromForm(this); // Detaching if unmounting
    },

    // Get the text the user entered from the text-type field. Meant to be called from
    // parent components.
    getValue: function() {
        if (this.props.type === 'text' || this.props.type === 'email' || this.props.type === 'number' || this.props.type === 'textarea') {
            return ReactDOM.findDOMNode(this.refs.input).value.trim();
        } else if (this.props.type === 'select') {
            return this.getSelectedOption().trim();
        } else if (this.props.type === 'checkbox') {
            return this.props.checked;
        }
    },

    // Toggles value for checkboxes
    toggleValue: function() {
        if (this.props.type === 'checkbox') {
            if (this.props.checked === true) {
                return false;
            }
            else {
                return true;
            }
        }
    },

    // Set the value of an input
    setValue: function(val) {
        if (this.props.type === 'text' || this.props.type === 'email' || this.props.type === 'textarea' || this.props.type === 'number') {
            ReactDOM.findDOMNode(this.refs.input).value = val;
            this.setState({value: val}, () => {this.props.validateDefault(this);});
        } else if (this.props.type === 'select') {
            this.setSelectedOption(val);
        } else if (this.props.type === 'checkbox') {
            ReactDOM.findDOMNode(this.refs.input).checked = val;
            this.setState({value: val}, () => {this.props.validateDefault(this);});
        }
    },

    resetValue: function() {
        if (this.props.type === 'text' || this.props.type === 'email' || this.props.type === 'textarea') {
            ReactDOM.findDOMNode(this.refs.input).value = '';
        } else if (this.props.type === 'select') {
            this.resetSelectedOption();
        } else if (this.props.type === 'checkbox') {
            this.resetSelectedCheckbox();
        }
    },

    // Reset <select> to default option
    resetSelectedOption: function() {
        var selectNode = this.refs.input;
        var optionNodes = selectNode.getElementsByTagName('option');
        if (optionNodes && optionNodes.length) {
            selectNode.value = optionNodes[0].value;
        }
    },

    // Reset checkbox
    resetSelectedCheckbox: function() {
        var selectNode = this.refs.input;
        selectNode.checked = false;
    },

    setSelectedOption: function(val) {
        var select = this.refs.input;
        select.value = val;
    },

    // Get the selected option from a <select> list
    getSelectedOption: function() {
        var optionNodes = this.refs.input.getElementsByTagName('option');

        // Get the DOM node for the selected <option>
        var selectedOptionNode = _(optionNodes).find(function(option) {
            return option.selected;
        });

        // Get the selected options value, or its text if it has no value
        if (selectedOptionNode) {
            var valAttr = selectedOptionNode.getAttribute('value');
            return valAttr === null ? selectedOptionNode.innerHTML : valAttr;
        }

        // Nothing selected
        return '';
    },

    // Called when any input's value changes from user input
    handleChange(ref, e) {
        this.setState({value: e.target.value});
        if (this.props.getFormError(ref)) {
            this.props.clrFormErrors(ref);
        }
        if (this.props.handleChange) {
            this.props.handleChange(ref, e);
        }
    },

    render: function() {
        var input, inputClasses, title;
        var groupClassName = 'form-group' + this.props.groupClassName ? ' ' + this.props.groupClassName : '';

        switch (this.props.type) {
            case 'text':
            case 'email':
            case 'number':
                var inputType = this.props.type === 'number' ? 'text' : this.props.type;
                inputClasses = 'form-control' + (this.props.getFormError(this.props.id) ? ' error' : '') + (this.props.inputClassName ? ' ' + this.props.inputClassName : '');
                var innerInput = (

                        <input className={inputClasses} type={inputType} id={this.props.id} name={this.props.id} placeholder={this.props.placeholder} ref="input" value={this.state.value} onChange={this.handleChange.bind(null, this.props.id)} onBlur={this.props.onBlur} maxLength={this.props.maxLength} disabled={this.props.inputDisabled} />

{this.props.getFormError(this.props.id) ? {this.props.getFormError(this.props.id)} :  }

                );
                input = (

                        {this.props.label ? {this.props.label}{this.props.required ? ' *' : ''} : null}
                        {this.props.wrapperClassName ?
{innerInput}
 : {innerInput}}

                );
                break;

            case 'select':
                inputClasses = 'form-control' + (this.props.error ? ' error' : '') + (this.props.inputClassName ? ' ' + this.props.inputClassName : '');
                input = (

                        {this.props.label ? {this.props.label}{this.props.required ? ' *' : ''} : null}

                            <select className={inputClasses} ref="input" onChange={this.handleChange.bind(null, this.props.id)} onBlur={this.props.onBlur} defaultValue={this.props.hasOwnProperty('value') ? this.props.value : this.props.defaultValue} disabled={this.props.inputDisabled}>
                                {this.props.children}
                            </select>

{this.props.error ? {this.props.error} :  }

                );
                break;

            case 'textarea':
                inputClasses = 'form-control' + (this.props.error ? ' error' : '') + (this.props.inputClassName ? ' ' + this.props.inputClassName : '');
                input = (

                        {this.props.label ? {this.props.label}{this.props.required ? ' *' : ''} : null}

                            <textarea className={inputClasses} id={this.props.id} name={this.props.id} ref="input" defaultValue={this.props.value} placeholder={this.props.placeholder} onChange={this.handleChange.bind(null, this.props.id)} onBlur={this.props.onBlur} disabled={this.props.inputDisabled} rows={this.props.rows} />

{this.props.error ? {this.props.error} :  }

                );
                break;

            case 'text-range':
                input = (

                        {this.props.label ? {this.props.label}{this.props.required ? ' *' : ''} : null}

                            {this.props.children}

                );
                break;

            case 'button':
                // Requires properties:
                //   title: Label to put into button
                //   clickHandler: Method to call when button is clicked
                inputClasses = 'btn' + (this.props.inputClassName ? ' ' + this.props.inputClassName : '') + (this.props.submitBusy ? ' submit-busy' : '');
                input = (

                        <input className={inputClasses} type={this.props.type} value={this.props.title} onClick={this.props.clickHandler} disabled={this.props.inputDisabled || this.props.submitBusy} />

                );
                break;

            case 'button-button':
                // Requires properties:
                //   title: Label to put into button
                //   clickHandler: Method to call when button is clicked
                inputClasses = 'btn' + (this.props.inputClassName ? ' ' + this.props.inputClassName : '') + (this.props.submitBusy ? ' submit-busy' : '');
                input = (

                        <button className={inputClasses} onClick={this.props.clickHandler} disabled={this.props.inputDisabled || this.props.submitBusy}>
                        {this.props.submitBusy ?  : null}{this.props.title}</button>

                );
                break;

            case 'checkbox':
                input = (

                        {this.props.label ? {this.props.label}{this.props.required ? ' *' : ''} : null}

                            <input className={inputClasses} ref="input" type={this.props.type} onChange={this.handleChange.bind(null, this.props.id)} disabled={this.props.inputDisabled} checked={this.props.checked} />

{this.props.error ? {this.props.error} :  }

                );
                break;

            case 'submit':
                title = this.props.title ? this.props.title : 'Submit';
                inputClasses = 'btn' + (this.props.inputClassName ? ' ' + this.props.inputClassName : '') + (this.props.submitBusy ? ' submit-busy' : '');
                input = (

                        <button className={inputClasses} onClick={this.props.submitHandler} disabled={this.props.inputDisabled || this.props.submitBusy}>
                        {this.props.submitBusy ?  : null}{title}</button>

                );
                break;

            case 'cancel':
                title = this.props.title ? this.props.title : 'Cancel';
                inputClasses = 'btn' + (this.props.inputClassName ? ' ' + this.props.inputClassName : '');
                input = (

                        <button className={inputClasses} onClick={this.props.cancelHandler} disabled={this.props.inputDisabled}>{title}</button>

                );
                break;

            default:
                break;
        }

        return {input};
    }
});
<commit_msg>Deleting an accidental commit<commit_after><|endoftext|>


<commit_before>/**
 *
 * A Stream is an iterable object that provides some functional operators to initiate or manipulate its
 * elements.
 *
 * Most of its methods return a new Stream, but they don't execute any operation until explicitly requested.
 * E.g. by iterating with a for..of, or by calling the toArray or other methods that consume the Stream, so that it can't be iterated again.
 * This is because the functions are executed lazily.
 *
 * Thanks to the laziness of the execution (achieved through generators), infinite streams can be manipulated.
 */
(function(){
    Stream = function(iterator){

    /**
     * iterator
     */
    this[Symbol.iterator] = ()=>iterator
    this.iterator = ()=>iterator

    /**
     * It is an iterator itself
     */
    this.next = ()=>iterator.next()
    this.nextValue = ()=>iterator.next().value

    /**
     * returns a new Stream that can iterate only on the first n elements (or less) of the stream
     */
    this.take = function(n){
        var takeGen = function*(){
            for(var i=0; i<n; i++){
                var next = iterator.next()
                if(next.done === false)
                    yield next.value
            }
        }
        return new Stream(takeGen())
    }

    /**
     * take alias
     */
    this.limit = this.take

    /**
     * returns a new Stream that skips the first n elements. Notice that this method actually iterates over
     * the stream immediatly to reach the new starting position.
     */
    this.skip = function(n){
        var ended = false
        for(var i=0; (i<n)&&(!ended); i++){
            var next = iterator.next()
            ended = next.done
        }
        var skipGen = function*(){
            if(!ended){
                for(var j of iterator){
                    yield j
                }
            }
        }
        return new Stream(skipGen())
    }

    /**
     * maps every element of the stream to another element applying the given function.
     * A new Stream is returned
     */
    this.map = function(f){
        var mapGen = function*(){
            for(var i of iterator){
                yield f(i)
            }
        }
        return new Stream(mapGen())
    }

    this.flatMap = function(f){
        var flatMapGen = function*(){
            for(var i of iterator){
                var l = f(i)
                for(var j of l){
                    yield j
                }
            }
        }
        return new Stream(flatMapGen())
    }

    /**
     * Filters every element with a function or an object, if the function f returns true, or the element has the property values given by the object,
     *  the element will be present in the returned Stream.
     */
    this.filter = function(f){
        var filterGen = function*(){
            for(var i of iterator){
                if(typeof f === 'function'){
                    if(f(i)===true){
                        yield i
                    }
                }
                else if(typeof f === 'object'){
                    var allMatch = true
                    for(var name in f){
                        if(i[name] !== f[name]){
                            allMatch = false
                        }
                    }
                    if(allMatch){
                        yield i
                    }
                }
            }
        }
        return new Stream(filterGen())
    }

    /**
     * Takes all the elements while they satisfy the f condition.
     * A new Stream is returned
     */
    this.takeWhile = function(f){
        var takeWhileGen = function*(){
            for(var i of iterator){
                if(f(i)){
                    yield i
                }
                else break
            }
        }
        return new Stream(takeWhileGen())
    }

    /**
     * Concats any iterable lazily. Returns a new Stream
     */
    this.concat = function(s){
        var concatGen = function*(){
            for(var i of iterator){
                yield i
            }
            for(var i of s){
                yield i
            }
        }
        return new Stream(concatGen())
    }

    /**
     * Apply a custom generator on the stream.
     * The generator should accept the stream as a parameter, and yield the elements of the new stream
     */
    this.applyGenerator = function(gen){
        return new Stream(gen(this))
    }

    /**
     * Takes an operator (a mapping function that takes two values and maps them into one value)
     * and another stream, and applies the operator to each couple of elements of the two streams to produce another stream.
     */
    this.applyOperator = function(operator, stream){
        var applyOpGen = function*(){
            for(var i of iterator){
                var n = stream.next()
                if(n.done===true)
                    break

                yield operator(i,n.value)
            }
        }
        return new Stream(applyOpGen())
    }

    //HEAVY METHODS
    //THEY USE A SUPPORT ARRAY AND THUS CAN ONLY OPERATE ON A FINITE STREAM!!
    /**
     * Returns a sorted version of the stream, according to natural ordering or according to a compare function, or by natural ordering of a property
     */
    this.sorted = function(){
        var thisInstance = this
        var args = arguments
        var arrayGen = function*(){
            var array = thisInstance.toArray()
            if(args.length === 0){
                array.sort()
            }else if(typeof args[0] === 'string'){
                var name = args[0]
                array.sort((a,b)=>{
                    if(a[name]<b[name])
                        return -1
                    else if(a[name]>b[name])
                        return 1
                    else
                        return 0
                })
            }
            for(var e of array){
                yield e
            }
        }

        return new Stream(arrayGen())
    }

    /**
     * alias
     */
    this.sort = this.sorted

    /**
     * distinct
     */
    this.distinct = function(){
        var distinctGen = function*(){
            var s = new Set()
            for(var e of iterator){
                if(!s.has(e)){
                    s.add(e)
                    yield e
                }
            }
        }
        return new Stream(distinctGen())
    }

    this.reversed = function(){
        var thisInstance = this
        var revGen = function*(){
            var array = thisInstance.toArray().reverse()
            for(var e of array){
                yield e
            }
        }
        return new Stream(revGen())
    }

    this.reverse = this.reversed

    //EAGER METHODS
    //THEY CONSUME THE STREAM!

    /**
     * Executes f(e) for every element e of the stream
     */
    this.forEach = function(f){
        for(var i of iterator){
            f(i)
        }
    }

    /**
     * process(n,f)
     * process n elements with the function f
     * Like forEach, but only for the first n elements, then returns the rest of the Stream
     */
    this.process = function(n, f){
        var ended = false
        for(var i=0; i<n && !ended; i++){
            var e = iterator.next()
            if(e.done){
                ended = true
            }
            else{
                f(e.value)
            }
        }
        return this
    }

    /**
     * equivalent to s.forEach(console.log)
     */
    this.log = function(){
        this.forEach(console.log)
    }

    /**
     * Finds the first occurence of an element e that satisfies f(e) and returns it
     */
    this.find = function(f){
        for(var i of iterator){
            if(f(i)===true){
                return i
            }
        }
        return undefined
    }

    /**
     * Groups the elements of the Stream using as key the result of function f applied to every element.
     * Or, if you pass a String, groups by that property (in a stream of objects)
     */
    this.groupBy = function(f){
        var obj = {}
        this.forEach(e=>{
            var key
            if(typeof f === 'function'){
                key  = f(e)
            }
            else if(typeof f === 'string'){
                key = e[f]
            }

            if(obj[key]===undefined){
                obj[key]=[e]
            }
            else {
                obj[key].push(e)
            }
        })
        return obj
    }

    /**
     * Partitions the elements of a Stream
     */
    this.partition = this.groupBy
    this.partitionBy = this.groupBy

    /**
     * Applies f on an accumulator (initiated with start) and every element of the Stream.
     * Returns a single value
     */
    this.reduce = function(f,start){
        var acc = start
        for(var i of iterator){
            acc = f(acc, i)
        }
        return acc
    }

    /**
     * Counts the elements of the stream
     */
    this.count = function(){
        var acc = 0
        for(var i of iterator){
            acc+=1
        }
        return acc
    }

    /**
     * count alias
     */
    this.size = this.count

    /**
     * Returns the first element
     */
    this.first = function(){
        for(var i of iterator){
            return i
        }
    }

    /**
     * Returns the last element
     */
    this.last = function(){
        var l
        for(var i of iterator){
            l=i
        }
        return l
    }

    /**
     * Sums all the elements of the stream
     */
    this.sum = function(){
        var acc = 0
        for(var i of iterator){
            acc+=i
        }
        return acc
    }

    /**
     * Average
     */
    this.avg = function(){
        var array = this.toArray()
        var sum = array.reduce((a,b)=>a+b)
        var count = array.length
        return sum / count
    }

    /**
     * Creates a new array with the stream elements
     */
    this.toArray = function(){
        var a = []
        var next = iterator.next()
        while(next.done === false){
            a.push(next.value)
            next = iterator.next()
        }
        return a
    }
}

/**
 * Stream composed of the given arguments
 */
Stream.of = function(){
    var args = arguments
    var ofGen = function*(){
        for(var a of args){
            yield a
        }
    }
    return new Stream(ofGen())
}

/**
 * Infinite stream of values obtained by applying the function f from the start value
 */
Stream.iterate = function(start, f){
    var lazyStream = function*() {
        var cur = start
        while(true){
            yield cur
            cur = f(cur)
        }
    }
    return new Stream(lazyStream())
}

/**
 * Infinite stream of values obtained by applying the function f to the index (starting from 0)
 */
Stream.tabulate = function(f){
    var tabGen = function*(){
        for(var i=0; ;i++){
            yield f(i)
        }
    }
    return new Stream(tabGen())
}

/**
 * Limited Stream of integers, from startInclusive to endExclusive
 */
Stream.range = function(startInclusive, endExclusive, step){
    if(step===undefined)
        step=1

    var ranGen = function*(){
        for(var i= startInclusive; i<endExclusive; i+=step){
            yield i
        }
    }
    return new Stream(ranGen())
}

/**
 * infinite stream composed of the results of the function f
 */
Stream.generate = function(f){
    var genGen = function*(){
        while(true){
            yield f()
        }
    }
    return new Stream(genGen())
}

/**
 * infinite stream composed of only the element e
 */
Stream.fill = function(e){
    var fillGen = function*(){
        while(true){
            yield e
        }
    }
    return new Stream(fillGen())
}

/**
 * An empty stream
 */
Stream.empty = function(){
    var emptyGen = function*(){
    }
    return new Stream(emptyGen())
}

/**
 * Creates a stream from an array, object, Set, Map.
 * With a Map, it creates a stream of {key:<key>, value:<value>} objects
 * With an object, it creates a stream of {name:<name>, value:<value>} objects
 *
 */
Stream.from = function(a){
    //if null
    if(a === null || a === undefined)
        return Stream.empty()

    //if array or Set
    if(a.constructor === Array || a.constructor === Set || typeof a === 'string')
        return new Stream(a[Symbol.iterator]())

    //if Map
    if(a.constructor === Map){
        var mapGen = function*(){
            for(var e of a){
                yield {
                    key: e[0],
                    value: e[1]
                }
            }
        }
        return new Stream(mapGen())
    }

    //if object
    if(typeof a === 'object'){
        var objGen = function*(){
            for(var e in a){
                yield {
                    name:e,
                    value:a[e]
                }
            }
        }
        return new Stream(objGen())
    }

    //if something else, call Stream.of
    return Stream.of(a)
}

module.exports = Stream

}.call(this))<commit_msg>Documented flatMap<commit_after>/**
 *
 * A Stream is an iterable object that provides some functional operators to initiate or manipulate its
 * elements.
 *
 * Most of its methods return a new Stream, but they don't execute any operation until explicitly requested.
 * E.g. by iterating with a for..of, or by calling the toArray or other methods that consume the Stream, so that it can't be iterated again.
 * This is because the functions are executed lazily.
 *
 * Thanks to the laziness of the execution (achieved through generators), infinite streams can be manipulated.
 */
(function(){
    Stream = function(iterator){

    /**
     * iterator
     */
    this[Symbol.iterator] = ()=>iterator
    this.iterator = ()=>iterator

    /**
     * It is an iterator itself
     */
    this.next = ()=>iterator.next()
    this.nextValue = ()=>iterator.next().value

    /**
     * returns a new Stream that can iterate only on the first n elements (or less) of the stream
     */
    this.take = function(n){
        var takeGen = function*(){
            for(var i=0; i<n; i++){
                var next = iterator.next()
                if(next.done === false)
                    yield next.value
            }
        }
        return new Stream(takeGen())
    }

    /**
     * take alias
     */
    this.limit = this.take

    /**
     * returns a new Stream that skips the first n elements. Notice that this method actually iterates over
     * the stream immediatly to reach the new starting position.
     */
    this.skip = function(n){
        var ended = false
        for(var i=0; (i<n)&&(!ended); i++){
            var next = iterator.next()
            ended = next.done
        }
        var skipGen = function*(){
            if(!ended){
                for(var j of iterator){
                    yield j
                }
            }
        }
        return new Stream(skipGen())
    }

    /**
     * maps every element of the stream to another element applying the given function.
     * A new Stream is returned
     */
    this.map = function(f){
        var mapGen = function*(){
            for(var i of iterator){
                yield f(i)
            }
        }
        return new Stream(mapGen())
    }

    /**
     * Maps the elements to a list of elements, each one yielded in the new Stream
     */
    this.flatMap = function(f){
        var flatMapGen = function*(){
            for(var i of iterator){
                var l = f(i)
                for(var j of l){
                    yield j
                }
            }
        }
        return new Stream(flatMapGen())
    }

    /**
     * Filters every element with a function or an object, if the function f returns true, or the element has the property values given by the object,
     *  the element will be present in the returned Stream.
     */
    this.filter = function(f){
        var filterGen = function*(){
            for(var i of iterator){
                if(typeof f === 'function'){
                    if(f(i)===true){
                        yield i
                    }
                }
                else if(typeof f === 'object'){
                    var allMatch = true
                    for(var name in f){
                        if(i[name] !== f[name]){
                            allMatch = false
                        }
                    }
                    if(allMatch){
                        yield i
                    }
                }
            }
        }
        return new Stream(filterGen())
    }

    /**
     * Takes all the elements while they satisfy the f condition.
     * A new Stream is returned
     */
    this.takeWhile = function(f){
        var takeWhileGen = function*(){
            for(var i of iterator){
                if(f(i)){
                    yield i
                }
                else break
            }
        }
        return new Stream(takeWhileGen())
    }

    /**
     * Concats any iterable lazily. Returns a new Stream
     */
    this.concat = function(s){
        var concatGen = function*(){
            for(var i of iterator){
                yield i
            }
            for(var i of s){
                yield i
            }
        }
        return new Stream(concatGen())
    }

    /**
     * Apply a custom generator on the stream.
     * The generator should accept the stream as a parameter, and yield the elements of the new stream
     */
    this.applyGenerator = function(gen){
        return new Stream(gen(this))
    }

    /**
     * Takes an operator (a mapping function that takes two values and maps them into one value)
     * and another stream, and applies the operator to each couple of elements of the two streams to produce another stream.
     */
    this.applyOperator = function(operator, stream){
        var applyOpGen = function*(){
            for(var i of iterator){
                var n = stream.next()
                if(n.done===true)
                    break

                yield operator(i,n.value)
            }
        }
        return new Stream(applyOpGen())
    }

    //HEAVY METHODS
    //THEY USE A SUPPORT ARRAY AND THUS CAN ONLY OPERATE ON A FINITE STREAM!!
    /**
     * Returns a sorted version of the stream, according to natural ordering or according to a compare function, or by natural ordering of a property
     */
    this.sorted = function(){
        var thisInstance = this
        var args = arguments
        var arrayGen = function*(){
            var array = thisInstance.toArray()
            if(args.length === 0){
                array.sort()
            }else if(typeof args[0] === 'string'){
                var name = args[0]
                array.sort((a,b)=>{
                    if(a[name]<b[name])
                        return -1
                    else if(a[name]>b[name])
                        return 1
                    else
                        return 0
                })
            }
            for(var e of array){
                yield e
            }
        }

        return new Stream(arrayGen())
    }

    /**
     * alias
     */
    this.sort = this.sorted

    /**
     * distinct
     */
    this.distinct = function(){
        var distinctGen = function*(){
            var s = new Set()
            for(var e of iterator){
                if(!s.has(e)){
                    s.add(e)
                    yield e
                }
            }
        }
        return new Stream(distinctGen())
    }

    this.reversed = function(){
        var thisInstance = this
        var revGen = function*(){
            var array = thisInstance.toArray().reverse()
            for(var e of array){
                yield e
            }
        }
        return new Stream(revGen())
    }

    this.reverse = this.reversed

    //EAGER METHODS
    //THEY CONSUME THE STREAM!

    /**
     * Executes f(e) for every element e of the stream
     */
    this.forEach = function(f){
        for(var i of iterator){
            f(i)
        }
    }

    /**
     * process(n,f)
     * process n elements with the function f
     * Like forEach, but only for the first n elements, then returns the rest of the Stream
     */
    this.process = function(n, f){
        var ended = false
        for(var i=0; i<n && !ended; i++){
            var e = iterator.next()
            if(e.done){
                ended = true
            }
            else{
                f(e.value)
            }
        }
        return this
    }

    /**
     * equivalent to s.forEach(console.log)
     */
    this.log = function(){
        this.forEach(console.log)
    }

    /**
     * Finds the first occurence of an element e that satisfies f(e) and returns it
     */
    this.find = function(f){
        for(var i of iterator){
            if(f(i)===true){
                return i
            }
        }
        return undefined
    }

    /**
     * Groups the elements of the Stream using as key the result of function f applied to every element.
     * Or, if you pass a String, groups by that property (in a stream of objects)
     */
    this.groupBy = function(f){
        var obj = {}
        this.forEach(e=>{
            var key
            if(typeof f === 'function'){
                key  = f(e)
            }
            else if(typeof f === 'string'){
                key = e[f]
            }

            if(obj[key]===undefined){
                obj[key]=[e]
            }
            else {
                obj[key].push(e)
            }
        })
        return obj
    }

    /**
     * Partitions the elements of a Stream
     */
    this.partition = this.groupBy
    this.partitionBy = this.groupBy

    /**
     * Applies f on an accumulator (initiated with start) and every element of the Stream.
     * Returns a single value
     */
    this.reduce = function(f,start){
        var acc = start
        for(var i of iterator){
            acc = f(acc, i)
        }
        return acc
    }

    /**
     * Counts the elements of the stream
     */
    this.count = function(){
        var acc = 0
        for(var i of iterator){
            acc+=1
        }
        return acc
    }

    /**
     * count alias
     */
    this.size = this.count

    /**
     * Returns the first element
     */
    this.first = function(){
        for(var i of iterator){
            return i
        }
    }

    /**
     * Returns the last element
     */
    this.last = function(){
        var l
        for(var i of iterator){
            l=i
        }
        return l
    }

    /**
     * Sums all the elements of the stream
     */
    this.sum = function(){
        var acc = 0
        for(var i of iterator){
            acc+=i
        }
        return acc
    }

    /**
     * Average
     */
    this.avg = function(){
        var array = this.toArray()
        var sum = array.reduce((a,b)=>a+b)
        var count = array.length
        return sum / count
    }

    /**
     * Creates a new array with the stream elements
     */
    this.toArray = function(){
        var a = []
        var next = iterator.next()
        while(next.done === false){
            a.push(next.value)
            next = iterator.next()
        }
        return a
    }
}

/**
 * Stream composed of the given arguments
 */
Stream.of = function(){
    var args = arguments
    var ofGen = function*(){
        for(var a of args){
            yield a
        }
    }
    return new Stream(ofGen())
}

/**
 * Infinite stream of values obtained by applying the function f from the start value
 */
Stream.iterate = function(start, f){
    var lazyStream = function*() {
        var cur = start
        while(true){
            yield cur
            cur = f(cur)
        }
    }
    return new Stream(lazyStream())
}

/**
 * Infinite stream of values obtained by applying the function f to the index (starting from 0)
 */
Stream.tabulate = function(f){
    var tabGen = function*(){
        for(var i=0; ;i++){
            yield f(i)
        }
    }
    return new Stream(tabGen())
}

/**
 * Limited Stream of integers, from startInclusive to endExclusive
 */
Stream.range = function(startInclusive, endExclusive, step){
    if(step===undefined)
        step=1

    var ranGen = function*(){
        for(var i= startInclusive; i<endExclusive; i+=step){
            yield i
        }
    }
    return new Stream(ranGen())
}

/**
 * infinite stream composed of the results of the function f
 */
Stream.generate = function(f){
    var genGen = function*(){
        while(true){
            yield f()
        }
    }
    return new Stream(genGen())
}

/**
 * infinite stream composed of only the element e
 */
Stream.fill = function(e){
    var fillGen = function*(){
        while(true){
            yield e
        }
    }
    return new Stream(fillGen())
}

/**
 * An empty stream
 */
Stream.empty = function(){
    var emptyGen = function*(){
    }
    return new Stream(emptyGen())
}

/**
 * Creates a stream from an array, object, Set, Map.
 * With a Map, it creates a stream of {key:<key>, value:<value>} objects
 * With an object, it creates a stream of {name:<name>, value:<value>} objects
 *
 */
Stream.from = function(a){
    //if null
    if(a === null || a === undefined)
        return Stream.empty()

    //if array or Set
    if(a.constructor === Array || a.constructor === Set || typeof a === 'string')
        return new Stream(a[Symbol.iterator]())

    //if Map
    if(a.constructor === Map){
        var mapGen = function*(){
            for(var e of a){
                yield {
                    key: e[0],
                    value: e[1]
                }
            }
        }
        return new Stream(mapGen())
    }

    //if object
    if(typeof a === 'object'){
        var objGen = function*(){
            for(var e in a){
                yield {
                    name:e,
                    value:a[e]
                }
            }
        }
        return new Stream(objGen())
    }

    //if something else, call Stream.of
    return Stream.of(a)
}

module.exports = Stream

}.call(this))<|endoftext|>


<commit_before>"use strict";

class gswaEffects {
	constructor( fns ) {
		this.ctx = null;
		this._getChanInput = fns.getChanInput;
		this._getChanOutput = fns.getChanOutput;
		this._wafxs = new Map();
		this.gsdata = new GSDataEffects( {
			dataCallbacks: {
				addEffect: this._addEffect.bind( this ),
				removeEffect: this._removeEffect.bind( this ),
				changeEffect: this._changeEffect.bind( this ),
				connectEffectTo: this._connectEffectTo.bind( this ),
				changeEffectData: ( id, data ) => this._wafxs.get( id ).change( data ),
			},
		} );
		Object.seal( this );
	}

	// .........................................................................
	setContext( ctx ) {
		this.ctx = ctx;
		this.gsdata.reset();
	}
	setBPM( bpm ) {
		this._wafxs.forEach( fx => fx.setBPM && fx.setBPM( bpm ) );
	}
	change( obj ) {
		this.gsdata.change( obj );
	}
	clear() {
		this.gsdata.clear();
	}
	liveChangeFxProp( id, prop, val ) {
		this._wafxs.get( id ).liveChange( prop, val );
	}

	// .........................................................................
	_addEffect( id, fx ) {
		const wafx = new ( gswaEffects.fxsMap.get( fx.type ) )();

		this._wafxs.set( id, wafx );
		wafx.setContext( this.ctx );
	}
	_removeEffect( id, prevId, nextId ) {
		const wafx = this._wafxs.get( id );

		wafx.output.disconnect();
		this._wafxs.delete( id );
	}
	_changeEffect( id, prop, val ) {
		if ( prop === "toggle" ) {
			this._wafxs.get( id ).toggle( val );
		}
	}
	_connectEffectTo( chanId, fxId, nextFxId ) {
		const dest = nextFxId
				? this._wafxs.get( nextFxId ).input
				: this._getChanOutput( chanId ),
			node = fxId
				? this._wafxs.get( fxId ).output
				: this._getChanInput( chanId );

		node.disconnect();
		node.connect( dest );
	}
}

gswaEffects.fxsMap = new Map();
Object.freeze( gswaEffects );
<commit_msg>gswaEffects: update gsdataEffect usage<commit_after>"use strict";

class gswaEffects {
	constructor( fns ) {
		this.ctx = null;
		this._getChanInput = fns.getChanInput;
		this._getChanOutput = fns.getChanOutput;
		this._wafxs = new Map();
		this.gsdata = new GSDataEffects( {
			dataCallbacks: {
				changeBPM: bpm => this._wafxs.forEach( fx => fx.setBPM && fx.setBPM( bpm ) ),
				addEffect: this._addEffect.bind( this ),
				removeEffect: this._removeEffect.bind( this ),
				changeEffect: this._changeEffect.bind( this ),
				connectEffectTo: this._connectEffectTo.bind( this ),
				changeEffectData: ( id, data ) => this._wafxs.get( id ).change( data ),
			},
		} );
		Object.seal( this );
	}

	// .........................................................................
	setContext( ctx ) {
		this.ctx = ctx;
		this.gsdata.reset();
	}
	change( obj ) {
		this.gsdata.change( obj );
	}
	clear() {
		this.gsdata.clear();
	}
	liveChangeFxProp( id, prop, val ) {
		this._wafxs.get( id ).liveChange( prop, val );
	}

	// .........................................................................
	_addEffect( id, fx ) {
		const wafx = new ( gswaEffects.fxsMap.get( fx.type ) )();

		this._wafxs.set( id, wafx );
		wafx.setContext( this.ctx );
	}
	_removeEffect( id, prevId, nextId ) {
		const wafx = this._wafxs.get( id );

		wafx.output.disconnect();
		this._wafxs.delete( id );
	}
	_changeEffect( id, prop, val ) {
		if ( prop === "toggle" ) {
			this._wafxs.get( id ).toggle( val );
		}
	}
	_connectEffectTo( chanId, fxId, nextFxId ) {
		const dest = nextFxId
				? this._wafxs.get( nextFxId ).input
				: this._getChanOutput( chanId ),
			node = fxId
				? this._wafxs.get( fxId ).output
				: this._getChanInput( chanId );

		node.disconnect();
		node.connect( dest );
	}
}

gswaEffects.fxsMap = new Map();
Object.freeze( gswaEffects );
<|endoftext|>


<commit_before>"use strict";

/**
 * Generates a GUID string.
 * @returns {String} The generated GUID.
 * @example af8a8416-6e18-a307-bd9c-f2c947bbb3aa
 * @author Slavik Meltser (slavik@meltser.info).
 * @link http://slavik.meltser.info/?p=142
 */
function guid() {
    function _p8(s) {
        var p = (Math.random().toString(16)+"000000000").substr(2,8);
        return s ? "-" + p.substr(0,4) + "-" + p.substr(4,4) : p ;
    }
    return _p8() + _p8(true) + _p8(true) + _p8();
}

var createCookie = function(name, value, days) {
    var expires;
    if (days) {
        var date = new Date();
        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
        expires = "; expires=" + date.toGMTString();
    }
    else {
        expires = "";
    }
    document.cookie = name + "=" + value + expires + "; path=/";
}

function getCookie(c_name) {
    if (document.cookie.length > 0) {
        var c_start = document.cookie.indexOf(c_name + "=");
        if (c_start != -1) {
            c_start = c_start + c_name.length + 1;
            var c_end = document.cookie.indexOf(";", c_start);
            if (c_end == -1) {
                c_end = document.cookie.length;
            }
            return unescape(document.cookie.substring(c_start, c_end));
        }
    }
    return "";
}

var HttpClient = function() {
    this.get = function(aUrl, aCallback) {
        return this.request("GET", aUrl, aCallback);
    }

    this.post = function(aUrl, aCallback) {
        return this.request("POST", aUrl, aCallback);
    }

    this.put = function(aUrl, aCallback) {
        return this.request("PUT", aUrl, aCallback);
    }

    this.request = function(method, aUrl, aCallback) {
        var anHttpRequest = new XMLHttpRequest();
        anHttpRequest.onreadystatechange = function() {
        if (anHttpRequest.readyState == 4)
            aCallback(anHttpRequest.status, JSON.parse(anHttpRequest.responseText));
        }

        anHttpRequest.open( method, aUrl, true );
        anHttpRequest.send( null );
    };
}

var cellWidth = 64;
var cellSpacing = 10;
var apiUrl = 'api/games';
var previousFencePost = null;

function player() {
    return {'id':getCookie('player_id'), 'name':getCookie('player_name')};
}

function currentGame() {
    return {"id":getCookie('game_id')};
}

function setup() {
    var p = player();
    var gid = currentGame().id;
    if (p.id.length == 0 || p.name.length == 0) {
        document.getElementById('playerInfo').style.display = 'block';
    } else if (gid.length > 0) {

        var http = new HttpClient();
        http.get(apiUrl + '/' + gid + '?id=' + p.id, function(status, game) {
            if (status != 200) {
                alert(game.message);
                return;
            }

            startGame(game);
        });
    } else {
        showGames(p);
    }
}

function login() {
    var nameView = document.getElementById('player_name');
    if (nameView.value.length > 0) {
        createCookie('player_id', guid(), 30);
        createCookie('player_name', nameView.value, 30);
        showGames(player());
    } else {
        alert('You must enter a name');
    }
    return false;
}

function showGames(player) {
    document.getElementById('welcomeName').innerHTML = 'Welcome ' + player.name + '!';
    document.getElementById('playerInfo').style.display = 'none';
    loadGames();
}

function formatTime(time) {
    var lastMoveAt = new Date(time);
    return lastMoveAt.toLocaleTimeString() + ' on ' + lastMoveAt.toLocaleDateString();
}

function loadGames() {

    var p = player();

    var http = new HttpClient();
    http.get(apiUrl, function(status, games) {
        if (status != 200) {
            alert(games.message);
            return;
        }

        var table = document.getElementById('publicGames');
        games.forEach(function(game) {
            var row = table.insertRow();

            var idCell = row.insertCell();
            idCell.appendChild(document.createTextNode(game.id));
            var age = row.insertCell();
            age.appendChild(document.createTextNode(formatTime(game.lastMoveAt)));
            var join = row.insertCell();
            var a = document.createElement('a');
            var linkText = document.createTextNode("Join");
            a.appendChild(linkText);
            a.title = "Join game " + game.id;
            var joinUrl = apiUrl + '?id='+p.id+'&name='+p.name+'&gameId='+game.id;
            a.href = joinUrl;
            a.onclick = function(e) {
                e.preventDefault();
                http.put(joinUrl, function(postStatus, joined) {
                    if (postStatus != 200) {
                        alert(joined.message);
                        return;
                    }

                    startGame(joined);
                });
            }
            join.appendChild(a);

        });
        document.getElementById('gameList').style.display = 'block';
    });
}

function createGame() {
    var p = player();

    var http = new HttpClient();
    http.post(apiUrl+'?name='+p.name+'&id='+p.id  , function(status, game) {
        if (status != 200) {
            alert(game.message);
            return;
        }

        startGame(game);
    });
}

function startGame(game) {
    document.getElementById('gameList').style.display = 'none';
    document.getElementById('boardContainer').style.display = 'block';
    createCookie('game_id', game.id, 30);
    window.setInterval(pollForUpdates, 5000);
    renderGame(game);
}

function pollForUpdates() {
    var http = new HttpClient();
    http.get(apiUrl + '/' + currentGame().id + '?id=' + player().id, function(status, game) {
        if (status == 200) {
            renderGame(game);
        }
    });
}

function renderGame(game) {
    console.log('rendering game');

    var boardView = document.getElementById("board");
    // TODO: reuse the existing views rather than removing and adding all new ones
    while (boardView.firstChild) {
        boardView.removeChild(boardView.firstChild);
    }

    for (var y = 0; y < 9; y++) {
        for (var x = 0; x < 9; x++) {
            var cell = document.createElement('div');
            cell.setAttribute('class', 'cell');
            cell.setAttribute('id', 'cell'+((y*9)+x));
            cell.addEventListener("click", moveHandler, false);
            boardView.appendChild(cell);
        }
    }

    for (var y = 0; y < 10; y++) {
        for (var x = 0; x < 10; x++) {
            var post = document.createElement('div');
            var postId = ((y*9)+x);
            post.setAttribute('class', 'post');
            post.setAttribute('id', 'post'+postId);
            var pos = positionForPost(postId);
            post.style.left = pos.x + 'px';
            post.style.top = pos.y + 'px';
            post.addEventListener("click", postHandler, false);
            if (previousFencePost != null && post.id == previousFencePost.id) {
                previousFencePost = post;
            }
            boardView.appendChild(post);
        }
    }

    if (game.me != null) {
        boardView.appendChild(playerView(game.me, 'me'));
        var fenceCount = 10;
        document.getElementById('myName').innerHTML = game.me.name + ' (me)';
        document.getElementById('myFenceCount').innerHTML = fenceCount + (fenceCount == 0 ? ' fence' : ' fences') + ' remaining';
        game.me.fences.forEach(function(fence) {
            if (fence.hasBeenPlayed) {
                boardView.appendChild(fenceView(fence));
            }
        });
    }
    if (game.you != null) {
        boardView.appendChild(playerView(game.you, 'you'));
        var fenceCount = 10;
        document.getElementById('yourName').innerHTML = game.you.name + ' (you)';
        document.getElementById('yourFenceCount').innerHTML = fenceCount + (fenceCount == 0 ? ' fence' : ' fences') + ' remaining';
        game.you.fences.forEach(function(fence) {
            if (fence.hasBeenPlayed) {
                boardView.appendChild(fenceView(fence));
            }
        });
    }

    var infoView = document.getElementById('gameInfo');
    infoView.innerHTML = 'Game is ' + gameIsInState(game.state);
    infoView.innerHTML = infoView.innerHTML + '
It is currently ' + (game.isMyTurn ? '' : 'not ') + 'your turn';
    if (game.winner != null) {
        infoView.innerHTML = infoView.innerHTML + "
" + game.winner.name + " wins!";
    }

    if (previousFencePost != null) {
        previousFencePost.style.opacity = 1;
    }
}

function gameIsInState(state) {
    switch (state) {
        case 'UNKNOWN': return 'in an unknown state';
        case 'WAITING_OPPONENT': return 'waiting for opponent';
        case 'IN_PROGRESS': return 'in progress';
        case 'GAME_OVER': return 'over';
    }
    return state;
}

function fenceView(fence) {
    var view = document.createElement('div');
    view.setAttribute('class', 'fence');
    var rect = rectForFence(fence.start, fence.end);
    view.style.top = rect.y + 'px';
    view.style.left = rect.x + 'px';
    view.style.width = rect.width + 'px';
    view.style.height = rect.height + 'px';
    return view;
}

function playerView(player, id) {
    var view = document.createElement('div');
    view.setAttribute('class', 'player');
    view.setAttribute('id', id);
    var pos = positionForCell(player.position);
    view.style.top = pos.y + 'px';
    view.style.left = pos.x + 'px';
    view.innerHTML = player.name;
    return view;
}

function rectForFence(start, end) {
    var startPos = positionForPost(start);
    var endPos = positionForPost(end);
    return {
        'x': Math.min(startPos.x, endPos.x)
        ,'y': Math.min(startPos.y, endPos.y)
        ,'width': Math.max(startPos.x, endPos.x) - Math.min(startPos.x, endPos.x) + 24
        ,'height': Math.max(startPos.y, endPos.y) - Math.min(startPos.y, endPos.y) + 24
    };
}

function positionForPost(index) {
    var x = index % 10;
    var y = Math.floor(index / 10);
    return {
        'x': ((cellSpacing + ((cellWidth * x) + (cellSpacing * x)))-((26/2)+6)),
        'y': ((cellSpacing + ((cellWidth * y) + (cellSpacing * y)))-((26/2)+6))
    };
}

function positionForCell(index) {
    return {
        'x': (((index % 9) * cellWidth) + ((index % 9) * cellSpacing) + cellSpacing),
        'y': (cellSpacing + (Math.floor(index / 9))*(cellWidth+cellSpacing))
    };
}

function moveHandler(e) {
    var end = e.target.id.replace('cell','');
    console.log("moving player to " + end);
    var http = new HttpClient();
    http.post(apiUrl + '/' + currentGame().id + '/move?id=' + player().id + '&end=' + end, function(status, game) {
        if (status != 200) {
            alert(game.message);
            return;
        }

        renderGame(game);
    });
}

function postHandler(e) {
    if (previousFencePost == null) {
        previousFencePost = e.target;
        e.target.style.opacity = 1;
    } else {
        previousFencePost.style.opacity = 0.1;
        var start = previousFencePost.id.replace('post','');
        var end = e.target.id.replace('post','');
        previousFencePost = null;
        console.log("building fence from " + start + " to " + end);
        var http = new HttpClient();
        http.post(apiUrl + '/' + currentGame().id + '/fence?id=' + player().id + '&start=' + start + '&end=' + end, function(status, game) {
            if (status != 200) {
                alert(game.message);
                return;
            }

            renderGame(game);
        });
    }
}<commit_msg>The message at the bottom of the game view now updates correctly whether or not it's your turn<commit_after>"use strict";

/**
 * Generates a GUID string.
 * @returns {String} The generated GUID.
 * @example af8a8416-6e18-a307-bd9c-f2c947bbb3aa
 * @author Slavik Meltser (slavik@meltser.info).
 * @link http://slavik.meltser.info/?p=142
 */
function guid() {
    function _p8(s) {
        var p = (Math.random().toString(16)+"000000000").substr(2,8);
        return s ? "-" + p.substr(0,4) + "-" + p.substr(4,4) : p ;
    }
    return _p8() + _p8(true) + _p8(true) + _p8();
}

var createCookie = function(name, value, days) {
    var expires;
    if (days) {
        var date = new Date();
        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
        expires = "; expires=" + date.toGMTString();
    }
    else {
        expires = "";
    }
    document.cookie = name + "=" + value + expires + "; path=/";
}

function getCookie(c_name) {
    if (document.cookie.length > 0) {
        var c_start = document.cookie.indexOf(c_name + "=");
        if (c_start != -1) {
            c_start = c_start + c_name.length + 1;
            var c_end = document.cookie.indexOf(";", c_start);
            if (c_end == -1) {
                c_end = document.cookie.length;
            }
            return unescape(document.cookie.substring(c_start, c_end));
        }
    }
    return "";
}

var HttpClient = function() {
    this.get = function(aUrl, aCallback) {
        return this.request("GET", aUrl, aCallback);
    }

    this.post = function(aUrl, aCallback) {
        return this.request("POST", aUrl, aCallback);
    }

    this.put = function(aUrl, aCallback) {
        return this.request("PUT", aUrl, aCallback);
    }

    this.request = function(method, aUrl, aCallback) {
        var anHttpRequest = new XMLHttpRequest();
        anHttpRequest.onreadystatechange = function() {
        if (anHttpRequest.readyState == 4)
            aCallback(anHttpRequest.status, JSON.parse(anHttpRequest.responseText));
        }

        anHttpRequest.open( method, aUrl, true );
        anHttpRequest.send( null );
    };
}

var cellWidth = 64;
var cellSpacing = 10;
var apiUrl = 'api/games';
var previousFencePost = null;

function player() {
    return {'id':getCookie('player_id'), 'name':getCookie('player_name')};
}

function currentGame() {
    return {"id":getCookie('game_id')};
}

function setup() {
    var p = player();
    var gid = currentGame().id;
    if (p.id.length == 0 || p.name.length == 0) {
        document.getElementById('playerInfo').style.display = 'block';
    } else if (gid.length > 0) {

        var http = new HttpClient();
        http.get(apiUrl + '/' + gid + '?id=' + p.id, function(status, game) {
            if (status != 200) {
                alert(game.message);
                return;
            }

            startGame(game);
        });
    } else {
        showGames(p);
    }
}

function login() {
    var nameView = document.getElementById('player_name');
    if (nameView.value.length > 0) {
        createCookie('player_id', guid(), 30);
        createCookie('player_name', nameView.value, 30);
        showGames(player());
    } else {
        alert('You must enter a name');
    }
    return false;
}

function showGames(player) {
    document.getElementById('welcomeName').innerHTML = 'Welcome ' + player.name + '!';
    document.getElementById('playerInfo').style.display = 'none';
    loadGames();
}

function formatTime(time) {
    var lastMoveAt = new Date(time);
    return lastMoveAt.toLocaleTimeString() + ' on ' + lastMoveAt.toLocaleDateString();
}

function loadGames() {

    var p = player();

    var http = new HttpClient();
    http.get(apiUrl, function(status, games) {
        if (status != 200) {
            alert(games.message);
            return;
        }

        var table = document.getElementById('publicGames');
        games.forEach(function(game) {
            var row = table.insertRow();

            var idCell = row.insertCell();
            idCell.appendChild(document.createTextNode(game.id));
            var age = row.insertCell();
            age.appendChild(document.createTextNode(formatTime(game.lastMoveAt)));
            var join = row.insertCell();
            var a = document.createElement('a');
            var linkText = document.createTextNode("Join");
            a.appendChild(linkText);
            a.title = "Join game " + game.id;
            var joinUrl = apiUrl + '?id='+p.id+'&name='+p.name+'&gameId='+game.id;
            a.href = joinUrl;
            a.onclick = function(e) {
                e.preventDefault();
                http.put(joinUrl, function(postStatus, joined) {
                    if (postStatus != 200) {
                        alert(joined.message);
                        return;
                    }

                    startGame(joined);
                });
            }
            join.appendChild(a);

        });
        document.getElementById('gameList').style.display = 'block';
    });
}

function createGame() {
    var p = player();

    var http = new HttpClient();
    http.post(apiUrl+'?name='+p.name+'&id='+p.id  , function(status, game) {
        if (status != 200) {
            alert(game.message);
            return;
        }

        startGame(game);
    });
}

function startGame(game) {
    document.getElementById('gameList').style.display = 'none';
    document.getElementById('boardContainer').style.display = 'block';
    createCookie('game_id', game.id, 30);
    window.setInterval(pollForUpdates, 5000);
    renderGame(game);
}

function pollForUpdates() {
    var http = new HttpClient();
    http.get(apiUrl + '/' + currentGame().id + '?id=' + player().id, function(status, game) {
        if (status == 200) {
            renderGame(game);
        }
    });
}

function renderGame(game) {
    console.log('rendering game');

    var boardView = document.getElementById("board");
    // TODO: reuse the existing views rather than removing and adding all new ones
    while (boardView.firstChild) {
        boardView.removeChild(boardView.firstChild);
    }

    for (var y = 0; y < 9; y++) {
        for (var x = 0; x < 9; x++) {
            var cell = document.createElement('div');
            cell.setAttribute('class', 'cell');
            cell.setAttribute('id', 'cell'+((y*9)+x));
            cell.addEventListener("click", moveHandler, false);
            boardView.appendChild(cell);
        }
    }

    for (var y = 0; y < 10; y++) {
        for (var x = 0; x < 10; x++) {
            var post = document.createElement('div');
            var postId = ((y*9)+x);
            post.setAttribute('class', 'post');
            post.setAttribute('id', 'post'+postId);
            var pos = positionForPost(postId);
            post.style.left = pos.x + 'px';
            post.style.top = pos.y + 'px';
            post.addEventListener("click", postHandler, false);
            if (previousFencePost != null && post.id == previousFencePost.id) {
                previousFencePost = post;
            }
            boardView.appendChild(post);
        }
    }

    if (game.me != null) {
        boardView.appendChild(playerView(game.me, 'me'));
        var fenceCount = 10;
        document.getElementById('myName').innerHTML = game.me.name + ' (me)';
        document.getElementById('myFenceCount').innerHTML = fenceCount + (fenceCount == 0 ? ' fence' : ' fences') + ' remaining';
        game.me.fences.forEach(function(fence) {
            if (fence.hasBeenPlayed) {
                boardView.appendChild(fenceView(fence));
            }
        });
    }
    if (game.you != null) {
        boardView.appendChild(playerView(game.you, 'you'));
        var fenceCount = 10;
        document.getElementById('yourName').innerHTML = game.you.name + ' (you)';
        document.getElementById('yourFenceCount').innerHTML = fenceCount + (fenceCount == 0 ? ' fence' : ' fences') + ' remaining';
        game.you.fences.forEach(function(fence) {
            if (fence.hasBeenPlayed) {
                boardView.appendChild(fenceView(fence));
            }
        });
    }

    var infoView = document.getElementById('gameInfo');
    infoView.innerHTML = 'Game is ' + gameIsInState(game.state);
    infoView.innerHTML = infoView.innerHTML + '
It's ' + (game.myTurn ? 'your' : 'not your') + ' turn';
    if (game.winner != null) {
        infoView.innerHTML = infoView.innerHTML + "
" + game.winner.name + " wins!";
    }

    if (previousFencePost != null) {
        previousFencePost.style.opacity = 1;
    }
}

function gameIsInState(state) {
    switch (state) {
        case 'UNKNOWN': return 'in an unknown state';
        case 'WAITING_OPPONENT': return 'waiting for opponent';
        case 'IN_PROGRESS': return 'in progress';
        case 'GAME_OVER': return 'over';
    }
    return state;
}

function fenceView(fence) {
    var view = document.createElement('div');
    view.setAttribute('class', 'fence');
    var rect = rectForFence(fence.start, fence.end);
    view.style.top = rect.y + 'px';
    view.style.left = rect.x + 'px';
    view.style.width = rect.width + 'px';
    view.style.height = rect.height + 'px';
    return view;
}

function playerView(player, id) {
    var view = document.createElement('div');
    view.setAttribute('class', 'player');
    view.setAttribute('id', id);
    var pos = positionForCell(player.position);
    view.style.top = pos.y + 'px';
    view.style.left = pos.x + 'px';
    view.innerHTML = player.name;
    return view;
}

function rectForFence(start, end) {
    var startPos = positionForPost(start);
    var endPos = positionForPost(end);
    return {
        'x': Math.min(startPos.x, endPos.x)
        ,'y': Math.min(startPos.y, endPos.y)
        ,'width': Math.max(startPos.x, endPos.x) - Math.min(startPos.x, endPos.x) + 24
        ,'height': Math.max(startPos.y, endPos.y) - Math.min(startPos.y, endPos.y) + 24
    };
}

function positionForPost(index) {
    var x = index % 10;
    var y = Math.floor(index / 10);
    return {
        'x': ((cellSpacing + ((cellWidth * x) + (cellSpacing * x)))-((26/2)+6)),
        'y': ((cellSpacing + ((cellWidth * y) + (cellSpacing * y)))-((26/2)+6))
    };
}

function positionForCell(index) {
    return {
        'x': (((index % 9) * cellWidth) + ((index % 9) * cellSpacing) + cellSpacing),
        'y': (cellSpacing + (Math.floor(index / 9))*(cellWidth+cellSpacing))
    };
}

function moveHandler(e) {
    var end = e.target.id.replace('cell','');
    console.log("moving player to " + end);
    var http = new HttpClient();
    http.post(apiUrl + '/' + currentGame().id + '/move?id=' + player().id + '&end=' + end, function(status, game) {
        if (status != 200) {
            alert(game.message);
            return;
        }

        renderGame(game);
    });
}

function postHandler(e) {
    if (previousFencePost == null) {
        previousFencePost = e.target;
        e.target.style.opacity = 1;
    } else {
        previousFencePost.style.opacity = 0.1;
        var start = previousFencePost.id.replace('post','');
        var end = e.target.id.replace('post','');
        previousFencePost = null;
        console.log("building fence from " + start + " to " + end);
        var http = new HttpClient();
        http.post(apiUrl + '/' + currentGame().id + '/fence?id=' + player().id + '&start=' + start + '&end=' + end, function(status, game) {
            if (status != 200) {
                alert(game.message);
                return;
            }

            renderGame(game);
        });
    }
}<|endoftext|>


<commit_before>$(document).ready(function() {
    var $LoginButton = $("#login-button"),
        $RegisterButton = $("#register-button"),
        oUserData = null,
        oRegisterData = null;

    $LoginButton.click(function() {
        oUserData = {
            user: $("#login-email").val(),
            password: $("#login-password").val()
        };

        $.ajax({
            url: 'rest/user/login',
            type: "POST",
            contentType: "application/json",
            data: JSON.stringify(oUserData),
            statusCode: {
                401: function() {
                    alert("Authentication failed");
                },
                200: function() {
                    alert("Authentication is fine!");
                }
            }
        });
    });

    $RegisterButton.click(function() {
        oRegisterData = {
            user: $("#register-email").val(),
            firstName: $("#register-firstName").val(),
            lastName: $("#register-lastName").val(),
            password: $("#register-password").val()
        };

        $.ajax({
                url: 'rest/user/register',
                type: "POST",
                contentType: "application/json",
                data: JSON.stringify(oRegisterData)
            })
            .success(function(data) {
                alert("Party brat");
            })
            .fail(function(data) {
                alert("Sorry brat");
            })
            .always(function() {
                $("#register-form").submit();
            });
    });
});
<commit_msg>login post method fixed<commit_after>$(document).ready(function() {
    var $LoginButton = $("#login-button"),
        $RegisterButton = $("#register-button"),
        oUserData = null,
        oRegisterData = null;

    $LoginButton.click(function() {
        oUserData = {
            user: {
                email: $("#login-email").val(),
                password: $("#login-password").val()
            }
        };

        $.ajax({
            url: 'rest/user/login',
            type: "POST",
            contentType: "application/json",
            data: JSON.stringify(oUserData),
            statusCode: {
                401: function() {
                    alert("Authentication failed");
                },
                200: function() {
                    alert("Authentication is fine!");
                }
            }
        });
    });

    $RegisterButton.click(function() {
        oRegisterData = {
            user: $("#register-email").val(),
            firstName: $("#register-firstName").val(),
            lastName: $("#register-lastName").val(),
            password: $("#register-password").val()
        };

        $.ajax({
                url: 'rest/user/register',
                type: "POST",
                contentType: "application/json",
                data: JSON.stringify(oRegisterData)
            })
            .success(function(data) {
                alert("Party brat");
            })
            .fail(function(data) {
                alert("Sorry brat");
            })
            .always(function() {
                $("#register-form").submit();
            });
    });
});
<|endoftext|>


<commit_before>import React from 'react'
import { Form, Input, TextArea, Button } from 'semantic-ui-react'

const FormExampleFieldControlId = () => (
  <Form>
    <Form.Group widths='equal'>
      <Form.Field
        id='form-input-control-first-name'
        control={Input}
        label='First name'
        placeholder='First name'
      />
      <Form.Field
        id='form-input-control-last-name'
        control={Input}
        label='Last name'
        placeholder='Last name'
      />
    </Form.Group>
    <Form.Field
      id='form-textarea-control-opinion'
      control={TextArea}
      label='Opinion'
      placeholder='Opinion'
    />
    <Form.Field
      id='form-button-control-public'
      control={Button}
      content='Confirm'
      label='Label with htmlFor'
    />
  </Form>
)

export default FormExampleFieldControlId
<commit_msg>docs(Form): add an example of accessible Form.Select (#3157)<commit_after>import React from 'react'
import { Form, Input, TextArea, Button, Select } from 'semantic-ui-react'

const genderOptions = [
  { key: 'm', text: 'Male', value: 'male' },
  { key: 'f', text: 'Female', value: 'female' },
]

const FormExampleFieldControlId = () => (
  <Form>
    <Form.Group widths='equal'>
      <Form.Field
        id='form-input-control-first-name'
        control={Input}
        label='First name'
        placeholder='First name'
      />
      <Form.Field
        id='form-input-control-last-name'
        control={Input}
        label='Last name'
        placeholder='Last name'
      />
      <Form.Field
        control={Select}
        options={genderOptions}
        label={{ children: 'Gender', htmlFor: 'form-select-control-gender' }}
        placeholder='Gender'
        search
        searchInput={{ id: 'form-select-control-gender' }}
      />
    </Form.Group>
    <Form.Field
      id='form-textarea-control-opinion'
      control={TextArea}
      label='Opinion'
      placeholder='Opinion'
    />
    <Form.Field
      id='form-button-control-public'
      control={Button}
      content='Confirm'
      label='Label with htmlFor'
    />
  </Form>
)

export default FormExampleFieldControlId
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react';
import ImageSliderItem from './ImageSliderItem';
import itemTypes from './itemTypes';
import { DropTarget } from 'react-dnd';

const cardTarget = {
  drop(props, monitor, component) {
    const dragIndex = monitor.getItem().order;
    const hoverIndex = props.order;
    const dragLocale = monitor.getItem().locale;
    const hoverLocale = props.locale;

    if(hoverLocale !== dragLocale){
      console.log('we do the action !');
      props.handleMoveItem(dragIndex, dragLocale, hoverIndex, hoverLocale);
    }
  },
  hover(props, monitor, component){
  },
};

@DropTarget(itemTypes.CARD, cardTarget, (connectDragSource, monitor) => ({
  connectDropTarget: connectDragSource.dropTarget(),
  isOver: monitor.isOver(),
  canDrop: monitor.canDrop(),
  item: monitor.getItem()
}))
class ImageSliderItemList extends React.Component{
  constructor(props){
    super(props);
  }

  _renderImageSliderItems = () => {
    const { items, handleRemoveItem, locale } = this.props;
    return items.map((item, index) => {
      const { name, order, value, id, image } = item;
      return (
        <ImageSliderItem
          name={name}
          order={index}
          value={value}
          locale={locale}
          handleRemoveItem={handleRemoveItem}
          handleMoveItem={this._handleMoveItem}
          image={image}
          id={id} />
      )
    });
  };

  _handleMoveItem = (dragIndex,dragLocale, hoverIndex, hoverLocale) => {
    const { handleMoveItem } = this.props;
    handleMoveItem(dragIndex, dragLocale, hoverIndex, hoverLocale);
  };

  render(){
    const { connectDropTarget } = this.props;
    return connectDropTarget(

        {this._renderImageSliderItems()}

    )
  }
}
ImageSliderItemList.propTypes = {
  items : PropTypes.array.isRequired,
  handleRemoveItem : PropTypes.func.isRequired,
  handleMoveItem: PropTypes.func.isRequired,
  connectDropTarget : PropTypes.func.isRequired
};

export default ImageSliderItemList;
<commit_msg>1. add style for image slider items<commit_after>import React, { PropTypes } from 'react';
import ImageSliderItem from './ImageSliderItem';
import itemTypes from './itemTypes';
import { DropTarget } from 'react-dnd';
const styles = {
  container : {
    border: '1px solid black',
    padding : '10px',
    marginTop : '10px',
    minHeight : '100px'
  }
};

const cardTarget = {
  drop(props, monitor, component) {
    const dragIndex = monitor.getItem().order;
    const hoverIndex = props.order;
    const dragLocale = monitor.getItem().locale;
    const hoverLocale = props.locale;

    if(hoverLocale !== dragLocale){
      console.log('we do the action !');
      props.handleMoveItem(dragIndex, dragLocale, hoverIndex, hoverLocale);
    }
  },
  hover(props, monitor, component){
  },
};

@DropTarget(itemTypes.CARD, cardTarget, (connectDragSource, monitor) => ({
  connectDropTarget: connectDragSource.dropTarget(),
  isOver: monitor.isOver(),
  canDrop: monitor.canDrop(),
  item: monitor.getItem()
}))
class ImageSliderItemList extends React.Component{
  constructor(props){
    super(props);
  }

  _renderImageSliderItems = () => {
    const { items, handleRemoveItem, locale } = this.props;
    const itemList = [];

    items.map((item, i) => {
      const { name, order, value, id, image } = item;
      if (item !== undefined) {
        itemList.push(
          <ImageSliderItem
            name={name}
            order={i}
            value={value}
            locale={locale}
            handleRemoveItem={handleRemoveItem}
            handleMoveItem={this._handleMoveItem}
            image={image}
            id={id}/>
        )
      }
    });
    return itemList;
  };

  _handleMoveItem = (dragIndex,dragLocale, hoverIndex, hoverLocale) => {
    const { handleMoveItem } = this.props;
    handleMoveItem(dragIndex, dragLocale, hoverIndex, hoverLocale);
  };

  render(){
    const { connectDropTarget } = this.props;
    return connectDropTarget(

        {this._renderImageSliderItems()}

    )
  }
}
ImageSliderItemList.propTypes = {
  items : PropTypes.array.isRequired,
  handleRemoveItem : PropTypes.func.isRequired,
  handleMoveItem: PropTypes.func.isRequired,
  connectDropTarget : PropTypes.func.isRequired
};

export default ImageSliderItemList;
<|endoftext|>