<commit_before>var alternator = 0;
var cooldown = 0;

function toggleMPD(){
	mpdRequest = new XMLHttpRequest();
	mpdRequest.open("GET", "http://shack.shack:5000/mpd/lounge/toggle", true);
	mpdRequest.setRequestHeader("Content-type","application/json");
	mpdRequest.send();

	if(document.getElementById("MPDbutton").src.split("/").slice(-1)[0] == "logo_mpd_stop.png"){ //I just wanted to select the last element :(
		document.getElementById("MPDbutton").src = "./images_home/logo_mpd_start.png";
	}
	else{
		document.getElementById("MPDbutton").src = "./images_home/logo_mpd_stop.png";
	}

	updateMPDButton();
}

function updateMPDButton(){
	var mpdStatus = new XMLHttpRequest();
	mpdStatus.open("GET", "http://shack.shack:5000/mpd/lounge/status", true);
	mpdStatus.setRequestHeader("Content-type","application/json");

	mpdStatus.onreadystatechange=function(){
		if(mpdStatus.readyState==4 && mpdStatus.status==200){
			response = JSON.parse(mpdStatus.responseText);
			console.log(response);
			if(response.status == "play"){
				document.getElementById("MPDbutton").src = "./images_home/logo_mpd_stop.png";
			}
			else{
				document.getElementById("MPDbutton").src = "./images_home/logo_mpd_start.png";
			}
		}
	}

	mpdStatus.send();

}

function requestMPDInformation(){
	var mpdRequest = null;
	mpdRequest = new XMLHttpRequest();
	mpdRequest.open("GET", "http://shack.shack:5000/mpd/lounge/song", true);
	mpdRequest.setRequestHeader("Content-type","application/json");

	mpdRequest.onreadystatechange=function(){
		if(mpdRequest.readyState==4 && mpdRequest.status==200){
			response = JSON.parse(mpdRequest.responseText);
			console.log(response);
			document.getElementById("mpd").style.backgroundColor = "#440";
			if(!response.file){
				document.getElementById("mpd").innerHTML= "MPD disabled"
			}
			else{
				if(!response.title){
					document.getElementById("mpd").innerHTML= response.file;
				}
				else{
					document.getElementById("mpd").innerHTML= response.title;
				}
			}

			//A little "responsive" scaling here. Not very responsive indeed.
			if(document.getElementById("mpd").innerHTML.length*25 > document.getElementById("mpdDiv").clientWidth){
				document.getElementById("mpd").style.fontSize = "20px";
			}
			else{
				document.getElementById("mpd").style.fontSize = "40px";
			}
		}
	}

	mpdRequest.send();
}

function requestPowerInformation(){
	var powerRequest = null;
	powerRequest = new XMLHttpRequest();
	powerRequest.open("GET", "http://glados.shack/siid/apps/powermeter.py?n=1", true);
	powerRequest.setRequestHeader("Content-type","application/json");

	powerRequest.onreadystatechange=function(){
		if(powerRequest.readyState==4 && powerRequest.status==200){
			response = JSON.parse(powerRequest.responseText);
			console.log(response);
			document.getElementById("power").innerHTML=response.Total[0] + " Watt";
		}
	}

	powerRequest.send();
}

function requestBTCInformation(){
	var btcRequest = null;
	btcRequest = new XMLHttpRequest();
	btcRequest.open("GET", "https://btc-e.com/api/3/ticker/btc_usd", true);
	btcRequest.setRequestHeader("Content-type","application/json");

	btcRequest.onreadystatechange=function(){
		if(btcRequest.readyState==4 && btcRequest.status==200){
			response = JSON.parse(btcRequest.responseText);
			console.log(response);
			document.getElementById("btc").innerHTML=response.btc_usd.avg.toString().substring(0, 5) + "$";
		}
	}

	btcRequest.send();
}

function requestKeyInformation(){
	var keyRequest = new XMLHttpRequest();
	keyRequest.open("GET", "http://portal.shack:8088/status", true);
	keyRequest.setRequestHeader("Content-type","application/json");

	keyRequest.onreadystatechange=function(){
		if(keyRequest.readyState==4 && keyRequest.status==200){
			response = JSON.parse(keyRequest.responseText);
			console.log(response);
			document.getElementById("keyholder").innerHTML="Key: " + response.keyholder;
			if(response.status == "closed"){
				document.getElementById("keyholder").style.backgroundColor = "#f00";
			}
			else{
				document.getElementById("keyholder").style.backgroundColor = "#002";
			}
		}
	}

	keyRequest.send();
}

function requestGelberSack(){
	var sackRequest = new XMLHttpRequest();
	sackRequest.open("GET", "http://openhab.shack/muellshack/gelber_sack", true);
	sackRequest.setRequestHeader("Content-type","application/json");

	sackRequest.onreadystatechange=function(){
		if(sackRequest.readyState==4 && sackRequest.status==200){
			response = JSON.parse(sackRequest.responseText);
			var sackdate = new Date(response.gelber_sack);
			if ( isNaN( sackdate.getTime() ) ) {
				document.getElementById("gelbersack").innerHTML= "kein Termin vorhanden";
			} else {
				var options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
				document.getElementById("gelbersack").innerHTML= "Gelber Sack: " + sackdate.toLocaleDateString('de-DE', options);
				if(sackdate.getTime() < Date.now()+60*60*24*1000){ //Color the date if its less than 24h away
					document.getElementById("gelbersack").style.backgroundColor = "#f00";
				}
				else{
					document.getElementById("gelbersack").style.backgroundColor = "#020";
				}
			}
		}
	}
	sackRequest.send();
}

function requestPapiermuell(){
	var sackRequest = new XMLHttpRequest();
	sackRequest.open("GET", "http://openhab.shack/muellshack/papiermuell", true);
	sackRequest.setRequestHeader("Content-type","application/json");

	sackRequest.onreadystatechange=function(){
		if(sackRequest.readyState==4 && sackRequest.status==200){
			response = JSON.parse(sackRequest.responseText);
			var sackdate = new Date(response.papiermuell);
			if ( isNaN( sackdate.getTime() ) ) {
				document.getElementById("papiermuell").innerHTML= "kein Termin vorhanden";
			} else {
				var options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
				document.getElementById("papiermuell").innerHTML= "Papiermuell: " + sackdate.toLocaleDateString('de-DE', options);
				if(sackdate.getTime() < Date.now()+60*60*24*1000){ //Color the date if its less than 24h away
					document.getElementById("papiermuell").style.backgroundColor = "#f00";
				}
				else{
					document.getElementById("papiermuell").style.backgroundColor = "#020";
				}
			}
		}
	}
	sackRequest.send();
}

function requestRestmuell(){
	var sackRequest = new XMLHttpRequest();
	sackRequest.open("GET", "http://openhab.shack/muellshack/restmuell", true);
	sackRequest.setRequestHeader("Content-type","application/json");

	sackRequest.onreadystatechange=function(){
		if(sackRequest.readyState==4 && sackRequest.status==200){
			response = JSON.parse(sackRequest.responseText);
			var sackdate = new Date(response.restmuell);
			if ( isNaN( sackdate.getTime() ) ) {
				document.getElementById("restmuell").innerHTML= "kein Termin vorhanden";
			} else {
				var options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
				document.getElementById("restmuell").innerHTML= "Restmuell: " + sackdate.toLocaleDateString('de-DE', options);
				if(sackdate.getTime() < Date.now()+60*60*24*1000){ //Color the date if its less than 24h away
					document.getElementById("restmuell").style.backgroundColor = "#f00";
				}
				else{
					document.getElementById("restmuell").style.backgroundColor = "#020";
				}
			}
		}
	}
	sackRequest.send();
}

function requestTemp(){
	var tempRequest = new XMLHttpRequest();
	tempRequest.open("GET", "http://smarthome.shack", true);
	tempRequest.setRequestHeader("Content-type","application/json");

	tempRequest.onreadystatechange=function(){
		if(tempRequest.readyState==4 && tempRequest.status==200){
			rt = tempRequest.responseText
			pos = rt.search("Humitidy : <b>")
			envstring = rt.substring(pos+14, pos+23).trim()
			console.log(envstring)
			document.getElementById("power").innerHTML=envstring
		}
	}
	tempRequest.send();
}

function requestNetwork(){
	var tokenRequest =  new XMLHttpRequest();
	tokenRequest.open("GET", "./tokens.txt", true);
	tokenRequest.onreadystatechange=function(){
		if(tokenRequest.readyState==4 && tokenRequest.status==200){
			console.log(tokenRequest.responseText);
			var token = JSON.parse(tokenRequest.responseText).librenms;
			var networkRequest = new XMLHttpRequest();
			networkRequest.open("GET", "http://librenms.shack/api/v0/devices/1/ports/Gi2%2F1", true);
			networkRequest.setRequestHeader("X-Auth-Token", token);
			networkRequest.onreadystatechange=function(){
				if(networkRequest.readyState==4 && networkRequest.status==200){
					var nd = JSON.parse(networkRequest.responseText);
					var downstream = (nd.port.ifInOctets_rate*8/1024/1024);
					var upstream = (nd.port.ifOutOctets_rate*8/1024/1024);
					document.getElementById("mpd").style.fontSize = "38px"; //Reset the font size
					if(downstream > 35 || upstream > 6){
						document.getElementById("mpd").style.backgroundColor = "#f00"; //Color the background red if high load
					}
					document.getElementById("mpd").innerHTML = "▼ " + downstream.toString().substring(0,4) + " Mbit/s (" + (downstream*2).toString().substring(0, 4) + "%) - ▲ " + upstream.toString().substring(0,4) + " Mbit/s (" + (upstream/0.1).toString().substring(0, 4) + "%)";
				}
			}
			networkRequest.send()
		}
	}
	tokenRequest.send()
}

function alarm(){
	if(cooldown < 3){
		cooldown++;
	}
	else{
		cooldown = -100; //Prevent double playing
		new Audio('./images_home/alarm.mp3').play();
	}
}

document.onreadystatechange = function() {
	var state = document.readyState;
	if(state == 'complete') {
		requestMPDInformation();
		requestPowerInformation();
		requestBTCInformation();
		requestKeyInformation();
		requestGelberSack();
		requestPapiermuell();
		requestRestmuell();
		updateMPDButton();

		setInterval(function(){
			alternator++; //Increment to allow for changing displays
			if(alternator%2 == 0){ //Alternate the displayed values
				requestPowerInformation();
				requestMPDInformation();
			}
			else{
				requestTemp();
				requestNetwork();
			}

			requestBTCInformation();
			requestKeyInformation();
			requestGelberSack();
			requestPapiermuell();
			requestRestmuell();
			updateMPDButton();
			cooldown = 0;
		}, 10000);
	}
}
<commit_msg>refactor sackrequest<commit_after>var alternator = 0;
var cooldown = 0;

function toggleMPD(){
	mpdRequest = new XMLHttpRequest();
	mpdRequest.open("GET", "http://shack.shack:5000/mpd/lounge/toggle", true);
	mpdRequest.setRequestHeader("Content-type","application/json");
	mpdRequest.send();

	if(document.getElementById("MPDbutton").src.split("/").slice(-1)[0] == "logo_mpd_stop.png"){ //I just wanted to select the last element :(
		document.getElementById("MPDbutton").src = "./images_home/logo_mpd_start.png";
	}
	else{
		document.getElementById("MPDbutton").src = "./images_home/logo_mpd_stop.png";
	}

	updateMPDButton();
}

