<commit_before>const _ = require("lodash");
const smash = require("../../../../smash.js");
const logger = smash.logger("Response");
const errorUtil = new smash.SmashError(logger);

class Response {
    constructor(terminate, request) {
        if (typeof terminate !== 'object') {
            throw new Error("First parameter of new Response() must be a object, " + smash.Logger.typeOf(terminate));
        }
        if (typeof terminate.handleResponse !== 'function') {
            throw new Error("First parameter of new Response() must be a object with a function called handleResponse, " + smash.Logger.typeOf(terminate.handleResponse));
        }
        if (terminate.handleResponse.length !== 1) {
            throw new Error("First parameter of new Response() must be a function witch takes 1 parameter, " + terminate.handleResponse.length + " given");
        }
        if (typeof terminate !== 'object') {
            throw new Error("Second parameter of new Response() must be a object, " + smash.Logger.typeOf(terminate));
        }
        this._terminate = terminate;
        this._request = request;
        this._code = null;
        this._headers = {};
        this._body = null;
    }

    get _errorPointer() {
        return {
            400: this.badRequest,
            401: this.unauthorized,
            403: this.forbidden,
            404: this.notFound,
            409: this.conflict,
            500: this.internalServerError,
            501: this.notImplemented,
            503: this.serviceUnavailable,
        }
    }

    _cleanAndAssign(body, optionalParameters) {
        if (smash.cleanRuleExist(this._request.route.action) !== true) {
            return this.internalServerError();
        }
        return _.assign(_.mapValues(body, property => smash.clean(this._request.route.action, property)), optionalParameters)
    }

    cleanOk(body, optionalParameters = {}) {
        return this.ok(this._cleanAndAssign(body, optionalParameters));
    }

    ok(body) {
        return this._handleResponse(200, body);
    }

    created(body) {
        return this._handleResponse(201, body);
    }

    cleanCreated(body, optionalParameters = {}) {
        return this.created(this._cleanAndAssign(body, optionalParameters));
    }

    accepted() {
        return this._handleResponse(202);
    }

    noContent() {
        return this._handleResponse(204);
    }

    _getRedirectHeaders(url) {
        return { Location: url };
    }

    movedPermanently(url) {
        return this._handleResponse(301, "", this._getRedirectHeaders(url));
    }

    found(url) {
        return this._handleResponse(302, "", this._getRedirectHeaders(url));
    }

    temporaryRedirect(url) {
        return this._handleResponse(307, "", this._getRedirectHeaders(url));
    }

    permanentRedirect(url) {
        return this._handleResponse(308, "", this._getRedirectHeaders(url));
    }

    badRequest(message, details) {
        const errorUtil = new smash.SmashError();
        return this.handleError(errorUtil.badRequestError(message, details));
    }

    unauthorized(message) {
        const errorUtil = new smash.SmashError();
        return this.handleError(errorUtil.unauthorizedError(message));
    }

    forbidden(message) {
        const errorUtil = new smash.SmashError();
        return this.handleError(errorUtil.forbiddenError(message));
    }

    notFound(message) {
        const errorUtil = new smash.SmashError();
        return this.handleError(errorUtil.notFoundError(message));
    }

    conflict(message) {
        const errorUtil = new smash.SmashError();
        return this.handleError(errorUtil.conflictError(message));
    }

    internalServerError(message) {
        const errorUtil = new smash.SmashError();
        return this.handleError(errorUtil.internalServerError(message));
    }

    notImplemented(message) {
        const errorUtil = new smash.SmashError();
        return this.handleError(errorUtil.notImplementedError(message));
    }

    serviceUnavailable(message) {
        const errorUtil = new smash.SmashError();
        return this.handleError(errorUtil.serviceUnavailableError(message));
    }

    _handleResponse(code, body = "", headers = null) {
        this._code = code;
        this._body = body;
        this.addHeaders(headers);
        this.terminate();
        return this;
    }

    handleError(error) {
        if (errorUtil.isSmashError(error) === false) {
            error = errorUtil.internalServerError("First argument of handleError(error) must ba a SmashError, " + errorUtil.typeOf(error));
        }
        error.requestId = this._request.requestId;
        error.printError();
        return this._handleResponse(error.code, error.body);
    }

    get headers() {
        return this._headers;
    }

    addHeader(key, value) {
        this._headers[key] = value;
        return this;
    }

    addHeaders(headers = {}) {
        _.each(headers, (value, key) => {
            this.addHeader(key, value);
        }, this);
    }

    get body() {
        return this._body;
    }

    get stringifiedBody() {
        return typeof this._body === 'object' ? JSON.stringify(this._body) : this._body;
    }

    set body(body) {
        this._body = body;
        return this;
    }

    get code() {
        return this._code;
    }

    terminate() {
        Object.freeze(this);
        this._terminate.handleResponse(this);
    }

    set route(route) {
        this._route = route;
        return this;
    }

    get route() {
        return this._route;
    }
}

module.exports = Response;
<commit_msg>Fix use of invalid shortcut<commit_after>const _ = require("lodash");
const smash = require("../../../../smash.js");
const logger = smash.logger("Response");
const errorUtil = new smash.SmashError(logger);

class Response {
    constructor(terminate, request) {
        if (typeof terminate !== 'object') {
            throw new Error("First parameter of new Response() must be a object, " + smash.Logger.typeOf(terminate));
        }
        if (typeof terminate.handleResponse !== 'function') {
            throw new Error("First parameter of new Response() must be a object with a function called handleResponse, " + smash.Logger.typeOf(terminate.handleResponse));
        }
        if (terminate.handleResponse.length !== 1) {
            throw new Error("First parameter of new Response() must be a function witch takes 1 parameter, " + terminate.handleResponse.length + " given");
        }
        if (typeof terminate !== 'object') {
            throw new Error("Second parameter of new Response() must be a object, " + smash.Logger.typeOf(terminate));
        }
        this._terminate = terminate;
        this._request = request;
        this._code = null;
        this._headers = {};
        this._body = null;
    }

    get _errorPointer() {
        return {
            400: this.badRequest,
            401: this.unauthorized,
            403: this.forbidden,
            404: this.notFound,
            409: this.conflict,
            500: this.internalServerError,
            501: this.notImplemented,
            503: this.serviceUnavailable,
        }
    }

    _cleanAndAssign(body, optionalParameters) {
        if (smash.binder.cleanRuleExist(this._request.route.action) !== true) {
            return this.internalServerError();
        }
        return _.assign(_.mapValues(body, property => smash.clean(this._request.route.action, property)), optionalParameters)
    }

    cleanOk(body, optionalParameters = {}) {
        return this.ok(this._cleanAndAssign(body, optionalParameters));
    }

    ok(body) {
        return this._handleResponse(200, body);
    }

    created(body) {
        return this._handleResponse(201, body);
    }

    cleanCreated(body, optionalParameters = {}) {
        return this.created(this._cleanAndAssign(body, optionalParameters));
    }

    accepted() {
        return this._handleResponse(202);
    }

    noContent() {
        return this._handleResponse(204);
    }

    _getRedirectHeaders(url) {
        return { Location: url };
    }

    movedPermanently(url) {
        return this._handleResponse(301, "", this._getRedirectHeaders(url));
    }

    found(url) {
        return this._handleResponse(302, "", this._getRedirectHeaders(url));
    }

    temporaryRedirect(url) {
        return this._handleResponse(307, "", this._getRedirectHeaders(url));
    }

    permanentRedirect(url) {
        return this._handleResponse(308, "", this._getRedirectHeaders(url));
    }

    badRequest(message, details) {
        const errorUtil = new smash.SmashError();
        return this.handleError(errorUtil.badRequestError(message, details));
    }

    unauthorized(message) {
        const errorUtil = new smash.SmashError();
        return this.handleError(errorUtil.unauthorizedError(message));
    }

    forbidden(message) {
        const errorUtil = new smash.SmashError();
        return this.handleError(errorUtil.forbiddenError(message));
    }

    notFound(message) {
        const errorUtil = new smash.SmashError();
        return this.handleError(errorUtil.notFoundError(message));
    }

    conflict(message) {
        const errorUtil = new smash.SmashError();
        return this.handleError(errorUtil.conflictError(message));
    }

    internalServerError(message) {
        const errorUtil = new smash.SmashError();
        return this.handleError(errorUtil.internalServerError(message));
    }

    notImplemented(message) {
        const errorUtil = new smash.SmashError();
        return this.handleError(errorUtil.notImplementedError(message));
    }

    serviceUnavailable(message) {
        const errorUtil = new smash.SmashError();
        return this.handleError(errorUtil.serviceUnavailableError(message));
    }

    _handleResponse(code, body = "", headers = null) {
        this._code = code;
        this._body = body;
        this.addHeaders(headers);
        this.terminate();
        return this;
    }

    handleError(error) {
        if (errorUtil.isSmashError(error) === false) {
            error = errorUtil.internalServerError("First argument of handleError(error) must ba a SmashError, " + errorUtil.typeOf(error));
        }
        error.requestId = this._request.requestId;
        error.printError();
        return this._handleResponse(error.code, error.body);
    }

    get headers() {
        return this._headers;
    }

    addHeader(key, value) {
        this._headers[key] = value;
        return this;
    }

    addHeaders(headers = {}) {
        _.each(headers, (value, key) => {
            this.addHeader(key, value);
        }, this);
    }

    get body() {
        return this._body;
    }

    get stringifiedBody() {
        return typeof this._body === 'object' ? JSON.stringify(this._body) : this._body;
    }

    set body(body) {
        this._body = body;
        return this;
    }

    get code() {
        return this._code;
    }

    terminate() {
        Object.freeze(this);
        this._terminate.handleResponse(this);
    }

    set route(route) {
        this._route = route;
        return this;
    }

    get route() {
        return this._route;
    }
}

module.exports = Response;
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import THREE from 'three';
import p2 from 'p2';
import { v3toP2, p2ToV3 } from '../../helpers/Utils';

const bubbleMinSize = 0.5;
const foamGrowSize = 0.3;
const foamGrowSpeed = 5.2;
const foamSpeed = 4.2;
const minimumPercentToShowFoam = 0.9;

// Computed values

const colRotation = new THREE.Euler( -Math.PI / 2, 0, Math.PI / 2 );
const toScreenRotation = new THREE.Euler( -Math.PI / 2, 0, 0 );
const axis = new THREE.Vector3( 0, -1, 0 );
// Which way the emitter flows by default
const forwardDirection = new THREE.Vector3( 1, 0, 0 );
const helperRotation = new THREE.Euler( 0, -Math.PI / 2, 0 );
const helperPosition = new THREE.Vector3( -0.5, 0, 0 );

const relativeImpulsePoint = [ 0, 0 ];

export default class SegmentedEmitter extends Component {

    static propTypes = {
        position: PropTypes.object.isRequired,
        rotation: PropTypes.object,
        scale: PropTypes.object,
        world: PropTypes.object,
        paused: PropTypes.bool,
        time: PropTypes.number,
        playerRadius: PropTypes.number,
        playerBody: PropTypes.object,
        maxLength: PropTypes.number.isRequired,
        impulse: PropTypes.number.isRequired,
        rayCount: PropTypes.number.isRequired,
        materialId: PropTypes.string.isRequired,
        foamMaterialId: PropTypes.string,
        foam: PropTypes.bool,
    }

    constructor( props, context ) {

        super( props, context );

        this.state = this.getStateFromProps( props, {} );

        this._onUpdate = this._onUpdate.bind( this );

    }

    componentWillReceiveProps( nextProps ) {

        if( ( nextProps.playerRadius !== this.props.playerRadius ) ||
           ( nextProps.rotation !== this.props.rotation ) ||
           ( nextProps.position !== this.props.position )
        ) {

            this.setState( this.getStateFromProps( nextProps, this.state ) );

        }

    }

