<commit_before>/*global define*/
/*
 * Transr.js
 * Minimalistic CSS3 Transitions and translations helper with feature detection and fallback
 *
 * Juhani Pelli <juhani.pelli@gmail.com>
 * https://github.com/unkhz/transr.js/
 *
 * MIT License
 *
 */

;(function (root, factory) {
    if ( typeof define === 'function' && define.amd ) {
        //Allow using this built library as an AMD module
        //in another project. That other project will only
        //see this AMD call, not the internal modules in
        //the closure below.
        define([], factory);
    } else {
        //Browser globals case. Just assign the
        //result to a property on the global.
        root.Transr = factory(root);
    }
}(this, function (root) {

    var
        // minification optimization
        arraySlice = Array.prototype.slice,

        // default properties for transition
        globalDefaults = {
            el:null,
            duration:"0.5s",
            timingFunction:"ease",
            delay:"0s",
            fallback:null,          // method to excecute if tests fail
            complete:null,          // method to execute upon completion of transition
            fail:false,             // force transition to fail
            // translate specific settings
            use3d:true,             // use translate3d if possible
            immediate:false         // skip transition entirely for faster response
        },
        testEl = document.createElement('div'),
        properties = {},
        possibleTransforms = {};

    function isValid(value) {
        return value !== undefined && value !== null;
    }

    // object helper method, copied from Mirin.js
    function extend() {
        var dest = arguments[0],
            rest = arraySlice.call(arguments,1),
            i,j,len;
        for ( i=0,len=rest.length;i<len;i++ ) {
            var src = rest[i];
            if ( src ) {
                for ( j in src ) {
                    dest[j] = src[j];
                }
            }
        }
        return dest;
    }

    function getStyleProperty(property) {
        if ( properties[property] ) { return properties[property]; }

        var returnProperty;
        if ( testEl.style[property] !== undefined ) {
          returnProperty = property;
        }
        for ( var i=0,prefixes=["webkit","moz","o","ms"],len=prefixes.length; i<len; i++ ) {
          var prefixedProperty = prefixes[i]+property.charAt(0).toUpperCase()+property.slice(1);
          if ( document.body.style[prefixedProperty] !== undefined ) {
            returnProperty = prefixedProperty;
          }
        }
        return properties[property] = returnProperty;
    }

    function getStyleCssProperty(property) {
        var p = getStyleProperty(property);
        if ( p !== property ) {
            return '-' + p.replace(/([A-Z])/g, '-' + '$1').toLowerCase();
        } else {
            return p;
        }
    }

    function canTransform(transformFunction) {
        var transformProp = getStyleProperty('transform');

        if ( !transformProp ) { return false; }

        if ( possibleTransforms[transformFunction] !== undefined ) { return possibleTransforms[transformFunction]; }

        var el = document.createElement('div');
        el.style[transformProp] = "";
        el.style[transformProp] = transformFunction;

        document.body.appendChild(el);
        var compiledTransform = el.style[transformProp],
            has = typeof compiledTransform === typeof "" && compiledTransform.length > 0;
        document.body.removeChild(el);

        return possibleTransforms[transformFunction] = has;
    }

    function buildDimensionString(val, aMethod) {
        var method = aMethod || 'translate',
            map = {
                translate:'px',
                rotate:'deg',
                scale:'',
                skew:'deg'
            }, suffix = map[method];
        // undefined == 0, null == null
        if ( val === undefined ) { val = "0" + suffix; }
        return typeof val ===  typeof 1 ? val.toString() + suffix : val;
    }

    function unbindTransitionEnd(el, listener) {
        try {
            el.removeEventListener("webkitTransitionEnd", listener);
            el.removeEventListener("transitionend", listener);
            el.removeEventListener("oTransitionEnd", listener);
        } catch(ee) {

        }
    }

    function bindTransitionEnd(el, listener) {
        try {
            el.addEventListener("webkitTransitionEnd", listener);
            el.addEventListener("transitionend", listener);
            el.addEventListener("oTransitionEnd", listener);
        } catch(ee) {

        }
    }

    function asMS(str) {
        return Number(str.replace(/[^0-9.]/g,'')) * 1000;
    }

    // set any style property value with transition and fallback
    function transition(options) {
        var transitionShorthandProperty = getStyleProperty("transition"),
            transitionProperty = getStyleProperty("transitionProperty"),
            transitionDuration = getStyleProperty("transitionDuration"),
            transitionTimingFunction = getStyleProperty("transitionTimingFunction"),
            transitionDelay = getStyleProperty("transitionDelay"),
            vendorSpecificProperty = getStyleProperty(options.property),
            enabled = transitionProperty && transitionDuration && transitionTimingFunction && vendorSpecificProperty ? true : false,
            endTimeoutId;

        if ( !enabled || options.fail ) {
            // fallback
            if ( options.fallback ) {
                options.fallback();
            } else {
                options.el.style[vendorSpecificProperty] = options.value;
            }
            if (options.complete) { options.complete(options.el, options.property); }
        } else {
            var el = options.el,
                vendor = transitionProperty.replace(/Transition.*$/, ''),
                vendorCSSProperty = getStyleCssProperty(options.property),
                transitionValue = vendorCSSProperty + " " + options.duration + " " + options.timingFunction + " " + options.delay,
                durationInMS = asMS(options.duration) + asMS(options.delay),
                fallbackDurationInMS = durationInMS + 1500,
                transitionEnded = false,

                onTransitionEnd = function(e){
                    // console.log("Transr onTransitionEnd", e ? e.target : 'no event', transitionShorthandProperty, vendorSpecificProperty, transitionValue, el.id, fallbackDurationInMS);

                    // check that we react on the correct element and property
                    if ( e.target !== el || e.propertyName !==  vendorCSSProperty ) { return; }

                    if ( transitionEnded ) { return; }
                    transitionEnded = true;

                    unbindTransitionEnd(options.el, onTransitionEnd);

                    //console.log("Transr reset transition", el.id, transformValue);
                    el.style[transitionShorthandProperty] = "";
                    el.style[vendorSpecificProperty] = options.value;

                    // make sure all possible fallback timeouts get cleared
                    clearTimeout(endTimeoutId);

                    if (options.complete) { options.complete(options.el, options.property); }
                };

            /*console.log("Transr", "transition", el.id ? el.id : el.nodeName,
                "|", transitionShorthandProperty, transitionValue,
                "|", "el.style."+vendorSpecificProperty, "=", options.value
            );*/

            //console.log(transitionShorthandProperty, transitionValue);
            options.el.style[transitionShorthandProperty] = transitionValue;

            //console.log(options.el.style[vendorSpecificProperty], options.value);

            // if we're already there, transitionend won't fire, so we need to complete asap
            if ( options.el.style[vendorSpecificProperty] === options.value ) {
                fallbackDurationInMS = 1;
            } else {
                options.el.style[vendorSpecificProperty] = options.value;
                // listen to transitionend event on real browsers, unless the duration is 0
                if ( durationInMS === 0 ) {
                    fallbackDurationInMS = 1;
                } else {
                    // FIXME: this does not actually unbind the earlier transitions since the function is always new
                    unbindTransitionEnd(options.el, onTransitionEnd);
                    bindTransitionEnd(options.el, onTransitionEnd);
                }

            }

            // fallback a little later, make sure old timeout is cleared when new transition is issued
            clearTimeout(endTimeoutId);
            endTimeoutId = setTimeout(onTransitionEnd, fallbackDurationInMS, {
                target:options.el,
                propertyName:vendorCSSProperty
            });

        }
    }

    function buildTransformFunctionString(options, transformProp) {
        var i,j,ilen,jlen,k,v,
            methods = ['translate','rotate','scale','skew'],
            axes = ['X','Y','Z'],
            str = options.el.style[transformProp] + " ";
        for ( i=0, ilen=methods.length;i<ilen;i++ ) {
            for ( j=0, jlen=axes.length;j<jlen;j++ ) {
                k=methods[i]+axes[j];
                v=options[k];
                if ( isValid(v) ) {
                    str += k + '(' + buildDimensionString(v,methods[i]) + ') ';
                }
            }
        }
        return str.replace(/\s+$/,'');
    }

    function transform(options) {
        var parentFallback = options.fallback,
            transformProp = getStyleProperty('transform'),
            transformValue = (options.value ?
                (options.value.join ?
                    options.value.join(' ') :
                    options.value) :
                buildTransformFunctionString(options, transformProp)),
            needs3d = !!transformValue.match(/Z/);

        if ( options.use3d && canTransform('translate3d(0,0,0)') ) {
            // 3d works
        } else if ( canTransform('translate(0,0)') && !needs3d ) {
            // 2d transform can only be used if Z was not defined
        } else {
            options.fail = true;
        }

        if ( options.immediate && transformProp && !options.fail ) {
            // skip timeouts and whatnot if we are not going to fail
            set(
                options.el,
                transformProp,
                transformValue
            );
            if ( options.complete ) { options.complete(options.el, 'transform'); }
        } else {
            transition(extend(options,{
                property:"transform",
                value:transformValue,
                fallback:function(){
                    if ( parentFallback ) {
                        // falls back if transition failed, even if transform works, e.g IE9
                        parentFallback();
                    } else if ( transformProp && transformValue ) {
                        set(options.el, transformProp, transformValue);
                    } else {
                        // if nothing works and we don't even have fallback
                        // defined, try fixing the situation with left/top
                        // even though it will most likely break
                        if ( (options.translateX !== undefined || options.translateY !== undefined) &&
                            ( !options.el.style.position || options.el.style.position === 'static' )
                        ) {
                            options.el.style.position = 'relative';
                        }

                        if ( isValid(options.translateX) ) { options.el.style.left = options.translateX; }
                        if ( isValid(options.translateY) ) { options.el.style.top = options.translateY; }
                    }
                }
            }));
        }
    }

    function transformWithPoint(options, methodName) {
        if ( isValid(options.x) ) { options[methodName+'X'] = options.x; }
        if ( isValid(options.y) ) { options[methodName+'Y'] = options.y; }
        if ( isValid(options.z) ) { options[methodName+'Z'] = options.z; }
        transform(options);
    }

    // set any style property value with fallback, but without transition
    function set(el, property, value, fallbackProperty, fallbackValue) {
        var transitionProperty = getStyleProperty("transition"),
            vendorSpecificProperty = getStyleProperty(property);

        if ( !vendorSpecificProperty ) {
            // fallback
            if ( fallbackProperty ) {
                el.style[fallbackProperty] = fallbackValue !== undefined ? fallbackValue : value;
            }
        } else {
            if ( transitionProperty && el.style[transitionProperty] ) {
                // force no transition
                var oldVal = el.style[transitionProperty];
                el.style[transitionProperty] = "";
                el.style[vendorSpecificProperty] = value;
                //el.style[transitionProperty] = oldVal;
            } else {
                el.style[vendorSpecificProperty] = value;
            }
            //console.log("Transr set", vendorSpecificProperty, value);
        }
    }

    // process possibly multiple sets of parameters with single method
    function process(method, params, callSpecificDefaults, transformMethodName) {
        if ( Object.prototype.toString.call(params) !== '[object Array]' ) { params = [params]; }
        for ( var i=0, len=params.length; i<len; i++ ) {
            method(extend({}, globalDefaults, callSpecificDefaults, params[i]), transformMethodName);
        }
    }

    // public api methods
    return {
        getStyleProperty:getStyleProperty,
        canTransform:canTransform,
        set:set,
        transition:function(options, defaults) {
            process(transition, options, defaults);
        },
        transform:function(options, defaults) {
            process(transform, options, defaults);
        },
        translate:function(options,defaults) {
            process(transformWithPoint, options, defaults, 'translate');
        },
        rotate:function(options,defaults) {
            process(transformWithPoint, options, defaults, 'rotate');
        },
        scale:function(options,defaults) {
            process(transformWithPoint, options, defaults, 'scale');
        },
        skew:function(options,defaults) {
            process(transformWithPoint, options, defaults, 'skew');
        }
    };

}));
<commit_msg>Replace existing transform functions instead of adding duplicates<commit_after>/*global define*/
/*
 * Transr.js
 * Minimalistic CSS3 Transitions and translations helper with feature detection and fallback
 *
 * Juhani Pelli <juhani.pelli@gmail.com>
 * https://github.com/unkhz/transr.js/
 *
 * MIT License
 *
 */