function updateMPDButton(){
	var mpdStatus = new XMLHttpRequest();
	mpdStatus.open("GET", "http://shack.shack:5000/mpd/lounge/status", true);
	mpdStatus.setRequestHeader("Content-type","application/json");

	mpdStatus.onreadystatechange=function(){
		if(mpdStatus.readyState==4 && mpdStatus.status==200){
			response = JSON.parse(mpdStatus.responseText);
			console.log(response);
			if(response.status == "play"){
				document.getElementById("MPDbutton").src = "./images_home/logo_mpd_stop.png";
			}
			else{
				document.getElementById("MPDbutton").src = "./images_home/logo_mpd_start.png";
			}
		}
	}

	mpdStatus.send();

}

function requestMPDInformation(){
	var mpdRequest = null;
	mpdRequest = new XMLHttpRequest();
	mpdRequest.open("GET", "http://shack.shack:5000/mpd/lounge/song", true);
	mpdRequest.setRequestHeader("Content-type","application/json");

	mpdRequest.onreadystatechange=function(){
		if(mpdRequest.readyState==4 && mpdRequest.status==200){
			response = JSON.parse(mpdRequest.responseText);
			console.log(response);
			document.getElementById("mpd").style.backgroundColor = "#440";
			if(!response.file){
				document.getElementById("mpd").innerHTML= "MPD disabled"
			}
			else{
				if(!response.title){
					document.getElementById("mpd").innerHTML= response.file;
				}
				else{
					document.getElementById("mpd").innerHTML= response.title;
				}
			}

			//A little "responsive" scaling here. Not very responsive indeed.
			if(document.getElementById("mpd").innerHTML.length*25 > document.getElementById("mpdDiv").clientWidth){
				document.getElementById("mpd").style.fontSize = "20px";
			}
			else{
				document.getElementById("mpd").style.fontSize = "40px";
			}
		}
	}

	mpdRequest.send();
}

function requestPowerInformation(){
	var powerRequest = null;
	powerRequest = new XMLHttpRequest();
	powerRequest.open("GET", "http://glados.shack/siid/apps/powermeter.py?n=1", true);
	powerRequest.setRequestHeader("Content-type","application/json");

	powerRequest.onreadystatechange=function(){
		if(powerRequest.readyState==4 && powerRequest.status==200){
			response = JSON.parse(powerRequest.responseText);
			console.log(response);
			document.getElementById("power").innerHTML=response.Total[0] + " Watt";
		}
	}

	powerRequest.send();
}

function requestBTCInformation(){
	var btcRequest = null;
	btcRequest = new XMLHttpRequest();
	btcRequest.open("GET", "https://btc-e.com/api/3/ticker/btc_usd", true);
	btcRequest.setRequestHeader("Content-type","application/json");

	btcRequest.onreadystatechange=function(){
		if(btcRequest.readyState==4 && btcRequest.status==200){
			response = JSON.parse(btcRequest.responseText);
			console.log(response);
			document.getElementById("btc").innerHTML=response.btc_usd.avg.toString().substring(0, 5) + "$";
		}
	}

	btcRequest.send();
}

function requestKeyInformation(){
	var keyRequest = new XMLHttpRequest();
	keyRequest.open("GET", "http://portal.shack:8088/status", true);
	keyRequest.setRequestHeader("Content-type","application/json");

	keyRequest.onreadystatechange=function(){
		if(keyRequest.readyState==4 && keyRequest.status==200){
			response = JSON.parse(keyRequest.responseText);
			console.log(response);
			document.getElementById("keyholder").innerHTML="Key: " + response.keyholder;
			if(response.status == "closed"){
				document.getElementById("keyholder").style.backgroundColor = "#f00";
			}
			else{
				document.getElementById("keyholder").style.backgroundColor = "#002";
			}
		}
	}

	keyRequest.send();
}

function requestGelberSack(){
  requestMuell("gelber_sack","Gelber Sack")
}

function requestPapiermuell(){
  requestMuell("papiermuell","Papiermüll")
}

function requestMuell(muell,fancyname){
	var Request = new XMLHttpRequest();
	Request.open("GET", "http://openhab.shack/muellshack/"+muell, true);
	Request.setRequestHeader("Content-type","application/json");

	Request.onreadystatechange=function(){
		if(Request.readyState==4 && Request.status==200){
			response = JSON.parse(Request.responseText);
			var sackdate = new Date(response[muell]);
			if ( isNaN( sackdate.getTime() ) ) {
				document.getElementById(muell).innerHTML= "kein Termin vorhanden";
			} else {
				var options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
				document.getElementById(muell).innerHTML= fancyname+": " + sackdate.toLocaleDateString('de-DE', options);
				if(sackdate.getTime() < Date.now()+60*60*24*1000){ //Color the date if its less than 24h away
					document.getElementById(muell).style.backgroundColor = "#f00";
          // also set muell img to visible
					document.getElementById(muell+"-img").style.visibility = "visible";
          document.getElementById("muell-head").style.visibility = "visible";
				}
				else{
					document.getElementById(muell).style.backgroundColor = "#020";
				}
			}
		}
	}
	Request.send();
}
function requestRestmuell(){
  requestMuell("restmuell","Restmüll")
}

function requestTemp(){
	var tempRequest = new XMLHttpRequest();
	tempRequest.open("GET", "http://smarthome.shack", true);
	tempRequest.setRequestHeader("Content-type","application/json");

	tempRequest.onreadystatechange=function(){
		if(tempRequest.readyState==4 && tempRequest.status==200){
			rt = tempRequest.responseText
			pos = rt.search("Humitidy : <b>")
			envstring = rt.substring(pos+14, pos+23).trim()
			console.log(envstring)
			document.getElementById("power").innerHTML=envstring
		}
	}
	tempRequest.send();
}

function requestNetwork(){
	var tokenRequest =  new XMLHttpRequest();
	tokenRequest.open("GET", "./tokens.txt", true);
	tokenRequest.onreadystatechange=function(){
		if(tokenRequest.readyState==4 && tokenRequest.status==200){
			console.log(tokenRequest.responseText);
			var token = JSON.parse(tokenRequest.responseText).librenms;
			var networkRequest = new XMLHttpRequest();
			networkRequest.open("GET", "http://librenms.shack/api/v0/devices/1/ports/Gi2%2F1", true);
			networkRequest.setRequestHeader("X-Auth-Token", token);
			networkRequest.onreadystatechange=function(){
				if(networkRequest.readyState==4 && networkRequest.status==200){
					var nd = JSON.parse(networkRequest.responseText);
					var downstream = (nd.port.ifInOctets_rate*8/1024/1024);
					var upstream = (nd.port.ifOutOctets_rate*8/1024/1024);
					document.getElementById("mpd").style.fontSize = "38px"; //Reset the font size
					if(downstream > 35 || upstream > 6){
						document.getElementById("mpd").style.backgroundColor = "#f00"; //Color the background red if high load
					}
					document.getElementById("mpd").innerHTML = "▼ " + downstream.toString().substring(0,4) + " Mbit/s (" + (downstream*2).toString().substring(0, 4) + "%) - ▲ " + upstream.toString().substring(0,4) + " Mbit/s (" + (upstream/0.1).toString().substring(0, 4) + "%)";
				}
			}
			networkRequest.send()
		}
	}
	tokenRequest.send()
}

function alarm(){
	if(cooldown < 3){
		cooldown++;
	}
	else{
		cooldown = -100; //Prevent double playing
		new Audio('./images_home/alarm.mp3').play();
	}
}

document.onreadystatechange = function() {
	var state = document.readyState;
	if(state == 'complete') {
		requestMPDInformation();
		requestPowerInformation();
		requestBTCInformation();
		requestKeyInformation();
		requestGelberSack();
		requestPapiermuell();
		requestRestmuell();
		updateMPDButton();

		setInterval(function(){
			alternator++; //Increment to allow for changing displays
			if(alternator%2 == 0){ //Alternate the displayed values
				requestPowerInformation();
				requestMPDInformation();
			}
			else{
				requestTemp();
				requestNetwork();
			}

			requestBTCInformation();
			requestKeyInformation();
			requestGelberSack();
			requestPapiermuell();
			requestRestmuell();
			updateMPDButton();
			cooldown = 0;
		}, 10000);
	}
}
<|endoftext|>


<commit_before>// client-dialback-test.js
//
// Test the client registration API
//
// Copyright 2012, StatusNet Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var assert = require("assert"),
    vows = require("vows"),
    Step = require("step"),
    querystring = require("querystring"),
    _ = require("underscore"),
    httputil = require("./lib/http"),
    oauthutil = require("./lib/oauth"),
    dialbackApp = require("./lib/dialback").dialbackApp,
    setupApp = oauthutil.setupApp;

var suite = vows.describe("client registration with dialback");

var dbreg = function(id, token, ts, params, callback) {
    var URL = "http://localhost:4815/api/client/register",
        requestBody = querystring.stringify(params);

    httputil.dialbackPost(URL, id, token, ts, requestBody, "application/x-www-form-urlencoded", callback);
};

var assoc = function(id, token, ts) {
    return function() {
        var callback = this.callback;
        if (!ts) ts = Date.now();
        dbreg(id,
              token,
              ts,
              {type: "client_associate"},
              callback);
    };
};

var assocFail = function(id, token, ts) {
    return {
        topic: assoc(id, token, ts),
        "it fails correctly": function(err, res, body) {
            assert.ifError(err);
            assert.equal(res.statusCode, 401);
        }
    };
};

suite.addBatch({
    "When we set up the app": {
        topic: function() {
            var app, callback = this.callback;
            Step(
                function() {
                    setupApp(this);
                },
                function(err, result) {
                    if (err) throw err;
                    app = result;
                    dialbackApp(80, "dialback.localhost", this);
                },
                function(err, dbapp) {
                    if (err) {
                        callback(err, null, null);
                    } else {
                        callback(err, app, dbapp);
                    }
                }
            );
        },
        teardown: function(app, dbapp) {
            app.close();
            dbapp.close();
        },
        "it works": function(err, app, dbapp) {
            assert.ifError(err);
        },
        "and we try to register with an invalid host":
        assocFail("social.invalid", "VALID"),
        "and we try to register with an invalid webfinger domain":
        assocFail("alice@social.invalid", "VALID"),
        "and we try to register with an invalid webfinger":
        assocFail("invalid@dialback.localhost", "VALID"),
        "and we try to register with a valid webfinger and invalid token":
        assocFail("valid@dialback.localhost", "INVALID"),
        "and we try to register with a valid webfinger and valid token and out-of-bounds date":
        assocFail("valid@dialback.localhost", "VALID", Date.now() - 600000)
    }
});

suite["export"](module);
<commit_msg>Test for successful association<commit_after>// client-dialback-test.js
//
// Test the client registration API
//
// Copyright 2012, StatusNet Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var assert = require("assert"),
    vows = require("vows"),
    Step = require("step"),
    querystring = require("querystring"),
    _ = require("underscore"),
    httputil = require("./lib/http"),
    oauthutil = require("./lib/oauth"),
    dialbackApp = require("./lib/dialback").dialbackApp,
    setupApp = oauthutil.setupApp;

var suite = vows.describe("client registration with dialback");

var dbreg = function(id, token, ts, params, callback) {
    var URL = "http://localhost:4815/api/client/register",
        requestBody = querystring.stringify(params);

    httputil.dialbackPost(URL, id, token, ts, requestBody, "application/x-www-form-urlencoded", callback);
};