    getStateFromProps( props, state ) {

        const {
            position, rotation, playerRadius, scale, maxLength, rayCount
        } = props;

        // dam son see http://stackoverflow.com/questions/5501581/javascript-new-arrayn-and-array-prototype-map-weirdness
        const rayArray = new Array( rayCount ).fill( 0 );
        const angle = new THREE.Euler().setFromQuaternion( rotation ).y;
        const impulse = ( props.impulse / rayCount ) * ( playerRadius || 0.45 );
        const flowDirection = forwardDirection.clone().applyQuaternion( rotation );

        return {
            rayArray,

            // The actual lenghts tweening towards targets
            lengths: state.lengths || rayArray.map( () => 1 ),

            // Where the waterfall should be ideally based on hit test
            lengthTargets: state.lengths || rayArray.map( () => 1 ),

            counter: 0,
            flowDirection2D: new THREE.Vector2( flowDirection.x, flowDirection.z ),
            hitVectors: rayArray.map( ( zero, index ) => {

                const streamHalfWidth = 0.5 / rayCount;

                // Construct the *local* unrotated vectors that define this
                // stream in local space
                const fromVectorInitial = new THREE.Vector3(
                    // move close to left edge of emitter
                    -0.499999,
                    // move toward the back to intersect player
                    -0.5 + ( playerRadius || 0.45 ),
                    // move to rectangle offset by index
                    -0.5 + /* center */( ( 1 / rayCount ) * index ) + streamHalfWidth
                );

                const toVectorInitial = new THREE.Vector3(
                    fromVectorInitial.x + maxLength,
                    fromVectorInitial.y,
                    fromVectorInitial.z,
                );

                // Calculate the initial two points for the hit test rectangle
                // to do box test on. These are world points
                const a = fromVectorInitial
                    .clone()
                    .sub( new THREE.Vector3( 0, 0, streamHalfWidth ) )
                    .applyQuaternion( rotation )
                    .add( position );

                const b = fromVectorInitial
                    .clone()
                    .add( new THREE.Vector3( 0, 0, streamHalfWidth ) )
                    .applyQuaternion( rotation )
                    .add( position );

                const startingPoints = {
                    a: new THREE.Vector2( a.x, a.z ),
                    b: new THREE.Vector2( b.x, b.z ),
                };

                // Note, these are all in world space except for the impulse
                return {
                    fromVector2D: v3toP2(
                        fromVectorInitial.applyQuaternion( rotation ).add( position )
                    ),
                    toVector2D: v3toP2(
                        toVectorInitial.applyQuaternion( rotation ).add( position )
                    ),
                    impulseVector2D: v3toP2(
                        new THREE.Vector3( impulse, 0, 0 ).applyQuaternion( rotation )
                    ),
                    startingPoints,
                };

            })
        };

    }

    _onUpdate() {

        const {
            world, position, paused, playerBody, playerRadius, maxLength
        } = this.props;

        const {
            counter,
            rayArray,
            lengths: oldLengths,
            lengthTargets: oldLengthTargets,
            hitVectors,
            flowDirection2D
        } = this.state;

        if( !world || paused ) {
            return;
        }

        const playerBox = new THREE.Box2().setFromCenterAndSize(
            new THREE.Vector2( playerBody.position[ 0 ], playerBody.position[ 1 ] ),
            new THREE.Vector2( playerRadius * 1.9, playerRadius * 1.9 ),
        );

        let lengthTargets = oldLengthTargets;

        const boxes = [];

        lengthTargets = rayArray.map( ( zero, index ) => {

            const {
                fromVector2D, toVector2D, impulseVector2D, startingPoints
            } = hitVectors[ index ];

            const ray = new p2.Ray({
                mode: p2.Ray.CLOSEST,
                from: fromVector2D,
                to: toVector2D,
            });

            const result = new p2.RaycastResult();
            world.raycast( result, ray );

            const { body } = result;
            const distance = result.getHitDistance( ray );
            let hitLength;

            if( body ) {

                if( body !== playerBody ) {

                    const { mass, position: bodyPosition, } = body;
                    if( mass ) {
                        body.applyImpulse( impulseVector2D, relativeImpulsePoint );
                        //body.velocity.x += impulseVector.x;
                        //body.velocity.z += impulseVector.z;
                    }

                }
                hitLength = distance;

            } else {

                hitLength = maxLength;

            }

            const { a, b } = startingPoints;

            const points = [ a, b,
                a.clone().add( flowDirection2D.clone().multiplyScalar( hitLength * 1.1 ) ),
                b.clone().add( flowDirection2D.clone().multiplyScalar( hitLength * 1.1 ) )
            ];

            const box = new THREE.Box2().setFromPoints( points );
            boxes.push( box );

            if( box.intersectsBox( playerBox ) ) {

                playerBody.applyImpulse( impulseVector2D, relativeImpulsePoint );
                //playerBody.velocity.x += impulseVector.x;
                //playerBody.velocity.z += impulseVector.z;
                hitLength = Math.min(
                    body === playerBody ?
                        hitLength :
                        p2.vec2.distance( fromVector2D, playerBody.position ),
                    maxLength
                );

            }

            return hitLength;

        });

        const lengths = oldLengths.map( ( length, index ) => {
            const target = lengthTargets[ index ];
            return target > length ? Math.min( length + 0.2, target ) : target;
        });

        this.setState({
            counter: counter + 1,
            lengths, lengthTargets, boxes, playerBox
        });

    }

    render() {

        const {
            position, rotation, scale, time, materialId, playerRadius,
            foamMaterialId, rayCount, foam, helperMaterial, debug
        } = this.props;
        const { lengths, lengthTargets, rayArray, } = this.state;
        const waterfallHeight = -0.5 + ( playerRadius || 0.45 );

        return <group>
            <group
                position={ position }
                quaternion={ rotation || new THREE.Quaternion( 0, 0, 0, 1 ) }
                scale={ scale }
                onUpdate={ this._onUpdate }
            >
                <mesh
                    ref="mesh"
                    position={ helperPosition }
                    rotation={ helperRotation }
                >
                    <geometryResource
                        resourceId="1x1plane"
                    />
                    <materialResource
                        resourceId={ helperMaterial || 'transparent' }
                    />
                </mesh>
                <mesh
                    ref="mesh"
                >
                    <geometryResource
                        resourceId="1x1box"
                    />
                    <materialResource
                        resourceId="transparent"
                    />
                </mesh>

                {/* Foam */}
                { foam ? rayArray.map( ( zero, index ) => {

                    const length = lengths[ index ];
                    const target = lengthTargets[ index ];
                    const percentToTarget = Math.max(
                        ( 1.0 - ( Math.abs( target - length ) / target ) ) - minimumPercentToShowFoam,
                        0
                    ) * ( 1 / ( 1 - minimumPercentToShowFoam ) );

                    return <group
                        key={ index }
                        position={ new THREE.Vector3(
                            -0.5 + length,
                            waterfallHeight,
                            -0.5 + ( ( 1 / rayCount ) * index ) + ( 0.5 / rayCount ),
                        ) }
                        scale={
                            new THREE.Vector3( 1, 1, 1 ).multiplyScalar( 1 / rayCount )
                        }
                    >
                        <mesh
                            position={ new THREE.Vector3(
                                0, 0, -0.25
                            ) }
                            scale={
                                new THREE.Vector3( 1, 1, 1 )
                                    .multiplyScalar(
                                        ( bubbleMinSize * 2 + foamGrowSize * Math.sin( foamGrowSpeed * time * 0.6 - index ) ) *
                                        percentToTarget
                                    )
                            }
                            rotation={ new THREE.Euler(
                                ( foamSpeed * time - index ) * 0.1,
                                ( foamSpeed * time + index ) * 1.1,
                                foamSpeed * time
                            )}
                        >
                            <geometryResource
                                resourceId="radius1sphere"
                            />
                            <materialResource
                                resourceId={ foamMaterialId || 'waterFoam' }
                            />
                        </mesh>
                        <mesh
                            position={ new THREE.Vector3(
                                0, 0, 0.25
                            ) }
                            scale={
                                new THREE.Vector3( 1, 1, 1 )
                                    .multiplyScalar(
                                        ( bubbleMinSize * 2 + foamGrowSize * Math.cos( foamGrowSpeed * time * 1.2 + index ) ) *
                                        percentToTarget
                                    )
                            }
                            rotation={ new THREE.Euler(
                                ( foamSpeed * time + index ) * 0.6,
                                foamSpeed * time,
                                ( foamSpeed * time + index ) * 1.2,
                            )}
                        >
                            <geometryResource
                                resourceId="radius1sphere"
                            />
                            <materialResource
                                resourceId={ foamMaterialId || 'waterFoam' }
                            />
                        </mesh>
                    </group>;

                }) : null }

                {/* Emitters */}
                { rayArray.map( ( zero, index ) =>
                    <mesh
                        key={ index }
                        position={ new THREE.Vector3(
                            -0.5 + ( lengths[ index ] / 2 ),
                            waterfallHeight,
                            -0.5 + ( ( 1 / rayCount ) * index ) + ( 0.5 / rayCount )
                        ) }
                        scale={ new THREE.Vector3(
                            1 / rayCount,
                            lengths[ index ],
                            1,
                        ) }
                        rotation={ colRotation }
                    >
                        <geometryResource
                            resourceId="1x1plane"
                        />
                        <materialResource
                            resourceId={ materialId }
                        />
                    </mesh>
                )}

            </group>

            { debug ? <mesh
                position={ p2ToV3( this.state.hitVectors[ 0 ].toVector2D ) }
                scale={ new THREE.Vector3( 0.5, 3, 0.5 ) }
            >
                <geometryResource
                    resourceId="radius1sphere"
                />
                <materialResource
                    resourceId="greenDebugMaterial"
                />
            </mesh> : null }
            { debug ? <mesh
                position={ p2ToV3( this.state.hitVectors[ 0 ].fromVector2D ) }
                scale={ new THREE.Vector3( 0.5, 3, 0.5 ) }
            >
                <geometryResource
                    resourceId="radius1sphere"
                />
                <materialResource
                    resourceId="blueDebugMaterial"
                />
            </mesh> : null }
            { debug ? this.state.boxes.map( ( box, index ) => <mesh
                key={ index }
                position={ new THREE.Vector3( box.center().x, 2, box.center().y ) }
                scale={ new THREE.Vector3( box.size().x, box.size().y + 2, 1 ) }
                rotation={ toScreenRotation }
            >
                <geometryResource
                    resourceId="1x1plane"
                />
                <materialResource
                    resourceId={ index % 2 ? 'purpleDebugMaterial' : 'greenDebugMaterial' }
                />
            </mesh> ) : null }
            { debug ? <mesh
                position={ new THREE.Vector3( this.state.playerBox.center().x, 2, this.state.playerBox.center().y ) }
                scale={ new THREE.Vector3( this.state.playerBox.size().x, this.state.playerBox.size().y, 1 ) }
                rotation={ toScreenRotation }
            >
                <geometryResource
                    resourceId="1x1plane"
                />
                <materialResource
                    resourceId="purpleDebugMaterial"
                />
            </mesh> : null }
        </group>;

    }

}
<commit_msg>that not how computer wokr<commit_after>import React, { Component, PropTypes } from 'react';
import THREE from 'three';
import p2 from 'p2';
import { v3toP2, p2ToV3 } from '../../helpers/Utils';

const bubbleMinSize = 0.5;
const foamGrowSize = 0.3;
const foamGrowSpeed = 5.2;
const foamSpeed = 4.2;
const minimumPercentToShowFoam = 0.9;