;(function (root, factory) {
    if ( typeof define === 'function' && define.amd ) {
        //Allow using this built library as an AMD module
        //in another project. That other project will only
        //see this AMD call, not the internal modules in
        //the closure below.
        define([], factory);
    } else {
        //Browser globals case. Just assign the
        //result to a property on the global.
        root.Transr = factory(root);
    }
}(this, function (root) {

    var
        // minification optimization
        arraySlice = Array.prototype.slice,

        // default properties for transition
        globalDefaults = {
            el:null,
            duration:"0.5s",
            timingFunction:"ease",
            delay:"0s",
            fallback:null,          // method to excecute if tests fail
            complete:null,          // method to execute upon completion of transition
            fail:false,             // force transition to fail
            // translate specific settings
            use3d:true,             // use translate3d if possible
            immediate:false         // skip transition entirely for faster response
        },
        testEl = document.createElement('div'),
        properties = {},
        possibleTransforms = {};

    function isValid(value) {
        return value !== undefined && value !== null;
    }

    // object helper method, copied from Mirin.js
    function extend() {
        var dest = arguments[0],
            rest = arraySlice.call(arguments,1),
            i,j,len;
        for ( i=0,len=rest.length;i<len;i++ ) {
            var src = rest[i];
            if ( src ) {
                for ( j in src ) {
                    dest[j] = src[j];
                }
            }
        }
        return dest;
    }

    function getStyleProperty(property) {
        if ( properties[property] ) { return properties[property]; }

        var returnProperty;
        if ( testEl.style[property] !== undefined ) {
          returnProperty = property;
        }
        for ( var i=0,prefixes=["webkit","moz","o","ms"],len=prefixes.length; i<len; i++ ) {
          var prefixedProperty = prefixes[i]+property.charAt(0).toUpperCase()+property.slice(1);
          if ( document.body.style[prefixedProperty] !== undefined ) {
            returnProperty = prefixedProperty;
          }
        }
        return properties[property] = returnProperty;
    }

    function getStyleCssProperty(property) {
        var p = getStyleProperty(property);
        if ( p !== property ) {
            return '-' + p.replace(/([A-Z])/g, '-' + '$1').toLowerCase();
        } else {
            return p;
        }
    }

    function canTransform(transformFunction) {
        var transformProp = getStyleProperty('transform');

        if ( !transformProp ) { return false; }

        if ( possibleTransforms[transformFunction] !== undefined ) { return possibleTransforms[transformFunction]; }

        var el = document.createElement('div');
        el.style[transformProp] = "";
        el.style[transformProp] = transformFunction;

        document.body.appendChild(el);
        var compiledTransform = el.style[transformProp],
            has = typeof compiledTransform === typeof "" && compiledTransform.length > 0;
        document.body.removeChild(el);

        return possibleTransforms[transformFunction] = has;
    }

    function buildDimensionString(val, aMethod) {
        var method = aMethod || 'translate',
            map = {
                translate:'px',
                rotate:'deg',
                scale:'',
                skew:'deg'
            }, suffix = map[method];
        // undefined == 0, null == null
        if ( val === undefined ) { val = "0" + suffix; }
        return typeof val ===  typeof 1 ? val.toString() + suffix : val;
    }

    function unbindTransitionEnd(el, listener) {
        try {
            el.removeEventListener("webkitTransitionEnd", listener);
            el.removeEventListener("transitionend", listener);
            el.removeEventListener("oTransitionEnd", listener);
        } catch(ee) {

        }
    }

    function bindTransitionEnd(el, listener) {
        try {
            el.addEventListener("webkitTransitionEnd", listener);
            el.addEventListener("transitionend", listener);
            el.addEventListener("oTransitionEnd", listener);
        } catch(ee) {

        }
    }

    function asMS(str) {
        return Number(str.replace(/[^0-9.]/g,'')) * 1000;
    }

    // set any style property value with transition and fallback
    function transition(options) {
        var transitionShorthandProperty = getStyleProperty("transition"),
            transitionProperty = getStyleProperty("transitionProperty"),
            transitionDuration = getStyleProperty("transitionDuration"),
            transitionTimingFunction = getStyleProperty("transitionTimingFunction"),
            transitionDelay = getStyleProperty("transitionDelay"),
            vendorSpecificProperty = getStyleProperty(options.property),
            enabled = transitionProperty && transitionDuration && transitionTimingFunction && vendorSpecificProperty ? true : false,
            endTimeoutId;

        if ( !enabled || options.fail ) {
            // fallback
            if ( options.fallback ) {
                options.fallback();
            } else {
                options.el.style[vendorSpecificProperty] = options.value;
            }
            if (options.complete) { options.complete(options.el, options.property); }
        } else {
            var el = options.el,
                vendor = transitionProperty.replace(/Transition.*$/, ''),
                vendorCSSProperty = getStyleCssProperty(options.property),
                transitionValue = vendorCSSProperty + " " + options.duration + " " + options.timingFunction + " " + options.delay,
                durationInMS = asMS(options.duration) + asMS(options.delay),
                fallbackDurationInMS = durationInMS + 1500,
                transitionEnded = false,

                onTransitionEnd = function(e){
                    // console.log("Transr onTransitionEnd", e ? e.target : 'no event', transitionShorthandProperty, vendorSpecificProperty, transitionValue, el.id, fallbackDurationInMS);

                    // check that we react on the correct element and property
                    if ( e.target !== el || e.propertyName !==  vendorCSSProperty ) { return; }

                    if ( transitionEnded ) { return; }
                    transitionEnded = true;

                    unbindTransitionEnd(options.el, onTransitionEnd);

                    //console.log("Transr reset transition", el.id, transformValue);
                    el.style[transitionShorthandProperty] = "";
                    el.style[vendorSpecificProperty] = options.value;

                    // make sure all possible fallback timeouts get cleared
                    clearTimeout(endTimeoutId);

                    if (options.complete) { options.complete(options.el, options.property); }
                };

            /*console.log("Transr", "transition", el.id ? el.id : el.nodeName,
                "|", transitionShorthandProperty, transitionValue,
                "|", "el.style."+vendorSpecificProperty, "=", options.value
            );*/

            //console.log(transitionShorthandProperty, transitionValue);
            options.el.style[transitionShorthandProperty] = transitionValue;

            //console.log(options.el.style[vendorSpecificProperty], options.value);

            // if we're already there, transitionend won't fire, so we need to complete asap
            if ( options.el.style[vendorSpecificProperty] === options.value ) {
                fallbackDurationInMS = 1;
            } else {
                options.el.style[vendorSpecificProperty] = options.value;
                // listen to transitionend event on real browsers, unless the duration is 0
                if ( durationInMS === 0 ) {
                    fallbackDurationInMS = 1;
                } else {
                    // FIXME: this does not actually unbind the earlier transitions since the function is always new
                    unbindTransitionEnd(options.el, onTransitionEnd);
                    bindTransitionEnd(options.el, onTransitionEnd);
                }

            }

            // fallback a little later, make sure old timeout is cleared when new transition is issued
            clearTimeout(endTimeoutId);
            endTimeoutId = setTimeout(onTransitionEnd, fallbackDurationInMS, {
                target:options.el,
                propertyName:vendorCSSProperty
            });

        }
    }

    function buildTransformFunctionString(options, transformProp) {
        var i,j,ilen,jlen,k,v,
            methods = ['translate','rotate','scale','skew'],
            axes = ['X','Y','Z'],
            str = options.el.style[transformProp] + " ";
        for ( i=0, ilen=methods.length;i<ilen;i++ ) {
            for ( j=0, jlen=axes.length;j<jlen;j++ ) {
                k=methods[i]+axes[j];
                v=options[k];
                if ( isValid(v) ) {
                    str = str.replace(new RegExp(k+'\\([^\\)]*\\)\\s+'), ' ');
                    str += k + '(' + buildDimensionString(v,methods[i]) + ') ';
                }
            }
        }
        return str.replace(/\s+$/,'');
    }

    function transform(options) {
        var parentFallback = options.fallback,
            transformProp = getStyleProperty('transform'),
            transformValue = (options.value ?
                (options.value.join ?
                    options.value.join(' ') :
                    options.value) :
                buildTransformFunctionString(options, transformProp)),
            needs3d = !!transformValue.match(/Z/);

        if ( options.use3d && canTransform('translate3d(0,0,0)') ) {
            // 3d works
        } else if ( canTransform('translate(0,0)') && !needs3d ) {
            // 2d transform can only be used if Z was not defined
        } else {
            options.fail = true;
        }

        if ( options.immediate && transformProp && !options.fail ) {
            // skip timeouts and whatnot if we are not going to fail
            set(
                options.el,
                transformProp,
                transformValue
            );
            if ( options.complete ) { options.complete(options.el, 'transform'); }
        } else {
            transition(extend(options,{
                property:"transform",
                value:transformValue,
                fallback:function(){
                    if ( parentFallback ) {
                        // falls back if transition failed, even if transform works, e.g IE9
                        parentFallback();
                    } else if ( transformProp && transformValue ) {
                        set(options.el, transformProp, transformValue);
                    } else {
                        // if nothing works and we don't even have fallback
                        // defined, try fixing the situation with left/top
                        // even though it will most likely break
                        if ( (options.translateX !== undefined || options.translateY !== undefined) &&
                            ( !options.el.style.position || options.el.style.position === 'static' )
                        ) {
                            options.el.style.position = 'relative';
                        }

                        if ( isValid(options.translateX) ) { options.el.style.left = options.translateX; }
                        if ( isValid(options.translateY) ) { options.el.style.top = options.translateY; }
                    }
                }
            }));
        }
    }

    function transformWithPoint(options, methodName) {
        if ( isValid(options.x) ) { options[methodName+'X'] = options.x; }
        if ( isValid(options.y) ) { options[methodName+'Y'] = options.y; }
        if ( isValid(options.z) ) { options[methodName+'Z'] = options.z; }
        transform(options);
    }

    // set any style property value with fallback, but without transition
    function set(el, property, value, fallbackProperty, fallbackValue) {
        var transitionProperty = getStyleProperty("transition"),
            vendorSpecificProperty = getStyleProperty(property);

        if ( !vendorSpecificProperty ) {
            // fallback
            if ( fallbackProperty ) {
                el.style[fallbackProperty] = fallbackValue !== undefined ? fallbackValue : value;
            }
        } else {
            if ( transitionProperty && el.style[transitionProperty] ) {
                // force no transition
                var oldVal = el.style[transitionProperty];
                el.style[transitionProperty] = "";
                el.style[vendorSpecificProperty] = value;
                //el.style[transitionProperty] = oldVal;
            } else {
                el.style[vendorSpecificProperty] = value;
            }
            //console.log("Transr set", vendorSpecificProperty, value);
        }
    }

    // process possibly multiple sets of parameters with single method
    function process(method, params, callSpecificDefaults, transformMethodName) {
        if ( Object.prototype.toString.call(params) !== '[object Array]' ) { params = [params]; }
        for ( var i=0, len=params.length; i<len; i++ ) {
            method(extend({}, globalDefaults, callSpecificDefaults, params[i]), transformMethodName);
        }
    }

    // public api methods
    return {
        getStyleProperty:getStyleProperty,
        canTransform:canTransform,
        set:set,
        transition:function(options, defaults) {
            process(transition, options, defaults);
        },
        transform:function(options, defaults) {
            process(transform, options, defaults);
        },
        translate:function(options,defaults) {
            process(transformWithPoint, options, defaults, 'translate');
        },
        rotate:function(options,defaults) {
            process(transformWithPoint, options, defaults, 'rotate');
        },
        scale:function(options,defaults) {
            process(transformWithPoint, options, defaults, 'scale');
        },
        skew:function(options,defaults) {
            process(transformWithPoint, options, defaults, 'skew');
        }
    };

}));
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';

