<commit_before>var myFirebaseRef = new Firebase("https://fiery-inferno-6630.firebaseio.com/");

var message = myFirebaseRef.child("message");
var selection = myFirebaseRef.child("selection");
var gyr_x = myFirebaseRef.child("gyr_x");
var gyr_y = myFirebaseRef.child("gyr_y");
var gyr_z = myFirebaseRef.child("gyr_z");
var acc_x = myFirebaseRef.child("acc_x");
var acc_y = myFirebaseRef.child("acc_y");
var acc_z = myFirebaseRef.child("acc_z");

var go = myFirebaseRef.child("go");

var $right = $(".glyphicon-chevron-right");
var $left = $(".glyphicon-chevron-left");

var $first = $('div:first', '#menu'),
	$last = $('div:last', '#menu');

dir = {}

var going = false;

dir.gyr_x_val = 0;
dir.gyr_y_val = 0;
dir.gyr_z_val = 0;
dir.acc_x_val = 0;
dir.acc_y_val = 0;
dir.acc_z_val = 0;

message.on("value", function(snapshot) {
	if(snapshot.val() != null) {
		$("#message").text(snapshot.val());
	}
});

selection.on("value", function(snapshot) {
  	if(snapshot.val() == "up") {
  		var $prev, $selected = $(".selected");

	    $prev = $selected.prev('div').length ? $selected.prev('div') : $last;
	    $selected.removeClass("selected");
	    $prev.addClass('selected');
  	} else if(snapshot.val() == "down") {
  		var $next, $selected = $(".selected");

	    $next = $selected.next('div').length ? $selected.next('div') : $first;
	    $selected.removeClass("selected");
	    $next.addClass('selected');
  	} else if(snapshot.val() == "Toggle") {
  		console.log("toggle");
  		$selected = $(".selected");
  		$selected.click();
  	}
  	message.set(null);
});

gyr_x.on("value", function(snapshot) {
	var val = Math.round( snapshot.val() * 10) / 10
	if(val > 2) {
		dir.gyr_x_val = 1
	} else if (val < -2) {
		dir.gyr_x_val = -1
	} else if (val > -.05 && val < .05){
		dir.gyr_x_val = 0;
	}
	$("#gyr_x").text(dir.gyr_x_val);
});

gyr_y.on("value", function(snapshot) {
	var val = Math.round( snapshot.val() * 10) / 10
	if(val > 2) {
		dir.gyr_y_val = 1
	} else if (val < -2) {
		dir.gyr_y_val = -1
	} else if (val > -.05 && val < .05) {
		dir.gyr_y_val = 0;
	}
	$("#gyr_y").text(dir.gyr_y_val);
});

gyr_z.on("value", function(snapshot) {
	var val = Math.round( snapshot.val() * 10) / 10
	if(val > 2) {
		dir.gyr_z_val = 1
	} else if (val < -2) {
		dir.gyr_z_val = -1
	} else if (val > -.1 && val < .1){
		dir.gyr_z_val = 0;
	}
	$("#gyr_z").text(dir.gyr_z_val);
});

acc_x.on("value", function(snapshot) {
	dir.acc_x_val += snapshot.val()
	$("#acc_x").text(dir.acc_x_val);
});

acc_y.on("value", function(snapshot) {
	dir.acc_y_val = Math.round( snapshot.val() * 10) / 10
	$("#acc_y").text(dir.acc_y_val);
});

acc_z.on("value", function(snapshot) {
	dir.acc_z_val = Math.round( snapshot.val() * 10) / 10
	$("#acc_z").text(dir.acc_z_val);
});

go.on("value", function(snapshot) {
	going = snapshot.val();
})

$( ".settings" ).click(function() {
	console.log("settings");
	$("#settings").toggle();
});

$( ".jetpack_dir" ).click(function() {
	console.log("jetpack_dir");
	$("#jetpack").toggle();
});

$(".message").click(function() {
	$("#message").text("Messages sent!")
	$("#message").fadeOut( "slow" , function() {
		$("#message").text("");
		$("#message").show();
	});
})

var renderer	= new THREE.WebGLRenderer({
	antialias	: true
});
renderer.setSize( window.innerWidth, window.innerHeight );
document.getElementById('hud').appendChild( renderer.domElement );
renderer.shadowMapEnabled	= true

var onRenderFcts= [];
var scene	= new THREE.Scene();
var camera	= new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 1000 );
camera.position.z = 1;
var light	= new THREE.AmbientLight( 0x222222 )
scene.add( light )
var light	= new THREE.DirectionalLight( 0xffffff, 1 )
light.position.set(5,5,5)
scene.add( light )
light.castShadow	= true
light.shadowCameraNear	= 0.01
light.shadowCameraFar	= 15
light.shadowCameraFov	= 45
light.shadowCameraLeft	= -1
light.shadowCameraRight	=  1
light.shadowCameraTop	=  1
light.shadowCameraBottom= -1
// light.shadowCameraVisible	= true
light.shadowBias	= 0.001
light.shadowDarkness	= 0.2
light.shadowMapWidth	= 1024
light.shadowMapHeight	= 1024

//////////////////////////////////////////////////////////////////////////////////
//		added starfield							//
//////////////////////////////////////////////////////////////////////////////////

var starSphere	= THREEx.Planets.createStarfield()
scene.add(starSphere)

//////////////////////////////////////////////////////////////////////////////////
//		add an object and make it move					//
//////////////////////////////////////////////////////////////////////////////////
// var datGUI	= new dat.GUI()
var containerEarth	= new THREE.Object3D()
//containerEarth.rotateZ(-23.4 * Math.PI/180)
containerEarth.position.z	= 0
scene.add(containerEarth)
var moonMesh	= THREEx.Planets.createMoon()
moonMesh.position.set(0.5,0.5,0.5)
moonMesh.scale.multiplyScalar(1/5)
moonMesh.receiveShadow	= true
//moonMesh.castShadow	= true
containerEarth.add(moonMesh)
var earthMesh	= THREEx.Planets.createEarth()
earthMesh.receiveShadow	= true
//earthMesh.castShadow	= true
containerEarth.add(earthMesh)
// onRenderFcts.push(function(delta, now){
// 	earthMesh.rotation.y += 1/32 * delta;
// })
var geometry	= new THREE.SphereGeometry(0.5, 32, 32)
var material	= THREEx.createAtmosphereMaterial()
material.uniforms.glowColor.value.set(0x00b3ff)
material.uniforms.coeficient.value	= 0.8
material.uniforms.power.value		= 2.0
var mesh	= new THREE.Mesh(geometry, material );
mesh.scale.multiplyScalar(1.01);
containerEarth.add( mesh );

// new THREEx.addAtmosphereMaterial2DatGui(material, datGUI)
var geometry	= new THREE.SphereGeometry(0.5, 32, 32)
var material	= THREEx.createAtmosphereMaterial()
material.side	= THREE.BackSide
material.uniforms.glowColor.value.set(0x00b3ff)
material.uniforms.coeficient.value	= 0.5
material.uniforms.power.value		= 4.0
var mesh	= new THREE.Mesh(geometry, material );
mesh.scale.multiplyScalar(1.15);
containerEarth.add( mesh );

// new THREEx.addAtmosphereMaterial2DatGui(material, datGUI)
var earthCloud	= THREEx.Planets.createEarthCloud()
earthCloud.receiveShadow	= true
//earthCloud.castShadow	= true
containerEarth.add(earthCloud)
onRenderFcts.push(function(delta, now){
	earthCloud.rotation.y += 1/8 * delta;
})

//////////////////////////////////////////////////////////////////////////////////
//		Camera Controls							//
//////////////////////////////////////////////////////////////////////////////////
// var mouse	= {x : 0, y : 0}
// document.addEventListener('mousemove', function(event){
// 	mouse.x	= (dir.gyr_x_val / window.innerWidth ) - 0.5
// 	mouse.y	= (dir.gyr_y_val / window.innerHeight) - 0.5
// }, false)
onRenderFcts.push(function(delta, now){
	//camera.position.x -= (dir.acc_x_val/100 )//- camera.position.x) * (delta*3)
	//camera.position.y -= (dir.acc_z_val/100) //- camera.position.y) * (delta*3)
	if(dir.gyr_x_val >= 1) {
		camera.rotation.x +=.01;
	} else if (dir.gyr_x_val <= -1) {
		camera.rotation.x -= .01;
	}
	if(dir.gyr_z_val >= 1) {
		camera.rotation.y +=.01;
	} else if (dir.gyr_z_val <= -1) {
		camera.rotation.y -= .01;
	}
	if(dir.gyr_y_val >= 1) {
		camera.rotation.z -=.01;
	} else if (dir.gyr_y_val <= -1) {
		camera.rotation.z += .01;
	}

	if(going) {
		camera.position.z -= .001
	}

	camera.position.x += dir.acc_x / 100;

	//camera.position.z += (dir.gyr_x_val/100) //- camera.position.z) //* (delta*3)
	// camera.rotation.x += (dir.gyr_x_val/100 )//- camera.rotation.x) * (delta*3)
	// camera.rotation.y += (dir.gyr_y_val/100 )//- camera.rotation.y) * (delta*3)
	// camera.rotation.z += (dir.gyr_z_val/100 )//- camera.rotation.z) * (delta*3)

	// camera.position.x += (gyr_x*5 - camera.position.x) * (delta*3);
	// camera.position.y += (gyr_y*5 - camera.position.y) * (delta*3);
	//camera.lookAt( scene.position )
})
//////////////////////////////////////////////////////////////////////////////////
//		render the scene						//
//////////////////////////////////////////////////////////////////////////////////
onRenderFcts.push(function(){
	renderer.render( scene, camera );
})

//////////////////////////////////////////////////////////////////////////////////
//		loop runner							//
//////////////////////////////////////////////////////////////////////////////////
var lastTimeMsec= null
requestAnimationFrame(function animate(nowMsec){
	// keep looping
	requestAnimationFrame( animate );
	// measure time
	lastTimeMsec	= lastTimeMsec || nowMsec-1000/60
	var deltaMsec	= Math.min(200, nowMsec - lastTimeMsec)
	lastTimeMsec	= nowMsec
	// call each update function
	onRenderFcts.forEach(function(onRenderFct){
		onRenderFct(deltaMsec/1000, nowMsec/1000)
	})
})<commit_msg>stuff<commit_after>var myFirebaseRef = new Firebase("https://fiery-inferno-6630.firebaseio.com/");

var message = myFirebaseRef.child("message");
var selection = myFirebaseRef.child("selection");
var gyr_x = myFirebaseRef.child("gyr_x");
var gyr_y = myFirebaseRef.child("gyr_y");
var gyr_z = myFirebaseRef.child("gyr_z");
var acc_x = myFirebaseRef.child("acc_x");
var acc_y = myFirebaseRef.child("acc_y");
var acc_z = myFirebaseRef.child("acc_z");

var go = myFirebaseRef.child("go");

var $right = $(".glyphicon-chevron-right");
var $left = $(".glyphicon-chevron-left");

var $first = $('div:first', '#menu'),
	$last = $('div:last', '#menu');

dir = {}

var going = false;

dir.gyr_x_val = 0;
dir.gyr_y_val = 0;
dir.gyr_z_val = 0;
dir.acc_x_val = 0;
dir.acc_y_val = 0;
dir.acc_z_val = 0;

message.on("value", function(snapshot) {
	if(snapshot.val() != null) {
		$("#message").text(snapshot.val());
	}
});

selection.on("value", function(snapshot) {
  	if(snapshot.val() == "up") {
  		var $prev, $selected = $(".selected");

	    $prev = $selected.prev('div').length ? $selected.prev('div') : $last;
	    $selected.removeClass("selected");
	    $prev.addClass('selected');
  	} else if(snapshot.val() == "down") {
  		var $next, $selected = $(".selected");

	    $next = $selected.next('div').length ? $selected.next('div') : $first;
	    $selected.removeClass("selected");
	    $next.addClass('selected');
  	} else if(snapshot.val() == "Toggle") {
  		console.log("toggle");
  		$selected = $(".selected");
  		$selected.click();
  	}
  	message.set(null);
});

gyr_x.on("value", function(snapshot) {
	var val = Math.round( snapshot.val() * 10) / 10
	if(val > 2) {
		dir.gyr_x_val = 1
	} else if (val < -2) {
		dir.gyr_x_val = -1
	} else if (val > -.05 && val < .05){
		dir.gyr_x_val = 0;
	}
	$("#gyr_x").text(dir.gyr_x_val);
});