// Computed values

const colRotation = new THREE.Euler( -Math.PI / 2, 0, Math.PI / 2 );
const toScreenRotation = new THREE.Euler( -Math.PI / 2, 0, 0 );
const axis = new THREE.Vector3( 0, -1, 0 );
// Which way the emitter flows by default
const forwardDirection = new THREE.Vector3( 1, 0, 0 );
const helperRotation = new THREE.Euler( 0, -Math.PI / 2, 0 );
const helperPosition = new THREE.Vector3( -0.5, 0, 0 );

const relativeImpulsePoint = [ 0, 0 ];

export default class SegmentedEmitter extends Component {

    static propTypes = {
        position: PropTypes.object.isRequired,
        rotation: PropTypes.object,
        scale: PropTypes.object,
        world: PropTypes.object,
        paused: PropTypes.bool,
        time: PropTypes.number,
        playerRadius: PropTypes.number,
        playerBody: PropTypes.object,
        maxLength: PropTypes.number.isRequired,
        impulse: PropTypes.number.isRequired,
        rayCount: PropTypes.number.isRequired,
        materialId: PropTypes.string.isRequired,
        foamMaterialId: PropTypes.string,
        foam: PropTypes.bool,
    }

    constructor( props, context ) {

        super( props, context );

        this.state = this.getStateFromProps( props, {} );

        this._onUpdate = this._onUpdate.bind( this );

    }

    componentWillReceiveProps( nextProps ) {

        if( ( nextProps.playerRadius !== this.props.playerRadius ) ||
           ( nextProps.rotation !== this.props.rotation ) ||
           ( nextProps.position !== this.props.position )
        ) {

            this.setState( this.getStateFromProps( nextProps, this.state ) );

        }

    }

    getStateFromProps( props, state ) {

        const {
            position, rotation, playerRadius, scale, maxLength, rayCount
        } = props;

        // dam son see http://stackoverflow.com/questions/5501581/javascript-new-arrayn-and-array-prototype-map-weirdness
        const rayArray = new Array( rayCount ).fill( 0 );
        const angle = new THREE.Euler().setFromQuaternion( rotation ).y;
        const impulse = ( props.impulse / rayCount );
        const playerImpulse = ( props.impulse / rayCount ) * ( playerRadius || 0.45 );
        const flowDirection = forwardDirection.clone().applyQuaternion( rotation );

        return {
            rayArray,

            // The actual lenghts tweening towards targets
            lengths: state.lengths || rayArray.map( () => 1 ),

            // Where the waterfall should be ideally based on hit test
            lengthTargets: state.lengths || rayArray.map( () => 1 ),

            counter: 0,
            flowDirection2D: new THREE.Vector2( flowDirection.x, flowDirection.z ),
            hitVectors: rayArray.map( ( zero, index ) => {

                const streamHalfWidth = 0.5 / rayCount;

                // Construct the *local* unrotated vectors that define this
                // stream in local space
                const fromVectorInitial = new THREE.Vector3(
                    // move close to left edge of emitter
                    -0.499999,
                    // move toward the back to intersect player
                    -0.5 + ( playerRadius || 0.45 ),
                    // move to rectangle offset by index
                    -0.5 + /* center */( ( 1 / rayCount ) * index ) + streamHalfWidth
                );

                const toVectorInitial = new THREE.Vector3(
                    fromVectorInitial.x + maxLength,
                    fromVectorInitial.y,
                    fromVectorInitial.z,
                );

                // Calculate the initial two points for the hit test rectangle
                // to do box test on. These are world points
                const a = fromVectorInitial
                    .clone()
                    .sub( new THREE.Vector3( 0, 0, streamHalfWidth ) )
                    .applyQuaternion( rotation )
                    .add( position );

                const b = fromVectorInitial
                    .clone()
                    .add( new THREE.Vector3( 0, 0, streamHalfWidth ) )
                    .applyQuaternion( rotation )
                    .add( position );

                const startingPoints = {
                    a: new THREE.Vector2( a.x, a.z ),
                    b: new THREE.Vector2( b.x, b.z ),
                };

                // Note, these are all in world space except for the impulse
                return {
                    fromVector2D: v3toP2(
                        fromVectorInitial.applyQuaternion( rotation ).add( position )
                    ),
                    toVector2D: v3toP2(
                        toVectorInitial.applyQuaternion( rotation ).add( position )
                    ),
                    impulseVector2D: v3toP2(
                        new THREE.Vector3( impulse, 0, 0 ).applyQuaternion( rotation )
                    ),
                    playerImpulseVector2D: v3toP2(
                        new THREE.Vector3( playerImpulse, 0, 0 ).applyQuaternion( rotation )
                    ),
                    startingPoints,
                };

            })
        };

    }

    _onUpdate() {

        const {
            world, position, paused, playerBody, playerRadius, maxLength
        } = this.props;

        const {
            counter,
            rayArray,
            lengths: oldLengths,
            lengthTargets: oldLengthTargets,
            hitVectors,
            flowDirection2D
        } = this.state;

        if( !world || paused ) {
            return;
        }

        const playerBox = new THREE.Box2().setFromCenterAndSize(
            new THREE.Vector2( playerBody.position[ 0 ], playerBody.position[ 1 ] ),
            new THREE.Vector2( playerRadius * 1.9, playerRadius * 1.9 ),
        );

        let lengthTargets = oldLengthTargets;

        const boxes = [];

        lengthTargets = rayArray.map( ( zero, index ) => {

            const {
                fromVector2D, toVector2D, impulseVector2D, startingPoints,
                playerImpulseVector2D
            } = hitVectors[ index ];

            const ray = new p2.Ray({
                mode: p2.Ray.CLOSEST,
                from: fromVector2D,
                to: toVector2D,
            });

            const result = new p2.RaycastResult();
            world.raycast( result, ray );

            const { body } = result;
            const distance = result.getHitDistance( ray );
            let hitLength;

            if( body ) {

                if( body !== playerBody ) {

                    const { mass, position: bodyPosition, } = body;
                    if( mass ) {
                        body.applyImpulse( impulseVector2D, relativeImpulsePoint );
                    }

                }
                hitLength = distance;

            } else {

                hitLength = maxLength;

            }

            const { a, b } = startingPoints;

            const points = [ a, b,
                a.clone().add( flowDirection2D.clone().multiplyScalar( hitLength * 1.1 ) ),
                b.clone().add( flowDirection2D.clone().multiplyScalar( hitLength * 1.1 ) )
            ];

            const box = new THREE.Box2().setFromPoints( points );
            boxes.push( box );

            if( box.intersectsBox( playerBox ) ) {

                playerBody.applyImpulse( playerImpulseVector2D, relativeImpulsePoint );
                hitLength = Math.min(
                    body === playerBody ?
                        hitLength :
                        p2.vec2.distance( fromVector2D, playerBody.position ),
                    maxLength
                );

            }

            return hitLength;

        });

        const lengths = oldLengths.map( ( length, index ) => {
            const target = lengthTargets[ index ];
            return target > length ? Math.min( length + 0.2, target ) : target;
        });

        this.setState({
            counter: counter + 1,
            lengths, lengthTargets, boxes, playerBox
        });

    }

    render() {

        const {
            position, rotation, scale, time, materialId, playerRadius,
            foamMaterialId, rayCount, foam, helperMaterial, debug
        } = this.props;
        const { lengths, lengthTargets, rayArray, } = this.state;
        const waterfallHeight = -0.5 + ( playerRadius || 0.45 );

        return <group>
            <group
                position={ position }
                quaternion={ rotation || new THREE.Quaternion( 0, 0, 0, 1 ) }
                scale={ scale }
                onUpdate={ this._onUpdate }
            >
                <mesh
                    ref="mesh"
                    position={ helperPosition }
                    rotation={ helperRotation }
                >
                    <geometryResource
                        resourceId="1x1plane"
                    />
                    <materialResource
                        resourceId={ helperMaterial || 'transparent' }
                    />
                </mesh>
                <mesh
                    ref="mesh"
                >
                    <geometryResource
                        resourceId="1x1box"
                    />
                    <materialResource
                        resourceId="transparent"
                    />
                </mesh>

                {/* Foam */}
                { foam ? rayArray.map( ( zero, index ) => {

                    const length = lengths[ index ];
                    const target = lengthTargets[ index ];
                    const percentToTarget = Math.max(
                        ( 1.0 - ( Math.abs( target - length ) / target ) ) - minimumPercentToShowFoam,
                        0
                    ) * ( 1 / ( 1 - minimumPercentToShowFoam ) );

                    return <group
                        key={ index }
                        position={ new THREE.Vector3(
                            -0.5 + length,
                            waterfallHeight,
                            -0.5 + ( ( 1 / rayCount ) * index ) + ( 0.5 / rayCount ),
                        ) }
                        scale={
                            new THREE.Vector3( 1, 1, 1 ).multiplyScalar( 1 / rayCount )
                        }
                    >
                        <mesh
                            position={ new THREE.Vector3(
                                0, 0, -0.25
                            ) }
                            scale={
                                new THREE.Vector3( 1, 1, 1 )
                                    .multiplyScalar(
                                        ( bubbleMinSize * 2 + foamGrowSize * Math.sin( foamGrowSpeed * time * 0.6 - index ) ) *
                                        percentToTarget
                                    )
                            }
                            rotation={ new THREE.Euler(
                                ( foamSpeed * time - index ) * 0.1,
                                ( foamSpeed * time + index ) * 1.1,
                                foamSpeed * time
                            )}
                        >
                            <geometryResource
                                resourceId="radius1sphere"
                            />
                            <materialResource
                                resourceId={ foamMaterialId || 'waterFoam' }
                            />
                        </mesh>
                        <mesh
                            position={ new THREE.Vector3(
                                0, 0, 0.25
                            ) }
                            scale={
                                new THREE.Vector3( 1, 1, 1 )
                                    .multiplyScalar(
                                        ( bubbleMinSize * 2 + foamGrowSize * Math.cos( foamGrowSpeed * time * 1.2 + index ) ) *
                                        percentToTarget
                                    )
                            }
                            rotation={ new THREE.Euler(
                                ( foamSpeed * time + index ) * 0.6,
                                foamSpeed * time,
                                ( foamSpeed * time + index ) * 1.2,
                            )}
                        >
                            <geometryResource
                                resourceId="radius1sphere"
                            />
                            <materialResource
                                resourceId={ foamMaterialId || 'waterFoam' }
                            />
                        </mesh>
                    </group>;

                }) : null }

                {/* Emitters */}
                { rayArray.map( ( zero, index ) =>
                    <mesh
                        key={ index }
                        position={ new THREE.Vector3(
                            -0.5 + ( lengths[ index ] / 2 ),
                            waterfallHeight,
                            -0.5 + ( ( 1 / rayCount ) * index ) + ( 0.5 / rayCount )
                        ) }
                        scale={ new THREE.Vector3(
                            1 / rayCount,
                            lengths[ index ],
                            1,
                        ) }
                        rotation={ colRotation }
                    >
                        <geometryResource
                            resourceId="1x1plane"
                        />
                        <materialResource
                            resourceId={ materialId }
                        />
                    </mesh>
                )}

            </group>

            { debug ? <mesh
                position={ p2ToV3( this.state.hitVectors[ 0 ].toVector2D ) }
                scale={ new THREE.Vector3( 0.5, 3, 0.5 ) }
            >
                <geometryResource
                    resourceId="radius1sphere"
                />
                <materialResource
                    resourceId="greenDebugMaterial"
                />
            </mesh> : null }
            { debug ? <mesh
                position={ p2ToV3( this.state.hitVectors[ 0 ].fromVector2D ) }
                scale={ new THREE.Vector3( 0.5, 3, 0.5 ) }
            >
                <geometryResource
                    resourceId="radius1sphere"
                />
                <materialResource
                    resourceId="blueDebugMaterial"
                />
            </mesh> : null }
            { debug ? this.state.boxes.map( ( box, index ) => <mesh
                key={ index }
                position={ new THREE.Vector3( box.center().x, 2, box.center().y ) }
                scale={ new THREE.Vector3( box.size().x, box.size().y + 2, 1 ) }
                rotation={ toScreenRotation }
            >
                <geometryResource
                    resourceId="1x1plane"
                />
                <materialResource
                    resourceId={ index % 2 ? 'purpleDebugMaterial' : 'greenDebugMaterial' }
                />
            </mesh> ) : null }
            { debug ? <mesh
                position={ new THREE.Vector3( this.state.playerBox.center().x, 2, this.state.playerBox.center().y ) }
                scale={ new THREE.Vector3( this.state.playerBox.size().x, this.state.playerBox.size().y, 1 ) }
                rotation={ toScreenRotation }
            >
                <geometryResource
                    resourceId="1x1plane"
                />
                <materialResource
                    resourceId="purpleDebugMaterial"
                />
            </mesh> : null }
        </group>;

    }

}
<|endoftext|>