class Home extends Component {
	constructor(props, context) {
		super(props, context);
		console.log(props, context);
		this.handleSubmit = this.handleSubmit.bind(this);
	}

	handleSubmit (e) {
		e.preventDefault();
		this.context.router.push(`${this._input.value}`);
	}

	render() {
		return (

				<form
					className="form-inline"
					role="form"
					onSubmit={this.handleSubmit}
				>

							<input
								type="text"
								placeholder="Enter a GitHub user..."
								className="form-control"
								ref={ref => (this._input = ref)}
							/>

					<button type="submit" className="btn btn-primary">
						Go
					</button>
				</form>

		);
	}
}

Home.contextTypes = {
	muiTheme: PropTypes.object.isRequired,
	router: PropTypes.object.isRequired
}

export default Home;<commit_msg>remove useless stuff from Home<commit_after>import React, { Component, PropTypes } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';

class Home extends Component {
	constructor(props, context) {
		super(props, context);
		console.log(props, context);
		this.handleSubmit = this.handleSubmit.bind(this);
	}

	handleSubmit (e) {
		e.preventDefault();
		this.context.router.push(`${this._input.value}`);
	}

	render() {
		return null;
	}
}

Home.contextTypes = {
	muiTheme: PropTypes.object.isRequired,
	router: PropTypes.object.isRequired
}

export default Home;<|endoftext|>


<commit_before>var ctlMod = angular.module( "linksWeb.controller-logout", [] );
<commit_msg>Fix logout controller<commit_after>var ctlMod = angular.module( "linksWeb.controller-logout", [] );

ctlMod.controller( "Logout", [ "$scope", function ( $scope ) {
} ] );
<|endoftext|>


<commit_before>import React from 'react'
import Page from 'components/Page'
import autobind from 'autobind-decorator'

import {Alert, Radio, Table, Modal, Button} from 'react-bootstrap'
import {Link} from 'react-router'

import RadioGroup from 'components/RadioGroup'
import Breadcrumbs from 'components/Breadcrumbs'
import LinkTo from 'components/LinkTo'
import ReportCollection from 'components/ReportCollection'
import Form from 'components/Form'
import Messages from 'components/Messages'

import API from 'api'
import {Person, Organization, Position, Poam} from 'models'

const QUERY_STRINGS = {
	reports: {
		pendingApprovalOf: "reports pending your approval",
		authorOrgId: "reports recently authored by your organization",
		authorId: "reports you recently authored",
	},
	organizations: "Organizations TODO",
	people: "People TODO",
}

const SEARCH_CONFIG = {
	"reports" : {
		listName : "reports: reportList",
		variableType: "ReportSearchQuery",
		fields : `id, intent, engagementDate, keyOutcomes, nextSteps, cancelledReason,
			author { id, name }
			primaryAdvisor { id, name, role, position { organization { id, shortName}}},
			primaryPrincipal { id, name, role, position { organization { id, shortName}}},
			advisorOrg { id, shortName},
			principalOrg { id, shortName},
			location { id, name, lat, lng},
			poams {id, shortName, longName}`
	},
	"persons" : {
		listName : "people: peopleList",
		variableType: "PersonSearchQuery",
		fields: "id, name, rank, emailAddress, role , position { id, name, organization { id, shortName} }"
	},
	"positions" : {
		listName: "positions: positionList",
		variableType: "PositionSearchQuery",
		fields: "id , name, type, organization { id, shortName}, person { id, name }"
	},
	"poams" : {
		listName: "poams: poamList",
		variableType: "PoamSearchQuery",
		fields: "id, shortName, longName"
	},
	"locations" : {
		listName: "locations: locationList",
		variableType: "LocationSearchQuery",
		fields : "id, name, lat, lng"
	},
	"organizations" : {
		listName: "organizations: organizationList",
		variableType: "OrganizationSearchQuery",
		fields: "id, shortName, longName"
	}
};

export default class Search extends Page {
	constructor(props) {
		super(props)

		this.state = {
			query: props.location.query.q,
			saveSearch: {show: false},
			results: {
				reports: null,
				people: null,
				organizations: null,
				positions: null,
				location: null,
				poams: null
			},
			error: null,
			success: null
		}
	}

	fetchData(props) {
		let type = props.location.query.type
		let text = props.location.query.text

		//Any query with a field other than 'text' and 'type' is an advanced query.
		let advQuery = Object.without(props.location.query, "type", "text")
		let isAdvQuery = Object.keys(advQuery).length;
		advQuery.text = text;

		if (isAdvQuery) {
			let config = SEARCH_CONFIG[type];
			API.query(/* GraphQL */
					`${config.listName} (f:search, query:$query) {
							pageNum, pageSize, totalCount, list { ${config.fields} }
					}`,
					{ query: advQuery},
					`($query: ${config.variableType} )`
				).then( data => {
				this.setState({results: data})
			}).catch(response =>
				this.setState({error: response})
			)
		} else {
			this.setState({text})
			//TODO: escape query in the graphQL query
			API.query(/* GraphQL */`
				searchResults(f:search, q:"${text}") {
					reports { totalCount, list { ${SEARCH_CONFIG.reports.fields}} }
					people { totalCount, list { ${SEARCH_CONFIG.persons.fields}} }
					positions { totalCount, list { ${SEARCH_CONFIG.positions.fields} }}
					poams { totalCount, list { ${SEARCH_CONFIG.poams.fields} }}
					locations { totalCount, list { ${SEARCH_CONFIG.locations.fields} }}
					organizations { totalCount, list { ${SEARCH_CONFIG.organizations.fields} }}
				}
			`).then(data =>
				this.setState({results: data.searchResults})
			).catch(response => {
				this.setState({error: response})
			})
		}
	}

	static pageProps = {
		navElement:

				<Link to="/">< Return to previous page</Link>

				<RadioGroup vertical size="large" style={{width: '100%'}}>
					<Radio value="all">Everything</Radio>
					<Radio value="reports">Reports</Radio>
					<Radio value="people">People</Radio>
					<Radio value="positions">Positions</Radio>
					<Radio value="locations">Locations</Radio>
					<Radio value="organizations">Organizations</Radio>
				</RadioGroup>

	}

	render() {
		let results = this.state.results
		let error = this.state.error
		let success = this.state.success

		let numResults = (results.reports ? results.reports.totalCount : 0) +
			(results.people ? results.people.totalCount : 0) +
			(results.positions ? results.positions.totalCount : 0) +
			(results.locations ? results.locations.totalCount : 0) +
			(results.organizations ? results.organizations.totalCount : 0)

		let noResults = numResults === 0

		let query = this.props.location.query
		let queryString = QUERY_STRINGS[query.type] || query.q || "TODO"

		if (typeof queryString === 'object') {
			queryString = queryString[Object.keys(query)[1]]
		}

		return (

				<Breadcrumbs items={[['Searching for ' + queryString, '/search']]} />

				<Messages error={error} success={success} />

				{noResults &&
					<Alert bsStyle="warning">
						No search results found!
					</Alert>
				}

					{this.props.location.query.text && <Button onClick={this.showSaveModal}>Save search</Button>}

				{results.reports && results.reports.totalCount > 0 &&
					<fieldset>
						<legend>Reports</legend>
						<ReportCollection reports={this.state.results.reports.list} />
					</fieldset>
				}

				{results.people && results.people.totalCount > 0 &&
					<fieldset>
						<legend>People</legend>
						{this.renderPeople()}
					</fieldset>
				}

				{results.organizations && results.organizations.totalCount > 0 &&
					<fieldset>
						<legend>Organizations</legend>
						{this.renderOrgs()}
					</fieldset>
				}

				{results.positions && results.positions.totalCount > 0 &&
					<fieldset>
						<legend>Positions</legend>
						{this.renderPositions()}
					</fieldset>
				}

				{results.locations && results.locations.totalCount > 0 &&
					<fieldset>
						<legend>Locations</legend>
						{this.renderLocations()}
					</fieldset>
				}

				{results.poams && results.poams.totalCount > 0 &&
					<fieldset>
						<legend>PoAMs</legend>
						{this.renderPoams()}
					</fieldset>
				}

				{this.state.saveSearch.show && this.renderSaveModal() }

		)
	}

	renderPeople() {
		return

					Name
					Position
					Org

				{Person.map(this.state.results.people.list, person =>

							<LinkTo person={person}>{person.rank} {person.name}</LinkTo>

						{person.phoneNumber}
						{person.position && <LinkTo position={person.position} />}
						{person.position && person.position.organization && <LinkTo organization={person.position.organization} />}

				)}

	}

	renderOrgs() {
		return

					Name
					Description
					Type

				{Organization.map(this.state.results.organizations.list, org =>

						<LinkTo organization={org} />
						{org.longName}
						{org.type}

				)}

	}

	renderPositions() {
		return

					Name
					Org
					Current Occupant

				{Position.map(this.state.results.positions.list, pos =>

							<LinkTo position={pos} >{pos.code} {pos.name}</LinkTo>

						{pos.organization && <LinkTo organization={pos.organization} />}
						{pos.person && <LinkTo person={pos.person} />}

				)}

	}

	renderLocations() {
		return

					Name

				{this.state.results.locations.list.map(loc =>

						<LinkTo location={loc} />

				)}

	}

	renderPoams() {
		return

					Name

				{Poam.map(this.state.results.poams.list, poam =>

						<LinkTo poam={poam} >{poam.shortName} {poam.longName}</LinkTo>

				)}

	}

	renderSaveModal() {
		return <Modal show={this.state.saveSearch.show} onHide={this.closeSaveModal}>
			<Modal.Header closeButton>
				<Modal.Title>Save search</Modal.Title>
			</Modal.Header>

			<Modal.Body>
				<Form formFor={this.state.saveSearch} onChange={this.onChangeSaveSearch}
					onSubmit={this.onSubmitSaveSearch} submitText={false}>
					<Form.Field id="name" placeholder="Give this saved search a name" />
					<Button type="submit" bsStyle="primary">Save</Button>
				</Form>
			</Modal.Body>
		</Modal>
	}

	@autobind
	onChangeSaveSearch() {
		let search = this.state.saveSearch;
		this.setState({saveSearch: search})
	}

	@autobind
	onSubmitSaveSearch(event) {
		event.stopPropagation()
		event.preventDefault()

		let search = Object.without(this.state.saveSearch, "show")
		search.query = this.props.location.query.q

		API.send('/api/savedSearches/new', search, {disableSubmits: true})
			.then(response => {
				if (response.code) throw response.code
				this.setState({
					success: "Search successfully saved!",
					saveSearch: {show: false}
				})
				window.scrollTo(0, 0)
			}).catch(response => {
				this.setState({
					error: response,
					saveSearch: { show: false}
				})
				window.scrollTo(0, 0)
			})
	}

