<commit_before>window.onload = function () {
    var CONSTANTS = {
        STAGE_WIDTH: 800,
        STAGE_HEIGHT: 600,
        JUMP_SPEED: 60,
        INITIAL_BIRD_X: 100,
        BIRD_GROW_RATE: 1.25,
        BIRD_SKINNIG_RATE: 1.33,
        MINIMUM_BIRD_RADIUS: 20,
        WON_GAME_BIRD_RADIUS: 80,
        GRAVITY_TO_RADIUS_RATIO: 11,
        INITIAL_BIRD_GRAVITY: 3
    },
    currentBirdGravity = CONSTANTS.INITIAL_BIRD_GRAVITY,

    var stage = new Kinetic.Stage({
        container: 'container',
        width: CONSTANTS.STAGE_WIDTH,
        height: CONSTANTS.STAGE_HEIGHT
    });

    var birdLayer = new Kinetic.Layer();
    var drinkLayer = new Kinetic.Layer();
    var obstaclesLayer = new Kinetic.Layer();

    var bird = drunkBird.init(CONSTANTS.INITIAL_BIRD_X, CONSTANTS.STAGE_HEIGHT / 2);

    var birdShape = new Kinetic.Circle({
        x: bird.x,
        y: bird.y,
        radius: bird.radius,
        fill: 'red',
        stroke: 'black',
        strokeWidth: 4
    });

    birdLayer.add(birdShape);
    //put kinetic layers here e.g stage.add(layerName);
    function birdAnimationFrame() {
    	if (bird.radius > 30) {
            currentBirdGravity = bird.radius/CONSTANTS.GRAVITY_TO_RADIUS_RATIO;
            // console.log(bird.radius);
        } else {
            currentBirdGravity = CONSTANTS.INITIAL_BIRD_GRAVITY;
        }
        bird.y += currentBirdGravity;

        if (bird.y >= CONSTANTS.STAGE_HEIGHT - bird.radius) {
            bird.y = CONSTANTS.STAGE_HEIGHT - bird.radius;
            bird.isFlying = false;

            birdShape.setY(bird.y);
            birdLayer.draw();

            alert('Game Over! Bird is not flying!');
            return;
        }

		if (bird.radius < CONSTANTS.MINIMUM_BIRD_RADIUS) {
			alert('Game Over! Bird is starved to dead without alcohol!');
            return;
		}

		if (bird.radius > CONSTANTS.WON_GAME_BIRD_RADIUS) {
			alert('Game Won! You got one happy drunk bird!');
            return;
		}

        birdShape.setY(bird.y);

        birdLayer.draw();

        requestAnimationFrame(birdAnimationFrame);
    }

    function performJump(bird) {
        if (bird.y - bird.radius >= CONSTANTS.JUMP_SPEED) {
            bird.y -= CONSTANTS.JUMP_SPEED;
        } else {
            bird.y = 0 + bird.radius;
        }
    }

    (function () {
        //if you want to jump as long as you press SPACE btn comment 'keyup EventListener'
        //and the logic with btnIsDown
        var btnIsDown = false;
        window.addEventListener('keydown', function (ev) {
            if (ev.keyCode === 32) {
                if (btnIsDown) {
                    return;
                }
                btnIsDown = true;
                performJump(bird);
                birdShape.setY(bird.y);
            }
        });

        window.addEventListener('keyup', function (ev) {
            if (ev.keyCode === 32) {
                btnIsDown = false;
            }
        });
    } ());

   // birdAnimationFrame();

    function areColliding(bird, drawableObject) {
        var inBottomLeft = false,
            inBottomRight = false,
            inTopLeft = false,
            inTopRight = false;

        var distanceBottomLeft = Math.pow(bird.x - drawableObject.x, 2) + Math.pow(bird.y - drawableObject.y, 2);
        var distanceTopLeft = Math.pow(bird.x - drawableObject.x, 2) + Math.pow(bird.y - (drawableObject.y + drawableObject.height), 2);
        var distanceTopRight = Math.pow(bird.x - (drawableObject.x + drawableObject.width), 2) + Math.pow(bird.y - (drawableObject.y + drawableObject.height), 2);
        var distanceBottomRight = Math.pow(bird.x - (drawableObject.x + drawableObject.width), 2) + Math.pow(bird.y - drawableObject.y, 2);

        if (distanceBottomLeft <= bird.radius * bird.radius) {
            inBottomLeft = true;
        }

        if (distanceTopRight <= bird.radius * bird.radius) {
            inTopRight = true;
        }

        if (distanceTopLeft <= bird.radius * bird.radius) {
            inTopLeft = true;
        }

        if (distanceBottomRight <= bird.radius * bird.radius) {
            inBottomRight = true;
        }

        return inTopLeft || inBottomLeft || inTopRight || inBottomRight;
    }

    /*    var testBird = drunkBird.init(50, 50);
        var testObstacle = obstacle.init(50, 50, 20, 20);

        console.log('collision: ' + areColliding(testBird, testObstacle));*/

    var initialIntervalMaxX = stage.getWidth(),
        initialIntervalMinY = 100,
        initialIntervalMaxY = stage.getHeight() - 100,
        cocktailSources = [
            'images/Cocktails/cocktailOne.png',
            'images/Cocktails/cocktailTwo.png',
            'images/Cocktails/cocktailThree.png',
            'images/Cocktails/cocktailFour.png',
            'images/Cocktails/cocktailFive.png'
        ], softDrinkSources = [
            'images/SoftDrinks/softDrinkOne.png',
            'images/SoftDrinks/softDrinkTwo.png',
            'images/SoftDrinks/softDrinkThree.png',
            'images/SoftDrinks/softDrinkFour.png',
            'images/SoftDrinks/softDrinkFive.png'
        ], obstacleAboveSources = [
            'images/Obstacles/cable_above.png',
            'images/Obstacles/chandelier_above.png',
            'images/Obstacles/speaker_above.png'
        ], obstacleBelowSources = [
            'images/Obstacles/chair_below.png',
            'images/Obstacles/tree-version1.png',
            'images/Obstacles/tree-version2.png'
        ],
        basicSpeed = -3,
        drinkCount = 0,
        drinkArr = [],
        drinkWidth = 30,
        drinkHeight = 50,
        obstacleAboveWidth = 70,
        obstacleAboveHeight = 30,
        aboveObstacleX = 0,
        belowObstacleX = 0,
        obstacleY = 0,
        speed = 3;

    function randomNumberInInterval(min, max) {
        var randomNumber = Math.floor(Math.random() * (max - min) + min);
        return randomNumber;
    }

    function setSoftDrinkImage(softDrinkObject) {
        var softDrinkImage = new Image();
        var number = Math.round(Math.random() * 4);
        softDrinkImage.src = softDrinkSources[number];

        softDrinkImage.onload = function () {
            softDrinkObject.setFillPatternImage(softDrinkImage);
            softDrinkObject.fillPatternScaleX(0.5);
            softDrinkObject.fillPatternScaleY(0.5);
            stage.draw();
        };

        return softDrinkImage;
    }

    function setCocktailImage(cocktailObject) {
        var cocktailImage = new Image();
        var number = Math.round(Math.random() * 4);
        cocktailImage.src = cocktailSources[number];

        cocktailImage.onload = function () {
            cocktailObject.setFillPatternImage(cocktailImage);
            cocktailObject.fillPatternScaleX(0.5);
            cocktailObject.fillPatternScaleY(0.5);
            stage.draw();
        };

        return cocktailImage;
    }

    function setObstacleImage(obstacleObject) {
        var obstacleImage = new Image();
        var number = Math.round(Math.random() * 3);
        obstacleImage.src = obstacleAboveSources[number];

        obstacleImage.onload = function () {
            obstacleObject.setFillPatternImage(obstacleImage);
            obstacleObject.fillPatternScaleX(1);
            obstacleObject.fillPatternScaleY(1);
            stage.draw();
        };

        return obstacleImage;
    }

    function generateDrinkObject(x, y, width, height, type) {

        var drink = new Kinetic.Rect({
            x: x,
            y: y,
            width: width,
            height: height,
            fillPriority: 'pattern'
        });

        if (type) {
            setCocktailImage(drink);
        } else {
            setSoftDrinkImage(drink);
        }
        return drink;
    }

    function generateObstacleObject(initialX, initialY) {
        var obstacle = new Kinetic.Rect({
            x: initialX,
            y: initialY,
            width: 100,
            height: 50,
            fillPriority: 'pattern'
        });

        return obstacle;
    }

    setInterval(function () {
        ++drinkCount;
        if (drinkCount % 3 === 0) {
            var cocktailObject = Object.create(cocktail).init(initialIntervalMaxX, randomNumberInInterval(initialIntervalMinY, initialIntervalMaxY), drinkWidth, drinkHeight);
            cocktailObject.speed = basicSpeed;
            cocktailObject.kineticObject = generateDrinkObject(cocktailObject.x, cocktailObject.y, cocktailObject.width, cocktailObject.height, cocktail.isPrototypeOf(cocktailObject));
            drinkLayer.add(cocktailObject.kineticObject);
            drinkArr.push(cocktailObject);
        } else {
            var softDrinkObject = Object.create(softDrink).init(initialIntervalMaxX, randomNumberInInterval(initialIntervalMinY, initialIntervalMaxY), drinkWidth, drinkHeight);
            softDrinkObject.speed = basicSpeed;
            softDrinkObject.kineticObject = generateDrinkObject(softDrinkObject.x, softDrinkObject.y, softDrinkObject.width, softDrinkObject.height, cocktail.isPrototypeOf(softDrinkObject));
            drinkLayer.add(softDrinkObject.kineticObject);
            drinkArr.push(softDrinkObject);
        }
    }, 1500);

    function animateDrinks() {
        drinkArr.forEach(function (drinkObject, index) {

            var updateX = drinkObject.speed;

            var x = drinkObject.kineticObject.getX() + updateX;

            drinkObject.kineticObject.setX(x);
            drinkObject.x = x;

            if (drinkObject.kineticObject.getX() + drinkObject.kineticObject.getWidth() < 0) {
                drinkObject.kineticObject.remove();
                drinkArr.splice(index, 1);
            }

            if (areColliding(bird, drinkObject)) {
                if (cocktail.isPrototypeOf(drinkObject)) {
                    bird.radius *= CONSTANTS.BIRD_GROW_RATE;
                } else {
                    bird.radius /= CONSTANTS.BIRD_SKINNIG_RATE;
                }

                birdShape.setRadius(bird.radius);
                // console.log(bird.radius);
                drinkObject.kineticObject.remove();
                drinkArr.splice(index, 1);
            }
            // console.log(birdArr.length);
        });
        drinkLayer.draw();
        requestAnimationFrame(animateDrinks);
    }

    var aboveObstacleObject = Object.create(obstacle).init(initialIntervalMaxX, initialIntervalMinY, 100, 50);
        aboveObstacleObject.kineticObject = generateObstacleObject(initialIntervalMaxX, initialIntervalMinY);
    var belowObstacleObject = Object.create(obstacle).init(initialIntervalMaxX, initialIntervalMinY, 100, 50);
        belowObstacleObject.kineticObject = generateObstacleObject(initialIntervalMaxX, initialIntervalMaxY);
    setObstacleImage(aboveObstacleObject.kineticObject);
    setObstacleImage(belowObstacleObject.kineticObject);

    function animateObstacleFrame() {
        obstaclesLayer.add(aboveObstacleObject.kineticObject);
        obstaclesLayer.add(belowObstacleObject.kineticObject);

        aboveObstacleX = aboveObstacleObject.kineticObject.getX();
        belowObstacleX = belowObstacleObject.kineticObject.getX();

        aboveObstacleX -= speed;
        belowObstacleX -= speed;

        aboveObstacleObject.x = aboveObstacleX;
        belowObstacleObject.x = belowObstacleX;

        aboveObstacleObject.kineticObject.setX(aboveObstacleX);
        belowObstacleObject.kineticObject.setX(belowObstacleX);

        if (areColliding(bird, aboveObstacleObject)) {
            alert('COLLISION');
            return;
        }
        if (areColliding(bird, belowObstacleObject)) {
            alert('COLLISION');
            console.log('asdasdasdsadsadsadsa');
            return;
        }

        obstaclesLayer.draw();

        requestAnimationFrame(animateObstacleFrame);

        if (aboveObstacleX < 0 ) {
            aboveObstacleObject.kineticObject.setX(800);
            aboveObstacleObject.x = 800;
            //aboveObstacleObject.setY(randomNumberInInterval(initialIntervalMinY, initialIntervalMaxY));
            setObstacleImage(aboveObstacleObject.kineticObject);
        }

        if (belowObstacleX < 0 ) {
            belowObstacleObject.kineticObject.setX(800);
            belowObstacleObject.x = 800;
            //aboveObstacleObject.setY(randomNumberInInterval(initialIntervalMinY, initialIntervalMaxY));
            setObstacleImage(belowObstacleObject.kineticObject);
        }
    }

    //animateObstacleFrame();
    //animateDrinks();

    //stage.add(background);
    //stage.add(drinkLayer);
    //stage.add(obstaclesLayer);
    //uncomment the 2 lines below to see homePage and optionsPage......
   	stage.add(homeScreen);
    //stage.add(birdLayer);

    window.addEventListener('navigateToHomeScreen', function() {
    	//hide other elements and show homeScreen
	    console.log('we change screen to HOME');
	    optionsScreen.clear();
	    //stage.re
	}, false);
	window.addEventListener('navigateToOptionsScreen', function() {
		//hide other elements and show optionsSCreen
	    console.log('we change screen to OPTIONS');
	}, false);
	window.addEventListener('navigateToIngameScreen', function() {
		//hide other elements and show optionsSCreen
	    console.log('we change screen to Ingame and start playing the game');
        homeScreen.clear();
        stage.add(background);
        stage.add(drinkLayer);
        stage.add(obstaclesLayer);
        stage.add(birdLayer);
        birdAnimationFrame();
        animateObstacleFrame();
        animateDrinks();

	}, false);
};
<commit_msg>missed semi-colon<commit_after>window.onload = function () {
    var CONSTANTS = {
        STAGE_WIDTH: 800,
        STAGE_HEIGHT: 600,
        JUMP_SPEED: 60,
        INITIAL_BIRD_X: 100,
        BIRD_GROW_RATE: 1.25,
        BIRD_SKINNIG_RATE: 1.33,
        MINIMUM_BIRD_RADIUS: 20,
        WON_GAME_BIRD_RADIUS: 80,
        GRAVITY_TO_RADIUS_RATIO: 11,
        INITIAL_BIRD_GRAVITY: 3
    },
    currentBirdGravity = CONSTANTS.INITIAL_BIRD_GRAVITY;

    var stage = new Kinetic.Stage({
        container: 'container',
        width: CONSTANTS.STAGE_WIDTH,
        height: CONSTANTS.STAGE_HEIGHT
    });

    var birdLayer = new Kinetic.Layer();
    var drinkLayer = new Kinetic.Layer();
    var obstaclesLayer = new Kinetic.Layer();

    var bird = drunkBird.init(CONSTANTS.INITIAL_BIRD_X, CONSTANTS.STAGE_HEIGHT / 2);

    var birdShape = new Kinetic.Circle({
        x: bird.x,
        y: bird.y,
        radius: bird.radius,
        fill: 'red',
        stroke: 'black',
        strokeWidth: 4
    });

    birdLayer.add(birdShape);
    //put kinetic layers here e.g stage.add(layerName);
    function birdAnimationFrame() {
    	if (bird.radius > 30) {
            currentBirdGravity = bird.radius/CONSTANTS.GRAVITY_TO_RADIUS_RATIO;
            // console.log(bird.radius);
        } else {
            currentBirdGravity = CONSTANTS.INITIAL_BIRD_GRAVITY;
        }
        bird.y += currentBirdGravity;

        if (bird.y >= CONSTANTS.STAGE_HEIGHT - bird.radius) {
            bird.y = CONSTANTS.STAGE_HEIGHT - bird.radius;
            bird.isFlying = false;

            birdShape.setY(bird.y);
            birdLayer.draw();

            alert('Game Over! Bird is not flying!');
            return;
        }

		if (bird.radius < CONSTANTS.MINIMUM_BIRD_RADIUS) {
			alert('Game Over! Bird is starved to dead without alcohol!');
            return;
		}

		if (bird.radius > CONSTANTS.WON_GAME_BIRD_RADIUS) {
			alert('Game Won! You got one happy drunk bird!');
            return;
		}

        birdShape.setY(bird.y);

        birdLayer.draw();

        requestAnimationFrame(birdAnimationFrame);
    }

    function performJump(bird) {
        if (bird.y - bird.radius >= CONSTANTS.JUMP_SPEED) {
            bird.y -= CONSTANTS.JUMP_SPEED;
        } else {
            bird.y = 0 + bird.radius;
        }
    }

    (function () {
        //if you want to jump as long as you press SPACE btn comment 'keyup EventListener'
        //and the logic with btnIsDown
        var btnIsDown = false;
        window.addEventListener('keydown', function (ev) {
            if (ev.keyCode === 32) {
                if (btnIsDown) {
                    return;
                }
                btnIsDown = true;
                performJump(bird);
                birdShape.setY(bird.y);
            }
        });

        window.addEventListener('keyup', function (ev) {
            if (ev.keyCode === 32) {
                btnIsDown = false;
            }
        });
    } ());

   // birdAnimationFrame();

    function areColliding(bird, drawableObject) {
        var inBottomLeft = false,
            inBottomRight = false,
            inTopLeft = false,
            inTopRight = false;

        var distanceBottomLeft = Math.pow(bird.x - drawableObject.x, 2) + Math.pow(bird.y - drawableObject.y, 2);
        var distanceTopLeft = Math.pow(bird.x - drawableObject.x, 2) + Math.pow(bird.y - (drawableObject.y + drawableObject.height), 2);
        var distanceTopRight = Math.pow(bird.x - (drawableObject.x + drawableObject.width), 2) + Math.pow(bird.y - (drawableObject.y + drawableObject.height), 2);
        var distanceBottomRight = Math.pow(bird.x - (drawableObject.x + drawableObject.width), 2) + Math.pow(bird.y - drawableObject.y, 2);

        if (distanceBottomLeft <= bird.radius * bird.radius) {
            inBottomLeft = true;
        }

        if (distanceTopRight <= bird.radius * bird.radius) {
            inTopRight = true;
        }

        if (distanceTopLeft <= bird.radius * bird.radius) {
            inTopLeft = true;
        }

        if (distanceBottomRight <= bird.radius * bird.radius) {
            inBottomRight = true;
        }

        return inTopLeft || inBottomLeft || inTopRight || inBottomRight;
    }

    /*    var testBird = drunkBird.init(50, 50);
        var testObstacle = obstacle.init(50, 50, 20, 20);

        console.log('collision: ' + areColliding(testBird, testObstacle));*/

    var initialIntervalMaxX = stage.getWidth(),
        initialIntervalMinY = 100,
        initialIntervalMaxY = stage.getHeight() - 100,
        cocktailSources = [
            'images/Cocktails/cocktailOne.png',
            'images/Cocktails/cocktailTwo.png',
            'images/Cocktails/cocktailThree.png',
            'images/Cocktails/cocktailFour.png',
            'images/Cocktails/cocktailFive.png'
        ], softDrinkSources = [
            'images/SoftDrinks/softDrinkOne.png',
            'images/SoftDrinks/softDrinkTwo.png',
            'images/SoftDrinks/softDrinkThree.png',
            'images/SoftDrinks/softDrinkFour.png',
            'images/SoftDrinks/softDrinkFive.png'
        ], obstacleAboveSources = [
            'images/Obstacles/cable_above.png',
            'images/Obstacles/chandelier_above.png',
            'images/Obstacles/speaker_above.png'
        ], obstacleBelowSources = [
            'images/Obstacles/chair_below.png',
            'images/Obstacles/tree-version1.png',
            'images/Obstacles/tree-version2.png'
        ],
        basicSpeed = -3,
        drinkCount = 0,
        drinkArr = [],
        drinkWidth = 30,
        drinkHeight = 50,
        obstacleAboveWidth = 70,
        obstacleAboveHeight = 30,
        aboveObstacleX = 0,
        belowObstacleX = 0,
        obstacleY = 0,
        speed = 3;

    function randomNumberInInterval(min, max) {
        var randomNumber = Math.floor(Math.random() * (max - min) + min);
        return randomNumber;
    }

    function setSoftDrinkImage(softDrinkObject) {
        var softDrinkImage = new Image();
        var number = Math.round(Math.random() * 4);
        softDrinkImage.src = softDrinkSources[number];

        softDrinkImage.onload = function () {
            softDrinkObject.setFillPatternImage(softDrinkImage);
            softDrinkObject.fillPatternScaleX(0.5);
            softDrinkObject.fillPatternScaleY(0.5);
            stage.draw();
        };

        return softDrinkImage;
    }

    function setCocktailImage(cocktailObject) {
        var cocktailImage = new Image();
        var number = Math.round(Math.random() * 4);
        cocktailImage.src = cocktailSources[number];

        cocktailImage.onload = function () {
            cocktailObject.setFillPatternImage(cocktailImage);
            cocktailObject.fillPatternScaleX(0.5);
            cocktailObject.fillPatternScaleY(0.5);
            stage.draw();
        };

        return cocktailImage;
    }

    function setObstacleImage(obstacleObject) {
        var obstacleImage = new Image();
        var number = Math.round(Math.random() * 3);
        obstacleImage.src = obstacleAboveSources[number];

        obstacleImage.onload = function () {
            obstacleObject.setFillPatternImage(obstacleImage);
            obstacleObject.fillPatternScaleX(1);
            obstacleObject.fillPatternScaleY(1);
            stage.draw();
        };

        return obstacleImage;
    }

    function generateDrinkObject(x, y, width, height, type) {

        var drink = new Kinetic.Rect({
            x: x,
            y: y,
            width: width,
            height: height,
            fillPriority: 'pattern'
        });

        if (type) {
            setCocktailImage(drink);
        } else {
            setSoftDrinkImage(drink);
        }
        return drink;
    }

    function generateObstacleObject(initialX, initialY) {
        var obstacle = new Kinetic.Rect({
            x: initialX,
            y: initialY,
            width: 100,
            height: 50,
            fillPriority: 'pattern'
        });

        return obstacle;
    }

    setInterval(function () {
        ++drinkCount;
        if (drinkCount % 3 === 0) {
            var cocktailObject = Object.create(cocktail).init(initialIntervalMaxX, randomNumberInInterval(initialIntervalMinY, initialIntervalMaxY), drinkWidth, drinkHeight);
            cocktailObject.speed = basicSpeed;
            cocktailObject.kineticObject = generateDrinkObject(cocktailObject.x, cocktailObject.y, cocktailObject.width, cocktailObject.height, cocktail.isPrototypeOf(cocktailObject));
            drinkLayer.add(cocktailObject.kineticObject);
            drinkArr.push(cocktailObject);
        } else {
            var softDrinkObject = Object.create(softDrink).init(initialIntervalMaxX, randomNumberInInterval(initialIntervalMinY, initialIntervalMaxY), drinkWidth, drinkHeight);
            softDrinkObject.speed = basicSpeed;
            softDrinkObject.kineticObject = generateDrinkObject(softDrinkObject.x, softDrinkObject.y, softDrinkObject.width, softDrinkObject.height, cocktail.isPrototypeOf(softDrinkObject));
            drinkLayer.add(softDrinkObject.kineticObject);
            drinkArr.push(softDrinkObject);
        }
    }, 1500);

    function animateDrinks() {
        drinkArr.forEach(function (drinkObject, index) {

            var updateX = drinkObject.speed;

            var x = drinkObject.kineticObject.getX() + updateX;

            drinkObject.kineticObject.setX(x);
            drinkObject.x = x;

            if (drinkObject.kineticObject.getX() + drinkObject.kineticObject.getWidth() < 0) {
                drinkObject.kineticObject.remove();
                drinkArr.splice(index, 1);
            }

            if (areColliding(bird, drinkObject)) {
                if (cocktail.isPrototypeOf(drinkObject)) {
                    bird.radius *= CONSTANTS.BIRD_GROW_RATE;
                } else {
                    bird.radius /= CONSTANTS.BIRD_SKINNIG_RATE;
                }

                birdShape.setRadius(bird.radius);
                // console.log(bird.radius);
                drinkObject.kineticObject.remove();
                drinkArr.splice(index, 1);
            }
            // console.log(birdArr.length);
        });
        drinkLayer.draw();
        requestAnimationFrame(animateDrinks);
    }

    var aboveObstacleObject = Object.create(obstacle).init(initialIntervalMaxX, initialIntervalMinY, 100, 50);
        aboveObstacleObject.kineticObject = generateObstacleObject(initialIntervalMaxX, initialIntervalMinY);
    var belowObstacleObject = Object.create(obstacle).init(initialIntervalMaxX, initialIntervalMinY, 100, 50);
        belowObstacleObject.kineticObject = generateObstacleObject(initialIntervalMaxX, initialIntervalMaxY);
    setObstacleImage(aboveObstacleObject.kineticObject);
    setObstacleImage(belowObstacleObject.kineticObject);

    function animateObstacleFrame() {
        obstaclesLayer.add(aboveObstacleObject.kineticObject);
        obstaclesLayer.add(belowObstacleObject.kineticObject);

        aboveObstacleX = aboveObstacleObject.kineticObject.getX();
        belowObstacleX = belowObstacleObject.kineticObject.getX();

        aboveObstacleX -= speed;
        belowObstacleX -= speed;

        aboveObstacleObject.x = aboveObstacleX;
        belowObstacleObject.x = belowObstacleX;

        aboveObstacleObject.kineticObject.setX(aboveObstacleX);
        belowObstacleObject.kineticObject.setX(belowObstacleX);

        if (areColliding(bird, aboveObstacleObject)) {
            alert('COLLISION');
            return;
        }
        if (areColliding(bird, belowObstacleObject)) {
            alert('COLLISION');
            console.log('asdasdasdsadsadsadsa');
            return;
        }

        obstaclesLayer.draw();

        requestAnimationFrame(animateObstacleFrame);

        if (aboveObstacleX < 0 ) {
            aboveObstacleObject.kineticObject.setX(800);
            aboveObstacleObject.x = 800;
            //aboveObstacleObject.setY(randomNumberInInterval(initialIntervalMinY, initialIntervalMaxY));
            setObstacleImage(aboveObstacleObject.kineticObject);
        }

        if (belowObstacleX < 0 ) {
            belowObstacleObject.kineticObject.setX(800);
            belowObstacleObject.x = 800;
            //aboveObstacleObject.setY(randomNumberInInterval(initialIntervalMinY, initialIntervalMaxY));
            setObstacleImage(belowObstacleObject.kineticObject);
        }
    }

    //animateObstacleFrame();
    //animateDrinks();

    //stage.add(background);
    //stage.add(drinkLayer);
    //stage.add(obstaclesLayer);
    //uncomment the 2 lines below to see homePage and optionsPage......
   	stage.add(homeScreen);
    //stage.add(birdLayer);

    window.addEventListener('navigateToHomeScreen', function() {
    	//hide other elements and show homeScreen
	    console.log('we change screen to HOME');
	    optionsScreen.clear();
	    //stage.re
	}, false);
	window.addEventListener('navigateToOptionsScreen', function() {
		//hide other elements and show optionsSCreen
	    console.log('we change screen to OPTIONS');
	}, false);
	window.addEventListener('navigateToIngameScreen', function() {
		//hide other elements and show optionsSCreen
	    console.log('we change screen to Ingame and start playing the game');
        homeScreen.clear();
        stage.add(background);
        stage.add(drinkLayer);
        stage.add(obstaclesLayer);
        stage.add(birdLayer);
        birdAnimationFrame();
        animateObstacleFrame();
        animateDrinks();

	}, false);
};
<|endoftext|>