<commit_before>var _ = require('lodash');

var NULL = 0;
var MOVE = 1;
var RESIZE = 2;

var Window = function (props) {
  _.extend(this, _.defaults(props || {}, this.defaults));
};

_.extend(Window.prototype, {

  onChange: _.noop,

  /**
   * defaults
   */

  defaults: {
    id: undefined,
    x: 0,
    y: 0,
    width: 0,
    height: 0,
    maxWidth: Infinity,
    minWidth: 0,
    maxHeight: Infinity,
    minHeight: 0,
    title: '',
    open: true
  },

  /**
   * move the window to a point
   * - x (int)
   * - y (int)
   */

  move: function (x, y) {
    this._realX = x - this._offsetX;
    this._realY = y - this._offsetY;
    this.snap();
  },

  startMove: function (x, y) {
    this._mode = MOVE;
    this._offsetX = x - this.x;
    this._offsetY = y - this.y;
    this._realX = this.x;
    this._realY = this.y;
  },

  endMove: function () {
    delete this._realX;
    delete this._realY;
    this._mode = NULL;
    this.onChange();
  },

  /**
   * resize the window by an amount
   * - deltaX (int) : negative=left, positive=right
   * - detlaY (int) : negative=up, positive=down
   * - isLeft (bool) : true=left, false=right
   * - isTop (bool) : true=top, false=bottom
   */

  resize: function (x, y) {
    var deltaX = x - this._originX;
    var deltaY = y - this._originY;

    console.log(deltaX, deltaY);

    var finalWidth = this.width + (this._quad.left ? deltaX * -1 : deltaX);
    var finalHeight = this.height + (this._quad.top ? deltaY * -1 : deltaY);

    if (finalWidth > this.maxWidth || finalWidth < this.minWidth) {
      deltaX = 0;
    }

    if (finalHeight > this.maxHeight || finalHeight < this.minHeight) {
      deltaY = 0;
    }

    if (this._quad.left) {
      this.x += deltaX;
      this.width -= deltaX;
    } else {
      this.width += deltaX;
    }

    if (this._quad.top) {
      this.y += deltaY;
      this.height -= deltaY;
    } else {
      this.height += deltaY;
    }
  },

  startResize: function (x, y) {
    console.log('starting resize');
    this._mode = RESIZE;
    this._quad = this.quadrant(x, y);
    this._originX = x;
    this._originY = y;
    this._realX = this.x;
    this._realY = this.y;
  },

  endResize: function () {
    console.log('ending resize');
    delete this._quad;
    delete this._realX;
    delete this._realY;
    delete this._originX;
    delete this._originY;
    this._mode = NULL;
    this.onChange();
  },

  /**
   * snap the window to some guidelines
   */

  snap: function () {
    this.x = this._realX;
    this.y = this._realY;
  },

  /**
   * find which quadrant of the window the mouse is
   * - x (int)
   * - y (int)
   */

  quadrant: function (x, y) {
    return {
      top: y < this.y + (this.height / 2),
      left: x < this.x + (this.width / 2)
    };
  },

  /**
   * close the window
   */

  close: function () {
    this.open = false;
    if (this.manager) this.manager.remove(this);
    this.onChange();
  },

  /**
   * focus the window
   */

  requestFocus: function () {
    if (this.manager) this.manager.bringToFront(this);
  },

  /*
   * rename the window
   * - title (string)
   */

  rename: function (title) {
    this.title = title;
    this.onChange();
  },

  /**
   * export model as json
   */

  toJSON: function () {
    return {
      id:      this.id,
      x:       this.x,
      y:       this.y,
      width:   this.width,
      height:  this.height,
      title:   this.title,
      open:    this.open
    };
  }

});

module.exports = Window;
<commit_msg>Fix resizing<commit_after>var _ = require('lodash');

var NULL = 0;
var MOVE = 1;
var RESIZE = 2;

var Window = function (props) {
  _.extend(this, _.defaults(props || {}, this.defaults));
};

_.extend(Window.prototype, {

  onChange: _.noop,

  /**
   * defaults
   */

  defaults: {
    id: undefined,
    x: 0,
    y: 0,
    width: 0,
    height: 0,
    maxWidth: Infinity,
    minWidth: 0,
    maxHeight: Infinity,
    minHeight: 0,
    title: '',
    open: true
  },

  /**
   * move the window to a point
   * - x (int)
   * - y (int)
   */

  move: function (x, y) {
    this._realX = x - this._offsetX;
    this._realY = y - this._offsetY;
    this.snap();
  },

  startMove: function (x, y) {
    this._mode = MOVE;
    this._offsetX = x - this.x;
    this._offsetY = y - this.y;
    this._realX = this.x;
    this._realY = this.y;
  },

  endMove: function () {
    delete this._realX;
    delete this._realY;
    this._mode = NULL;
    this.onChange();
  },

  /**
   * resize the window by an amount
   * - deltaX (int) : negative=left, positive=right
   * - detlaY (int) : negative=up, positive=down
   * - isLeft (bool) : true=left, false=right
   * - isTop (bool) : true=top, false=bottom
   */

  resize: function (x, y) {
    var deltaX = x - this._originX;
    var deltaY = y - this._originY;

    var finalWidth = this._startWidth + (this._quad.left ? deltaX * -1 : deltaX);
    var finalHeight = this._startHeight + (this._quad.top ? deltaY * -1 : deltaY);

    if (finalWidth > this.maxWidth || finalWidth < this.minWidth) {
      deltaX = this.maxWidth - this._startWidth;
      if (this._quad.left) deltaX *= -1;
    }

    if (finalHeight > this.maxHeight || finalHeight < this.minHeight) {
      deltaY = this.maxHeight - this._startHeight;
      if (this._quad.top) deltaY *= -1;
    }

    if (this._quad.left) {
      this.x = this._startX + deltaX;
      this.width = this._startWidth - deltaX;
    } else {
      this.width = this._startWidth + deltaX;
    }

    if (this._quad.top) {
      this.y = this._startY + deltaY;
      this.height = this._startHeight - deltaY;
    } else {
      this.height = this._startHeight + deltaY;
    }
  },

  startResize: function (x, y) {
    console.log('starting resize');
    this._mode = RESIZE;
    this._quad = this.quadrant(x, y);
    this._startX = this.x;
    this._startY = this.y;
    this._startWidth = this.width;
    this._startHeight = this.height;
    this._originX = x;
    this._originY = y;
    this._realX = this.x;
    this._realY = this.y;
  },

  endResize: function () {
    console.log('ending resize');
    delete this._quad;
    delete this._realX;
    delete this._realY;
    delete this._originX;
    delete this._originY;
    this._mode = NULL;
    this.onChange();
  },

  /**
   * snap the window to some guidelines
   */

  snap: function () {
    this.x = this._realX;
    this.y = this._realY;
  },

  /**
   * find which quadrant of the window the mouse is
   * - x (int)
   * - y (int)
   */

  quadrant: function (x, y) {
    return {
      top: y < this.y + (this.height / 2),
      left: x < this.x + (this.width / 2)
    };
  },

  /**
   * close the window
   */

  close: function () {
    this.open = false;
    if (this.manager) this.manager.remove(this);
    this.onChange();
  },

  /**
   * focus the window
   */

  requestFocus: function () {
    if (this.manager) this.manager.bringToFront(this);
  },

  /*
   * rename the window
   * - title (string)
   */

  rename: function (title) {
    this.title = title;
    this.onChange();
  },

  /**
   * export model as json
   */

  toJSON: function () {
    return {
      id:      this.id,
      x:       this.x,
      y:       this.y,
      width:   this.width,
      height:  this.height,
      title:   this.title,
      open:    this.open
    };
  }

});

module.exports = Window;
<|endoftext|>


<commit_before>import { scaleLinear } from 'd3';

import {
  DoubleSide,
  Geometry,
  Line,
  LineBasicMaterial,
  LinePieces,
  Mesh,
  MeshBasicMaterial,
  PlaneBufferGeometry,
  ShaderMaterial,
  Shape,
  ShapeGeometry,
  TextGeometry,
  Vector3
} from 'three';

import {
  LINE,
  LINE_SHADER
} from 'components/fragments/fragments-defaults';

import fgmState from './fragments-state';

export function calculateClusterPiling (
  threshold, matrices, distanceMatrix
) {
  let piling = [0];
  let pilecount = 1;
  for (let i = 1; i < matrices.length; i++) {
    for (let j = i - 1; j >= piling[pilecount - 1]; j--) {
      if (distanceMatrix[i][j] > threshold) {
        piling[pilecount] = i;
        pilecount += 1;
        break;
      }
    }
  }
  return piling;
}

export function calculateDistances (matrices) {
  // Init distance with `-1`
  const distanceMatrix = Array(matrices.length).fill(
    Array(matrices.length).fill(-1)
  );

  let maxDistance = 0;

  for (let i = 1; i < matrices.length; i++) {
    for (let j = i - 1; j >= 0; j--) {
      const distance = calculateDistance(matrices[i], matrices[j]);

      distanceMatrix[i][j] = distance;
      distanceMatrix[j][i] = distance;

      maxDistance = Math.max(maxDistance, distance);
    }
  }

  return { distanceMatrix, maxDistance };
}

export const cellValue = scaleLinear().range([0, 1]).nice();

export const frameValue = scaleLinear().range([0.1, 0.9]).nice();

/**
 * Get the minimal dimension of two matrices assuming that both are squared.
 *
 * @param {array} matrix1 - First raw matrix.
 * @param {array} matrix2 - Second raw matrix.
 * @return {number} Smaller dimension of the two matrices.
 */
function getMinDim (matrix1, matrix2) {
  return Math.min(matrix1.length, matrix2.length);
}

/**
 * Calculate the distance between two matrices.
 *
 * @param {array} matrix1 - First raw matrix.
 * @param {array} matrix2 - Second raw matrix.
 * @return {number} Distance
 */
function calculateDistance (matrix1, matrix2) {
  const dim = getMinDim(matrix1, matrix2);

  let distance = 0;

  for (let i = 0; i < dim; i++) {
    for (let j = i; j < dim; j++) {
      distance += (matrix1[i][j] - matrix2[i][j]) ** 2;
    }
  }

  return Math.sqrt(distance);
}

/**
 * Add a 2D squared buffered rantagnle
 *
 * @param {array} positions - List of positions that will be added to in-place.
 * @param {number} x - X position
 * @param {number} y - Y position
 * @param {number} w - Width
 * @param {array} colors - List of colors that will be added to in-place.
 * @param {array} color - RGB color array.
 */