	@autobind
	showSaveModal() {
		this.setState({saveSearch: {show: true, name: ''}})
	}

	@autobind
	closeSaveModal() {
		this.setState({saveSearch: {show: false}});
	}
}
<commit_msg>Fix parameter for actually saving a search<commit_after>import React from 'react'
import Page from 'components/Page'
import autobind from 'autobind-decorator'

import {Alert, Radio, Table, Modal, Button} from 'react-bootstrap'
import {Link} from 'react-router'

import RadioGroup from 'components/RadioGroup'
import Breadcrumbs from 'components/Breadcrumbs'
import LinkTo from 'components/LinkTo'
import ReportCollection from 'components/ReportCollection'
import Form from 'components/Form'
import Messages from 'components/Messages'

import API from 'api'
import {Person, Organization, Position, Poam} from 'models'

const QUERY_STRINGS = {
	reports: {
		pendingApprovalOf: "reports pending your approval",
		authorOrgId: "reports recently authored by your organization",
		authorId: "reports you recently authored",
	},
	organizations: "Organizations TODO",
	people: "People TODO",
}

const SEARCH_CONFIG = {
	"reports" : {
		listName : "reports: reportList",
		variableType: "ReportSearchQuery",
		fields : `id, intent, engagementDate, keyOutcomes, nextSteps, cancelledReason,
			author { id, name }
			primaryAdvisor { id, name, role, position { organization { id, shortName}}},
			primaryPrincipal { id, name, role, position { organization { id, shortName}}},
			advisorOrg { id, shortName},
			principalOrg { id, shortName},
			location { id, name, lat, lng},
			poams {id, shortName, longName}`
	},
	"persons" : {
		listName : "people: peopleList",
		variableType: "PersonSearchQuery",
		fields: "id, name, rank, emailAddress, role , position { id, name, organization { id, shortName} }"
	},
	"positions" : {
		listName: "positions: positionList",
		variableType: "PositionSearchQuery",
		fields: "id , name, type, organization { id, shortName}, person { id, name }"
	},
	"poams" : {
		listName: "poams: poamList",
		variableType: "PoamSearchQuery",
		fields: "id, shortName, longName"
	},
	"locations" : {
		listName: "locations: locationList",
		variableType: "LocationSearchQuery",
		fields : "id, name, lat, lng"
	},
	"organizations" : {
		listName: "organizations: organizationList",
		variableType: "OrganizationSearchQuery",
		fields: "id, shortName, longName"
	}
};

export default class Search extends Page {
	constructor(props) {
		super(props)

		this.state = {
			query: props.location.query.q,
			saveSearch: {show: false},
			results: {
				reports: null,
				people: null,
				organizations: null,
				positions: null,
				location: null,
				poams: null
			},
			error: null,
			success: null
		}
	}

	fetchData(props) {
		let type = props.location.query.type
		let text = props.location.query.text

		//Any query with a field other than 'text' and 'type' is an advanced query.
		let advQuery = Object.without(props.location.query, "type", "text")
		let isAdvQuery = Object.keys(advQuery).length;
		advQuery.text = text;

		if (isAdvQuery) {
			let config = SEARCH_CONFIG[type];
			API.query(/* GraphQL */
					`${config.listName} (f:search, query:$query) {
							pageNum, pageSize, totalCount, list { ${config.fields} }
					}`,
					{ query: advQuery},
					`($query: ${config.variableType} )`
				).then( data => {
				this.setState({results: data})
			}).catch(response =>
				this.setState({error: response})
			)
		} else {
			this.setState({text})
			//TODO: escape query in the graphQL query
			API.query(/* GraphQL */`
				searchResults(f:search, q:"${text}") {
					reports { totalCount, list { ${SEARCH_CONFIG.reports.fields}} }
					people { totalCount, list { ${SEARCH_CONFIG.persons.fields}} }
					positions { totalCount, list { ${SEARCH_CONFIG.positions.fields} }}
					poams { totalCount, list { ${SEARCH_CONFIG.poams.fields} }}
					locations { totalCount, list { ${SEARCH_CONFIG.locations.fields} }}
					organizations { totalCount, list { ${SEARCH_CONFIG.organizations.fields} }}
				}
			`).then(data =>
				this.setState({results: data.searchResults})
			).catch(response => {
				this.setState({error: response})
			})
		}
	}

	static pageProps = {
		navElement:

				<Link to="/">< Return to previous page</Link>

				<RadioGroup vertical size="large" style={{width: '100%'}}>
					<Radio value="all">Everything</Radio>
					<Radio value="reports">Reports</Radio>
					<Radio value="people">People</Radio>
					<Radio value="positions">Positions</Radio>
					<Radio value="locations">Locations</Radio>
					<Radio value="organizations">Organizations</Radio>
				</RadioGroup>

	}

	render() {
		let results = this.state.results
		let error = this.state.error
		let success = this.state.success

		let numResults = (results.reports ? results.reports.totalCount : 0) +
			(results.people ? results.people.totalCount : 0) +
			(results.positions ? results.positions.totalCount : 0) +
			(results.locations ? results.locations.totalCount : 0) +
			(results.organizations ? results.organizations.totalCount : 0)

		let noResults = numResults === 0

		let query = this.props.location.query
		let queryString = QUERY_STRINGS[query.type] || query.q || "TODO"

		if (typeof queryString === 'object') {
			queryString = queryString[Object.keys(query)[1]]
		}

		return (

				<Breadcrumbs items={[['Searching for ' + queryString, '/search']]} />

				<Messages error={error} success={success} />

				{noResults &&
					<Alert bsStyle="warning">
						No search results found!
					</Alert>
				}

					{this.props.location.query.text && <Button onClick={this.showSaveModal}>Save search</Button>}

				{results.reports && results.reports.totalCount > 0 &&
					<fieldset>
						<legend>Reports</legend>
						<ReportCollection reports={this.state.results.reports.list} />
					</fieldset>
				}

				{results.people && results.people.totalCount > 0 &&
					<fieldset>
						<legend>People</legend>
						{this.renderPeople()}
					</fieldset>
				}

				{results.organizations && results.organizations.totalCount > 0 &&
					<fieldset>
						<legend>Organizations</legend>
						{this.renderOrgs()}
					</fieldset>
				}

				{results.positions && results.positions.totalCount > 0 &&
					<fieldset>
						<legend>Positions</legend>
						{this.renderPositions()}
					</fieldset>
				}

				{results.locations && results.locations.totalCount > 0 &&
					<fieldset>
						<legend>Locations</legend>
						{this.renderLocations()}
					</fieldset>
				}

				{results.poams && results.poams.totalCount > 0 &&
					<fieldset>
						<legend>PoAMs</legend>
						{this.renderPoams()}
					</fieldset>
				}

				{this.renderSaveModal()}

		)
	}

	renderPeople() {
		return

					Name
					Position
					Org

				{Person.map(this.state.results.people.list, person =>

							<LinkTo person={person}>{person.rank} {person.name}</LinkTo>

						{person.phoneNumber}
						{person.position && <LinkTo position={person.position} />}
						{person.position && person.position.organization && <LinkTo organization={person.position.organization} />}

				)}

	}

	renderOrgs() {
		return

					Name
					Description
					Type

				{Organization.map(this.state.results.organizations.list, org =>

						<LinkTo organization={org} />
						{org.longName}
						{org.type}

				)}

	}

	renderPositions() {
		return

					Name
					Org
					Current Occupant

				{Position.map(this.state.results.positions.list, pos =>

							<LinkTo position={pos} >{pos.code} {pos.name}</LinkTo>

						{pos.organization && <LinkTo organization={pos.organization} />}
						{pos.person && <LinkTo person={pos.person} />}

				)}

	}

	renderLocations() {
		return

					Name

				{this.state.results.locations.list.map(loc =>

						<LinkTo location={loc} />

				)}

	}

	renderPoams() {
		return

					Name

				{Poam.map(this.state.results.poams.list, poam =>

						<LinkTo poam={poam} >{poam.shortName} {poam.longName}</LinkTo>

				)}

	}

	renderSaveModal() {
		return <Modal show={this.state.saveSearch.show} onHide={this.closeSaveModal}>
			<Modal.Header closeButton>
				<Modal.Title>Save search</Modal.Title>
			</Modal.Header>

			<Modal.Body>
				<Form formFor={this.state.saveSearch} onChange={this.onChangeSaveSearch}
					onSubmit={this.onSubmitSaveSearch} submitText={false}>
					<Form.Field id="name" placeholder="Give this saved search a name" />
					<Button type="submit" bsStyle="primary">Save</Button>
				</Form>
			</Modal.Body>
		</Modal>
	}

	@autobind
	onChangeSaveSearch() {
		let search = this.state.saveSearch;
		this.setState({saveSearch: search})
	}

	@autobind
	onSubmitSaveSearch(event) {
		event.stopPropagation()
		event.preventDefault()

		let search = Object.without(this.state.saveSearch, "show")
		search.query = this.props.location.query.text

		API.send('/api/savedSearches/new', search, {disableSubmits: true})
			.then(response => {
				if (response.code) throw response.code
				this.setState({
					success: "Search successfully saved!",
					saveSearch: {show: false}
				})
				window.scrollTo(0, 0)
			}).catch(response => {
				this.setState({
					error: response,
					saveSearch: {show: false}
				})
				window.scrollTo(0, 0)
			})
	}

	@autobind
	showSaveModal() {
		this.setState({saveSearch: {show: true, name: ''}})
	}

	@autobind
	closeSaveModal() {
		this.setState({saveSearch: {show: false}})
	}
}
<|endoftext|>


<commit_before>/*global Search*/
'use strict'

/**
 * @typedef {Object} Suggest~Result
 * @property {Array<Suggest~Text}>} text
 * @property {string} type - either 'property' or 'value'
 * @property {Parse~Object|Parse~Base} context - Object for 'property' and Base for 'value'
 */

/**
 * @typedef {Object} Suggest~Text
 * @property {string} plain
 * @property {Array<string>} highlight - plain split into substrings. Odd indexes are highlights
 */

let Suggest = {}

/**
 * Make suggestions based on the cursor position and schema definition
 * @param {Parse~Object} parsed
 * @param {Sample~Schema} schema
 * @returns {?Suggest~Result}
 */
Suggest.getSuggestions = function (parsed, schema) {
	if (parsed.type !== 'object') {
		return
	}
	return Suggest._processCursorInFind(parsed, schema, '')
}

/*
 * The mongodb query structure is depicted bellow:
 *
 * {name: {$ne: 'John'}}
 * ^      ^     ^
 * |      |     +- value
 * |      +- field expression
 * +- find
 *
 * Each context have different suggestion mechanisms.
 * For example, in the find context fields are suggested,
 * while in the field expression context operators are suggested
 */

/**
 * Process cursor in a find construction
 * @param {Parse~Object} parsed
 * @param {Sample~Schema} schema
 * @param {string} prefix
 * @returns {?Suggest~Result}
 * @private
 */