var assoc = function(id, token, ts) {
    return function() {
        var callback = this.callback;
        if (!ts) ts = Date.now();
        dbreg(id,
              token,
              ts,
              {type: "client_associate"},
              callback);
    };
};

var assocFail = function(id, token, ts) {
    return {
        topic: assoc(id, token, ts),
        "it fails correctly": function(err, res, body) {
            assert.ifError(err);
            assert.equal(res.statusCode, 401);
        }
    };
};

var assocSucceed = function(id, token, ts) {
    return {
        topic: assoc(id, token, ts),
        "it works": function(err, res, body) {
            assert.ifError(err);
            assert.greater(res.statusCode, 199);
            assert.lesser(res.statusCode, 300);
        },
        "it looks right": function(err, res, body) {
            var parsed;
            assert.ifError(err);
            assert.greater(res.statusCode, 199);
            assert.lesser(res.statusCode, 300);
            parsed = JSON.parse(body);
            assert.include(parsed, "client_id");
            assert.include(parsed, "client_secret");
            assert.include(parsed, "expires_at");
        }
    };
};

suite.addBatch({
    "When we set up the app": {
        topic: function() {
            var app, callback = this.callback;
            Step(
                function() {
                    setupApp(this);
                },
                function(err, result) {
                    if (err) throw err;
                    app = result;
                    dialbackApp(80, "dialback.localhost", this);
                },
                function(err, dbapp) {
                    if (err) {
                        callback(err, null, null);
                    } else {
                        callback(err, app, dbapp);
                    }
                }
            );
        },
        teardown: function(app, dbapp) {
            app.close();
            dbapp.close();
        },
        "it works": function(err, app, dbapp) {
            assert.ifError(err);
        },
        "and we try to register with an invalid host":
        assocFail("social.invalid", "VALID1"),
        "and we try to register with an invalid webfinger domain":
        assocFail("alice@social.invalid", "VALID2"),
        "and we try to register with an invalid webfinger":
        assocFail("invalid@dialback.localhost", "VALID3"),
        "and we try to register with a valid webfinger and invalid token":
        assocFail("valid@dialback.localhost", "INVALID"),
        "and we try to register with a valid webfinger and valid token and out-of-bounds date":
        assocFail("valid1@dialback.localhost", "VALID4", Date.now() - 600000),
        "and we try to register with a valid host and invalid token":
        assocFail("dialback.localhost", "INVALID"),
        "and we try to register with a valid host and valid token and out-of-bounds date":
        assocFail("dialback.localhost", "VALID5", Date.now() - 600000),
        "and we try to register with a valid webfinger and valid token":
        assocSucceed("valid2@dialback.localhost", "VALID6"),
        "and we try to register with a valid host and valid token":
        assocSucceed("dialback.localhost", "VALID7")
    }
});

suite["export"](module);
<|endoftext|>


<commit_before>"use strict";

const ArchiveView    = require.resolve("./consumers/archive-view.js");
const FindAndReplace = require.resolve("./consumers/find-and-replace.js");
const FuzzyFinder    = require.resolve("./consumers/fuzzy-finder.js");
const Tabs           = require.resolve("./consumers/tabs.js");
const TreeView       = require.resolve("./consumers/tree-view.js");
const Consumers      = require.resolve("./consumers/all.js");
const Options        = require.resolve("./options.js");
const Storage        = require.resolve("./storage.js");

const log = [];

module.exports = {
	get options (){ return require(Options)},
	get storage (){ return require(Storage)},
	get paths   (){ return this.fs.paths},
	get fs      (){ return require("atom-fs")},
	get log     (){ return Array.from(log)},
	get print   (){ return require("print")},

	// Consumer classes
	get archiveView    (){ return require(ArchiveView)},
	get findAndReplace (){ return require(FindAndReplace)},
	get fuzzyFinder    (){ return require(FuzzyFinder)},
	get tabs           (){ return require(Tabs)},
	get treeView       (){ return require(TreeView)},
	get consumers      (){ return require(Consumers)},

	/**
	 * Record and timestamp a hash of data.
	 * @param {Object} input
	 */
	logInfo(input){
		Object.defineProperty(input, "timestamp", {
			value: new Date(),
			writable: false,
			enumerable: false
		});
		log.push(input);
	},

	/**
	 * Include a file relative to package's base directory.
	 *
	 * @example inc("lib/consumers/tree-view")
	 * @param {String} file
	 * @return {Object}
	 */
	inc(file){
		const {join} = require("path");
		const {path} = atom.packages.loadedPackages["file-icons"];
		return require(join(path, ...file.split(/[\\\/]+/g)));
	},

	/**
	 * Wrapper for {@link FileSystem.grep} optimised for console inspection.
	 *
	 * @param {String|RegExp} name
	 * @return {Resource|Resource[]}
	 */
	grep(name){
		const results = require(FileSystem).grep(name);
		switch(results.length){
			case 0:  return null;       break;
			case 1:  return results[0]; break;
			default: return results;
		}
	},
};

Object.freeze(module.exports);
Object.defineProperty(global, "_FileIcons", {
	value: module.exports,
	enumerable:   true,
	configurable: false,
	writable:     false,
});
<commit_msg>Fix broken reference to FileSystem singleton<commit_after>"use strict";

const ArchiveView    = require.resolve("./consumers/archive-view.js");
const FindAndReplace = require.resolve("./consumers/find-and-replace.js");
const FuzzyFinder    = require.resolve("./consumers/fuzzy-finder.js");
const Tabs           = require.resolve("./consumers/tabs.js");
const TreeView       = require.resolve("./consumers/tree-view.js");
const Consumers      = require.resolve("./consumers/all.js");
const Options        = require.resolve("./options.js");
const Storage        = require.resolve("./storage.js");

const log = [];

module.exports = {
	get options (){ return require(Options)},
	get storage (){ return require(Storage)},
	get paths   (){ return this.fs.paths},
	get fs      (){ return require("atom-fs")},
	get log     (){ return Array.from(log)},
	get print   (){ return require("print")},

	// Consumer classes
	get archiveView    (){ return require(ArchiveView)},
	get findAndReplace (){ return require(FindAndReplace)},
	get fuzzyFinder    (){ return require(FuzzyFinder)},
	get tabs           (){ return require(Tabs)},
	get treeView       (){ return require(TreeView)},
	get consumers      (){ return require(Consumers)},

	/**
	 * Record and timestamp a hash of data.
	 * @param {Object} input
	 */
	logInfo(input){
		Object.defineProperty(input, "timestamp", {
			value: new Date(),
			writable: false,
			enumerable: false
		});
		log.push(input);
	},

	/**
	 * Include a file relative to package's base directory.
	 *
	 * @example inc("lib/consumers/tree-view")
	 * @param {String} file
	 * @return {Object}
	 */
	inc(file){
		const {join} = require("path");
		const {path} = atom.packages.loadedPackages["file-icons"];
		return require(join(path, ...file.split(/[\\\/]+/g)));
	},

	/**
	 * Wrapper for {@link FileSystem.grep} optimised for console inspection.
	 *
	 * @param {String|RegExp} name
	 * @return {Resource|Resource[]}
	 */
	grep(name){
		const results = global.AtomFS.grep(name);
		switch(results.length){
			case 0:  return null;       break;
			case 1:  return results[0]; break;
			default: return results;
		}
	},
};

Object.freeze(module.exports);
Object.defineProperty(global, "_FileIcons", {
	value: module.exports,
	enumerable:   true,
	configurable: false,
	writable:     false,
});
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import { logInfo, logDebug, logWarn, logError } from 'pretty-logs/src/index';

class App extends Component {
  render() {
    logInfo('CATEGORY', 'This is a message', {});
    logDebug('CATEGORY', 'This is a message', {});
    logWarn('CATEGORY', 'This is a message', {});
    logError('CATEGORY', 'This is a message', {});

    return (

Welcome to React

          To get started, edit src/App.js and save to reload.

    );
  }
}

export default App;
<commit_msg>Update example-app<commit_after>import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import plog from 'pretty-logs/src/index';

class App extends Component {
  render() {
    plog({
      level: 'debug',
      message: 'Login debug',
      extra: { category: 'AUTH' }
    });

    return (

Welcome to React

          To get started, edit src/App.js and save to reload.

    );
  }
}

export default App;
<|endoftext|>


<commit_before>const path = require('path')
const fs = require('fs')
const should = require('should')
const jsreportVersionToTest = require('../jsreportVersionToTest')
const utils = require('../utils')
const repair = require('../../lib/commands/repair').handler

const TEMP_DIRS = [
  'repair-empty',
  'repair-with-specific-version',
  'repair-packagejson-only',
  'repair-packagejson-with-server',
  'repair-packagejson-with-config'
]

describe('repair command', function () {
  // disabling timeout because removing files could take a
  // couple of seconds
  this.timeout(0)

  before(() => {
    utils.cleanTempDir(TEMP_DIRS)

    utils.createTempDir(TEMP_DIRS, (dir, absoluteDir) => {
      switch (dir) {
        case 'repair-packagejson-only':
          fs.writeFileSync(
            path.join(absoluteDir, './package.json'),
            JSON.stringify({
              name: 'packagejson-only',
              dependencies: {
                jsreport: jsreportVersionToTest
              }
            }, null, 2)
          )
          return

        case 'repair-packagejson-with-server':
          fs.writeFileSync(
            path.join(absoluteDir, './package.json'),
            JSON.stringify({
              name: 'packagejson-with-server',
              dependencies: {
                jsreport: jsreportVersionToTest
              }
            }, null, 2)
          )

          fs.writeFileSync(
            path.join(absoluteDir, './server.js'),
            'require("jsreport")().init()'
          )
          return

        case 'repair-packagejson-with-config':
          fs.writeFileSync(
            path.join(absoluteDir, './package.json'),
            JSON.stringify({
              name: 'config',
              dependencies: {
                jsreport: jsreportVersionToTest
              }
            }, null, 2)
          )

          fs.writeFileSync(
            path.join(absoluteDir, './jsreport.config.json'),
            '{"store": { "provider": "fs" }}'
          )
      }
    })
  })

  it('should work on empty directory', async function () {
    // disabling timeout because npm install could take a
    // couple of minutes
    this.timeout(0)

    const dir = utils.getTempDir('repair-empty')

    const jsreportPackage = await repair({ context: { cwd: dir } })

    // should install jsreport package
    should(fs.existsSync(path.join(dir, 'node_modules/' + jsreportPackage.name))).be.eql(true)
    // and generate default files
    should(fs.existsSync(path.join(dir, 'server.js'))).be.eql(true)
    should(fs.existsSync(path.join(dir, 'jsreport.config.json'))).be.eql(true)
    should(fs.existsSync(path.join(dir, 'package.json'))).be.eql(true)
  })

  it('should work with specific jsreport version', async function () {
    // disabling timeout because npm install could take a
    // couple of minutes
    this.timeout(0)

    const dir = utils.getTempDir('repair-with-specific-version')
    const versionToInstall = jsreportVersionToTest

    const jsreportPackage = await repair({ context: { cwd: dir }, _: [null, versionToInstall] })

    // should install jsreport package
    should(fs.existsSync(path.join(dir, 'node_modules/' + jsreportPackage.name))).be.eql(true)
    // and generate default files
    should(fs.existsSync(path.join(dir, 'server.js'))).be.eql(true)
    should(fs.existsSync(path.join(dir, 'jsreport.config.json'))).be.eql(true)
    should(fs.existsSync(path.join(dir, 'package.json'))).be.eql(true)

    should(JSON.parse(
      fs.readFileSync(path.join(dir, 'package.json')).toString()
    ).dependencies.jsreport).endWith(versionToInstall)
  })

  it('should work on a directory that contains only package.json', async function () {
    // disabling timeout because npm install could take a
    // couple of minutes
    this.timeout(0)

    const dir = utils.getTempDir('repair-packagejson-only')

    await repair({ context: { cwd: dir } })

    // should generate default files
    should(fs.existsSync(path.join(dir, 'server.js'))).be.eql(true)
    should(fs.existsSync(path.join(dir, 'jsreport.config.json'))).be.eql(true)
    // and replace package.json in dir
    should(
      JSON.parse(
        fs.readFileSync(path.join(dir, 'package.json')).toString()
      ).name
    ).be.eql('jsreport-server')
  })

  it('should override server.js file', async function () {
    // disabling timeout because npm install could take a
    // couple of minutes
    this.timeout(0)

    const dir = utils.getTempDir('repair-packagejson-with-server')

    await repair({ context: { cwd: dir } })

    // should generate default files
    should(fs.existsSync(path.join(dir, 'jsreport.config.json'))).be.eql(true)
    // replace package.json in dir
    should(
      JSON.parse(
        fs.readFileSync(path.join(dir, 'package.json')).toString()
      ).name
    ).be.eql('jsreport-server')
    // and replace server.js
    should(
      fs.readFileSync(path.join(dir, 'server.js')).toString().trim()
    ).be.not.eql('require("jsreport")().init()')
  })

  it('should override jsreport.config.json file', async function () {
    // disabling timeout because npm install could take a
    // couple of minutes
    this.timeout(0)

    const dir = utils.getTempDir('repair-packagejson-with-config')

    await repair({ context: { cwd: dir } })

    // should generate default files
    should(fs.existsSync(path.join(dir, 'jsreport.config.json'))).be.eql(true)
    should(fs.existsSync(path.join(dir, 'server.js'))).be.eql(true)
    // replace package.json in dir
    should(
      JSON.parse(
        fs.readFileSync(path.join(dir, 'package.json')).toString()
      ).name
    ).be.eql('jsreport-server')
    // and replace jsreport.config.json
    should(
      fs.readFileSync(path.join(dir, 'jsreport.config.json')).toString().trim()
    ).be.not.eql('{"store": { "provider": "fs" }}')
  })

  after(() => utils.cleanTempDir(TEMP_DIRS))
})
<commit_msg>fix test<commit_after>const path = require('path')
const fs = require('fs')
const should = require('should')
const jsreportVersionToTest = require('../jsreportVersionToTest')
const utils = require('../utils')
const repair = require('../../lib/commands/repair').handler