export function add2dSqrtBuffRect (positions, x, y, w, colors, color) {
  addBufferedRect(positions, x, y, 0, w, w, colors, color);
}

/**
 * Add a buffered rectangle configs.
 *
 * @description
 * This methods add positions and colors in-place on `positions` and `colors`.
 *
 * @param {array} positions - List of positions that will be added to in-place.
 * @param {number} x - X position
 * @param {number} y - Y position
 * @param {number} z - Z position
 * @param {number} w - Width
 * @param {number} h - Height
 * @param {array} colors - List of colors that will be added to in-place.
 * @param {array} color - RGB color array.
 */
export function addBufferedRect (positions, x, y, z, w, h, colors, color) {
  const widthHalf = w / 2;
  const heightHalf = h / 2;

  positions.push(
    [x - widthHalf, y - heightHalf, z],
    [x + widthHalf, y - heightHalf, z],
    [x + widthHalf, y + heightHalf, z],
    [x + widthHalf, y + heightHalf, z],
    [x - widthHalf, y + heightHalf, z],
    [x - widthHalf, y - heightHalf, z]
  );

  colors.push(
    [color[0], color[1], color[2]],
    [color[0], color[1], color[2]],
    [color[0], color[1], color[2]],
    [color[0], color[1], color[2]],
    [color[0], color[1], color[2]],
    [color[0], color[1], color[2]]
  );
}

export function makeBuffer3f (array) {
  const buffer = new Float32Array(array.length * 3);  // three components per vertex

  array.forEach((entry, index) => {
    buffer[(index * 3) + 0] = entry[0];
    buffer[(index * 3) + 1] = entry[1];
    buffer[(index * 3) + 2] = entry[2];
  });

  return buffer;
}

export function createLineFrame (width, height, color, lineWidth) {
  const wh = width / 2;
  const hh = height / 2;

  const coordinates = [
    [-wh, -hh],
    [-wh, hh],
    [wh, hh],
    [wh, -hh]
  ];

  const geometry = LINE(coordinates, { closed: true });

  const material = new ShaderMaterial(LINE_SHADER({
    side: DoubleSide,
    diffuse: color,
    thickness: lineWidth
  }));

  return new Mesh(geometry, material);
}

export function createChMap (
  points, convexHull, polygonMaterial, pointsMaterial, lineMaterial
) {
  // Create the bg for the convexHull
  const chMesh = createPolygon(convexHull, polygonMaterial, lineMaterial);

  return chMesh;
}

export function createPolygon (points, polygonMaterial, lineMaterial) {
  const polygon = new Shape();

  polygon.autoClose = true;

  polygon.moveTo(points[0][0], points[0][1]);

  points.slice(1).forEach((point, index) => {
    polygon.lineTo(point[0], point[1]);
  });

  let polygonGeom = new ShapeGeometry(polygon);

  const mesh = new Mesh(polygonGeom, polygonMaterial);

  if (lineMaterial) {
    const ass = LINE(points, { closed: true });
    mesh.add(new Mesh(ass, lineMaterial));
  }

  return mesh;
}

export function createRectFrame (w, h, color, lineWidth) {
  const wh = w / 2;
  const hh = h / 2;

  let geom = new Geometry();

  geom.vertices = [
    new Vector3(-wh, -hh, 0),
    new Vector3(-wh, hh, 0),
    new Vector3(wh, hh, 0),
    new Vector3(wh, -hh, 0),
    new Vector3(-wh, -hh, 0)
  ];

  let material = new LineBasicMaterial({
    color,
    linewidth: lineWidth,
    linejoin: 'round',
    linecap: 'round'
  });

  return new Line(geom, material);
}

export function createRect (w, h, color) {
  let geom = new PlaneBufferGeometry(w, h, 1, 1);
  let m = new MeshBasicMaterial({
    color,
    transparent: true,
    opacity: 1
  });
  return new Mesh(geom, m);
}

export function createText (string, x, y, z, size, color, weight) {
  const textGeom = new TextGeometry(string, {
    size: size || 8,
    height: 1,
    weight: weight || 'normal',
    curveSegments: 1,
    font: fgmState.font,
    bevelEnabled: false
  });

  const textMaterial = new MeshBasicMaterial({
    color: color || 0xff0000
  });

  const label = new Mesh(textGeom, textMaterial);

  label.position.set(x, y, z);

  return label;
}

export function createMarker (x, y, z, color) {
  let l = 10;
  let geom = new Geometry();

  geom.vertices = [
    new Vector3(-l, 0, 0),
    new Vector3(l, 0, 0),
    new Vector3(0, -l, 0),
    new Vector3(0, l, 0)
  ];

  let material = new LineBasicMaterial({
    color,
    linewidth: 1
  });

  let m = new Line(geom, material, LinePieces);

  m.position.set(x, y, z);

  return m;
}

<commit_msg>Enable 1D and 2D pile maps<commit_after>import { scaleLinear } from 'd3';

import {
  BufferAttribute,
  BufferGeometry,
  DoubleSide,
  Geometry,
  Line,
  LineBasicMaterial,
  LinePieces,
  Mesh,
  MeshBasicMaterial,
  PlaneBufferGeometry,
  ShaderMaterial,
  Shape,
  ShapeGeometry,
  TextGeometry,
  Vector3
} from 'three';

import {
  LINE,
  LINE_SHADER,
  SHADER_ATTRIBUTES
} from 'components/fragments/fragments-defaults';

import fgmState from './fragments-state';

export function calculateClusterPiling (
  threshold, matrices, distanceMatrix
) {
  let piling = [0];
  let pilecount = 1;
  for (let i = 1; i < matrices.length; i++) {
    for (let j = i - 1; j >= piling[pilecount - 1]; j--) {
      if (distanceMatrix[i][j] > threshold) {
        piling[pilecount] = i;
        pilecount += 1;
        break;
      }
    }
  }
  return piling;
}

export function calculateDistances (matrices) {
  // Init distance with `-1`
  const distanceMatrix = Array(matrices.length).fill(
    Array(matrices.length).fill(-1)
  );

  let maxDistance = 0;

  for (let i = 1; i < matrices.length; i++) {
    for (let j = i - 1; j >= 0; j--) {
      const distance = calculateDistance(matrices[i], matrices[j]);

      distanceMatrix[i][j] = distance;
      distanceMatrix[j][i] = distance;

      maxDistance = Math.max(maxDistance, distance);
    }
  }

  return { distanceMatrix, maxDistance };
}

export const cellValue = scaleLinear().range([0, 1]).nice();

export const frameValue = scaleLinear().range([0.1, 0.9]).nice();

/**
 * Get the minimal dimension of two matrices assuming that both are squared.
 *
 * @param {array} matrix1 - First raw matrix.
 * @param {array} matrix2 - Second raw matrix.
 * @return {number} Smaller dimension of the two matrices.
 */
function getMinDim (matrix1, matrix2) {
  return Math.min(matrix1.length, matrix2.length);
}

/**
 * Calculate the distance between two matrices.
 *
 * @param {array} matrix1 - First raw matrix.
 * @param {array} matrix2 - Second raw matrix.
 * @return {number} Distance
 */
function calculateDistance (matrix1, matrix2) {
  const dim = getMinDim(matrix1, matrix2);

  let distance = 0;

  for (let i = 0; i < dim; i++) {
    for (let j = i; j < dim; j++) {
      distance += (matrix1[i][j] - matrix2[i][j]) ** 2;
    }
  }

  return Math.sqrt(distance);
}

/**
 * Add a 2D squared buffered rantagnle
 *
 * @param {array} positions - List of positions that will be added to in-place.
 * @param {number} x - X position
 * @param {number} y - Y position
 * @param {number} w - Width
 * @param {array} colors - List of colors that will be added to in-place.
 * @param {array} color - RGB color array.
 */
export function add2dSqrtBuffRect (positions, x, y, w, colors, color) {
  addBufferedRect(positions, x, y, 0, w, w, colors, color);
}

/**
 * Add a buffered rectangle configs.
 *
 * @description
 * This methods add positions and colors in-place on `positions` and `colors`.
 *
 * @param {array} positions - List of positions that will be added to in-place.
 * @param {number} x - X position
 * @param {number} y - Y position
 * @param {number} z - Z position
 * @param {number} w - Width
 * @param {number} h - Height
 * @param {array} colors - List of colors that will be added to in-place.
 * @param {array} color - RGB color array.
 */
export function addBufferedRect (positions, x, y, z, w, h, colors, color) {
  const widthHalf = w / 2;
  const heightHalf = h / 2;

  positions.push(
    [x - widthHalf, y - heightHalf, z],
    [x + widthHalf, y - heightHalf, z],
    [x + widthHalf, y + heightHalf, z],
    [x + widthHalf, y + heightHalf, z],
    [x - widthHalf, y + heightHalf, z],
    [x - widthHalf, y - heightHalf, z]
  );

  colors.push(
    [color[0], color[1], color[2]],
    [color[0], color[1], color[2]],
    [color[0], color[1], color[2]],
    [color[0], color[1], color[2]],
    [color[0], color[1], color[2]],
    [color[0], color[1], color[2]]
  );
}

export function makeBuffer3f (array) {
  const buffer = new Float32Array(array.length * 3);  // three components per vertex

  array.forEach((entry, index) => {
    buffer[(index * 3) + 0] = entry[0];
    buffer[(index * 3) + 1] = entry[1];
    buffer[(index * 3) + 2] = entry[2];
  });

  return buffer;
}

export function createLineFrame (width, height, color, lineWidth) {
  const wh = width / 2;
  const hh = height / 2;

  const coordinates = [
    [-wh, -hh],
    [-wh, hh],
    [wh, hh],
    [wh, -hh]
  ];

  const geometry = LINE(coordinates, { closed: true });

  const material = new ShaderMaterial(LINE_SHADER({
    side: DoubleSide,
    diffuse: color,
    thickness: lineWidth
  }));

  return new Mesh(geometry, material);
}

export function createChMap (
  points, convexHull, polygonMaterial, pointsMaterial, lineMaterial
) {
  // Draw locations of all piled up snippets
  const positions = new Float32Array(points.length * 18);
  const widthHalf = 2;
  const heightHalf = widthHalf;

  points.forEach((point, index) => {
    positions[(index * 18) + 0] = point[0] - widthHalf;
    positions[(index * 18) + 1] = point[1] - heightHalf;
    positions[(index * 18) + 2] = 0;
    positions[(index * 18) + 3] = point[0] + widthHalf;
    positions[(index * 18) + 4] = point[1] - widthHalf;
    positions[(index * 18) + 5] = 0;
    positions[(index * 18) + 6] = point[0] + widthHalf;
    positions[(index * 18) + 7] = point[1] + widthHalf;
    positions[(index * 18) + 8] = 0;
    positions[(index * 18) + 9] = point[0] + widthHalf;
    positions[(index * 18) + 10] = point[1] + widthHalf;
    positions[(index * 18) + 11] = 0;
    positions[(index * 18) + 12] = point[0] - widthHalf;
    positions[(index * 18) + 13] = point[1] + widthHalf;
    positions[(index * 18) + 14] = 0;
    positions[(index * 18) + 15] = point[0] - widthHalf;
    positions[(index * 18) + 16] = point[1] - widthHalf;
    positions[(index * 18) + 17] = 0;
  });

  const pointsGeometry = new BufferGeometry({
    attributes: SHADER_ATTRIBUTES
  });

  pointsGeometry.addAttribute(
    'position',
    new BufferAttribute(positions, 3)
  );

  const mesh = new Mesh(pointsGeometry, pointsMaterial);

  if (points.length > 2) {
    // Create the bg for the convexHull
    mesh.add(createPolygon(convexHull, polygonMaterial, lineMaterial));
  } else {
    mesh.add(new Mesh(LINE(points), lineMaterial));
  }

  return mesh;
}

