<commit_before>// Copyright 2014-2017, University of Colorado Boulder

/**
 * A rectangular toggle button that switches the value of a property between 2 values.
 *
 * @author John Blanco (PhET Interactive Simulations)
 * @author Sam Reid (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var inherit = require( 'PHET_CORE/inherit' );
  var RectangularButtonView = require( 'SUN/buttons/RectangularButtonView' );
  var sun = require( 'SUN/sun' );
  var Tandem = require( 'TANDEM/Tandem' );
  var ToggleButtonInteractionStateProperty = require( 'SUN/buttons/ToggleButtonInteractionStateProperty' );
  var ToggleButtonIO = require( 'SUN/buttons/ToggleButtonIO' );
  var ToggleButtonModel = require( 'SUN/buttons/ToggleButtonModel' );

  /**
   * @param {Object} valueOff - value when the button is in the off state
   * @param {Object} valueOn - value when the button is in the on state
   * @param {Property} property - axon Property that can be either valueOff or valueOn
   * @param {Object} [options]
   * @constructor
   */
  function RectangularToggleButton( valueOff, valueOn, property, options ) {

    options = _.extend( {
      tandem: Tandem.required,
      phetioType: ToggleButtonIO
    }, options );

    // @public (phet-io)
    // Note it shares a tandem with this, so the emitter will be instrumented as a child of the button
    this.toggleButtonModel = new ToggleButtonModel( valueOff, valueOn, property, options );

    RectangularButtonView.call( this, this.toggleButtonModel, new ToggleButtonInteractionStateProperty( this.toggleButtonModel ), options );
  }

  sun.register( 'RectangularToggleButton', RectangularToggleButton );

  return inherit( RectangularButtonView, RectangularToggleButton );
} );<commit_msg>Disposed interactionStateProperty for RectangularToggleButton, see https://github.com/phetsims/sun/issues/121<commit_after>// Copyright 2014-2017, University of Colorado Boulder

/**
 * A rectangular toggle button that switches the value of a property between 2 values.
 *
 * @author John Blanco (PhET Interactive Simulations)
 * @author Sam Reid (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var inherit = require( 'PHET_CORE/inherit' );
  var RectangularButtonView = require( 'SUN/buttons/RectangularButtonView' );
  var sun = require( 'SUN/sun' );
  var Tandem = require( 'TANDEM/Tandem' );
  var ToggleButtonInteractionStateProperty = require( 'SUN/buttons/ToggleButtonInteractionStateProperty' );
  var ToggleButtonIO = require( 'SUN/buttons/ToggleButtonIO' );
  var ToggleButtonModel = require( 'SUN/buttons/ToggleButtonModel' );

  /**
   * @param {Object} valueOff - value when the button is in the off state
   * @param {Object} valueOn - value when the button is in the on state
   * @param {Property} property - axon Property that can be either valueOff or valueOn
   * @param {Object} [options]
   * @constructor
   */
  function RectangularToggleButton( valueOff, valueOn, property, options ) {

    options = _.extend( {
      tandem: Tandem.required,
      phetioType: ToggleButtonIO
    }, options );

    // @public (phet-io)
    // Note it shares a tandem with this, so the emitter will be instrumented as a child of the button
    this.toggleButtonModel = new ToggleButtonModel( valueOff, valueOn, property, options );
    var toggleButtonInteractionStateProperty = new ToggleButtonInteractionStateProperty( this.toggleButtonModel )
    RectangularButtonView.call( this, this.toggleButtonModel, toggleButtonInteractionStateProperty, options );

    // @private
    this.disposeRectangularToggleButton = function() {
      toggleButtonInteractionStateProperty.dispose();
    };
  }

  sun.register( 'RectangularToggleButton', RectangularToggleButton );

  return inherit( RectangularButtonView, RectangularToggleButton, {

    /**
     * @public
     */
    dispose: function() {
      this.disposeRectangularToggleButton();
      RectangularButtonView.prototype.dispose && RectangularButtonView.prototype.dispose.call( this );
    }
  } );
} );<|endoftext|>


<commit_before>//  Sample refactored by David Rousset - Microsoft France - http://blogs.msdn.com/davrous
//  Using Hand.js to support all platforms

//  Based on https://github.com/sebleedelisle/JSTouchController/blob/master/Touches.html

//  Copyright (c)2010-2011, Seb Lee-Delisle, sebleedelisle.com. All rights reserved.

//  Redistribution and use in source and binary forms, with or without modification, are permitted provided
//  that the following conditions are met:

//    * Redistributions of source code must retain the above copyright notice,
//      this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above copyright notice,
//      this list of conditions and the following disclaimer in the documentation
//      and/or other materials provided with the distribution.

//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
//  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
//  AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
//  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
//  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
//  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
//  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// shim layer with setTimeout fallback
window.requestAnimFrame = (function () {
    return window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function (callback) {
        window.setTimeout(callback, 1000 / 30);
    };
})();

var control_canvas,
c,        // c is the fg_canvas' context 2D
halfWidth,
halfHeight,
leftPointerID = -1,
leftPointerPos = new Vector2(0, 0),
leftPointerStartPos = new Vector2(0, 0),
leftVector = new Vector2(0, 0);
arrow = new VectorLED(0, 0, 0, 0);

var touches; // collections of pointers

/////////////////////////////// ARDUINO SETUP
var IOBoard = BO.IOBoard;
var IOBoardEvent = BO.IOBoardEvent;
var Pin = BO.Pin;

//// Variables
// LED related
var led1; //-90
var led2; //0
var led3; //90
var led4; //180=-180
var LEDloopON = false;
var LEDcont = 1;
var max_val;

var frame = 0;
var lastUpdateTime = 0;
var acDelta = 0;
var msPerFrame = 10;

// Set to true to print debug messages to console
BO.enableDebugging = true;

var host = window.location.hostname;
// if the file is opened locally, set the host to "localhost"
if (window.location.protocol.indexOf("file:") === 0) {
        host = "171.65.102.132";
    }
var arduino = new IOBoard(host, 8887);
///////////////////////////// ARDUINO SETUP END

var username = "noname";
var socket;

document.addEventListener("DOMContentLoaded", init);

//window.onorientationchange = resetCanvas;
//window.onresize = resetCanvas;

function init() {
    setupCanvas();
    setupVidCanvas();

    touches = new Collection();

    arduino.addEventListener(IOBoardEvent.READY, onReady);
}

