<commit_before>var obj_canvas,
obj_c,
cp_canvas = null;

var video_canvas,
vid_c;

var brown_const=0;

var vid_width = 640;
var vid_height = 480;

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

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

        getMjpeg();
}

function getMjpeg(){
    var img = new Image();
    img.onload = function() {
        vid_c.clearRect(0, 0, vid_width, vid_height);
        vid_c.drawImage(img, 0, 0, vid_width, vid_height);
        // motion detection
        compareFrame(img);
        // load frame
        window.requestAnimFrame(getMjpeg);
    };
    img.src = "http://171.65.102.132:8080/?action=snapshot?t=" + new Date().getTime();
}

function drawShip(box_X,box_Y,box_rad){
	switch(gamephase)
	{
		case 'gameover':
			vid_c.beginPath();
			vid_c.strokeStyle="rgba(253,172,13,1)";
			vid_c.moveTo(0-4,-5+10);
			vid_c.lineTo(0-4,-5+22);
    		vid_c.stroke();
    		vid_c.moveTo(0-4,-5+10);
			vid_c.lineTo(0-4,-5+22);
    		vid_c.stroke();
    		vid_c.moveTo(0-4,-5+10);
			vid_c.lineTo(0-4,-5+22);
    		vid_c.stroke();
    		vid_c.moveTo(0-4,-5+10);
			vid_c.lineTo(0-4,-5+22);
    		vid_c.stroke();
    		vid_c.moveTo(0-4,-5+10);
			vid_c.lineTo(0-4,-5+22);
    		vid_c.stroke();
    		vid_c.moveTo(0-4,-5+10);
			vid_c.lineTo(0-4,-5+22);
    		vid_c.stroke();

			vid_c.beginPath();
    		vid_c.fillStyle = "#fff";
    		vid_c.fillText('GAME OVER',vid_width/2,vid_height/2);
		break;
		case 'engine':
			// begin transformation
    		vid_c.translate(box_X, box_Y);
			vid_c.rotate(-box_rad);
    		// draw ship body
    		vid_c.beginPath();
    		vid_c.strokeStyle=(hit > 0) ? "rgba(253,172,13,1)" : "rgba(255,255,255,1)";
			vid_c.moveTo(0,-5);
			vid_c.lineTo(0-4,-5+10);
			vid_c.lineTo(0+4,-5+10);
			vid_c.closePath();
    		vid_c.stroke();
    		ctx.fillStyle=(hit > 0) ? "rgba(253,172,13,1)" : "rgba(255,255,255,1)";
			ctx.fill();
    		// draw ship fins
    		vid_c.beginPath();
    		vid_c.moveTo(0-4,-5+10);
			vid_c.lineTo(0-4,-5+22);
    		vid_c.stroke();
    		vid_c.beginPath();
    		vid_c.moveTo(0+4,-5+10);
			vid_c.lineTo(0+4,-5+22);
    		vid_c.stroke();
    		// exit transformation
    		vid_c.rotate(box_rad);
			vid_c.translate(-box_X, -box_Y);
		break;
		case 'rest':
			// begin transformation
    		vid_c.translate(box_X, box_Y);
			vid_c.rotate(-box_rad);
			// draw ship body
    		vid_c.beginPath();
    		vid_c.strokeStyle=(hit > 0) ? "rgba(253,172,13,1)" : "rgba(255,255,255,1)";
			vid_c.moveTo(0,-3);
			vid_c.lineTo(0-5,-3+7);
			vid_c.lineTo(0+5,-3+7);
			vid_c.closePath();
    		vid_c.stroke();
    		// draw ship fins
    		vid_c.beginPath();
    		vid_c.moveTo(0-5,-3+7);
			vid_c.lineTo(0-12,-3+12);
    		vid_c.stroke();
    		vid_c.beginPath();
    		vid_c.moveTo(0+5,-3+7);
			vid_c.lineTo(0+12,-3+12);
    		vid_c.stroke();
    		// exit transformation
    		vid_c.rotate(box_rad);
    		vid_c.translate(-box_X, -box_Y);
		default:
			vid_c.beginPath();
    		vid_c.fillStyle = "#fff";
    		vid_c.fillText('READY TO START',vid_width/2,vid_height/2);
	}
}

function drawStar(aX,aY,bX,bY,step){
	var arrStar =
		[
			[0+2*Math.random(),-10+2*Math.random()],
			[8+2*Math.random(),-4+2*Math.random()],
			[8+2*Math.random(),2+2*Math.random()],
			[0+2*Math.random(),8+2*Math.random()],
			[-8+2*Math.random(),2+2*Math.random()],
			[-8+2*Math.random(),-4+2*Math.random()]
		];

	// draw star body
	switch(gamephase)
	{
		case 'gameover':
			// gameover
			DrawStar();
		break;
		case 'engine':
    		// no path to draw
    		DrawStar();
		break;
		case 'rest':
			DrawStar();
			step = (step > gamelevel) ? gamelevel : step;
			var dX=(bX-aX)*step/gamelevel;
			var dY=(bY-aY)*step/gamelevel;
			DrawDottedLine(aX,aY,aX+dX,aY+dY,2,step,"white");
		default:
			//
			DrawStar();
	}

	function DrawStar(){
		vid_c.strokeStyle="rgba(255,255,255,1)";
		for(var i=0;i<5;i++)
		{
			for(var j=0;j<(5-i);j++){
				vid_c.beginPath();
				vid_c.moveTo(bX+arrStar[i][0],bY+arrStar[i][1]);
				vid_c.lineTo(bX+arrStar[i+j+1][0],bY+arrStar[i+j+1][1]);
    			vid_c.stroke();
    		}
		}
	}

    function DrawDottedLine(x1,y1,x2,y2,dotRadius,dotCount,dotColor){
        var dx=x2-x1;
        var dy=y2-y1;
        var spaceX=dx/(dotCount-1);
        var spaceY=dy/(dotCount-1);
        var newX=x1;
        var newY=y1;
        for (var i=0;i<dotCount;i++){
        	drawDot(newX,newY,dotRadius,dotColor);
        	newX+=spaceX;
            newY+=spaceY;
        }
        drawDot(x1,y1,2,"red");
        drawDot(x2,y2,2,"red");
    }

    function drawDot(x,y,dotRadius,dotColor){
        vid_c.beginPath();
        vid_c.arc(x,y, dotRadius, 0, 2 * Math.PI, false);
        vid_c.fillStyle = dotColor;
        vid_c.fill();
    }
}

var shipX=vid_width/2,
shipY=vid_height/2,
shipRad,
shipL=20,
starX=40,
starY=20;
var gamelevel;
var int_star=-1;
var int_engine=-1;
var engine = false;
var rest = false;
var starTimer;
var enginerTimer;
var gamephase;
var score_val = 0;
var gameTimer;
var hit=0;

function resetGame(){
    score_val = 0;
    hit = 0;
    gamelevel=1;

	shipX = vid_width/2;
    shipY = vid_height/2;

    gamephase='rest';
    gameLoop();
}

function gameLoop(){
	console.log(gamephase);
	switch(gamephase)
	{
		case 'rest':
  			if(rest==false)
			{
				rest=true;
				int_star=gamelevel+6;
				getStarLocation(); // get new starX, starY, shipRad
				starTimer=window.setInterval(showStar,500);
			}
  		break;
		case 'engine':
  			if(hit>0)
			{
				window.clearInterval(engineTimer);
				engine=false;
				rest=false;
				int_star=-1;
				int_engine=-1;
				phase='gameover';
				gamelevel=-1;
			}
			else
			{
				if(engine==false)
				{
					engine=true;
					int_engine=gamelevel+4;
					engineTimer=window.setInterval(runEngine,500);
				}
			}
  		break;
  		case 'gameover':
  			window.cancelRequestAnimationFrame(gameTimer);
       		gameTimer = undefined;
  			gameOver();
  		break;
	}

	drawStar(shipX,shipY,starX,starY,gamelevel-(int_star-6));
	drawShip(shipX,shipY,shipRad);
	gameTimer = window.requestAnimationFrame(gameLoop);
}

var unit=20;

function getStarLocation(){
	shipRad=Math.random()*Math.PI*2;
	starX=shipX+unit*(Math.cos(shipRad))*gamelevel;
	starY=shipY+unit*(Math.sin(shipRad))*gamelevel;
}

function getShipLocation(){
	var step = gamelevel-(int_engine-4);
	step = (step > gamelevel) ? gamelevel : step;
	shipX=shipX+unit*(Math.cos(shipRad))*step/gamelevel;
	shipY=shipY+unit*(Math.sin(shipRad))*step/gamelevel;
}

function showStar(){
	if(int_star>0)
	{
		int_star=int_star-1;
	}
	else
	{
		window.clearInterval(starTimer);
		rest=false;
		gamephase='engine';
	}
}

function runEngine(){
	if(int_engine>0)
	{
		getShipLocation();
		int_engine=int_engine-1;
	}
	else
	{
		window.clearInterval(engineTimer);
		engine=false;
		gamephase='rest';
		if(gamelevel<10)
		{
			gamelevel=gamelevel+1;
		}
	}
}

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

/*******************************************************************************
  Copyright (C) 2009 Tom Stoeveken
  This program is free software;
  you can redistribute it and/or modify it under the terms of the
  GNU General Public License, version 2.
  See the file COPYING for details.
*******************************************************************************/

var img1 = null;
var img2 = null;
var md_canvas = null;

/*
  compare two images and count the differences

  input.: image1 and image2 are Image() objects
  input.: threshold specifies by how much the color value of a pixel
          must differ before they are regarded to be different

  return: number of different pixels
*/

function compare(image1, image2, ptX, ptY, threshold, ObjR) {
  var movement = new Array(0,0,0,0);
  var md_ctx = md_canvas.getContext("2d");
  var width = md_canvas.width/2, height = md_canvas.height/2;

  // copy images into canvas element
  // these steps scale the images and decodes the image data
  md_ctx.drawImage(image1, 0, 0, width, height);
  md_ctx.drawImage(image2, width, 0, width, height);

  // this makes r,g,b,alpha data of images available
  var pixels1 = md_ctx.getImageData(0, 0, width, height);
  var pixels2 = md_ctx.getImageData(width, 0, width, height);

  // substract picture1 from picture2
  // if they differ set color value to max,
  // if the difference is below threshold set difference to 0.
  for (var x = Math.round((ptX-ObjR)/2); x < Math.round((ptX+ObjR)/2); x++) {
    for (var y = Math.round((ptY-ObjR)/2); y < Math.round((ptY+ObjR)/2); y++) {

      // each pixel has a red, green, blue and alpha value
      // all values are stored in a linear array
      var i = x*4 + y*4*pixels1.width;

      var ch0 = ((pixels1.data[i] - pixels2.data[i])>threshold)?255:0;
      var ch1 = ((pixels1.data[i] - pixels2.data[i])>threshold)?255:0;
      var ch2 = ((pixels1.data[i] - pixels2.data[i])>threshold)?255:0;

      // count differing pixels
      var n = (x<Math.round(ptX/2))?0:1;
      var m = (y<Math.round(ptY/2))?0:2;
      movement[n+m] += Math.min(1, ch0 + ch1 + ch2);
    }
  }
  return movement;
}