export function createPolygon (points, polygonMaterial, lineMaterial) {
  const polygon = new Shape();

  polygon.autoClose = true;

  polygon.moveTo(points[0][0], points[0][1]);

  points.slice(1).forEach((point, index) => {
    polygon.lineTo(point[0], point[1]);
  });

  let polygonGeom = new ShapeGeometry(polygon);

  const mesh = new Mesh(polygonGeom, polygonMaterial);

  if (lineMaterial) {
    mesh.add(new Mesh(LINE(points, { closed: true }), lineMaterial));
  }

  return mesh;
}

export function createRectFrame (w, h, color, lineWidth) {
  const wh = w / 2;
  const hh = h / 2;

  let geom = new Geometry();

  geom.vertices = [
    new Vector3(-wh, -hh, 0),
    new Vector3(-wh, hh, 0),
    new Vector3(wh, hh, 0),
    new Vector3(wh, -hh, 0),
    new Vector3(-wh, -hh, 0)
  ];

  let material = new LineBasicMaterial({
    color,
    linewidth: lineWidth,
    linejoin: 'round',
    linecap: 'round'
  });

  return new Line(geom, material);
}

export function createRect (w, h, color) {
  let geom = new PlaneBufferGeometry(w, h, 1, 1);
  let m = new MeshBasicMaterial({
    color,
    transparent: true,
    opacity: 1
  });
  return new Mesh(geom, m);
}

export function createText (string, x, y, z, size, color, weight) {
  const textGeom = new TextGeometry(string, {
    size: size || 8,
    height: 1,
    weight: weight || 'normal',
    curveSegments: 1,
    font: fgmState.font,
    bevelEnabled: false
  });

  const textMaterial = new MeshBasicMaterial({
    color: color || 0xff0000
  });

  const label = new Mesh(textGeom, textMaterial);

  label.position.set(x, y, z);

  return label;
}

export function createMarker (x, y, z, color) {
  let l = 10;
  let geom = new Geometry();

  geom.vertices = [
    new Vector3(-l, 0, 0),
    new Vector3(l, 0, 0),
    new Vector3(0, -l, 0),
    new Vector3(0, l, 0)
  ];

  let material = new LineBasicMaterial({
    color,
    linewidth: 1
  });

  let m = new Line(geom, material, LinePieces);

  m.position.set(x, y, z);

  return m;
}

<|endoftext|>


<commit_before>var rekapiToCSS = function (Rekapi, global, deps) {

  // CONSTANTS
  //
  var DEFAULT_GRANULARITY = 100;
  var VENDOR_PREFIXES = Rekapi.util.VENDOR_PREFIXES = {
    'microsoft': '-ms-'
    ,'mozilla': '-moz-'
    ,'opera': '-o-'
    ,'w3': ''
    ,'webkit': '-webkit-'
  };
  var _ = (deps && deps.underscore) ? deps.underscore : global._;

  // TEMPLATES
  //

  /**
   * [0]: vendor
   * [1]: animation name
   * [2]: keyframes
   */
  var KEYFRAME_TEMPLATE = [
    '@%skeyframes %s-keyframes {'
    ,'%s'
    ,'}'
  ].join('\n');

  /**
   * [0] class name
   * [1] class attributes
   */
  var CLASS_BOILERPLATE = [
    '.%s {'
    ,'  position: absolute;'
    ,'%s'
    ,'}'
  ].join('\n');

  // PROTOTYPE EXTENSIONS
  //
  /**
   * @param {Object} opts
   */
  global.Kapi.prototype.toCSS = function (opts) {
    opts = opts || {};
    var animationCSS = [];
    var actorIds = this.getActorIds();

    _.each(actorIds, function (id) {
      animationCSS.push(this.getActor(id).toCSS(opts));
    }, this);

    return animationCSS.join('\n');
  };

  /**
   * @param {Object} opts
   */
  global.Kapi.Actor.prototype.toCSS = function (opts) {
    opts = opts || {};
    var actorCSS = [];
    var granularity = opts.granularity || DEFAULT_GRANULARITY;
    var actorClass = generateCSSClass(this, opts.vendors);
    actorCSS.push(actorClass);
    var keyframes = generateActorKeyframes(this, granularity);
    var boilerplatedKeyframes = applyVendorBoilerplates(
        keyframes, this.getCSSName(), opts.vendors);
    actorCSS.push(boilerplatedKeyframes);

    return actorCSS.join('\n');
  };

  // UTILITY FUNCTIONS
  //
  /**
   * @param {string} str
   */
  function isColorString (str) {
    return /rgb/.test(str);
  }

  /**
   * @param {Rekapi.Actor} actor
   */
  function serializeActorStep (actor) {
    var serializedProps = ['{'];
    var printVal;
    _.each(actor.get(), function (val, key) {
      printVal = val;
      serializedProps.push(key + ':' + printVal + ';');
    });

    serializedProps.push('}');
    return serializedProps.join('');
  };

  /**
   * @param {Rekapi.Actor} actor
   * @param {number} granularity
   * @return {string}
   */
  function generateActorKeyframes (actor, granularity) {
    var animLength = actor.getLength();
    var i, delay = actor.getStart();
    var serializedFrames = [];
    var percent, adjustedPercent, stepPrefix;
    var increment = animLength / granularity;
    var animPercent = animLength / 100;

    for (i = delay; i <= animLength + delay; i += increment) {
      actor.calculatePosition(i);
      percent = (i - delay) / animPercent;
      adjustedPercent = +percent.toFixed(2)
      if (adjustedPercent === 0) {
        stepPrefix = 'from ';
      } else if (adjustedPercent === 100) {
        stepPrefix = 'to ';
      } else {
        stepPrefix = adjustedPercent + '% ';
      }
      serializedFrames.push('  ' + stepPrefix + serializeActorStep(actor));
    }

    return serializedFrames.join('\n');
  }

  /**
   * @param {string} toKeyframes Generated keyframes to wrap in boilerplates
   * @param {string} animName
   * @param {[string]} opt_vendors Vendor boilerplates to be applied.  Should be
   *     any of the values in Rekapi.util.VENDOR_PREFIXES.
   * @return {string}
   */
  function applyVendorBoilerplates (toKeyframes, animName, opt_vendors) {
    opt_vendors = opt_vendors || ['w3'];
    var renderedKeyframes = [];

    _.each(opt_vendors, function (vendor) {
      var renderedChunk = printf(KEYFRAME_TEMPLATE,
          [VENDOR_PREFIXES[vendor], animName, toKeyframes]);

      renderedKeyframes.push(renderedChunk);
    });

    return renderedKeyframes.join('\n');
  }

  /**
   * @param {Rekapi.Actor} actor
   * @param {[string]} opt_vendors
   */
  function generateCSSClass (actor, opt_vendors) {
    opt_vendors = opt_vendors || ['w3'];
    var classAttrs = [];
    var vendorAttrs;

    _.each(opt_vendors, function (vendor) {
      vendorAttrs = generateCSSVendorAttributes(actor, vendor);
      classAttrs.push(vendorAttrs);
    });

    var boilerplatedClass = printf(CLASS_BOILERPLATE
        ,[actor.getCSSName(), classAttrs.join('\n')]);

    return boilerplatedClass;
  }

  /**
   * @param {Rekapi.Actor} actor
   * @param {string} vendor
   */
  function generateCSSVendorAttributes (actor, vendor) {
    var generatedAttributes = [];
    var prefix = VENDOR_PREFIXES[vendor];
    var start = actor.getStart();
    var duration = actor.getEnd() - start;

    var duration = printf('  %sanimation-duration: %sms;'
        ,[prefix, duration]);
    generatedAttributes.push(duration);

    var animationName = printf('  %sanimation-name: %s;'
        ,[prefix, actor.getCSSName() + '-keyframes']);
    generatedAttributes.push(animationName);

    var delay = printf('  %sanimation-delay: %sms;', [prefix, start]);
    generatedAttributes.push(delay);

    var fillMode = printf('  %sanimation-fill-mode: forwards;', [prefix]);
    generatedAttributes.push(fillMode);

    return generatedAttributes.join('\n');
  }

  /**
   * @param {string} formatter
   * @param {[string]} args
   * @return {string}
   */
  var printf = Rekapi.util.printf = function (formatter, args) {
    var composedStr = formatter;
    _.each(args, function (arg) {
      composedStr = composedStr.replace('%s', arg);
    });

    return composedStr;
  };

};
<commit_msg>Made the CSS generator algorithm a little safer.<commit_after>var rekapiToCSS = function (Rekapi, global, deps) {

  // CONSTANTS
  //
  var DEFAULT_GRANULARITY = 100;
  var VENDOR_PREFIXES = Rekapi.util.VENDOR_PREFIXES = {
    'microsoft': '-ms-'
    ,'mozilla': '-moz-'
    ,'opera': '-o-'
    ,'w3': ''
    ,'webkit': '-webkit-'
  };
  var _ = (deps && deps.underscore) ? deps.underscore : global._;

  // TEMPLATES
  //

  /**
   * [0]: vendor
   * [1]: animation name
   * [2]: keyframes
   */
  var KEYFRAME_TEMPLATE = [
    '@%skeyframes %s-keyframes {'
    ,'%s'
    ,'}'
  ].join('\n');

  /**
   * [0] class name
   * [1] class attributes
   */
  var CLASS_BOILERPLATE = [
    '.%s {'
    ,'  position: absolute;'
    ,'%s'
    ,'}'
  ].join('\n');

  // PROTOTYPE EXTENSIONS
  //
  /**
   * @param {Object} opts
   */
  global.Kapi.prototype.toCSS = function (opts) {
    opts = opts || {};
    var animationCSS = [];
    var actorIds = this.getActorIds();

    _.each(actorIds, function (id) {
      animationCSS.push(this.getActor(id).toCSS(opts));
    }, this);

    return animationCSS.join('\n');
  };

  /**
   * @param {Object} opts
   */
  global.Kapi.Actor.prototype.toCSS = function (opts) {
    opts = opts || {};
    var actorCSS = [];
    var granularity = opts.granularity || DEFAULT_GRANULARITY;
    var actorClass = generateCSSClass(this, opts.vendors);
    actorCSS.push(actorClass);
    var keyframes = generateActorKeyframes(this, granularity);
    var boilerplatedKeyframes = applyVendorBoilerplates(
        keyframes, this.getCSSName(), opts.vendors);
    actorCSS.push(boilerplatedKeyframes);

    return actorCSS.join('\n');
  };

  // UTILITY FUNCTIONS
  //
  /**
   * @param {string} str
   */
  function isColorString (str) {
    return /rgb/.test(str);
  }

  /**
   * @param {Rekapi.Actor} actor
   */
  function serializeActorStep (actor) {
    var serializedProps = ['{'];
    var printVal;
    _.each(actor.get(), function (val, key) {
      printVal = val;
      serializedProps.push(key + ':' + printVal + ';');
    });

    serializedProps.push('}');
    return serializedProps.join('');
  };

  /**
   * @param {Rekapi.Actor} actor
   * @param {number} granularity
   * @return {string}
   */
  function generateActorKeyframes (actor, granularity) {
    var animLength = actor.getLength();
    var delay = actor.getStart();
    var serializedFrames = [];
    var percent, adjustedPercent, stepPrefix;
    var increment = animLength / granularity;
    var adjustedIncrement = Math.floor(increment);
    var animPercent = animLength / 100;
    var loopStart = delay + increment;
    var loopEnd = animLength + delay - increment;

    actor.calculatePosition(delay);
    serializedFrames.push('  from ' + serializeActorStep(actor));

    for (var i = loopStart; i <= loopEnd; i += increment) {
      actor.calculatePosition(i);
      percent = (i - delay) / animPercent;
      adjustedPercent = +percent.toFixed(2)
      stepPrefix = adjustedPercent + '% ';
      serializedFrames.push('  ' + stepPrefix + serializeActorStep(actor));
    }

    actor.calculatePosition(animLength + delay);
    serializedFrames.push('  to ' + serializeActorStep(actor));

    return serializedFrames.join('\n');
  }

  /**
   * @param {string} toKeyframes Generated keyframes to wrap in boilerplates
   * @param {string} animName
   * @param {[string]} opt_vendors Vendor boilerplates to be applied.  Should be
   *     any of the values in Rekapi.util.VENDOR_PREFIXES.
   * @return {string}
   */
  function applyVendorBoilerplates (toKeyframes, animName, opt_vendors) {
    opt_vendors = opt_vendors || ['w3'];
    var renderedKeyframes = [];

    _.each(opt_vendors, function (vendor) {
      var renderedChunk = printf(KEYFRAME_TEMPLATE,
          [VENDOR_PREFIXES[vendor], animName, toKeyframes]);

      renderedKeyframes.push(renderedChunk);
    });

    return renderedKeyframes.join('\n');
  }

  /**
   * @param {Rekapi.Actor} actor
   * @param {[string]} opt_vendors
   */
  function generateCSSClass (actor, opt_vendors) {
    opt_vendors = opt_vendors || ['w3'];
    var classAttrs = [];
    var vendorAttrs;

    _.each(opt_vendors, function (vendor) {
      vendorAttrs = generateCSSVendorAttributes(actor, vendor);
      classAttrs.push(vendorAttrs);
    });

    var boilerplatedClass = printf(CLASS_BOILERPLATE
        ,[actor.getCSSName(), classAttrs.join('\n')]);

    return boilerplatedClass;
  }

  /**
   * @param {Rekapi.Actor} actor
   * @param {string} vendor
   */
  function generateCSSVendorAttributes (actor, vendor) {
    var generatedAttributes = [];
    var prefix = VENDOR_PREFIXES[vendor];
    var start = actor.getStart();
    var duration = actor.getEnd() - start;

    var duration = printf('  %sanimation-duration: %sms;'
        ,[prefix, duration]);
    generatedAttributes.push(duration);

    var animationName = printf('  %sanimation-name: %s;'
        ,[prefix, actor.getCSSName() + '-keyframes']);
    generatedAttributes.push(animationName);

    var delay = printf('  %sanimation-delay: %sms;', [prefix, start]);
    generatedAttributes.push(delay);

    var fillMode = printf('  %sanimation-fill-mode: forwards;', [prefix]);
    generatedAttributes.push(fillMode);

    return generatedAttributes.join('\n');
  }

  /**
   * @param {string} formatter
   * @param {[string]} args
   * @return {string}
   */
  var printf = Rekapi.util.printf = function (formatter, args) {
    var composedStr = formatter;
    _.each(args, function (arg) {
      composedStr = composedStr.replace('%s', arg);
    });

    return composedStr;
  };

};
<|endoftext|>