gyr_y.on("value", function(snapshot) {
	var val = Math.round( snapshot.val() * 10) / 10
	if(val > 2) {
		dir.gyr_y_val = 1
	} else if (val < -2) {
		dir.gyr_y_val = -1
	} else if (val > -.05 && val < .05) {
		dir.gyr_y_val = 0;
	}
	$("#gyr_y").text(dir.gyr_y_val);
});

gyr_z.on("value", function(snapshot) {
	var val = Math.round( snapshot.val() * 10) / 10
	if(val > 2) {
		dir.gyr_z_val = 1
	} else if (val < -2) {
		dir.gyr_z_val = -1
	} else if (val > -.1 && val < .1){
		dir.gyr_z_val = 0;
	}
	$("#gyr_z").text(dir.gyr_z_val);
});

acc_x.on("value", function(snapshot) {
	dir.acc_x_val += snapshot.val()
	$("#acc_x").text(dir.acc_x_val);
});

acc_y.on("value", function(snapshot) {
	dir.acc_y_val = Math.round( snapshot.val() * 10) / 10
	$("#acc_y").text(dir.acc_y_val);
});

acc_z.on("value", function(snapshot) {
	dir.acc_z_val = Math.round( snapshot.val() * 10) / 10
	$("#acc_z").text(dir.acc_z_val);
});

go.on("value", function(snapshot) {
	going = snapshot.val();
})

$( ".settings" ).click(function() {
	console.log("settings");
	$("#settings").toggle();
});

$( ".jetpack_dir" ).click(function() {
	console.log("jetpack_dir");
	$("#jetpack").toggle();
});

$(".message").click(function() {
	$("#message").text("Messages sent!")
	$("#message").fadeOut( "slow" , function() {
		$("#message").text("");
		$("#message").show();
	});
})

var renderer	= new THREE.WebGLRenderer({
	antialias	: true
});
renderer.setSize( window.innerWidth, window.innerHeight );
document.getElementById('hud').appendChild( renderer.domElement );
renderer.shadowMapEnabled	= true

var onRenderFcts= [];
var scene	= new THREE.Scene();
var camera	= new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 1000 );
camera.position.z = 1;
var light	= new THREE.AmbientLight( 0x222222 )
scene.add( light )
var light	= new THREE.DirectionalLight( 0xffffff, 1 )
light.position.set(5,5,5)
scene.add( light )
light.castShadow	= true
light.shadowCameraNear	= 0.01
light.shadowCameraFar	= 15
light.shadowCameraFov	= 45
light.shadowCameraLeft	= -1
light.shadowCameraRight	=  1
light.shadowCameraTop	=  1
light.shadowCameraBottom= -1
// light.shadowCameraVisible	= true
light.shadowBias	= 0.001
light.shadowDarkness	= 0.2
light.shadowMapWidth	= 1024
light.shadowMapHeight	= 1024

//////////////////////////////////////////////////////////////////////////////////
//		added starfield							//
//////////////////////////////////////////////////////////////////////////////////

var starSphere	= THREEx.Planets.createStarfield()
scene.add(starSphere)

//////////////////////////////////////////////////////////////////////////////////
//		add an object and make it move					//
//////////////////////////////////////////////////////////////////////////////////
// var datGUI	= new dat.GUI()
var containerEarth	= new THREE.Object3D()
//containerEarth.rotateZ(-23.4 * Math.PI/180)
containerEarth.position.z	= 0
scene.add(containerEarth)
var moonMesh	= THREEx.Planets.createMoon()
moonMesh.position.set(0.5,0.5,0.5)
moonMesh.scale.multiplyScalar(1/5)
moonMesh.receiveShadow	= true
//moonMesh.castShadow	= true
containerEarth.add(moonMesh)
var earthMesh	= THREEx.Planets.createEarth()
earthMesh.receiveShadow	= true
//earthMesh.castShadow	= true
containerEarth.add(earthMesh)
// onRenderFcts.push(function(delta, now){
// 	earthMesh.rotation.y += 1/32 * delta;
// })
var geometry	= new THREE.SphereGeometry(0.5, 32, 32)
var material	= THREEx.createAtmosphereMaterial()
material.uniforms.glowColor.value.set(0x00b3ff)
material.uniforms.coeficient.value	= 0.8
material.uniforms.power.value		= 2.0
var mesh	= new THREE.Mesh(geometry, material );
mesh.scale.multiplyScalar(1.01);
containerEarth.add( mesh );

// new THREEx.addAtmosphereMaterial2DatGui(material, datGUI)
var geometry	= new THREE.SphereGeometry(0.5, 32, 32)
var material	= THREEx.createAtmosphereMaterial()
material.side	= THREE.BackSide
material.uniforms.glowColor.value.set(0x00b3ff)
material.uniforms.coeficient.value	= 0.5
material.uniforms.power.value		= 4.0
var mesh	= new THREE.Mesh(geometry, material );
mesh.scale.multiplyScalar(1.15);
containerEarth.add( mesh );

// new THREEx.addAtmosphereMaterial2DatGui(material, datGUI)
var earthCloud	= THREEx.Planets.createEarthCloud()
earthCloud.receiveShadow	= true
//earthCloud.castShadow	= true
containerEarth.add(earthCloud)
onRenderFcts.push(function(delta, now){
	earthCloud.rotation.y += 1/8 * delta;
})

//////////////////////////////////////////////////////////////////////////////////
//		Camera Controls							//
//////////////////////////////////////////////////////////////////////////////////
// var mouse	= {x : 0, y : 0}
// document.addEventListener('mousemove', function(event){
// 	mouse.x	= (dir.gyr_x_val / window.innerWidth ) - 0.5
// 	mouse.y	= (dir.gyr_y_val / window.innerHeight) - 0.5
// }, false)
onRenderFcts.push(function(delta, now){
	//camera.position.x -= (dir.acc_x_val/100 )//- camera.position.x) * (delta*3)
	//camera.position.y -= (dir.acc_z_val/100) //- camera.position.y) * (delta*3)
	if(dir.gyr_x_val >= 1) {
		camera.rotation.x +=.01;
	} else if (dir.gyr_x_val <= -1) {
		camera.rotation.x -= .01;
	}
	if(dir.gyr_z_val >= 1) {
		camera.rotation.y +=.01;
	} else if (dir.gyr_z_val <= -1) {
		camera.rotation.y -= .01;
	}
	if(dir.gyr_y_val >= 1) {
		camera.rotation.z -=.01;
	} else if (dir.gyr_y_val <= -1) {
		camera.rotation.z += .01;
	}

	if(going) {
		camera.position.z -= .001
	}

	camera.position.x += dir.acc_x_val / 100;

	//camera.position.z += (dir.gyr_x_val/100) //- camera.position.z) //* (delta*3)
	// camera.rotation.x += (dir.gyr_x_val/100 )//- camera.rotation.x) * (delta*3)
	// camera.rotation.y += (dir.gyr_y_val/100 )//- camera.rotation.y) * (delta*3)
	// camera.rotation.z += (dir.gyr_z_val/100 )//- camera.rotation.z) * (delta*3)

	// camera.position.x += (gyr_x*5 - camera.position.x) * (delta*3);
	// camera.position.y += (gyr_y*5 - camera.position.y) * (delta*3);
	//camera.lookAt( scene.position )
})
//////////////////////////////////////////////////////////////////////////////////
//		render the scene						//
//////////////////////////////////////////////////////////////////////////////////
onRenderFcts.push(function(){
	renderer.render( scene, camera );
})

//////////////////////////////////////////////////////////////////////////////////
//		loop runner							//
//////////////////////////////////////////////////////////////////////////////////
var lastTimeMsec= null
requestAnimationFrame(function animate(nowMsec){
	// keep looping
	requestAnimationFrame( animate );
	// measure time
	lastTimeMsec	= lastTimeMsec || nowMsec-1000/60
	var deltaMsec	= Math.min(200, nowMsec - lastTimeMsec)
	lastTimeMsec	= nowMsec
	// call each update function
	onRenderFcts.forEach(function(onRenderFct){
		onRenderFct(deltaMsec/1000, nowMsec/1000)
	})
})<|endoftext|>


<commit_before>var fs = require('fs');
var redis = require('redis');
var slack = require('slack-notify')(process.env.SLACK_URL);

// ------------------

var SpotifyWebApi = require('spotify-web-api-node');
var spotifyApi = new SpotifyWebApi({
  clientId: process.env.SPOTIFY_CLIENT_ID,
  clientSecret: process.env.SPOTIFY_CLIENT_SECRET
});
var spotifyUser = process.env.SPOTIFY_USERNAME;
var spotifyPlaylistId = process.env.SPOTIFY_PLAYLIST;
var redisUrl = process.env.REDISTOGO_URL;
var runWebServer = process.env.VCAP_APP || false;

// ------------------
var lastDate;
var redisClient;

if (redisUrl) {
  var rtg = require('url').parse(redisUrl);
  redisClient = redis.createClient(rtg.port, rtg.hostname);
  redisClient.auth(rtg.auth.split(":")[1]);

  redisClient.on('error', function (err) {
    console.log("Redis - Error " + err);
  });
  redisClient.get("lastDate", function(err, value) {
    if (!err) {
      lastDate = new Date(value);
    }
  });
} else {
  fs.readFile('./last_date.txt', {encoding: 'UTF-8'}, function(err, date){
     lastDate = date ? new Date(date) : void 0;
  });
}

var start = false;
function grantClient() {
  spotifyApi.clientCredentialsGrant()
    .then(function(data) {
      console.log('Spotify - got new access token, valid for', data.expires_in, 'seconds', data);

      spotifyApi.setAccessToken(data.access_token);
      start = true;

      setTimeout(grantClient, data.expires_in*1000);
    }, function(err) {
      console.log('Spotify - Error retrieving an access token:', err);
      process.exit(1);
    });
}

function writeLastDate(date) {
  lastDate = date

  if (redisUrl) {
      redisClient.set('lastDate', date);
  } else {
     fs.writeFile('./last_date.txt', date, function() {});
  }
}

function fetchPlaylist() {
  if (!start) {
    return;
  }

  console.log('Playlist last known song added at:', lastDate);
  spotifyApi.getPlaylist(spotifyUser, spotifyPlaylistId, { limit: 1000,
      fields: 'tracks.items(added_by.id,added_at,track(name,artists.name,album.name)),name,external_urls.spotify'})
    .then(function(data) {
      console.log('Spotify - playlist fetched:', data);
      var date = 0;
      for (var i in data.tracks.items) {
        date = new Date(data.tracks.items[i].added_at);
        if((lastDate === undefined) || (date > lastDate)) {
          post(data.name,
            data.external_urls.spotify,
            data.tracks.items[i].added_by ? data.tracks.items[i].added_by.id : 'Unknown',
            data.tracks.items[i].track.name,
            data.tracks.items[i].track.artists);
        }
      }
      console.log('Spotify - last date in playlist', date);
      writeLastDate(date);
    }, function(err) {
      console.log('Spotify - Error retrieving playlist:', err);
    });
}

slack.onError = function (err) {
  console.log('Slack - Error:', err);
};

var slacker = slack.extend({
  username: 'spotify-playlist',
  icon_url: 'http://icons.iconarchive.com/icons/xenatt/the-circle/256/App-Spotify-icon.png',
  unfurl_media : false
});

function post(list_name, list_url, added_by, trackname, artists) {
  var text = 'New track added by ' + added_by + ' - *' + trackname+'* with '+artists[0].name+' in list <'+list_url+'|'+list_name+'>';
  console.log(text);
  slacker({text: text});
}

function startWebServer() {
  var http = require('http');
  var host = process.env.VCAP_APP_HOST || 'localhost';
  var port = process.env.VCAP_APP_PORT || 1337

  http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.end('No functions and features at this place...' + process.version);
  }).listen(port, null);

  console.log('Server running to provide incoming network connetion for Bluemix at http://' + host + ':' + port + '/');

  // set the current date as the initial date to avoid writing the whole song history to the slack channel
  now = new Date();
  writeLastDate(now);
}

if(runWebServer) {
  startWebServer();
}
grantClient();
setInterval(fetchPlaylist, 1000 * 10);
<commit_msg>Fix new body nesting<commit_after>var fs = require('fs');
var redis = require('redis');
var slack = require('slack-notify')(process.env.SLACK_URL);

// ------------------