/*
  Callback function for completed picture downloads

  With every new picture a compare() is performed.
  The new picture is 'img1', the previous picture is stored in 'img2'.
*/
function compareFrame(img1) {
  // just compare if there are two pictures
  if ( img2 != null ) {
    var res;
    var ObjR=10;

    try {
      // compare the two pictures, the given threshold helps to ignore noise
      res = compare(img1, img2, shipX, shipY, 6, ObjR);
    }
    catch(e) {
      // errors can happen if the pictures were corrupted during transfer
      // instead of giving up, just proceed
    }

    var md_ctx = md_canvas.getContext("2d");
    if ((res[0]>400)||(res[1]>400)||(res[2]>400)||(res[3]>400)){
            res[0]=0;res[1]=0;res[2]=0;res[3]=0;
    }
  }

  //hit=res[0]+res[1]+res[2]+res[3];
  hit=0;
  // copy reference of img1 to img2
  img2 = img1;
}

/*
  Initialize the elements

  * Create a Canvas() object and insert it into the page
  * Download the first image
  * Pause the Livestream again if we were paused previously
    This way we will not pause, but we will lower the refresh rate
    For a proper pause, the page can not be reloaded
*/
function setupMotionDetection() {
  md_canvas = document.getElementById('mdCanvas');
  test_canvas = document.getElementById('testCanvas');
  md_canvas.width = vid_width;
  md_canvas.height = vid_height;
}
<commit_msg>debug new game<commit_after>var obj_canvas,
obj_c,
cp_canvas = null;

var video_canvas,
vid_c;

var brown_const=0;

var vid_width = 640;
var vid_height = 480;

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

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

        getMjpeg();
}

function getMjpeg(){
    var img = new Image();
    img.onload = function() {
        vid_c.clearRect(0, 0, vid_width, vid_height);
        vid_c.drawImage(img, 0, 0, vid_width, vid_height);
        // motion detection
        compareFrame(img);
        // load frame
        window.requestAnimFrame(getMjpeg);
    };
    img.src = "http://171.65.102.132:8080/?action=snapshot?t=" + new Date().getTime();
}

function drawShip(box_X,box_Y,box_rad){
	switch(gamephase)
	{
		case 'gameover':
			vid_c.beginPath();
			vid_c.strokeStyle="rgba(253,172,13,1)";
			vid_c.moveTo(0-4,-5+10);
			vid_c.lineTo(0-4,-5+22);
    		vid_c.stroke();
    		vid_c.moveTo(0-4,-5+10);
			vid_c.lineTo(0-4,-5+22);
    		vid_c.stroke();
    		vid_c.moveTo(0-4,-5+10);
			vid_c.lineTo(0-4,-5+22);
    		vid_c.stroke();
    		vid_c.moveTo(0-4,-5+10);
			vid_c.lineTo(0-4,-5+22);
    		vid_c.stroke();
    		vid_c.moveTo(0-4,-5+10);
			vid_c.lineTo(0-4,-5+22);
    		vid_c.stroke();
    		vid_c.moveTo(0-4,-5+10);
			vid_c.lineTo(0-4,-5+22);
    		vid_c.stroke();

			vid_c.beginPath();
    		vid_c.fillStyle = "#fff";
    		vid_c.fillText('GAME OVER',vid_width/2,vid_height/2);
		break;
		case 'engine':
			// begin transformation
    		vid_c.translate(box_X, box_Y);
			vid_c.rotate(-box_rad);
    		// draw ship body
    		vid_c.beginPath();
    		vid_c.strokeStyle=(hit > 0) ? "rgba(253,172,13,1)" : "rgba(255,255,255,1)";
			vid_c.moveTo(0,-5);
			vid_c.lineTo(0-4,-5+10);
			vid_c.lineTo(0+4,-5+10);
			vid_c.closePath();
    		vid_c.stroke();
    		vid_c.fillStyle=(hit > 0) ? "rgba(253,172,13,1)" : "rgba(255,255,255,1)";
			vid_c.fill();
    		// draw ship fins
    		vid_c.beginPath();
    		vid_c.moveTo(0-4,-5+10);
			vid_c.lineTo(0-4,-5+22);
    		vid_c.stroke();
    		vid_c.beginPath();
    		vid_c.moveTo(0+4,-5+10);
			vid_c.lineTo(0+4,-5+22);
    		vid_c.stroke();
    		// exit transformation
    		vid_c.rotate(box_rad);
			vid_c.translate(-box_X, -box_Y);
		break;
		case 'rest':
			// begin transformation
    		vid_c.translate(box_X, box_Y);
			vid_c.rotate(-box_rad);
			// draw ship body
    		vid_c.beginPath();
    		vid_c.strokeStyle=(hit > 0) ? "rgba(253,172,13,1)" : "rgba(255,255,255,1)";
			vid_c.moveTo(0,-3);
			vid_c.lineTo(0-5,-3+7);
			vid_c.lineTo(0+5,-3+7);
			vid_c.closePath();
    		vid_c.stroke();
    		// draw ship fins
    		vid_c.beginPath();
    		vid_c.moveTo(0-5,-3+7);
			vid_c.lineTo(0-12,-3+12);
    		vid_c.stroke();
    		vid_c.beginPath();
    		vid_c.moveTo(0+5,-3+7);
			vid_c.lineTo(0+12,-3+12);
    		vid_c.stroke();
    		// exit transformation
    		vid_c.rotate(box_rad);
    		vid_c.translate(-box_X, -box_Y);
		default:
			vid_c.beginPath();
    		vid_c.fillStyle = "#fff";
    		vid_c.fillText('READY TO START',vid_width/2,vid_height/2);
	}
}

function drawStar(aX,aY,bX,bY,step){
	var arrStar =
		[
			[0+2*Math.random(),-10+2*Math.random()],
			[8+2*Math.random(),-4+2*Math.random()],
			[8+2*Math.random(),2+2*Math.random()],
			[0+2*Math.random(),8+2*Math.random()],
			[-8+2*Math.random(),2+2*Math.random()],
			[-8+2*Math.random(),-4+2*Math.random()]
		];

	// draw star body
	switch(gamephase)
	{
		case 'gameover':
			// gameover
			DrawStar();
		break;
		case 'engine':
    		// no path to draw
    		DrawStar();
		break;
		case 'rest':
			DrawStar();
			step = (step > gamelevel) ? gamelevel : step;
			var dX=(bX-aX)*step/gamelevel;
			var dY=(bY-aY)*step/gamelevel;
			DrawDottedLine(aX,aY,aX+dX,aY+dY,2,step,"white");
		default:
			//
			DrawStar();
	}

	function DrawStar(){
		vid_c.strokeStyle="rgba(255,255,255,1)";
		for(var i=0;i<5;i++)
		{
			for(var j=0;j<(5-i);j++){
				vid_c.beginPath();
				vid_c.moveTo(bX+arrStar[i][0],bY+arrStar[i][1]);
				vid_c.lineTo(bX+arrStar[i+j+1][0],bY+arrStar[i+j+1][1]);
    			vid_c.stroke();
    		}
		}
	}

    function DrawDottedLine(x1,y1,x2,y2,dotRadius,dotCount,dotColor){
        var dx=x2-x1;
        var dy=y2-y1;
        var spaceX=dx/(dotCount-1);
        var spaceY=dy/(dotCount-1);
        var newX=x1;
        var newY=y1;
        for (var i=0;i<dotCount;i++){
        	drawDot(newX,newY,dotRadius,dotColor);
        	newX+=spaceX;
            newY+=spaceY;
        }
        drawDot(x1,y1,2,"red");
        drawDot(x2,y2,2,"red");
    }

    function drawDot(x,y,dotRadius,dotColor){
        vid_c.beginPath();
        vid_c.arc(x,y, dotRadius, 0, 2 * Math.PI, false);
        vid_c.fillStyle = dotColor;
        vid_c.fill();
    }
}

var shipX=vid_width/2,
shipY=vid_height/2,
shipRad,
shipL=20,
starX=40,
starY=20;
var gamelevel;
var int_star=-1;
var int_engine=-1;
var engine = false;
var rest = false;
var starTimer;
var enginerTimer;
var gamephase;
var score_val = 0;
var gameTimer;
var hit=0;

function resetGame(){
    score_val = 0;
    hit = 0;
    gamelevel=1;

	shipX = vid_width/2;
    shipY = vid_height/2;

    gamephase='rest';
    gameLoop();
}

function gameLoop(){
	console.log(gamephase);
	switch(gamephase)
	{
		case 'rest':
  			if(rest==false)
			{
				rest=true;
				int_star=gamelevel+6;
				getStarLocation(); // get new starX, starY, shipRad
				starTimer=window.setInterval(showStar,500);
			}
  		break;
		case 'engine':
  			if(hit>0)
			{
				window.clearInterval(engineTimer);
				engine=false;
				rest=false;
				int_star=-1;
				int_engine=-1;
				phase='gameover';
				gamelevel=-1;
			}
			else
			{
				if(engine==false)
				{
					engine=true;
					int_engine=gamelevel+4;
					engineTimer=window.setInterval(runEngine,500);
				}
			}
  		break;
  		case 'gameover':
  			window.cancelRequestAnimationFrame(gameTimer);
       		gameTimer = undefined;
  			gameOver();
  		break;
	}

	drawStar(shipX,shipY,starX,starY,gamelevel-(int_star-6));
	drawShip(shipX,shipY,shipRad);
	gameTimer = window.requestAnimationFrame(gameLoop);
}

var unit=20;

function getStarLocation(){
	shipRad=Math.random()*Math.PI*2;
	starX=shipX+unit*(Math.cos(shipRad))*gamelevel;
	starY=shipY+unit*(Math.sin(shipRad))*gamelevel;
}

function getShipLocation(){
	var step = gamelevel-(int_engine-4);
	step = (step > gamelevel) ? gamelevel : step;
	shipX=shipX+unit*(Math.cos(shipRad))*step/gamelevel;
	shipY=shipY+unit*(Math.sin(shipRad))*step/gamelevel;
}

function showStar(){
	if(int_star>0)
	{
		int_star=int_star-1;
	}
	else
	{
		window.clearInterval(starTimer);
		rest=false;
		gamephase='engine';
	}
}

function runEngine(){
	if(int_engine>0)
	{
		getShipLocation();
		int_engine=int_engine-1;
	}
	else
	{
		window.clearInterval(engineTimer);
		engine=false;
		gamephase='rest';
		if(gamelevel<10)
		{
			gamelevel=gamelevel+1;
		}
	}
}

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

/*******************************************************************************
  Copyright (C) 2009 Tom Stoeveken
  This program is free software;
  you can redistribute it and/or modify it under the terms of the
  GNU General Public License, version 2.
  See the file COPYING for details.
*******************************************************************************/