<commit_before>/**
# Events
*/
/* global module, console, window, require, KeyboardEvent */

'use strict';

const {findWithin} = require('./b8r.dom.js');
const {get, registered, call} = require('./b8r.registry.js');
const anyElement = require('./b8r.anyElement.js');
const keys = require('./b8r.keystroke.js');
const {pathSplit} = require('./b8r.byPath.js');

const implicit_event_types = [
  'mousedown', 'mouseup', 'mousemove', 'mouseover', 'mouseout', 'click',
  'mouseleave', 'mouseenter',
  'mousewheel', 'scroll', // FIXEME passive?!
  'dragstart', 'dragenter', 'dragover', 'dragleave', 'dragend', 'drop',
  'transitionend', 'animationend',
  'input', 'change',
  'keydown', 'keyup',
  'focus', 'blur' // more to follow
];

const onOffArgs = args => {
  var element, event_type, object, method, prepend = false;
  if(typeof args[2] === 'object') {
    console.warn('b8r.on(element, type, OBJECT) is deprecated');
    [element, event_type, object] = args;
    return on(element, event_type, object.model, object.method);
  } else if(args.length > 4 || typeof args[3] === 'string') {
    [element, event_type, object, method, prepend] = args;
    if(typeof object !== 'string' || typeof method !== 'string') {
      console.error('implicit bindings are by name, not', object, method);
      return;
    }
    method = object + '.' + method;
  } else {
    [element, event_type, method, prepend] = args;
  }
  if (!(element instanceof Element)) {
    console.error('bind bare elements please, not', element);
    throw 'bad argument';
  }
  return {element, event_type, path: method, prepend};
};