var SpotifyWebApi = require('spotify-web-api-node');
var spotifyApi = new SpotifyWebApi({
  clientId: process.env.SPOTIFY_CLIENT_ID,
  clientSecret: process.env.SPOTIFY_CLIENT_SECRET
});
var spotifyUser = process.env.SPOTIFY_USERNAME;
var spotifyPlaylistId = process.env.SPOTIFY_PLAYLIST;
var redisUrl = process.env.REDISTOGO_URL;
var runWebServer = process.env.VCAP_APP || false;

// ------------------
var lastDate;
var redisClient;

if (redisUrl) {
  var rtg = require('url').parse(redisUrl);
  redisClient = redis.createClient(rtg.port, rtg.hostname);
  redisClient.auth(rtg.auth.split(":")[1]);

  redisClient.on('error', function (err) {
    console.log("Redis - Error " + err);
  });
  redisClient.get("lastDate", function(err, value) {
    if (!err) {
      lastDate = new Date(value);
    }
  });
} else {
  fs.readFile('./last_date.txt', {encoding: 'UTF-8'}, function(err, date){
     lastDate = date ? new Date(date) : void 0;
  });
}

var start = false;
function grantClient() {
  spotifyApi.clientCredentialsGrant()
    .then(function(data) {
      console.log('Spotify - got new access token, valid for', data.body.expires_in, 'seconds');

      spotifyApi.setAccessToken(data.access_token);
      start = true;

      setTimeout(grantClient, data.expires_in*1000);
    }, function(err) {
      console.log('Spotify - Error retrieving an access token:', err);
      process.exit(1);
    });
}

function writeLastDate(date) {
  lastDate = date

  if (redisUrl) {
      redisClient.set('lastDate', date);
  } else {
     fs.writeFile('./last_date.txt', date, function() {});
  }
}

function fetchPlaylist() {
  if (!start) {
    return;
  }

  console.log('Playlist last known song added at:', lastDate);
  spotifyApi.getPlaylist(spotifyUser, spotifyPlaylistId, { limit: 1000,
      fields: 'tracks.items(added_by.id,added_at,track(name,artists.name,album.name)),name,external_urls.spotify'})
    .then(function(data) {
      console.log('Spotify - playlist fetched:', data);
      var date = 0;
      for (var i in data.tracks.items) {
        date = new Date(data.tracks.items[i].added_at);
        if((lastDate === undefined) || (date > lastDate)) {
          post(data.name,
            data.external_urls.spotify,
            data.tracks.items[i].added_by ? data.tracks.items[i].added_by.id : 'Unknown',
            data.tracks.items[i].track.name,
            data.tracks.items[i].track.artists);
        }
      }
      console.log('Spotify - last date in playlist', date);
      writeLastDate(date);
    }, function(err) {
      console.log('Spotify - Error retrieving playlist:', err);
    });
}

slack.onError = function (err) {
  console.log('Slack - Error:', err);
};

var slacker = slack.extend({
  username: 'spotify-playlist',
  icon_url: 'http://icons.iconarchive.com/icons/xenatt/the-circle/256/App-Spotify-icon.png',
  unfurl_media : false
});

function post(list_name, list_url, added_by, trackname, artists) {
  var text = 'New track added by ' + added_by + ' - *' + trackname+'* with '+artists[0].name+' in list <'+list_url+'|'+list_name+'>';
  console.log(text);
  slacker({text: text});
}

function startWebServer() {
  var http = require('http');
  var host = process.env.VCAP_APP_HOST || 'localhost';
  var port = process.env.VCAP_APP_PORT || 1337

  http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.end('No functions and features at this place...' + process.version);
  }).listen(port, null);

  console.log('Server running to provide incoming network connetion for Bluemix at http://' + host + ':' + port + '/');

  // set the current date as the initial date to avoid writing the whole song history to the slack channel
  now = new Date();
  writeLastDate(now);
}

if(runWebServer) {
  startWebServer();
}
grantClient();
setInterval(fetchPlaylist, 1000 * 10);
<|endoftext|>


<commit_before>// Enemies our player must avoid
var Enemy = function() {
    // Variables applied to each of our instances go here,
    // we've provided one for you to get started

    // The image/sprite for our enemies, this uses
    // a helper we've provided to easily load images
    this.sprite = 'images/enemy-bug.png';
};

// Update the enemy's position, required method for game
// Parameter: dt, a time delta between ticks
Enemy.prototype.update = function(dt) {
    // You should multiply any movement by the dt parameter
    // which will ensure the game runs at the same speed for
    // all computers.
};

// Draw the enemy on the screen, required method for game
Enemy.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
};

// Now write your own player class
// This class requires an update(), render() and
// a handleInput() method.
var player = function() {

    this.sprite = 'images/char-boy.png';
};

player.prototype.update = function(dt) {
    //TODO: add something here
};

player.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
};

// Now instantiate your objects.

// Place all enemy objects in an array called allEnemies
var allEnemies = [new Enemy, new Enemy, new Enemy];

// Place the player object in a variable called player

// This listens for key presses and sends the keys to your
// Player.handleInput() method. You don't need to modify this.
document.addEventListener('keyup', function(e) {
    var allowedKeys = {
        37: 'left',
        38: 'up',
        39: 'right',
        40: 'down'
    };

    player.handleInput(allowedKeys[e.keyCode]);
});
<commit_msg>change player to Player for object prototype.<commit_after>// Enemies our player must avoid
var Enemy = function() {
    // Variables applied to each of our instances go here,
    // we've provided one for you to get started

    // The image/sprite for our enemies, this uses
    // a helper we've provided to easily load images
    this.sprite = 'images/enemy-bug.png';
};

// Update the enemy's position, required method for game
// Parameter: dt, a time delta between ticks
Enemy.prototype.update = function(dt) {
    // You should multiply any movement by the dt parameter
    // which will ensure the game runs at the same speed for
    // all computers.
};

// Draw the enemy on the screen, required method for game
Enemy.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
};

// Now write your own player class
// This class requires an update(), render() and
// a handleInput() method.
var Player = function() {

    this.sprite = 'images/char-boy.png';
};

Player.prototype.update = function(dt) {

    //TODO: add something here
};

Player.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
};

// Now instantiate your objects.

// Place all enemy objects in an array called allEnemies
var allEnemies = [new Enemy, new Enemy, new Enemy];

// Place the player object in a variable called player

// This listens for key presses and sends the keys to your
// Player.handleInput() method. You don't need to modify this.
document.addEventListener('keyup', function(e) {
    var allowedKeys = {
        37: 'left',
        38: 'up',
        39: 'right',
        40: 'down'
    };

    player.handleInput(allowedKeys[e.keyCode]);
});
<|endoftext|>


<commit_before>
/**
 * Naive bayed classifier.
 *
 * Examples:
 *
 *  var bayes = classifier();
 *  bayes.train('weather is cold', 'weather');
 *  bayer.guess('what is the weathr?');
 *
 * @return {Object}
 * @api public
 */

module.exports = function() {

	/**
	 * Classifier instance.
	 */

  var that = {};

  /**
   * Number of trainings.
   */

  var total = 0;

  /**
   * Number of trainings
   * by category.
   */

  var categories = {};

  /**
   * Uniq array of words used
   * during the training.
   */

  var dictionary = [];

  /**
   * Number of training by
   * category.
   */

  var count = {};

  /**
   * Frequency of words
   * by category.
   */

  var frequency = {};

  /**
   * Train classifier.
   *
   * @param {String} sentence
   * @param {String} category
   * @api public
   */

  that.train = function(sentence, category) {
  	return that;
  };

  /**
   * Classify array of words with category.
   *
   * @param {Array} arr
   * @param {String} category
   * @api public
   */

  that.classify = function(arr, category) {
  	var l = arr.length;
  	update(category, l);
  	while(l--) {
  		var word = arr[l];
  		frequency[category][word] = ++frequency[category][word] || 1;
  		if(~!dictionary.indexOf(word)) dictionary.push(word);
  	}
  	return that;
  };

  /**
   * Guess category.
   *
   * @param {String} sentence
   * @param {String}
   * @api public
   */

  that.guess = function(sentence) {
  	return '';
  };

  /**
   * Probabily a word belongs to
   * a category.
   *
   * @param {String} word
   * @param {String} category
   * @api public
   */

  that.probability = function(word, category) {
  	return ((frequency[category][word] || 0) + 1) / (count[category] + dictionary.length);
  };

  /**
   * Return a uniq category for
   * a list of tokens.
   *
   * @param {String}
   * @api public
   */

  that.categorize = function(arr) {
  	var max = -Infinity;
  	var tokens = frequence(arr);
  	var choice;
  	for(var category in categories) {
  		var prob = Math.log(count[category] / total);
  		for(var token in tokens) {
  			prob += tokens[token] * Math.log(that.probability(token, category));
  		}
  		if (prob > max) {
  		   max = prob
  		   choice = category
  		 }
  	}
  	return choice;
  };

  /**
   * Clone classifier.
   *
   * @return {Object}
   * @api public
   */

  that.clone = function() {
  	return {};
  };

  /**
   * Return the frequencies of
   * a word in a sentence.
   * @note could be used in classify
   *
   * @param {Array} words
   * @param {Object}
   * @api private
   */

  function frequence(words) {
  	var obj = {};
  	for(var l = words.length; l--;) {
  		obj[words[l]] = ++obj[words[l]] || 1;
  	}
  	return obj;
  }

  /**
   * Update/initialize classifier
   * statistics.
   *
   * @param {String} category
   * @param {Number} length (number of words to classify)
   * @api private
   */

  function update(category, length) {
  	count[category] = (count[category] || 0) + length;
  	frequency[category] = frequency[category] || {};
  	categories[category] = ++categories[category] || 1;
  	total++;
  }

  return that;
};

<commit_msg>only accept array of words<commit_after>
/**
 * Naive bayed classifier.
 *
 * Examples:
 *
 *  var bayes = classifier();
 *  bayes.train('weather is cold', 'weather');
 *  bayer.guess('what is the weathr?');
 *
 * @return {Object}
 * @api public
 */

module.exports = function() {

	/**
	 * Classifier instance.
	 */

  var that = {};

  /**
   * Number of trainings.
   */

  var total = 0;

  /**
   * Number of trainings
   * by category.
   */

  var categories = {};

  /**
   * Uniq array of words used
   * during the training.
   */

  var dictionary = [];

  /**
   * Number of training by
   * category.
   */

  var count = {};

  /**
   * Frequency of words
   * by category.
   */

  var frequency = {};

  /**
   * Train classifier.
   *
   * Classify array of words with category.
   *
   * @param {Array} arr
   * @param {String} category
   * @api public
   */

  that.train = function(arr, category) {
  	var l = arr.length;
  	update(category, l);
  	while(l--) {
  		var word = arr[l];
  		frequency[category][word] = ++frequency[category][word] || 1;
  		if(~!dictionary.indexOf(word)) dictionary.push(word);
  	}
  	return that;
  };

  /**
   * Probabily a word belongs to
   * a category.
   *
   * @param {String} word
   * @param {String} category
   * @api public
   */

  that.probability = function(word, category) {
  	return ((frequency[category][word] || 0) + 1) / (count[category] + dictionary.length);
  };

  /**
   * Guess category.
   *
   * Return a uniq category for
   * a list of tokens.
   *
   * @param {String}
   * @api public
   */

  that.guess = function(arr) {
  	var max = -Infinity;
  	var tokens = frequence(arr);
  	var choice;
  	for(var category in categories) {
  		var prob = Math.log(count[category] / total);
  		for(var token in tokens) {
  			prob += tokens[token] * Math.log(that.probability(token, category));
  		}
  		if (prob > max) {
  		   max = prob
  		   choice = category
  		 }
  	}
  	return choice;
  };

  /**
   * Return the frequencies of
   * a word in a sentence.
   * @note could be used in classify
   *
   * @param {Array} words
   * @param {Object}
   * @api private
   */

  function frequence(words) {
  	var obj = {};
  	for(var l = words.length; l--;) {
  		obj[words[l]] = ++obj[words[l]] || 1;
  	}
  	return obj;
  }

  /**
   * Update/initialize classifier
   * statistics.
   *
   * @param {String} category
   * @param {Number} length (number of words to classify)
   * @api private
   */

  function update(category, length) {
  	count[category] = (count[category] || 0) + length;
  	frequency[category] = frequency[category] || {};
  	categories[category] = ++categories[category] || 1;
  	total++;
  }

  return that;
};

<|endoftext|>


<commit_before>/**
 * @copyright Maichong Software Ltd. 2016 http://maichong.it
 * @date 2016-02-22
 * @author Liang <liang@maichong.it>
 */