function onReady(event) {
        // Remove the event listener because it is no longer needed
        arduino.removeEventListener(IOBoardEvent.READY, onReady);

        // Set Pin 5,6,9,10 to PWM
        arduino.setDigitalPinMode(5, Pin.PWM);
        arduino.setDigitalPinMode(6, Pin.PWM);
        arduino.setDigitalPinMode(9, Pin.PWM);
        arduino.setDigitalPinMode(10, Pin.PWM);

        // Create an LED object to interface with the LED wired
        // to the I/O board
        led1 = arduino.getDigitalPin(5);
        led2 = arduino.getDigitalPin(6);
        led3 = arduino.getDigitalPin(9);
        led4 = arduino.getDigitalPin(10);

        // jQuery part for the button
    $("#slider").slider({
        step: 0.05,
        min : 0.0,
        max : 1.0
    });

    $('#value').text("Value: 0");

    $( "#slider" ).bind( "slide", function(event, ui) {
        var value = ui.value;
        $('#value').text("Value: " + value.toFixed(2));
        brown_const = value;
        console.log(brown_const);
    });

        $('input[name=setUsername]').click(function(){
                        if($('input[name=usernameTxt]').val() != ""){
                                username = $('input[name=usernameTxt]').val();
                                var msg = {type:'setUsername', user:username};
                                socket.json.send(msg);
                        }
        });

        socket = new io.connect('http://171.65.102.132:3001');

        socket.on('connect', function() {
        	console.log("Connected");
        	getFrame();
        });

        var board = $('#board');

        socket.on('postscore', function(score){
            board.empty();
            for (var i=0;i<score.length;i++){
                if(i==0){
                    board.append(''+ score[i][0]+'  :  '+score[i][1]+'
');
                }else{
                    board.append(score[i][0]+'  :  '+score[i][1]+ '
');
            	}
            }
            board.fadeOut('fast');
            board.fadeIn('fast');
            board.fadeOut('fast');
            board.fadeIn('fast');
        });

        socket.on('disconnect', function() {
            console.log('disconnected');
        });

        $("input[name=recBtn]").click(function(){
        	var cc = new CanvasCapture({
				debug: true,
    			inCanvasEl: document.getElementById('videoCanvas')
			});
        	cc.start();
        	setTimeout(function(){cc.stop();}, 1000);
        });

    control_canvas.addEventListener('pointerdown', onPointerDown, false);
    control_canvas.addEventListener('pointermove', onPointerMove, false);
    control_canvas.addEventListener('pointerup', onPointerUp, false);
    control_canvas.addEventListener('pointerout', onPointerUp, false);

    requestAnimFrame(draw);
}

function draw() {
    c.clearRect(0, 0, control_canvas.width, control_canvas.height);

    c.beginPath();
    c.moveTo(halfWidth, halfHeight-4);
    c.strokeStyle = "rgba(250, 102, 0, 1)";
    c.lineWidth = 2;
    c.lineTo(halfWidth, halfHeight+4);
    c.stroke();

    c.beginPath();
    c.moveTo(halfWidth+4, halfHeight);
    c.strokeStyle = "rgba(250, 102, 0, 1)";
    c.lineWidth = 2;
    c.lineTo(halfWidth-4, halfHeight);
    c.stroke();

    drawCircles(halfWidth, halfHeight);

        //// mouse event loop
    touches.forEach(function (touch) {
        if (touch.identifier == leftPointerID) {
            var alpha = arrow.trimArrow(leftVector, max_val);

            c.beginPath();
            c.fillStyle = "rgba(250, 102, 0, 1)";
            c.arc(leftPointerPos.x, leftPointerPos.y, 16, 0, Math.PI * 2, true);
            c.fill();

            c.beginPath();
            c.moveTo(leftPointerStartPos.x,leftPointerStartPos.y);
            c.strokeStyle = "rgba(250, 102, 0, 1)";
                        c.lineTo(leftPointerStartPos.x+max_val*(arrow.int2-arrow.int4),leftPointerStartPos.y+max_val*(arrow.int1-arrow.int3));
                        c.lineWidth = 3;
                        c.stroke();

                        c.beginPath();
                        c.fillStyle = "rgba(255, 255, 255, "+alpha*(LEDcont)+")";
                    c.arc(halfWidth, halfHeight, 16, 0, Math.PI * 2, true);
                    c.fill();

                        c.beginPath();
                c.fillStyle = "#fff";
                c.fillText(alpha,halfWidth-10, halfHeight-25);

                c.beginPath();
                c.fillStyle = "#dd6600";
                var theta = leftVector.angle();
                c.fillText(theta.toFixed(0),leftPointerPos.x+10, leftPointerPos.y-20);
        }
    });

    requestAnimFrame(draw);

    //// LED control loop
    var delta = Date.now() - lastUpdateTime;
    if (acDelta > msPerFrame)
    {
        acDelta = 0;
        if(LEDloopON)
        {
                //LEDon = frame%2;
                LEDcont = 1;
                changeLED(LEDcont);
        }
        frame++;
        if (frame >= 2) {frame = 0;}
    } else
    {
        acDelta += delta;
    }
    lastUpdateTime = Date.now();
}

function drawCircles(xCenter,yCenter)
{
        var needle = new Vector2(max_val, 0);
        for(var i=0;i<24*3;i++)
        {
                c.beginPath();
                c.fillStyle = "rgba(255, 255, 255, 0.5)";
                c.lineWidth = 3;
                c.arc(xCenter + needle.x, yCenter + needle.y, 1, 0, Math.PI * 2, true);
                c.fill();
                needle.rotate(5,0);
        }
}

function givePointerType(event) {
    switch (event.pointerType) {
        case event.POINTER_TYPE_MOUSE:
            return "MOUSE";
            break;
        case event.POINTER_TYPE_PEN:
            return "PEN";
            break;
        case event.POINTER_TYPE_TOUCH:
            return "TOUCH";
            break;
    }
}

function onPointerDown(e) {
    var newPointer = { identifier: e.pointerId, x: e.clientX, y: e.clientY, type: givePointerType(e) };
    leftPointerID = e.pointerId;
    //leftPointerStartPos.reset(e.clientX, e.clientY);
    leftPointerStartPos.reset(halfWidth, halfHeight);
    leftPointerPos.copyFrom(leftPointerStartPos);
    leftVector.reset(0, 0);
    arrow.reset(0, 0, 0, 0);
    touches.add(e.pointerId, newPointer);
}

function onPointerMove(e) {
    if (leftPointerID == e.pointerId) {
        //leftPointerPos.reset(e.clientX, e.clientY);
        leftPointerPos.reset(e.offsetX, e.offsetY);
        leftVector.copyFrom(leftPointerPos);
        //leftVector.minusEq(leftPointerStartPos);
        leftVector.minusEq(leftPointerStartPos);
        arrow.setArrow(leftVector, max_val);
        LEDloopON = true;
    }
    else {
        if (touches.item(e.pointerId)) {
            touches.item(e.pointerId).x = e.clientX;
            touches.item(e.pointerId).y = e.clientY;
        }
    }
}

function onPointerUp(e) {
    if (leftPointerID == e.pointerId) {
        leftPointerID = -1;
        leftVector.reset(0, 0);
    }
    leftVector.reset(0, 0);
    arrow.reset(0, 0, 0, 0);
    touches.remove(e.pointerId);
    LEDloopON = false;
    changeLED(0);
}

function setupCanvas() {
    control_canvas = document.getElementById('controlCanvas');
    c = control_canvas.getContext('2d');
    //resetCanvas();
    c.strokeStyle = "#ffffff";
    c.lineWidth = 2;
}

// Arduino control functions
function changeLED(LEDon) {
    if(LEDon)
    {
            led1.value = arrow.int1;
            led2.value = arrow.int2;
            led3.value = arrow.int3;
            led4.value = arrow.int4;
    }
    else
    {
            led1.value = 0;
            led2.value = 0;
            led3.value = 0;
            led4.value = 0;
        }
}

/*function resetCanvas(e) {
    max_val = (document.getElementById("controlArea").offsetWidth-100)/2;

    // resize the canvas - but remember - this clears the canvas too.

    control_canvas.width = document.getElementById("controlArea").offsetWidth-20;
    control_canvas.height = control_canvas.width-20;

    halfWidth = (control_canvas.width)/2;
    halfHeight = (control_canvas.height)/2;

    // make sure we scroll to the top left.
    window.scrollTo(0, 0);
}*/

var obj_canvas,
obj_c,
ObjX,
ObjY,
ObjL=80,
cp_canvas = null;

var video_canvas,
vid_c;

var brown_const=0;
var int_timer=0;
var max_timer=40;

var scoreX = 0;
var scoreY = 0;
var score_val = 0;
var gametimer;

var vid_width = 640;
var vid_height = 480;

function setupVidCanvas() {
        video_canvas = document.getElementById('videoCanvas');
        vid_c = video_canvas.getContext('2d');

        video_canvas.width = vid_width;
        video_canvas.height = vid_height;
}

function getFrame(){
    var msg = {type:'reqframe', user:username};
    socket.json.send(msg);

    socket.on('postframe', function(data){
		var img = new Image();
        img.onload = function() {
            vid_c.clearRect(0, 0, vid_width, vid_height);
            vid_c.drawImage(img, 0, 0, vid_width, vid_height);

            // load frame
            requestAnimFrame(getFrame);
        };
        img.src = data;
    });
}

function resetGame(){
        window.clearTimeout(gametimer);

        score_val = 0;
        scoreX = ObjX;
        scoreY = ObjY;

        int_timer = max_timer;

        gametimer=requestAnimFrame(countDown);
}

function countDown(){
        int_timer = int_timer - 0.1;
        if (int_timer > 0){
                score_val = (Math.pow(scoreX-ObjX,2) + Math.pow(scoreY-ObjY,2))*10;
                gametimer=requestAnimFrame(countDown);
        }else{
                window.clearTimeout(gametimer);

                var msg = {type:'sendscore', user:username, score:score_val};
                socket.json.send(msg);

                int_timer=0;
                score_val = 0;
                ObjX = vid_width/2;
                ObjY = vid_height/2;
        }
}<commit_msg>debug livegame.js<commit_after>//  Sample refactored by David Rousset - Microsoft France - http://blogs.msdn.com/davrous
//  Using Hand.js to support all platforms

//  Based on https://github.com/sebleedelisle/JSTouchController/blob/master/Touches.html

//  Copyright (c)2010-2011, Seb Lee-Delisle, sebleedelisle.com. All rights reserved.

//  Redistribution and use in source and binary forms, with or without modification, are permitted provided
//  that the following conditions are met:

//    * Redistributions of source code must retain the above copyright notice,
//      this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above copyright notice,
//      this list of conditions and the following disclaimer in the documentation
//      and/or other materials provided with the distribution.

//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
//  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
//  AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
//  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
//  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
//  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
//  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// shim layer with setTimeout fallback
window.requestAnimFrame = (function () {
    return window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function (callback) {
        window.setTimeout(callback, 1000 / 30);
    };
})();

var control_canvas,
c,        // c is the fg_canvas' context 2D
halfWidth,
halfHeight,
leftPointerID = -1,
leftPointerPos = new Vector2(0, 0),
leftPointerStartPos = new Vector2(0, 0),
leftVector = new Vector2(0, 0);
arrow = new VectorLED(0, 0, 0, 0);

var touches; // collections of pointers

/////////////////////////////// ARDUINO SETUP
var IOBoard = BO.IOBoard;
var IOBoardEvent = BO.IOBoardEvent;
var Pin = BO.Pin;

//// Variables
// LED related
var led1; //-90
var led2; //0
var led3; //90
var led4; //180=-180
var LEDloopON = false;
var LEDcont = 1;
var max_val;

var frame = 0;
var lastUpdateTime = 0;
var acDelta = 0;
var msPerFrame = 10;

// Set to true to print debug messages to console
BO.enableDebugging = true;

var host = window.location.hostname;
// if the file is opened locally, set the host to "localhost"
if (window.location.protocol.indexOf("file:") === 0) {
        host = "171.65.102.132";
    }
var arduino = new IOBoard(host, 8887);
///////////////////////////// ARDUINO SETUP END

var username = "noname";
var socket;

document.addEventListener("DOMContentLoaded", init);

//window.onorientationchange = resetCanvas;
//window.onresize = resetCanvas;

function init() {
    setupCanvas();
    setupVidCanvas();

    touches = new Collection();

    arduino.addEventListener(IOBoardEvent.READY, onReady);
}

function onReady(event) {
        // Remove the event listener because it is no longer needed
        arduino.removeEventListener(IOBoardEvent.READY, onReady);

        // Set Pin 5,6,9,10 to PWM
        arduino.setDigitalPinMode(5, Pin.PWM);
        arduino.setDigitalPinMode(6, Pin.PWM);
        arduino.setDigitalPinMode(9, Pin.PWM);
        arduino.setDigitalPinMode(10, Pin.PWM);

        // Create an LED object to interface with the LED wired
        // to the I/O board
        led1 = arduino.getDigitalPin(5);
        led2 = arduino.getDigitalPin(6);
        led3 = arduino.getDigitalPin(9);
        led4 = arduino.getDigitalPin(10);

        // jQuery part for the button
    $("#slider").slider({
        step: 0.05,
        min : 0.0,
        max : 1.0
    });

    $('#value').text("Value: 0");

    $( "#slider" ).bind( "slide", function(event, ui) {
        var value = ui.value;
        $('#value').text("Value: " + value.toFixed(2));
        brown_const = value;
        console.log(brown_const);
    });

        $('input[name=setUsername]').click(function(){
                        if($('input[name=usernameTxt]').val() != ""){
                                username = $('input[name=usernameTxt]').val();
                                var msg = {type:'setUsername', user:username};
                                socket.json.send(msg);
                        }
        });

        socket = new io.connect('http://171.65.102.132:3001');

        socket.on('connect', function() {
        	console.log("Connected");
        	getFrame();
        });

        var board = $('#board');

        socket.on('postscore', function(score){
            board.empty();
            for (var i=0;i<score.length;i++){
                if(i==0){
                    board.append(''+ score[i][0]+'  :  '+score[i][1]+'
');
                }else{
                    board.append(score[i][0]+'  :  '+score[i][1]+ '
');
            	}
            }
            board.fadeOut('fast');
            board.fadeIn('fast');
            board.fadeOut('fast');
            board.fadeIn('fast');
        });

        socket.on('disconnect', function() {
            console.log('disconnected');
        });

        socket.on('postframe', function(data){
			var img = new Image();
        	img.onload = function() {
            	vid_c.clearRect(0, 0, vid_width, vid_height);
            	vid_c.drawImage(img, 0, 0, vid_width, vid_height);

	            // load frame
    	        //requestAnimFrame(getFrame);
        	};
        	img.src = data;
    	});

        $("input[name=recBtn]").click(function(){
        	var cc = new CanvasCapture({
				debug: true,
    			inCanvasEl: document.getElementById('videoCanvas')
			});
        	cc.start();
        	setTimeout(function(){cc.stop();}, 1000);
        });

    control_canvas.addEventListener('pointerdown', onPointerDown, false);
    control_canvas.addEventListener('pointermove', onPointerMove, false);
    control_canvas.addEventListener('pointerup', onPointerUp, false);
    control_canvas.addEventListener('pointerout', onPointerUp, false);

    requestAnimFrame(draw);
}

function draw() {
    c.clearRect(0, 0, control_canvas.width, control_canvas.height);

    c.beginPath();
    c.moveTo(halfWidth, halfHeight-4);
    c.strokeStyle = "rgba(250, 102, 0, 1)";
    c.lineWidth = 2;
    c.lineTo(halfWidth, halfHeight+4);
    c.stroke();

    c.beginPath();
    c.moveTo(halfWidth+4, halfHeight);
    c.strokeStyle = "rgba(250, 102, 0, 1)";
    c.lineWidth = 2;
    c.lineTo(halfWidth-4, halfHeight);
    c.stroke();

    drawCircles(halfWidth, halfHeight);

        //// mouse event loop
    touches.forEach(function (touch) {
        if (touch.identifier == leftPointerID) {
            var alpha = arrow.trimArrow(leftVector, max_val);

            c.beginPath();
            c.fillStyle = "rgba(250, 102, 0, 1)";
            c.arc(leftPointerPos.x, leftPointerPos.y, 16, 0, Math.PI * 2, true);
            c.fill();

            c.beginPath();
            c.moveTo(leftPointerStartPos.x,leftPointerStartPos.y);
            c.strokeStyle = "rgba(250, 102, 0, 1)";
                        c.lineTo(leftPointerStartPos.x+max_val*(arrow.int2-arrow.int4),leftPointerStartPos.y+max_val*(arrow.int1-arrow.int3));
                        c.lineWidth = 3;
                        c.stroke();

                        c.beginPath();
                        c.fillStyle = "rgba(255, 255, 255, "+alpha*(LEDcont)+")";
                    c.arc(halfWidth, halfHeight, 16, 0, Math.PI * 2, true);
                    c.fill();

                        c.beginPath();
                c.fillStyle = "#fff";
                c.fillText(alpha,halfWidth-10, halfHeight-25);

                c.beginPath();
                c.fillStyle = "#dd6600";
                var theta = leftVector.angle();
                c.fillText(theta.toFixed(0),leftPointerPos.x+10, leftPointerPos.y-20);
        }
    });

    requestAnimFrame(draw);

    //// LED control loop
    var delta = Date.now() - lastUpdateTime;
    if (acDelta > msPerFrame)
    {
        acDelta = 0;
        if(LEDloopON)
        {
                //LEDon = frame%2;
                LEDcont = 1;
                changeLED(LEDcont);
        }
        frame++;
        if (frame >= 2) {frame = 0;}
    } else
    {
        acDelta += delta;
    }
    lastUpdateTime = Date.now();
}

function drawCircles(xCenter,yCenter)
{
        var needle = new Vector2(max_val, 0);
        for(var i=0;i<24*3;i++)
        {
                c.beginPath();
                c.fillStyle = "rgba(255, 255, 255, 0.5)";
                c.lineWidth = 3;
                c.arc(xCenter + needle.x, yCenter + needle.y, 1, 0, Math.PI * 2, true);
                c.fill();
                needle.rotate(5,0);
        }
}

function givePointerType(event) {
    switch (event.pointerType) {
        case event.POINTER_TYPE_MOUSE:
            return "MOUSE";
            break;
        case event.POINTER_TYPE_PEN:
            return "PEN";
            break;
        case event.POINTER_TYPE_TOUCH:
            return "TOUCH";
            break;
    }
}

function onPointerDown(e) {
    var newPointer = { identifier: e.pointerId, x: e.clientX, y: e.clientY, type: givePointerType(e) };
    leftPointerID = e.pointerId;
    //leftPointerStartPos.reset(e.clientX, e.clientY);
    leftPointerStartPos.reset(halfWidth, halfHeight);
    leftPointerPos.copyFrom(leftPointerStartPos);
    leftVector.reset(0, 0);
    arrow.reset(0, 0, 0, 0);
    touches.add(e.pointerId, newPointer);
}

function onPointerMove(e) {
    if (leftPointerID == e.pointerId) {
        //leftPointerPos.reset(e.clientX, e.clientY);
        leftPointerPos.reset(e.offsetX, e.offsetY);
        leftVector.copyFrom(leftPointerPos);
        //leftVector.minusEq(leftPointerStartPos);
        leftVector.minusEq(leftPointerStartPos);
        arrow.setArrow(leftVector, max_val);
        LEDloopON = true;
    }
    else {
        if (touches.item(e.pointerId)) {
            touches.item(e.pointerId).x = e.clientX;
            touches.item(e.pointerId).y = e.clientY;
        }
    }
}

function onPointerUp(e) {
    if (leftPointerID == e.pointerId) {
        leftPointerID = -1;
        leftVector.reset(0, 0);
    }
    leftVector.reset(0, 0);
    arrow.reset(0, 0, 0, 0);
    touches.remove(e.pointerId);
    LEDloopON = false;
    changeLED(0);
}

function setupCanvas() {
    control_canvas = document.getElementById('controlCanvas');
    c = control_canvas.getContext('2d');
    //resetCanvas();
    c.strokeStyle = "#ffffff";
    c.lineWidth = 2;
}

// Arduino control functions
function changeLED(LEDon) {
    if(LEDon)
    {
            led1.value = arrow.int1;
            led2.value = arrow.int2;
            led3.value = arrow.int3;
            led4.value = arrow.int4;
    }
    else
    {
            led1.value = 0;
            led2.value = 0;
            led3.value = 0;
            led4.value = 0;
        }
}

/*function resetCanvas(e) {
    max_val = (document.getElementById("controlArea").offsetWidth-100)/2;

    // resize the canvas - but remember - this clears the canvas too.

    control_canvas.width = document.getElementById("controlArea").offsetWidth-20;
    control_canvas.height = control_canvas.width-20;

    halfWidth = (control_canvas.width)/2;
    halfHeight = (control_canvas.height)/2;

    // make sure we scroll to the top left.
    window.scrollTo(0, 0);
}*/

var obj_canvas,
obj_c,
ObjX,
ObjY,
ObjL=80,
cp_canvas = null;

var video_canvas,
vid_c;

var brown_const=0;
var int_timer=0;
var max_timer=40;

var scoreX = 0;
var scoreY = 0;
var score_val = 0;
var gametimer;

var vid_width = 640;
var vid_height = 480;

function setupVidCanvas() {
        video_canvas = document.getElementById('videoCanvas');
        vid_c = video_canvas.getContext('2d');

        video_canvas.width = vid_width;
        video_canvas.height = vid_height;
}

/*function getFrame(){
    var msg = {type:'reqframe', user:username};
    socket.json.send(msg);

    socket.on('postframe', function(data){
		var img = new Image();
        img.onload = function() {
            vid_c.clearRect(0, 0, vid_width, vid_height);
            vid_c.drawImage(img, 0, 0, vid_width, vid_height);

            // load frame
            //requestAnimFrame(getFrame);
        };
        img.src = data;
    });
}*/

function resetGame(){
        window.clearTimeout(gametimer);

        score_val = 0;
        scoreX = ObjX;
        scoreY = ObjY;

        int_timer = max_timer;

        gametimer=requestAnimFrame(countDown);
}

function countDown(){
        int_timer = int_timer - 0.1;
        if (int_timer > 0){
                score_val = (Math.pow(scoreX-ObjX,2) + Math.pow(scoreY-ObjY,2))*10;
                gametimer=requestAnimFrame(countDown);
        }else{
                window.clearTimeout(gametimer);

                var msg = {type:'sendscore', user:username, score:score_val};
                socket.json.send(msg);

                int_timer=0;
                score_val = 0;
                ObjX = vid_width/2;
                ObjY = vid_height/2;
        }
}<|endoftext|>


<commit_before>const mqtt = require('mqtt');
const SerialPort = require('serialport');
const client = mqtt.connect('mqtt://localhost:1883'); // TODO config
var port = new SerialPort('/dev/ttyAMA0', {
  baudRate: 2400
});

var buffer = [];
var count = 0;
var bufferComplete = false;

port.on('open', function() {
    console.log('open serialport.');
});

// open errors will be emitted as an error event
port.on('error', function(err) {
    console.log('Error: ', err.message);
});

port.on('data', function (data) {
  console.log(data);
  for (var i = 0; i < data.length; i++) {
    var byte = data.readUInt8(i);
    buffer[count] = byte;

    if (buffer[count] == 0xAA) {
      count = 0;
    } else if (buffer[count] == 0xFF) {
      bufferComplete = true;
    }

    count++;
    if (count >= 7) {
      count = 0;
    }
  }

  if (bufferComplete === true) {
    bufferComplete = false;
    port.pause(); // pause
    if (((buffer[1] + buffer[2]+buffer[3] + buffer[4]) & 0xFF) != buffer[5]) {
      console.log('check bit error!');
      return;
    }
    var v_out = 0;
    v_out = ((buffer[1]*256)+buffer[2])*5/1024;
    var ppm = v_out*1000*0.5;
    console.log("ppm = " + ppm + "ug/m3");

    var air = {
        sensorId: 1,
        pm25: ppm,
        probe: 'sensor pm25',
        updated: new Date(),
        location: [
            120.19,30.26
        ]
    };
    console.log(air);
    client.publish('/stats/air', JSON.stringify(air));
  }
});

client.on('connect', function() {
    console.log('Client connected IoT!');
});

client.on('message', function (topic, message) {
  // message is Buffer
  console.log(topic+'  ' + message.toString());
});

// speed control
setInterval(function() {
  port.resume();
}, 1000);

<commit_msg>pm25 calculation optimze<commit_after>const mqtt = require('mqtt');
const SerialPort = require('serialport');
const client = mqtt.connect('mqtt://localhost:1883'); // TODO config
var port = new SerialPort('/dev/ttyAMA0', {
  baudRate: 2400
});

var buffer = [];
var airs = [];
var miss = 0;

port.on('open', function() {
    console.log('open serialport.');
});

// open errors will be emitted as an error event
port.on('error', function(err) {
    console.log('Error: ', err.message);
});

port.on('data', function (data) {
  console.log(data);
  for (var i = 0; i < data.length; i++) {
    var byte = data.readUInt8(i);
    buffer.append(byte);
  }

  // make sure the first byte is 0xAA
  while (buffer[0] !== 0xAA && buffer[0] !== undefined) {
    buffer.shift();
  }

  while (buffer.length >= 7) {
    if (buffer[6] === 0xFF) {
      var crc = (buffer[1] + buffer[2] + buffer[3] + buffer[4]) % 256;
      if (crc === buffer[5]) {
        var v_out = ((buffer[1]*256)+buffer[2])*5/1024;
        var ppm = v_out * 1000 * 0.5;
        airs.append(ppm);
      }
      // remove the first 7 bytes
      buffer = buffer.slice(7, buffer.length);
    } else {
      // remove the first 0xAA, loop it when next data received.
      while (buffer[0] !== 0xAA && buffer[0] !== undefined) {
        buffer.shift();
      }
    }
  }

});

client.on('connect', function() {
    console.log('Client connected IoT!');
});

client.on('message', function (topic, message) {
  // message is Buffer
  console.log(topic+'  ' + message.toString());
});

// speed control
setInterval(function() {
  if (airs.length === 0) {
    console.log('error....');
    miss++;
    if (miss >= 3) {
      console.log('there is something wrong with the pm25 sensor: ' + miss + 's');
    }
    return;
  }
  miss = 0;
  var sum = 0;
  for (var i = 0; i < airs.length; i++) {
    sum += airs[i];
  }

  var air = {
    sensorId: id,
    pm25: sum / airs.length,
    probe: 'sensor pm25',
    updated: new Date(),
    location: [
      114.434945, 38.583943
    ]
  };

  console.log(air);
  client.publish('/stats/air', JSON.stringify(air));
  airs = [];
}, 1000);
<|endoftext|>


<commit_before>var bwa = require('../')
var fs = require('fs')
var crypto = require('crypto')
var request = require('request')
var tool = require('tool-stream')
var through = require('through2')
var async = require('async')
var test = require('tape')

test("Align reads to reference with BWA", function (t) {
  t.plan(2)
  var referencePath = 'test/reference.fasta.gz'
  var readsPath = 'test/reads.fastq.gz'
  var alignmentPath = 'test/alignment.sam'
  var referenceURL = 'http://ftp.ncbi.nlm.nih.gov/genbank/genomes/Eukaryotes/protozoa/Guillardia_theta/Guith1/Primary_Assembly/unplaced_scaffolds/FASTA/unplaced.scaf.fa.gz'
  var readsURL = 'http://ftp.sra.ebi.ac.uk//vol1/fastq/SRR070/SRR070675/SRR070675.fastq.gz'

  var downloads = [
    download(referenceURL, referencePath),
    download(readsURL, readsPath)
  ]
  async.series(downloads, alignReadsToRef)

  function alignReadsToRef() {
    var msg = "should take paths for reference, reads and aligment. Reference should be indexed first."
    var mem = bwa() // default to mem
    mem([referencePath, readsPath, alignmentPath])
    .on('data', function(data) { checksum(data, '3dae171586e8f5fda2737795ff2e39df711701cb', msg, t) })

    var msg = "should align using a Stream that takes arrays of paths for reference and reads."
    var mem = bwa('mem -x pacbio')
    var memStream = mem() // we will pass arguments with write
    memStream.write([referencePath, readsPath])
    memStream.end()
    memStream.on('data', function(data) { checksum(data, 'a2ac465ac0d9e0879a9f9a43108e36b682f2e018', msg, t) })
  }
})

function download(url, path) {
  return function task(callback) {
    var read = request(url)
    var write = fs.createWriteStream(path)
    read.pipe(write)
    write
    .on('finish', callback)
    .on('error', function (error) {
      console.warn(error)
    })
  }
}

function checksum(data, hash, msg, t) {
  if (['index', 'aln'].indexOf(data.operation) === -1 && data.status === 'finished') {
    t.ok(fs.statSync(data.sam).size > 5500000, "check that it aligned something")
    // var alignmentFile = fs.createReadStream(data.sam)
    // var shasum = crypto.createHash('sha1')
    // alignmentFile.on('data', function(d) { shasum.update(d) })
    // alignmentFile.on('end', function() {
    //   var sha1 = shasum.digest('hex');
    //   t.equal(sha1, hash, msg)
    // })
  }
}
<commit_msg>Fix test random error (2nd try)<commit_after>var bwa = require('../')
var fs = require('fs')
var crypto = require('crypto')
var request = require('request')
var tool = require('tool-stream')
var through = require('through2')
var async = require('async')
var test = require('tape')

test("Align reads to reference with BWA", function (t) {
  t.plan(2)
  var referencePath = 'test/reference.fasta.gz'
  var readsPath = 'test/reads.fastq.gz'
  var alignmentPath = 'test/alignment.sam'
  var referenceURL = 'http://ftp.ncbi.nlm.nih.gov/genbank/genomes/Eukaryotes/protozoa/Guillardia_theta/Guith1/Primary_Assembly/unplaced_scaffolds/FASTA/unplaced.scaf.fa.gz'
  var readsURL = 'http://ftp.sra.ebi.ac.uk//vol1/fastq/SRR070/SRR070675/SRR070675.fastq.gz'

  var asyncFuncs = [
    download(referenceURL, referencePath),
    download(readsURL, readsPath),
    alignReadsToRef1,
    alignReadsToRef2
  ]
  async.series(asyncFuncs)

  function alignReadsToRef1(cb) {
    var msg = "should take paths for reference, reads and aligment. Reference should be indexed first."
    var mem = bwa() // default to mem
    mem([referencePath, readsPath, alignmentPath])
    .on('data', function(data) {
      checksum(data, '3dae171586e8f5fda2737795ff2e39df711701cb', msg, t)
      cb()
    })
  }
  function alignReadsToRef2(cb) {
    var msg = "should align using a Stream that takes arrays of paths for reference and reads."
    var mem = bwa('mem -x pacbio')
    var memStream = mem() // we will pass arguments with write
    memStream.write([referencePath, readsPath])
    memStream.end()
    memStream.on('data', function(data) {
      checksum(data, 'a2ac465ac0d9e0879a9f9a43108e36b682f2e018', msg, t)
      cb()
    })
  }
})

function download(url, path) {
  return function task(callback) {
    var read = request(url)
    var write = fs.createWriteStream(path)
    read.pipe(write)
    write
    .on('finish', callback)
    .on('error', function (error) {
      console.warn(error)
    })
  }
}

function checksum(data, hash, msg, t) {
  if (['index', 'aln'].indexOf(data.operation) === -1 && data.status === 'finished') {
    t.ok(fs.statSync(data.sam).size > 5500000, "check that it aligned something")
    // var alignmentFile = fs.createReadStream(data.sam)
    // var shasum = crypto.createHash('sha1')
    // alignmentFile.on('data', function(d) { shasum.update(d) })
    // alignmentFile.on('end', function() {
    //   var sha1 = shasum.digest('hex');
    //   t.equal(sha1, hash, msg)
    // })
  }
}
<|endoftext|>


<commit_before>var extension_url = chrome.extension.getURL("markdown-editor/index.html");

chrome.tabs.onCreated.addListener(function(newTab) {
  console.log(newTab)
  if (newTab.url === "chrome://newtab/"  // chrome
      || newTab.url === "about:newtab") { // firefox
    chrome.tabs.update(newTab.id, {url: extension_url});
  }
});

chrome.browserAction.onClicked.addListener(function() {
  console.log("browserAction")
  chrome.tabs.create({url: extension_url});
});
<commit_msg>remove new tab listener<commit_after>var extension_url = chrome.extension.getURL("markdown-editor/index.html");

// chrome.tabs.onCreated.addListener(function(newTab) {
//   console.log(newTab)
//   if (newTab.url === "chrome://newtab/"  // chrome
//       || newTab.url === "about:newtab") { // firefox
//     chrome.tabs.update(newTab.id, {url: extension_url});
//   }
// });

chrome.browserAction.onClicked.addListener(function() {
  chrome.tabs.create({url: extension_url});
});
<|endoftext|>


<commit_before>/**
 * Grunt configuration file for simulations.
 * Requires a package.json file containing project settings.
 *
 * @author Chris Malley (PixelZoom, Inc.)
 */
module.exports = function( grunt ) {

  // Project configuration.
  grunt.initConfig(
      {
        // Read in the project settings from the package.json file into the pkg property.
        // This allows us to refer to project settings from within this config file.
        pkg: grunt.file.readJSON('package.json'),

        // configure the RequireJS plugin
        requirejs: {

          // builds the minified script
          build: {
            options: {
              almond: true,
              mainConfigFile: "js/<%= pkg.name %>-config.js",
              out: "build/<%= pkg.name %>.min.js",
              name: "<%= pkg.name %>-config",
              optimize: 'uglify2',
              wrap: true
            },
            uglify2: {
              compress: {
                global_defs: {
                  // scenery assertions
                  sceneryAssert: false,
                  sceneryAssertExtra: false,
                  // scenery logging
                  sceneryLayerLog: false,
                  sceneryEventLog: false,
                  sceneryAccessibilityLog: false
                },
                dead_code: true
              }
            }
          }
        },

        // configure the JSHint plugin
        jshint: {
          // source files that are specific to this simulation
          simFiles: [ 'js/**/*.js' ],
          // source files for common-code dependencies
          commonFiles: [
            '../assert/js/**/*.js',
            '../dot/js/**/*.js',
            '../joist/js/**/*.js',
            '../kite/js/**/*.js',
            '../phet-core/js/**/*.js',
            '../phetcommon/js/**/*.js',
            '../scenery/js/**/*.js',
            '../scenery-phet/js/**/*.js',
            '../sun/js/**/*.js'
          ],
          // reference external JSHint options in jshint-options.js
          options: require( './jshint-options' )
        }
      } );

  // Default task ('grunt')
  grunt.registerTask( 'default', [ 'lint-sim', 'lint-common', 'build' ] );

  // Other tasks ('grunt taskName')
  grunt.registerTask( 'lint-sim', [ 'jshint:simFiles' ] );
  grunt.registerTask( 'lint-common', [ 'jshint:commonFiles' ] );
  grunt.registerTask( 'build', [ 'requirejs:build' ] );

  // Load tasks from grunt plugins that have been installed locally using npm.
  // Put these in package.json and run 'npm install' before running grunt.
  grunt.loadNpmTasks( 'grunt-requirejs' );
  grunt.loadNpmTasks( 'grunt-contrib-jshint' );
};
<commit_msg>Moving uglify2 options into the requirejs options (was silently being ignored). Now assertions and debugging logs are stripped from the files for decreased size and increased performance<commit_after>/**
 * Grunt configuration file for simulations.
 * Requires a package.json file containing project settings.
 *
 * @author Chris Malley (PixelZoom, Inc.)
 */
module.exports = function( grunt ) {

  // Project configuration.
  grunt.initConfig(
      {
        // Read in the project settings from the package.json file into the pkg property.
        // This allows us to refer to project settings from within this config file.
        pkg: grunt.file.readJSON('package.json'),

        // configure the RequireJS plugin
        requirejs: {

          // builds the minified script
          build: {
            options: {
              almond: true,
              mainConfigFile: "js/<%= pkg.name %>-config.js",
              out: "build/<%= pkg.name %>.min.js",
              name: "<%= pkg.name %>-config",
              optimize: 'uglify2',
              wrap: true,
              uglify2: {
                compress: {
                  global_defs: {
                    // scenery assertions
                    sceneryAssert: false,
                    sceneryAssertExtra: false,
                    // scenery logging
                    sceneryLayerLog: false,
                    sceneryEventLog: false,
                    sceneryAccessibilityLog: false
                  },
                  dead_code: true
                }
              }
            }
          }
        },

        // configure the JSHint plugin
        jshint: {
          // source files that are specific to this simulation
          simFiles: [ 'js/**/*.js' ],
          // source files for common-code dependencies
          commonFiles: [
            '../assert/js/**/*.js',
            '../dot/js/**/*.js',
            '../joist/js/**/*.js',
            '../kite/js/**/*.js',
            '../phet-core/js/**/*.js',
            '../phetcommon/js/**/*.js',
            '../scenery/js/**/*.js',
            '../scenery-phet/js/**/*.js',
            '../sun/js/**/*.js'
          ],
          // reference external JSHint options in jshint-options.js
          options: require( './jshint-options' )
        }
      } );

  // Default task ('grunt')
  grunt.registerTask( 'default', [ 'lint-sim', 'lint-common', 'build' ] );

  // Other tasks ('grunt taskName')
  grunt.registerTask( 'lint-sim', [ 'jshint:simFiles' ] );
  grunt.registerTask( 'lint-common', [ 'jshint:commonFiles' ] );
  grunt.registerTask( 'build', [ 'requirejs:build' ] );

  // Load tasks from grunt plugins that have been installed locally using npm.
  // Put these in package.json and run 'npm install' before running grunt.
  grunt.loadNpmTasks( 'grunt-requirejs' );
  grunt.loadNpmTasks( 'grunt-contrib-jshint' );
};
<|endoftext|>


<commit_before>$(document).ready(
	function() {
		var day_editor = ace.edit('day-editor');
		day_editor.setTheme('ace/theme/twilight');
		day_editor.setShowInvisibles(true);
		day_editor.setShowPrintMargin(false);

		var saved_flag_container = $('.saved-flag');
		var saved_flag_icon = $('span', saved_flag_container);
		var is_saved = true;
		var SetSavedFlag = function(saved) {
			is_saved = saved;

			if (saved) {
				saved_flag_container
					.addClass('label-success')
					.removeClass('label-danger');
				saved_flag_icon
					.addClass('glyphicon-floppy-saved')
					.removeClass('glyphicon-floppy-remove');

				var last_symbol = document.title.slice(-1);
				if (last_symbol.length && last_symbol == '*') {
					document.title = document.title.slice(0, -1);
				}
			} else {
				saved_flag_container
					.addClass('label-danger')
					.removeClass('label-success');
				saved_flag_icon
					.addClass('glyphicon-floppy-remove')
					.removeClass('glyphicon-floppy-saved');

				var last_symbol = document.title.slice(-1);
				if (last_symbol.length && last_symbol != '*') {
					document.title += '*';
				}
			}
		};

		var number_of_points_view = $('.number-of-points-view');
		var SetNumberOfPoints = function() {
			var points_description = day_editor.getValue();
			var points =
				points_description
				.split('\n')
				.filter(
					function(line) {
						return line.trim().length != 0;
					}
				);

			var number_of_points = points.length;
			number_of_points_view.text(
				number_of_points.toString()
				+ ' '
				+ GetPointUnit(number_of_points)
			);
		};
		day_editor.on(
			'change',
			function() {
				SetSavedFlag(false);
				SetNumberOfPoints();
			}
		);

		var save_button = $('.save-day-button');
		var save_url = save_button.data('save-url');
		var processing_animation_image = $('img', save_button);
		var save_icon = $('span', save_button);
		var day_editor_container = $(day_editor.container);
		var FinishAnimation = function() {
			save_button.prop('disabled', false);
			processing_animation_image.hide();
			save_icon.show();
			day_editor_container.removeClass('wait');
		};
		var SaveViaAjax = function(callback) {
			save_button.prop('disabled', true);
			processing_animation_image.show();
			save_icon.hide();
			day_editor_container.addClass('wait');

			var data = $.extend(
				{'points_description': day_editor.getValue()},
				CSRF_TOKEN
			);
			$.post(
				save_url,
				data,
				function() {
					SetSavedFlag(true);
					FinishAnimation();

					if (typeof callback !== 'undefined') {
						callback();
					}
				}
			).fail(
				function(xhr, text_status) {
					FinishAnimation();
					AjaxErrorDialog.handler(xhr, text_status);
				}
			);
		};
		save_button.click(
			function() {
				SaveViaAjax();
			}
		);
		$(window).keydown(
			function(event) {
				if (
					(event.ctrlKey || event.metaKey)
					&& String.fromCharCode(event.which).toLowerCase() == 's'
				) {
					event.preventDefault();
					SaveViaAjax();
				}
			}
		);

		var close_button = $('.close-button');
		var day_date = close_button.data('date');
		var day_my_date = close_button.data('my-date');
		var view_url = close_button.data('view-url');
		var CloseDayEditor = function() {
			location.href = view_url;
		};
		close_button.click(
			function() {
				if (!is_saved) {
					CloseDialog.show(
						day_my_date,
						day_date,
						function() {
							CloseDialog.hide();
							SaveViaAjax(CloseDayEditor);
						},
						CloseDayEditor
					);
				} else {
					CloseDayEditor();
				}
			}
		);

		var form = $('.day-form');
		form.submit(
			function() {
				event.preventDefault();
				event.stopPropagation();
				return false;
			}
		);
	}
);
<commit_msg>Issue #115: add filtering.<commit_after>$(document).ready(
	function() {
		var day_editor = ace.edit('day-editor');
		day_editor.setTheme('ace/theme/twilight');
		day_editor.setShowInvisibles(true);
		day_editor.setShowPrintMargin(false);

		var FormatPoints = function(points, cursor_position) {
			points = points.map(
				function(point, index) {
					if (
						typeof cursor_position == 'undefined'
						|| cursor_position.row != index
					) {
						return point.replace(/\s+$/, '');
					} else {
						return point;
					}
				}
			);

			while (
				points.length
				&& points[0].trim().length == 0
				&& (typeof cursor_position == 'undefined'
				|| cursor_position.row > 0)
			) {
				points.shift();
				if (typeof cursor_position != 'undefined') {
					cursor_position.row--;
				}
			}
			while (
				points.length
				&& points.slice(-1)[0].trim().length == 0
				&& (typeof cursor_position == 'undefined'
				|| cursor_position.row + 1 < points.length)
			) {
				points.pop();
			}
			if (points.length && points.slice(-1)[0].length != 0) {
				points.push('');
			}

			if (typeof cursor_position != 'undefined') {
				return {
					points: points,
					cursor_position: cursor_position
				};
			} else {
				return points;
			}
		};
		var FormatPointsDescription = function(
			points_description,
			cursor_position
		) {
			var points = points_description.split('\n');
			var result = FormatPoints(points, cursor_position);
			points_description = result.points.join('\n');

			return {
				points_description: points_description,
				cursor_position: result.cursor_position
			};
		};
		day_editor.formatContent = function() {
			var points_description = this.getValue();
			var cursor_position = this.getCursorPosition();
			var result = FormatPointsDescription(
				points_description,
				cursor_position
			);

			this.setValue(result.points_description, -1);
			if (typeof result.cursor_position != 'undefined') {
				this.moveCursorToPosition(result.cursor_position);
			}
		};

		var saved_flag_container = $('.saved-flag');
		var saved_flag_icon = $('span', saved_flag_container);
		var is_saved = true;
		var SetSavedFlag = function(saved) {
			is_saved = saved;

			if (saved) {
				saved_flag_container
					.addClass('label-success')
					.removeClass('label-danger');
				saved_flag_icon
					.addClass('glyphicon-floppy-saved')
					.removeClass('glyphicon-floppy-remove');

				var last_symbol = document.title.slice(-1);
				if (last_symbol.length && last_symbol == '*') {
					document.title = document.title.slice(0, -1);
				}
			} else {
				saved_flag_container
					.addClass('label-danger')
					.removeClass('label-success');
				saved_flag_icon
					.addClass('glyphicon-floppy-remove')
					.removeClass('glyphicon-floppy-saved');

				var last_symbol = document.title.slice(-1);
				if (last_symbol.length && last_symbol != '*') {
					document.title += '*';
				}
			}
		};

		var number_of_points_view = $('.number-of-points-view');
		var SetNumberOfPoints = function() {
			var points_description = day_editor.getValue();
			var points =
				points_description
				.split('\n')
				.filter(
					function(line) {
						return line.trim().length != 0;
					}
				);

			var number_of_points = points.length;
			number_of_points_view.text(
				number_of_points.toString()
				+ ' '
				+ GetPointUnit(number_of_points)
			);
		};
		day_editor.on(
			'change',
			function() {
				SetSavedFlag(false);
				SetNumberOfPoints();
			}
		);

		var save_button = $('.save-day-button');
		var save_url = save_button.data('save-url');
		var processing_animation_image = $('img', save_button);
		var save_icon = $('span', save_button);
		var day_editor_container = $(day_editor.container);
		var FinishAnimation = function() {
			save_button.prop('disabled', false);
			processing_animation_image.hide();
			save_icon.show();
			day_editor_container.removeClass('wait');
		};
		var SaveViaAjax = function(callback) {
			save_button.prop('disabled', true);
			processing_animation_image.show();
			save_icon.hide();
			day_editor_container.addClass('wait');

			day_editor.formatContent();
			var data = $.extend(
				{'points_description': day_editor.getValue()},
				CSRF_TOKEN
			);
			$.post(
				save_url,
				data,
				function() {
					SetSavedFlag(true);
					FinishAnimation();

					if (typeof callback !== 'undefined') {
						callback();
					}
				}
			).fail(
				function(xhr, text_status) {
					FinishAnimation();
					AjaxErrorDialog.handler(xhr, text_status);
				}
			);
		};
		save_button.click(
			function() {
				SaveViaAjax();
			}
		);
		$(window).keydown(
			function(event) {
				if (
					(event.ctrlKey || event.metaKey)
					&& String.fromCharCode(event.which).toLowerCase() == 's'
				) {
					event.preventDefault();
					SaveViaAjax();
				}
			}
		);

		var close_button = $('.close-button');
		var day_date = close_button.data('date');
		var day_my_date = close_button.data('my-date');
		var view_url = close_button.data('view-url');
		var CloseDayEditor = function() {
			location.href = view_url;
		};
		close_button.click(
			function() {
				if (!is_saved) {
					CloseDialog.show(
						day_my_date,
						day_date,
						function() {
							CloseDialog.hide();
							SaveViaAjax(CloseDayEditor);
						},
						CloseDayEditor
					);
				} else {
					CloseDayEditor();
				}
			}
		);

		var form = $('.day-form');
		form.submit(
			function() {
				event.preventDefault();
				event.stopPropagation();
				return false;
			}
		);
	}
);
<|endoftext|>


<commit_before>   'use strict';
 var React = require('react');
 var _ = require('../underscore_ext');

 import '../../css/transcript_css/densityPlot.css';
 var sc = require('science');
 var {deepPureRenderMixin} = require('../react-utils');

const bin = 20; //number of bins
const plotHeight = 35;
const plotWidth = 200;
const zoomFactor = 3;
const topColor = "#BAA0CF";//"#008080";
const bottomColor = "#79C6C5";//"steelblue";

function calculateHeight(exp, max, min, plotHt, plotWidth, unit) {
   let minValue = unit === "tpm" ? Math.log2(0.001) : min;
   let pxWidth = (max - minValue) / plotWidth;
   let newExp = exp.filter(e => e > minValue);
   let percentNonZero = newExp.length / exp.length;
   let kdePoints = newExp.length ? sc.stats.kde().sample(newExp)(_.range(minValue, max + pxWidth, pxWidth)) : [];
   let yHeights = kdePoints.map(kdep => kdep[1] * percentNonZero);
  //  let binWidth = plotWidth / yHeights.length;
   let zPxWidth = 5; // draw zero at 5 px width
   let zeroWidth = pxWidth * zPxWidth;
   let zeroHeight = (1 - percentNonZero) / zeroWidth;
  //    let vscale = Math.max(zeroHeight, ...yHeights);
  //    //polyline points here
  //    let polylinePoints = [`0,${plotHt}`, ...yHeights.map((y, i) => `${i * binWidth},${(1 - y / vscale) * plotHt}`), `${plotWidth},${plotHt}`].join(' ');
  //
  // //   For debugging the scaling. The 'sum' should be 1: area under the curve
  // //   of a density plot should always be 1. We take the values from kde and scale
  // //   them by percentNonZero, then compute zeroHeight to perserve the correct area.
  // //
  // //   We then scale the y axis by the max y value, to ensure that the data is
  // //   not clipped (for a sharp spike), or drawn too small to see (for a uniform
  // //   distribution).
  // //
  // //   pxSum and zPxSum compute the pixel area for zero and non-zero points. They
  // //   should have the same ratio as zeroSum and nonZeroSum if we've scaled correctly.
  // //
  // //   var zeroSum = zeroWidth * zeroHeight;
  // //   var nonZeroSum = _.sum(kdePoints.map(([, y]) => y * pxWidth)) * percentNonZero;
  // //   var pxSum = _.sum(yHeights.map(y => y * plotHt * binWidth));
  // //   var zPxSum = zPxWidth * zeroHeight * plotHt;
  // //   console.log('sum', nonZeroSum + zeroSum, JSON.stringify({nonZeroSum, zeroSum}));
  // //   console.log(JSON.stringify({nz: pxSum / (pxSum + zPxSum), z: zPxSum / (pxSum + zPxSum)}));
  //    return {
  //      polylinePoints: polylinePoints,
  //      zeroWidth: zPxWidth,
  //      zeroHeight: zeroHeight / vscale * plotHt
  //    };
  return {
    yHeights: yHeights,
    zeroWidth: zPxWidth,
    zeroHeight: zeroHeight
  };
 }

 function calculateFrequency(exp, max, min) {
     const stepSize = (max - min) / bin;
     let freq = _.times(bin, _.constant(0));

     exp.forEach(value => {
       freq[Math.floor((value - min) / stepSize)]++;
     });
     freq.forEach(( value, index) => {
       value = value; //did this to remove error while committing "value is never used"
       freq[index] = freq[index] / exp.length;
     });
    return freq;
  }

var DensityPlot = React.createClass ({
 mixins: [deepPureRenderMixin],
 	render () {
    let totalWidth = plotWidth + 20;
 		let data = this.props.data ? this.props.data : null;
    let max = Math.max.apply(Math, _.flatten(_.pluck(data.studyA, "expA").concat(_.pluck(data.studyB, "expB"))));
    let min = Math.min.apply(Math, _.flatten(_.pluck(data.studyA, "expA").concat(_.pluck(data.studyB, "expB"))));
 		let rows = _.mmap(data.studyA, data.studyB, data.nameAndZoom, (studyA, studyB, nameAndZoom) => {
      let rowClass = nameAndZoom.zoom ? "densityPlot--row--zoom" : "densityPlot--row";
      if(this.props.type === 'density')
      {
        let polylinePoints, vscale, binWidth;
        let plotHt = nameAndZoom.zoom ? plotHeight * zoomFactor : plotHeight;
        let {yHeights: yHeightsA, zeroWidth: zeroWidthA, zeroHeight: zeroHeightA} = calculateHeight(studyA.expA, max, min, plotHt, plotWidth, this.props.unit);
        let {yHeights: yHeightsB, zeroWidth: zeroWidthB, zeroHeight: zeroHeightB} = calculateHeight(studyB.expB, max, min, plotHt, plotWidth, this.props.unit);
        vscale = Math.max(zeroHeightA, zeroHeightB, ...yHeightsA, ...yHeightsB);
        return (
          <div className={rowClass} style={{width: `${totalWidth}px`}}onClick={() => this.props.getNameZoom(nameAndZoom.name)}>
            <div className="densityPlot--row--xAxis" style={{width: `${plotWidth * 100 / totalWidth}%`, left: "20px"}}/>

                 {
                   //rectangle starts at 0,plotHt and polyline starts at 20,plotHt
                  //  {yHeights, zeroWidth, zeroHeight} = calculateHeight(studyA.expA, max, min, plotHt, plotWidth, this.props.unit),
                   binWidth = plotWidth / yHeightsA.length,
                   polylinePoints = [`20,${plotHt}`, ...yHeightsA.map((y, i) => `${i * binWidth + 20},${(1 - y / vscale) * plotHt}`), `${plotWidth + 20},${plotHt}`].join(' '),
                   zeroHeightA = zeroHeightA / vscale * plotHt,
                   <svg width={totalWidth} height={plotHt}>
                     <rect x="0" y={plotHt - zeroHeightA} width={zeroWidthA} height={zeroHeightA} fill={topColor}/>
                     <polyline points={polylinePoints} fill={topColor}/>
                   </svg>
                 }

                 {
                  //  {yHeights, zeroWidth, zeroHeight} = calculateHeight(studyB.expB, max, min, plotHt, plotWidth, this.props.unit),
                  binWidth = plotWidth / yHeightsB.length,
                  polylinePoints = [`20,${plotHt}`, ...yHeightsB.map((y, i) => `${i * binWidth + 20},${(1 - y / vscale) * plotHt}`), `${plotWidth + 20},${plotHt}`].join(' '),
                  zeroHeightB = zeroHeightB / vscale * plotHt,
                   <svg width={totalWidth} height={plotHt}>
                     <rect x="0" y={plotHt - zeroHeightB} width={zeroWidthB} height={zeroHeightB} fill={bottomColor} margin="5"/>
                     <polyline points={polylinePoints} fill={bottomColor}/>
                   </svg>
                 }

        );
      }
      else if(this.props.type === 'histogram')
      {
        let frequency;
   			return (

              {
                  frequency = calculateFrequency(studyA.expA, max, min),
                  frequency.map( f => {
                    return (

                    );
                  })
                }

                {
                  frequency = calculateFrequency(studyB.expB, max, min),
                  frequency.map( f => {
                    return (

                    );
                  })
              }

);
      }
 		});
 		return (

 				{rows}

 			);
 	}
 });

 module.exports = {DensityPlot, bottomColor, topColor, plotWidth};
<commit_msg>More cleanup in transcript_views<commit_after>'use strict';

var React = require('react');
var _ = require('../underscore_ext');
import '../../css/transcript_css/densityPlot.css';
var sc = require('science');
var {deepPureRenderMixin} = require('../react-utils');

const bin = 20; //number of bins
const plotHeight = 35;
const plotWidth = 200;
const zoomFactor = 3;
const topColor = "#BAA0CF";
const bottomColor = "#79C6C5";

function calculateHeight(exp, max, min, plotHt, plotWidth, unit) {
	let minValue = unit === "tpm" ? Math.log2(0.001) : min;
	let pxWidth = (max - minValue) / plotWidth;
	let newExp = exp.filter(e => e > minValue);
	let percentNonZero = newExp.length / exp.length;
	let kdePoints = newExp.length ? sc.stats.kde().sample(newExp)(_.range(minValue, max + pxWidth, pxWidth)) : [];
	let yHeights = kdePoints.map(kdep => kdep[1] * percentNonZero);
	//  let binWidth = plotWidth / yHeights.length;
	let zPxWidth = 5; // draw zero at 5 px width
	let zeroWidth = pxWidth * zPxWidth;
	let zeroHeight = (1 - percentNonZero) / zeroWidth;
  //    let vscale = Math.max(zeroHeight, ...yHeights);
  //    //polyline points here
  //    let polylinePoints = [`0,${plotHt}`, ...yHeights.map((y, i) => `${i * binWidth},${(1 - y / vscale) * plotHt}`), `${plotWidth},${plotHt}`].join(' ');
  //
  // //   For debugging the scaling. The 'sum' should be 1: area under the curve
  // //   of a density plot should always be 1. We take the values from kde and scale
  // //   them by percentNonZero, then compute zeroHeight to perserve the correct area.
  // //
  // //   We then scale the y axis by the max y value, to ensure that the data is
  // //   not clipped (for a sharp spike), or drawn too small to see (for a uniform
  // //   distribution).
  // //
  // //   pxSum and zPxSum compute the pixel area for zero and non-zero points. They
  // //   should have the same ratio as zeroSum and nonZeroSum if we've scaled correctly.
  // //
  // //   var zeroSum = zeroWidth * zeroHeight;
  // //   var nonZeroSum = _.sum(kdePoints.map(([, y]) => y * pxWidth)) * percentNonZero;
  // //   var pxSum = _.sum(yHeights.map(y => y * plotHt * binWidth));
  // //   var zPxSum = zPxWidth * zeroHeight * plotHt;
  // //   console.log('sum', nonZeroSum + zeroSum, JSON.stringify({nonZeroSum, zeroSum}));
  // //   console.log(JSON.stringify({nz: pxSum / (pxSum + zPxSum), z: zPxSum / (pxSum + zPxSum)}));
  //    return {
  //      polylinePoints: polylinePoints,
  //      zeroWidth: zPxWidth,
  //      zeroHeight: zeroHeight / vscale * plotHt
  //    };
	return {
		yHeights,
		zeroWidth: zPxWidth,
		zeroHeight
	};
 }

function calculateFrequency(exp, max, min) {
	var stepSize = (max - min) / bin,
		freq = _.times(bin, _.constant(0));

	// We could do this immutably with reduce/assoc, but it would cause
	// many array copies. Could also do groupBy/count, but it seems excessive.
	exp.forEach(value => {
		freq[Math.floor((value - min) / stepSize)]++;
	});
	freq.forEach(( value, index) => {
		freq[index] = freq[index] / exp.length; //eslint-disable-line local/no-property-assignments
	});
	return freq;
}

function densitySvg(heights, height, totalWidth, vscale, A) {
	let {yHeights, zeroWidth, zeroHeight} = heights,
		binWidth = plotWidth / yHeights.length,
		polylinePoints = [`20,${height}`, ...yHeights.map((y, i) => `${i * binWidth + 20},${(1 - y / vscale) * height}`), `${plotWidth + 20},${height}`].join(' '),
		scaledZeroHeight = zeroHeight / vscale * height;
	return (
		<svg width={totalWidth} height={height}>
			<rect x="0" y={height - scaledZeroHeight} width={zeroWidth} height={scaledZeroHeight} fill={A ? topColor : bottomColor} margin={A ? "" : "5"}/>
			<polyline points={polylinePoints} fill={A ? topColor : bottomColor}/>
		</svg>);
}

var drawDensityPlot = (min, max, totalWidth, unit, getNameZoom) => (studyA, studyB, nameAndZoom) => {
	let height = nameAndZoom.zoom ? plotHeight * zoomFactor : plotHeight,
		rowClass = nameAndZoom.zoom ? "densityPlot--row--zoom" : "densityPlot--row",
		aHeight = calculateHeight(studyA.expA, max, min, height, plotWidth, unit),
		bHeight = calculateHeight(studyB.expB, max, min, height, plotWidth, unit),
		vscale = Math.max(aHeight.zeroHeight, bHeight.zeroHeight, ...aHeight.yHeights, ...bHeight.yHeights);
	return (
		<div className={rowClass} style={{width: `${totalWidth}px`}}onClick={() => getNameZoom(nameAndZoom.name)}>
			<div className="densityPlot--row--xAxis" style={{width: `${plotWidth * 100 / totalWidth}%`, left: "20px"}}/>

				{densitySvg(aHeight, height, totalWidth, vscale, true)}

				{densitySvg(bHeight, height, totalWidth, vscale, false)}

);
};

var histogramRowBin = backgroundColor => freq => (

);

var drawHistogram = (min, max) => (studyA, studyB) => {
	let freqA = calculateFrequency(studyA.expA, max, min),
		freqB = calculateFrequency(studyB.expB, max, min);
	return (

				{freqA.map(histogramRowBin(topColor))}

				{freqB.map(histogramRowBin(bottomColor))}

);
};

var DensityPlot = React.createClass ({
 mixins: [deepPureRenderMixin],
 	render () {
		let {unit, getNameZoom, type} = this.props,
			totalWidth = plotWidth + 20,
			data = this.props.data ? this.props.data : null,
			max = _.max(_.flatten(_.pluck(data.studyA, "expA").concat(_.pluck(data.studyB, "expB")))),
			min = _.min(_.flatten(_.pluck(data.studyA, "expA").concat(_.pluck(data.studyB, "expB")))),
			drawPlot = (type === 'density' ? drawDensityPlot : drawHistogram)(min, max, totalWidth, unit, getNameZoom),
			rows = _.mmap(data.studyA, data.studyB, data.nameAndZoom, drawPlot);
		return (

				{rows}

);
 	}
 });

 module.exports = {DensityPlot, bottomColor, topColor, plotWidth};
<|endoftext|>


<commit_before>'use strict';
/*global describe, it, before, beforeEach, after, afterEach */
/*jshint -W030 */
/*jshint loopfunc:true */

var expect = require('chai').expect;
var redis = require('../index');

var entryNodes = [
    {host: "127.0.0.1", port: 7000}, // One live node in redis cluster
    {host: "127.0.0.1", port: 7009}, // One non-existing node in redis cluster
];

describe('create client in different ways: ', function() {

    it('single live node', function (done) {
        var client = redis.createClient('127.0.0.1', 7000);
        client.on('ready', function () {
            client.close(done);
        });
    });

    it('multi nodes array-array', function (done) {
        var client = redis.createClient([['127.0.0.1', 7000], ['127.0.0.1', 7009]]);
        client.on('ready', function () {
            client.close(done);
        });
    });

    it('multi nodes object-array', function (done) {
        var client = redis.createClient([{host: '127.0.0.1', port: 7000}, {host: '127.0.0.1', port: 7009}]);
        client.on('ready', function () {
            client.close(done);
        });
    });

    it('multi nodes string-array', function (done) {
        var client = redis.createClient(['127.0.0.1:7000', '127.0.0.1:7001', '127.0.0.1:7009']);
        client.on('ready', function () {
            client.close(done);
        });
    });
});

describe('cluster command tests: ', function() {

    var client;

    before(function(done) {
        client = redis.createClient(entryNodes,
            {
                debug_mode: false
            },
            1
        );

        client.on('ready', function() {
            done();
        });
    });

    describe('client helper functions', function() {
        it('should get key table from args', function(done) {
            var kt = client.findKeyTable('mset', ['key1', 'value1', 'key2', 'value2']);
            expect(kt.size).to.be.equal(2);
            expect(kt.get(0)).to.be.equal('key1');
            expect(kt.get(2)).to.be.equal('key2');
            done();
        });
    });

    describe('redis server info', function() {

        it('should get redis info', function(done) {
            client.info(function(err, res) {
                expect(res).to.have.string('redis_version:3');
                done();
            });
        });

        it('should get redis cluster info', function(done) {
            client.cluster('info', function(err, res) {
                expect(res).to.have.string('cluster_state:ok');
                done();
            });
        });
    });

    describe('check whether a command is readonly or not', function() {
        it('should get correct command type', function(done) {
            for(var cmd in client.commands) {
                if(client.commands[cmd][1][0] == 'readonly') {
                    expect(client.isReadOnly(cmd)).to.be.true;
                } else {
                    expect(client.isReadOnly(cmd)).to.be.false;
                }
            }
            done();
        });
    });

    describe('commands: get / set / del', function() {

        it('should returns null for non-exists key', function(done) {
            client.get('non-exists-key', function(err, res) {
                expect(res).to.be.null;
                done();
            });
        });

        it('should set a single key-value success', function(done) {
            client.set('key1', 'value1', function(err, res) {
                expect(res).to.be.equal('OK');
                done();
            });
        });

        it('should get a key success', function(done) {
            client.get('key1', function(err, res) {
                expect(res).to.be.equal('value1');
                done();
            });
        });

        it('should del a key success', function(done) {
            client.del('key1', function(err, res) {
                expect(res).to.be.equal(1);
                done();
            });
        });
    });

    describe('commands: mget / mset', function() {

        it('should mset multi keys in different slots failed', function (done) {
            client.mset('key1', 'value1', 'key2', 'value2', function (err, res) {
                expect(err).to.be.an.instanceOf(Error);
                expect(res).to.not.exist;
                done();
            });
        });

        it('should mset multi key-value in same slots success', function (done) {
            client.mset('{1}key1', 'value1', '{1}key2', 'value2', function (err, res) {
                expect(res).to.be.equal('OK');
                done();
            });
        });

        it('should mget keys in same slots success', function (done) {
            client.mget('{1}key1', '{1}key2', function (err, res) {
                expect(err).to.not.exist;
                expect(res[0]).to.be.equal('value1');
                expect(res[1]).to.be.equal('value2');
                done();
            });
        });

        it('should del keys with hash tag success', function (done) {
            client.del('{1}key1', function (err, res) {
                expect(res).to.be.equal(1);
                client.del('{1}key2', function (err, res) {
                    expect(res).to.be.equal(1);
                    done();
                });
            });
        });

        it('should key "key_redirection" cause redirection but finally success', function (done) {
            var steps = 2;
            var key = 'key_redirection';
            client.keySlotMap.set(key, 0);
            client.once('redirection', function(err) {
                client.keySlotMap.delete(key);
                expect(err.message).to.have.string('MOVED');
                steps -= 1;
            });
            client.get(key, function (err, res) {
                expect(err).to.not.exist;
                expect(res).to.be.null;
                steps -= 1;
                if(steps === 0) {
                    done();
                }
            });
        });
    });

    describe('command: publish & subscribe', function() {

        it('should publish success', function(done) {
            client.publish('test topic', 'test message', function(err, res) {
                expect(err).to.not.exist;
                expect(res).to.be.equal(0);
                done();
            });
        });

        it('should subscribe success', function(done) {
            var topic = 'test topic';
            var msg = 'test message';

            client.subscribe(topic, function(err, res) {
                expect(res[0]).to.be.equal('subscribe');
                expect(res[1]).to.be.equal(topic);
                expect(res[2]).to.be.equal(1);
            });

            client.on('message', function(channel, message) {
                expect(channel).to.be.equal(topic);
                expect(message).to.be.equal(msg);
                client.unsubscribe(topic, function(err, res) {
                    expect(res).to.be.equal(topic);
                    done();
                });
            });

            setTimeout(function() {
                client.publish(topic, msg);
            }, 30);
        });
    });

    describe('command: trasactions', function() {

        it('should explicit exec works', function(done) {
            client.multi()
                .set('key1','value1')
                .set('key2','value2')
                .set('key3','value3')
                .get('key1')
                .get('key2')
                .get('key3')
                .exec(function(err, replies) {
                    expect(err).to.not.exist;
                    expect(replies[0]).to.be.equal('OK');
                    expect(replies[1]).to.be.equal('OK');
                    expect(replies[2]).to.be.equal('OK');
                    expect(replies[3]).to.be.equal('value1');
                    expect(replies[4]).to.be.equal('value2');
                    expect(replies[5]).to.be.equal('value3');
                    done();
                });
        });

        it('should implicit exec works', function(done) {
            client.multi(function(m) {
                m.set('key1','value1')
                .set('key2','value2')
                .set('key3','value3')
                .get('key1')
                .get('key2')
                .get('key3', function(err, res) {
                    done();
                });
            });
        });
    });

    describe('command: pipelining', function() {

        it('should implicit exec works', function(done) {

            var numberOfCallbacks = 4;
            var ensureDone = function() {
                numberOfCallbacks -= 1;
                if (numberOfCallbacks === 0) {
                    done();
                }
            };

            client.pipelined(function(pipeline) {

                pipeline.ping(function(err, res) {
                    expect(err).to.not.exist;
                    expect(res).to.be.equal('PONG');
                    ensureDone();
                })
                .ping()
                .ping(function(err, res) {
                    expect(err).to.not.exist;
                    expect(res).to.be.equal('PONG');
                    ensureDone();
                });

                pipeline.set('key1', 'value1', function(err, res) {
                    expect(err).to.not.exist;
                    expect(res).to.be.equal('OK');
                    ensureDone();
                });

                pipeline.set('key2', 'value2', function(err, res) {
                    expect(err).to.not.exist;
                    expect(res).to.be.equal('OK');
                    ensureDone();
                });

                // no callback
                pipeline.set('key3', 'value3');
            });
        });

        it('should explicit exec works', function(done) {

            var pipeline = client.pipelined();

            pipeline.ping(function(err, res) {
                expect(err).to.not.exist;
                expect(res).to.be.equal('PONG');
            })
            .ping()
            .ping(function(err, res) {
                expect(err).to.not.exist;
                expect(res).to.be.equal('PONG');
            });

            pipeline.set('key1', 'value1', function(err, res) {
                expect(err).to.not.exist;
                expect(res).to.be.equal('OK');
            });

            pipeline.set('key2', 'value2', function(err, res) {
                expect(err).to.not.exist;
                expect(res).to.be.equal('OK');
            });

            // no callback
            pipeline.set('key3', 'value3');

            pipeline.exec(function(err, replies) {
                expect(err).to.not.exist;
                expect(replies[0]).to.be.equal('PONG');
                expect(replies[1]).to.be.equal('PONG');
                expect(replies[2]).to.be.equal('PONG');
                expect(replies[3]).to.be.equal('OK');
                expect(replies[4]).to.be.equal('OK');
                expect(replies[5]).to.be.equal('OK');
                done();
            });
        });
    });

    /**
     * cleanup connections.
     */
    after(function(done) {
        client.close(done);
    });
});<commit_msg>improve test case<commit_after>'use strict';
/*global describe, it, before, beforeEach, after, afterEach */
/*jshint -W030 */
/*jshint loopfunc:true */

var expect = require('chai').expect;
var redis = require('../index');

var entryNodes = [
    {host: "127.0.0.1", port: 7000}, // One live node in redis cluster
    {host: "127.0.0.1", port: 7009}, // One non-existing node in redis cluster
];

describe('create client in different ways: ', function() {

    it('single live node', function (done) {
        var client = redis.createClient('127.0.0.1', 7000);
        client.on('ready', function () {
            client.close(done);
        });
    });

    it('multi nodes array-array', function (done) {
        var client = redis.createClient([['127.0.0.1', 7000], ['127.0.0.1', 7009]]);
        client.on('ready', function () {
            client.close(done);
        });
    });

    it('multi nodes object-array', function (done) {
        var client = redis.createClient([{host: '127.0.0.1', port: 7000}, {host: '127.0.0.1', port: 7009}]);
        client.on('ready', function () {
            client.close(done);
        });
    });

    it('multi nodes string-array', function (done) {
        var client = redis.createClient(['127.0.0.1:7000', '127.0.0.1:7001', '127.0.0.1:7009']);
        client.on('ready', function () {
            client.close(done);
        });
    });
});

describe('cluster command tests: ', function() {

    var client;

    before(function(done) {
        client = redis.createClient(entryNodes,
            {
                debug_mode: false
            },
            1
        );

        client.on('ready', function() {
            done();
        });
    });

    describe('client helper functions', function() {
        it('should get key table from args', function(done) {
            var kt = client.findKeyTable('mset', ['key1', 'value1', 'key2', 'value2']);
            expect(kt.size).to.be.equal(2);
            expect(kt.get(0)).to.be.equal('key1');
            expect(kt.get(2)).to.be.equal('key2');
            done();
        });
    });

    describe('redis server info', function() {

        it('should get redis info', function(done) {
            client.info(function(err, res) {
                expect(res).to.have.string('redis_version:');
                done();
            });
        });

        it('should get redis cluster info', function(done) {
            client.cluster('info', function(err, res) {
                expect(res).to.have.string('cluster_state:ok');
                done();
            });
        });
    });

    describe('check whether a command is readonly or not', function() {
        it('should get correct command type', function(done) {
            for(var cmd in client.commands) {
                if(client.commands[cmd][1][0] == 'readonly') {
                    expect(client.isReadOnly(cmd)).to.be.true;
                } else {
                    expect(client.isReadOnly(cmd)).to.be.false;
                }
            }
            done();
        });
    });

    describe('commands: get / set / del', function() {

        it('should returns null for non-exists key', function(done) {
            client.get('non-exists-key', function(err, res) {
                expect(res).to.be.null;
                done();
            });
        });

        it('should set a single key-value success', function(done) {
            client.set('key1', 'value1', function(err, res) {
                expect(res).to.be.equal('OK');
                done();
            });
        });

        it('should get a key success', function(done) {
            client.get('key1', function(err, res) {
                expect(res).to.be.equal('value1');
                done();
            });
        });

        it('should del a key success', function(done) {
            client.del('key1', function(err, res) {
                expect(res).to.be.equal(1);
                done();
            });
        });
    });

    describe('commands: mget / mset', function() {

        it('should mset multi keys in different slots failed', function (done) {
            client.mset('key1', 'value1', 'key2', 'value2', function (err, res) {
                expect(err).to.be.an.instanceOf(Error);
                expect(res).to.not.exist;
                done();
            });
        });

        it('should mset multi key-value in same slots success', function (done) {
            client.mset('{1}key1', 'value1', '{1}key2', 'value2', function (err, res) {
                expect(res).to.be.equal('OK');
                done();
            });
        });

        it('should mget keys in same slots success', function (done) {
            client.mget('{1}key1', '{1}key2', function (err, res) {
                expect(err).to.not.exist;
                expect(res[0]).to.be.equal('value1');
                expect(res[1]).to.be.equal('value2');
                done();
            });
        });

        it('should del keys with hash tag success', function (done) {
            client.del('{1}key1', function (err, res) {
                expect(res).to.be.equal(1);
                client.del('{1}key2', function (err, res) {
                    expect(res).to.be.equal(1);
                    done();
                });
            });
        });

        it('should key "key_redirection" cause redirection but finally success', function (done) {
            var steps = 2;
            var key = 'key_redirection';
            client.keySlotMap.set(key, 0);
            client.once('redirection', function(err) {
                client.keySlotMap.delete(key);
                expect(err.message).to.have.string('MOVED');
                steps -= 1;
            });
            client.get(key, function (err, res) {
                expect(err).to.not.exist;
                expect(res).to.be.null;
                steps -= 1;
                if(steps === 0) {
                    done();
                }
            });
        });
    });

    describe('command: publish & subscribe', function() {

        it('should publish success', function(done) {
            client.publish('test topic', 'test message', function(err, res) {
                expect(err).to.not.exist;
                expect(res).to.be.equal(0);
                done();
            });
        });

        it('should subscribe success', function(done) {
            var topic = 'test topic';
            var msg = 'test message';

            client.subscribe(topic, function(err, res) {
                expect(res[0]).to.be.equal('subscribe');
                expect(res[1]).to.be.equal(topic);
                expect(res[2]).to.be.equal(1);
            });

            client.on('message', function(channel, message) {
                expect(channel).to.be.equal(topic);
                expect(message).to.be.equal(msg);
                client.unsubscribe(topic, function(err, res) {
                    expect(res).to.be.equal(topic);
                    done();
                });
            });

            setTimeout(function() {
                client.publish(topic, msg);
            }, 30);
        });
    });

    describe('command: trasactions', function() {

        it('should explicit exec works', function(done) {
            client.multi()
                .set('key1','value1')
                .set('key2','value2')
                .set('key3','value3')
                .get('key1')
                .get('key2')
                .get('key3')
                .exec(function(err, replies) {
                    expect(err).to.not.exist;
                    expect(replies[0]).to.be.equal('OK');
                    expect(replies[1]).to.be.equal('OK');
                    expect(replies[2]).to.be.equal('OK');
                    expect(replies[3]).to.be.equal('value1');
                    expect(replies[4]).to.be.equal('value2');
                    expect(replies[5]).to.be.equal('value3');
                    done();
                });
        });

        it('should implicit exec works', function(done) {
            client.multi(function(m) {
                m.set('key1','value1')
                .set('key2','value2')
                .set('key3','value3')
                .get('key1')
                .get('key2')
                .get('key3', function(err, res) {
                    done();
                });
            });
        });
    });

    describe('command: pipelining', function() {

        it('should implicit exec works', function(done) {

            var numberOfCallbacks = 4;
            var ensureDone = function() {
                numberOfCallbacks -= 1;
                if (numberOfCallbacks === 0) {
                    done();
                }
            };

            client.pipelined(function(pipeline) {

                pipeline.ping(function(err, res) {
                    expect(err).to.not.exist;
                    expect(res).to.be.equal('PONG');
                    ensureDone();
                })
                .ping()
                .ping(function(err, res) {
                    expect(err).to.not.exist;
                    expect(res).to.be.equal('PONG');
                    ensureDone();
                });

                pipeline.set('key1', 'value1', function(err, res) {
                    expect(err).to.not.exist;
                    expect(res).to.be.equal('OK');
                    ensureDone();
                });

                pipeline.set('key2', 'value2', function(err, res) {
                    expect(err).to.not.exist;
                    expect(res).to.be.equal('OK');
                    ensureDone();
                });

                // no callback
                pipeline.set('key3', 'value3');
            });
        });

        it('should explicit exec works', function(done) {

            var pipeline = client.pipelined();

            pipeline.ping(function(err, res) {
                expect(err).to.not.exist;
                expect(res).to.be.equal('PONG');
            })
            .ping()
            .ping(function(err, res) {
                expect(err).to.not.exist;
                expect(res).to.be.equal('PONG');
            });

            pipeline.set('key1', 'value1', function(err, res) {
                expect(err).to.not.exist;
                expect(res).to.be.equal('OK');
            });

            pipeline.set('key2', 'value2', function(err, res) {
                expect(err).to.not.exist;
                expect(res).to.be.equal('OK');
            });

            // no callback
            pipeline.set('key3', 'value3');

            pipeline.exec(function(err, replies) {
                expect(err).to.not.exist;
                expect(replies[0]).to.be.equal('PONG');
                expect(replies[1]).to.be.equal('PONG');
                expect(replies[2]).to.be.equal('PONG');
                expect(replies[3]).to.be.equal('OK');
                expect(replies[4]).to.be.equal('OK');
                expect(replies[5]).to.be.equal('OK');
                done();
            });
        });
    });

    /**
     * cleanup connections.
     */
    after(function(done) {
        client.close(done);
    });
});<|endoftext|>


<commit_before>/*
 * HomePage
 *
 * This is the first thing users see of the app
 * Route: /
 *
 */

import React, { Component } from 'react';
import { Link } from 'react-router';
import Nav from '../Nav.react';
import { connect } from 'react-redux';

class HomePage extends Component {
	render() {
    const dispatch = this.props.dispatch;
    const { loggedIn } = this.props.data;

    return (

						{/* Change the copy based on the authentication status */}
						{loggedIn ? (

Welcome to Login Flow, you are logged in!

						) : (

Weclome to Login Flow!

						)}

This application demonstrates what a React.js based register/login workflow might look like on the Frontend. I used react-boilerplate as a starting point — the app thus uses Redux, PostCSS, react-router, ServiceWorker, AppCache, bcrypt and lots more.

						<Link to="/login" className="btn btn--login">Log In</Link>
						<Link to="/register" className="btn btn--register">Register</Link>

Features

Using react-hot-loader, your changes in the CSS and JS get reflected in the app instantly without refreshing the page. That means that the current application state persists even when you change something in the underlying code! For a very good explanation and demo watch Dan Abramov himself talking about it at react-europe.

Redux is a much better implementation of a flux–like, unidirectional data flow. Redux makes actions composable, reduces the boilerplate code and makes hot–reloading possible in the first place. For a good overview of redux check out the talk linked above or the official documentation!

PostCSS is like Sass, but modular and capable of much more. PostCSS is, in essence, just a wrapper for plugins which exposes an easy to use, but very powerful API. While it is possible to replicate Sass features with PostCSS, PostCSS has an ecosystem of amazing plugins with functionalities Sass cannot even dream about having.

react-router is used for routing in this boilerplate. react-router makes routing really easy to do and takes care of a lot of the work.

ServiceWorker and AppCache make it possible to use the application offline. As soon as the website has been opened once, it is cached and available without a network connection. manifest.json is specifically for Chrome on Android. Users can add the website to the homescreen and use it like a native app!

Authentication

Authentication happens in js/utils/auth.js, using fakeRequest.js and fakeServer.js. fakeRequest is a fake XMLHttpRequest wrapper with a similar syntax to request.js. fakeServer responds to the fake HTTP requests and pretends to be a real server, storing the current users in localStorage with the passwords encrypted using bcrypt.

To change it to real authentication, you’d only have to import request.js instead of fakeRequest.js and have a server running somewhere.

		);
  }
}

// Which props do we want to inject, given the global state?
function select(state) {
  return {
    data: state
  };
}

// Wrap the component to inject dispatch and state into it
export default connect(select)(HomePage);
<commit_msg>More copy changes<commit_after>/*
 * HomePage
 *
 * This is the first thing users see of the app
 * Route: /
 *
 */

import React, { Component } from 'react';
import { Link } from 'react-router';
import Nav from '../Nav.react';
import { connect } from 'react-redux';

class HomePage extends Component {
	render() {
    const dispatch = this.props.dispatch;
    const { loggedIn } = this.props.data;

    return (

						{/* Change the copy based on the authentication status */}
						{loggedIn ? (

Welcome to Login Flow, you are logged in!

						) : (

Weclome to Login Flow!

						)}

This application demonstrates what a React.js based register/login workflow might look like on the Frontend. I used react-boilerplate as a starting point — the app thus uses Redux, PostCSS, react-router, ServiceWorker, AppCache, bcrypt and lots more.

						{loggedIn ? null : (

								<Link to="/login" className="btn btn--login">Log In</Link>
								<Link to="/register" className="btn btn--register">Register</Link>

						)}

Features

Using react-hot-loader, your changes in the CSS and JS get reflected in the app instantly without refreshing the page. That means that the current application state persists even when you change something in the underlying code! For a very good explanation and demo watch Dan Abramov himself talking about it at react-europe.

Redux is a much better implementation of a flux–like, unidirectional data flow. Redux makes actions composable, reduces the boilerplate code and makes hot–reloading possible in the first place. For a good overview of redux check out the talk linked above or the official documentation!

PostCSS is like Sass, but modular and capable of much more. PostCSS is, in essence, just a wrapper for plugins which exposes an easy to use, but very powerful API. While it is possible to replicate Sass features with PostCSS, PostCSS has an ecosystem of amazing plugins with functionalities Sass cannot even dream about having.

react-router is used for routing in this boilerplate. react-router makes routing really easy to do and takes care of a lot of the work.

ServiceWorker and AppCache make it possible to use the application offline. As soon as the website has been opened once, it is cached and available without a network connection. manifest.json is specifically for Chrome on Android. Users can add the website to the homescreen and use it like a native app!

Authentication

Authentication happens in js/utils/auth.js, using fakeRequest.js and fakeServer.js. fakeRequest is a fake XMLHttpRequest wrapper with a similar syntax to request.js. fakeServer responds to the fake HTTP requests and pretends to be a real server, storing the current users in localStorage with the passwords encrypted using bcrypt.

To change it to real authentication, you’d only have to import request.js instead of fakeRequest.js and have a server running somewhere.

		);
  }
}

// Which props do we want to inject, given the global state?
function select(state) {
  return {
    data: state
  };
}

// Wrap the component to inject dispatch and state into it
export default connect(select)(HomePage);
<|endoftext|>