const getEventHandlers = (element) => {
  const source = element.getAttribute('data-event');
  const existing = source ?
                   source.
                   replace(/\s*(^|$|[,:;])\s*/g, '$1').split(';').
                   filter(handler => handler.trim()) :
                   [];
  return existing;
};

/**

    b8r.getParsedEventHandlers(element)

returns an array of parsed implicit event handlers for an element, e.g.

    data-event="type1:model1.method1;type2,type3:model2.method2"

is returned as

    [
      { types: ["type1"], model: "model1", method: "method1"},
      { types: ["type2", "type3"], model: "model2", method: "method2"}
    ]
*/

const getParsedEventHandlers = element => {
  var handlers = getEventHandlers(element);
  return handlers.map(function(instruction){
    var [type, handler] = instruction.split(':');
    if (!handler) {
      if(instruction.indexOf('.')) {
        console.error('bad event handler (missing event type)', instruction, 'in', element);
      } else {
        console.error('bad event handler (missing handler)', instruction, 'in', element);
      }
      return { types: [] };
    }
    var [model, method] = handler.trim().split('.');
    var types = type.split(',').sort();
    return {
      types: types.map(s => s.split('(')[0].trim()),
      type_args: types.map(s => {
        if (s.substr(0,3) === 'key') {
          s = s.replace(/Key|Digit/g, '');
        }
        var args = s.match(/\(([^)]+)\)/);
        return args && args[1] ? args[1].split(',') : false;
      }),
      model,
      method,
    };
  });
};

const makeHandler = (event_type, method) => {
  if (typeof event_type === 'string') {
    event_type = [event_type];
  }
  if(!Array.isArray(event_type)) {
    console.error('makeHandler failed; bad event_type', event_type);
    return;
  }
  return event_type.sort().join(',') + ':' + method;
};

/**
    on(element, event_type, model_name, method_name);

creates an implicit event-binding data attribute:

    data-event="event_type:module_name.method_name"

Multiple handlers are semicolon-delimited, e.g.

    data-event="mouseover:_component_.show;mouseover:_component_.hide"

You can bind multiple event types separated by commas, e.g.

    data-event="click,keyup:do.something"

**Note**: if you link two event types to the same method separately they will NOT be collated.

You can remove an implicit event binding using:

    off(element, event_type, model_name, method_name);

### Keyboard Events

To make it easy to handle specific keystrokes, you can bind to keystrokes by name, e.g.

    data-bind="keydown(meta-KeyS)"

For your convenience, there's a *Keyboard Event Utility*.
*/

const on = (...args) => {
  const {element, event_type, path, prepend} = onOffArgs(args);
  const handler = makeHandler(event_type, path);
  const existing = getEventHandlers(element);
  if(existing.indexOf(handler) === -1) {
    if (prepend) {
      existing.unshift(handler);
    } else {
      existing.push(handler);
    }
  }
  element.setAttribute('data-event', existing.join(';'));
};

const off = (...args) => {
  var element, event_type, object, method;
  if(args.length === 4) {
    [element, event_type, object, method] = args;
    method = object + '.' + method;
  } else if (args.length === 3) {
    [element, event_type, method] = args;
  } else {
    throw 'b8r.off requires three or four arguments';
  }
  const existing = element.getAttribute('data-event').split(';');
  const handler = makeHandler(event_type, method);
  const idx = existing.indexOf(handler);
  if (idx > -1) {
    existing.splice(idx, 1);
    if (existing.length) {
      element.setAttribute('data-event', existing.join(';'));
    } else {
      element.removeAttribute('data-event');
    }
  }
};

/**
## Enabling and Disabling Event Handlers

Convenience methods for (temporarily) enabling and disabling event handlers.

Will not play nicely with event handler creation / removal.

    enable(element);

Returns data-event-disabled attributes to data-event attributes.

    disable(element);

Finds all data-event bindings on elements within the specified target and
turns them into data-event-disabled attributes;
*/

const disable = within_elt => {
  findWithin(within_elt, '[data-event]').forEach(elt => {
    elt.setAttribute('data-event-disabled', elt.getAttribute('data-event'));
    elt.removeAttribute('data-event');
  });
};

const enable = within_elt => {
  findWithin(within_elt, '[data-event-disabled]').forEach(elt => {
    elt.setAttribute('data-event', elt.getAttribute('data-event-disabled'));
    elt.removeAttribute('data-event-disabled');
  });
};

const dispatch = (type, target) => {
  const event = new Event(type);
  target.dispatchEvent(event);
  return event;
};

// add touch events if needed
if (window.TouchEvent) {
  ['touchstart', 'touchcancel', 'touchmove', 'touchend'].forEach(
      type => implicit_event_types.push(type));
}

const get_component_with_method = function(element, path) {
  var component_id = false;
  element = element.closest('[data-component-id]');
  while (element instanceof Element) {
    if (get(`${element.getAttribute('data-component-id')}.${path}`) instanceof Function) {
      component_id = element.getAttribute('data-component-id');
      break;
    }
    element = element.parentElement.closest('[data-component-id]');
  }
  return component_id;
};

/**
    b8r.callMethod(method_path, ...args)
    b8r.callMethod(model, method, ...args);

Call a method by name from a registered method. If the relevant model has not
yet been registered (e.g. it's being loaded asynchronously) it will get the
message when it's registered.
*/

var saved_messages = [];  // {model, method, evt}

function saveMethodCall(model, method, args) {
  saved_messages.push({model, method, args});
}

const play_saved_messages = for_model => {
  var playbackQueue = [];
  for (var i = saved_messages.length - 1; i >= 0; i--) {
    if (saved_messages[i].model === for_model) {
      playbackQueue.push(saved_messages[i]);
      saved_messages.splice(i, 1);
    }
  }
  while (playbackQueue.length) {
    var {model, method, args} = playbackQueue.pop();
    callMethod(model, method, ...args);
  }
};