'use strict';

const alaska = require('alaska');

exports.views = {
  cell: {
    name: 'TextFieldCell',
    field: __dirname + '/lib/cell.js'
  },
  view: {
    name: 'TextFieldView',
    field: __dirname + '/lib/view.js'
  }
};

exports.plain = String;
exports.initSchema = function (field, schema, Model) {
  let options = {
    type: String,
    lowercase: field.lowercase,
    uppercase: field.uppercase,
    trim: field.trim,
    match: field.match instanceof RegExp ? field.match : null,
    maxlength: field.maxlength,
    minlength: field.minlength
  };
  if (field.default !== undefined) {
    options.default = field.default;
  }
  schema.path(field.path, options);
}
/**
 * alaska-admin-view 前端控件初始化参数
 * @param field
 * @param Model
 */
exports.viewOptions = function (field, Model) {
  let options = alaska.Field.viewOptions.apply(this, arguments);
  options.trim = field.trim;
  options.match = field.match instanceof RegExp ? field.match.toString() : field.match;
  options.lowercase = field.lowercase;
  options.uppercase = field.uppercase;
  options.maxlength = field.maxlength instanceof Array ? field.maxlength[0] : field.maxlength;
  options.multiLine = field.multiLine instanceof Array ? field.multiLine[0] : field.multiLine;
  return options;
};
<commit_msg>Schema options<commit_after>/**
 * @copyright Maichong Software Ltd. 2016 http://maichong.it
 * @date 2016-02-22
 * @author Liang <liang@maichong.it>
 */

'use strict';

const alaska = require('alaska');

exports.views = {
  cell: {
    name: 'TextFieldCell',
    field: __dirname + '/lib/cell.js'
  },
  view: {
    name: 'TextFieldView',
    field: __dirname + '/lib/view.js'
  }
};

exports.plain = String;
exports.initSchema = function (field, schema, Model) {
  let options = {
    type: Number
  };
  [
    'get',
    'set',
    'default',
    'index',
    'required',
    'select',
    'trim',
    'match',
    'lowercase',
    'uppercase',
    'maxlength',
    'minlength'
  ].forEach(function (key) {
    if (field[key] !== undefined) {
      options[key] = field[key];
    }
  });
  schema.path(field.path, options);
}
/**
 * alaska-admin-view 前端控件初始化参数
 * @param field
 * @param Model
 */
exports.viewOptions = function (field, Model) {
  let options = alaska.Field.viewOptions.apply(this, arguments);
  options.trim = field.trim;
  options.match = field.match instanceof RegExp ? field.match.toString() : field.match;
  options.lowercase = field.lowercase;
  options.uppercase = field.uppercase;
  options.maxlength = field.maxlength instanceof Array ? field.maxlength[0] : field.maxlength;
  options.multiLine = field.multiLine instanceof Array ? field.multiLine[0] : field.multiLine;
  return options;
};
<|endoftext|>


<commit_before>$(function () {
  // Compare Info API
  var compareInfoParamType = 'noneParam';
  var compareInfoParam = '';
  var compareInfoURL = '/api/rivalWar/menu/getRootCompareInfo.do';
  var compareInfoType = 'GET';
  var compareInfoReturnType = 'json';
  function compareInfoBeforeSendCallback(){ console.log("beforeSendCallback"); }
  function compareInfoSuccessCallback (responseData) {
    console.log(responseData);
    $("#compareInfoTime").text(responseData.calTime);

    $("#botImage").attr("href", responseData.botImageUrl1);

    $("#botVender").attr("href", responseData.botVenderUrl);
    $("#botVender").html(responseData.botVenderText + " ");

    $("#botPost1").attr("href", responseData.botPost1Url);
    $("#botPost1").html(" "+ responseData.botPost1Text);

    $("#botPost2").attr("href", responseData.botPost2Url);
    $("#botPost2").html(" "+ responseData.botPost2Text);

    $("#botPost3").attr("href", responseData.botPost3Url);
    $("#botPost3").html(" "+ responseData.botPost3Text);

    $("#botPost4").attr("href", responseData.botPost4Url);
    $("#botPost4").html(" "+ responseData.botPost4Text);

    $("#botPost5").attr("href", responseData.botPost5Url);
    $("#botPost5").html(" "+ responseData.botPost5Text);

    //mid
    $("#midImage").attr("src", responseData.midImageUrl1);

    $("#midVender").attr("src", responseData.midVenderUrl);
    $("#midVender").html(responseData.midVenderText + " ");

    $("#midPost1").attr("src", responseData.midPost1Url);
    $("#midPost1").html(" "+ responseData.midPost1Text);

    $("#midPost2").attr("src", responseData.midPost2Url);
    $("#midPost2").html(" "+ responseData.midPost2Text);

    $("#midPost3").attr("src", responseData.midPost3Url);
    $("#midPost3").html(" "+ responseData.midPost3Text);

    $("#midPost4").attr("src", responseData.midPost4Url);
    $("#midPost4").html(" "+ responseData.midPost4Text);

    $("#midPost5").attr("src", responseData.midPost5Url);
    $("#midPost5").html(" "+ responseData.midPost5Text);

    //top
    $("#topImage").attr("src", responseData.topImageUrl1);

    $("#topVender").attr("src", responseData.topVenderUrl);
    $("#topVender").html(responseData.topVenderText + " ");

    $("#topPost1").attr("src", responseData.topPost1Url);
    $("#topPost1").html(" "+ responseData.topPost1Text);

    $("#topPost2").attr("src", responseData.topPost2Url);
    $("#topPost2").html(" "+ responseData.topPost2Text);

    $("#topPost3").attr("src", responseData.topPost3Url);
    $("#topPost3").html(" "+ responseData.topPost3Text);

    $("#topPost4").attr("src", responseData.topPost4Url);
    $("#topPost4").html(" "+ responseData.topPost4Text);

    $("#topPost5").attr("src", responseData.topPost5Url);
    $("#topPost5").html(" "+ responseData.topPost5Text);
  }
  function compareInfoErrorCallback(){ console.log("errorCallback"); }
  function compareInfoCompleteCallback(){ console.log("completeCallback"); }
  callAjax(compareInfoParamType, compareInfoParam, compareInfoURL, compareInfoType, compareInfoReturnType, compareInfoBeforeSendCallback, compareInfoSuccessCallback, compareInfoErrorCallback, compareInfoCompleteCallback);
});
<commit_msg>compareInfo js update :)<commit_after>$(function () {
  // Compare Info API
  var compareInfoParamType = 'noneParam';
  var compareInfoParam = '';
  var compareInfoURL = '/api/rivalWar/menu/getRootCompareInfo.do';
  var compareInfoType = 'GET';
  var compareInfoReturnType = 'json';
  function compareInfoBeforeSendCallback(){ console.log("beforeSendCallback"); }
  function compareInfoSuccessCallback (responseData) {
    console.log(responseData);
    $("#compareInfoTime").text(responseData.calTime);

    $("#botImage").attr("src", responseData.botImageUrl1);

    $("#botVender").attr("href", responseData.botVenderUrl);
    $("#botVender").html(responseData.botVenderText + " ");

    $("#botPost1").attr("href", responseData.botPost1Url);
    $("#botPost1").html(" "+ responseData.botPost1Text);

    $("#botPost2").attr("href", responseData.botPost2Url);
    $("#botPost2").html(" "+ responseData.botPost2Text);

    $("#botPost3").attr("href", responseData.botPost3Url);
    $("#botPost3").html(" "+ responseData.botPost3Text);

    $("#botPost4").attr("href", responseData.botPost4Url);
    $("#botPost4").html(" "+ responseData.botPost4Text);

    $("#botPost5").attr("href", responseData.botPost5Url);
    $("#botPost5").html(" "+ responseData.botPost5Text);

    //mid
    $("#midImage").attr("src", responseData.midImageUrl1);

    $("#midVender").attr("href", responseData.midVenderUrl);
    $("#midVender").html(responseData.midVenderText + " ");

    $("#midPost1").attr("href", responseData.midPost1Url);
    $("#midPost1").html(" "+ responseData.midPost1Text);

    $("#midPost2").attr("href", responseData.midPost2Url);
    $("#midPost2").html(" "+ responseData.midPost2Text);

    $("#midPost3").attr("href", responseData.midPost3Url);
    $("#midPost3").html(" "+ responseData.midPost3Text);

    $("#midPost4").attr("href", responseData.midPost4Url);
    $("#midPost4").html(" "+ responseData.midPost4Text);

    $("#midPost5").attr("href", responseData.midPost5Url);
    $("#midPost5").html(" "+ responseData.midPost5Text);

    //top
    $("#topImage").attr("src", responseData.topImageUrl1);

    $("#topVender").attr("href", responseData.topVenderUrl);
    $("#topVender").html(responseData.topVenderText + " ");

    $("#topPost1").attr("href", responseData.topPost1Url);
    $("#topPost1").html(" "+ responseData.topPost1Text);

    $("#topPost2").attr("href", responseData.topPost2Url);
    $("#topPost2").html(" "+ responseData.topPost2Text);

    $("#topPost3").attr("href", responseData.topPost3Url);
    $("#topPost3").html(" "+ responseData.topPost3Text);

    $("#topPost4").attr("href", responseData.topPost4Url);
    $("#topPost4").html(" "+ responseData.topPost4Text);

    $("#topPost5").attr("href", responseData.topPost5Url);
    $("#topPost5").html(" "+ responseData.topPost5Text);
  }
  function compareInfoErrorCallback(){ console.log("errorCallback"); }
  function compareInfoCompleteCallback(){ console.log("completeCallback"); }
  callAjax(compareInfoParamType, compareInfoParam, compareInfoURL, compareInfoType, compareInfoReturnType, compareInfoBeforeSendCallback, compareInfoSuccessCallback, compareInfoErrorCallback, compareInfoCompleteCallback);
});
<|endoftext|>


<commit_before>var EventEmitter = require('events').EventEmitter,
  path = require('path'),
  url = require('url'),
  async = require('async'),
  util = require('util'),
  http = require('http'),
  https = require('https'),
  appManager = require('./lib/appManager.js'),
  mongooseManager = require('./lib/mongooseManager.js'),
  redisManager = require('./lib/redisManager.js'),
  toobusy = require('toobusy');

function MWC(config) {

  EventEmitter.call(this);
  if (typeof config === 'object') {
  if(process.env.redisUrl && !config.redis){
//Using redis configuration from enviromental value
    config.redis=process.env.redisUrl;
  }
  if(process.env.mongoUrl && !config.mongoUrl){
//Using mongo configuration from enviromental value
    config.mongoUrl=process.env.mongoUrl;
  }
  }
  this.validateConfig(config);
  this.config = config;
  this._extendCoreFunctions = [];
  this._additionalModels = [];
  this._extendAppFunctions = [];
  this._additionalStrategies = [];
  this._extendMiddlewaresFunctions = [];
  this._extendRoutesFunctions = [];

  return this;
}

util.inherits(MWC, EventEmitter);

MWC.prototype.validateConfig = function(config) {
  // General check
  if (typeof config !== 'object') {
    throw new Error('Config is not an object!');
  }
  if (!(config.hostUrl && url.parse(config.hostUrl)['hostname'])) {
    throw new Error('Config.hostUrl have to be valid hostname - for example, http://example.org/ with http(s) on start and "/" at end!!!');
  }
  if (!(config.secret && config.secret.length>9)) {
    throw new Error('Config.secret is not set or is to short!');
  }

  mongooseManager.validateConfig(config.mongoUrl);
  redisManager.validateConfig(config.redis);

  return true;
};

//extending application
MWC.prototype.extendCore = function (settingsFunction) {
  if (this.prepared) {
    throw new Error('MWC core application is already prepared! WE CAN\'T EXTEND IT NOW!');
  } else {
    if (typeof settingsFunction === 'function') {
      this._extendCoreFunctions.push(settingsFunction);
      return this;
    } else {
      throw new Error('MWC.extendCore requires argument of function(core){...}');
    }
  }
};

MWC.prototype.extendModel = function (modelName, modelFunction) {
  if (modelName === 'Users') {
    throw new Error('Error extending model, "Users" is reserved name');
  } else {
    if (typeof modelName === 'string' && typeof modelFunction === 'function') {
      this._additionalModels.push({'name': modelName, 'initFunction': modelFunction});
      return this;
    } else {
      throw new Error('MWC.extendModel requires arguments of string of "modelName" and function(core){...}');
    }
  }
};