Suggest._processCursorInFind = function (parsed, schema, prefix) {
	let keys = parsed.properties.map(prop => prop.key.name)

	if (parsed.cursor === -1) {
		// Nothing is focused
		return
	} else if (parsed.cursor === parsed.properties.length) {
		// Empty property focused
		return Suggest._suggestFields('', schema, prefix, keys, parsed)
	}

	let property = parsed.properties[parsed.cursor],
		key = property.key.name,
		subPrefix = prefix ? prefix + '.' + key : key
	if (property.key.cursor !== -1) {
		// Key has focus
		let search = key.slice(0, property.key.cursor)
		return Suggest._suggestFields(search, schema, prefix, keys, parsed)
	} else if (key === '$or' || key === '$and' || key === '$nor') {
		// Multiple sub-finds
		if (property.value.type !== 'array') {
			return
		}

		let element = property.value.values[property.value.cursor]
		if (!element || element.type !== 'object') {
			return
		}

		return Suggest._processCursorInFind(element, schema, prefix)
	} else if (property.value.type === 'array' || property.value.type === 'source') {
		// Focus in field value
		return Suggest._suggestValues(property.value.raw, schema[subPrefix], property.value)
	} else if (property.value.type === 'object') {
		return Suggest._processCursorInFieldExp(property.value, schema, subPrefix)
	} else {
		// Unknown
		return
	}
}

/**
 * @param {Parse~Object} parsed
 * @param {Sample~Schema} schema
 * @param {string} prefix
 * @returns {?Suggest~Result}
 * @private
 */
Suggest._processCursorInFieldExp = function (parsed, schema, prefix) {
	let keys = parsed.properties.map(prop => prop.key.name)

	if (keys.some(key => key[0] !== '$')) {
		// Not actually a field expression, like in '{a: {b: 2}}',
		// '{b: 2}' is not a field expression
		return Suggest._suggestValues(parsed.raw, schema[prefix], parsed)
	}

	if (parsed.cursor === -1) {
		// Nothing is focused
		return
	} else if (parsed.cursor === parsed.properties.length) {
		// Empty property focused
		return Suggest._suggestOperators('', schema, prefix, keys, parsed)
	}

	let property = parsed.properties[parsed.cursor],
		key = property.key.name
	if (property.key.cursor !== -1) {
		// Key has focus
		let search = key.slice(0, property.key.cursor)
		return Suggest._suggestOperators(search, schema, prefix, keys, parsed)
	} else if (key === '$eq' || key === '$ne' ||
		key === '$gt' || key === '$gte' ||
		key === '$lt' || key === '$lte') {
		// COMP VALUE
		return Suggest._suggestValues(property.value.raw, schema[prefix], property.value)
	} else if (key === '$in' || key === '$nin' || key === '$all') {
		// COMP [VALUE]
		if (property.value.type !== 'array') {
			return
		}

		let element = property.value.values[property.value.cursor]
		return Suggest._suggestValues(element ? element.raw : '', schema[prefix], property.value)
	} else if (key === '$not') {
		// $not FIELD-EXP
		if (property.value.type !== 'object') {
			return
		}

		return Suggest._processCursorInFieldExp(property.value, schema, prefix)
	} else if (key === '$exists') {
		// $exists BOOL
		return Suggest._suggestValues(property.value.raw, {
			bool: true
		}, property.value)
	} else if (key === '$type') {
		// $type STRING
		return Suggest._suggestValues(property.value.raw, {
			string: [
				'double',
				'string',
				'object',
				'array',
				'binData',
				'objectId',
				'bool',
				'date',
				'null',
				'regex',
				'javascript',
				'javascriptWithScope',
				'int',
				'timestamp',
				'long',
				'minKey',
				'maxKey',
				'number'
			]
		}, property.value)
	} else if (key === '$mod') {
		// $mod [NUM, NUM]
		return [{
			text: '[divisor, remainder]'
		}]
	} else if (key === '$elemMatch') {
		// $elemMatch FIND
		if (property.value.type !== 'object') {
			return
		}

		return Suggest._processCursorInFind(property.value, schema, prefix)
	} else if (key === '$size') {
		// $size NUM
		return [{
			text: '(number)'
		}]
	} else {
		// Unknown
		return
	}
}

/**
 * @param {string} search
 * @param {Sample~Schema} schema
 * @param {string} prefix
 * @param {Array<string>} blacklist - keys already used at this level
 * @param {Parse~Object} context
 * @returns {?Suggest~Result}
 * @private
 */
Suggest._suggestFields = function (search, schema, prefix, blacklist, context) {
	// search='a', prefix='' -> pathPrefix='', field='a'
	// search='a.b', prefix='' -> pathPrefix='a.', field='b'
	// search='a', prefix='x' -> pathPrefix='x.', field='a'
	// search='ab.cd.e', prefix='x' -> pathPrefix='x.ab.cd.', field='e'
	let lastDot = search.lastIndexOf('.'),
		keyPrefix = lastDot === -1 ? '' : search.slice(0, lastDot + 1),
		pathPrefix = (prefix ? prefix + '.' : '') + keyPrefix,
		field = lastDot === -1 ? search : search.slice(lastDot + 1),
		searchSpace = []

	if (lastDot === -1) {
		for (let operator of ['$or', '$and', '$nor']) {
			if (blacklist.indexOf(operator) === -1) {
				searchSpace.push(operator)
			}
		}
	}

	// Collect fields in the same and following levels
	for (let path in schema) {
		if (path.startsWith(pathPrefix)) {
			let text = path.slice(pathPrefix.length),
				key = path.slice((prefix ? prefix + '.' : '').length)

			if (blacklist.indexOf(key) !== -1) {
				continue
			}

			searchSpace.push(text)
		}
	}

	return {
		texts: Search.search(searchSpace, field),
		type: 'property',
		context: context
	}
}

/**
 * @param {string} search
 * @param {Sample~Schema} schema
 * @param {string} prefix
 * @param {Array<string>} blacklist
 * @param {Parse~Object} context
 * @returns {?Suggest~Result}
 * @private
 */
Suggest._suggestOperators = function (search, schema, prefix, blacklist, context) {
	let operators = [
			// Basic operators
			'$eq', '$ne', '$gt', '$gte', '$lt', '$lte',
			'$in', '$nin', '$not', '$type'
		],
		fieldSchema = schema[prefix]

	// Additional type-dependent operators
	if (fieldSchema) {
		if (fieldSchema.null) {
			operators.push('$exists')
		}
		if (fieldSchema.double) {
			operators.push('$mod')
		}
		if (fieldSchema.array && fieldSchema.object) {
			operators.push('$elemMatch')
		}
		if (fieldSchema.array) {
			operators.push('$size', '$all')
		}
	}

	if (search[0] !== '$') {
		search = '$' + search
	}

	let matches = operators.filter(op => {
		return blacklist.indexOf(op) === -1 && op.startsWith(search)
	}).sort().map(each => ({
		plain: each,
		highlight: ['', search, each.slice(search.length)]
	}))

	return {
		texts: matches.slice(0, 7),
		type: 'property',
		context: context
	}
}

/**
 * @param {string} search
 * @param {?Sample~FieldSchema} fieldSchema
 * @param {Parse~Base} context
 * @returns {?Suggest~Result}
 * @private
 */
Suggest._suggestValues = function (search, fieldSchema, context) {
	if (!fieldSchema) {
		// Nothing useful to provide
		return
	}

	search = search.trim()
	let values = [],
		quote = search[0] === '"' ? '"' : '\''
	if (Array.isArray(fieldSchema.double)) {
		values = values.concat(fieldSchema.double.map(e => String(e)))
	}
	if (Array.isArray(fieldSchema.string)) {
		values = values.concat(fieldSchema.string.map(e => quote + Suggest._escape(e) + quote))
	}
	if (fieldSchema.bool) {
		values.push('true')
		values.push('false')
	}

	let texts = values.filter(value => {
		return value.startsWith(search)
	}).sort().map(each => {
		return {
			plain: each,
			highlight: ['', search, each.slice(search.length)]
		}
	}).slice(0, 7)

	let types = [
		'double',
		'string',
		'object',
		'array',
		'binData',
		'objectId',
		'date',
		'null',
		'regex',
		'timestamp',
		'long',
		'minKey',
		'maxKey'
	]

	types.forEach(type => {
		if (fieldSchema[type]) {
			let text = '(' + type + ')'
			texts.push({
				plain: text,
				highlight: [text]
			})
		}
	})

	return {
		texts,
		type: 'value',
		context: context
	}
}

/**
 * Escape a string to put between quotes
 * @param {string} str
 * @returns {string}
 * @private
 */