const TEMP_DIRS = [
  'repair-empty',
  'repair-with-specific-version',
  'repair-packagejson-only',
  'repair-packagejson-with-server',
  'repair-packagejson-with-config'
]

describe('repair command', function () {
  // disabling timeout because removing files could take a
  // couple of seconds
  this.timeout(0)

  before(() => {
    utils.cleanTempDir(TEMP_DIRS)

    utils.createTempDir(TEMP_DIRS, (dir, absoluteDir) => {
      switch (dir) {
        case 'repair-packagejson-only':
          fs.writeFileSync(
            path.join(absoluteDir, './package.json'),
            JSON.stringify({
              name: 'packagejson-only',
              dependencies: {
                jsreport: jsreportVersionToTest
              }
            }, null, 2)
          )
          return

        case 'repair-packagejson-with-server':
          fs.writeFileSync(
            path.join(absoluteDir, './package.json'),
            JSON.stringify({
              name: 'packagejson-with-server',
              dependencies: {
                jsreport: jsreportVersionToTest
              }
            }, null, 2)
          )

          fs.writeFileSync(
            path.join(absoluteDir, './server.js'),
            'require("jsreport")().init()'
          )
          return

        case 'repair-packagejson-with-config':
          fs.writeFileSync(
            path.join(absoluteDir, './package.json'),
            JSON.stringify({
              name: 'config',
              dependencies: {
                jsreport: jsreportVersionToTest
              }
            }, null, 2)
          )

          fs.writeFileSync(
            path.join(absoluteDir, './jsreport.config.json'),
            '{"store": { "provider": "fs" }}'
          )
      }
    })
  })

  it('should work on empty directory', async function () {
    // disabling timeout because npm install could take a
    // couple of minutes
    this.timeout(0)

    const dir = utils.getTempDir('repair-empty')

    const jsreportPackage = await repair({ context: { cwd: dir } })

    // should install jsreport package
    should(fs.existsSync(path.join(dir, 'node_modules/' + jsreportPackage.name))).be.eql(true)
    // and generate default files
    should(fs.existsSync(path.join(dir, 'server.js'))).be.eql(true)
    should(fs.existsSync(path.join(dir, 'jsreport.config.json'))).be.eql(true)
    should(fs.existsSync(path.join(dir, 'package.json'))).be.eql(true)
  })

  it('should work with specific jsreport version', async function () {
    // disabling timeout because npm install could take a
    // couple of minutes
    this.timeout(0)

    const dir = utils.getTempDir('repair-with-specific-version')
    const versionToInstall = jsreportVersionToTest

    const jsreportPackage = await repair({ context: { cwd: dir }, _: [null, versionToInstall] })

    // should install jsreport package
    should(fs.existsSync(path.join(dir, 'node_modules/' + jsreportPackage.name))).be.eql(true)
    // and generate default files
    should(fs.existsSync(path.join(dir, 'server.js'))).be.eql(true)
    should(fs.existsSync(path.join(dir, 'jsreport.config.json'))).be.eql(true)
    should(fs.existsSync(path.join(dir, 'package.json'))).be.eql(true)

    should(JSON.parse(
      fs.readFileSync(path.join(dir, 'package.json')).toString()
    ).dependencies.jsreport).not.be.undefined()
  })

  it('should work on a directory that contains only package.json', async function () {
    // disabling timeout because npm install could take a
    // couple of minutes
    this.timeout(0)

    const dir = utils.getTempDir('repair-packagejson-only')

    await repair({ context: { cwd: dir } })

    // should generate default files
    should(fs.existsSync(path.join(dir, 'server.js'))).be.eql(true)
    should(fs.existsSync(path.join(dir, 'jsreport.config.json'))).be.eql(true)
    // and replace package.json in dir
    should(
      JSON.parse(
        fs.readFileSync(path.join(dir, 'package.json')).toString()
      ).name
    ).be.eql('jsreport-server')
  })

  it('should override server.js file', async function () {
    // disabling timeout because npm install could take a
    // couple of minutes
    this.timeout(0)

    const dir = utils.getTempDir('repair-packagejson-with-server')

    await repair({ context: { cwd: dir } })

    // should generate default files
    should(fs.existsSync(path.join(dir, 'jsreport.config.json'))).be.eql(true)
    // replace package.json in dir
    should(
      JSON.parse(
        fs.readFileSync(path.join(dir, 'package.json')).toString()
      ).name
    ).be.eql('jsreport-server')
    // and replace server.js
    should(
      fs.readFileSync(path.join(dir, 'server.js')).toString().trim()
    ).be.not.eql('require("jsreport")().init()')
  })

  it('should override jsreport.config.json file', async function () {
    // disabling timeout because npm install could take a
    // couple of minutes
    this.timeout(0)

    const dir = utils.getTempDir('repair-packagejson-with-config')

    await repair({ context: { cwd: dir } })

    // should generate default files
    should(fs.existsSync(path.join(dir, 'jsreport.config.json'))).be.eql(true)
    should(fs.existsSync(path.join(dir, 'server.js'))).be.eql(true)
    // replace package.json in dir
    should(
      JSON.parse(
        fs.readFileSync(path.join(dir, 'package.json')).toString()
      ).name
    ).be.eql('jsreport-server')
    // and replace jsreport.config.json
    should(
      fs.readFileSync(path.join(dir, 'jsreport.config.json')).toString().trim()
    ).be.not.eql('{"store": { "provider": "fs" }}')
  })

  after(() => utils.cleanTempDir(TEMP_DIRS))
})
<|endoftext|>


<commit_before>/**
 * Copyright 2013-2014 Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * TodoStore
 */

var AppDispatcher = require('../dispatcher/AppDispatcher');
var EventEmitter = require('events').EventEmitter;
var TodoConstants = require('../constants/TodoConstants');
var merge = require('react/lib/merge');

var CHANGE_EVENT = 'change';

var _todos = {};

/**
 * Create a TODO item.
 * @param  {string} text The content of the TODO
 */
function create(text) {
  // Hand waving here -- not showing how this interacts with XHR or persistent
  // server-side storage.
  // Using the current timestamp in place of a real id.
  var id = Date.now();
  _todos[id] = {
    id: id,
    complete: false,
    text: text
  };
}

/**
 * Update a TODO item.
 * @param  {string} id
 * @param {object} updates An object literal containing only the data to be
 *     updated.
 */
function update(id, updates) {
  _todos[id] = merge(_todos[id], updates);
}

/**
 * Update all of the TODO items with the same object.
 *     the data to be updated.  Used to mark all TODOs as completed.
 * @param  {object} updates An object literal containing only the data to be
 *     updated.

 */
function updateAll(updates) {
  for (var id in _todos) {
    update(id, updates);
  }
}

/**
 * Delete a TODO item.
 * @param  {string} id
 */
function destroy(id) {
  delete _todos[id];
}

/**
 * Delete all the completed TODO items.
 */
function destroyCompleted() {
  for (var id in _todos) {
    if (_todos[id].complete) {
      destroy(id);
    }
  }
}

var TodoStore = merge(EventEmitter.prototype, {

  /**
   * Tests whether all the remaining TODO items are marked as completed.
   * @return {booleam}
   */
  areAllComplete: function() {
    for (id in _todos) {
      if (!_todos[id].complete) {
        return false;
        break;
      }
    }
    return true;
  },

  /**
   * Get the entire collection of TODOs.
   * @return {object}
   */
  getAll: function() {
    return _todos;
  },

  emitChange: function() {
    this.emit(CHANGE_EVENT);
  },

  /**
   * @param {function} callback
   */
  addChangeListener: function(callback) {
    this.on(CHANGE_EVENT, callback);
  },

  /**
   * @param {function} callback
   */
  removeChangeListener: function(callback) {
    this.removeListener(CHANGE_EVENT, callback);
  }
});

// Register to handle all updates
AppDispatcher.register(function(payload) {
  var action = payload.action;
  var text;

  switch(action.actionType) {
    case TodoConstants.TODO_CREATE:
      text = action.text.trim();
      if (text !== '') {
        create(text);
      }
      break;

    case TodoConstants.TODO_TOGGLE_COMPLETE_ALL:
      if (TodoStore.areAllComplete()) {
        updateAll({complete: false});
      } else {
        updateAll({complete: true});
      }
      break;

    case TodoConstants.TODO_UNDO_COMPLETE:
      update(action.id, {complete: false});
      break;

    case TodoConstants.TODO_COMPLETE:
      update(action.id, {complete: true});
      break;

    case TodoConstants.TODO_UPDATE_TEXT:
      text = action.text.trim();
      if (text !== '') {
        update(action.id, {text: text});
      }
      break;

    case TodoConstants.TODO_DESTROY:
      destroy(action.id);
      break;

    case TodoConstants.TODO_DESTROY_COMPLETED:
      destroyCompleted();
      break;

    default:
      return true;
  }

  // This often goes in each case that should trigger a UI change. This store
  // needs to trigger a UI change after every view action, so we can make the
  // code less repetitive by putting it here.  We need the default case,
  // however, to make sure this only gets called after one of the cases above.
  TodoStore.emitChange();

  return true; // No errors.  Needed by promise in Dispatcher.
});