<commit_before>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';

import InputBase from './InputBase';
import Box, { omitBoxProps, pickBoxProps } from '../box';
import ValidationText from '../validationText';

import theme from './theme.css';

class SingleLineInputBase extends PureComponent {
  state = {
    inputHasfocus: false,
  };

  handleBlur = event => {
    this.setState({ inputHasfocus: false });
    if (this.props.onBlur) {
      this.props.onBlur(event);
    }
  };

  handleFocus = event => {
    this.setState({ inputHasfocus: true });
    if (this.props.onFocus) {
      this.props.onFocus(event);
    }
  };

  renderOneOrMultipleElements(prop) {
    if (Array.isArray(prop)) {
      return prop.map((element, index) => React.cloneElement(element, { key: index }));
    }

    return prop;
  }

  render() {
    const {
      className,
      connectedLeft,
      connectedRight,
      disabled,
      error,
      helpText,
      onFocus,
      onBlur,
      prefix,
      inverse,
      readOnly,
      suffix,
      width,
      warning,
      ...others
    } = this.props;

    const classNames = cx(
      theme['wrapper'],
      {
        [theme['has-focus']]: this.state.inputHasfocus,
        [theme['has-error']]: error,
        [theme['has-warning']]: warning,
        [theme['has-connected-left']]: connectedLeft,
        [theme['has-connected-right']]: connectedRight,
        [theme['is-disabled']]: disabled,
        [theme['is-inverse']]: inverse,
        [theme['is-read-only']]: readOnly,
      },
      className,
    );

    const boxProps = pickBoxProps(others);
    const inputProps = {
      disabled,
      error,
      inverse,
      onBlur: this.handleBlur,
      onFocus: this.handleFocus,
      readOnly,
      ...omitBoxProps(others),
    };

    return (
      <Box className={classNames} {...boxProps}>

          {connectedLeft}

            {prefix &&
{this.renderOneOrMultipleElements(prefix)}
}
            <InputBase {...inputProps} />
            {suffix &&
{this.renderOneOrMultipleElements(suffix)}
}

          {connectedRight}

        <ValidationText error={error} help={helpText} inverse={inverse} warning={warning} />
      </Box>
    );
  }
}

SingleLineInputBase.propTypes = {
  /** Element stuck to the left hand side of the component. */
  connectedLeft: PropTypes.element,
  /** Element stuck to the right hand side of the component. */
  connectedRight: PropTypes.element,
  /** The text string/element to use as error message below the input. */
  error: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
  /** The text string to use as help text below the input. */
  helpText: PropTypes.string,
  /** The text string/element to use as a prefix inside the input field */
  prefix: PropTypes.oneOfType([PropTypes.array, PropTypes.element]),
  /** The text string/element to use as a suffix inside the input field */
  suffix: PropTypes.oneOfType([PropTypes.array, PropTypes.element]),
  /** A custom width for the input field */
  width: PropTypes.string,
};

export default SingleLineInputBase;
<commit_msg>SingleLineInputBase: add 'warning' prop type & its description<commit_after>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';

import InputBase from './InputBase';
import Box, { omitBoxProps, pickBoxProps } from '../box';
import ValidationText from '../validationText';

import theme from './theme.css';

class SingleLineInputBase extends PureComponent {
  state = {
    inputHasfocus: false,
  };

  handleBlur = event => {
    this.setState({ inputHasfocus: false });
    if (this.props.onBlur) {
      this.props.onBlur(event);
    }
  };

  handleFocus = event => {
    this.setState({ inputHasfocus: true });
    if (this.props.onFocus) {
      this.props.onFocus(event);
    }
  };

  renderOneOrMultipleElements(prop) {
    if (Array.isArray(prop)) {
      return prop.map((element, index) => React.cloneElement(element, { key: index }));
    }

    return prop;
  }

  render() {
    const {
      className,
      connectedLeft,
      connectedRight,
      disabled,
      error,
      helpText,
      onFocus,
      onBlur,
      prefix,
      inverse,
      readOnly,
      suffix,
      width,
      warning,
      ...others
    } = this.props;

    const classNames = cx(
      theme['wrapper'],
      {
        [theme['has-focus']]: this.state.inputHasfocus,
        [theme['has-error']]: error,
        [theme['has-warning']]: warning,
        [theme['has-connected-left']]: connectedLeft,
        [theme['has-connected-right']]: connectedRight,
        [theme['is-disabled']]: disabled,
        [theme['is-inverse']]: inverse,
        [theme['is-read-only']]: readOnly,
      },
      className,
    );

    const boxProps = pickBoxProps(others);
    const inputProps = {
      disabled,
      error,
      inverse,
      onBlur: this.handleBlur,
      onFocus: this.handleFocus,
      readOnly,
      ...omitBoxProps(others),
    };

    return (
      <Box className={classNames} {...boxProps}>

          {connectedLeft}

            {prefix &&
{this.renderOneOrMultipleElements(prefix)}
}
            <InputBase {...inputProps} />
            {suffix &&
{this.renderOneOrMultipleElements(suffix)}
}

          {connectedRight}

        <ValidationText error={error} help={helpText} inverse={inverse} warning={warning} />
      </Box>
    );
  }
}

SingleLineInputBase.propTypes = {
  /** Element stuck to the left hand side of the component. */
  connectedLeft: PropTypes.element,
  /** Element stuck to the right hand side of the component. */
  connectedRight: PropTypes.element,
  /** The text string/element to use as error message below the input. */
  error: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
  /** The text string to use as help text below the input. */
  helpText: PropTypes.string,
  /** The text string/element to use as a prefix inside the input field */
  prefix: PropTypes.oneOfType([PropTypes.array, PropTypes.element]),
  /** The text string/element to use as a suffix inside the input field */
  suffix: PropTypes.oneOfType([PropTypes.array, PropTypes.element]),
  /** The text to use as warning message below the input. */
  warning: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
  /** A custom width for the input field */
  width: PropTypes.string,
};

export default SingleLineInputBase;
<|endoftext|>