Suggest._escape = function (str) {
	return str.replace(/\\/g, '\\\\').replace(/'/g, '\\\'').replace(/"/g, '\\"')
}<commit_msg>Improve suggestions for values and operators<commit_after>/*global Search*/
'use strict'

/**
 * @typedef {Object} Suggest~Result
 * @property {Array<Suggest~Text}>} texts
 * @property {string} type - either 'property' or 'value'
 * @property {Parse~Object|Parse~Base} context - Object for 'property' and Base for 'value'
 */

/**
 * @typedef {Object} Suggest~Text
 * @property {string} plain
 * @property {Array<string>} highlight - plain split into substrings. Odd indexes are highlights
 */

let Suggest = {}

/**
 * Make suggestions based on the cursor position and schema definition
 * @param {Parse~Object} parsed
 * @param {Sample~Schema} schema
 * @returns {?Suggest~Result}
 */
Suggest.getSuggestions = function (parsed, schema) {
	if (parsed.type !== 'object') {
		return
	}
	return Suggest._processCursorInFind(parsed, schema, '')
}

/*
 * The mongodb query structure is depicted bellow:
 *
 * {name: {$ne: 'John'}}
 * ^      ^     ^
 * |      |     +- value
 * |      +- field expression
 * +- find
 *
 * Each context have different suggestion mechanisms.
 * For example, in the find context fields are suggested,
 * while in the field expression context operators are suggested
 */

/**
 * Process cursor in a find construction
 * @param {Parse~Object} parsed
 * @param {Sample~Schema} schema
 * @param {string} prefix
 * @returns {?Suggest~Result}
 * @private
 */
Suggest._processCursorInFind = function (parsed, schema, prefix) {
	let keys = parsed.properties.map(prop => prop.key.name)

	if (parsed.cursor === -1) {
		// Nothing is focused
		return
	} else if (parsed.cursor === parsed.properties.length) {
		// Empty property focused
		return Suggest._suggestFields('', schema, prefix, keys, parsed)
	}

	let property = parsed.properties[parsed.cursor],
		key = property.key.name,
		subPrefix = prefix ? prefix + '.' + key : key
	if (property.key.cursor !== -1) {
		// Key has focus
		let search = key.slice(0, property.key.cursor)
		return Suggest._suggestFields(search, schema, prefix, keys, parsed)
	} else if (key === '$or' || key === '$and' || key === '$nor') {
		// Multiple sub-finds
		if (property.value.type !== 'array') {
			return
		}

		let element = property.value.values[property.value.cursor]
		if (!element || element.type !== 'object') {
			return
		}

		return Suggest._processCursorInFind(element, schema, prefix)
	} else if (property.value.type === 'array' || property.value.type === 'source') {
		// Focus in field value
		return Suggest._suggestValues(property.value.raw, schema[subPrefix], property.value)
	} else if (property.value.type === 'object') {
		return Suggest._processCursorInFieldExp(property.value, schema, subPrefix)
	} else {
		// Unknown
		return
	}
}

/**
 * @param {Parse~Object} parsed
 * @param {Sample~Schema} schema
 * @param {string} prefix
 * @returns {?Suggest~Result}
 * @private
 */
Suggest._processCursorInFieldExp = function (parsed, schema, prefix) {
	let keys = parsed.properties.map(prop => prop.key.name)

	if (keys.some(key => key[0] !== '$')) {
		// Not actually a field expression, like in '{a: {b: 2}}',
		// '{b: 2}' is not a field expression
		return Suggest._suggestValues(parsed.raw, schema[prefix], parsed)
	}

	if (parsed.cursor === -1) {
		// Nothing is focused
		return
	} else if (parsed.cursor === parsed.properties.length) {
		// Empty property focused
		return Suggest._suggestOperators('', schema, prefix, keys, parsed)
	}

	let property = parsed.properties[parsed.cursor],
		key = property.key.name
	if (property.key.cursor !== -1) {
		// Key has focus
		let search = key.slice(0, property.key.cursor)
		return Suggest._suggestOperators(search, schema, prefix, keys, parsed)
	} else if (key === '$eq' || key === '$ne' ||
		key === '$gt' || key === '$gte' ||
		key === '$lt' || key === '$lte') {
		// COMP VALUE
		return Suggest._suggestValues(property.value.raw, schema[prefix], property.value)
	} else if (key === '$in' || key === '$nin' || key === '$all') {
		// COMP [VALUE]
		if (property.value.type !== 'array') {
			return
		}

		let element = property.value.values[property.value.cursor]
		return Suggest._suggestValues(element ? element.raw : '', schema[prefix], property.value)
	} else if (key === '$not') {
		// $not FIELD-EXP
		if (property.value.type !== 'object') {
			return
		}

		return Suggest._processCursorInFieldExp(property.value, schema, prefix)
	} else if (key === '$exists') {
		// $exists BOOL
		return Suggest._suggestValues(property.value.raw, {
			bool: true
		}, property.value)
	} else if (key === '$type') {
		// $type STRING
		return Suggest._suggestValues(property.value.raw, {
			string: [
				'double',
				'string',
				'object',
				'array',
				'binData',
				'objectId',
				'bool',
				'date',
				'null',
				'regex',
				'javascript',
				'javascriptWithScope',
				'int',
				'timestamp',
				'long',
				'minKey',
				'maxKey',
				'number'
			]
		}, property.value)
	} else if (key === '$mod') {
		// $mod [NUM, NUM]
		return buildSimpleSuggestion('[divisor, remainder]', property.value)
	} else if (key === '$elemMatch') {
		// $elemMatch FIND
		if (property.value.type !== 'object') {
			return
		}

		return Suggest._processCursorInFind(property.value, schema, prefix)
	} else if (key === '$size') {
		// $size NUM
		return buildSimpleSuggestion('(number)', property.value)
	} else {
		// Unknown
		return
	}

	function buildSimpleSuggestion(text, context) {
		return {
			texts: [{
				plain: text,
				highlight: [text]
			}],
			type: 'value',
			context
		}
	}
}

/**
 * @param {string} search
 * @param {Sample~Schema} schema
 * @param {string} prefix
 * @param {Array<string>} blacklist - keys already used at this level
 * @param {Parse~Object} context
 * @returns {?Suggest~Result}
 * @private
 */
Suggest._suggestFields = function (search, schema, prefix, blacklist, context) {
	// search='a', prefix='' -> pathPrefix='', field='a'
	// search='a.b', prefix='' -> pathPrefix='a.', field='b'
	// search='a', prefix='x' -> pathPrefix='x.', field='a'
	// search='ab.cd.e', prefix='x' -> pathPrefix='x.ab.cd.', field='e'
	let lastDot = search.lastIndexOf('.'),
		keyPrefix = lastDot === -1 ? '' : search.slice(0, lastDot + 1),
		pathPrefix = (prefix ? prefix + '.' : '') + keyPrefix,
		field = lastDot === -1 ? search : search.slice(lastDot + 1),
		searchSpace = []

	if (lastDot === -1) {
		for (let operator of ['$or', '$and', '$nor']) {
			if (blacklist.indexOf(operator) === -1) {
				searchSpace.push(operator)
			}
		}
	}

	// Collect fields in the same and following levels
	for (let path in schema) {
		if (path.startsWith(pathPrefix)) {
			let text = path.slice(pathPrefix.length),
				key = path.slice((prefix ? prefix + '.' : '').length)

			if (blacklist.indexOf(key) !== -1) {
				continue
			}

			searchSpace.push(text)
		}
	}

	return {
		texts: Search.search(searchSpace, field),
		type: 'property',
		context: context
	}
}

/**
 * @param {string} search
 * @param {Sample~Schema} schema
 * @param {string} prefix
 * @param {Array<string>} blacklist
 * @param {Parse~Object} context
 * @returns {?Suggest~Result}
 * @private
 */
Suggest._suggestOperators = function (search, schema, prefix, blacklist, context) {
	let operators = [
			// Basic operators
			'$eq', '$ne', '$gt', '$gte', '$lt', '$lte',
			'$in', '$nin', '$not', '$type'
		],
		fieldSchema = schema[prefix]

	// Additional type-dependent operators
	if (fieldSchema) {
		if (fieldSchema.null) {
			operators.push('$exists')
		}
		if (fieldSchema.double) {
			operators.push('$mod')
		}
		if (fieldSchema.array && fieldSchema.object) {
			operators.push('$elemMatch')
		}
		if (fieldSchema.array) {
			operators.push('$size', '$all')
		}
	}

	return {
		texts: Search.search(operators, search),
		type: 'property',
		context: context
	}
}

/**
 * @param {string} search
 * @param {?Sample~FieldSchema} fieldSchema
 * @param {Parse~Base} context
 * @returns {?Suggest~Result}
 * @private
 */
Suggest._suggestValues = function (search, fieldSchema, context) {
	if (!fieldSchema) {
		// Nothing useful to provide
		return
	}

	search = search.trim()
	let values = [],
		quote = search[0] === '"' ? '"' : '\''
	if (Array.isArray(fieldSchema.double)) {
		values = values.concat(fieldSchema.double.map(e => String(e)))
	}
	if (Array.isArray(fieldSchema.string)) {
		values = values.concat(fieldSchema.string.map(e => quote + Suggest._escape(e) + quote))
	}
	if (fieldSchema.bool) {
		values.push('true')
		values.push('false')
	}

	let texts = Search.search(values, search)

	let types = [
		'double',
		'string',
		'object',
		'array',
		'binData',
		'objectId',
		'date',
		'null',
		'regex',
		'timestamp',
		'long',
		'minKey',
		'maxKey'
	]

	types.forEach(type => {
		if (fieldSchema[type]) {
			let text = '(' + type + ')'
			texts.push({
				plain: text,
				highlight: [text]
			})
		}
	})

	return {
		texts,
		type: 'value',
		context: context
	}
}

/**
 * Escape a string to put between quotes
 * @param {string} str
 * @returns {string}
 * @private
 */
Suggest._escape = function (str) {
	return str.replace(/\\/g, '\\\\').replace(/'/g, '\\\'').replace(/"/g, '\\"')
}<|endoftext|>


<commit_before>//to include in html add {{> splash}}

if (Meteor.isClient) {

  Template.splash.helpers({
    //make sure zipcode is valid.
  });

  Template.splash.events({

    "submit form": function(event, template){
      // client side global variable to store user's zip code
      zip = event.target.zipcode.value
      event.preventDefault();
      FlowRouter.go('/search_results');
    }
  });
};
<commit_msg>Update splash.js<commit_after>//to include in html add {{> splash}}

if (Meteor.isClient) {

  Template.splash.helpers({
    //make sure zipcode is valid.
  });

  Template.splash.events({

    "submit form": function(event, template){
      // client side global variable to store user's zip code
      zip = event.target.zipcode.value
      event.preventDefault();
      FlowRouter.go('/searchresults');
    }
  });
};
<|endoftext|>


<commit_before>angular.module('MyApp')
    .controller('MyTravelCtrl', function ($scope, $stateParams, $state, TravelService,Account,toastr) {
        $scope.isMyTravelsLoading = true;
        $scope.travels =[];
        $scope.user ={};
        $scope.getProfile = function () {
            Account.getProfile()
                .then(function (response) {
                    $scope.user = response.data;
                    TravelService.getMyTravel(response.data.email)
                        .then(function (response) {
                            console.log(response);
                            $scope.travels = response.data;
                            $scope.isMyTravelsLoading =false;
                        })
                        .catch(function (response) {
                            toastr.clear();
                            toastr.error(response.data.message, response.status);
                        });
                })
                .catch(function (response) {
                    toastr.clear();
                    toastr.error(response.data.message, response.status);
                });
        };
        $scope.getProfile();

        var COLORS = [
            '#e21400', '#91580f', '#f8a700', '#f78b00',
            '#58dc00', '#287b00', '#a8f07a', '#4ae8c4',
            '#3b88eb', '#3824aa', '#a700ff', '#d300e7'
        ];
        //Generate color for the same user.
        $scope.getTitleColor= function(title) {
            // Compute hash code
            var hash = 7;
            for (var i = 0; i < title.length; i++) {
                hash = title.charCodeAt(i) + (hash << 5) - hash;
            }
            // Calculate color
            var index = Math.abs(hash % COLORS.length);
            return COLORS[index];
        }

        $scope.getTravel = function(id){
            $state.go('travel', {id:id});
        }
        $scope.deleteTravel =function(id){
            TravelService.deleteTravel(id)
                .then(function(response){
                    console.log(response);
                    $scope.isMyTravelsLoading = true;
                    $scope.getProfile();
                })
                .catch(function(response){
                    console.log(response);
                });
        }
    });<commit_msg>COLOR changes<commit_after>angular.module('MyApp')
    .controller('MyTravelCtrl', function ($scope, $stateParams, $state, TravelService,Account,toastr) {
        $scope.isMyTravelsLoading = true;
        $scope.travels =[];
        $scope.user ={};
        $scope.getProfile = function () {
            Account.getProfile()
                .then(function (response) {
                    $scope.user = response.data;
                    TravelService.getMyTravel(response.data.email)
                        .then(function (response) {
                            console.log(response);
                            $scope.travels = response.data;
                            $scope.isMyTravelsLoading =false;
                        })
                        .catch(function (response) {
                            toastr.clear();
                            toastr.error(response.data.message, response.status);
                        });
                })
                .catch(function (response) {
                    toastr.clear();
                    toastr.error(response.data.message, response.status);
                });
        };
        $scope.getProfile();

        var COLORS = [
            '#e67e22', '#2980b9', '#47A447', '#e67e22',
            '#2980b9', '#47A447', '#e67e22', '#2980b9',
            '#47A447', '#47A447', '#e67e22', '#2980b9'
        ];
        //Generate color for the same user.
        $scope.getTitleColor= function(title) {
            // Compute hash code
            var hash = 7;
            for (var i = 0; i < title.length; i++) {
                hash = title.charCodeAt(i) + (hash << 5) - hash;
            }
            // Calculate color
            var index = Math.abs(hash % COLORS.length);
            return COLORS[index];
        }

        $scope.getTravel = function(id){
            $state.go('travel', {id:id});
        }
        $scope.deleteTravel =function(id){
            TravelService.deleteTravel(id)
                .then(function(response){
                    console.log(response);
                    $scope.isMyTravelsLoading = true;
                    $scope.getProfile();
                })
                .catch(function(response){
                    console.log(response);
                });
        }
    });<|endoftext|>


<commit_before>var socket = io.connect(_address + ":" + _port);

// on connection to server, ask for username
socket.on("connect", function () {
    var email = null;
    while (email == null) {
        email = prompt("Enter email address:"); //Don't allow null email addys
    }
    socket.emit("adduser", email);
});
// update the audit log when appropriate
socket.on("updateaudit", function (username, data) {
    //$.jGrowl(data, { header: username });
});
// update users list when needed
socket.on("updateusers", function (data) {
    var userList = "<% _.each(gravatarUrls, function(gravatarUrl) { %>
<img src='<%= gravatarUrl %>'/>
 <% }); %>";
    $("#users > ul").html(_.template(userList, { gravatarUrls: data }));
});
socket.on("activeitemchanged", function (item) {
    console.log('activeitemchanged');
    var curr = $('#current');
    if (!item) {
        curr.html('Waiting for organizer to select item...');
        return;
    }
    var itemId = item.Id,
        currDesc = $('#currentDesc'),
        itemTempl = "<div class='<%= item.EntityType.Name %>-icon'>
[<%= item.Project.Name %>] (<%= item.Id %>) [<%= item.Assignments.Items.length > 0 ? item.Assignments.Items[0].GeneralUser.FirstName : 'unassigned' %>]

 <%= item.Name %>

shown

no demo
";

    var html = _.template(itemTempl, { item: item });
    curr.html(html)
        .addClass(item.EntityType.Name);
        //.addClass('itemShown' + item.shown)
        //.addClass('itemCanDemo' + item.canDemo);

    currDesc.empty()
        .append((item.Description && item.Description.length > 0) ? item.Description : "No description provided.");

    $('#user-shown').addClass('itemShown' + item.shown);
    $('#user-no-demo').addClass('itemCanDemo' + item.canDemo);

    //remove any inline style applied by TP, et al
    $('#currentDesc > div').children().attr('style', '');
});
socket.on("shownchanged", function (data) {
    console.log('shownchanged');
    var currEl = $('#current'),
        userShownEl = $('#user-shown');
    if (currEl && data.val === 1) {
        //currEl.addClass('itemShown1');
        userShownEl.addClass('itemShown1');
    } else if (currEl) {
        //currEl.removeClass('itemShown1');
        userShownEl.removeClass('itemShown1');
    }
});
socket.on("nodemochanged", function (data) {
    console.log('nodemochanged');
    var currEl = $('#current'),
        userNoDemoEl = $('#user-no-demo');
    if (currEl && data.val === 0) {
        //currEl.addClass('itemCanDemo0');
        userNoDemoEl.addClass('itemCanDemo0');
    } else if (currEl) {
        //currEl.removeClass('itemCanDemo0');
        userNoDemoEl.removeClass('itemCanDemo0');
    }
});
$(document).ready(function () {
    //request the active item when ready
    socket.emit("retrieveactiveitem");
});<commit_msg>remove those pesky conole.log lines<commit_after>var socket = io.connect(_address + ":" + _port);