module.exports = TodoStore;
<commit_msg>Fix typo<commit_after>/**
 * Copyright 2013-2014 Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * TodoStore
 */

var AppDispatcher = require('../dispatcher/AppDispatcher');
var EventEmitter = require('events').EventEmitter;
var TodoConstants = require('../constants/TodoConstants');
var merge = require('react/lib/merge');

var CHANGE_EVENT = 'change';

var _todos = {};

/**
 * Create a TODO item.
 * @param  {string} text The content of the TODO
 */
function create(text) {
  // Hand waving here -- not showing how this interacts with XHR or persistent
  // server-side storage.
  // Using the current timestamp in place of a real id.
  var id = Date.now();
  _todos[id] = {
    id: id,
    complete: false,
    text: text
  };
}

/**
 * Update a TODO item.
 * @param  {string} id
 * @param {object} updates An object literal containing only the data to be
 *     updated.
 */
function update(id, updates) {
  _todos[id] = merge(_todos[id], updates);
}

/**
 * Update all of the TODO items with the same object.
 *     the data to be updated.  Used to mark all TODOs as completed.
 * @param  {object} updates An object literal containing only the data to be
 *     updated.

 */
function updateAll(updates) {
  for (var id in _todos) {
    update(id, updates);
  }
}

/**
 * Delete a TODO item.
 * @param  {string} id
 */
function destroy(id) {
  delete _todos[id];
}

/**
 * Delete all the completed TODO items.
 */
function destroyCompleted() {
  for (var id in _todos) {
    if (_todos[id].complete) {
      destroy(id);
    }
  }
}

var TodoStore = merge(EventEmitter.prototype, {

  /**
   * Tests whether all the remaining TODO items are marked as completed.
   * @return {boolean}
   */
  areAllComplete: function() {
    for (id in _todos) {
      if (!_todos[id].complete) {
        return false;
        break;
      }
    }
    return true;
  },

  /**
   * Get the entire collection of TODOs.
   * @return {object}
   */
  getAll: function() {
    return _todos;
  },

  emitChange: function() {
    this.emit(CHANGE_EVENT);
  },

  /**
   * @param {function} callback
   */
  addChangeListener: function(callback) {
    this.on(CHANGE_EVENT, callback);
  },

  /**
   * @param {function} callback
   */
  removeChangeListener: function(callback) {
    this.removeListener(CHANGE_EVENT, callback);
  }
});

// Register to handle all updates
AppDispatcher.register(function(payload) {
  var action = payload.action;
  var text;

  switch(action.actionType) {
    case TodoConstants.TODO_CREATE:
      text = action.text.trim();
      if (text !== '') {
        create(text);
      }
      break;

    case TodoConstants.TODO_TOGGLE_COMPLETE_ALL:
      if (TodoStore.areAllComplete()) {
        updateAll({complete: false});
      } else {
        updateAll({complete: true});
      }
      break;

    case TodoConstants.TODO_UNDO_COMPLETE:
      update(action.id, {complete: false});
      break;

    case TodoConstants.TODO_COMPLETE:
      update(action.id, {complete: true});
      break;

    case TodoConstants.TODO_UPDATE_TEXT:
      text = action.text.trim();
      if (text !== '') {
        update(action.id, {text: text});
      }
      break;

    case TodoConstants.TODO_DESTROY:
      destroy(action.id);
      break;

    case TodoConstants.TODO_DESTROY_COMPLETED:
      destroyCompleted();
      break;

    default:
      return true;
  }

  // This often goes in each case that should trigger a UI change. This store
  // needs to trigger a UI change after every view action, so we can make the
  // code less repetitive by putting it here.  We need the default case,
  // however, to make sure this only gets called after one of the cases above.
  TodoStore.emitChange();

  return true; // No errors.  Needed by promise in Dispatcher.
});

module.exports = TodoStore;
<|endoftext|>


<commit_before>/*
	Pour tester, lancer la commande "babel-node main.es6.js"

	Il faut avoir installé :
	 - nodejs ;
	 - npm ;
	 - les modules listés dans package.json ;
	 - babel
	 - stylus
*/

var express = require('express');
var bodyParser = require('body-parser');

var app = express();

//Pour les requêtes POST
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

//Le répertoire /static/ est considéré comme statique
app.use("/static", express.static(__dirname + "/static"));
//Les vues sont stockées dans /views
app.set('views', __dirname + '/views')
//Les vues sont en jade, préprocesseur pour HTML
app.set('view engine', 'jade');

var pages = [
	{
		url: 'index',
		icon: 'home',
		title: 'Accueil'
	},
	{
		url: 'calender',
		icon: 'calendar',
		title: 'Planning'
	},
	{
		url: 'documents',
		icon: 'book',
		title: 'Cours'
	},
	{
		url: 'tutoring',
		icon: 'graduation-cap',
		title: 'Tutorat'
	},
	{
		url: 'sign-in',
		icon: 'sign-in',
		title: 'Connexion'
	},
];

app.get('/', (req, res) => {
	res.redirect("/index");
});
app.get('/:page', (req, res) => {
	if(pages.find((page) => page.url==req.params.page))
		res.render("index.jade",
				{
					pages: pages.map(
						(page) => ({
							url: page.url,
							title: page.title,
							icon: page.icon,
							isActive: (page.url==req.params.page)
						})
					),
					page: req.params.page
				}
			);
	else
		res.redirect("/index");
});

app.listen(8080);
<commit_msg>Change port<commit_after>/*
	Pour tester, lancer la commande "babel-node main.es6.js"

	Il faut avoir installé :
	 - nodejs ;
	 - npm ;
	 - les modules listés dans package.json ;
	 - babel
	 - stylus
*/

var express = require('express');
var bodyParser = require('body-parser');

var app = express();

//Pour les requêtes POST
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

//Le répertoire /static/ est considéré comme statique
app.use("/static", express.static(__dirname + "/static"));
//Les vues sont stockées dans /views
app.set('views', __dirname + '/views')
//Les vues sont en jade, préprocesseur pour HTML
app.set('view engine', 'jade');

var pages = [
	{
		url: 'index',
		icon: 'home',
		title: 'Accueil'
	},
	{
		url: 'calender',
		icon: 'calendar',
		title: 'Planning'
	},
	{
		url: 'documents',
		icon: 'book',
		title: 'Cours'
	},
	{
		url: 'tutoring',
		icon: 'graduation-cap',
		title: 'Tutorat'
	},
	{
		url: 'sign-in',
		icon: 'sign-in',
		title: 'Connexion'
	},
];

app.get('/', (req, res) => {
	res.redirect("/index");
});
app.get('/:page', (req, res) => {
	if(pages.find((page) => page.url==req.params.page))
		res.render("index.jade",
				{
					pages: pages.map(
						(page) => ({
							url: page.url,
							title: page.title,
							icon: page.icon,
							isActive: (page.url==req.params.page)
						})
					),
					page: req.params.page
				}
			);
	else
		res.redirect("/index");
});

app.listen(57651);
<|endoftext|>


<commit_before>/**
 * `modules/idea-hub` data store: saved-ideas.
 *
 * Site Kit by Google, Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import invariant from 'invariant';
import isPlainObject from 'lodash/isPlainObject';

/**
 * Internal dependencies
 */
import API from 'googlesitekit-api';
import Data from 'googlesitekit-data';
import { createFetchStore } from '../../../googlesitekit/data/create-fetch-store';

const fetchCreateIdeaDraftPostStore = createFetchStore( {
	baseName: 'createIdeaDraftPost',
	controlCallback: ( { idea } ) => {
		return API.set( 'modules', 'idea-hub', 'create-idea-draft-post', { idea } );
	},
	reducerCallback: ( state, ideaDraftPost ) => {
		return {
			...state,
			ideaDraftPost,
		};
	},
	argsToParams: ( idea ) => {
		return { idea };
	},
	validateParams: ( { idea } ) => {
		invariant( isPlainObject( idea ), 'idea must be an object.' );
		invariant( typeof idea.name === 'string', 'idea.name must be a string.' );
		invariant( typeof idea.text === 'string', 'idea.text must be a string.' );
		invariant( Array.isArray( idea.topics ), 'idea.topics must be an array.' );
		idea.topics.forEach( ( topic ) => {
			invariant( typeof topic.mid === 'string', 'topic.mid must be a string.' );
			invariant( typeof topic.display_name === 'string', 'topic.display_name must be a string.' );
		} );
	},
} );

const baseInitialState = {
	ideaDraftPost: null,
};

const baseActions = {
	/**
	 * Creates a new Idea Hub Draft Post
	 *
	 * Creates a new draft post and attaches an idea to it.
	 *
	 * @since n.e.x.t
	 *
	 * @param {Object} idea Idea Hub Idea.
	 * @return {Object} Object with `response` and `error`.
	 */
	*createIdeaDraftPost( idea ) {
		const { response, error } = yield fetchCreateIdeaDraftPostStore.actions.fetchCreateIdeaDraftPost( idea );
		return { response, error };
	},
};

const store = Data.combineStores(
	fetchCreateIdeaDraftPostStore,
	{
		initialState: baseInitialState,
		actions: baseActions,
	}
);

export const initialState = store.initialState;
export const actions = store.actions;
export const controls = store.controls;
export const reducer = store.reducer;
export const resolvers = store.resolvers;
export const selectors = store.selectors;

export default store;
<commit_msg>Response does not need to be saved in state.<commit_after>/**
 * `modules/idea-hub` data store: saved-ideas.
 *
 * Site Kit by Google, Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import invariant from 'invariant';
import isPlainObject from 'lodash/isPlainObject';

/**
 * Internal dependencies
 */
import API from 'googlesitekit-api';
import Data from 'googlesitekit-data';
import { createFetchStore } from '../../../googlesitekit/data/create-fetch-store';

const fetchCreateIdeaDraftPostStore = createFetchStore( {
	baseName: 'createIdeaDraftPost',
	controlCallback: ( { idea } ) => {
		return API.set( 'modules', 'idea-hub', 'create-idea-draft-post', { idea } );
	},
	argsToParams: ( idea ) => {
		return { idea };
	},
	validateParams: ( { idea } ) => {
		invariant( isPlainObject( idea ), 'idea must be an object.' );
		invariant( typeof idea.name === 'string', 'idea.name must be a string.' );
		invariant( typeof idea.text === 'string', 'idea.text must be a string.' );
		invariant( Array.isArray( idea.topics ), 'idea.topics must be an array.' );
		idea.topics.forEach( ( topic ) => {
			invariant( typeof topic.mid === 'string', 'topic.mid must be a string.' );
			invariant( typeof topic.display_name === 'string', 'topic.display_name must be a string.' );
		} );
	},
} );

const baseActions = {
	/**
	 * Creates a new Idea Hub Draft Post
	 *
	 * Creates a new draft post and attaches an idea to it.
	 *
	 * @since n.e.x.t
	 *
	 * @param {Object} idea Idea Hub Idea.
	 * @return {Object} Object with `response` and `error`.
	 */
	*createIdeaDraftPost( idea ) {
		const { response, error } = yield fetchCreateIdeaDraftPostStore.actions.fetchCreateIdeaDraftPost( idea );
		return { response, error };
	},
};