var img1 = null;
var img2 = null;
var md_canvas = null;

/*
  compare two images and count the differences

  input.: image1 and image2 are Image() objects
  input.: threshold specifies by how much the color value of a pixel
          must differ before they are regarded to be different

  return: number of different pixels
*/

function compare(image1, image2, ptX, ptY, threshold, ObjR) {
  var movement = new Array(0,0,0,0);
  var md_ctx = md_canvas.getContext("2d");
  var width = md_canvas.width/2, height = md_canvas.height/2;

  // copy images into canvas element
  // these steps scale the images and decodes the image data
  md_ctx.drawImage(image1, 0, 0, width, height);
  md_ctx.drawImage(image2, width, 0, width, height);

  // this makes r,g,b,alpha data of images available
  var pixels1 = md_ctx.getImageData(0, 0, width, height);
  var pixels2 = md_ctx.getImageData(width, 0, width, height);

  // substract picture1 from picture2
  // if they differ set color value to max,
  // if the difference is below threshold set difference to 0.
  for (var x = Math.round((ptX-ObjR)/2); x < Math.round((ptX+ObjR)/2); x++) {
    for (var y = Math.round((ptY-ObjR)/2); y < Math.round((ptY+ObjR)/2); y++) {

      // each pixel has a red, green, blue and alpha value
      // all values are stored in a linear array
      var i = x*4 + y*4*pixels1.width;

      var ch0 = ((pixels1.data[i] - pixels2.data[i])>threshold)?255:0;
      var ch1 = ((pixels1.data[i] - pixels2.data[i])>threshold)?255:0;
      var ch2 = ((pixels1.data[i] - pixels2.data[i])>threshold)?255:0;

      // count differing pixels
      var n = (x<Math.round(ptX/2))?0:1;
      var m = (y<Math.round(ptY/2))?0:2;
      movement[n+m] += Math.min(1, ch0 + ch1 + ch2);
    }
  }
  return movement;
}

/*
  Callback function for completed picture downloads

  With every new picture a compare() is performed.
  The new picture is 'img1', the previous picture is stored in 'img2'.
*/
function compareFrame(img1) {
  // just compare if there are two pictures
  if ( img2 != null ) {
    var res;
    var ObjR=10;

    try {
      // compare the two pictures, the given threshold helps to ignore noise
      res = compare(img1, img2, shipX, shipY, 6, ObjR);
    }
    catch(e) {
      // errors can happen if the pictures were corrupted during transfer
      // instead of giving up, just proceed
    }

    var md_ctx = md_canvas.getContext("2d");
    if ((res[0]>400)||(res[1]>400)||(res[2]>400)||(res[3]>400)){
            res[0]=0;res[1]=0;res[2]=0;res[3]=0;
    }
  }

  //hit=res[0]+res[1]+res[2]+res[3];
  hit=0;
  // copy reference of img1 to img2
  img2 = img1;
}

/*
  Initialize the elements

  * Create a Canvas() object and insert it into the page
  * Download the first image
  * Pause the Livestream again if we were paused previously
    This way we will not pause, but we will lower the refresh rate
    For a proper pause, the page can not be reloaded
*/
function setupMotionDetection() {
  md_canvas = document.getElementById('mdCanvas');
  test_canvas = document.getElementById('testCanvas');
  md_canvas.width = vid_width;
  md_canvas.height = vid_height;
}
<|endoftext|>