// on connection to server, ask for username
socket.on("connect", function () {
    var email = null;
    while (email == null) {
        email = prompt("Enter email address:"); //Don't allow null email addys
    }
    socket.emit("adduser", email);
});
// update the audit log when appropriate
socket.on("updateaudit", function (username, data) {
    //$.jGrowl(data, { header: username });
});
// update users list when needed
socket.on("updateusers", function (data) {
    var userList = "<% _.each(gravatarUrls, function(gravatarUrl) { %>
<img src='<%= gravatarUrl %>'/>
 <% }); %>";
    $("#users > ul").html(_.template(userList, { gravatarUrls: data }));
});
socket.on("activeitemchanged", function (item) {
    var curr = $('#current');
    if (!item) {
        curr.html('Waiting for organizer to select item...');
        return;
    }
    var itemId = item.Id,
        currDesc = $('#currentDesc'),
        itemTempl = "<div class='<%= item.EntityType.Name %>-icon'>
[<%= item.Project.Name %>] (<%= item.Id %>) [<%= item.Assignments.Items.length > 0 ? item.Assignments.Items[0].GeneralUser.FirstName : 'unassigned' %>]

 <%= item.Name %>

shown

no demo
";

    var html = _.template(itemTempl, { item: item });
    curr.html(html)
        .addClass(item.EntityType.Name);
        //.addClass('itemShown' + item.shown)
        //.addClass('itemCanDemo' + item.canDemo);

    currDesc.empty()
        .append((item.Description && item.Description.length > 0) ? item.Description : "No description provided.");

    $('#user-shown').addClass('itemShown' + item.shown);
    $('#user-no-demo').addClass('itemCanDemo' + item.canDemo);

    //remove any inline style applied by TP, et al
    $('#currentDesc > div').children().attr('style', '');
});
socket.on("shownchanged", function (data) {
    var currEl = $('#current'),
        userShownEl = $('#user-shown');
    if (currEl && data.val === 1) {
        //currEl.addClass('itemShown1');
        userShownEl.addClass('itemShown1');
    } else if (currEl) {
        //currEl.removeClass('itemShown1');
        userShownEl.removeClass('itemShown1');
    }
});
socket.on("nodemochanged", function (data) {
    var currEl = $('#current'),
        userNoDemoEl = $('#user-no-demo');
    if (currEl && data.val === 0) {
        //currEl.addClass('itemCanDemo0');
        userNoDemoEl.addClass('itemCanDemo0');
    } else if (currEl) {
        //currEl.removeClass('itemCanDemo0');
        userNoDemoEl.removeClass('itemCanDemo0');
    }
});
$(document).ready(function () {
    //request the active item when ready
    socket.emit("retrieveactiveitem");
});<|endoftext|>


<commit_before>Chart= function(parentEl, outerWidth, outerHeight ) {

  var margin = {top: 20, right: 40, bottom: 20, left: 40};

  this.width = outerWidth - margin.left - margin.right,
  this.height = outerHeight - margin.top - margin.bottom;

  this._buildScales();
  this._buildGraph( parentEl, outerWidth, outerHeight, margin );
  this._buildBackground();
  this._buildAxes();
}

Chart.prototype._buildAxes= function() {

  this.xAxis = d3.svg.axis()
      .scale(this.x)
      .orient("bottom");

  this.yAxis = d3.svg.axis()
      .scale(this.y)
      .ticks(5)
      .orient("left");

//  this.yAxis2 = d3.svg.axis()
//      .scale(this.y)
//      .orient("right");

  // X Axis
  this.svg.append("g")
          .attr("class", "x-axis")
          .attr("transform", "translate(0," + this.height + ")")
          .call(this.xAxis)
  // Y Axes.
//  this.svg.append("g")
//          .attr("class", "y axis")
//          .attr("transform", "translate(" + this.width + ",0)")
//          .call(this.yAxis);

  this.svg.append("g")
          .attr("class", "y-axis")
          .call(this.yAxis);
}

Chart.prototype._buildBackground= function() {
/*  this.graph.append("rect")
            .attr("class", "inner")
            .attr("width", this.width)
            .attr("height", this.height); */
}

Chart.prototype._buildGraph= function( el, w, h, margin ) {
  this.svg = d3.select("#" + el).append("svg")
      .attr("width", w)
      .attr("height", h)
      .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
  this.graph = this.svg.append("g")
  var that= this;

  this.line = d3.svg.line()
                   .x(function(d) {
                     return that.x( new Date(d[1]*1000) ); })
                   .y(function(d) {
                      return that.y(d[0]); })
  this.graph.append("path")
            .attr("fill", "none")
            .attr("stroke", "#000");

  //.attr("d", this.line([]));
}

Chart.prototype._buildScales= function() {
  console.log( this.width );
  this.x = d3.time.scale()
      .range([0, this.width]);

  this.y = d3.scale.linear()
      .range([this.height, 0]);
}

Chart.prototype.refreshData= function( data ) {
    if( data && data.length > 0 ) {
      this.x.domain(  [new Date( data[0].datapoints[0][1]* 1000 ),
                      new Date( data[0].datapoints[data[0].datapoints.length-1][1]* 1000 )] );

      this.y.domain([0, d3.max(data[0].datapoints, function(d) { return d[0]; })]);
      this.yAxis.scale(this.y);
      this.xAxis.scale(this.x);

      this.svg.select("g.x-axis").call(this.xAxis);
      this.svg.select("g.y-axis").call(this.yAxis);
  /*
      graph.selectAll("path")
      					.data([data]) // set the new data
      					.attr("d", line); /
*/
      this.graph.selectAll("path")
      					.attr("d", this.line(data[0].datapoints) ); // set the new data
/*
      					.attr("transform", "translate(" + x(1) + ")") // set the transform to the right by x(1) pixels (6 for the scale we've set) to hide the new value
      					.attr("d", line) // apply the new data values ... but the new value is hidden at this point off the right of the canvas
      					.transition() // start a transition to bring the new value into view
      					.ease("linear")
      					.duration(transitionDelay) // for this demo we want a continual slide so set this to the same as the setInterval amount below
      					.attr("transform", "translate(" + x(0) + ")"); // animate a slide to the left back to x(0) pixels to reveal the new value
  */
    }
    else {
      // TODO: no data returned
    }
}<commit_msg>Working basic area (and line)<commit_after>Chart= function(parentEl, outerWidth, outerHeight ) {
  this.outerWidth= outerWidth;
  this.outerHeight= outerHeight;

  var graphContainer = d3.select("#" + parentEl).append("svg")
      .attr("width", this.outerWidth)
      .attr("height", this.outerHeight);

  this.svg= graphContainer.append("g")
       .classed("canvasArea", true);

  this.graph = this.svg.append("g")
                      .classed("chartArea", true);

  this._buildBackground();
  this._buildScales();
  this._buildChart();
  this._buildAxes();
  this._updateChartAreaSize();
}

Chart.prototype._updateChartAreaSize= function( margins ) {
  margins= margins || {top: 5, right: 40, bottom: 20, left: 40};
  this.width = this.outerWidth - margins.left - margins.right,
  this.height = this.outerHeight - margins.top - margins.bottom;

  // Update our transformation that 'simplifies' width + height  calculations elsewhere.
  this.svg.attr("transform", "translate(" + margins.left + "," + margins.top + ")");
  this.x.range([0, this.width]);
  this.y.range([this.height, 0]);
  this.svg.select("g.x-axis").attr("transform", "translate(0," + this.height + ")");
}

Chart.prototype._buildAxes= function() {

  this.xAxis = d3.svg.axis()
      .scale(this.x)
      .orient("bottom");

  this.yAxis = d3.svg.axis()
      .scale(this.y)
      .ticks(5)
      .orient("left");

//  this.yAxis2 = d3.svg.axis()
//      .scale(this.y)
//      .orient("right");

  // X Axis
  this.svg.append("g")
          .attr("class", "x-axis")
          .call(this.xAxis)
  // Y Axes.
//  this.svg.append("g")
//          .attr("class", "y axis")
//          .attr("transform", "translate(" + this.width + ",0)")
//          .call(this.yAxis);

  this.svg.append("g")
          .attr("class", "y-axis")
          .call(this.yAxis);
}

Chart.prototype._buildBackground= function() {
/*  this.graph.append("rect")
            .attr("class", "inner")
            .attr("width", this.width)
            .attr("height", this.height); */
}

Chart.prototype._buildChart= function() {

  var that= this;

  this.line = d3.svg.line()
                   .x(function(d) {
                     return that.x( new Date(d[1]*1000) ); })
                   .y(function(d) {
                      return that.y(d[0]); })
  this.area = d3.svg.area()
    .x(this.line.x())
    .y1(this.line.y())
    .y0(this.y(0));

  var c= d3.rgb("#9CC1E0")
  this.areaPath= this.graph.append("path")
                      .attr("fill", c.toString() );

  this.linePath= this.graph.append("path")
                       .attr("fill", "none")
                       .attr("stroke-width", "2px")
                       .attr("stroke", c.darker().toString() );
}