const store = Data.combineStores(
	fetchCreateIdeaDraftPostStore,
	{
		actions: baseActions,
	}
);

export const initialState = store.initialState;
export const actions = store.actions;
export const controls = store.controls;
export const reducer = store.reducer;
export const resolvers = store.resolvers;
export const selectors = store.selectors;

export default store;
<|endoftext|>


<commit_before>/*jslint white: true */
/*global State, module, require, console */

/**
 * Copyright (c) 2014 markewest@gmail.com
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

module.exports = (function () {
  'use strict';

  var Socket   = null;
  var response = '';

  /**
   * @author markewest@gmail.com, jfeiler87
   * @fileoverview Basic control of Denon x4000 Receiver
   * @requires net
   */
  return {
    version : 20140910,

    inputs : ['command', 'list'],

    /**
     * Whitelist of available key codes to use.
     */
    keymap : ['POWER_STATUS', 'POWERON', 'POWEROFF', 'VOL_STATUS' ,'VOLUP', 'VOLDOWN', 'MUTE_STATUS', 'MUTE', 'UNMUTE', 'INPUT_STATUS', 'INPUT_BLURAY', 'INPUT_MPLAYER', 'INPUT_CD', 'INPUT_NETWORK', 'INPUT_TV', 'INPUT_GAME', 'MENU_STATUS', 'MENU', 'MENU_UP', 'MENU_DOWN', 'MENU_LEFT', 'MENU_RIGHT', 'MENU_ENTER', 'MENU_RETURN', 'SOUND_STATUS', 'SOUND_MOVIE', 'SOUND_MCHSTEREO', 'SOUND_PURE', 'ZONE1_STATUS', 'ZONE1_ON', 'ZONE1_OFF', 'ZONE2_STATUS', 'ZONE2_ON', 'ZONE2_VOL_UP', 'ZONE2_VOL_DOWN', 'ZONE2_OFF', 'ZONE3_STATUS', 'ZONE3_ON', 'ZONE3_VOL_UP', 'ZONE3_VOL_DOWN', 'ZONE3_OFF'],

    /**
     * Map inputted commands to the values the device or API is expecting.
     */
    hashTable : { 'POWER_STATUS'    : 'PW?',
                  'POWERON'         : 'ZMON',
                  'POWEROFF'        : 'PWSTANDBY',
                  'VOL_STATUS'      : 'MV?',
                  'VOLUP'           : 'MVUP',
                  'VOLDOWN'         : 'MVDOWN',
                  'MUTE_STATUS'     : 'MU?',
                  'MUTE'            : 'MUON',
                  'UNMUTE'          : 'MUOFF',
                  'INPUT_STATUS'    : 'SI?',
                  'INPUT_BLURAY'    : 'SIBD',
                  'INPUT_MPLAYER'   : 'SIMPLAY',
                  'INPUT_CD'        : 'SICD',
                  'INPUT_NETWORK'   : 'SINET',
                  'INPUT_TV'        : 'SISAT/CBL',
                  'INPUT_GAME'      : 'SIGAME',
                  'MENU_STATUS'     : 'MNMEN?',
                  'MENU'            : 'MNMEN ON',
                  'MENU_UP'         : 'MNCUP',
                  'MENU_DOWN'       : 'MNCDN',
                  'MENU_LEFT'       : 'MNCLT',
                  'MENU_RIGHT'      : 'MNCRT',
                  'MENU_ENTER'      : 'MNENT',
                  'MENU_RETURN'     : 'MNRTN',
                  'SOUND_STATUS'    : 'MS?',
                  'SOUND_MOVIE'     : 'MSMOVIE',
                  'SOUND_MCHSTEREO' : 'MSMCH STEREO',
                  'SOUND_PURE'      : 'MSPURE DIRECT',
                  'ZONE1_STATUS'    : 'ZM?',
                  'ZONE1_ON'        : 'ZMON',
                  'ZONE1_OFF'       : 'ZMOFF',
                  'ZONE2_STATUS'    : 'Z2?',
                  'ZONE2_ON'        : 'Z2ON',
                  'ZONE2_VOL_UP'    : 'Z2UP',
                  'ZONE2_VOL_DOWN'  : 'Z3DOWN',
                  'ZONE2_OFF'       : 'Z2OFF',
                  'ZONE3_STATUS'    : 'Z3?',
                  'ZONE3_ON'        : 'Z3ON',
                  'ZONE3_VOL_UP'    : 'Z3UP',
                  'ZONE3_VOL_DOWN'  : 'Z3DOWN',
                  'ZONE3_OFF'       : 'Z3OFF'
    },

    /**
     * Prepares and calls send() to request the current state.
     */
    state : function (controller, config, callback, count) {
      var deviceState    = require(__dirname + '/../lib/deviceState'),
          that           = this,
          denonState     = deviceState.getDeviceState(config.deviceId),
          denon          = { device : {}, config : {} },
          statusCommands = ['POWER_STATUS', 'MUTE_STATUS', 'ZONE1_STATUS', 'VOL_STATUS', 'INPUT_STATUS', 'SOUND_STATUS', 'ZONE2_STATUS', 'ZONE3_STATUS'];
          count          = count || 0;

      if(typeof denonState === 'undefined') {
        denonState = { value : { ZONE1 : {}, ZONE2 : {}, ZONE3 : {} } };
      }

      callback                  = callback || function() {};
      denon.device.deviceId     = controller.config.deviceId;
      denon.device.deviceIp     = controller.config.deviceIp;
      denon.device.localTimeout = controller.config.localTimeout || config.localTimeout;
      denon.command             = statusCommands[count];

      denon.callback = function (err, reply) {
        var rex = '';

        for(var i in reply) {

          if(reply[i].match(/PW.+/)) {
            if(rex = reply[i].match(/PW(ON|OFF|STANDBY)/)) {
              denonState.value.power = rex[1];
            }
          }

          else if(reply[i].match(/MU.+/)) {
            if(rex = reply[i].match(/MU(ON|OFF)/)) {
              denonState.value.ZONE1.mute = rex[1];
            }
          }

          else if(reply[i].match(/ZM.+/)) {
            if(rex = reply[i].match(/ZM(ON|OFF)/)) {
              denonState.value.ZONE1.power = rex[1];
            }
          }

          else if(reply[i].match(/MV.+/)) {
            if(rex = reply[i].match(/MV([0-9]+)/)) {
              denonState.value.ZONE1.volume = rex[1];
            }
            else if(rex = reply[i].match(/MVMAX.([0-9]+)/)) {
              denonState.value.ZONE1.maxvolume = rex[1];
            }
          }

          else if(reply[i].match(/SI.+/)) {
            if(rex = reply[i].match(/SI(.+)/)) {
              denonState.value.ZONE1.input = rex[1];
            }
          }

          else if(reply[i].match(/MS.+/)) {
            if(rex = reply[i].match(/MS(.+)/)) {
              denonState.value.ZONE1.mode = rex[1];
            }
          }

          else if(reply[i].match(/Z2.+/)) {
            if(rex = reply[i].match(/Z2(ON|OFF)/)) {
              denonState.value.ZONE2.power = rex[1];
            }
            else if(rex = reply[i].match(/Z2([0-9]+)/)) {
              denonState.value.ZONE2.volume = rex[1];
            }
            else if(rex = reply[i].match(/Z2(.+)/)) {
              denonState.value.ZONE2.input = rex[1];
            }
          }

          else if(reply[i].match(/Z3.+/)) {
            if(rex = reply[i].match(/Z3(ON|OFF)/)) {
              denonState.value.ZONE3.power = rex[1];
            }
            else if(rex = reply[i].match(/Z3([0-9]+)/)) {
              denonState.value.ZONE3.volume = rex[1];
            }
            else if(rex = reply[i].match(/Z3(.+)/)) {
              denonState.value.ZONE3.input = rex[1];
            }
          }

        }
/*
        else {
          callback(denon.device.deviceId, 'err');
        }
*/
        if(count === statusCommands.length) {
          callback(denon.device.deviceId, null, 'ok', denonState);
          if(response > 256) { response = ''; }
        }

        else {
          that.state(controller, config, callback, (count += 1));
        }
      };

      this.send(denon);
    },

    /**
     * Grab the latest state as soon as SwitchBoard starts up.
     */
    init : function (controller) {
      var runCommand = require(__dirname + '/../lib/runCommand');

      runCommand.runCommand(controller.config.deviceId, 'list', controller.config.deviceId);
    },

    send : function (config) {
      var net      = require('net'),
          passover = '',
          denon    = {};

      denon.deviceIp   = config.device.deviceIp;
      denon.timeout    = config.device.localTimeout     || config.config.localTimeout;
      denon.command    = this.hashTable[config.command] || '';
      denon.devicePort = config.devicePort              || 23;
      denon.callback   = config.callback                || function () {};

      if((Socket) && (denon.command) && (!Socket.destroyed)) {
        if((denon.command !== 'state') && (denon.command !== 'list')) {
          Socket.write(denon.command + "\r");
        }

        denon.callback(null, 'ok');
      }

      else if(denon.command === 'list') {
        this.state({}, denon, denon.callback);
      }

      else if(denon.command) {
        Socket = new net.Socket();
        Socket.connect(denon.devicePort, denon.deviceIp);

        Socket.once('connect', function() {
          if(denon.command) {
            Socket.write(denon.command + "\r");
          }

          denon.callback(null, 'ok');
        });

        if(denon.command === 'state') {
          Socket.setTimeout(denon.timeout, function() {
            Socket.destroy();
            denon.callback({ code : 'ETIMEDOUT' });
          });
        }

        Socket.on('data', function(dataReply) {
          response += dataReply;
          passover = response.toString().split("\r");
          denon.callback(null, passover);
        });

        Socket.once('end', function() {
          Socket = null;
        });

        Socket.once('error', function(err) {
        var deviceState    = require(__dirname + '/../lib/deviceState'),
            denonState     = deviceState.getDeviceState(config.deviceId);

          if((err.code !== 'ETIMEDOUT') || (denon.command !== 'state')) {
            denon.callback(err, denonState);
          }
        });
      }
    }
  };
}());
<commit_msg>Fix translations for Denon<commit_after>/*jslint white: true */
/*global State, module, require, console */