MWC.prototype.extendApp = function (environment, settingsFunction) {
  if (this.prepared) {
    throw new Error('MWC core application is already prepared! WE CAN\'T EXTEND IT NOW!');
  } else {
    var environmentToUse = null;
    if (typeof settingsFunction === 'undefined') {
      settingsFunction = environment;
      environment = null;
    }
    if (typeof environment === 'string') {
      environmentToUse = [];
      environmentToUse.push(environment);
    }
    if (environment instanceof Array) {
      environmentToUse = environment;
      for (var i = 0; i < environment.length;i++){
        if(typeof environment[i] !== 'string'){
          throw new Error('#MWC.extendApp requires environment name to be a string!');
        }
      }
    }
    if (typeof settingsFunction === 'function') {
      if (environmentToUse) {
        for (var i = 0; i < environmentToUse.length; i++) {
          this._extendAppFunctions.push({
            'environment': environmentToUse[i],
            'settingsFunction': settingsFunction
          });
        }
      } else {
        this._extendAppFunctions.push({
          'settingsFunction': settingsFunction
        });
      }
    } else {
      throw new Error('Wrong arguments for extendApp(arrayOrStringOfEnvironments,settingsFunction)');
    }
    return this;
  }
};

MWC.prototype.extendStrategies = function(strategyObject){
  if(typeof strategyObject !== 'object') throw new Error('mwc.extendStrategies requires strategyObject to be an object');
  if(typeof strategyObject.strategy !== 'function') throw new Error('mwc.extendStrategies requires strategyObject.strategy to be a proper function!');
  if(typeof strategyObject.routes !== 'function') throw new Error('mwc.extendStrategies requires strategyObject.routes to be a proper function!');

  this._additionalStrategies.push(strategyObject);
  return this;
};

MWC.prototype.extendMiddlewares = function (environment, path, settingsFunction) {
  if (this.prepared) {
    throw new Error('MWC core application is already prepared! WE CAN\'T EXTEND IT NOW!');
  } else {
    var environmentToUse = null,
      pathToUse = '/',
      settingsFunctionToUse = null;

    if (typeof environment === 'function' && typeof path === 'undefined' && typeof settingsFunction === 'undefined') {
      settingsFunctionToUse = environment;
    }

    if (typeof environment === 'string' || environment instanceof Array) {

      if (typeof environment === 'string') {
        environmentToUse = [];
        environmentToUse.push(environment);
      }
      if (environment instanceof Array) {
        environmentToUse = environment;
        for (var i = 0; i < environment.length;i++){
          if(typeof environment[i] !== 'string'){
            throw new Error('#MWC.extendMiddlewares requires environment name to be a string!');
          }
        }
      }
      if (typeof path === 'string') {
        if(/^\//.test(path)){
          pathToUse = path;
          if (typeof settingsFunction === 'function') {
            settingsFunctionToUse = settingsFunction;
          }
        } else {
          throw new Error('#MWC.extendMiddlewares path to be a middleware valid path, that starts from "/"!');
        }
      } else {
        if (typeof path === 'function') {
          settingsFunctionToUse = path;
        }
      }
    }

    if (settingsFunctionToUse) {
      if (environmentToUse) {
        for (var i = 0; i < environmentToUse.length; i++) {
          this._extendMiddlewaresFunctions.push({
            'environment': environmentToUse[i],
            'path': pathToUse,
            'SettingsFunction': settingsFunctionToUse
          });
        }
      } else {
        //we set middleware for all environments
        this._extendMiddlewaresFunctions.push({
          'path': pathToUse,
          'SettingsFunction': settingsFunctionToUse
        });
      }
    } else {
      throw new Error('Wrong arguments for function MWC.extendMiddlewares(environmentArrayOrStrings, [path], settingsFunction(core){...})');
    }
    return this;
  }
};

MWC.prototype.extendRoutes = function (settingsFunction) {
  if (this.prepared) {
    throw new Error('MWC core application is already prepared! WE CAN\'T EXTEND IT NOW!');
  } else {
    if (typeof settingsFunction === 'function') {
      this._extendRoutesFunctions.push(settingsFunction);
      return this;
    } else {
      throw new Error('Wrong argument for MWC.extendAppRoutes(function(core){...});');
    }
  }
};

MWC.prototype.usePlugin = function (pluginObjectOrName) {
  if (this.prepared) {
    throw new Error('MWC core application is already prepared! WE CAN\'T EXTEND IT NOW!');
  } else {
    var pluginToBeInstalled = {};
    if (typeof pluginObjectOrName === 'string') {
      pluginToBeInstalled = require('' + pluginObjectOrName);
    } else {
      pluginToBeInstalled = pluginObjectOrName;
    }

    if (pluginToBeInstalled.extendCore) {
      this.extendCore(pluginToBeInstalled.extendCore);
    }
    if (pluginToBeInstalled.extendModel && typeof pluginToBeInstalled.extendModel === 'object') {
      for (var x in pluginToBeInstalled.extendModel) {
        this.extendModel(x, pluginObjectOrName.extendModel[x]);
      }
    }
    if(pluginToBeInstalled.setAppParameters && typeof pluginToBeInstalled.extendApp === 'undefined'){
      console.log('Plugin is outdated! Use extendApp instead of setAppParameters with same syntax!');
      pluginToBeInstalled.extendApp=pluginToBeInstalled.setAppParameters;
    }
    if (pluginToBeInstalled.extendApp) {
      this.extendApp(pluginToBeInstalled.extendApp);
    }
    if(pluginToBeInstalled.setAppMiddlewares && typeof pluginToBeInstalled.extendMiddlewares === 'undefined'){
      console.log('Plugin is outdated! Use extendMiddlewares instead of setAppMiddlewares with same syntax!');
      pluginToBeInstalled.extendMiddlewares=pluginToBeInstalled.setAppMiddlewares;
    }
    if (pluginToBeInstalled.extendMiddlewares) {
      this.extendMiddlewares(pluginToBeInstalled.extendMiddlewares);
    }
    if(pluginToBeInstalled.extendAppRoutes && typeof pluginToBeInstalled.extendRoutes === 'undefined'){
      console.log('Plugin is outdated! Use extendMiddlewares instead of setAppMiddlewares with same syntax!');
      pluginToBeInstalled.extendRoutes=pluginToBeInstalled.extendAppRoutes;
    }
    if (pluginToBeInstalled.extendRoutes) {
      this.extendRoutes(pluginToBeInstalled.extendRoutes);
    }
    return this;
  }
};

MWC.prototype.ready = function () {
  var thisMWC = this;//because we sometimes issue closures with thisMWC
  thisMWC.prepared = true;

  //injecting redis
  thisMWC.redisClient = redisManager.create(thisMWC.config.redis);

  // initializing MongoDB and Core Models
  thisMWC.mongoose = mongooseManager.create(thisMWC.config.mongoUrl);
  thisMWC.mongoose.setConnectEvent(thisMWC);
  thisMWC.model = mongooseManager.initModels(thisMWC);

  //doing extendCore
  //extending core by extendCore
  thisMWC._extendCoreFunctions.map(function (settingsFunction) {
    settingsFunction(thisMWC);
  });

  //loading custom models //todo - maybe redo
  thisMWC._additionalModels.map(function (customModel) {
    thisMWC.model[customModel.name] = customModel.initFunction(thisMWC.mongoose, thisMWC.config);
  });

  //initialize expressJS application
  thisMWC.app = appManager.create(thisMWC);
  appManager.extendApp(thisMWC);

  // set shutdown procedure
  process.on('SIGINT', thisMWC.shutdown);

  return thisMWC;
};

MWC.prototype.listen = function (httpOrHttpsOrPort) {

  if (!this.prepared) {
    this.ready();
  }

  if (httpOrHttpsOrPort) {
    if (typeof httpOrHttpsOrPort === 'number' && httpOrHttpsOrPort > 0) {
      this.app.listen(httpOrHttpsOrPort);
      return;
    }

    if (httpOrHttpsOrPort instanceof http || httpOrHttpsOrPort instanceof https) {
      httpOrHttpsOrPort.createServer(this.app).listen(this.app.get('port'));
      return;
    }
    throw new Error('Function MWC.listen(httpOrHttpsOrPort) accepts objects of null, http, https or port\'s number as argument!');
  } else {
    this.app.listen(this.app.get('port'));//listening to default port
  }
};

MWC.prototype.setAppParameters = function(environment, settingsFunction){
  console.log('setAppParameters is outdated, use extendApp  with the same syntax');
  this.extendApp(environment, settingsFunction);
  return this;
};

MWC.prototype.setAppMiddlewares = function(environment, path, settingsFunction){
  console.log('setAppMiddlewares is outdated, use extendMiddlewares with the same syntax');
  this.extendMiddlewares(environment, path, settingsFunction);
  return this;
};

MWC.prototype.extendAppRoutes = function(settingsFunction){
  console.log('extendAppRoutes is outdated, use extendRoutes with the same syntax');
  this.extendRoutes(settingsFunction);
  return this;
};

MWC.prototype.shutdown = function () {

  console.log('MWC IS GOING TO SHUT DOWN....');
  if(this.mongoose.connection){
    this.mongoose.connection.close();
  }
  this.redisClient.end();
  // calling .shutdown allows your process to exit normally
  toobusy.shutdown();
  process.exit();

};

MWC.prototype.injectEmit = function(object) {
  var thisMWC = this;
  object.emitMWC = function (eventName, eventContent) {
    thisMWC.emit(eventName, eventContent);
  };
};

//Use this function with great caution! Because usually redis-database-as-a-service providers have
//strict connection limit!!! and every one redis client created like this consumes one connection!
//Usually, MWC needs only one redis client connection
//BTW, redis is NOT MySQL - we can't increase speed with connection pooling!
MWC.prototype.createRedisClient = function(){
  return redisManager.create(this.config.redis);
};

MWC.create = function(config){
  return new MWC(config);
};

module.exports = exports = MWC.create;
<commit_msg>[refactor] - removed modules unneeded<commit_after>var EventEmitter = require('events').EventEmitter,
  url = require('url'),
  util = require('util'),
  http = require('http'),
  https = require('https'),
  appManager = require('./lib/appManager.js'),
  mongooseManager = require('./lib/mongooseManager.js'),
  redisManager = require('./lib/redisManager.js');

function MWC(config) {

  EventEmitter.call(this);
  if (typeof config === 'object') {
  if(process.env.redisUrl && !config.redis){
//Using redis configuration from enviromental value
    config.redis=process.env.redisUrl;
  }
  if(process.env.mongoUrl && !config.mongoUrl){
//Using mongo configuration from enviromental value
    config.mongoUrl=process.env.mongoUrl;
  }
  }
  this.validateConfig(config);
  this.config = config;
  this._extendCoreFunctions = [];
  this._additionalModels = [];
  this._extendAppFunctions = [];
  this._additionalStrategies = [];
  this._extendMiddlewaresFunctions = [];
  this._extendRoutesFunctions = [];

  return this;
}

util.inherits(MWC, EventEmitter);

MWC.prototype.validateConfig = function(config) {
  // General check
  if (typeof config !== 'object') {
    throw new Error('Config is not an object!');
  }
  if (!(config.hostUrl && url.parse(config.hostUrl)['hostname'])) {
    throw new Error('Config.hostUrl have to be valid hostname - for example, http://example.org/ with http(s) on start and "/" at end!!!');
  }
  if (!(config.secret && config.secret.length>9)) {
    throw new Error('Config.secret is not set or is to short!');
  }

  mongooseManager.validateConfig(config.mongoUrl);
  redisManager.validateConfig(config.redis);

  return true;
};

//extending application
MWC.prototype.extendCore = function (settingsFunction) {
  if (this.prepared) {
    throw new Error('MWC core application is already prepared! WE CAN\'T EXTEND IT NOW!');
  } else {
    if (typeof settingsFunction === 'function') {
      this._extendCoreFunctions.push(settingsFunction);
      return this;
    } else {
      throw new Error('MWC.extendCore requires argument of function(core){...}');
    }
  }
};

MWC.prototype.extendModel = function (modelName, modelFunction) {
  if (modelName === 'Users') {
    throw new Error('Error extending model, "Users" is reserved name');
  } else {
    if (typeof modelName === 'string' && typeof modelFunction === 'function') {
      this._additionalModels.push({'name': modelName, 'initFunction': modelFunction});
      return this;
    } else {
      throw new Error('MWC.extendModel requires arguments of string of "modelName" and function(core){...}');
    }
  }
};