<commit_before>loadPhastJS('public/resources-loader.js', function (phast) {

    QUnit.module('ResourcesLoader', function (hooks) {

        var client,
            documentParams = [];

        hooks.before(function () {
            document.querySelectorAll('[data-phast-params]').forEach(function (el) {
                var params = phast.ResourceLoader.RequestParams.fromString(el.dataset.phastParams);
                documentParams.push(params);
            });
        });

        hooks.beforeEach(function () {
            client = new phast.ResourceLoader.BundlerServiceClient('phast.php?service=bundler');
        });

        QUnit.module('Request', function (hooks) {
            var request;

            hooks.beforeEach(function () {
                request = new phast.ResourceLoader.Request();
            });

            QUnit.test('Check setting/getting handlers', function (assert) {

                assert.strictEqual(request.onsuccess, undefined, 'Initially onsuccess is undefined');
                assert.strictEqual(request.onerror, undefined, 'Initially onerror is undefined');

                var onerror = function () {},
                    onsuccess = function () {};

                request.onsuccess = onsuccess;
                request.onerror = onerror;

                assert.strictEqual(request.onsuccess, onsuccess, 'The onsuccess sets correctly');
                assert.strictEqual(request.onerror, onerror, 'The onerror sets correctly');
            });

            QUnit.test('Check resolving/rejecting', function (assert) {
                var called = false;
                request.onsuccess = function (responseText) {
                    assert.equal('my css', responseText, 'Resolves with appropriate argument');
                    called = true;
                };
                request.success('my css');
                assert.ok(called, 'onsuccess callback was called');
                called = false;

                request = new phast.ResourceLoader.Request();
                request.onerror = function () {
                    called = true;
                };
                request.error();
                assert.ok(called, 'onerror callback was called');
            });

            QUnit.test('Check not dying when resolving with no handlers', function (assert) {
                request.error();
                request.success();
                assert.expect(0);
            });

            QUnit.test('Check instant callback if already resolved/rejected', function (assert) {
                var successCalled = false,
                    errorCalled = false;

                request.success('my js');
                request.onsuccess = function (responseText) {
                    assert.equal('my js', responseText, 'Response text is ok');
                    successCalled = true;
                };
                request.onerror = function () {
                    errorCalled = true;
                };

                assert.ok(successCalled, 'Success callback was called on success');
                assert.notOk(errorCalled, 'Error callback was not called on success');

                successCalled = false;
                errorCalled = false;

                request = new phast.ResourceLoader.Request();
                request.error();
                request.onsuccess = function () {
                    successCalled = true;
                };
                request.onerror = function () {
                    errorCalled = true;
                };

                assert.notOk(successCalled, 'Success was not called on error');
                assert.ok(errorCalled, 'Error was not called on error');

            });

            QUnit.test('Check resolving/rejecting only once', function (assert) {
                assert.expect(0);
                var done = assert.async(2);
                var resolved = new phast.ResourceLoader.Request();
                var rejected = new phast.ResourceLoader.Request();
                resolved.onsuccess = function () {
                    done();
                };
                rejected.onerror = function () {
                    done();
                };
                resolved.success('');
                resolved.success('');
                resolved.error();

                rejected.error();
                rejected.error();
                rejected.success('');
            });

            QUnit.test('Check calling onend on resolving', function (assert) {
                assert.expect(0);
                var done = assert.async();
                request.onsuccess = function () {};
                request.onend = function () {
                    done();
                };
                request.success('');
            });

            QUnit.test('Check calling onend on error', function (assert) {
                assert.expect(0);
                var done = assert.async();
                request.onerror = function() {};
                request.onend = function () {
                    done();
                };
                request.error();
            });

        });

        QUnit.module('RequestParams', function () {

            QUnit.test('Check creating from string', function (assert) {
                var string = JSON.stringify({key1: 'value1', key2: 'value2'});
                var params = phast.ResourceLoader.RequestParams.fromString(string);
                assert.equal(params.key1, 'value1', 'key1 is set right');
                assert.equal(params.key2, 'value2', 'key2 is set right');
                assert.notOk(params.isFaulty(), 'It is not faulty');
            });

            QUnit.test('Check bad params', function (assert) {
                var params = phast.ResourceLoader.RequestParams.fromString('invalid json');
                assert.ok(params.isFaulty(), 'It is faulty');
            });
        });

        QUnit.module('BundlerServiceClient', function () {

            QUnit.test('Test fetching files', function (assert) {
                checkFetchingFiles(assert, client);
            });

            QUnit.test('Test fetching from dedicated service file', function (assert) {
                var done = assert.async();
                var client = new phast.ResourceLoader.BundlerServiceClient('bundler.php');
                var request = client.get(documentParams[0]);
                request.then(function (responseText) {
                    assert.equal('text-1-contents', responseText, 'Fetched correctly');
                    done();
                }).catch(function () {
                    assert.ok(false, 'Does not reject');
                    done();
                });
            });

            QUnit.test('Test error on faulty params', function (assert) {
                var done = assert.async();
                var params = phast.ResourceLoader.RequestParams.fromString('invalid json');
                var request = client.get(params);
                request.then(function () {
                    assert.ok(false, 'Does not reject');
                    done();
                }).catch(function () {
                    assert.ok(true, 'Rejects on invalid json');
                    done();
                });
            });

            QUnit.test('Test handling service errors', function (assert) {
                var iterations = 3;
                var done = assert.async(iterations);
                for (var i = 0; i < iterations; i++) {
                    var params = phast.ResourceLoader.RequestParams.fromObject({fail: 'yes'});
                    var request = client.get(params);
                    request.then(function () {
                        assert.ok(false, 'Rejects');
                        done();
                    }).catch(function () {
                        assert.ok(true, 'Rejects');
                        done();
                    });
                }
            });

            QUnit.test('Test handling network errors', function (assert) {
                var iterations = 3;
                var done = assert.async(iterations);
                var client = new phast.ResourceLoader.BundlerServiceClient('does-not-exist');
                for (var i = 0; i < iterations; i++) {
                    var params = phast.ResourceLoader.RequestParams.fromObject({});
                    var request = client.get(params);
                    request.then(function () {
                        assert.ok(false, 'Rejects');
                        done();
                    }).catch(function () {
                        assert.ok(true, 'Rejects');
                        done();
                    });
                }
            });

            QUnit.test('Test ignoring exceptions while dispatching responses', function (assert) {
                var done = assert.async();
                var badParams = {
                    src: 'some-url',
                    token: 'some-token'
                };
                var request1 = client.get(documentParams[0]);
                var request2 = client.get(phast.ResourceLoader.RequestParams.fromObject(badParams));
                var request3 = client.get(documentParams[1]);
                request1.then(function () {
                    throw 'an error';
                });
                request2.catch(function () {
                    throw 'another error';
                });
                request3.then(function () {
                    assert.ok(true, 'Resolves');
                    done();
                });
            });

            QUnit.test('Test ignoring exceptions while dispatching network error', function (assert) {
                var done = assert.async();
                var client = new phast.ResourceLoader.BundlerServiceClient('bad-url');
                var request1 = client.get(documentParams[0]);
                var request2 = client.get(documentParams[1]);
                request1.catch(function () {
                    throw 'an error';
                });
                request2.catch(function () {
                    assert.ok(true, 'Gets executed');
                    done();
                });
            });
        });

        QUnit.module('IndexedDBResourceCache', function (hooks) {

            var Cache = phast.ResourceLoader.IndexedDBResourceCache;
            var Request = phast.ResourceLoader.Request;

            Cache.cleanupProbability = 0;

            function cleanupDB(cb) {
                cb();
            }

            hooks.beforeEach(function () {
                Cache.closeDB();
                Cache.dbName = 'test' + Date.now();
            });

            QUnit.test('Check fetching files with client', function (assert) {
                assert.timeout(2000);
                var done = assert.async(documentParams.length);
                cleanupDB(function () {
                    var cache = new Cache(client);
                    checkFetchingFiles(assert, cache, done);
                });
            });

            QUnit.test('Check retrieval from cache', function (assert) {
                assert.timeout(2000);
                var done = assert.async(documentParams.length);
                cleanupDB(function () {
                    var cache = new Cache(client);
                    var filesFetched = 0;
                    documentParams.forEach(function (params) {
                        var request = cache.get(params);
                        request.then(function () {
                            filesFetched++;
                        });
                    });
                    wait(
                        assert,
                        function () {
                            return filesFetched === documentParams.length;
                        },
                        function () {
                            var cache = new Cache({
                                get: function () {
                                    throw 'Calling client when should have fetched from cache';
                                }
                            });
                            checkFetchingFiles(assert, cache, done);
                        }
                    );
                })
            });

            QUnit.test('Check handling missing store when retrieving from', function (assert) {
                assert.timeout(2000);
                var done = assert.async();
                cleanupDB(function () {
                    var dbOpenRequest = Cache.openDB(false);
                    dbOpenRequest.then(function (db) {
                        db.close();
                        var request = new Cache(client).get(documentParams[0]);
                        request.then(function (responseText) {
                            assert.equal('text-1-contents', responseText);
                            done();
                        });
                    });
                });
            });

            QUnit.test('Check cache cleanup', function (assert) {
                assert.timeout(2000);
                assert.expect(0);
                var done = assert.async(3);
                cleanupDB(function () {
                    var slowClient = {
                        multiplier: 1,
                        get: function (params) {
                            var _this = this;
                            return new Promise(function (resolve) {
                                setTimeout(function () {
                                    console.log('Token:', params.token);
                                    resolve('Token: ' + params.token);
                                }, _this.multiplier++ * 100);
                            })
                        }
                    };
                    var caching = new Cache(slowClient);

                    var fetchedCnt = 0;
                    function fetched() {
                        fetchedCnt++;
                    }

                    caching.get({token: 1}).then(fetched);
                    caching.get({token: 2}).then(fetched);
                    caching.get({token: 3}).then(fetched);

                    wait(assert, function () { return fetchedCnt === 3; }, function () {
                        Cache.maybeCleanup(90, 1);

                        setTimeout(function () {
                            var dummyClient = {
                                get: function () {
                                    return Promise.reject();
                                }
                            };
                            var nonCaching = new Cache(dummyClient);
                            nonCaching.get({token: 1}).catch(done);
                            nonCaching.get({token: 2}).catch(done);
                            nonCaching.get({token: 3}).then(done);
                        }, 200);

                    });
                });
            });

        });

        function checkFetchingFiles(assert, client, done) {
            done = done || assert.async(documentParams.length);
            assert.expect(documentParams.length);
            documentParams.forEach(function (params, idx) {
                var request = client.get(params);
                request.then(function (responseText) {
                    assert.equal('text-' + (idx + 1) + '-contents', responseText, 'Contents are correct');
                    done();
                });
            });
        }

    });

});
<commit_msg>Cleanup code<commit_after>loadPhastJS('public/resources-loader.js', function (phast) {

    QUnit.module('ResourcesLoader', function (hooks) {

        var client,
            documentParams = [];

        hooks.before(function () {
            document.querySelectorAll('[data-phast-params]').forEach(function (el) {
                var params = phast.ResourceLoader.RequestParams.fromString(el.dataset.phastParams);
                documentParams.push(params);
            });
        });

        hooks.beforeEach(function () {
            client = new phast.ResourceLoader.BundlerServiceClient('phast.php?service=bundler');
        });

        QUnit.module('Request', function (hooks) {
            var request;

            hooks.beforeEach(function () {
                request = new phast.ResourceLoader.Request();
            });

            QUnit.test('Check setting/getting handlers', function (assert) {

                assert.strictEqual(request.onsuccess, undefined, 'Initially onsuccess is undefined');
                assert.strictEqual(request.onerror, undefined, 'Initially onerror is undefined');

                var onerror = function () {},
                    onsuccess = function () {};

                request.onsuccess = onsuccess;
                request.onerror = onerror;

                assert.strictEqual(request.onsuccess, onsuccess, 'The onsuccess sets correctly');
                assert.strictEqual(request.onerror, onerror, 'The onerror sets correctly');
            });

            QUnit.test('Check resolving/rejecting', function (assert) {
                var called = false;
                request.onsuccess = function (responseText) {
                    assert.equal('my css', responseText, 'Resolves with appropriate argument');
                    called = true;
                };
                request.success('my css');
                assert.ok(called, 'onsuccess callback was called');
                called = false;

                request = new phast.ResourceLoader.Request();
                request.onerror = function () {
                    called = true;
                };
                request.error();
                assert.ok(called, 'onerror callback was called');
            });

            QUnit.test('Check not dying when resolving with no handlers', function (assert) {
                request.error();
                request.success();
                assert.expect(0);
            });

            QUnit.test('Check instant callback if already resolved/rejected', function (assert) {
                var successCalled = false,
                    errorCalled = false;

                request.success('my js');
                request.onsuccess = function (responseText) {
                    assert.equal('my js', responseText, 'Response text is ok');
                    successCalled = true;
                };
                request.onerror = function () {
                    errorCalled = true;
                };

                assert.ok(successCalled, 'Success callback was called on success');
                assert.notOk(errorCalled, 'Error callback was not called on success');

                successCalled = false;
                errorCalled = false;

                request = new phast.ResourceLoader.Request();
                request.error();
                request.onsuccess = function () {
                    successCalled = true;
                };
                request.onerror = function () {
                    errorCalled = true;
                };

                assert.notOk(successCalled, 'Success was not called on error');
                assert.ok(errorCalled, 'Error was not called on error');

            });

            QUnit.test('Check resolving/rejecting only once', function (assert) {
                assert.expect(0);
                var done = assert.async(2);
                var resolved = new phast.ResourceLoader.Request();
                var rejected = new phast.ResourceLoader.Request();
                resolved.onsuccess = function () {
                    done();
                };
                rejected.onerror = function () {
                    done();
                };
                resolved.success('');
                resolved.success('');
                resolved.error();

                rejected.error();
                rejected.error();
                rejected.success('');
            });

            QUnit.test('Check calling onend on resolving', function (assert) {
                assert.expect(0);
                var done = assert.async();
                request.onsuccess = function () {};
                request.onend = function () {
                    done();
                };
                request.success('');
            });

            QUnit.test('Check calling onend on error', function (assert) {
                assert.expect(0);
                var done = assert.async();
                request.onerror = function() {};
                request.onend = function () {
                    done();
                };
                request.error();
            });

        });

        QUnit.module('RequestParams', function () {

            QUnit.test('Check creating from string', function (assert) {
                var string = JSON.stringify({key1: 'value1', key2: 'value2'});
                var params = phast.ResourceLoader.RequestParams.fromString(string);
                assert.equal(params.key1, 'value1', 'key1 is set right');
                assert.equal(params.key2, 'value2', 'key2 is set right');
                assert.notOk(params.isFaulty(), 'It is not faulty');
            });

            QUnit.test('Check bad params', function (assert) {
                var params = phast.ResourceLoader.RequestParams.fromString('invalid json');
                assert.ok(params.isFaulty(), 'It is faulty');
            });
        });

        QUnit.module('BundlerServiceClient', function () {

            QUnit.test('Test fetching files', function (assert) {
                checkFetchingFiles(assert, client);
            });

            QUnit.test('Test fetching from dedicated service file', function (assert) {
                var done = assert.async();
                var client = new phast.ResourceLoader.BundlerServiceClient('bundler.php');
                var request = client.get(documentParams[0]);
                request.then(function (responseText) {
                    assert.equal('text-1-contents', responseText, 'Fetched correctly');
                    done();
                }).catch(function () {
                    assert.ok(false, 'Does not reject');
                    done();
                });
            });

            QUnit.test('Test error on faulty params', function (assert) {
                var done = assert.async();
                var params = phast.ResourceLoader.RequestParams.fromString('invalid json');
                var request = client.get(params);
                request.then(function () {
                    assert.ok(false, 'Does not reject');
                    done();
                }).catch(function () {
                    assert.ok(true, 'Rejects on invalid json');
                    done();
                });
            });

            QUnit.test('Test handling service errors', function (assert) {
                var iterations = 3;
                var done = assert.async(iterations);
                for (var i = 0; i < iterations; i++) {
                    var params = phast.ResourceLoader.RequestParams.fromObject({fail: 'yes'});
                    var request = client.get(params);
                    request.then(function () {
                        assert.ok(false, 'Rejects');
                        done();
                    }).catch(function () {
                        assert.ok(true, 'Rejects');
                        done();
                    });
                }
            });

            QUnit.test('Test handling network errors', function (assert) {
                var iterations = 3;
                var done = assert.async(iterations);
                var client = new phast.ResourceLoader.BundlerServiceClient('does-not-exist');
                for (var i = 0; i < iterations; i++) {
                    var params = phast.ResourceLoader.RequestParams.fromObject({});
                    var request = client.get(params);
                    request.then(function () {
                        assert.ok(false, 'Rejects');
                        done();
                    }).catch(function () {
                        assert.ok(true, 'Rejects');
                        done();
                    });
                }
            });

            QUnit.test('Test ignoring exceptions while dispatching responses', function (assert) {
                var done = assert.async();
                var badParams = {
                    src: 'some-url',
                    token: 'some-token'
                };
                var request1 = client.get(documentParams[0]);
                var request2 = client.get(phast.ResourceLoader.RequestParams.fromObject(badParams));
                var request3 = client.get(documentParams[1]);
                request1.then(function () {
                    throw 'an error';
                });
                request2.catch(function () {
                    throw 'another error';
                });
                request3.then(function () {
                    assert.ok(true, 'Resolves');
                    done();
                });
            });

            QUnit.test('Test ignoring exceptions while dispatching network error', function (assert) {
                var done = assert.async();
                var client = new phast.ResourceLoader.BundlerServiceClient('bad-url');
                var request1 = client.get(documentParams[0]);
                var request2 = client.get(documentParams[1]);
                request1.catch(function () {
                    throw 'an error';
                });
                request2.catch(function () {
                    assert.ok(true, 'Gets executed');
                    done();
                });
            });
        });

        QUnit.module('IndexedDBResourceCache', function (hooks) {

            var Cache = phast.ResourceLoader.IndexedDBResourceCache;
            Cache.cleanupProbability = 0;

            hooks.beforeEach(function () {
                Cache.closeDB();
                Cache.dbName = 'test' + Date.now();
            });

            QUnit.test('Check fetching files with client', function (assert) {
                assert.timeout(2000);
                var done = assert.async(documentParams.length);
                var cache = new Cache(client);
                checkFetchingFiles(assert, cache, done);
            });

            QUnit.test('Check retrieval from cache', function (assert) {
                assert.timeout(2000);
                var done = assert.async(documentParams.length);
                var cache = new Cache(client);
                var filesFetched = 0;
                documentParams.map(function (params) {
                    var request = cache.get(params);
                    request.then(function () {
                        filesFetched++;
                    });
                });
                wait(
                    assert,
                    function () {
                        return filesFetched === documentParams.length;
                    },
                    function () {
                        var cache = new Cache({
                            get: function () {
                                throw 'Calling client when should have fetched from cache';
                            }
                        });
                        checkFetchingFiles(assert, cache, done);
                    }
                );
            });

            QUnit.test('Check handling missing store when retrieving from', function (assert) {
                assert.timeout(2000);
                var done = assert.async();
                var dbOpenRequest = Cache.openDB(false);
                dbOpenRequest.then(function (db) {
                    db.close();
                    return new Cache(client).get(documentParams[0]);
                }).then(function (responseText) {
                    assert.equal('text-1-contents', responseText);
                    done();
                });;
            });

            QUnit.test('Check cache cleanup', function (assert) {
                assert.timeout(2000);
                assert.expect(0);
                var done = assert.async(3);
                var slowClient = {
                    get: function (params) {
                        return new Promise(function (resolve) {
                            setTimeout(function () {
                                console.log('Token:', params.token);
                                resolve('Token: ' + params.token);
                            }, 100);
                        })
                    }
                };
                var dummyClient = {
                    get: function () {
                        return Promise.reject();
                    }
                };

                var caching = new Cache(slowClient);
                caching.get({token: 1}).then(function () {
                    return caching.get({token: 2});
                }).then(function () {
                    return caching.get({token: 3});
                }).then(function () {
                    Cache.maybeCleanup(90, 1);

                    setTimeout(function () {
                        var nonCaching = new Cache(dummyClient);
                        nonCaching.get({token: 1}).catch(done);
                        nonCaching.get({token: 2}).catch(done);
                        nonCaching.get({token: 3}).then(done);
                    }, 200);
                });
            });

        });

        function checkFetchingFiles(assert, client, done) {
            done = done || assert.async(documentParams.length);
            assert.expect(documentParams.length);
            documentParams.forEach(function (params, idx) {
                var request = client.get(params);
                request.then(function (responseText) {
                    assert.equal('text-' + (idx + 1) + '-contents', responseText, 'Contents are correct');
                    done();
                });
            });
        }

    });

});
<|endoftext|>