/**
 * Copyright (c) 2014 markewest@gmail.com
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

module.exports = (function () {
  'use strict';

  var Socket = null;

  /**
   * @author markewest@gmail.com, jfeiler87
   * @fileoverview Basic control of Denon x4000 Receiver
   * @requires net
   */
  return {
    version : 20140911,

    inputs : ['command', 'list'],

    /**
     * Whitelist of available key codes to use.
     */
    keymap : ['POWER_STATUS', 'POWERON', 'POWEROFF', 'VOL_STATUS' ,'VOLUP', 'VOLDOWN', 'MUTE_STATUS', 'MUTE', 'UNMUTE', 'INPUT_STATUS', 'INPUT_BLURAY', 'INPUT_MPLAYER', 'INPUT_CD', 'INPUT_NETWORK', 'INPUT_TV', 'INPUT_GAME', 'MENU_STATUS', 'MENU', 'MENU_UP', 'MENU_DOWN', 'MENU_LEFT', 'MENU_RIGHT', 'MENU_ENTER', 'MENU_RETURN', 'SOUND_STATUS', 'SOUND_MOVIE', 'SOUND_MCHSTEREO', 'SOUND_PURE', 'ZONE1_STATUS', 'ZONE1_ON', 'ZONE1_OFF', 'ZONE2_STATUS', 'ZONE2_ON', 'ZONE2_VOL_UP', 'ZONE2_VOL_DOWN', 'ZONE2_OFF', 'ZONE3_STATUS', 'ZONE3_ON', 'ZONE3_VOL_UP', 'ZONE3_VOL_DOWN', 'ZONE3_OFF'],

    /**
     * Map inputted commands to the values the device or API is expecting.
     */
    hashTable : { 'POWER_STATUS'    : 'PW?',
                  'POWERON'         : 'ZMON',
                  'POWEROFF'        : 'PWSTANDBY',
                  'VOL_STATUS'      : 'MV?',
                  'VOLUP'           : 'MVUP',
                  'VOLDOWN'         : 'MVDOWN',
                  'MUTE_STATUS'     : 'MU?',
                  'MUTE'            : 'MUON',
                  'UNMUTE'          : 'MUOFF',
                  'INPUT_STATUS'    : 'SI?',
                  'INPUT_BLURAY'    : 'SIBD',
                  'INPUT_MPLAYER'   : 'SIMPLAY',
                  'INPUT_CD'        : 'SICD',
                  'INPUT_NETWORK'   : 'SINET',
                  'INPUT_TV'        : 'SISAT/CBL',
                  'INPUT_GAME'      : 'SIGAME',
                  'MENU_STATUS'     : 'MNMEN?',
                  'MENU'            : 'MNMEN ON',
                  'MENU_UP'         : 'MNCUP',
                  'MENU_DOWN'       : 'MNCDN',
                  'MENU_LEFT'       : 'MNCLT',
                  'MENU_RIGHT'      : 'MNCRT',
                  'MENU_ENTER'      : 'MNENT',
                  'MENU_RETURN'     : 'MNRTN',
                  'SOUND_STATUS'    : 'MS?',
                  'SOUND_MOVIE'     : 'MSMOVIE',
                  'SOUND_MCHSTEREO' : 'MSMCH STEREO',
                  'SOUND_PURE'      : 'MSPURE DIRECT',
                  'ZONE1_STATUS'    : 'ZM?',
                  'ZONE1_ON'        : 'ZMON',
                  'ZONE1_OFF'       : 'ZMOFF',
                  'ZONE2_STATUS'    : 'Z2?',
                  'ZONE2_ON'        : 'Z2ON',
                  'ZONE2_VOL_UP'    : 'Z2UP',
                  'ZONE2_VOL_DOWN'  : 'Z3DOWN',
                  'ZONE2_OFF'       : 'Z2OFF',
                  'ZONE3_STATUS'    : 'Z3?',
                  'ZONE3_ON'        : 'Z3ON',
                  'ZONE3_VOL_UP'    : 'Z3UP',
                  'ZONE3_VOL_DOWN'  : 'Z3DOWN',
                  'ZONE3_OFF'       : 'Z3OFF'
    },

    /**
     * Prepares and calls send() to request the current state.
     */
    state : function (controller, config, callback, count) {
      var deviceState    = require(__dirname + '/../lib/deviceState'),
          encodeName     = require(__dirname + '/../lib/sharedUtil').encodeName,
          that           = this,
          denonState     = deviceState.getDeviceState(config.deviceId),
          denon          = { device : {}, config : {} },
          statusCommands = ['POWER_STATUS', 'MUTE_STATUS', 'ZONE1_STATUS', 'VOL_STATUS', 'INPUT_STATUS', 'SOUND_STATUS', 'ZONE2_STATUS', 'ZONE3_STATUS'];
          count          = count || 0;

      if(typeof denonState === 'undefined') {
        denonState = { value : { ZONE1 : {}, ZONE2 : {}, ZONE3 : {} } };
      }

      callback                  = callback || function() {};
      denon.device.deviceId     = controller.config.deviceId;
      denon.device.deviceIp     = controller.config.deviceIp;
      denon.device.localTimeout = controller.config.localTimeout || config.localTimeout;
      denon.command             = statusCommands[count];

      denon.callback = function (err, reply, response) {
        var rex = '';

        for(var i in reply) {
          if(reply[i].match(/PW.+/)) {
            if(rex = reply[i].match(/PW(ON|OFF|STANDBY)/)) {
              denonState.value.power = encodeName(rex[1]);
            }
          }

          else if(reply[i].match(/MU.+/)) {
            if(rex = reply[i].match(/MU(ON|OFF)/)) {
              denonState.value.ZONE1.mute = encodeName(rex[1]);
            }
          }

          else if(reply[i].match(/ZM.+/)) {
            if(rex = reply[i].match(/ZM(ON|OFF)/)) {
              denonState.value.ZONE1.power = encodeName(rex[1]);
            }
          }

          else if(reply[i].match(/MV.+/)) {
            if(rex = reply[i].match(/MV([0-9]+)/)) {
              denonState.value.ZONE1.volume = rex[1];
            }
            else if(rex = reply[i].match(/MVMAX.([0-9]+)/)) {
              denonState.value.ZONE1.maxvolume = rex[1];
            }
          }

          else if(reply[i].match(/SI.+/)) {
            if(rex = reply[i].match(/SI(.+)/)) {
              denonState.value.ZONE1.input = encodeName(rex[1]);
            }
          }

          else if(reply[i].match(/MS.+/)) {
            if(rex = reply[i].match(/MS(.+)/)) {
              denonState.value.ZONE1.mode = encodeName(rex[1]);
            }
          }

          else if(reply[i].match(/Z2.+/)) {
            if(rex = reply[i].match(/Z2(ON|OFF)/)) {
              denonState.value.ZONE2.power = encodeName(rex[1]);
            }
            else if(rex = reply[i].match(/Z2([0-9]+)/)) {
              denonState.value.ZONE2.volume = rex[1];
            }
            else if(rex = reply[i].match(/Z2(.+)/)) {
              denonState.value.ZONE2.input = encodeName(rex[1]);
            }
          }

          else if(reply[i].match(/Z3.+/)) {
            if(rex = reply[i].match(/Z3(ON|OFF)/)) {
              denonState.value.ZONE3.power = encodeName(rex[1]);
            }
            else if(rex = reply[i].match(/Z3([0-9]+)/)) {
              denonState.value.ZONE3.volume = encodeName(rex[1]);
            }
            else if(rex = reply[i].match(/Z3(.+)/)) {
              denonState.value.ZONE3.input = encodeName(rex[1]);
            }
          }
        }

        if(count === statusCommands.length) {
          callback(denon.device.deviceId, null, 'ok', denonState);

          if(response > 256) {
            response = '';
          }
        }

        else {
          that.state(controller, config, callback, (count += 1));
        }
      };

      this.send(denon);
    },

    /**
     * Grab the latest state as soon as SwitchBoard starts up.
     */
    init : function (controller) {
      var runCommand = require(__dirname + '/../lib/runCommand');

      runCommand.runCommand(controller.config.deviceId, 'list', controller.config.deviceId);
    },

    send : function (config) {
      var net      = require('net'),
          passover = '',
          denon    = {},
          response;

      denon.deviceIp   = config.device.deviceIp;
      denon.timeout    = config.device.localTimeout     || config.config.localTimeout;
      denon.command    = this.hashTable[config.command] || '';
      denon.devicePort = config.devicePort              || 23;
      denon.callback   = config.callback                || function () {};

      if((Socket) && (denon.command) && (!Socket.destroyed)) {
        if((denon.command !== 'state') && (denon.command !== 'list')) {
          Socket.write(denon.command + "\r");
        }

        denon.callback(null, 'ok');
      }

      else if(denon.command === 'list') {
        this.state({}, denon, denon.callback);
      }

      else if(denon.command) {
        Socket = new net.Socket();
        Socket.connect(denon.devicePort, denon.deviceIp);

        Socket.once('connect', function() {
          if(denon.command) {
            Socket.write(denon.command + "\r");
          }

          denon.callback(null, 'ok');
        });

        if(denon.command === 'state') {
          Socket.setTimeout(denon.timeout, function() {
            Socket.destroy();
            denon.callback({ code : 'ETIMEDOUT' });
          });
        }

        Socket.on('data', function(dataReply) {
          response += dataReply;
          passover = response.toString().split("\r");
          denon.callback(null, passover, response);
        });

        Socket.once('end', function() {
          Socket = null;
        });

        Socket.once('error', function(err) {
        var deviceState = require(__dirname + '/../lib/deviceState'),
            denonState  = deviceState.getDeviceState(config.deviceId);

          if((err.code !== 'ETIMEDOUT') || (denon.command !== 'state')) {
            denon.callback(err, denonState);
          }
        });
      }
    }
  };
}());
<|endoftext|>


<commit_before>module('IcMenuListComponent', {
  setup: function() {
    App.reset();
  }
});

test('focus trigger on escape key close', function() {
  click('#trigger1').then(function() {
    return keyEvent('#list1', 'keydown', 27);
  }).then(function() {
    ok(find('#list1').is(':hidden'), 'list is hidden on escape');
    ok(find('#trigger1').is(':focus'), 'trigger get focus on list close');
  });
});

test('focuses first item on open', function() {
  click('#trigger1').then(function() {
    ok(find('#list1').is(':visible'), 'list is visible');
  }).then(function() {
    assertSelected(':first', 'selects first element by default');
  });
});

test('up selects previous', function() {
  click('#trigger1').then(function() {
    // at first element
    return keyEvent('#list1', 'keydown', 40);
  }).then(function() {
    // at second/last element
    assertSelected(':last', 'selects next element with down arrow');
    return keyEvent('#list1', 'keydown', 38);
  }).then(function(){
    assertSelected(':first', 'selects previous element with up arrow');
  });
});

test('down selects next', function() {
  click('#trigger1').then(function() {
    return keyEvent('#list1', 'keydown', 40);
  }).then(function() {
    assertSelected(':last', 'selects next element with down arrow');
  });
});

test('loops to top', function() {
  click('#trigger1').then(function() {
    // at top of list by default
    return keyEvent('#list1', 'keydown', 40);
  }).then(function(){
    // at bottom of list
    return keyEvent('#list1', 'keydown', 40);
  }).then(function() {
    assertSelected(':first', 'loops to top element');
  });
});

test('loops to bottom', function() {
  click('#trigger1').then(function() {
    // at top of list by default
    return keyEvent('#list1', 'keydown', 38);
  }).then(function(){
    // at bottom of list
    assertSelected(':last', 'loops to bottom element');
  });
});

test('closes on focusOut', function() {
  click('#trigger1').then(function() {
    return click('button:last');
  }).then(function() {
    ok(find('#list1').is(':hidden'), 'list is not visible');
  }).then(function() {
    return click('button:last');
  });
});

function assertSelected(position, message) {
    var selectedId, positionId;
    selectedId = find(':focus').attr('id');
    positionId = find("#list1 .ic-menu-item" + position).attr('id')
    equal(selectedId, positionId, message);
}

//test('repositions when window resizes');
//test('respects offset-x and offset-y');
//test('collision detection');
//test('collision detection');
//test('positions when x/y change');
//test('appends to application root element');
<commit_msg>fix tests for custom elements instead of classes<commit_after>module('IcMenuListComponent', {
  setup: function() {
    App.reset();
  }
});

test('focus trigger on escape key close', function() {
  click('#trigger1').then(function() {
    return keyEvent('#list1', 'keydown', 27);
  }).then(function() {
    ok(find('#list1').is(':hidden'), 'list is hidden on escape');
    ok(find('#trigger1').is(':focus'), 'trigger get focus on list close');
  });
});