const callMethod = (...args) => {
  var model, method;
  try {
    if (args[0].match(/[\[.]/)) {
      [method, ...args] = args;
      [model, method] = pathSplit(method);
    } else {
      [model, method, ...args] = args;
    }
  } catch (e) {
    debugger;  // jshint ignore:line
  }
  var result = null;
  if (registered(model)) {
    result = call(`${model}.${method}`, ...args);
  } else {
    // TODO queue if model not available
    // event is stopped from further propagation
    // provide global wrappers that can e.g. put up a spinner then call the
    // method
    saveMethodCall(model, method, args);
  }
  return result;
};

/**
    b8r.trigger(type, target, ...args); //

Trigger a synthetic implicit (only!) event. Note that you can trigger and
handle completely made-up events, but if you trigger events that occur
naturally the goal is for them to be handled exactly as if they were "real".
*/

const trigger = (type, target, ...args) => {
  if (typeof type !== 'string' ||
      !(target.dispatchEvent instanceof Function)) {
    console.error(
        'expected trigger(event_type, target_element)', type, target);
  }
  if (target) {
    const event = dispatch(type, target);
    if (target instanceof Element &&
        implicit_event_types.indexOf(type) === -1) {
      handle_event(event, ...args);
    }
  } else {
    console.warn('b8r.trigger called with no specified target');
  }
};

const handle_event = evt => {
  var target = anyElement;
  var keystroke = evt instanceof KeyboardEvent ? keys.keystroke(evt) : {};
  while (target) {
    var handlers = getParsedEventHandlers(target);
    var result = false;
    for (var i = 0; i < handlers.length; i++) {
      var handler = handlers[i];
      for (var type_index = 0; type_index < handler.types.length;
           type_index++) {
        if (handler.types[type_index] === evt.type &&
            (!handler.type_args[type_index] ||
             handler.type_args[type_index].indexOf(keystroke) > -1)) {
          if (handler.model && handler.method) {
            if (handler.model === '_component_') {
              handler.model = get_component_with_method(target, handler.method);
            }
            if (handler.model) {
              result = callMethod(handler.model, handler.method, evt, target);
            } else {
              console.warn(`_component_.${handler.method} not found`, target);
            }
          } else {
            console.error('incomplete event handler on', target);
            break;
          }
          if (result !== true) {
            evt.stopPropagation();
            evt.preventDefault();
            return;
          }
        }
      }
    }
    target = target === anyElement ? evt.target : target.parentElement;
  }
};

module.exports = {
  makeHandler,
  getEventHandlers,
  getParsedEventHandlers,
  on, off, enable, disable, dispatch, trigger, callMethod,
  implicit_event_types, get_component_with_method, handle_event, play_saved_messages,
};

<commit_msg>fix — trigger does not explode if its fired against a non-existent element (it warns, as intended)<commit_after>/**
# Events
*/
/* global module, console, window, require, KeyboardEvent */

'use strict';

const {findWithin} = require('./b8r.dom.js');
const {get, registered, call} = require('./b8r.registry.js');
const anyElement = require('./b8r.anyElement.js');
const keys = require('./b8r.keystroke.js');
const {pathSplit} = require('./b8r.byPath.js');

const implicit_event_types = [
  'mousedown', 'mouseup', 'mousemove', 'mouseover', 'mouseout', 'click',
  'mouseleave', 'mouseenter',
  'mousewheel', 'scroll', // FIXEME passive?!
  'dragstart', 'dragenter', 'dragover', 'dragleave', 'dragend', 'drop',
  'transitionend', 'animationend',
  'input', 'change',
  'keydown', 'keyup',
  'focus', 'blur' // more to follow
];

const onOffArgs = args => {
  var element, event_type, object, method, prepend = false;
  if(typeof args[2] === 'object') {
    console.warn('b8r.on(element, type, OBJECT) is deprecated');
    [element, event_type, object] = args;
    return on(element, event_type, object.model, object.method);
  } else if(args.length > 4 || typeof args[3] === 'string') {
    [element, event_type, object, method, prepend] = args;
    if(typeof object !== 'string' || typeof method !== 'string') {
      console.error('implicit bindings are by name, not', object, method);
      return;
    }
    method = object + '.' + method;
  } else {
    [element, event_type, method, prepend] = args;
  }
  if (!(element instanceof Element)) {
    console.error('bind bare elements please, not', element);
    throw 'bad argument';
  }
  return {element, event_type, path: method, prepend};
};

const getEventHandlers = (element) => {
  const source = element.getAttribute('data-event');
  const existing = source ?
                   source.
                   replace(/\s*(^|$|[,:;])\s*/g, '$1').split(';').
                   filter(handler => handler.trim()) :
                   [];
  return existing;
};

/**

    b8r.getParsedEventHandlers(element)

returns an array of parsed implicit event handlers for an element, e.g.

    data-event="type1:model1.method1;type2,type3:model2.method2"

is returned as

    [
      { types: ["type1"], model: "model1", method: "method1"},
      { types: ["type2", "type3"], model: "model2", method: "method2"}
    ]
*/

const getParsedEventHandlers = element => {
  var handlers = getEventHandlers(element);
  return handlers.map(function(instruction){
    var [type, handler] = instruction.split(':');
    if (!handler) {
      if(instruction.indexOf('.')) {
        console.error('bad event handler (missing event type)', instruction, 'in', element);
      } else {
        console.error('bad event handler (missing handler)', instruction, 'in', element);
      }
      return { types: [] };
    }
    var [model, method] = handler.trim().split('.');
    var types = type.split(',').sort();
    return {
      types: types.map(s => s.split('(')[0].trim()),
      type_args: types.map(s => {
        if (s.substr(0,3) === 'key') {
          s = s.replace(/Key|Digit/g, '');
        }
        var args = s.match(/\(([^)]+)\)/);
        return args && args[1] ? args[1].split(',') : false;
      }),
      model,
      method,
    };
  });
};

const makeHandler = (event_type, method) => {
  if (typeof event_type === 'string') {
    event_type = [event_type];
  }
  if(!Array.isArray(event_type)) {
    console.error('makeHandler failed; bad event_type', event_type);
    return;
  }
  return event_type.sort().join(',') + ':' + method;
};

/**
    on(element, event_type, model_name, method_name);

creates an implicit event-binding data attribute:

    data-event="event_type:module_name.method_name"

Multiple handlers are semicolon-delimited, e.g.

    data-event="mouseover:_component_.show;mouseover:_component_.hide"

You can bind multiple event types separated by commas, e.g.

    data-event="click,keyup:do.something"

**Note**: if you link two event types to the same method separately they will NOT be collated.

You can remove an implicit event binding using:

    off(element, event_type, model_name, method_name);

### Keyboard Events

To make it easy to handle specific keystrokes, you can bind to keystrokes by name, e.g.

    data-bind="keydown(meta-KeyS)"

For your convenience, there's a *Keyboard Event Utility*.
*/

const on = (...args) => {
  const {element, event_type, path, prepend} = onOffArgs(args);
  const handler = makeHandler(event_type, path);
  const existing = getEventHandlers(element);
  if(existing.indexOf(handler) === -1) {
    if (prepend) {
      existing.unshift(handler);
    } else {
      existing.push(handler);
    }
  }
  element.setAttribute('data-event', existing.join(';'));
};

const off = (...args) => {
  var element, event_type, object, method;
  if(args.length === 4) {
    [element, event_type, object, method] = args;
    method = object + '.' + method;
  } else if (args.length === 3) {
    [element, event_type, method] = args;
  } else {
    throw 'b8r.off requires three or four arguments';
  }
  const existing = element.getAttribute('data-event').split(';');
  const handler = makeHandler(event_type, method);
  const idx = existing.indexOf(handler);
  if (idx > -1) {
    existing.splice(idx, 1);
    if (existing.length) {
      element.setAttribute('data-event', existing.join(';'));
    } else {
      element.removeAttribute('data-event');
    }
  }
};

/**
## Enabling and Disabling Event Handlers

Convenience methods for (temporarily) enabling and disabling event handlers.

Will not play nicely with event handler creation / removal.

    enable(element);

Returns data-event-disabled attributes to data-event attributes.

    disable(element);

Finds all data-event bindings on elements within the specified target and
turns them into data-event-disabled attributes;
*/

const disable = within_elt => {
  findWithin(within_elt, '[data-event]').forEach(elt => {
    elt.setAttribute('data-event-disabled', elt.getAttribute('data-event'));
    elt.removeAttribute('data-event');
  });
};

const enable = within_elt => {
  findWithin(within_elt, '[data-event-disabled]').forEach(elt => {
    elt.setAttribute('data-event', elt.getAttribute('data-event-disabled'));
    elt.removeAttribute('data-event-disabled');
  });
};

const dispatch = (type, target) => {
  const event = new Event(type);
  target.dispatchEvent(event);
  return event;
};

// add touch events if needed
if (window.TouchEvent) {
  ['touchstart', 'touchcancel', 'touchmove', 'touchend'].forEach(
      type => implicit_event_types.push(type));
}

const get_component_with_method = function(element, path) {
  var component_id = false;
  element = element.closest('[data-component-id]');
  while (element instanceof Element) {
    if (get(`${element.getAttribute('data-component-id')}.${path}`) instanceof Function) {
      component_id = element.getAttribute('data-component-id');
      break;
    }
    element = element.parentElement.closest('[data-component-id]');
  }
  return component_id;
};

/**
    b8r.callMethod(method_path, ...args)
    b8r.callMethod(model, method, ...args);

Call a method by name from a registered method. If the relevant model has not
yet been registered (e.g. it's being loaded asynchronously) it will get the
message when it's registered.
*/

var saved_messages = [];  // {model, method, evt}

function saveMethodCall(model, method, args) {
  saved_messages.push({model, method, args});
}

const play_saved_messages = for_model => {
  var playbackQueue = [];
  for (var i = saved_messages.length - 1; i >= 0; i--) {
    if (saved_messages[i].model === for_model) {
      playbackQueue.push(saved_messages[i]);
      saved_messages.splice(i, 1);
    }
  }
  while (playbackQueue.length) {
    var {model, method, args} = playbackQueue.pop();
    callMethod(model, method, ...args);
  }
};