MWC.prototype.extendApp = function (environment, settingsFunction) {
  if (this.prepared) {
    throw new Error('MWC core application is already prepared! WE CAN\'T EXTEND IT NOW!');
  } else {
    var environmentToUse = null;
    if (typeof settingsFunction === 'undefined') {
      settingsFunction = environment;
      environment = null;
    }
    if (typeof environment === 'string') {
      environmentToUse = [];
      environmentToUse.push(environment);
    }
    if (environment instanceof Array) {
      environmentToUse = environment;
      for (var i = 0; i < environment.length;i++){
        if(typeof environment[i] !== 'string'){
          throw new Error('#MWC.extendApp requires environment name to be a string!');
        }
      }
    }
    if (typeof settingsFunction === 'function') {
      if (environmentToUse) {
        for (var i = 0; i < environmentToUse.length; i++) {
          this._extendAppFunctions.push({
            'environment': environmentToUse[i],
            'settingsFunction': settingsFunction
          });
        }
      } else {
        this._extendAppFunctions.push({
          'settingsFunction': settingsFunction
        });
      }
    } else {
      throw new Error('Wrong arguments for extendApp(arrayOrStringOfEnvironments,settingsFunction)');
    }
    return this;
  }
};

MWC.prototype.extendStrategies = function(strategyObject){
  if(typeof strategyObject !== 'object') throw new Error('mwc.extendStrategies requires strategyObject to be an object');
  if(typeof strategyObject.strategy !== 'function') throw new Error('mwc.extendStrategies requires strategyObject.strategy to be a proper function!');
  if(typeof strategyObject.routes !== 'function') throw new Error('mwc.extendStrategies requires strategyObject.routes to be a proper function!');

  this._additionalStrategies.push(strategyObject);
  return this;
};

MWC.prototype.extendMiddlewares = function (environment, path, settingsFunction) {
  if (this.prepared) {
    throw new Error('MWC core application is already prepared! WE CAN\'T EXTEND IT NOW!');
  } else {
    var environmentToUse = null,
      pathToUse = '/',
      settingsFunctionToUse = null;

    if (typeof environment === 'function' && typeof path === 'undefined' && typeof settingsFunction === 'undefined') {
      settingsFunctionToUse = environment;
    }

    if (typeof environment === 'string' || environment instanceof Array) {

      if (typeof environment === 'string') {
        environmentToUse = [];
        environmentToUse.push(environment);
      }
      if (environment instanceof Array) {
        environmentToUse = environment;
        for (var i = 0; i < environment.length;i++){
          if(typeof environment[i] !== 'string'){
            throw new Error('#MWC.extendMiddlewares requires environment name to be a string!');
          }
        }
      }
      if (typeof path === 'string') {
        if(/^\//.test(path)){
          pathToUse = path;
          if (typeof settingsFunction === 'function') {
            settingsFunctionToUse = settingsFunction;
          }
        } else {
          throw new Error('#MWC.extendMiddlewares path to be a middleware valid path, that starts from "/"!');
        }
      } else {
        if (typeof path === 'function') {
          settingsFunctionToUse = path;
        }
      }
    }

    if (settingsFunctionToUse) {
      if (environmentToUse) {
        for (var i = 0; i < environmentToUse.length; i++) {
          this._extendMiddlewaresFunctions.push({
            'environment': environmentToUse[i],
            'path': pathToUse,
            'SettingsFunction': settingsFunctionToUse
          });
        }
      } else {
        //we set middleware for all environments
        this._extendMiddlewaresFunctions.push({
          'path': pathToUse,
          'SettingsFunction': settingsFunctionToUse
        });
      }
    } else {
      throw new Error('Wrong arguments for function MWC.extendMiddlewares(environmentArrayOrStrings, [path], settingsFunction(core){...})');
    }
    return this;
  }
};

MWC.prototype.extendRoutes = function (settingsFunction) {
  if (this.prepared) {
    throw new Error('MWC core application is already prepared! WE CAN\'T EXTEND IT NOW!');
  } else {
    if (typeof settingsFunction === 'function') {
      this._extendRoutesFunctions.push(settingsFunction);
      return this;
    } else {
      throw new Error('Wrong argument for MWC.extendAppRoutes(function(core){...});');
    }
  }
};

MWC.prototype.usePlugin = function (pluginObjectOrName) {
  if (this.prepared) {
    throw new Error('MWC core application is already prepared! WE CAN\'T EXTEND IT NOW!');
  } else {
    var pluginToBeInstalled = {};
    if (typeof pluginObjectOrName === 'string') {
      pluginToBeInstalled = require('' + pluginObjectOrName);
    } else {
      pluginToBeInstalled = pluginObjectOrName;
    }

    if (pluginToBeInstalled.extendCore) {
      this.extendCore(pluginToBeInstalled.extendCore);
    }
    if (pluginToBeInstalled.extendModel && typeof pluginToBeInstalled.extendModel === 'object') {
      for (var x in pluginToBeInstalled.extendModel) {
        this.extendModel(x, pluginObjectOrName.extendModel[x]);
      }
    }
    if(pluginToBeInstalled.setAppParameters && typeof pluginToBeInstalled.extendApp === 'undefined'){
      console.log('Plugin is outdated! Use extendApp instead of setAppParameters with same syntax!');
      pluginToBeInstalled.extendApp=pluginToBeInstalled.setAppParameters;
    }
    if (pluginToBeInstalled.extendApp) {
      this.extendApp(pluginToBeInstalled.extendApp);
    }
    if(pluginToBeInstalled.setAppMiddlewares && typeof pluginToBeInstalled.extendMiddlewares === 'undefined'){
      console.log('Plugin is outdated! Use extendMiddlewares instead of setAppMiddlewares with same syntax!');
      pluginToBeInstalled.extendMiddlewares=pluginToBeInstalled.setAppMiddlewares;
    }
    if (pluginToBeInstalled.extendMiddlewares) {
      this.extendMiddlewares(pluginToBeInstalled.extendMiddlewares);
    }
    if(pluginToBeInstalled.extendAppRoutes && typeof pluginToBeInstalled.extendRoutes === 'undefined'){
      console.log('Plugin is outdated! Use extendMiddlewares instead of setAppMiddlewares with same syntax!');
      pluginToBeInstalled.extendRoutes=pluginToBeInstalled.extendAppRoutes;
    }
    if (pluginToBeInstalled.extendRoutes) {
      this.extendRoutes(pluginToBeInstalled.extendRoutes);
    }
    return this;
  }
};

MWC.prototype.ready = function () {
  var thisMWC = this;//because we sometimes issue closures with thisMWC
  thisMWC.prepared = true;

  //injecting redis
  thisMWC.redisClient = redisManager.create(thisMWC.config.redis);

  // initializing MongoDB and Core Models
  thisMWC.mongoose = mongooseManager.create(thisMWC.config.mongoUrl);
  thisMWC.mongoose.setConnectEvent(thisMWC);
  thisMWC.model = mongooseManager.initModels(thisMWC);

  //doing extendCore
  //extending core by extendCore
  thisMWC._extendCoreFunctions.map(function (settingsFunction) {
    settingsFunction(thisMWC);
  });

  //loading custom models //todo - maybe redo
  thisMWC._additionalModels.map(function (customModel) {
    thisMWC.model[customModel.name] = customModel.initFunction(thisMWC.mongoose, thisMWC.config);
  });

  //initialize expressJS application
  thisMWC.app = appManager.create(thisMWC);
  appManager.extendApp(thisMWC);

  // set shutdown procedure
  process.on('SIGINT', thisMWC.shutdown);

  return thisMWC;
};

MWC.prototype.listen = function (httpOrHttpsOrPort) {

  if (!this.prepared) {
    this.ready();
  }

  if (httpOrHttpsOrPort) {
    if (typeof httpOrHttpsOrPort === 'number' && httpOrHttpsOrPort > 0) {
      this.app.listen(httpOrHttpsOrPort);
      return;
    }

    if (httpOrHttpsOrPort instanceof http || httpOrHttpsOrPort instanceof https) {
      httpOrHttpsOrPort.createServer(this.app).listen(this.app.get('port'));
      return;
    }
    throw new Error('Function MWC.listen(httpOrHttpsOrPort) accepts objects of null, http, https or port\'s number as argument!');
  } else {
    this.app.listen(this.app.get('port'));//listening to default port
  }
};

MWC.prototype.setAppParameters = function(environment, settingsFunction){
  console.log('setAppParameters is outdated, use extendApp  with the same syntax');
  this.extendApp(environment, settingsFunction);
  return this;
};

MWC.prototype.setAppMiddlewares = function(environment, path, settingsFunction){
  console.log('setAppMiddlewares is outdated, use extendMiddlewares with the same syntax');
  this.extendMiddlewares(environment, path, settingsFunction);
  return this;
};

MWC.prototype.extendAppRoutes = function(settingsFunction){
  console.log('extendAppRoutes is outdated, use extendRoutes with the same syntax');
  this.extendRoutes(settingsFunction);
  return this;
};

MWC.prototype.shutdown = function () {

  console.log('MWC IS GOING TO SHUT DOWN....');
  if(this.mongoose.connection){
    this.mongoose.connection.close();
  }
  this.redisClient.end();
  // calling .shutdown allows your process to exit normally
  toobusy.shutdown();
  process.exit();

};

MWC.prototype.injectEmit = function(object) {
  var thisMWC = this;
  object.emitMWC = function (eventName, eventContent) {
    thisMWC.emit(eventName, eventContent);
  };
};

//Use this function with great caution! Because usually redis-database-as-a-service providers have
//strict connection limit!!! and every one redis client created like this consumes one connection!
//Usually, MWC needs only one redis client connection
//BTW, redis is NOT MySQL - we can't increase speed with connection pooling!
MWC.prototype.createRedisClient = function(){
  return redisManager.create(this.config.redis);
};

MWC.create = function(config){
  return new MWC(config);
};

module.exports = exports = MWC.create;
<|endoftext|>


<commit_before>var channel_list = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];

function getinfo() {
    channel_list.forEach(function(c) {
        var url = "https://wind-bow.gomix.me/twitch-api/streams/" + c + "/?callback=?";
        $.getJSON(url, function(data) {
            console.log(data);
            updateInfo(data, c);
        });
    });
}

function updateInfo(data, c) {
    if (data.stream === null) {
        $(document)
            .getElementById("#status-" + c)
            .textContent = "Offline";
    }
}

$(document)
    .ready(getinfo);
<commit_msg>Add function descriptions<commit_after>var channel_list = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];

function getinfo() {
    channel_list.forEach(function(c) {
        var url = "https://wind-bow.gomix.me/twitch-api/streams/" + c + "/?callback=?";
        $.getJSON(url, function(data) {
            console.log(data);
            setStreamStatus(data, c);
        });
    });
}

function setStreamStatus(data, c) {
    if (data.stream !== null) {
        updateInfo(data, c);
    } else if (data.stream === null) {
        var temp = c + "-text";
        document
            .getElementById(temp)
            .textContent = "The channel is not streaming currently";
    }
}

function updateInfo(data, c) {
    var temp = c + "-text";
    document
        .getElementById(temp)
        .textContent = data.stream.game;
    temp = c + "-status";
    document
        .getElementById(temp)
        .addClass("green");
    document
        .getElementById(temp)
        .removeClass("red");
}

$(document)
    .ready(getinfo);
<|endoftext|>


<commit_before>/*
    interface:
        Main interface for quickAlgo, common to all languages.
*/