test('focuses first item on open', function() {
  click('#trigger1').then(function() {
    ok(find('#list1').is(':visible'), 'list is visible');
  }).then(function() {
    assertSelected(':first', 'selects first element by default');
  });
});

test('up selects previous', function() {
  click('#trigger1').then(function() {
    // at first element
    return keyEvent('#list1', 'keydown', 40);
  }).then(function() {
    // at second/last element
    assertSelected(':last', 'selects next element with down arrow');
    return keyEvent('#list1', 'keydown', 38);
  }).then(function(){
    assertSelected(':first', 'selects previous element with up arrow');
  });
});

test('down selects next', function() {
  click('#trigger1').then(function() {
    return keyEvent('#list1', 'keydown', 40);
  }).then(function() {
    assertSelected(':last', 'selects next element with down arrow');
  });
});

test('loops to top', function() {
  click('#trigger1').then(function() {
    // at top of list by default
    return keyEvent('#list1', 'keydown', 40);
  }).then(function(){
    // at bottom of list
    return keyEvent('#list1', 'keydown', 40);
  }).then(function() {
    assertSelected(':first', 'loops to top element');
  });
});

test('loops to bottom', function() {
  click('#trigger1').then(function() {
    // at top of list by default
    return keyEvent('#list1', 'keydown', 38);
  }).then(function(){
    // at bottom of list
    assertSelected(':last', 'loops to bottom element');
  });
});

test('closes on focusOut', function() {
  click('#trigger1').then(function() {
    return click('button:last');
  }).then(function() {
    ok(find('#list1').is(':hidden'), 'list is not visible');
  }).then(function() {
    return click('button:last');
  });
});

function assertSelected(position, message) {
  var selectedId, positionId;
  selectedId = find(':focus').attr('id');
  positionId = find("#list1 ic-menu-item" + position).attr('id')
  equal(selectedId, positionId, message);
}

//test('repositions when window resizes');
//test('respects offset-x and offset-y');
//test('collision detection');
//test('collision detection');
//test('positions when x/y change');
//test('appends to application root element');
<|endoftext|>


<commit_before>angular.module('arachne.visualizations.directives')
    .directive('con10tD3AuthorsChord', function () { // con10t-d3
        return {
            restrict: 'E',
            scope: {
                spec: '@',
                name: '@'
            },
            link: function () {
                var matrix = [
                    [11975, 5871, 8916, 2868],
                    [1951, 10048, 2060, 6171],
                    [8010, 16145, 8090, 8045],
                    [1013, 990, 940, 6907]
                ];

                var svg = d3.select("svg"),
                    width = +svg.attr("width"),
                    height = +svg.attr("height"),
                    outerRadius = Math.min(width, height) * 0.5 - 40,
                    innerRadius = outerRadius - 30;

                var formatValue = d3.formatPrefix(",.0", 1e3);

                var chord = d3.chord()
                    .padAngle(0.05)
                    .sortSubgroups(d3.descending);

                var arc = d3.arc()
                    .innerRadius(innerRadius)
                    .outerRadius(outerRadius);

                var ribbon = d3.ribbon()
                    .radius(innerRadius);

                var color = d3.scaleOrdinal()
                    .domain(d3.range(4))
                    .range(["#000000", "#FFDD89", "#957244", "#F26223"]);

                var g = svg.append("g")
                    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
                    .datum(chord(matrix));

                var group = g.append("g")
                    .attr("class", "groups")
                    .selectAll("g")
                    .data(function (chords) {
                        return chords.groups;
                    })
                    .enter().append("g");

                group.append("path")
                    .style("fill", function (d) {
                        return color(d.index);
                    })
                    .style("stroke", function (d) {
                        return d3.rgb(color(d.index)).darker();
                    })
                    .attr("d", arc);

                var groupTick = group.selectAll(".group-tick")
                    .data(function (d) {
                        return groupTicks(d, 1e3);
                    })
                    .enter().append("g")
                    .attr("class", "group-tick")
                    .attr("transform", function (d) {
                        return "rotate(" + (d.angle * 180 / Math.PI - 90) + ") translate(" + outerRadius + ",0)";
                    });

                groupTick.append("line")
                    .attr("x2", 6);

                groupTick
                    .filter(function (d) {
                        return d.value % 5e3 === 0;
                    })
                    .append("text")
                    .attr("x", 8)
                    .attr("dy", ".35em")
                    .attr("transform", function (d) {
                        return d.angle > Math.PI ? "rotate(180) translate(-16)" : null;
                    })
                    .style("text-anchor", function (d) {
                        return d.angle > Math.PI ? "end" : null;
                    })
                    .text(function (d) {
                        return formatValue(d.value);
                    });

                g.append("g")
                    .attr("class", "ribbons")
                    .selectAll("path")
                    .data(function (chords) {
                        return chords;
                    })
                    .enter().append("path")
                    .attr("d", ribbon)
                    .style("fill", function (d) {
                        return color(d.target.index);
                    })
                    .style("stroke", function (d) {
                        return d3.rgb(color(d.target.index)).darker();
                    });

                // Returns an array of tick angles and values for a given group and step.
                function groupTicks(d, step) {
                    var k = (d.endAngle - d.startAngle) / d.value;
                    return d3.range(0, d.value, step).map(function (value) {
                        return {value: value, angle: value * k + d.startAngle};
                    });
                }
            }
        }
    });
<commit_msg>#9327 - determine d3-chord data<commit_after>angular.module('arachne.visualizations.directives')
    .directive('con10tD3AuthorsChord', function () { // con10t-d3
        return {
            restrict: 'E',
            scope: {
                spec: '@',
                name: '@'
            },
            link: function () {
                var names = [
                    "Braun, Emil",
                    "Brunn, Heinrich von",
                    "Bunsen, Christian Karl Josias von",
                    "Gerhard, Eduard",
                    "Henzen, Wilhelm",
                    "Jahn, Otto",
                    "Lepsius, Carl Richard",
                    "Michaelis, Adolf",
                    "Mommsen, Theodor",
                    "Unbekannt"
                ];
                var matrix = [
                    // Autoren:
                    // Braun, Brunn, Bunsen, Gerhard, Henzen, Jahn, Lepsius, Michaelis, Mommsen, Unbekannt
                    [      0,     0,      0,     538,     31,   10,      31,         0,       0,        0], // Braun
                    [      8,     0,      0,      82,    254,    5,       0,         0,       1,        1], // Brunn
                    [    100,     2,      0,      67,     10,    0,      23,         0,       0,       21], // Bunsen
                    [    461,     2,     59,       0,    578,   14,      33,         0,       0,        6], // Gerhard
                    [     30,    52,      0,     661,      2,    5,      41,         0,       0,        6], // Henzen
                    [      0,     0,      0,       0,      0,    0,       0,         0,       0,        0], // Jahn
                    [     92,     0,      2,      48,    245,    0,       0,         0,       0,        5], // Lepsius
                    [      0,     0,      0,      62,      0,  252,       0,         0,       0,        0], // Michaelis
                    [      1,     0,      0,       0,    337,    1,       0,         0,       0,       12], // Mommsen
                    [      0,     0,      0,      21,      0,   12,       0,         0,       0,        0]  // Unbekannt
                ];

                var svg = d3.select("svg"),
                    width = +svg.attr("width"),
                    height = +svg.attr("height"),
                    outerRadius = Math.min(width, height) * 0.5 - 40,
                    innerRadius = outerRadius - 30;

                var formatValue = d3.formatPrefix(",.0", 1e3);

                var chord = d3.chord()
                    .padAngle(0.05)
                    .sortSubgroups(d3.descending);

                var arc = d3.arc()
                    .innerRadius(innerRadius)
                    .outerRadius(outerRadius);

                var ribbon = d3.ribbon()
                    .radius(innerRadius);

                var color = d3.scaleOrdinal()
                    .domain(d3.range(4))
                    .range([
                        "#cd3d08", "#ec8f00", "#6dae29", "#683f92", "#b60275",
                        "#2058a5", "#00a592", "#009d3c", "#378974", "#ffca00"
                    ]);

                var g = svg.append("g")
                    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
                    .datum(chord(matrix));

                var group = g.append("g")
                    .attr("class", "groups")
                    .selectAll("g")
                    .data(function (chords) {
                        return chords.groups;
                    })
                    .enter().append("g");

                group.append("path")
                    .style("fill", function (d) {
                        return color(d.index);
                    })
                    .style("stroke", function (d) {
                        return d3.rgb(color(d.index)).darker();
                    })
                    .attr("d", arc);

                var groupTick = group.selectAll(".group-tick")
                    .data(function (d) {
                        return groupTicks(d, 1e3);
                    })
                    .enter().append("g")
                    .attr("class", "group-tick")
                    .attr("transform", function (d) {
                        return "rotate(" + (d.angle * 180 / Math.PI - 90) + ") translate(" + outerRadius + ",0)";
                    });

                groupTick.append("line")
                    .attr("x2", 6);

                groupTick
                    .filter(function (d) {
                        return d.value % 5e3 === 0;
                    })
                    .append("text")
                    .attr("x", 8)
                    .attr("dy", ".35em")
                    .attr("transform", function (d) {
                        return d.angle > Math.PI ? "rotate(180) translate(-16)" : null;
                    })
                    .style("text-anchor", function (d) {
                        return d.angle > Math.PI ? "end" : null;
                    })
                    .text(function (d) {
                        return formatValue(d.value);
                    });

                g.append("g")
                    .attr("class", "ribbons")
                    .selectAll("path")
                    .data(function (chords) {
                        return chords;
                    })
                    .enter().append("path")
                    .attr("d", ribbon)
                    .style("fill", function (d) {
                        return color(d.target.index);
                    })
                    .style("stroke", function (d) {
                        return d3.rgb(color(d.target.index)).darker();
                    });

                // Returns an array of tick angles and values for a given group and step.
                function groupTicks(d, step) {
                    var k = (d.endAngle - d.startAngle) / d.value;
                    return d3.range(0, d.value, step).map(function (value) {
                        return {value: value, angle: value * k + d.startAngle};
                    });
                }
            }
        }
    });
<|endoftext|>


<commit_before>'use strict';

const _ = require('lodash');

module.exports = {
  where(json, table) {
    const entries = _.entries(json);

    return entries.map(([key, value], i) => {
      key = _.snakeCase(key);

      if (table) key = `${table}.${key}`;

      if (value === null) {
        return `${key} IS NULL`;
      }

      return `${key} = $${i + 1}`;
    }).join(' AND ');
  },
};
<commit_msg>columns & values sql helpers<commit_after>'use strict';

const _ = require('lodash');

module.exports = {
  columns(array, table) {
    return array.map((column) => {
      const snakeCase = _.snakeCase(column);

      let str = '';

      if (snakeCase !== column) {
        str += `${_.snakeCase(column)} as "${column}"`;
      } else {
        str += column;
      }

      if (table) {
        str = `${table}.${str}`;
      }

      return str;
    }).join(', ');
  },

  where(json, table) {
    const entries = _.entries(json);

    return entries.map(([key, value], i) => {
      key = _.snakeCase(key);

      if (table) key = `${table}.${key}`;

      if (value === null) {
        return `${key} IS NULL`;
      }

      return `${key} = $${i + 1}`;
    }).join(' AND ');
  },

  values(json) {
    return _.values(_.omitBy(json, _.isNil));
  },
};
<|endoftext|>


<commit_before>

<meta charset="UTF-8">

<commit_msg>Fixed min width<commit_after>

<meta charset="UTF-8">

<|endoftext|>