Chart.prototype._buildScales= function() {
  this.x = d3.time.scale()
  this.y = d3.scale.linear()
}

Chart.prototype.refreshData= function( data ) {
    if( data && data.length > 0 ) {
      this.x.domain(  [new Date( data[0].datapoints[0][1]* 1000 ),
                      new Date( data[0].datapoints[data[0].datapoints.length-1][1]* 1000 )] );

      this.y.domain([0, d3.max(data[0].datapoints, function(d) { return d[0]; })]);
//      this._updateChartAreaSize(
//       { left:Math.random()*40, right:Math.random()*40, top:Math.random()*40, bottom:Math.random()*40 }
//       );

      this.yAxis.scale(this.y);
      this.xAxis.scale(this.x);

      this.svg.select("g.x-axis").call(this.xAxis);
      this.svg.select("g.y-axis").call(this.yAxis);
      this.area.y0(this.y(0));

  /*
      graph.selectAll("path")
      					.data([data]) // set the new data
      					.attr("d", line); /
*/
      this.linePath
          .attr("d", this.line(data[0].datapoints) ); // set the new data
      this.areaPath
          .attr("d", this.area(data[0].datapoints) ); // set the new data

/*
      					.attr("transform", "translate(" + x(1) + ")") // set the transform to the right by x(1) pixels (6 for the scale we've set) to hide the new value
      					.attr("d", line) // apply the new data values ... but the new value is hidden at this point off the right of the canvas
      					.transition() // start a transition to bring the new value into view
      					.ease("linear")
      					.duration(transitionDelay) // for this demo we want a continual slide so set this to the same as the setInterval amount below
      					.attr("transform", "translate(" + x(0) + ")"); // animate a slide to the left back to x(0) pixels to reveal the new value
  */
    }
    else {
      // TODO: no data returned
    }
}<|endoftext|>


<commit_before>import xhr from 'xhr'

const loading = {}

export default function load (page, cb) {
  if (!loading[page]) {
    loading[page] = [ cb ]

    xhr(`./wiki/${page}`, (err, response) => {
      if (err) done(err)
      else done(null, response.body)
    })
  } else {
    loading[page].push(cb)
  }

  function done (e, content) {
    loading[page].forEach((cb) => {
      cb(e, content)
    })
    delete loading[page]
  }
}
<commit_msg>Refactor load-page.<commit_after>import xhr from 'xhr'

const callbacks = {}

export default function load (page, cb) {
  if (callbacks[page]) {
    callbacks[page].push(cb)
    return
  }

  callbacks[page] = [ cb ]

  xhr(`./wiki/${page}`, (err, response) => {
    if (err) done(err)
    else done(null, response.body)
  })

  function done (e, content) {
    callbacks[page].forEach((cb) => {
      cb(e, content)
    })
    delete callbacks[page]
  }
}
<|endoftext|>


<commit_before>var semtag = semtag || {};

semtag.buildTag = function (id, parentId, options) {

	var el,
		type,
		className;
	type = options.type || 'div';
	className = options.className || '';
	el = document.createElement(type);
	el.setAttribute('id', id);
	el.className = className;
	document.getElementById(parentId).appendChild(el);
	return el;
};

semtag.getId = function (content) {
	var id,
		baseString,
		counter = 1;
	baseString = 'semtag-' + content.replace(/ /g, '_') + '-';
	id =  baseString + counter;
	while (document.getElementById(id)){

		counter += 1;
		id =  baseString + counter;
	}
	return id;
};

semtag.buildDidYouMeanTable = function (json, tableId) {
	var didYouMean,
		sensCount = json.senses.length,
		i,
		list,
		el,
		header;

		didYouMean = document.getElementById(tableId) || semtag.buildTag(tableId, 'content-container', {className: "span4"});
		list = document.getElementById('senses') || semtag.buildTag('senses', tableId, {type: "ul"});
		header = document.createElement('h5');
		header.innerText = 'When you say "' + json.word + '" did you mean:';
		didYouMean.innerHTML = "";
		list.innerHTML = "";
		didYouMean.appendChild(header);
		for (i = 0; i < sensCount; i += 1) {
			el = document.createElement('li');
			el.setAttribute('id', json.senses[i].senseid);
			el.className = 'word-sense';
			el.innerText = json.senses[i].explanation;
			list.appendChild(el);
		}
		didYouMean.appendChild(list);

		$('.word-sense').click( function () {
			var toTag,
				sense,
				id,
				remove,
				removeIcon;

			toTag = document.getElementById('toTag');
			id = semtag.getId(toTag.textContent);
			sense = this.getAttribute('id');
			toTag.setAttribute('id', id);
			toTag.setAttribute('rel', 'http://purl.org/linguistics/gold/hasMeaning');
			toTag.setAttribute('title', this.textContent);
			toTag.setAttribute('resource', sense);
			toTag.setAttribute('about', document.URL + '#' + id);
			toTag.className = 'tagged';
			remove = document.createElement('span');
			remove.className = 'remove';
			removeIcon = document.createElement('img');
			removeIcon.setAttribute('src', '/images/remove.png');
			removeIcon.className = 'removeIcon';
			removeIcon.setAttribute('alt', 'X');
			remove.appendChild(removeIcon);
			toTag.appendChild(remove);
			$('.removeIcon').unbind('click');
			$('.removeIcon').click(function () {
				var taggedNode,
					taggedNodeParent,
					content;
				taggedNode = this.parentNode.parentNode;
				taggedNodeParent = taggedNode.parentNode;
				content = document.createTextNode(taggedNode.textContent);
				taggedNodeParent.replaceChild(content, taggedNode);
			});
			didYouMean.parentNode.removeChild(didYouMean);

		});

};

semtag.sw = function (word) {
	$.getJSON('http://localhost:3000/lex?data={"word":"' + word + '"}', function (data) {
	semtag.buildDidYouMeanTable(data, 'dym');
	});
};

semtag.surround = function (range, className) {
		fragment = range.extractContents();
		var tag = document.createElement("span");
		tag.setAttribute("id", className);
		tag.appendChild(fragment);
		range.insertNode(tag);
};

semtag.resetToTag = function (id, callback) {
	var toRemove,
		parent,
		child;
	toRemove = document.getElementById(id);
	if ( toRemove ) {
		contents = toRemove.childNodes[0];
		parent = toRemove.parentNode;
		if (contents) {
			parent.replaceChild(contents, toRemove);
		} else {
			parent.removeChild(toRemove);
		}
	}
	callback();
}

$('#content').mouseup(function () {
	var range = window.getSelection().getRangeAt(0);
	if (range && range.toString() !== '') {
		semtag.resetToTag('toTag', function () {
			semtag.surround(range, 'toTag');
			semtag.sw(range.toString().replace(/ /g, '_'));
			document.getSelection().addRange(range);
		});
	}
});
<commit_msg>Added check for schema.org vocab. Puts schema.org at top of DYM list<commit_after>var semtag = semtag || {};

semtag.buildTag = function (id, parentId, options) {

	var el,
		type,
		className;
	type = options.type || 'div';
	className = options.className || '';
	el = document.createElement(type);
	el.setAttribute('id', id);
	el.className = className;
	document.getElementById(parentId).appendChild(el);
	return el;
};

semtag.getId = function (content) {
	var id,
		baseString,
		counter = 1;
	baseString = 'semtag-' + content.replace(/ /g, '_') + '-';
	id =  baseString + counter;
	while (document.getElementById(id)){

		counter += 1;
		id =  baseString + counter;
	}
	return id;
};

semtag.buildDidYouMeanTable = function (json, tableId) {
	var didYouMean,
		sensCount = json.senses.length,
		i,
		list,
		el,
		header;

		didYouMean = document.getElementById(tableId) || semtag.buildTag(tableId, 'content-container', {className: "span4"});
		list = document.getElementById('senses') || semtag.buildTag('senses', tableId, {type: "ul"});
		header = document.createElement('h5');
		header.innerText = 'When you say "' + json.word + '" did you mean:';
		didYouMean.innerHTML = "";
		list.innerHTML = "";
		didYouMean.appendChild(header);
		for (i = 0; i < sensCount; i += 1) {
			el = document.createElement('li');
			el.setAttribute('id', json.senses[i].senseid);
			el.className = 'word-sense';
			el.innerText = json.senses[i].explanation;
			list.appendChild(el);
		}
		didYouMean.appendChild(list);

		$('.word-sense').click( function () {
			var toTag,
				sense,
				id,
				remove,
				removeIcon;

			toTag = document.getElementById('toTag');
			id = semtag.getId(toTag.textContent);
			sense = this.getAttribute('id');
			toTag.setAttribute('id', id);
			toTag.setAttribute('rel', 'http://purl.org/linguistics/gold/hasMeaning');
			toTag.setAttribute('title', this.textContent);
			toTag.setAttribute('resource', sense);
			toTag.setAttribute('about', document.URL + '#' + id);
			toTag.className = 'tagged';
			remove = document.createElement('span');
			remove.className = 'remove';
			removeIcon = document.createElement('img');
			removeIcon.setAttribute('src', '/images/remove.png');
			removeIcon.className = 'removeIcon';
			removeIcon.setAttribute('alt', 'X');
			remove.appendChild(removeIcon);
			toTag.appendChild(remove);
			$('.removeIcon').unbind('click');
			$('.removeIcon').click(function () {
				var taggedNode,
					taggedNodeParent,
					content;
				taggedNode = this.parentNode.parentNode;
				taggedNodeParent = taggedNode.parentNode;
				content = document.createTextNode(taggedNode.textContent);
				taggedNodeParent.replaceChild(content, taggedNode);
			});
			didYouMean.parentNode.removeChild(didYouMean);

		});

};
semtag.schema = function (word) {
	var i,
		sense,
		schema_senses = [];
	word = word.replace(/s$/,"s?"); // Simple hack to make most plural forms optional
	for (i = 0; i < schema.org.length; i += 1) {
		if (schema.org[i].label.search(new RegExp("(\s|^)" + word, "i")) != -1 ) {
			sense = {};
			sense.senseid = "http://schema.org/" + schema.org[i].id;
			sense.explanation = schema.org[i].comment;
			schema_senses.push(sense);
		}
	}
	return schema_senses;
}

semtag.sw = function (word) {
	var schema_senses = [];
	word = word.replace(/^\s*|\s*$/g,'') // Removes leading and trailing white space

	schema_senses = semtag.schema(word);

	word = word.replace(/ /g, '_'); // Replaces inner white space with underscores
	$.getJSON('http://localhost:3000/lex?data={"word":"' + word + '"}', function (data) {

	data.senses = schema_senses.concat(data.senses);
	semtag.buildDidYouMeanTable(data, 'dym');
	});
};

semtag.surround = function (range, className) {
		fragment = range.extractContents();
		var tag = document.createElement("span");
		tag.setAttribute("id", className);
		tag.appendChild(fragment);
		range.insertNode(tag);
};

semtag.resetToTag = function (id, callback) {
	var toRemove,
		parent,
		child;
	toRemove = document.getElementById(id);
	if ( toRemove ) {
		contents = toRemove.childNodes[0];
		parent = toRemove.parentNode;
		if (contents) {
			parent.replaceChild(contents, toRemove);
		} else {
			parent.removeChild(toRemove);
		}
	}
	callback();
}

$('#content').mouseup(function () {
	var range = window.getSelection().getRangeAt(0);
	if (range && range.toString() !== '') {
		semtag.resetToTag('toTag', function () {
			semtag.surround(range, 'toTag');
			semtag.sw(range.toString());
			document.getSelection().addRange(range);
		});
	}
});
<|endoftext|>