var quickAlgoInterface = {
    strings: {},
    nbTestCases: 0,
    delayFactory: new DelayFactory(),
    curMode: null,

    fullscreen: false,

    enterFullscreen: function() {
        var el = document.documentElement;
        if(el.requestFullscreen) {
            el.requestFullscreen();
        } else if(el.mozRequestFullScreen) {
            el.mozRequestFullScreen();
        } else if(el.webkitRequestFullscreen) {
            el.webkitRequestFullscreen();
        } else if(el.msRequestFullscreen) {
            el.msRequestFullscreen();
        }
    },

    exitFullscreen: function() {
        var el = document;
        if(el.exitFullscreen) {
            el.exitFullscreen();
        } else if(el.mozCancelFullScreen) {
            el.mozCancelFullScreen();
        } else if(el.webkitExitFullscreen) {
            el.webkitExitFullscreen();
        } else if(el.msExitFullscreen) {
            el.msExitFullscreen();
        }
    },

    toggleFullscreen: function() {
        this.fullscreen = !this.fullscreen;
        if(this.fullscreen) {
            $('#fullscreenButton').html('[-]');
            this.enterFullscreen();
        } else {
            $('#fullscreenButton').html('[+]');
            this.exitFullscreen();
        }
        this.onResize();
    },

    loadInterface: function(context) {
        // Load quickAlgo interface into the DOM
        var self = this;
        this.context = context;
        this.strings = window.languageStrings;

        var gridHtml = "";
        gridHtml += "

";
        gridHtml += "

";
        gridHtml += "

";
        gridHtml += "";
        $("#gridContainer").html(gridHtml)

        $("#blocklyLibContent").html(
            "
" +
                "

" +
                "<button type='button' id='fullscreenButton'>[+]</button>" +
                "<button type='button' id='displayHelpBtn' onclick='conceptViewer.show()'>?</button>" +
                "
" +
                    "<button type='button' id='toggleEditorMenu'>≡</button>" +
                    "
" +
                        "
" + this.strings.loadExample + "
" +
                        "
" + this.strings.saveProgram + "
" +
                        "" +
                        "
" + this.strings.restart + "
" +
                        "
" +
                            "<input type='file' id='task-upload-file' " +
                            "onchange='task.displayedSubTask.blocklyHelper.handleFiles(this.files);resetFormElement($(this));$(\"#editorMenu\").hide();'>" +
                            this.strings.reloadProgram +
                        "
" +
                        "
" + this.strings.loadBestAnswer+ "
" +
                    "
" +
                "
" +
                "
" +
            "

"
        );

        $('#fullscreenButton').click(function() {
            self.toggleFullscreen();
        });

        $('#toggleEditorMenu').click(function() {
            var el = $('#editorMenu');
            if(el.is(":visible")) {
                el.hide();
            } else {
                $('#editorMenu div[rel=best-answer]').toggle(!!displayHelper.savedAnswer);
                el.show();
            }
        });

        // TODO :: something cleaner (add when editorMenu is opened, remove when closed?)
        $(document).click(function(e) {
            if($(e.target).attr('id') != 'toggleEditorMenu') {
                $('#editorMenu').hide();
            }
        });

        $('#editorMenu div[rel=example]').click(function(e) {
            task.displayedSubTask.loadExample()
        });

        $('#editorMenu div[rel=save]').click(function(e) {
            $('#editorMenu').hide();
            task.displayedSubTask.blocklyHelper.saveProgram();
        });

        $('#editorMenu div[rel=restart]').click(function(e) {
            $('#editorMenu').hide();
            displayHelper.restartAll();
        });

        $('#editorMenu div[rel=best-answer]').click(function(e) {
            $('#editorMenu').hide();
            displayHelper.retrieveAnswer();
        });

        // Buttons from buttonsAndMessages
        var addTaskHTML = '
';
        var placementNames = ['graderMessage', 'validate', 'saved'];
        for (var iPlacement = 0; iPlacement < placementNames.length; iPlacement++) {
            var placement = 'displayHelper_' + placementNames[iPlacement];
            if ($('#' + placement).length === 0) {
                addTaskHTML += '

';
            }
        }
        addTaskHTML += '
';
        /*
        if(!$('#displayHelper_cancel').length) {
            $('body').append($('

'));
        }
    */
        var scaleControl = '';
        if(context.display && context.infos.buttonScaleDrawing) {
            var scaleControl = '
' +
                '<input id="scaleDrawing" type="checkbox">' +
                this.strings.scaleDrawing +
                '' +
                '
';
        }

        var gridButtonsAfter = scaleControl
            + "

"
            //+ "<button type='button' id='submitBtn' class='btn btn-primary' onclick='task.displayedSubTask.submit()'>"
            //+ this.strings.submitProgram
            //+ "</button>
"
            //+ "

"
            + addTaskHTML;
        $("#gridButtonsAfter").html(gridButtonsAfter);
        $('#scaleDrawing').change(this.onScaleDrawingChange.bind(this));
   },

    setOptions: function(opt) {
        // Load options from the task
        $('#editorMenu div[rel=example]').toggle(opt.hasExample);
        $('#editorMenu div[rel=save]').toggle(!opt.hideSaveOrLoad);
        $('#editorMenu div[rel=load]').toggle(!opt.hideSaveOrLoad);
        $('#editorMenu div[rel=best-answer]').toggle(!opt.hideLoadBestAnswer);

        if(opt.conceptViewer) {
            conceptViewer.load(opt.conceptViewerLang);
            $('#displayHelpBtn').show();
        } else {
            $('#displayHelpBtn').hide();
        }
    },

    devMode: function() {
        $('#editorMenu .item').show();
    },

    onScaleDrawingChange: function(e) {
        console.log('onScaleDrawingChange')
        var scaled = $(e.target).prop('checked');
        $("#gridContainer").toggleClass('gridContainerScaled', scaled);
        $("#blocklyLibContent").toggleClass('blocklyLibContentScaled', scaled);
        this.context.setScale(scaled ? 2 : 1);
    },

    blinkRemaining: function(times, red) {
        console.log('blinkRemaining')
        var capacity = $('#capacity');
        if(times % 2 == 0) {
            capacity.removeClass('capacityRed');
        } else {
            capacity.addClass('capacityRed');
        }
        if(times > (red ? 1 : 0)) {
            var that = this;
            this.delayFactory.destroy('blinkRemaining');
            this.delayFactory.createTimeout('blinkRemaining', function() { that.blinkRemaining(times - 1, red); }, 200);
        }
    },

    stepDelayMin: 25,
    stepDelayMax: 250,

    refreshStepDelay: function() {
        var v = parseInt($('#speedSlider').val(), 10),
            delay = this.stepDelayMin + this.stepDelayMax - v;
        task.displayedSubTask.setStepDelay(delay);
    },

    initPlaybackControls: function() {
        var self = this;

        var speedControls =
            '
' +
                '
' +
                    '' + this.strings.speedSliderSlower + '' +
                    '<input type="range" min="0" max="' + (this.stepDelayMax - this.stepDelayMin) + '" value="0" class="slider" id="speedSlider">' +
                    '' + this.strings.speedSliderFaster + '' +
                '
' +
                '
' +
                    '

' +
                    '

' +
                    '

' +
                    '

' +
                '
' +
            '
';
        $('#task').find('.speedControls').remove();
        $('#task').append(speedControls);

        $('#speedSlider').on('input change', function(e) {
            self.refreshStepDelay();
        });
        $('.speedSlower').click(function() {
            var el = $('#speedSlider'),
                maxVal = parseInt(el.attr('max'), 10),
                delta = Math.floor(maxVal / 10),
                newVal = parseInt(el.val(), 10) - delta;
            el.val(Math.max(newVal, 0));
            self.refreshStepDelay();
        });
        $('.speedFaster').click(function() {
            var el = $('#speedSlider'),
                maxVal = parseInt(el.attr('max'), 10),
                delta = Math.floor(maxVal / 10),
                newVal = parseInt(el.val(), 10) + delta;
            el.val(Math.min(newVal, maxVal));
            self.refreshStepDelay();
        });

        $('#playerControls .stop').click(function() {
            task.displayedSubTask.stop();
            self.setPlayPause(false);
        });

        $('#playPause').click(function(e) {
            if($(this).hasClass('play')) {
                self.refreshStepDelay();
                task.displayedSubTask.play();
                self.setPlayPause(true);
            } else {
                task.displayedSubTask.pause();
                self.setPlayPause(false);
            }
        })

        $('#playerControls .step').click(function() {
            self.setPlayPause(false);
            task.displayedSubTask.step();
        });

        $('#playerControls .end').click(function() {
            task.displayedSubTask.setStepDelay(0);
            task.displayedSubTask.play();
            self.setPlayPause(true);
        });
    },

    setPlayPause: function(isPlaying) {
        if(isPlaying) {
            $('#playPause').removeClass('play').addClass('pause');
        } else {
            $('#playPause').removeClass('pause').addClass('play');
        }
    },

    initTestSelector: function (nbTestCases) {
        var self = this;
        console.log('initTestSelector')
        // Create the DOM for the tests display
        this.nbTestCases = nbTestCases;

        var testTabs = '
';
        for(var iTest=0; iTest<this.nbTestCases; iTest++) {
            if(this.nbTestCases > 1) {
                testTabs += '

';
            }
        }
        testTabs += "
";
        $('#testSelector').html(testTabs);

        this.updateTestSelector(0);
        this.resetTestScores();
        this.initPlaybackControls();
    },

    updateTestScores: function (testScores) {
        console.log('updateTestScores')
        // Display test results
        for(var iTest=0; iTest<testScores.length; iTest++) {
            if(testScores[iTest].successRate >= 1) {
                var icon = '✔';
                var label = ''+this.strings.correctAnswer+'';
            } else if(testScores[iTest].successRate > 0) {
                var icon = '✖';
                var label = ''+this.strings.partialAnswer+'';
            } else {
                var icon = '✖';
                var label = ''+this.strings.wrongAnswer+'';
            }
            $('#testTab'+iTest+' .testTitle').html(icon+' Test '+(iTest+1)+' '+label);
        }
    },

    resetTestScores: function () {
        console.log('resetTestScores')
        // Reset test results display
        for(var iTest=0; iTest<this.nbTestCases; iTest++) {
            $('#testTab'+iTest+' .testTitle').html('  Test '+(iTest+1));
        }
    },

    updateTestSelector: function (newCurTest) {
        console.log('updateTestSelector')
        $("#testSelector .testTab").removeClass('currentTest');
        $("#testTab"+newCurTest).addClass('currentTest');
        $("#task").append($('#messages'));
        //$("#testTab"+newCurTest+" .panel-body").prepend($('#grid')).append($('#messages')).show();
    },

    createModeSelectorButtons: function() {
        var self = this;
        $("#task").append('\

\

\

\

\

');

        $('#modeSelector div').click(function() {
            self.selectMode($(this).attr('id'));
        })
    },

    selectMode: function(mode) {
        if(mode === this.curMode) return;
        $('#task').removeClass(this.curMode).addClass(mode);
        $('#' + mode).hide();
        if(this.curMode) {
            $('#' + this.curMode).show();
        }
        if(mode == 'mode-instructions') {
            $('#taskIntro .short').hide();
            $('#taskIntro .long').show();
        }
        if(mode == 'mode-player') {
            $('#taskIntro .short').show();
            $('#taskIntro .long').hide();
        }
        this.curMode = mode;
        this.onResize();
    },

    unloadLevel: function() {
        // Called when level is unloaded
        this.resetTestScores();
        if(this.curMode == 'mode-editor') {
           this.selectMode('mode-player');
        }
    },

    onResize: function(e) {
        var blocklyArea = document.getElementById('blocklyContainer');
        var blocklyDiv = document.getElementById('blocklyDiv');
        blocklyDiv.style.width = blocklyArea.offsetWidth + 'px';
        blocklyDiv.style.height = blocklyArea.offsetHeight + 'px';
        Blockly.svgResize(window.blocklyWorkspace);
    },

    displayError: function(message) {
        $('#errorModal').remove();
        if(!message) return;
        var html =
            '
' +
            '
' +
            '<button type="button" class="btn close" onclick="closeModal(`errorModal`)">x</button>' +
            '
' + message + '
' +
            '
' +
            '
';
        $(document.body).append($(html));
        $("#errorModal").show();
    }
};

$(document).ready(function() {

    $("#task h1").appendTo($("#miniPlatformHeader table td").first());
    $('#taskIntro, #gridContainer').wrapAll("

");

    quickAlgoInterface.createModeSelectorButtons();
    //selectMode('mode-instructions');
    quickAlgoInterface.selectMode('mode-player');

    window.addEventListener('resize', quickAlgoInterface.onResize, false);
    quickAlgoInterface.onResize();
});
<commit_msg>cleanup tests player, use icons from fontawesome<commit_after>/*
    interface:
        Main interface for quickAlgo, common to all languages.
*/

var quickAlgoInterface = {
    strings: {},
    nbTestCases: 0,
    delayFactory: new DelayFactory(),
    curMode: null,

    fullscreen: false,

    enterFullscreen: function() {
        var el = document.documentElement;
        if(el.requestFullscreen) {
            el.requestFullscreen();
        } else if(el.mozRequestFullScreen) {
            el.mozRequestFullScreen();
        } else if(el.webkitRequestFullscreen) {
            el.webkitRequestFullscreen();
        } else if(el.msRequestFullscreen) {
            el.msRequestFullscreen();
        }
    },

    exitFullscreen: function() {
        var el = document;
        if(el.exitFullscreen) {
            el.exitFullscreen();
        } else if(el.mozCancelFullScreen) {
            el.mozCancelFullScreen();
        } else if(el.webkitExitFullscreen) {
            el.webkitExitFullscreen();
        } else if(el.msExitFullscreen) {
            el.msExitFullscreen();
        }
    },

    toggleFullscreen: function() {
        this.fullscreen = !this.fullscreen;
        if(this.fullscreen) {
            $('#fullscreenButton').html('[-]');
            this.enterFullscreen();
        } else {
            $('#fullscreenButton').html('[+]');
            this.exitFullscreen();
        }
        this.onResize();
    },

    loadInterface: function(context) {
        // Load quickAlgo interface into the DOM
        var self = this;
        this.context = context;
        this.strings = window.languageStrings;

        var gridHtml = "";
        gridHtml += "

";
        gridHtml += "

";
        gridHtml += "

";
        gridHtml += "";
        $("#gridContainer").html(gridHtml)

        $("#blocklyLibContent").html(
            "
" +
                "

" +
                "<button type='button' id='fullscreenButton'>[+]</button>" +
                "<button type='button' id='displayHelpBtn' onclick='conceptViewer.show()'>?</button>" +
                "
" +
                    "<button type='button' id='toggleEditorMenu'>≡</button>" +
                    "
" +
                        "
" + this.strings.loadExample + "
" +
                        "
" + this.strings.saveProgram + "
" +
                        "" +
                        "
" + this.strings.restart + "
" +
                        "
" +
                            "<input type='file' id='task-upload-file' " +
                            "onchange='task.displayedSubTask.blocklyHelper.handleFiles(this.files);resetFormElement($(this));$(\"#editorMenu\").hide();'>" +
                            this.strings.reloadProgram +
                        "
" +
                        "
" + this.strings.loadBestAnswer+ "
" +
                    "
" +
                "
" +
                "
" +
            "

"
        );

        $('#fullscreenButton').click(function() {
            self.toggleFullscreen();
        });

        $('#toggleEditorMenu').click(function() {
            var el = $('#editorMenu');
            if(el.is(":visible")) {
                el.hide();
            } else {
                $('#editorMenu div[rel=best-answer]').toggle(!!displayHelper.savedAnswer);
                el.show();
            }
        });

        // TODO :: something cleaner (add when editorMenu is opened, remove when closed?)
        $(document).click(function(e) {
            if($(e.target).attr('id') != 'toggleEditorMenu') {
                $('#editorMenu').hide();
            }
        });

        $('#editorMenu div[rel=example]').click(function(e) {
            task.displayedSubTask.loadExample()
        });

        $('#editorMenu div[rel=save]').click(function(e) {
            $('#editorMenu').hide();
            task.displayedSubTask.blocklyHelper.saveProgram();
        });

        $('#editorMenu div[rel=restart]').click(function(e) {
            $('#editorMenu').hide();
            displayHelper.restartAll();
        });

        $('#editorMenu div[rel=best-answer]').click(function(e) {
            $('#editorMenu').hide();
            displayHelper.retrieveAnswer();
        });

        // Buttons from buttonsAndMessages
        var addTaskHTML = '
';
        var placementNames = ['graderMessage', 'validate', 'saved'];
        for (var iPlacement = 0; iPlacement < placementNames.length; iPlacement++) {
            var placement = 'displayHelper_' + placementNames[iPlacement];
            if ($('#' + placement).length === 0) {
                addTaskHTML += '

';
            }
        }
        addTaskHTML += '
';
        /*
        if(!$('#displayHelper_cancel').length) {
            $('body').append($('

'));
        }
    */
        var scaleControl = '';
        if(context.display && context.infos.buttonScaleDrawing) {
            var scaleControl = '
' +
                '<input id="scaleDrawing" type="checkbox">' +
                this.strings.scaleDrawing +
                '' +
                '
';
        }

        var gridButtonsAfter = scaleControl
            + "

"
            //+ "<button type='button' id='submitBtn' class='btn btn-primary' onclick='task.displayedSubTask.submit()'>"
            //+ this.strings.submitProgram
            //+ "</button>
"
            //+ "

"
            + addTaskHTML;
        $("#gridButtonsAfter").html(gridButtonsAfter);
        $('#scaleDrawing').change(this.onScaleDrawingChange.bind(this));
   },

    setOptions: function(opt) {
        // Load options from the task
        $('#editorMenu div[rel=example]').toggle(opt.hasExample);
        $('#editorMenu div[rel=save]').toggle(!opt.hideSaveOrLoad);
        $('#editorMenu div[rel=load]').toggle(!opt.hideSaveOrLoad);
        $('#editorMenu div[rel=best-answer]').toggle(!opt.hideLoadBestAnswer);

        if(opt.conceptViewer) {
            conceptViewer.load(opt.conceptViewerLang);
            $('#displayHelpBtn').show();
        } else {
            $('#displayHelpBtn').hide();
        }
    },

    devMode: function() {
        $('#editorMenu .item').show();
    },

    onScaleDrawingChange: function(e) {
        console.log('onScaleDrawingChange')
        var scaled = $(e.target).prop('checked');
        $("#gridContainer").toggleClass('gridContainerScaled', scaled);
        $("#blocklyLibContent").toggleClass('blocklyLibContentScaled', scaled);
        this.context.setScale(scaled ? 2 : 1);
    },

    blinkRemaining: function(times, red) {
        console.log('blinkRemaining')
        var capacity = $('#capacity');
        if(times % 2 == 0) {
            capacity.removeClass('capacityRed');
        } else {
            capacity.addClass('capacityRed');
        }
        if(times > (red ? 1 : 0)) {
            var that = this;
            this.delayFactory.destroy('blinkRemaining');
            this.delayFactory.createTimeout('blinkRemaining', function() { that.blinkRemaining(times - 1, red); }, 200);
        }
    },

    stepDelayMin: 25,
    stepDelayMax: 250,

    refreshStepDelay: function() {
        var v = parseInt($('#speedSlider').val(), 10),
            delay = this.stepDelayMin + this.stepDelayMax - v;
        task.displayedSubTask.setStepDelay(delay);
    },

    initPlaybackControls: function() {
        var self = this;

        var speedControls =
            '
' +
                '
' +
                    '' + this.strings.speedSliderSlower + '' +
                    '<input type="range" min="0" max="' + (this.stepDelayMax - this.stepDelayMin) + '" value="0" class="slider" id="speedSlider">' +
                    '' + this.strings.speedSliderFaster + '' +
                '
' +
                '
' +
                    '

' +
                    '

' +
                    '

' +
                    '

' +
                '
' +
            '
';
        $('#task').find('.speedControls').remove();
        $('#task').append(speedControls);

        $('#speedSlider').on('input change', function(e) {
            self.refreshStepDelay();
        });
        $('.speedSlower').click(function() {
            var el = $('#speedSlider'),
                maxVal = parseInt(el.attr('max'), 10),
                delta = Math.floor(maxVal / 10),
                newVal = parseInt(el.val(), 10) - delta;
            el.val(Math.max(newVal, 0));
            self.refreshStepDelay();
        });
        $('.speedFaster').click(function() {
            var el = $('#speedSlider'),
                maxVal = parseInt(el.attr('max'), 10),
                delta = Math.floor(maxVal / 10),
                newVal = parseInt(el.val(), 10) + delta;
            el.val(Math.min(newVal, maxVal));
            self.refreshStepDelay();
        });

        $('#playerControls .backToFirst').click(function() {
            task.displayedSubTask.stop();
            task.displayedSubTask.play();
            self.setPlayPause(true);
        });

        $('#playerControls .playPause').click(function(e) {
            if($(this).hasClass('play')) {
                self.refreshStepDelay();
                task.displayedSubTask.play();
                self.setPlayPause(true);
            } else {
                task.displayedSubTask.pause();
                self.setPlayPause(false);
            }
        })

        $('#playerControls .nextStep').click(function() {
            self.setPlayPause(false);
            task.displayedSubTask.step();
        });

        $('#playerControls .goToEnd').click(function() {
            task.displayedSubTask.setStepDelay(0);
            task.displayedSubTask.play();
            self.setPlayPause(false);
        });
    },

    setPlayPause: function(isPlaying) {
        if(isPlaying) {
            $('#playerControls .playPause').html('');
            $('#playerControls .playPause').removeClass('play').addClass('pause');
        } else {
            $('#playerControls .playPause').html('');
            $('#playerControls .playPause').removeClass('pause').addClass('play');
        }
    },

    initTestSelector: function (nbTestCases) {
        var self = this;
        console.log('initTestSelector')
        // Create the DOM for the tests display
        this.nbTestCases = nbTestCases;

        var testTabs = '
';
        for(var iTest=0; iTest<this.nbTestCases; iTest++) {
            if(this.nbTestCases > 1) {
                testTabs += '

';
            }
        }
        testTabs += "
";
        $('#testSelector').html(testTabs);

        this.updateTestSelector(0);
        this.resetTestScores();
        this.initPlaybackControls();
    },

    updateTestScores: function (testScores) {
        console.log('updateTestScores')
        // Display test results
        for(var iTest=0; iTest<testScores.length; iTest++) {
            if(testScores[iTest].successRate >= 1) {
                var icon = '✔';
                var label = ''+this.strings.correctAnswer+'';
            } else if(testScores[iTest].successRate > 0) {
                var icon = '✖';
                var label = ''+this.strings.partialAnswer+'';
            } else {
                var icon = '✖';
                var label = ''+this.strings.wrongAnswer+'';
            }
            $('#testTab'+iTest+' .testTitle').html(icon+' Test '+(iTest+1)+' '+label);
        }
    },

    resetTestScores: function () {
        console.log('resetTestScores')
        // Reset test results display
        for(var iTest=0; iTest<this.nbTestCases; iTest++) {
            $('#testTab'+iTest+' .testTitle').html('  Test '+(iTest+1));
        }
    },

    updateTestSelector: function (newCurTest) {
        console.log('updateTestSelector')
        $("#testSelector .testTab").removeClass('currentTest');
        $("#testTab"+newCurTest).addClass('currentTest');
        $("#task").append($('#messages'));
        //$("#testTab"+newCurTest+" .panel-body").prepend($('#grid')).append($('#messages')).show();
    },

    createModeSelectorButtons: function() {
        var self = this;
        $("#task").append('\

\

\

\

\

');

        $('#modeSelector div').click(function() {
            self.selectMode($(this).attr('id'));
        })
    },

    selectMode: function(mode) {
        if(mode === this.curMode) return;
        $('#task').removeClass(this.curMode).addClass(mode);
        $('#' + mode).hide();
        if(this.curMode) {
            $('#' + this.curMode).show();
        }
        if(mode == 'mode-instructions') {
            $('#taskIntro .short').hide();
            $('#taskIntro .long').show();
        }
        if(mode == 'mode-player') {
            $('#taskIntro .short').show();
            $('#taskIntro .long').hide();
        }
        this.curMode = mode;
        this.onResize();
    },

    unloadLevel: function() {
        // Called when level is unloaded
        this.resetTestScores();
        if(this.curMode == 'mode-editor') {
           this.selectMode('mode-player');
        }
    },

    onResize: function(e) {
        var blocklyArea = document.getElementById('blocklyContainer');
        var blocklyDiv = document.getElementById('blocklyDiv');
        blocklyDiv.style.width = blocklyArea.offsetWidth + 'px';
        blocklyDiv.style.height = blocklyArea.offsetHeight + 'px';
        Blockly.svgResize(window.blocklyWorkspace);
    },

    displayError: function(message) {
        $('#errorModal').remove();
        if(!message) return;
        var html =
            '
' +
            '
' +
            '<button type="button" class="btn close" onclick="closeModal(`errorModal`)">x</button>' +
            '
' + message + '
' +
            '
' +
            '
';
        $(document.body).append($(html));
        $("#errorModal").show();
    }
};

$(document).ready(function() {

    $("#task h1").appendTo($("#miniPlatformHeader table td").first());
    $('#taskIntro, #gridContainer').wrapAll("

");

    $('head').append('<link rel="stylesheet"\
    href="https://use.fontawesome.com/releases/v5.3.1/css/all.css"\
    integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU"\
    crossorigin="anonymous">');

    quickAlgoInterface.createModeSelectorButtons();
    //selectMode('mode-instructions');
    quickAlgoInterface.selectMode('mode-player');

    window.addEventListener('resize', quickAlgoInterface.onResize, false);
    quickAlgoInterface.onResize();
});
<|endoftext|>