<commit_before>
var presets = (function() {
	var list = [];
	var current = false;
	var getByName = function(name) {

	};
	var set = function(p) {
		list = p;
	};
	var getCurrent = function(name) {
		if (current) {

		} else {
			current = getByName('Default');
		}
		return current;
	};
	var setCurrent = function(name) {

	};
	var getAll = function(name) {
		return list;
	};
	var sort = function() {
		//sort the presets by name (just because its more fun to do it on every clik... right?)
		list.sort(function(a, b) {
			a = ('' + a).toLowerCase();
			b = ('' + b).toLowerCase();
			if (a.name > b.name) {
				return 1;
			}
			if (a.name < b.name) {
				return -1;
			}
			return 0;
		});
	};
	return {
		getByName : getByName,
		getAll : getAll,
		set : set
	};
})(); <commit_msg>Presets wrapper<commit_after>var presets = (function() {
	var list = [];
	var selected = false;

	var getByName = function(name, presetList) {
		presetList = presetList ? presetList : list;
		name = (name) ?''+ name : '';
		for (var i = 0, l = presetList.length; i < l; i++) {
			if (presetList[i].name.toLowerCase() === name.toLowerCase()) {
				return presetList[i];
			}
		}
		return false;
	};

	var removeByName = function(name) {
		name = (name) ? ''+name : '';
		for (var i = 0, l = list.length; i < l; i++) {
			if (list[i].name.toLowerCase() === name.toLowerCase() && list[i].default !== true) {
				list.splice(i, 1);
				selected = false;
				getSelected();
				return true;
			}
		}
		return false;
	};

	var setAll = function(p) {
		list = (p) ? JSON.parse(JSON.stringify(p)) : JSON.parse(JSON.stringify(CONST.PRESETS));
		console.log('presets.setAll', list);
	};

	var getSelected = function() {
		if (!selected) {
			selected = getByName('default');
		}
		return selected;
	};
	var isSelected = function(preset) {
		var selected = getSelected();
		if (preset.name == selected.name && preset.default == selected.default) {
			return true;
		}
		return false;
	};

	var setSelected = function(name) {
		selected = getByName(name);
		var ret = getSelected();
		console.log('presets.setSelected', selected, ret);
		return ret;
	};
	var setPreset = function(preset) {
	};
	var setNewPreset = function(preset) {
		delete preset['default'];
		list.push(preset);
		console.log(list);
	};
	var getUsers = function() {
		var retList = [];
		for (var i = 0, l = list.length; i < l; i++) {
			if (list[i].default !== true) {
				console.log(i);
				retList.push(list[i]);
			}
		}
		console.log('retList', list, retList);
		return sort(retList);
	};

	var getPredefined = function() {
		var retList = [];
		for (var i = 0, l = list.length; i < l; i++) {
			if (list[i].default === true) {
				retList.push(list[i]);
			}
		}
		return retList;
	};

	var getAll = function(name) {
		return list;
	};

	var reset = function(name) {
		var oldPreset = getByName(name, presetList);
		var preset = getByName(name);
		preset = oldPreset;
		//TODO:
	};
	var resetAll = function() {
		list = JSON.parse(JSON.stringify(CONST.PRESETS));
		console.log('list', list);
		selected = false;
	};

	var sort = function(list) {
		//sort the presets by name (just because its more fun to do it on every clik... right?)
		list.sort(function(a, b) {
			if (a.name.toLowerCase() > b.name.toLowerCase()) {
				return 1;
			}
			if (a.name.toLowerCase() < b.name.toLowerCase()) {
				return -1;
			}
			return 0;
		});
		return list;
	};
	return {
		getByName : getByName,
		removeByName : removeByName,
		getSelected : getSelected,
		setSelected : setSelected,
		setNewPreset : setNewPreset,
		setPreset : setPreset,
		isSelected : isSelected,
		getUsers : getUsers,
		getPredefined : getPredefined,
		getAll : getAll,
		setAll : setAll,
		reset : reset,
		resetAll : resetAll

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


<commit_before>/**
* Copyright 2012-2016, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

var fontAttrs = require('../../plots/font_attributes');
var colorAttrs = require('../color/attributes');
var extendFlat = require('../../lib/extend').extendFlat;
var buttonAttrs = require('./button_attributes');

module.exports = {
    visible: {
        valType: 'boolean',
        description: [
            'Determines whether or not this range selector is visible.'
        ].join(' ')
    },

    buttons: {
        role: 'object',
        items: buttonAttrs,
        description: [
            'buttons!!!'
        ].join(' ')
    },

    x: {
        valType: 'number',
        min: -2,
        max: 3,
        dflt: 0,
        role: 'style',
        description: 'Sets the x position (in normalized coordinates) of the range selector.'
    },
    xanchor: {
        valType: 'enumerated',
        values: ['auto', 'left', 'center', 'right'],
        dflt: 'left',
        role: 'info',
        description: [
            'Sets the range selector \'s horizontal position anchor.',
            'This anchor binds the `x` position to the *left*, *center*',
            'or *right* of the range selector.'
        ].join(' ')
    },
    y: {
        valType: 'number',
        min: -2,
        max: 3,
        dflt: 1,
        role: 'style',
        description: 'Sets the y position (in normalized coordinates) of the range selector.'
    },
    yanchor: {
        valType: 'enumerated',
        values: ['auto', 'top', 'middle', 'bottom'],
        dflt: 'auto',
        role: 'info',
        description: [
            'Sets the range selector\'s vertical position anchor',
            'This anchor binds the `y` position to the *top*, *middle*',
            'or *bottom* of the range selector.'
        ].join(' ')
    },

    font: extendFlat({}, fontAttrs, {
        description: 'Sets the font used to text the range selector buttons.'
    }),

    bgcolor: {
        valType: 'color',
        role: 'style',
        description: 'Sets the range selector background color.'
    },
    bordercolor: {
        valType: 'color',
        dflt: colorAttrs.defaultLine,
        role: 'style',
        description: 'Sets the color of the border enclosing the range selector.'
    },
    borderwidth: {
        valType: 'number',
        min: 0,
        dflt: 0,
        role: 'style',
        description: 'Sets the width (in px) of the border enclosing the range selector.'
    }
};
<commit_msg>make range selector border width dflt 1<commit_after>/**
* Copyright 2012-2016, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

var fontAttrs = require('../../plots/font_attributes');
var colorAttrs = require('../color/attributes');
var extendFlat = require('../../lib/extend').extendFlat;
var buttonAttrs = require('./button_attributes');

module.exports = {
    visible: {
        valType: 'boolean',
        description: [
            'Determines whether or not this range selector is visible.'
        ].join(' ')
    },

    buttons: {
        role: 'object',
        items: buttonAttrs,
        description: [
            'buttons!!!'
        ].join(' ')
    },

    x: {
        valType: 'number',
        min: -2,
        max: 3,
        dflt: 0,
        role: 'style',
        description: 'Sets the x position (in normalized coordinates) of the range selector.'
    },
    xanchor: {
        valType: 'enumerated',
        values: ['auto', 'left', 'center', 'right'],
        dflt: 'left',
        role: 'info',
        description: [
            'Sets the range selector \'s horizontal position anchor.',
            'This anchor binds the `x` position to the *left*, *center*',
            'or *right* of the range selector.'
        ].join(' ')
    },
    y: {
        valType: 'number',
        min: -2,
        max: 3,
        dflt: 1,
        role: 'style',
        description: 'Sets the y position (in normalized coordinates) of the range selector.'
    },
    yanchor: {
        valType: 'enumerated',
        values: ['auto', 'top', 'middle', 'bottom'],
        dflt: 'auto',
        role: 'info',
        description: [
            'Sets the range selector\'s vertical position anchor',
            'This anchor binds the `y` position to the *top*, *middle*',
            'or *bottom* of the range selector.'
        ].join(' ')
    },

    font: extendFlat({}, fontAttrs, {
        description: 'Sets the font used to text the range selector buttons.'
    }),

    bgcolor: {
        valType: 'color',
        role: 'style',
        description: 'Sets the range selector background color.'
    },
    bordercolor: {
        valType: 'color',
        dflt: colorAttrs.defaultLine,
        role: 'style',
        description: 'Sets the color of the border enclosing the range selector.'
    },
    borderwidth: {
        valType: 'number',
        min: 0,
        dflt: 1,
        role: 'style',
        description: 'Sets the width (in px) of the border enclosing the range selector.'
    }
};
<|endoftext|>


<commit_before>/*
 * index.js: Compute client for OpenStack
 *
 * (C) 2013 Nodejitsu Inc.
 *
 */

var utile     = require('utile'),
    openstack = require('../../client');

var Client = exports.Client = function (options) {
  openstack.Client.call(this, options);

  utile.mixin(this, require('./flavors'));
  // utile.mixin(this, require('./images'));
  // utile.mixin(this, require('./servers'));
};

utile.inherits(Client, openstack.Client);

Client.prototype.url = function () {
  var args = Array.prototype.slice.call(arguments);
  return [
    this.config.serversUrl || 'http://trystack.org',
    'v2.0'
  ].concat(args).join('/');
};

//
// Gets the version of the OpenStack Compute API we are running against
// Parameters: callback
//
Client.prototype.getVersion = function getVersion (callback) {
  this._request({
    path: '/'
  }, callback, function (body, res) {
    return callback(null,
      ((typeof body === 'object') ? body.version.id : JSON.parse(body).version.id));
  });
};
<commit_msg>[openstack][compute] added getVersion() and pass the tests<commit_after>/*
 * index.js: Compute client for OpenStack
 *
 * (C) 2013 Nodejitsu Inc.
 *
 */

var utile     = require('utile'),
    openstack = require('../../client');

var Client = exports.Client = function (options) {
  openstack.Client.call(this, options);

  utile.mixin(this, require('./flavors'));
  // utile.mixin(this, require('./images'));
  // utile.mixin(this, require('./servers'));
};

utile.inherits(Client, openstack.Client);

Client.prototype.url = function url () {
  return this.serviceUrl.apply(this, ['compute'].concat(Array.prototype.slice.call(arguments)));
};

//
// Gets the version of the OpenStack Compute API we are running against
// Parameters: callback
//
Client.prototype.getVersion = function getVersion (callback) {
  var self = this;

  this.auth(function () {
    self._request({
      url: self.url().replace(self.config.tenantId, '')
    }, callback, function (body, res) {
        var verbose = ((typeof body === 'object') ? body.version : JSON.parse(body).version);
        return callback(null, verbose.id, verbose);
    });
  });
};
<|endoftext|>


<commit_before>function onKeyPress(key) {
    if(key === NEXT) {
        var nextButton = document.querySelector('button.next-btn');
        simulateClick(nextButton);
    } else if(key === PLAY) {
        var playButton = document.querySelector('button.play-btn'),
            pauseButton;
        try {
            if (playButton.classList.contains('hidden')) {
                pauseButton = document.querySelector('button.pause-btn');
                simulateClick(pauseButton);
            } else {
                simulateClick(playButton);
            }
        } catch (e) {
            var playAllButton = document.querySelector('a.play-btn');
            simulateClick(playAllButton);
        }
    } else if(key === PREV) {
        var backButton = document.querySelector('button.previous-btn');
        simulateClick(backButton);
    } else if(key === STOP) {
        var backButton = document.querySelector('button.stop-btn');
        simulateClick(backButton);
    }
}<commit_msg>Fixed copypasta stop button variable name.<commit_after>function onKeyPress(key) {
    if(key === NEXT) {
        var nextButton = document.querySelector('button.next-btn');
        simulateClick(nextButton);
    } else if(key === PLAY) {
        var playButton = document.querySelector('button.play-btn'),
            pauseButton;
        try {
            if (playButton.classList.contains('hidden')) {
                pauseButton = document.querySelector('button.pause-btn');
                simulateClick(pauseButton);
            } else {
                simulateClick(playButton);
            }
        } catch (e) {
            var playAllButton = document.querySelector('a.play-btn');
            simulateClick(playAllButton);
        }
    } else if(key === PREV) {
        var backButton = document.querySelector('button.previous-btn');
        simulateClick(backButton);
    } else if(key === STOP) {
        var stopButton = document.querySelector('button.stop-btn');
        simulateClick(stopButton);
    }
}<|endoftext|>


<commit_before>google.load('visualization', '1', {packages: ['corechart']});
function drawVisualization() {

    var backlogurl = ($('body').data('backlog') ? '/velocity/data/departmentvelocity/'+ $('body').data('backlog') : '/velocity/data');

    // Get the json
    var jsonData = getData(backlogurl);

    // Create our data table out of JSON data loaded from server.
    var data = new google.visualization.DataTable(jsonData);

        // var data = google.visualization.arrayToDataTable([
        //   ['Year/Month', 'Velocity'],
        //   ['2012/09',  23],
        //   ['2012/10',  20],
        //   ['2012/11',  26],
        //   ['2012/12',  24]
        // ]);

    var options = {
      title: 'Company Performance',
      hAxis: {title: 'Year', titleTextStyle: {color: 'red'}}
    };

    var options = {
        title : 'Department Velocity',
        vAxis: {title: "Velocity", baseline: 0, gridlines: { count: 10 }, maxValue: 35},
        hAxis: {title: "Year/Month"}
    };

    var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
    chart.draw(data, options);

}
setTimeout(google.setOnLoadCallback(drawVisualization), 2000);
<commit_msg>Fixed bug with data url<commit_after>google.load('visualization', '1', {packages: ['corechart']});
function drawVisualization() {

    var backlogurl = ($('body').data('backlog') ? '/data/departmentvelocity/'+ $('body').data('backlog') : '/data/departmentvelocity');

    // Get the json
    var jsonData = getData(backlogurl);

    // Create our data table out of JSON data loaded from server.
    var data = new google.visualization.DataTable(jsonData);

    var options = {
      title: 'Company Performance',
      hAxis: {title: 'Year', titleTextStyle: {color: 'red'}}
    };

    var options = {
        title : 'Department Velocity',
        vAxis: {title: "Velocity", baseline: 0, gridlines: { count: 10 }, maxValue: 35},
        hAxis: {title: "Year/Month"}
    };

    var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
    chart.draw(data, options);

}
setTimeout(google.setOnLoadCallback(drawVisualization), 2000);
<|endoftext|>