const callMethod = (...args) => {
  var model, method;
  try {
    if (args[0].match(/[\[.]/)) {
      [method, ...args] = args;
      [model, method] = pathSplit(method);
    } else {
      [model, method, ...args] = args;
    }
  } catch (e) {
    debugger;  // jshint ignore:line
  }
  var result = null;
  if (registered(model)) {
    result = call(`${model}.${method}`, ...args);
  } else {
    // TODO queue if model not available
    // event is stopped from further propagation
    // provide global wrappers that can e.g. put up a spinner then call the
    // method
    saveMethodCall(model, method, args);
  }
  return result;
};

/**
    b8r.trigger(type, target, ...args); //

Trigger a synthetic implicit (only!) event. Note that you can trigger and
handle completely made-up events, but if you trigger events that occur
naturally the goal is for them to be handled exactly as if they were "real".
*/

const trigger = (type, target, ...args) => {
  if (
    typeof type !== 'string' ||
    (target && !(target.dispatchEvent instanceof Function))
  ) {
    console.error(
      'expected trigger(event_type, target_element)',
      type,
      target
    );
  }
  if (target) {
    const event = dispatch(type, target);
    if (target instanceof Element &&
        implicit_event_types.indexOf(type) === -1) {
      handle_event(event, ...args);
    }
  } else {
    console.warn('b8r.trigger called with no specified target');
  }
};

const handle_event = evt => {
  var target = anyElement;
  var keystroke = evt instanceof KeyboardEvent ? keys.keystroke(evt) : {};
  while (target) {
    var handlers = getParsedEventHandlers(target);
    var result = false;
    for (var i = 0; i < handlers.length; i++) {
      var handler = handlers[i];
      for (var type_index = 0; type_index < handler.types.length;
           type_index++) {
        if (handler.types[type_index] === evt.type &&
            (!handler.type_args[type_index] ||
             handler.type_args[type_index].indexOf(keystroke) > -1)) {
          if (handler.model && handler.method) {
            if (handler.model === '_component_') {
              handler.model = get_component_with_method(target, handler.method);
            }
            if (handler.model) {
              result = callMethod(handler.model, handler.method, evt, target);
            } else {
              console.warn(`_component_.${handler.method} not found`, target);
            }
          } else {
            console.error('incomplete event handler on', target);
            break;
          }
          if (result !== true) {
            evt.stopPropagation();
            evt.preventDefault();
            return;
          }
        }
      }
    }
    target = target === anyElement ? evt.target : target.parentElement;
  }
};

module.exports = {
  makeHandler,
  getEventHandlers,
  getParsedEventHandlers,
  on, off, enable, disable, dispatch, trigger, callMethod,
  implicit_event_types, get_component_with_method, handle_event, play_saved_messages,
};

<|endoftext|>


<commit_before>(function () {
	"use strict";

	angular.module("ngMobileDialog", []).provider("$dialog", function () {
		var vm = this;
		vm.multiple = false;
		vm.currentScopes = {};
		vm.$get = function ($timeout, $compile, $rootScope, $controller, $injector, $q, $http, $templateCache) {

			function Dialog(opts, modalEl) {
				this.options = opts;
				this.modalEl = modalEl;
			}

			Dialog.prototype.open = function () {
				var self = this;
				var $body = angular.element("body");
				var $backdrop = angular.element(".dialog-backdrop");

				this._loadResolves().then(function (locals) {
					try{
						var $scope = locals.$scope = locals.$scope ? locals.$scope : $rootScope.$new();
						$scope.dialogId = new Date();
						vm.currentScopes[$scope.dialogId] = $scope;

						if (self.options.controller) {
							var ctrl = $controller(self.options.controller, locals);
							self.modalEl.data("ngControllerController", ctrl);
						}

						self.modalEl.addClass("dialog");

						var $modal = $compile(self.modalEl)($scope).find(".dialog").prevObject;

						$scope.options = self.options;

						var backdrop = self.options.backdrop === false ? false : true;

						if (backdrop) {
							$backdrop.on("click", function () {
								$scope.resolve();
							});
						}

						$scope.resolve = function (result) {
							delete vm.currentScopes[$scope.dialogId];
							self.deferred.resolve(result);
							self.deferred = null;
							$modal.removeClass("active");

							$timeout(function () {
								$scope.$destroy();
								vm.currentDialog = null;
							}, 100);
						};

						$scope.$on("$destroy", function () {
							$modal.remove();
							$backdrop.remove();
							$body.off("keypress");
							$body.trigger("hidden.ngMobileDialog");
						});

						$scope.$on("$locationChangeSuccess", function () {
							$modal.removeClass("active");
						});

						$timeout(function () {
							$modal.addClass("active");
							$backdrop.addClass("in");
							$body.on("keypress", function (e) {
								if (e.keyCode === 13) {
									e.preventDefault();
								}
							});
						}, 50);
					}catch(ex){
						console.log(ex);
					}
				});

				this.deferred = $q.defer();
				return this.deferred.promise;
			};

			Dialog.prototype._loadResolves = function () {
				var values = [];
				var keys = [];

				angular.forEach(this.options.resolve || [], function (value, key) {
					keys.push(key);
					values.push(angular.isString(value) ? $injector.get(value) : $injector.invoke(value));
				});

				return $q.all(values).then(function (values) {
					var locals = {};
					angular.forEach(values, function (value, index) {
						locals[keys[index]] = value;
					});

					return locals;
				});
			};

			return {
				create: function (opts, callback) {
					if (!this.multiple && angular.element(".dialog").length) {
						return;
					}

					if (!opts.template && !opts.templateUrl) {
						throw new Error("Template or template url must be informed!");
					}

					var templateCache = null;

					if (opts.templateUrl) {
						templateCache = $templateCache.get(opts.templateUrl);

						if (templateCache) {
							setElements(templateCache);
							return;
						}
					}

					if (opts.template && !opts.templateUrl) {
						setElements(opts.template);
						return;
					}

					$http.get(opts.templateUrl, {})
					.success(function(data) {
						setElements(data);
						$templateCache.put(opts.templateUrl, data);
				  	}).error(function() {
						throw new Error("Can not load dialog template from url: " + opts.templateUrl);
				  	});

					function setElements (template) {
						var backdrop = "\n

";

						var modalEl = angular.element("
");
						modalEl.html(template);

						angular.element("body").append(modalEl).append(backdrop);

						var dialog = new Dialog(opts, modalEl);

						callback(dialog);
					}
				},
				multiple: this.multiple,
				resolve: function (result){
					if(vm.currentScopes){
						for (var key in vm.currentScopes) {
						   if (vm.currentScopes.hasOwnProperty(key)) {
							   var obj = vm.currentScopes[key];
								obj.resolve(result);
							}
						}
					}
				}
			};
		};
	});
})();
<commit_msg>add support for custom headers in dialog<commit_after>(function () {
	"use strict";

	angular.module("ngMobileDialog", []).provider("$dialog", function () {
		var vm = this;
		vm.multiple = false;
		vm.headers = {};
		vm.currentScopes = {};
		vm.$get = function ($timeout, $compile, $rootScope, $controller, $injector, $q, $http, $templateCache) {

			function Dialog(opts, modalEl) {
				this.options = opts;
				this.modalEl = modalEl;
			}

			Dialog.prototype.open = function () {
				var self = this;
				var $body = angular.element("body");
				var $backdrop = angular.element(".dialog-backdrop");

				this._loadResolves().then(function (locals) {
					try{
						var $scope = locals.$scope = locals.$scope ? locals.$scope : $rootScope.$new();
						$scope.dialogId = new Date();
						vm.currentScopes[$scope.dialogId] = $scope;

						if (self.options.controller) {
							var ctrl = $controller(self.options.controller, locals);
							self.modalEl.data("ngControllerController", ctrl);
						}

						self.modalEl.addClass("dialog");

						var $modal = $compile(self.modalEl)($scope).find(".dialog").prevObject;

						$scope.options = self.options;

						var backdrop = self.options.backdrop === false ? false : true;

						if (backdrop) {
							$backdrop.on("click", function () {
								$scope.resolve();
							});
						}

						$scope.resolve = function (result) {
							delete vm.currentScopes[$scope.dialogId];
							self.deferred.resolve(result);
							self.deferred = null;
							$modal.removeClass("active");

							$timeout(function () {
								$scope.$destroy();
								vm.currentDialog = null;
							}, 100);
						};

						$scope.$on("$destroy", function () {
							$modal.remove();
							$backdrop.remove();
							$body.off("keypress");
							$body.trigger("hidden.ngMobileDialog");
						});

						$scope.$on("$locationChangeSuccess", function () {
							$modal.removeClass("active");
						});

						$timeout(function () {
							$modal.addClass("active");
							$backdrop.addClass("in");
							$body.on("keypress", function (e) {
								if (e.keyCode === 13) {
									e.preventDefault();
								}
							});
						}, 50);
					}catch(ex){
						console.log(ex);
					}
				});

				this.deferred = $q.defer();
				return this.deferred.promise;
			};

			Dialog.prototype._loadResolves = function () {
				var values = [];
				var keys = [];

				angular.forEach(this.options.resolve || [], function (value, key) {
					keys.push(key);
					values.push(angular.isString(value) ? $injector.get(value) : $injector.invoke(value));
				});

				return $q.all(values).then(function (values) {
					var locals = {};
					angular.forEach(values, function (value, index) {
						locals[keys[index]] = value;
					});

					return locals;
				});
			};

			return {
				create: function (opts, callback) {
					if (!this.multiple && angular.element(".dialog").length) {
						return;
					}

					if (!opts.template && !opts.templateUrl) {
						throw new Error("Template or template url must be informed!");
					}

					var templateCache = null;

					if (opts.templateUrl) {
						templateCache = $templateCache.get(opts.templateUrl);

						if (templateCache) {
							setElements(templateCache);
							return;
						}
					}

					if (opts.template && !opts.templateUrl) {
						setElements(opts.template);
						return;
					}

					$http.get(opts.templateUrl, {
						headers: this.headers
					})
					.success(function(data) {
						setElements(data);
						$templateCache.put(opts.templateUrl, data);
				  	}).error(function() {
						throw new Error("Can not load dialog template from url: " + opts.templateUrl);
				  	});

					function setElements (template) {
						var backdrop = "\n

";

						var modalEl = angular.element("
");
						modalEl.html(template);

						angular.element("body").append(modalEl).append(backdrop);

						var dialog = new Dialog(opts, modalEl);

						callback(dialog);
					}
				},
				multiple: this.multiple,
				headers: this.headers,
				resolve: function (result){
					if(vm.currentScopes){
						for (var key in vm.currentScopes) {
						   if (vm.currentScopes.hasOwnProperty(key)) {
							   var obj = vm.currentScopes[key];
								obj.resolve(result);
							}
						}
					}
				}
			};
		};
	});
})();
<|endoftext|>


<commit_before>'use strict';

/**
 * An object representing one audio sample.
 * @param {string} filename Name of the audio file without a file extension. Assumes that the audio file is located
 * in Audio.audioPath.
 * @param {boolean=} isLooping Whether the sample should loop when played. Defaults to false.
 * @param {Array.<string>} fileExtensions Array of extensions. Defaults to ogg and mp3, which should be enough for
 * cross-browser compatibility.
 * @constructor
 */
var Audio = function(filename, isLooping, fileExtensions) {
    if (isLooping === undefined) {
        isLooping = false;
    }
    if (fileExtensions === undefined) {
        fileExtensions = ['ogg', 'mp3'];
    }
    this.loaded = false;
    this.playWhenLoaded = false;
    this.audio = document.createElement('audio');
    this.audio.loop = isLooping;
    this.filenames = [];
    for (var i = 0; i < fileExtensions.length; ++i) {
        this.filenames.push(filename + '.' + fileExtensions[i]);
    }
    this.addSourcesTo(this.audio);
    this.clones = [];
};

/**
 * Path for audio files. Set this before creating any Audio objects.
 */
Audio.audioPath = 'assets/sounds/';

/**
 * @param {HTMLAudioElement} audioElement Element to add audio sources to.
 * @protected
 */
Audio.prototype.addSourcesTo = function(audioElement) {
    for (var i = 0; i < this.filenames.length; ++i) {
        var source = document.createElement('source');
        source.src = Audio.audioPath + this.filenames[i];
        audioElement.appendChild(source);
    }
};

/**
 * Play a clone of this sample. Will not affect other clones, and playback can not be stopped.
 */
Audio.prototype.playClone = function () {
    if (this.audio.readyState < 4) {
        return;
    }
    for (var i = 0; i < this.clones.length; ++i) {
        if (this.clones[i].ended) {
            this.clones[i].currentTime = 0;
            this.clones[i].play();
            return;
        }
    }
    var clone = document.createElement('audio');
    this.addSourcesTo(clone);
    this.clones.push(clone);
    clone.play();
};

/**
 * Play this sample when it is ready. Use only if only one copy of this sample is going to play simultaneously.
 */
Audio.prototype.play = function () {
    if (this.audio.readyState === 4) {
        this.audio.play();
    } else {
        var that = this.audio;
        this.audio.oncanplay = function() {
            that.play();
        };
    }
};

/**
 * Stop playing this sample.
 */
Audio.prototype.stop = function () {
    this.audio.pause();
    this.audio.currentTime = 0;
};
<commit_msg>Improvements to the Audio class<commit_after>'use strict';

/**
 * An object representing one audio sample.
 * @param {string} filename Name of the audio file without a file extension. Assumes that the audio file is located
 * in Audio.audioPath.
 * @param {Array.<string>} fileExtensions Array of extensions. Defaults to ogg and mp3, which should be enough for
 * cross-browser compatibility.
 * @constructor
 */
var Audio = function(filename, fileExtensions) {
    if (fileExtensions === undefined) {
        fileExtensions = ['ogg', 'mp3'];
    }
    this.loaded = false;
    this.playWhenLoaded = false;
    this.audio = document.createElement('audio');
    this.filenames = [];
    for (var i = 0; i < fileExtensions.length; ++i) {
        this.filenames.push(filename + '.' + fileExtensions[i]);
    }
    this.addSourcesTo(this.audio);
    this.clones = [];
    this.ensureOneClone();
};

/**
 * Path for audio files. Set this before creating any Audio objects.
 */
Audio.audioPath = 'assets/sounds/';

/**
 * @param {HTMLAudioElement} audioElement Element to add audio sources to.
 * @protected
 */
Audio.prototype.addSourcesTo = function(audioElement) {
    for (var i = 0; i < this.filenames.length; ++i) {
        var source = document.createElement('source');
        source.src = Audio.audioPath + this.filenames[i];
        audioElement.appendChild(source);
    }
};

/**
 * Play a clone of this sample. Will not affect other clones. Playback will not loop and playback can not be stopped.
 */
Audio.prototype.play = function () {
    if (this.audio.readyState < 4) {
        return;
    }
    var clone = this.ensureOneClone();
    clone.play();
    this.ensureOneClone(); // Make another clone ready ahead of time.
};

/**
 * Play this sample when it is ready. Use only if only one copy of this sample is going to play simultaneously.
 * Playback can be stopped by calling stop().
 * @param {boolean=} loop Whether the sample should loop when played. Defaults to false.
 */
Audio.prototype.playSingular = function (loop) {
    if (loop === undefined) {
        this.audio.loop = false;
    } else {
        this.audio.loop = loop;
    }
    if (this.audio.readyState === 4) {
        this.audio.play();
    } else {
        var that = this.audio;
        this.audio.oncanplay = function() {
            that.play();
        };
    }
};

/**
 * Stop playing this sample.
 */
Audio.prototype.stop = function () {
    this.audio.pause();
    this.audio.currentTime = 0;
};

/**
 * Ensure that there is one clone available for playback and return it.
 * @protected
 * @return {HTMLAudioElement} Clone that is ready for playback.
 */
Audio.prototype.ensureOneClone = function() {
    for (var i = 0; i < this.clones.length; ++i) {
        if (this.clones[i].ended) {
            this.clones[i].currentTime = 0;
            return this.clones[i];
        }
    }
    var clone = document.createElement('audio');
    this.addSourcesTo(clone);
    this.clones.push(clone);
    return clone;
};
<|endoftext|>


<commit_before>var wav_1_minute = 'RFPT-WW13-20111229213002-540-60-KR8.wav';
var wav_15_minute = "RFPT-WW10A-2013-02-14T02.00.10-KR5.wav";

function fill_canvas(wav){
    var canvas = document.getElementById('fft');
    var context = canvas.getContext('2d');
    var width = canvas.width;
    var spacing = wav.length / width;
    var window_size = 1024;
    var fft = new FFT(window_size, wav.sampleRate);
    //context.fillRect(50, 25, 150, 100);
    var imgdata = context.createImageData(canvas.width, canvas.height);
    var pixels = imgdata.data;
    var i;
    var left, col;
    var audio = wav.channels[0];
    var mask_window = new Float32Array(window_size);
    var data_window = new Float32Array(window_size);
    var tau_norm = Math.PI * 2 / window_size;
    for (i = 0; i < window_size; i++){
        mask_window[i] = 0.5 - 0.5 * Math.cos(tau_norm * i);
    }

    for (left = 0, col = 0; left + window_size < wav.length; left += spacing, col++){
        var square_window = audio.subarray(left, left + window_size);
        for (i = 0; i < window_size; i++){
            data_window[i] = square_window[i] * mask_window[i];
        }
        fft.forward(data_window);
        var s = fft.spectrum;
        for (i = canvas.height - 1; i >= 0; i--){
            var o = ((canvas.height - i - 1) * width + col) * 4;
            var v = s[i] * s[i] + s[i + 1] * s[i + 1] * 10;
            //pixels[o] = Math.pow(Math.max(v - 1e-7, 0), 0.33) * 1e4;
            pixels[o] = 256 - 1e-4 / (v + 1e-12);
            pixels[o + 1] = Math.sqrt(v) * 1e5;
            pixels[o + 2] = Math.pow(v, 0.25) * 3e3;
            pixels[o + 3] = 255;
        }
        //console.log(col, v, s[200], spacing, pixels[o]);
    }
    context.putImageData(imgdata, 0, 0);
}

function message(m){
    var el = document.getElementById('message');
    el.innerHTML += "
" +  m + "
";
}

function on_page_load() {
    if (document.location.protocol == 'file:'){
        message("Warning: this probably won't work from the local filesystem " +
                "(<tt>file://</tt> protocol), due to browser security settings. " +
                "
Use a local webserver, like webfsd.");
    }
    var request = new AudioFileRequest(wav_1_minute);
    request.onSuccess = function(decoded) {
        fill_canvas(decoded);
    };
    request.onFailure = function() {
        alert("bad ");
    };
    request.send();
}

window.addEventListener('load', on_page_load);
<commit_msg>basic drawing on the canvas<commit_after>var wav_1_minute = 'RFPT-WW13-20111229213002-540-60-KR8.wav';
var wav_15_minute = "RFPT-WW10A-2013-02-14T02.00.10-KR5.wav";

var drawing = 0;

function fill_canvas(wav){
    var canvas = document.getElementById('fft');
    var context = canvas.getContext('2d');
    var width = canvas.width;
    var spacing = wav.length / width;
    var window_size = 1024;
    var fft = new FFT(window_size, wav.sampleRate);
    //context.fillRect(50, 25, 150, 100);
    var imgdata = context.createImageData(canvas.width, canvas.height);
    var pixels = imgdata.data;
    var i;
    var left, col;
    var audio = wav.channels[0];
    var mask_window = new Float32Array(window_size);
    var data_window = new Float32Array(window_size);
    var tau_norm = Math.PI * 2 / window_size;
    for (i = 0; i < window_size; i++){
        mask_window[i] = 0.5 - 0.5 * Math.cos(tau_norm * i);
    }

    for (left = 0, col = 0; left + window_size < wav.length; left += spacing, col++){
        var square_window = audio.subarray(left, left + window_size);
        for (i = 0; i < window_size; i++){
            data_window[i] = square_window[i] * mask_window[i];
        }
        fft.forward(data_window);
        var s = fft.spectrum;
        for (i = canvas.height - 1; i >= 0; i--){
            var o = ((canvas.height - i - 1) * width + col) * 4;
            var v = s[i] * s[i] + s[i + 1] * s[i + 1] * 10;
            //pixels[o] = Math.pow(Math.max(v - 1e-7, 0), 0.33) * 1e4;
            pixels[o] = 256 - 1e-4 / (v + 1e-12);
            pixels[o + 1] = Math.sqrt(v) * 1e5;
            pixels[o + 2] = Math.pow(v, 0.25) * 3e3;
            pixels[o + 3] = 255;
        }
        //console.log(col, v, s[200], spacing, pixels[o]);
    }
    context.putImageData(imgdata, 0, 0);
    function draw_to(x, y, colour){
        context.lineTo(x, y);
        context.stroke();
    }
    canvas.onmousedown = function(e){
        drawing = 1;
        var x = e.pageX - this.offsetLeft;
        var y = e.pageY - this.offsetTop;
        context.beginPath();
        context.lineWidth = 5;
	context.lineJoin = 'round';
        context.strokeStyle = "#0ff";
        context.moveTo(x, y);
        draw_to(x, y);
    };
    document.onmouseup = function(e){
        drawing = 0;
    };
    canvas.onmousemove = function(e){
        if (drawing){
            draw_to(e.pageX - this.offsetLeft,
                    e.pageY - this.offsetTop);
        }
    };
}

function message(m){
    var el = document.getElementById('message');
    el.innerHTML += "
" +  m + "
";
}

function on_page_load() {
    if (document.location.protocol == 'file:'){
        message("Warning: this probably won't work from the local filesystem " +
                "(<tt>file://</tt> protocol), due to browser security settings. " +
                "
Use a local webserver, like webfsd.");
    }
    var request = new AudioFileRequest(wav_1_minute);
    request.onSuccess = function(decoded) {
        fill_canvas(decoded);
    };
    request.onFailure = function() {
        alert("bad ");
    };
    request.send();
}

window.addEventListener('load', on_page_load);
<|endoftext|>


<commit_before>import React from 'react';
import { shallow } from 'enzyme';

import { ManagedNumberField } from '../../../forms/inputs';
import { isNonNegNumber, hasOnlyNonNegNumberChars } from '../../../utils/validators';

test('ManagedNumberField should match snapshot', () => {
  const wrapper = shallow(
    <ManagedNumberField
      format={ () => {} }
      value={ 0 }
      name={ `test` }
      otherData={{ interval: `monthly` }} />
  );
  expect(wrapper).toMatchSnapshot();
});

test('should set focused state to true on focus if current value of FormInput is positive number', () => {
  const value = 10;
  const wrapper = shallow(
    <ManagedNumberField
      format={ () => {} }
      value={ value }
      otherData={{ interval: `monthly` }} />
  );
  wrapper.find('FormInput').simulate('focus', { target: { value }});
  expect(wrapper.state('focused')).toBe(true);
});

test('should set focused state to true on focus if current value of FormInput is 0', () => {
  const value = 0;
  const wrapper = shallow(
    <ManagedNumberField
      format={ () => {} }
      value={ value }
      otherData={{ interval: `monthly` }} />
  );
  wrapper.find('FormInput').simulate('focus', { target: { value }});
  expect(wrapper.state('focused')).toBe(true);
});

test('should blank focusedVal state before focus if current value of FormInput is 0', () => {
  const inputValue = 0;
  const wrapper = shallow(
    <ManagedNumberField
      format={ () => {} }
      value={ 0 }
      otherData={{ interval: `monthly` }} />
  );
  wrapper.find('FormInput').simulate('focus', { target: { value: inputValue }});
  expect(wrapper.state('focusedVal')).toBe('');
});

test('should set focused state to false on blur', () => {
  const value = 10;
  const wrapper = shallow(
    <ManagedNumberField
      format={ () => {} }
      value={ value }
      otherData={{ interval: `monthly` }} />
  );
  wrapper.setState({ focused: true });
  wrapper.find('FormInput').simulate('blur', { target: { value }});
  expect(wrapper.state('focused')).toBe(false);
});

test('should change local and app state correctly when user inputs positive number', () => {
  const mockValidator = jest.fn();
  const mockStore = jest.fn();

  // Define the test case here
  const userInput = 5;
  mockValidator.mockReturnValue(true);

  const wrapper = shallow(
    <ManagedNumberField
      format={ () => {} }
      otherData={ null }
      store={ mockStore }
      storeValidator={ mockValidator }
      displayValidator={ mockValidator }
      value={ 0 }
      otherData={{ interval: `monthly` }} />
  );
  wrapper.find('FormInput').simulate('change', {}, { value: userInput });

  // sending the proper call to change the application's state
  // TODO: Determine whether the 1st and 3rd arguments should be checked w/ Enzyme too
  expect(mockStore.mock.calls[ 0 ][ 1 ]).toEqual({ value: userInput });

  // changes to this.state's focusedVal and valid variables
  expect(wrapper.state('focusedVal')).toBe(userInput);
  expect(wrapper.state('valid')).toBe(true);
});

test('should change local and app state correctly when user inputs empty string', () => {
  const mockValidator = jest.fn();
  const mockStore = jest.fn();

  // Define the test case here
  const userInput = '';
  mockValidator.mockReturnValue(true);

  const wrapper = shallow(
    <ManagedNumberField
      format={ () => {} }
      otherData={ null }
      store={ mockStore }
      displayValidator={ mockValidator }
      storeValidator={ mockValidator }
      value={ 0 }
      otherData={{ interval: `monthly` }} />
  );
  wrapper.find('FormInput').simulate('change', {}, { value: userInput });

  // sending the proper call to change the application's state
  // Since userInput is empty string, store should be given 0 as value
  expect(mockStore.mock.calls[ 0 ][ 1 ]).toEqual({ value: '0' });

  // changes to this.state's focusedVal and valid variables
  expect(wrapper.state('focusedVal')).toBe(userInput);
  expect(wrapper.state('valid')).toBe(true);
});

test('should change local and app state correctly when user inputs negative number', () => {
  const mockStore = jest.fn();

  var mockDisplayValidator = jest.fn();
  mockDisplayValidator.mockImplementation(hasOnlyNonNegNumberChars);

  var mockStoreValidator = jest.fn();
  mockStoreValidator.mockImplementation(isNonNegNumber);

  // Define the test case here
  const userInput1 = 6;
  const userInput2 = -6;

  const wrapper = shallow(
    <ManagedNumberField
      format={ () => {} }
      otherData={ null }
      store={ mockStore }
      displayValidator={ mockDisplayValidator }
      storeValidator={ mockStoreValidator }
      value={ 0 }
      otherData={{ interval: `monthly` }} />
  );
  wrapper.find('FormInput').simulate('change', {}, { value: userInput1 });
  wrapper.find('FormInput').simulate('change', {}, { value: userInput2 });

  // expect that the store has not been called
  expect(mockStore.mock.calls).toHaveLength(1);

  // changes to this.state's focusedVal and valid variables
  expect(wrapper.state('focusedVal')).toBe(userInput1);
  expect(wrapper.state('valid')).toBe(true);
});

test('should set FormInput error state properly when valid condition changes', () => {
  const wrapper = shallow(
    <ManagedNumberField
      format={ () => {} }
      value={ 0 }
      otherData={{ interval: `monthly` }} />
  );
  // Set valid to false -- FormInput error should be true
  wrapper.setState({ valid: false });
  expect(wrapper.find('FormInput').props().error).toBe(true);
  // Set valid back to true -- FormInput error should be false
  wrapper.setState({ valid: true });
  expect(wrapper.find('FormInput').props().error).toBe(false);
});
<commit_msg>When did these tests start having warnings?<commit_after>import React from 'react';
import { shallow } from 'enzyme';

import { ManagedNumberField } from '../../../forms/inputs';
import { isNonNegNumber, hasOnlyNonNegNumberChars } from '../../../utils/validators';

test('ManagedNumberField should match snapshot', () => {
  const wrapper = shallow(
    <ManagedNumberField
      format={ () => {} }
      value={ 0 }
      name={ `test` }
      otherData={{ interval: `monthly` }} />
  );
  expect(wrapper).toMatchSnapshot();
});

test('should set focused state to true on focus if current value of FormInput is positive number', () => {
  const value = 10;
  const wrapper = shallow(
    <ManagedNumberField
      format={ () => {} }
      value={ value }
      otherData={{ interval: `monthly` }} />
  );
  wrapper.find('FormInput').simulate('focus', { target: { value }});
  expect(wrapper.state('focused')).toBe(true);
});

test('should set focused state to true on focus if current value of FormInput is 0', () => {
  const value = 0;
  const wrapper = shallow(
    <ManagedNumberField
      format={ () => {} }
      value={ value }
      otherData={{ interval: `monthly` }} />
  );
  wrapper.find('FormInput').simulate('focus', { target: { value }});
  expect(wrapper.state('focused')).toBe(true);
});

test('should blank focusedVal state before focus if current value of FormInput is 0', () => {
  const inputValue = 0;
  const wrapper = shallow(
    <ManagedNumberField
      format={ () => {} }
      value={ 0 }
      otherData={{ interval: `monthly` }} />
  );
  wrapper.find('FormInput').simulate('focus', { target: { value: inputValue }});
  expect(wrapper.state('focusedVal')).toBe('');
});

test('should set focused state to false on blur', () => {
  const value = 10;
  const wrapper = shallow(
    <ManagedNumberField
      format={ () => {} }
      value={ value }
      otherData={{ interval: `monthly` }} />
  );
  wrapper.setState({ focused: true });
  wrapper.find('FormInput').simulate('blur', { target: { value }});
  expect(wrapper.state('focused')).toBe(false);
});

test('should change local and app state correctly when user inputs positive number', () => {
  const mockValidator = jest.fn();
  const mockStore = jest.fn();

  // Define the test case here
  const userInput = 5;
  mockValidator.mockReturnValue(true);

  const wrapper = shallow(
    <ManagedNumberField
      format={ () => {} }
      store={ mockStore }
      storeValidator={ mockValidator }
      displayValidator={ mockValidator }
      value={ 0 }
      otherData={{ interval: `monthly` }} />
  );
  wrapper.find('FormInput').simulate('change', {}, { value: userInput });

  // sending the proper call to change the application's state
  // TODO: Determine whether the 1st and 3rd arguments should be checked w/ Enzyme too
  expect(mockStore.mock.calls[ 0 ][ 1 ]).toEqual({ value: userInput });

  // changes to this.state's focusedVal and valid variables
  expect(wrapper.state('focusedVal')).toBe(userInput);
  expect(wrapper.state('valid')).toBe(true);
});

test('should change local and app state correctly when user inputs empty string', () => {
  const mockValidator = jest.fn();
  const mockStore = jest.fn();

  // Define the test case here
  const userInput = '';
  mockValidator.mockReturnValue(true);

  const wrapper = shallow(
    <ManagedNumberField
      format={ () => {} }
      store={ mockStore }
      displayValidator={ mockValidator }
      storeValidator={ mockValidator }
      value={ 0 }
      otherData={{ interval: `monthly` }} />
  );
  wrapper.find('FormInput').simulate('change', {}, { value: userInput });

  // sending the proper call to change the application's state
  // Since userInput is empty string, store should be given 0 as value
  expect(mockStore.mock.calls[ 0 ][ 1 ]).toEqual({ value: '0' });

  // changes to this.state's focusedVal and valid variables
  expect(wrapper.state('focusedVal')).toBe(userInput);
  expect(wrapper.state('valid')).toBe(true);
});

test('should change local and app state correctly when user inputs negative number', () => {
  const mockStore = jest.fn();

  var mockDisplayValidator = jest.fn();
  mockDisplayValidator.mockImplementation(hasOnlyNonNegNumberChars);

  var mockStoreValidator = jest.fn();
  mockStoreValidator.mockImplementation(isNonNegNumber);

  // Define the test case here
  const userInput1 = 6;
  const userInput2 = -6;

  const wrapper = shallow(
    <ManagedNumberField
      format={ () => {} }
      store={ mockStore }
      displayValidator={ mockDisplayValidator }
      storeValidator={ mockStoreValidator }
      value={ 0 }
      otherData={{ interval: `monthly` }} />
  );
  wrapper.find('FormInput').simulate('change', {}, { value: userInput1 });
  wrapper.find('FormInput').simulate('change', {}, { value: userInput2 });

  // expect that the store has not been called
  expect(mockStore.mock.calls).toHaveLength(1);

  // changes to this.state's focusedVal and valid variables
  expect(wrapper.state('focusedVal')).toBe(userInput1);
  expect(wrapper.state('valid')).toBe(true);
});

test('should set FormInput error state properly when valid condition changes', () => {
  const wrapper = shallow(
    <ManagedNumberField
      format={ () => {} }
      value={ 0 }
      otherData={{ interval: `monthly` }} />
  );
  // Set valid to false -- FormInput error should be true
  wrapper.setState({ valid: false });
  expect(wrapper.find('FormInput').props().error).toBe(true);
  // Set valid back to true -- FormInput error should be false
  wrapper.setState({ valid: true });
  expect(wrapper.find('FormInput').props().error).toBe(false);
});
<|endoftext|>


<commit_before>#!/usr/bin/env node

(function() {
    'use strict';

    var inline      = require('..'),

        fs          = require('fs'),
        path        = require('path'),

        argv        = process.argv.slice(2),
        arg         = argv[0];

    if (/^(-v|--version)$/.test(arg))
        version();
    else if (!arg || /^(-h|--help)$/.test(arg))
        help();
    else
        main(arg);

    function main(name) {
        fs.readFile(name, 'utf8', function(error, data) {
            var dir = path.dirname(name);

            e(error) || inline(data, dir, function(error, data) {
                e(error) || console.log(data);
            });
        });
    }

    function e(error) {
        if (error)
            console.error(error.message);

        return error;
    }

    function version() {
        console.log('v' + info().version);
    }

    function info() {
        return require('../package');
    }

    function help() {
        var usage       = 'Usage: ' + info().name + ' <file>';

        console.log(usage);
    }
})();
<commit_msg>feature(inline) speed up<commit_after>#!/usr/bin/env node

(function() {
    'use strict';

    var argv        = process.argv.slice(2),
        arg         = argv[0];

    if (/^(-v|--version)$/.test(arg))
        version();
    else if (!arg || /^(-h|--help)$/.test(arg))
        help();
    else
        main(arg);

    function main(name) {
        var inline      = require('..'),
            fs          = require('fs'),
            path        = require('path');

        fs.readFile(name, 'utf8', function(error, data) {
            var dir = path.dirname(name);

            e(error) || inline(data, dir, function(error, data) {
                e(error) || console.log(data);
            });
        });
    }

    function e(error) {
        if (error)
            console.error(error.message);

        return error;
    }

    function version() {
        console.log('v' + info().version);
    }

    function info() {
        return require('../package');
    }

    function help() {
        var usage       = 'Usage: ' + info().name + ' <file>';

        console.log(usage);
    }
})();
<|endoftext|>


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

/**
 * A round push button that draws gradients and such in order to create
 * a somewhat 3D look.
 *
 * @author John Blanco
 */
define( function( require ) {
  'use strict';

  // Includes
  var AbstractButton = require( 'SUN/experimental/buttons/AbstractButton' );
  var Circle = require( 'SCENERY/nodes/Circle' );
  var Color = require( 'SCENERY/util/Color' );
  var inherit = require( 'PHET_CORE/inherit' );
  var RadialGradient = require( 'SCENERY/util/RadialGradient' );
  var Shape = require( 'KITE/Shape' );
  var Vector2 = require( 'DOT/Vector2' );

  // Constants
  var HIGHLIGHT_GRADIENT_LENGTH = 7; // In screen coords, which are roughly pixels.
  var SHADE_GRADIENT_LENGTH = 7; // In screen coords, which are roughly pixels.

  /**
   * @param {Node} content - Node to put on surface of button, could be text, icon, or whatever
   * @param {Object} options
   * @constructor
   */
  function RoundPushButton( content, options ) {

    var thisButton = this;

    options = _.extend( {
      // Default values.
      cursor: 'pointer',
      baseColor: new Color( 153, 206, 255 ),
      disabledBaseColor: new Color( 220, 220, 220 ),
      minXPadding: 5, // Minimum padding in x direction, i.e. on left and right
      minYPadding: 5, // Minimum padding in x direction, i.e. on top and bottom
      listener: null,
      fireOnDown: false,
      touchExpansion: 5 // In screen units (roughly pixels) beyond button's edge.
    }, options );

    AbstractButton.call( thisButton, { listener: options.listener, fireOnDown: options.fireOnDown } );

    var buttonRadius = Math.max( content.width + options.minXPadding * 2, content.height + options.minYPadding * 2 ) / 2;
    var upCenter = Vector2.ZERO;
    var downCenter = upCenter.plus( new Vector2( 0.5, 0.5 ) ); // Displacement empirically determined.
    var baseColor = options.baseColor;
    var disabledBaseColor = options.disabledBaseColor;
    var transparentBaseColor = new Color( baseColor.getRed(), baseColor.getGreen(), baseColor.getBlue(), 0 );
    var transparentDisabledBaseColor = new Color( disabledBaseColor.getRed(), disabledBaseColor.getGreen(), disabledBaseColor.getBlue(), 0 );

    // Create the gradient fills used for various button states
    var upFillHighlight = new RadialGradient( HIGHLIGHT_GRADIENT_LENGTH / 4, HIGHLIGHT_GRADIENT_LENGTH / 4, buttonRadius - HIGHLIGHT_GRADIENT_LENGTH / 2, 0, 0, buttonRadius )
      .addColorStop( 0, baseColor )
      .addColorStop( 1, baseColor.colorUtilsBrighter( 0.7 ) );

    var upFillShadow = new RadialGradient( -SHADE_GRADIENT_LENGTH / 4, -SHADE_GRADIENT_LENGTH / 4, buttonRadius - SHADE_GRADIENT_LENGTH / 2, 0, 0, buttonRadius )
      .addColorStop( 0, transparentBaseColor )
      .addColorStop( 1, baseColor.colorUtilsDarker( 0.5 ) );

    var overFillHighlight = new RadialGradient( HIGHLIGHT_GRADIENT_LENGTH / 4, HIGHLIGHT_GRADIENT_LENGTH / 4, buttonRadius - HIGHLIGHT_GRADIENT_LENGTH / 2, 0, 0, buttonRadius )
      .addColorStop( 0, baseColor.colorUtilsBrighter( 0.4 ) )
      .addColorStop( 1, baseColor.colorUtilsBrighter( 0.8 ) );

    var overFillShadow = new RadialGradient( -SHADE_GRADIENT_LENGTH / 4, -SHADE_GRADIENT_LENGTH / 4, buttonRadius - SHADE_GRADIENT_LENGTH / 2, 0, 0, buttonRadius )
      .addColorStop( 0, transparentBaseColor )
      .addColorStop( 1, baseColor.colorUtilsDarker( 0.5 ) );

    var downFill = new RadialGradient( HIGHLIGHT_GRADIENT_LENGTH / 4, HIGHLIGHT_GRADIENT_LENGTH / 4, 0, 0, 0, buttonRadius )
      .addColorStop( 0, baseColor )
      .addColorStop( 0.5, baseColor )
      .addColorStop( 0.7, baseColor.colorUtilsDarker( 0.1 ) )
      .addColorStop( 0.9, baseColor )
      .addColorStop( 1, baseColor.colorUtilsBrighter( 0.7 ) );

    var disabledFillHighlight = new RadialGradient( HIGHLIGHT_GRADIENT_LENGTH / 4, HIGHLIGHT_GRADIENT_LENGTH / 4, buttonRadius - HIGHLIGHT_GRADIENT_LENGTH / 2, 0, 0, buttonRadius )
      .addColorStop( 0, disabledBaseColor )
      .addColorStop( 1, disabledBaseColor.colorUtilsBrighter( 0.5 ) );

    var disabledFillShadow = new RadialGradient( -SHADE_GRADIENT_LENGTH / 4, -SHADE_GRADIENT_LENGTH / 4, buttonRadius - SHADE_GRADIENT_LENGTH / 2, 0, 0, buttonRadius )
      .addColorStop( 0, transparentDisabledBaseColor )
      .addColorStop( 1, disabledBaseColor.colorUtilsDarker( 0.5 ) );

    // Create the basic button shape.
    var background = new Circle( buttonRadius,
      {
        fill: options.baseColor
      } );
    this.addChild( background );

    // Create the overlay that is used to add horizontal shading.
    var overlayForHorizGradient = new Circle( buttonRadius,
      {
        fill: options.baseColor
      } );
    this.addChild( overlayForHorizGradient );

    content.center = upCenter;
    thisButton.addChild( content );

    // Hook up the function that will modify button appearance as the state changes.
    this.buttonModel.interactionState.link( function( interactionState ) {

      switch( interactionState ) {

        case 'idle':
          content.center = upCenter;
          content.opacity = 1;
          background.fill = upFillHighlight;
          overlayForHorizGradient.fill = upFillShadow;
          thisButton.pickable = true;
          break;

        case 'over':
          content.center = upCenter;
          content.opacity = 1;
          background.fill = overFillHighlight;
          overlayForHorizGradient.fill = overFillShadow;
          thisButton.pickable = true;
          break;

        case 'pressed':
          content.center = downCenter;
          content.opacity = 1;
          background.fill = downFill;
          overlayForHorizGradient.fill = overFillShadow;
          thisButton.pickable = true;
          break;

        case 'disabled':
          content.center = upCenter;
          content.opacity = 0.3;
          background.fill = disabledFillHighlight;
          overlayForHorizGradient.fill = disabledFillShadow;
          thisButton.pickable = false;
          break;
      }
    } );

    // Expand the touch area.
    this.touchArea = Shape.circle( 0, 0, buttonRadius + options.touchExpansion );

    // Set pickable such that sub-nodes are pruned from hit testing.
    this.pickable = null;

    // Mutate with the options after the layout is complete so that
    // width-dependent fields like centerX will work.
    thisButton.mutate( options );
  }

  return inherit( AbstractButton, RoundPushButton );
} );<commit_msg>Improved and simplified RoundPushButton.<commit_after>// Copyright 2002-2014, University of Colorado Boulder

/**
 * A round push button that draws gradients and such in order to create
 * a somewhat 3D look.
 *
 * @author John Blanco
 */
define( function( require ) {
  'use strict';

  // Includes
  var AbstractButton = require( 'SUN/experimental/buttons/AbstractButton' );
  var Circle = require( 'SCENERY/nodes/Circle' );
  var Color = require( 'SCENERY/util/Color' );
  var inherit = require( 'PHET_CORE/inherit' );
  var RadialGradient = require( 'SCENERY/util/RadialGradient' );
  var Shape = require( 'KITE/Shape' );
  var Vector2 = require( 'DOT/Vector2' );

  // Constants
  var HIGHLIGHT_GRADIENT_LENGTH = 5; // In screen coords, which are roughly pixels.

  /**
   * @param {Node} content - Node to put on surface of button, could be text, icon, or whatever
   * @param {Object} options
   * @constructor
   */
  function RoundPushButton( content, options ) {

    var thisButton = this;

    options = _.extend( {
      // Default values.
      cursor: 'pointer',
      baseColor: new Color( 153, 206, 255 ),
      disabledBaseColor: new Color( 220, 220, 220 ),
      minXPadding: 5, // Minimum padding in x direction, i.e. on left and right
      minYPadding: 5, // Minimum padding in x direction, i.e. on top and bottom
      listener: null,
      fireOnDown: false,
      touchExpansion: 5 // In screen units (roughly pixels) beyond button's edge.
    }, options );

    AbstractButton.call( thisButton, { listener: options.listener, fireOnDown: options.fireOnDown } );

    var buttonRadius = Math.max( content.width + options.minXPadding * 2, content.height + options.minYPadding * 2 ) / 2;
    var upCenter = Vector2.ZERO;
    var downCenter = upCenter.plus( new Vector2( 0.5, 0.5 ) ); // Displacement empirically determined.
    var baseColor = options.baseColor;
    var disabledBaseColor = options.disabledBaseColor;
    var transparentBaseColor = new Color( baseColor.getRed(), baseColor.getGreen(), baseColor.getBlue(), 0 );
    var transparentDisabledBaseColor = new Color( disabledBaseColor.getRed(), disabledBaseColor.getGreen(), disabledBaseColor.getBlue(), 0 );

    // The multiplier below can be varied in order to tweak the highlight appearance.
    var innerGradientRadius = buttonRadius - HIGHLIGHT_GRADIENT_LENGTH / 2;
    var outerGradientRadius = buttonRadius + HIGHLIGHT_GRADIENT_LENGTH / 2;
    var gradientOffset = HIGHLIGHT_GRADIENT_LENGTH / 2;

    // Create the gradient fills used for various button states
    var upFillHighlight = new RadialGradient( gradientOffset, gradientOffset, innerGradientRadius, gradientOffset, gradientOffset, outerGradientRadius )
      .addColorStop( 0, baseColor )
      .addColorStop( 1, baseColor.colorUtilsBrighter( 0.7 ) );

    var upFillShadow = new RadialGradient( -gradientOffset, -gradientOffset, innerGradientRadius, -gradientOffset, -gradientOffset, outerGradientRadius )
      .addColorStop( 0, transparentBaseColor )
      .addColorStop( 1, baseColor.colorUtilsDarker( 0.5 ) );

    var overFillHighlight = new RadialGradient( gradientOffset, gradientOffset, innerGradientRadius, gradientOffset, gradientOffset, outerGradientRadius )
      .addColorStop( 0, baseColor.colorUtilsBrighter( 0.4 ) )
      .addColorStop( 1, baseColor.colorUtilsBrighter( 0.8 ) );

    var overFillShadow = new RadialGradient( -gradientOffset, -gradientOffset, innerGradientRadius, -gradientOffset, -gradientOffset, outerGradientRadius )
      .addColorStop( 0, transparentBaseColor )
      .addColorStop( 1, baseColor.colorUtilsDarker( 0.5 ) );

    var downFill = new RadialGradient( 0, 0, 0, 0, 0, outerGradientRadius )
      .addColorStop( 0, baseColor )
      .addColorStop( 0.5, baseColor )
      .addColorStop( 0.7, baseColor.colorUtilsDarker( 0.1 ) )
      .addColorStop( 0.9, baseColor )
      .addColorStop( 1, baseColor.colorUtilsBrighter( 0.7 ) );

    var disabledFillHighlight = new RadialGradient( gradientOffset, gradientOffset, innerGradientRadius, gradientOffset, gradientOffset, outerGradientRadius )
      .addColorStop( 0, disabledBaseColor )
      .addColorStop( 1, disabledBaseColor.colorUtilsBrighter( 0.5 ) );

    var disabledFillShadow = new RadialGradient( -gradientOffset, -gradientOffset, innerGradientRadius, -gradientOffset, -gradientOffset, outerGradientRadius )
      .addColorStop( 0, transparentDisabledBaseColor )
      .addColorStop( 1, disabledBaseColor.colorUtilsDarker( 0.5 ) );

    // Create the basic button shape.
    var background = new Circle( buttonRadius,
      {
        fill: options.baseColor
      } );
    this.addChild( background );

    // Create the overlay that is used to add shading.
    var overlayForShadowGradient = new Circle( buttonRadius,
      {
        fill: options.baseColor
      } );
    this.addChild( overlayForShadowGradient );

    content.center = upCenter;
    thisButton.addChild( content );

    // Hook up the function that will modify button appearance as the state changes.
    this.buttonModel.interactionState.link( function( interactionState ) {

      switch( interactionState ) {

        case 'idle':
          content.center = upCenter;
          content.opacity = 1;
          background.fill = upFillHighlight;
          overlayForShadowGradient.fill = upFillShadow;
          thisButton.pickable = true;
          break;

        case 'over':
          content.center = upCenter;
          content.opacity = 1;
          background.fill = overFillHighlight;
          overlayForShadowGradient.fill = overFillShadow;
          thisButton.pickable = true;
          break;

        case 'pressed':
          content.center = downCenter;
          content.opacity = 1;
          background.fill = downFill;
          overlayForShadowGradient.fill = overFillShadow;
          thisButton.pickable = true;
          break;

        case 'disabled':
          content.center = upCenter;
          content.opacity = 0.3;
          background.fill = disabledFillHighlight;
          overlayForShadowGradient.fill = disabledFillShadow;
          thisButton.pickable = false;
          break;
      }
    } );

    // Expand the touch area.
    this.touchArea = Shape.circle( 0, 0, buttonRadius + options.touchExpansion );

    // Set pickable such that sub-nodes are pruned from hit testing.
    this.pickable = null;

    // Mutate with the options after the layout is complete so that
    // width-dependent fields like centerX will work.
    thisButton.mutate( options );
  }

  return inherit( AbstractButton, RoundPushButton );
} );<|endoftext|>