<commit_before>var testHelper = require('../../test_helper');
var should = testHelper.should;
var waterlock = testHelper.waterlock_local;

var reset = waterlock.actions.extras.reset;

describe('email reset action', function(){
  it('should exist', function(done){
    reset.should.be.Function;
    done();
  });

  it('should respond with 404', function(done){
    var req = {method: 'PUT'};
    var res = {json: function(code){
      code.should.equal(404);
      done();
    }};
    reset(req, res);
  });
});<commit_msg>Solve error during reset action test<commit_after>var testHelper = require('../../test_helper');
var should = testHelper.should;
var waterlock = testHelper.waterlock_local;

var reset = waterlock.actions.extras.reset;

describe('email reset action', function(){
  it('should exist', function(done){
    reset.should.be.Function;
    done();
  });

  it('should respond with 404', function(done){
    var req = {method: 'PUT'};
    var res = {
      status: function(code) {
        code.should.equal(404);
        return {
          json: function(code) {
            code.should.equal(404);
            done();
          }
        };
      }
    };
    reset(req, res);
  });
});
<|endoftext|>


<commit_before>openerp.web.data_import = function(openerp) {
var QWeb = openerp.web.qweb,
    _t = openerp.web._t;
/**
 * Safari does not deal well at all with raw JSON data being returned. As a
 * result, we're going to cheat by using a pseudo-jsonp: instead of getting
 * JSON data in the iframe, we're getting a ``script`` tag which consists of a
 * function call and the returned data (the json dump).
 *
 * The function is an auto-generated name bound to ``window``, which calls
 * back into the callback provided here.
 *
 * @param {Object} form the form element (DOM or jQuery) to use in the call
 * @param {Object} attributes jquery.form attributes object
 * @param {Function} callback function to call with the returned data
 */
function jsonp(form, attributes, callback) {
    attributes = attributes || {};
    var options = {jsonp: _.uniqueId('import_callback_')};
    window[options.jsonp] = function () {
        delete window[options.jsonp];
        callback.apply(null, arguments);
    };
    if ('data' in attributes) {
        _.extend(attributes.data, options);
    } else {
        _.extend(attributes, {data: options});
    }
    $(form).ajaxSubmit(attributes);
}

openerp.web.DataImport = openerp.web.Dialog.extend({
    template: 'ImportDataView',
    dialog_title: {toString: function () { return _t("Import Data"); }},
    init: function(parent, dataset){
        var self = this;
        this._super(parent, {});
        this.model = parent.model;
        this.fields = [];
        this.all_fields = [];
        this.fields_with_defaults = [];
        this.required_fields = null;

        var convert_fields = function (root, prefix) {
            prefix = prefix || '';
            _(root.fields).each(function (f) {
                self.all_fields.push(prefix + f.name);
                if (f.fields) {
                    convert_fields(f, prefix + f.id + '/');
                }
            });
        };
        this.ready  = $.Deferred.queue().then(function () {
            self.required_fields = _(self.fields).chain()
                .filter(function (field) {
                    return field.required &&
                           !_.include(self.fields_with_defaults, field.id); })
                .pluck('name')
                .value();
            convert_fields(self);
            self.all_fields.sort();
        });
    },
    start: function() {
        var self = this;
        this._super();
        this.open({
            buttons: [
                {text: _t("Close"), click: function() { self.stop(); }},
                {text: _t("Import File"), click: function() { self.do_import(); }, 'class': 'oe-dialog-import-button'}
            ],
            close: function(event, ui) {
                self.stop();
            }
        });
        this.toggle_import_button(false);
        this.$element.find('#csvfile').change(this.on_autodetect_data);
        this.$element.find('fieldset').change(this.on_autodetect_data);
        this.$element.delegate('fieldset legend', 'click', function() {
            $(this).parent().toggleClass('oe-closed');
        });
        this.ready.push(new openerp.web.DataSet(this, this.model).call(
            'fields_get', [], function (fields) {
                self.graft_fields(fields);
                self.ready.push(new openerp.web.DataSet(self, self.model)
                        .default_get(_.pluck(self.fields, 'id')).then(function (fields) {
                    _.each(fields, function(val, key) {
                        if (val) {
                            self.fields_with_defaults.push(key);
                        }
                    });
                })
            )
        }));
    },
    graft_fields: function (fields, parent, level) {
        parent = parent || this;
        level = level || 0;

        var self = this;
        if (level === 0) {
            parent.fields.push({
                id: 'id',
                name: 'id',
                string: _t('External ID'),
                required: false
            });
        }
        _(fields).each(function (field, field_name) {
            // Ignore spec for id field
            // Don't import function fields (function and related)
            if (field_name === 'id') {
                return;
            }
            // Skip if there's no state which could disable @readonly,
            // if a field is ever always readonly we can't import it
            if (field.readonly) {
                // no states at all
                if (_.isEmpty(field.states)) { return; }
                // no state altering @readonly
                if (!_.any(field.states, function (modifiers) {
                    return _(modifiers).chain().pluck(0).contains('readonly').value();
                })) { return; }
            }

            var f = {
                id: field_name,
                name: field_name,
                string: field.string,
                required: field.required
            };

            switch (field.type) {
            case 'many2many':
            case 'many2one':
                f.name += '/id';
                break;
            case 'one2many':
                f.name += '/id';
                f.fields = [];
                // only fetch sub-fields to a depth of 2 levels
                if (level < 2) {
                    self.ready.push(new openerp.web.DataSet(self, field.relation).call(
                        'fields_get', [], function (fields) {
                            self.graft_fields(fields, f, level+1);
                    }));
                }
                break;
            }
            parent.fields.push(f);
        });
    },
    toggle_import_button: function (newstate) {
        this.$element.dialog('widget')
                .find('.oe-dialog-import-button')
                .button('option', 'disabled', !newstate);
    },
    do_import: function() {
        if(!this.$element.find('#csvfile').val()) { return; }
        var lines_to_skip = parseInt(this.$element.find('#csv_skip').val(), 10);
        var with_headers = this.$element.find('#file_has_headers').prop('checked');
        if (!lines_to_skip && with_headers) {
            lines_to_skip = 1;
        }
        var indices = [], fields = [];
        this.$element.find(".sel_fields").each(function(index, element) {
            var val = element.value;
            if (!val) {
                return;
            }
            indices.push(index);
            fields.push(val);
        });

        jsonp(this.$element.find('#import_data'), {
            url: '/web/import/import_data',
            data: {
                model: this.model,
                meta: JSON.stringify({
                    skip: lines_to_skip,
                    indices: indices,
                    fields: fields
                })
            }
        }, this.on_import_results);
    },
    on_autodetect_data: function() {
        if(!this.$element.find('#csvfile').val()) { return; }
        jsonp(this.$element.find('#import_data'), {
            url: '/web/import/detect_data'
        }, this.on_import_results);
    },
    on_import_results: function(results) {
        this.$element.find('#result').empty();
        var headers, result_node = this.$element.find("#result");

        if (results['error']) {
            result_node.append(QWeb.render('ImportView.error', {
                'error': results['error']}));
            this.$element.find('fieldset').removeClass('oe-closed');
            return;
        }
        if (results['success']) {
            if (this.widget_parent.widget_parent.active_view == "list") {
                this.widget_parent.reload_content();
            }
            this.stop();
            return;
        }

        if (results['records']) {
            var lines_to_skip = parseInt(this.$element.find('#csv_skip').val(), 10),
                with_headers = this.$element.find('#file_has_headers').prop('checked');
            headers = with_headers ? results.records[0] : null;

            result_node.append(QWeb.render('ImportView.result', {
                'headers': headers,
                'records': lines_to_skip ? results.records.slice(lines_to_skip)
                          : with_headers ? results.records.slice(1)
                          : results.records
            }));
            this.$element.find('fieldset').addClass('oe-closed');
        }
        this.$element.find('form').removeClass('oe-import-no-result');

        this.$element.delegate('.oe-m2o-drop-down-button', 'click', function () {
            $(this).prev('input').focus();
        });

        var self = this;
        this.ready.then(function () {
            var $fields = self.$element.find('.sel_fields').bind('blur', function () {
                if (this.value && !_(self.all_fields).contains(this.value)) {
                    this.value = '';
                }
            }).autocomplete({
                minLength: 0,
                source: self.all_fields,
                change: self.on_check_field_values
            }).focus(function () {
                $(this).autocomplete('search');
            });
            // Column auto-detection
            _(headers).each(function (header, index) {
                var field_name = self.match_column_to_field(header);
                if (field_name) {
                    $fields.eq(index).val(field_name);
                }
            });
            self.on_check_field_values();
        });
    },
    /**
     * Returns the name of the field (nested) matching the provided column name
     *
     * @param {String} name column name to look for
     * @param {Array} [fields] fields to look into for the provided name
     * @returns {String|undefined}
     */
    match_column_to_field: function (name, fields) {
        fields = fields || this.fields;
        var f;
        f = _(fields).detect(function (field) {
            // TODO: levenshtein between header and field.string
            return field.name === name
                || field.string.toLowerCase() === name.toLowerCase();
        });
        if (f) { return f.name; }

        // if ``name`` is a path (o2m), we need to recurse through its .fields
        var index = name.indexOf('/');
        if (index === -1) { return undefined; }
        // Get the first path section, try to find the matching field
        var column_name = name.substring(0, index);
        f = _(fields).detect(function (field) {
            // field.name for o2m is $foo/id, so we want to match on id
            return field.id === column_name
                || field.string.toLowerCase() === column_name.toLowerCase()
        });
        if (!f) { return undefined; }

        // if we found a matching field for the first path section, recurse in
        // its own .fields to try and get the rest of the path matched
        var rest = this.match_column_to_field(
                name.substring(index+1), f.fields);
        if (!rest) { return undefined; }
        return f.id + '/' + rest;
    },
    /**
     * Looks through all the field selections, and tries to find if two
     * (or more) columns were matched to the same model field.
     *
     * Returns a map of the multiply-mapped fields to an array of offending
     * columns (not actually columns, but the inputs containing the same field
     * names).
     *
     * Also has the side-effect of marking the discovered inputs with the class
     * ``duplicate_fld``.
     *
     * @returns {Object<String, Array<String>>} map of duplicate field matches to same-valued inputs
     */
    find_duplicate_fields: function() {
        // Maps values to DOM nodes, in order to discover duplicates
        var values = {}, duplicates = {};
        this.$element.find(".sel_fields").each(function(index, element) {
            var value = element.value;
            var $element = $(element).removeClass('duplicate_fld');
            if (!value) { return; }

            if (!(value in values)) {
                values[value] = element;
            } else {
                var same_valued_field = values[value];
                if (value in duplicates) {
                    duplicates[value].push(element);
                } else {
                    duplicates[value] = [same_valued_field, element];
                }
                $element.add(same_valued_field).addClass('duplicate_fld');
            }
        });
        return duplicates;
    },
    on_check_field_values: function () {
        this.$element.find("#message, #msg").remove();

        var required_valid = this.check_required();

        var duplicates = this.find_duplicate_fields();
        if (_.isEmpty(duplicates)) {
            this.toggle_import_button(required_valid);
        } else {
            var $err = $('
Destination fields should only be selected once, some fields are selected more than once:
').insertBefore(this.$element.find('#result'));
            var $dupes = $('
').appendTo($err);
            _(duplicates).each(function(elements, value) {
                $('
').text(value).appendTo($dupes);
                _(elements).each(function(element) {
                    var cell = $(element).closest('td');
                    $('
').text(cell.parent().children().index(cell)).appendTo($dupes);
                });
            });
            this.toggle_import_button(false);
        }

    },
    check_required: function() {
        if (!this.required_fields.length) { return true; }

        var selected_fields = _(this.$element.find('.sel_fields').get()).chain()
            .pluck('value')
            .compact()
            .value();

        var missing_fields = _.difference(this.required_fields, selected_fields);
        if (missing_fields.length) {
            this.$element.find("#result").before('
*Required Fields are not selected : ' + missing_fields + '.
');
            return false;
        }
        return true;
    },
    stop: function() {
        this.$element.remove();
        this._super();
    }
});
};
<commit_msg>[MERGE] missing translation mark in import error dialogs<commit_after>openerp.web.data_import = function(openerp) {
var QWeb = openerp.web.qweb,
    _t = openerp.web._t;
/**
 * Safari does not deal well at all with raw JSON data being returned. As a
 * result, we're going to cheat by using a pseudo-jsonp: instead of getting
 * JSON data in the iframe, we're getting a ``script`` tag which consists of a
 * function call and the returned data (the json dump).
 *
 * The function is an auto-generated name bound to ``window``, which calls
 * back into the callback provided here.
 *
 * @param {Object} form the form element (DOM or jQuery) to use in the call
 * @param {Object} attributes jquery.form attributes object
 * @param {Function} callback function to call with the returned data
 */
function jsonp(form, attributes, callback) {
    attributes = attributes || {};
    var options = {jsonp: _.uniqueId('import_callback_')};
    window[options.jsonp] = function () {
        delete window[options.jsonp];
        callback.apply(null, arguments);
    };
    if ('data' in attributes) {
        _.extend(attributes.data, options);
    } else {
        _.extend(attributes, {data: options});
    }
    $(form).ajaxSubmit(attributes);
}

openerp.web.DataImport = openerp.web.Dialog.extend({
    template: 'ImportDataView',
    dialog_title: {toString: function () { return _t("Import Data"); }},
    init: function(parent, dataset){
        var self = this;
        this._super(parent, {});
        this.model = parent.model;
        this.fields = [];
        this.all_fields = [];
        this.fields_with_defaults = [];
        this.required_fields = null;

        var convert_fields = function (root, prefix) {
            prefix = prefix || '';
            _(root.fields).each(function (f) {
                self.all_fields.push(prefix + f.name);
                if (f.fields) {
                    convert_fields(f, prefix + f.id + '/');
                }
            });
        };
        this.ready  = $.Deferred.queue().then(function () {
            self.required_fields = _(self.fields).chain()
                .filter(function (field) {
                    return field.required &&
                           !_.include(self.fields_with_defaults, field.id); })
                .pluck('name')
                .value();
            convert_fields(self);
            self.all_fields.sort();
        });
    },
    start: function() {
        var self = this;
        this._super();
        this.open({
            buttons: [
                {text: _t("Close"), click: function() { self.stop(); }},
                {text: _t("Import File"), click: function() { self.do_import(); }, 'class': 'oe-dialog-import-button'}
            ],
            close: function(event, ui) {
                self.stop();
            }
        });
        this.toggle_import_button(false);
        this.$element.find('#csvfile').change(this.on_autodetect_data);
        this.$element.find('fieldset').change(this.on_autodetect_data);
        this.$element.delegate('fieldset legend', 'click', function() {
            $(this).parent().toggleClass('oe-closed');
        });
        this.ready.push(new openerp.web.DataSet(this, this.model).call(
            'fields_get', [], function (fields) {
                self.graft_fields(fields);
                self.ready.push(new openerp.web.DataSet(self, self.model)
                        .default_get(_.pluck(self.fields, 'id')).then(function (fields) {
                    _.each(fields, function(val, key) {
                        if (val) {
                            self.fields_with_defaults.push(key);
                        }
                    });
                })
            )
        }));
    },
    graft_fields: function (fields, parent, level) {
        parent = parent || this;
        level = level || 0;

        var self = this;
        if (level === 0) {
            parent.fields.push({
                id: 'id',
                name: 'id',
                string: _t('External ID'),
                required: false
            });
        }
        _(fields).each(function (field, field_name) {
            // Ignore spec for id field
            // Don't import function fields (function and related)
            if (field_name === 'id') {
                return;
            }
            // Skip if there's no state which could disable @readonly,
            // if a field is ever always readonly we can't import it
            if (field.readonly) {
                // no states at all
                if (_.isEmpty(field.states)) { return; }
                // no state altering @readonly
                if (!_.any(field.states, function (modifiers) {
                    return _(modifiers).chain().pluck(0).contains('readonly').value();
                })) { return; }
            }

            var f = {
                id: field_name,
                name: field_name,
                string: field.string,
                required: field.required
            };

            switch (field.type) {
            case 'many2many':
            case 'many2one':
                f.name += '/id';
                break;
            case 'one2many':
                f.name += '/id';
                f.fields = [];
                // only fetch sub-fields to a depth of 2 levels
                if (level < 2) {
                    self.ready.push(new openerp.web.DataSet(self, field.relation).call(
                        'fields_get', [], function (fields) {
                            self.graft_fields(fields, f, level+1);
                    }));
                }
                break;
            }
            parent.fields.push(f);
        });
    },
    toggle_import_button: function (newstate) {
        this.$element.dialog('widget')
                .find('.oe-dialog-import-button')
                .button('option', 'disabled', !newstate);
    },
    do_import: function() {
        if(!this.$element.find('#csvfile').val()) { return; }
        var lines_to_skip = parseInt(this.$element.find('#csv_skip').val(), 10);
        var with_headers = this.$element.find('#file_has_headers').prop('checked');
        if (!lines_to_skip && with_headers) {
            lines_to_skip = 1;
        }
        var indices = [], fields = [];
        this.$element.find(".sel_fields").each(function(index, element) {
            var val = element.value;
            if (!val) {
                return;
            }
            indices.push(index);
            fields.push(val);
        });

        jsonp(this.$element.find('#import_data'), {
            url: '/web/import/import_data',
            data: {
                model: this.model,
                meta: JSON.stringify({
                    skip: lines_to_skip,
                    indices: indices,
                    fields: fields
                })
            }
        }, this.on_import_results);
    },
    on_autodetect_data: function() {
        if(!this.$element.find('#csvfile').val()) { return; }
        jsonp(this.$element.find('#import_data'), {
            url: '/web/import/detect_data'
        }, this.on_import_results);
    },
    on_import_results: function(results) {
        this.$element.find('#result').empty();
        var headers, result_node = this.$element.find("#result");

        if (results['error']) {
            result_node.append(QWeb.render('ImportView.error', {
                'error': results['error']}));
            this.$element.find('fieldset').removeClass('oe-closed');
            return;
        }
        if (results['success']) {
            if (this.widget_parent.widget_parent.active_view == "list") {
                this.widget_parent.reload_content();
            }
            this.stop();
            return;
        }

        if (results['records']) {
            var lines_to_skip = parseInt(this.$element.find('#csv_skip').val(), 10),
                with_headers = this.$element.find('#file_has_headers').prop('checked');
            headers = with_headers ? results.records[0] : null;

            result_node.append(QWeb.render('ImportView.result', {
                'headers': headers,
                'records': lines_to_skip ? results.records.slice(lines_to_skip)
                          : with_headers ? results.records.slice(1)
                          : results.records
            }));
            this.$element.find('fieldset').addClass('oe-closed');
        }
        this.$element.find('form').removeClass('oe-import-no-result');

        this.$element.delegate('.oe-m2o-drop-down-button', 'click', function () {
            $(this).prev('input').focus();
        });

        var self = this;
        this.ready.then(function () {
            var $fields = self.$element.find('.sel_fields').bind('blur', function () {
                if (this.value && !_(self.all_fields).contains(this.value)) {
                    this.value = '';
                }
            }).autocomplete({
                minLength: 0,
                source: self.all_fields,
                change: self.on_check_field_values
            }).focus(function () {
                $(this).autocomplete('search');
            });
            // Column auto-detection
            _(headers).each(function (header, index) {
                var field_name = self.match_column_to_field(header);
                if (field_name) {
                    $fields.eq(index).val(field_name);
                }
            });
            self.on_check_field_values();
        });
    },
    /**
     * Returns the name of the field (nested) matching the provided column name
     *
     * @param {String} name column name to look for
     * @param {Array} [fields] fields to look into for the provided name
     * @returns {String|undefined}
     */
    match_column_to_field: function (name, fields) {
        fields = fields || this.fields;
        var f;
        f = _(fields).detect(function (field) {
            // TODO: levenshtein between header and field.string
            return field.name === name
                || field.string.toLowerCase() === name.toLowerCase();
        });
        if (f) { return f.name; }

        // if ``name`` is a path (o2m), we need to recurse through its .fields
        var index = name.indexOf('/');
        if (index === -1) { return undefined; }
        // Get the first path section, try to find the matching field
        var column_name = name.substring(0, index);
        f = _(fields).detect(function (field) {
            // field.name for o2m is $foo/id, so we want to match on id
            return field.id === column_name
                || field.string.toLowerCase() === column_name.toLowerCase()
        });
        if (!f) { return undefined; }

        // if we found a matching field for the first path section, recurse in
        // its own .fields to try and get the rest of the path matched
        var rest = this.match_column_to_field(
                name.substring(index+1), f.fields);
        if (!rest) { return undefined; }
        return f.id + '/' + rest;
    },
    /**
     * Looks through all the field selections, and tries to find if two
     * (or more) columns were matched to the same model field.
     *
     * Returns a map of the multiply-mapped fields to an array of offending
     * columns (not actually columns, but the inputs containing the same field
     * names).
     *
     * Also has the side-effect of marking the discovered inputs with the class
     * ``duplicate_fld``.
     *
     * @returns {Object<String, Array<String>>} map of duplicate field matches to same-valued inputs
     */
    find_duplicate_fields: function() {
        // Maps values to DOM nodes, in order to discover duplicates
        var values = {}, duplicates = {};
        this.$element.find(".sel_fields").each(function(index, element) {
            var value = element.value;
            var $element = $(element).removeClass('duplicate_fld');
            if (!value) { return; }

            if (!(value in values)) {
                values[value] = element;
            } else {
                var same_valued_field = values[value];
                if (value in duplicates) {
                    duplicates[value].push(element);
                } else {
                    duplicates[value] = [same_valued_field, element];
                }
                $element.add(same_valued_field).addClass('duplicate_fld');
            }
        });
        return duplicates;
    },
    on_check_field_values: function () {
        this.$element.find("#message, #msg").remove();

        var required_valid = this.check_required();

        var duplicates = this.find_duplicate_fields();
        if (_.isEmpty(duplicates)) {
            this.toggle_import_button(required_valid);
        } else {
            var $err = $('
'+_t("Destination fields should only be selected once, some fields are selected more than once:")+'
').insertBefore(this.$element.find('#result'));
            var $dupes = $('
').appendTo($err);
            _(duplicates).each(function(elements, value) {
                $('
').text(value).appendTo($dupes);
                _(elements).each(function(element) {
                    var cell = $(element).closest('td');
                    $('
').text(cell.parent().children().index(cell)).appendTo($dupes);
                });
            });
            this.toggle_import_button(false);
        }

    },
    check_required: function() {
        if (!this.required_fields.length) { return true; }

        var selected_fields = _(this.$element.find('.sel_fields').get()).chain()
            .pluck('value')
            .compact()
            .value();

        var missing_fields = _.difference(this.required_fields, selected_fields);
        if (missing_fields.length) {
            this.$element.find("#result").before('
' + _t("*Required Fields are not selected :") + missing_fields + '.
');
            return false;
        }
        return true;
    },
    stop: function() {
        this.$element.remove();
        this._super();
    }
});
};
<|endoftext|>


<commit_before>/*! Overthrow. An overflow:auto polyfill for responsive design. (c) 2012: Scott Jehl, Filament Group, Inc. http://filamentgroup.github.com/Overthrow/license.txt */
(function( w, undefined ){

	var doc = w.document,
		docElem = doc.documentElement,
		enabledClassName = "overthrow-enabled",

		// Touch events are used in the polyfill, and thus are a prerequisite
		canBeFilledWithPoly = "ontouchmove" in doc,

		// The following attempts to determine whether the browser has native overflow support
		// so we can enable it but not polyfill
		nativeOverflow =
			// Features-first. iOS5 overflow scrolling property check - no UA needed here. thanks Apple :)
			"WebkitOverflowScrolling" in docElem.style ||
			// Test the windows scrolling property as well
			"msOverflowStyle" in docElem.style ||
			// Touch events aren't supported and screen width is greater than X
			// ...basically, this is a loose "desktop browser" check.
			// It may wrongly opt-in very large tablets with no touch support.
			( !canBeFilledWithPoly && w.screen.width > 800 ) ||
			// Hang on to your hats.
			// Whitelist some popular, overflow-supporting mobile browsers for now and the future
			// These browsers are known to get overlow support right, but give us no way of detecting it.
			(function(){
				var ua = w.navigator.userAgent,
					// Webkit crosses platforms, and the browsers on our list run at least version 534
					webkit = ua.match( /AppleWebKit\/([0-9]+)/ ),
					wkversion = webkit && webkit[1],
					wkLte534 = webkit && wkversion >= 534;

				return (
					/* Android 3+ with webkit gte 534
					~: Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13 */
					ua.match( /Android ([0-9]+)/ ) && RegExp.$1 >= 3 && wkLte534 ||
					/* Blackberry 7+ with webkit gte 534
					~: Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en-US) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.0.0 Mobile Safari/534.11+ */
					ua.match( / Version\/([0-9]+)/ ) && RegExp.$1 >= 0 && w.blackberry && wkLte534 ||
					/* Blackberry Playbook with webkit gte 534
					~: Mozilla/5.0 (PlayBook; U; RIM Tablet OS 1.0.0; en-US) AppleWebKit/534.8+ (KHTML, like Gecko) Version/0.0.1 Safari/534.8+ */
					ua.indexOf( /PlayBook/ ) > -1 && RegExp.$1 >= 0 && wkLte534 && !ua.indexOf( "Android 2" ) === -1 ||
					/* Firefox Mobile (Fennec) 4 and up
					~: Mozilla/5.0 (Mobile; rv:15.0) Gecko/15.0 Firefox/15.0 */
					ua.match(/Firefox\/([0-9]+)/) && RegExp.$1 >= 4 ||
					/* WebOS 3 and up (TouchPad too)
					~: Mozilla/5.0 (hp-tablet; Linux; hpwOS/3.0.0; U; en-US) AppleWebKit/534.6 (KHTML, like Gecko) wOSBrowser/233.48 Safari/534.6 TouchPad/1.0 */
					ua.match( /wOSBrowser\/([0-9]+)/ ) && RegExp.$1 >= 233 && wkLte534 ||
					/* Nokia Browser N8
					~: Mozilla/5.0 (Symbian/3; Series60/5.2 NokiaN8-00/012.002; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/533.4 (KHTML, like Gecko) NokiaBrowser/7.3.0 Mobile Safari/533.4 3gpp-gba
					~: Note: the N9 doesn't have native overflow with one-finger touch. wtf */
					ua.match( /NokiaBrowser\/([0-9\.]+)/ ) && parseFloat(RegExp.$1) === 7.3 && webkit && wkversion >= 533
				);
			})();

	// Expose overthrow API
	w.overthrow = {};

	w.overthrow.addClass = function(){
		if( docElem.className.indexOf( enabledClassName ) === -1 ){
			docElem.className += " " + enabledClassName;
		}
	};

	w.overthrow.removeClass = function(){
		docElem.className = docElem.className.replace( enabledClassName, "" );
	};

	// Enable and potentially polyfill overflow
	w.overthrow.set = function(){

		// If nativeOverflow or at least the element canBeFilledWithPoly, add a class to cue CSS that assumes overflow scrolling will work (setting height on elements and such)
		if( nativeOverflow ){
			w.overthrow.addClass();
		}

	};

	// expose polyfillable
	w.overthrow.canBeFilledWithPoly = canBeFilledWithPoly;

	// Destroy everything later. If you want to.
	w.overthrow.forget = function(){

		w.overthrow.removeClass();

	};

	// Expose overthrow API
	w.overthrow.support = nativeOverflow ? "native" : "none";

})( this );
<commit_msg>fixed the playbook match. fixes #39<commit_after>/*! Overthrow. An overflow:auto polyfill for responsive design. (c) 2012: Scott Jehl, Filament Group, Inc. http://filamentgroup.github.com/Overthrow/license.txt */
(function( w, undefined ){

	var doc = w.document,
		docElem = doc.documentElement,
		enabledClassName = "overthrow-enabled",

		// Touch events are used in the polyfill, and thus are a prerequisite
		canBeFilledWithPoly = "ontouchmove" in doc,

		// The following attempts to determine whether the browser has native overflow support
		// so we can enable it but not polyfill
		nativeOverflow =
			// Features-first. iOS5 overflow scrolling property check - no UA needed here. thanks Apple :)
			"WebkitOverflowScrolling" in docElem.style ||
			// Test the windows scrolling property as well
			"msOverflowStyle" in docElem.style ||
			// Touch events aren't supported and screen width is greater than X
			// ...basically, this is a loose "desktop browser" check.
			// It may wrongly opt-in very large tablets with no touch support.
			( !canBeFilledWithPoly && w.screen.width > 800 ) ||
			// Hang on to your hats.
			// Whitelist some popular, overflow-supporting mobile browsers for now and the future
			// These browsers are known to get overlow support right, but give us no way of detecting it.
			(function(){
				var ua = w.navigator.userAgent,
					// Webkit crosses platforms, and the browsers on our list run at least version 534
					webkit = ua.match( /AppleWebKit\/([0-9]+)/ ),
					wkversion = webkit && webkit[1],
					wkLte534 = webkit && wkversion >= 534;

				return (
					/* Android 3+ with webkit gte 534
					~: Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13 */
					ua.match( /Android ([0-9]+)/ ) && RegExp.$1 >= 3 && wkLte534 ||
					/* Blackberry 7+ with webkit gte 534
					~: Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en-US) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.0.0 Mobile Safari/534.11+ */
					ua.match( / Version\/([0-9]+)/ ) && RegExp.$1 >= 0 && w.blackberry && wkLte534 ||
					/* Blackberry Playbook with webkit gte 534
					~: Mozilla/5.0 (PlayBook; U; RIM Tablet OS 1.0.0; en-US) AppleWebKit/534.8+ (KHTML, like Gecko) Version/0.0.1 Safari/534.8+ */
					ua.indexOf( "PlayBook" ) > -1 && wkLte534 && !ua.indexOf( "Android 2" ) === -1 ||
					/* Firefox Mobile (Fennec) 4 and up
					~: Mozilla/5.0 (Mobile; rv:15.0) Gecko/15.0 Firefox/15.0 */
					ua.match(/Firefox\/([0-9]+)/) && RegExp.$1 >= 4 ||
					/* WebOS 3 and up (TouchPad too)
					~: Mozilla/5.0 (hp-tablet; Linux; hpwOS/3.0.0; U; en-US) AppleWebKit/534.6 (KHTML, like Gecko) wOSBrowser/233.48 Safari/534.6 TouchPad/1.0 */
					ua.match( /wOSBrowser\/([0-9]+)/ ) && RegExp.$1 >= 233 && wkLte534 ||
					/* Nokia Browser N8
					~: Mozilla/5.0 (Symbian/3; Series60/5.2 NokiaN8-00/012.002; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/533.4 (KHTML, like Gecko) NokiaBrowser/7.3.0 Mobile Safari/533.4 3gpp-gba
					~: Note: the N9 doesn't have native overflow with one-finger touch. wtf */
					ua.match( /NokiaBrowser\/([0-9\.]+)/ ) && parseFloat(RegExp.$1) === 7.3 && webkit && wkversion >= 533
				);
			})();

	// Expose overthrow API
	w.overthrow = {};

	w.overthrow.addClass = function(){
		if( docElem.className.indexOf( enabledClassName ) === -1 ){
			docElem.className += " " + enabledClassName;
		}
	};

	w.overthrow.removeClass = function(){
		docElem.className = docElem.className.replace( enabledClassName, "" );
	};

	// Enable and potentially polyfill overflow
	w.overthrow.set = function(){

		// If nativeOverflow or at least the element canBeFilledWithPoly, add a class to cue CSS that assumes overflow scrolling will work (setting height on elements and such)
		if( nativeOverflow ){
			w.overthrow.addClass();
		}

	};

	// expose polyfillable
	w.overthrow.canBeFilledWithPoly = canBeFilledWithPoly;

	// Destroy everything later. If you want to.
	w.overthrow.forget = function(){

		w.overthrow.removeClass();

	};

	// Expose overthrow API
	w.overthrow.support = nativeOverflow ? "native" : "none";

})( this );
<|endoftext|>


<commit_before>(function(window){
    function Plane(planeBitmap){
        this.initialize(planeBitmap);
    }
    Plane.prototype = new createjs.Container();

    Plane.prototype.container_initialize = Plane.prototype.initialize;

    Plane.prototype.initialize = function(planeBitmap) {
        this.container_initialize();
        this.name = 'plane';
        this.setBounds(0, 0, settings.plane.width, settings.plane.height);
        this.width = settings.plane.width/2;
        this.height = settings.plane.height/2;
        this.regX = settings.plane.width/2;
        this.regY = settings.plane.height/2;
        this.x = Math.floor(Math.random()*(settings.width-1000));
        this.y = 3977;
        this.vel = 0;
        this.velX = 0;
        this.velY = -0;
        this.velRotation = 0;
        this.engineOn = false;
        this.gravity = {
            y : 0,
            apply : function(){

            }
        }
        this.gravity.apply();
        //this.addEventListener("click", function(event) { alert("clicked"); })
        this.addChild(planeBitmap);
        assets.tickArray.push(this);
    }
    Plane.prototype.tick = function(){
        //----Rotating the plane----//
        this.rotation = -Math.atan2(assets.mouse.x - this.x-assets.world.x, assets.mouse.y - this.y-assets.world.y)*180/Math.PI+90;
        if(this.vel>1){
                this.velRotation = this.velRotation + ((this.rotation-this.velRotation)*((settings.plane.maxVel-this.vel)/settings.plane.maxVel));
                console.log('vel: ' + ((settings.plane.maxVel-this.vel)/settings.plane.maxVel) + '\nrotation: ' + this.rotation + '\nvelRotation: ' + this.velRotation);
        }
        //----Moving the plane----//
        //Vector velocity
        if(this.vel<settings.plane.maxVel && this.engineOn){
            this.vel+=/*((Math.cos(this.rotation * (Math.PI/180))) * */0.3//);
        }
        //Velocity Y
        this.velY = ((Math.sin(this.velRotation * (Math.PI/180))) * this.vel);
        if(this.y+this.height<settings.height-settings.ground.height){
            if(this.vel<2){
                this.velY += (this.vel<1) ? this.velY : 1;
            }
        }
        else if(this.velY>0){
            this.velY = 0;
            //this.vel = ((Math.cos(this.velRotation * (Math.PI/180))) * this.vel);
        }
        this.y+=this.velY;
        //Velocity X
        if(this.x < settings.width-settings.plane.width/2 && this.x+settings.plane.width/2 > 0){
            this.velX = ((Math.cos(this.velRotation * (Math.PI/180))) * this.vel);
            this.x+=this.velX;
        }
        //Moving the world with the plane
        assets.world.x = canvas.width/2 - this.x;
        assets.world.y = canvas.height/2 - this.y;
        if(assets.world.x>0) assets.world.x = 0;
        if(assets.world.y>0) assets.world.y = 0;
        if(assets.world.x<canvas.width-settings.width) assets.world.x = canvas.width-settings.width;
        if(assets.world.y<canvas.height-settings.height) assets.world.y = canvas.height-settings.height;
        //console.log(((assets.mouse.x-this.x-assets.world.x)/(assets.mouse.y - this.y-assets.world.y+(assets.mouse.x-this.x-assets.world.x))));
        if(assets.plane.engineOn){
            //console.log('Engine on!');
            if(Math.sqrt(Math.pow(this.velX, 2) + Math.pow(this.velY, 2)) < settings.plane.maxVel){
                this.velX += Math.cos(this.velRotation/180)*0.3;
                if(Math.sqrt(Math.pow(this.velX, 2) + Math.pow(this.velY, 2)) > settings.plane.takeOffVel){
                    //this.velY += Math
                }
            }
        }
        else{
            //console.log('Engine off!');
            //if(Math.sqrt(Math.pow(this.velX, 2) + Math.pow(this.velY, 2)) < settings.plane.maxVel){
            if(this.velX>0){
                this.velX -= 0.05;   //Air drag. later, if needed in other places, put under settings.
            }
            //}
        }
    }
    function applyGravity(){console.log('gravity applied at: ' + this.gravity.y);}
    window.Plane = Plane;
} (window));<commit_msg>Plane Cont'd<commit_after>(function(window){
    function Plane(planeBitmap){
        this.initialize(planeBitmap);
    }
    Plane.prototype = new createjs.Container();

    Plane.prototype.container_initialize = Plane.prototype.initialize;

    Plane.prototype.initialize = function(planeBitmap) {
        this.container_initialize();
        this.name = 'plane';
        this.setBounds(0, 0, settings.plane.width, settings.plane.height);
        this.width = settings.plane.width/2;
        this.height = settings.plane.height/2;
        this.regX = settings.plane.width/2;
        this.regY = settings.plane.height/2;
        this.x = Math.floor(Math.random()*(settings.width-1000));
        this.y = 3977;
        this.vel = 0;
        this.velX = 0;
        this.velY = -0;
        this.velRotation = 0;
        this.cursorRotation = 0;
        this.engineOn = false;
        this.gravity = {
            y : 0,
            apply : function(){

            }
        }
        this.gravity.apply();
        //this.addEventListener("click", function(event) { alert("clicked"); })
        this.addChild(planeBitmap);
        assets.tickArray.push(this);
    }
    Plane.prototype.tick = function(){
        //----Rotating the plane----//
        this.cursorRotation = -Math.atan2(assets.mouse.x - this.x-assets.world.x, assets.mouse.y - this.y-assets.world.y)*180/Math.PI+90;

        if(Math.abs(this.cursorRotation-this.velRotation)>180){
            if(this.cursorRotation>this.velRotation) this.velRotation+=360;
            else this.velRotation-=360;
        }
        if(this.vel>1){
            this.velRotation = (this.velRotation + ((this.cursorRotation-this.velRotation)*(this.vel/(settings.plane.maxVel+200))));
             console.log('+vel: ' + this.vel + '\nrotation: ' + this.cursorRotation + '\nvelRotation: ' + this.velRotation);
        } else {
            this.velRotation = (this.velRotation + ((this.cursorRotation-this.velRotation)*(1/settings.plane.maxVel)));
            console.log('-vel: ' + this.vel + '\nrotation: ' + this.cursorRotation + '\nvelRotation: ' + this.velRotation);
        }
        this.rotation = this.velRotation;
        //----Moving the plane----//
        //Vector velocity
        if(this.vel<settings.plane.maxVel && this.engineOn){
            this.vel+=/*((Math.cos(this.cursorRotation * (Math.PI/180))) * */0.3//);
        }
        else if(this.vel>0) this.vel-=0.5;
        //Velocity Y
        this.velY = ((Math.sin(this.velRotation * (Math.PI/180))) * this.vel);
        if(this.y+this.height<settings.height-settings.ground.height){
            //if(this.vel<2){
                this.velY += (this.vel<1) ? this.velY : 1;
            //}
        }
        else if(this.velY>0){
            this.velY = 0;
            //this.vel = ((Math.cos(this.velRotation * (Math.PI/180))) * this.vel);
        }
        this.y+=this.velY;
        //Velocity X
        if(this.x < settings.width-settings.plane.width/2 && this.x+settings.plane.width/2 > 0){
            this.velX = ((Math.cos(this.velRotation * (Math.PI/180))) * this.vel);
            this.x+=this.velX;
        }
        //Moving the world with the plane
        assets.world.x = canvas.width/2 - this.x;
        assets.world.y = canvas.height/2 - this.y;
        if(assets.world.x>0) assets.world.x = 0;
        if(assets.world.y>0) assets.world.y = 0;
        if(assets.world.x<canvas.width-settings.width) assets.world.x = canvas.width-settings.width;
        if(assets.world.y<canvas.height-settings.height) assets.world.y = canvas.height-settings.height;
        //console.log(((assets.mouse.x-this.x-assets.world.x)/(assets.mouse.y - this.y-assets.world.y+(assets.mouse.x-this.x-assets.world.x))));
        if(assets.plane.engineOn){
            //console.log('Engine on!');
            if(Math.sqrt(Math.pow(this.velX, 2) + Math.pow(this.velY, 2)) < settings.plane.maxVel){
                this.velX += Math.cos(this.velRotation/180)*0.3;
                if(Math.sqrt(Math.pow(this.velX, 2) + Math.pow(this.velY, 2)) > settings.plane.takeOffVel){
                    //this.velY += Math
                }
            }
        }
        else{
            //console.log('Engine off!');
            //if(Math.sqrt(Math.pow(this.velX, 2) + Math.pow(this.velY, 2)) < settings.plane.maxVel){
            if(this.velX>0){
                this.velX -= 0.05;   //Air drag. later, if needed in other places, put under settings.
            }
            //}
        }
    }
    function applyGravity(){console.log('gravity applied at: ' + this.gravity.y);}
    window.Plane = Plane;
} (window));<|endoftext|>