<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/13/ports/em0", 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>Inserted new upstream port<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(){
	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);
	}
}
<|endoftext|>


<commit_before>var net = require('net');
var socks = require('socksv5');
var http = require('http');
var https = require('https');
var parseUrl = require('url').parse;
var path = require('path');
var fs = require('fs');

var proxyServerPort = exports.proxyServerPort = 1090;
var socksServerPort = exports.socksServerPort = 1080;
var httpServerPort = exports.httpServerPort = 1070;
var httpsServerPort = exports.httpsServerPort = 1060;
var socketServerPort = exports.socketServerPort = 1050;
var options = {
  key: fs.readFileSync(path.join(__dirname, 'assets/certs/root.key')),
  cert: fs.readFileSync(path.join(__dirname, 'assets/certs/root.crt'))
};

exports.startProxyServer = function() {
  var server = http.createServer(function(req, res) {
    var fullUrl = /^http:/.test(req.url) ? req.url : 'http://' + req.headers.host + req.url;
    var options = parseUrl(fullUrl);
    delete options.hostname;
    options.host = '127.0.0.1';
    options.port = httpServerPort;
    options.method = req.method;
    options.headers = req.headers;
    var client = http.request(options, function(_res) {
      _res.pipe(res);
    });
    req.pipe(client);
  });

  server.on('connect', function(req, socket) {
    var options = parseUrl('https://' + req.url);
    var client = net.connect({
      host: '127.0.0.1',
      port: options.port || httpsServerPort
    }, function() {
      socket.pipe(client).pipe(socket);
      socket.write('HTTP/1.1 200 Connection Established\r\nProxy-Agent: whistle/test\r\n\r\n');
    });
  });

  return new Promise(function(resolve) {
    server.listen(proxyServerPort, resolve);
  });
};

exports.startSocksServer = function() {
  var socksServer = socks.createServer(function(info, accept, deny) {
    var socket, client;
    if (info.dstPort === 443) {
      if (socket = accept(true)) {
        client = net.connect({
          host: '127.0.0.1',
          port: httpsServerPort
        }, function() {
          socket.pipe(client).pipe(socket);
        });
      }
      return;
    }
    if (info.dstPort === 80) {
      if (socket = accept(true)) {
        client = net.connect({
          host: '127.0.0.1',
          port: httpServerPort
        }, function() {
          socket.pipe(client).pipe(socket);
        });
      }
      return;
    }
    if (socket = accept(true)) {
      client = net.connect({
        host: '127.0.0.1',
        port: info.dstPort
      }, function() {
        socket.pipe(client).pipe(socket);
      });
    }
  });
  socksServer.useAuth(socks.auth.None());
  return new Promise(function(resolve) {
    socksServer.listen(socksServerPort, resolve);
  });
};

exports.startHttpServer = function() {

  return Promise.all([
    new Promise(function(resolve) {
      https.createServer(options, function(req, res) {
        res.end('HTTPS');
      }).listen(httpsServerPort, resolve);
    }),
    new Promise(function(resolve) {
      var server = http.createServer(function(req, res) {
        res.end('HTTP');
      });
      server.listen(httpServerPort, resolve);
    }),
  ]);
};

exports.startSocketServer = function() {

  return new Promise(function(resolve) {
    var server = net.createServer();
    server.on('connection', function(socket) {
      socket.write('socket');
      socket.on('data', function(data) {
        console.log(data + '==========')
      })
    });
    server.listen(socketServerPort, resolve);
  });
};

<commit_msg>test: Refine code<commit_after>var net = require('net');
var socks = require('socksv5');
var http = require('http');
var https = require('https');
var parseUrl = require('url').parse;
var path = require('path');
var fs = require('fs');

var proxyServerPort = exports.proxyServerPort = 1090;
var socksServerPort = exports.socksServerPort = 1080;
var httpServerPort = exports.httpServerPort = 1070;
var httpsServerPort = exports.httpsServerPort = 1060;
var socketServerPort = exports.socketServerPort = 1050;
var options = {
  key: fs.readFileSync(path.join(__dirname, 'assets/certs/root.key')),
  cert: fs.readFileSync(path.join(__dirname, 'assets/certs/root.crt'))
};

exports.startProxyServer = function() {
  var server = http.createServer(function(req, res) {
    var fullUrl = /^http:/.test(req.url) ? req.url : 'http://' + req.headers.host + req.url;
    var options = parseUrl(fullUrl);
    delete options.hostname;
    options.host = '127.0.0.1';
    options.port = httpServerPort;
    options.method = req.method;
    options.headers = req.headers;
    var client = http.request(options, function(_res) {
      _res.pipe(res);
    });
    req.pipe(client);
  });

  server.on('connect', function(req, socket) {
    var options = parseUrl('https://' + req.url);
    var client = net.connect({
      host: '127.0.0.1',
      port: options.port || httpsServerPort
    }, function() {
      socket.pipe(client).pipe(socket);
      socket.write('HTTP/1.1 200 Connection Established\r\nProxy-Agent: whistle/test\r\n\r\n');
    });
  });

  return new Promise(function(resolve) {
    server.listen(proxyServerPort, resolve);
  });
};

exports.startSocksServer = function() {
  var socksServer = socks.createServer(function(info, accept, deny) {
    var socket, client;
    if (info.dstPort === 443) {
      if (socket = accept(true)) {
        client = net.connect({
          host: '127.0.0.1',
          port: httpsServerPort
        }, function() {
          socket.pipe(client).pipe(socket);
        });
      }
      return;
    }
    if (info.dstPort === 80) {
      if (socket = accept(true)) {
        client = net.connect({
          host: '127.0.0.1',
          port: httpServerPort
        }, function() {
          socket.pipe(client).pipe(socket);
        });
      }
      return;
    }
    if (socket = accept(true)) {
      client = net.connect({
        host: '127.0.0.1',
        port: info.dstPort
      }, function() {
        socket.pipe(client).pipe(socket);
      });
    }
  });
  socksServer.useAuth(socks.auth.None());
  return new Promise(function(resolve) {
    socksServer.listen(socksServerPort, resolve);
  });
};

exports.startHttpServer = function() {

  return Promise.all([
    new Promise(function(resolve) {
      https.createServer(options, function(req, res) {
        res.end('HTTPS');
      }).listen(httpsServerPort, resolve);
    }),
    new Promise(function(resolve) {
      var server = http.createServer(function(req, res) {
        res.end('HTTP');
      });
      server.listen(httpServerPort, resolve);
    }),
  ]);
};

exports.startSocketServer = function() {

  return new Promise(function(resolve) {
    var server = net.createServer();
    server.on('connection', function(socket) {
      socket.write('socket');
    });
    server.listen(socketServerPort, resolve);
  });
};

<|endoftext|>


<commit_before>(function(root) {
    var get   = typeof require == 'function' && require('request')
    var hyve  = typeof exports != 'undefined'?  exports : root.hyve = { }

    // ECMA-262 compatible Array#forEach polyfills
    Array.prototype.forEach = Array.prototype.forEach
    || function(fn, ctx) {
           var len = this.length >>> 0
           for (var i = 0; i < len; ++i)
               if (i in this) fn.call(ctx, this[i], i, this)
       }

    // Fills a template with data from an object
    function format(string, data) {
        return string.replace( /{{(?:#(.+?)#)?\s*(.+?)\s*}}/g
                             , function(m, cond, id) {
                                 var rv = data[id]
                                 return rv? (cond || '') + rv
                                          :  cond? m : '' })
    }

    // Pulls data from several streams and handle all them with the given
    // callback
    function stream(query, callback, custom_services) {
        var services
        services = custom_services || Object.keys(hyve.feeds)
        services.forEach(function(service){
            if ( hyve.feeds[service.toLowerCase()].orig_url == undefined ){
                hyve.feeds[service.toLowerCase()].orig_url = hyve.feeds[service.toLowerCase()].feed_url
            }
            var options = hyve.feeds[service.toLowerCase()]
            var feed_url = format( options.feed_url,
                                     { query:  query
                                     , apikey: options.api_key })
                fetch(feed_url, service, callback)
            hyve.feeds[service.toLowerCase()].lock = setInterval(function(){
                var feed_url = format( options.feed_url,
                                     { query:  query
                                     , apikey: options.api_key })
                fetch(feed_url, service, callback)
            }, options.interval)
        })
    }

    function stop(custom_services) {
        var services
        services = custom_services || Object.keys(hyve.feeds)
        services.forEach(function(service){
            if (hyve.feeds[service.toLowerCase()].lock != null) {
                console.log(hyve.feeds[service.toLowerCase()].feed_url)
                hyve.feeds[service.toLowerCase()].feed_url = hyve.feeds[service.toLowerCase()].orig_url
                interval_id =  hyve.feeds[service.toLowerCase()].lock
                clearInterval(interval_id)
                console.log('intervals cleared for ' + service)
                console.log(hyve.feeds[service.toLowerCase()].feed_url)
            }
        })
    }
    // Fetches a JSON stream
    var fetch = function() {
        var counter   = 0
        var callbacks = { }
        var head      = !get && document.getElementsByTagName('head')[0]

        // Returns a qualified identifier pointing to a callback
        function get_callback() {
            return format('hyve.callbacks.f{{id}}', { id: ++counter })
        }

        // Requires an URI using JSONP
        function jsonp(url, callback) {
            hyve.callbacks['f' + counter] = callback
            var s = document.createElement('script')
            s.setAttribute('src', url)
            head.appendChild(s)
        }

        // Requires an URI using Node.js's request library
        function request(url, callback) {
            get({uri: url}, function(error, res, data) {
                try {
                    callback(JSON.parse(data))
                }
                catch(e){
                    callback({ }, e)
                }
            })
        }

        // Abstracts fetching URIs.
        function fetch(url, service, callback) {
            var fn = pass(service, callback)
            var cb = !get && get_callback()
            url    = format(url, { callback: cb })

            var fetcher = get? request : jsonp
            fetcher(url, fn)
        }

        // Higher-order function to process the fetched data
        function pass(service, callback) {
            return function(data) {
                hyve.feeds[service].parse(data, callback)
            }
        }

        // Export the `fetch` function
        return fetch
    }()

    // Exports data to the outside world
    hyve.stream    = stream
    hyve.stop      = stop
    hyve.callbacks = []
    hyve.feeds     = {
            twitter: {
                interval : 2000,
                feed_url :'http://search.twitter.com/search.json?lang=en&q={{query}}{{#&callback=#callback}}',
                parse : function(data,callback){
                    if (data.refresh_url != null){
                        this.feed_url = 'http://search.twitter.com/search.json'
                                      + data.refresh_url
                                      + '{{#&callback=#callback}}'
                    }
                    if (data.results != null){
                        data.results.forEach(function(item){
                            callback({
                                'service' : 'twitter',
                                'user' : {
                                    'id' : item.from_user_id_str,
                                    'name' : item.from_user,
                                    'avatar' : item.profile_image_url
                                },
                                'id' : item.id_str,
                                'date' : item.created_at, //TODO: normalize
                                'text' : item.text,
                                'source' : item.source
                            })
                        })
                    }
                }
            },
            identica: {
                interval : 6000,
                feed_url :'http://identi.ca/api/search.json?lang=en&q={{query}}{{#&callback=#callback}}',
                parse : function(data,callback){
                    if (data.refresh_url != null){
                        this.feed_url = 'http://identi.ca/api/search.json' + data.refresh_url+ '{{#&callback=#callback}}'
                    }
                    data.results.forEach(function(item){
                        callback({
                            'service' : 'identica',
                            'user' : {
                                'id' : item.from_user_id_str,
                                'name' : item.from_user,
                                'avatar' : item.profile_image_url
                            },
                            'id' : item.id_str,
                            'date' : item.created_at, //TODO: normalize
                            'text' : item.text,
                            'source' : item.source
                        })
                    })
                }
            },
            buzz: {
                interval : 5000,
                api_key: '',
                feed_url :'https://www.googleapis.com/buzz/v1/activities/search?q={{query}}&alt=json&orderby=published{{#&callback=#callback}}{{#&key=#apikey}}',
                parse : function(data,callback){
                    if (this.orig_url == null){
                        this.orig_url = this.feed_url
                    }
                    if (data.data != null){
                        var last_date = data.data.items[0].updated.split('.')[0]
                        this.feed_url = this.orig_url.replace('{{query}}','{{query}}%20AND%20date%3E' + last_date)
                        data.data.items.forEach(function(item){
                            if (item.title != '-'){
                                callback({
                                    'service' : 'buzz',
                                    'user' : {
                                        'id' : item.actor.name,
                                        'name' : item.actor.name,
                                        'avatar' : item.actor.thumbnailUrl,
                                        'source' : item.actor.profileUrl
                                    },
                                    'id' : item.id.split(':')[3],
                                    'date' : item.published, //TODO normalize
                                    'text' : item.title,
                                    'source' : item.object.links.alternate[0].href
                                })
                            }
                        })
                    }
                }
            },
            facebook: {
                interval : 3000,
                feed_url : 'https://graph.facebook.com/search?q={{query}}&type=post{{#&callback=#callback}}',
                parse : function(data,callback){
                    if (data.data != null){
                        if (data.paging != null) {
                            this.feed_url = data.paging.previous + '{{#&callback=#callback}}'
                        }
                        data.data.forEach(function(item){
                            if (item.message != null){
                                callback({
                                    'service' : 'facebook',
                                    'user' : {
                                        'id' : item.from.id,
                                        'name' : item.from.name,
                                        'avatar' : 'http://graph.facebook.com/'+item.from.id+'/picture'
                                    },
                                    'id' : item.id,
                                    'date' : item.created_time, //TODO: normalize
                                    'text' : item.message,
                                    'source' : 'http://facebook.com/'+item.from.id
                                })
                            }
                        })
                    }
                }
            },
            reddit: {
                interval : 5000,
                feed_url : 'http://www.reddit.com/search.json?q={{query}}&sort=new{{#&jsonp=#callback}}',
                parse : function(data,callback){
                    if (data.data.children[0]){
                        if (this.orig_url == null){
                            this.orig_url = this.feed_url
                        }
                        var before = data.data.children[0].data.name
                        if (before != null){
                            this.feed_url = this.orig_url + '&before=' + before
                        }
                        data.data.children.forEach(function(item){
                            item = item.data
                            callback({
                                'service' : 'reddit',
                                'user' : {
                                    'id' : '',
                                    'name' : '',
                                    'avatar' : ''
                                },
                                'id' : item.id,
                                'date' : item.created_utc, //TODO: normalize
                                'text' : item.title,
                                'source' : item.url,
                                'thumbnail':'http://reddit.com' + item.thumbnail
                            })
                        })
                    }
                }
            },
            flickr: {
                interval : 10000,
                api_key : '',
                feed_url : 'http://api.flickr.com/services/feeds/photos_public.gne?format=json&tagmode=all&tags={{query}}{{#&jsoncallback=#callback}}&extras=date_upload,date_taken,owner_name,geo,tags,views',
                parse : function(data,callback){
                    if (this.items_seen == null){
                        this.items_seen = {};
                    }
                    data.items && data.items.forEach(function(item){
                        if (this.items_seen[item.media.m] == null){
                            this.items_seen[item.media.m] = true
                            callback({
                                'service' : 'flickr',
                                'user' : {
                                    'id' : item.author_id,
                                    'name' : item.author,
                                    'avatar' : ''
                                },
                                'id' : '',
                                'date' : item.published, //TODO: normalize
                                'text' : item.title,
                                'source' : item.link,
                                'thumbnail':item.media.m
                            })
                        }
                    }, this)
                }
            },
            youtube: {
                interval : 8000,
                feed_url : 'http://gdata.youtube.com/feeds/api/videos?q={{query}}&time=today&orderby=published&format=5&max-results=20&v=2&alt=jsonc{{#&callback=#callback}}',
                parse : function(data,callback){
                    if (this.items_seen == null){
                        this.items_seen = {};
                    }
                    if (data.data != null){
                        data.data.items.forEach(function(item){
                            if (this.items_seen[item.id] == null){
                                this.items_seen[item.id] = true
                                callback({
                                    'service' : 'youtube',
                                    'user' : {
                                        'id' : item.uploader,
                                        'name' : item.uploader,
                                        'profile' : 'http://youtube.com/' + item.uploader,
                                        'avatar' : ''
                                    },
                                    'id' : item.id,
                                    'date' : '', //TODO: normalize
                                    'text' : item.title,
                                    'source' : 'http://youtu.be/'+ item.id,
                                    'thumbnail':'http://i.ytimg.com/vi/' + item.id + '/hqdefault.jpg'
                                })
                            }
                        }, this)
                    }
                }
            },
            wordpress: {
                interval : 10000,
                feed_url : 'http://pipes.yahoo.com/pipes/pipe.run?_id=332d9216d8910ba39e6c2577fd321a6a&_render=json&u=http%3A%2F%2Fen.search.wordpress.com%2F%3Fq%3D{{query}}%26s%3Ddate%26f%3Djson{{#&_callback=#callback}}',
                parse : function(data,callback){
                    if (this.items_seen == null){
                        this.items_seen = {};
                    }
                    if (data != null){
                        data.value.items.forEach(function(item){
                            if (this.items_seen[item.guid] == null){
                                this.items_seen[item.guid] = true
                                callback({
                                    'service' : 'wordpress',
                                    'user' : {
                                        'id' : item.author,
                                        'name' : item.author,
                                        'profile' :'',
                                        'avatar' : ''
                                    },
                                    'id' : item.id,
                                    'date' : '', //TODO: normalize
                                    'text' : item.title,
                                    'description':item.content,
                                    'source' : item.guid,
                                })
                            }
                        }, this)
                    }
                }
            }
        }
})(this);

/*
$.getJSON('http://pipes.yahoo.com/pipes/pipe.run?_id=332d9216d8910ba39e6c2577fd321a6a&_render=json&u=http%3A%2F%2Fen.search.wordpress.com%2F%3Fq%3D' + query + '%26f%3Djson&_callback=?', function(data){                                  $('
Wordpress

').appendTo($('body')).show('slow')
    $.each(data.value.items, function(i,item) {
        $('
'+ item.author + ' : ' + item.title + '
').hide().appendTo($('body')).show('slow')
    });
});
});*/
<commit_msg>Add picasa support<commit_after>(function(root) {
    var get   = typeof require == 'function' && require('request')
    var hyve  = typeof exports != 'undefined'?  exports : root.hyve = { }

    // ECMA-262 compatible Array#forEach polyfills
    Array.prototype.forEach = Array.prototype.forEach
    || function(fn, ctx) {
           var len = this.length >>> 0
           for (var i = 0; i < len; ++i)
               if (i in this) fn.call(ctx, this[i], i, this)
       }

    // Fills a template with data from an object
    function format(string, data) {
        return string.replace( /{{(?:#(.+?)#)?\s*(.+?)\s*}}/g
                             , function(m, cond, id) {
                                 var rv = data[id]
                                 return rv? (cond || '') + rv
                                          :  cond? m : '' })
    }

    // Pulls data from several streams and handle all them with the given
    // callback
    function stream(query, callback, custom_services) {
        var services
        services = custom_services || Object.keys(hyve.feeds)
        services.forEach(function(service){
            if ( hyve.feeds[service.toLowerCase()].orig_url == undefined ){
                hyve.feeds[service.toLowerCase()].orig_url = hyve.feeds[service.toLowerCase()].feed_url
            }
            var options = hyve.feeds[service.toLowerCase()]
            var feed_url = format( options.feed_url,
                                     { query:  query
                                     , apikey: options.api_key })
                fetch(feed_url, service, callback)
            hyve.feeds[service.toLowerCase()].lock = setInterval(function(){
                var feed_url = format( options.feed_url,
                                     { query:  query
                                     , apikey: options.api_key })
                fetch(feed_url, service, callback)
            }, options.interval)
        })
    }

    function stop(custom_services) {
        var services
        services = custom_services || Object.keys(hyve.feeds)
        services.forEach(function(service){
            if (hyve.feeds[service.toLowerCase()].lock != null) {
                console.log(hyve.feeds[service.toLowerCase()].feed_url)
                hyve.feeds[service.toLowerCase()].feed_url = hyve.feeds[service.toLowerCase()].orig_url
                interval_id =  hyve.feeds[service.toLowerCase()].lock
                clearInterval(interval_id)
                console.log('intervals cleared for ' + service)
                console.log(hyve.feeds[service.toLowerCase()].feed_url)
            }
        })
    }
    // Fetches a JSON stream
    var fetch = function() {
        var counter   = 0
        var callbacks = { }
        var head      = !get && document.getElementsByTagName('head')[0]

        // Returns a qualified identifier pointing to a callback
        function get_callback() {
            return format('hyve.callbacks.f{{id}}', { id: ++counter })
        }

        // Requires an URI using JSONP
        function jsonp(url, callback) {
            hyve.callbacks['f' + counter] = callback
            var s = document.createElement('script')
            s.setAttribute('src', url)
            head.appendChild(s)
        }

        // Requires an URI using Node.js's request library
        function request(url, callback) {
            get({uri: url}, function(error, res, data) {
                try {
                    callback(JSON.parse(data))
                }
                catch(e){
                    callback({ }, e)
                }
            })
        }

        // Abstracts fetching URIs.
        function fetch(url, service, callback) {
            var fn = pass(service, callback)
            var cb = !get && get_callback()
            url    = format(url, { callback: cb })

            var fetcher = get? request : jsonp
            fetcher(url, fn)
        }

        // Higher-order function to process the fetched data
        function pass(service, callback) {
            return function(data) {
                hyve.feeds[service].parse(data, callback)
            }
        }

        // Export the `fetch` function
        return fetch
    }()

    // Exports data to the outside world
    hyve.stream    = stream
    hyve.stop      = stop
    hyve.callbacks = []
    hyve.feeds     = {
            twitter: {
                interval : 2000,
                feed_url :'http://search.twitter.com/search.json?lang=en&q={{query}}{{#&callback=#callback}}',
                parse : function(data,callback){
                    if (data.refresh_url != null){
                        this.feed_url = 'http://search.twitter.com/search.json'
                                      + data.refresh_url
                                      + '{{#&callback=#callback}}'
                    }
                    if (data.results != null){
                        data.results.forEach(function(item){
                            callback({
                                'service' : 'twitter',
                                'user' : {
                                    'id' : item.from_user_id_str,
                                    'name' : item.from_user,
                                    'avatar' : item.profile_image_url
                                },
                                'id' : item.id_str,
                                'date' : item.created_at, //TODO: normalize
                                'text' : item.text,
                                'source' : item.source
                            })
                        })
                    }
                }
            },
            identica: {
                interval : 6000,
                feed_url :'http://identi.ca/api/search.json?lang=en&q={{query}}{{#&callback=#callback}}',
                parse : function(data,callback){
                    if (data.refresh_url != null){
                        this.feed_url = 'http://identi.ca/api/search.json' + data.refresh_url+ '{{#&callback=#callback}}'
                    }
                    data.results.forEach(function(item){
                        callback({
                            'service' : 'identica',
                            'user' : {
                                'id' : item.from_user_id_str,
                                'name' : item.from_user,
                                'avatar' : item.profile_image_url
                            },
                            'id' : item.id_str,
                            'date' : item.created_at, //TODO: normalize
                            'text' : item.text,
                            'source' : item.source
                        })
                    })
                }
            },
            buzz: {
                interval : 5000,
                api_key: '',
                feed_url :'https://www.googleapis.com/buzz/v1/activities/search?q={{query}}&alt=json&orderby=published{{#&callback=#callback}}{{#&key=#apikey}}',
                parse : function(data,callback){
                    if (this.orig_url == null){
                        this.orig_url = this.feed_url
                    }
                    if (data.data != null){
                        var last_date = data.data.items[0].updated.split('.')[0]
                        this.feed_url = this.orig_url.replace('{{query}}','{{query}}%20AND%20date%3E' + last_date)
                        data.data.items.forEach(function(item){
                            if (item.title != '-'){
                                callback({
                                    'service' : 'buzz',
                                    'user' : {
                                        'id' : item.actor.name,
                                        'name' : item.actor.name,
                                        'avatar' : item.actor.thumbnailUrl,
                                        'source' : item.actor.profileUrl
                                    },
                                    'id' : item.id.split(':')[3],
                                    'date' : item.published, //TODO normalize
                                    'text' : item.title,
                                    'source' : item.object.links.alternate[0].href
                                })
                            }
                        })
                    }
                }
            },
            facebook: {
                interval : 3000,
                feed_url : 'https://graph.facebook.com/search?q={{query}}&type=post{{#&callback=#callback}}',
                parse : function(data,callback){
                    if (data.data != null){
                        if (data.paging != null) {
                            this.feed_url = data.paging.previous + '{{#&callback=#callback}}'
                        }
                        data.data.forEach(function(item){
                            if (item.message != null){
                                callback({
                                    'service' : 'facebook',
                                    'user' : {
                                        'id' : item.from.id,
                                        'name' : item.from.name,
                                        'avatar' : 'http://graph.facebook.com/'+item.from.id+'/picture'
                                    },
                                    'id' : item.id,
                                    'date' : item.created_time, //TODO: normalize
                                    'text' : item.message,
                                    'source' : 'http://facebook.com/'+item.from.id
                                })
                            }
                        })
                    }
                }
            },
            reddit: {
                interval : 5000,
                feed_url : 'http://www.reddit.com/search.json?q={{query}}&sort=new{{#&jsonp=#callback}}',
                parse : function(data,callback){
                    if (data.data.children[0]){
                        if (this.orig_url == null){
                            this.orig_url = this.feed_url
                        }
                        var before = data.data.children[0].data.name
                        if (before != null){
                            this.feed_url = this.orig_url + '&before=' + before
                        }
                        data.data.children.forEach(function(item){
                            item = item.data
                            callback({
                                'service' : 'reddit',
                                'user' : {
                                    'id' : '',
                                    'name' : '',
                                    'avatar' : ''
                                },
                                'id' : item.id,
                                'date' : item.created_utc, //TODO: normalize
                                'text' : item.title,
                                'source' : item.url,
                                'thumbnail':'http://reddit.com' + item.thumbnail
                            })
                        })
                    }
                }
            },
            picasa: {
                interval : 15000,
                feed_url : 'https://picasaweb.google.com/data/feed/api/all?q={{query}}&max-results=20&kind=photo&alt=json{{#&callback=#callback}}',
                parse : function(data,callback){
                    if (data.feed.entry){
                        data.feed.entry.forEach(function(item){
                             if (this.items_seen == null){
                                this.items_seen = {};
                            }
                            if (this.items_seen[item.id.$t] == null){
                                this.items_seen[item.id.$t] = true
                                callback({
                                    'service' : 'picasa',
                                    'user' : {
                                        'id' : item.author[0].gphoto$user.$t,
                                        'name' : item.author[0].name.$t,
                                        'avatar' : item.author[0].gphoto$thumbnail.$t
                                    },
                                    'id' : item.id.$t,
                                    'date' : item.published.$t, //TODO: normalize
                                    'text' : item.title.$t,
                                    'source' : item.content.src,
                                    'thumbnail':item.media$group.media$thumbnail[1].url
                                })
                            }
                            if (this.orig_url == null){
                                this.orig_url = this.feed_url
                            }
                            var datetime = item.published.$t.split('.')[0]
                            var epoch = Date.parse(datetime)
                            if (this.newest_epoch == null){
                                this.newest_epoch = epoch
                                this.newest_date = datetime
                            } else if (this.epoch > this.newest_epoch){
                                newest_epoch = epoch
                                this.newest_date = datetime
                            }
                        })
                        this.feed_url = this.orig_url.replace('{{query}}','{{query}}&published-min=' + newest_date)
                        console.log(this.feed_url)
                    }
                }
            },
            flickr: {
                interval : 10000,
                api_key : '',
                feed_url : 'http://api.flickr.com/services/feeds/photos_public.gne?format=json&tagmode=all&tags={{query}}{{#&jsoncallback=#callback}}&extras=date_upload,date_taken,owner_name,geo,tags,views',
                parse : function(data,callback){
                    if (this.items_seen == null){
                        this.items_seen = {};
                    }
                    data.items && data.items.forEach(function(item){
                        if (this.items_seen[item.media.m] == null){
                            this.items_seen[item.media.m] = true
                            callback({
                                'service' : 'flickr',
                                'user' : {
                                    'id' : item.author_id,
                                    'name' : item.author,
                                    'avatar' : ''
                                },
                                'id' : '',
                                'date' : item.published, //TODO: normalize
                                'text' : item.title,
                                'source' : item.link,
                                'thumbnail':item.media.m
                            })
                        }
                    }, this)
                }
            },
            youtube: {
                interval : 8000,
                feed_url : 'http://gdata.youtube.com/feeds/api/videos?q={{query}}&time=today&orderby=published&format=5&max-results=20&v=2&alt=jsonc{{#&callback=#callback}}',
                parse : function(data,callback){
                    if (this.items_seen == null){
                        this.items_seen = {};
                    }
                    if (data.data != null){
                        data.data.items.forEach(function(item){
                            if (this.items_seen[item.id] == null){
                                this.items_seen[item.id] = true
                                callback({
                                    'service' : 'youtube',
                                    'user' : {
                                        'id' : item.uploader,
                                        'name' : item.uploader,
                                        'profile' : 'http://youtube.com/' + item.uploader,
                                        'avatar' : ''
                                    },
                                    'id' : item.id,
                                    'date' : '', //TODO: normalize
                                    'text' : item.title,
                                    'source' : 'http://youtu.be/'+ item.id,
                                    'thumbnail':'http://i.ytimg.com/vi/' + item.id + '/hqdefault.jpg'
                                })
                            }
                        }, this)
                    }
                }
            },
            wordpress: {
                interval : 10000,
                feed_url : 'http://pipes.yahoo.com/pipes/pipe.run?_id=332d9216d8910ba39e6c2577fd321a6a&_render=json&u=http%3A%2F%2Fen.search.wordpress.com%2F%3Fq%3D{{query}}%26s%3Ddate%26f%3Djson{{#&_callback=#callback}}',
                parse : function(data,callback){
                    if (this.items_seen == null){
                        this.items_seen = {};
                    }
                    if (data != null){
                        data.value.items.forEach(function(item){
                            if (this.items_seen[item.guid] == null){
                                this.items_seen[item.guid] = true
                                callback({
                                    'service' : 'wordpress',
                                    'user' : {
                                        'id' : item.author,
                                        'name' : item.author,
                                        'profile' :'',
                                        'avatar' : ''
                                    },
                                    'id' : item.id,
                                    'date' : '', //TODO: normalize
                                    'text' : item.title,
                                    'description':item.content,
                                    'source' : item.guid,
                                })
                            }
                        }, this)
                    }
                }
            }
        }
})(this);

/*
$.getJSON('http://pipes.yahoo.com/pipes/pipe.run?_id=332d9216d8910ba39e6c2577fd321a6a&_render=json&u=http%3A%2F%2Fen.search.wordpress.com%2F%3Fq%3D' + query + '%26f%3Djson&_callback=?', function(data){                                  $('
Wordpress

').appendTo($('body')).show('slow')
    $.each(data.value.items, function(i,item) {
        $('
'+ item.author + ' : ' + item.title + '
').hide().appendTo($('body')).show('slow')
    });
});
});*/
<|endoftext|>


<commit_before>// System.js plugin
function normalizeLocaleId(localeId) {
    return localeId && localeId.replace(/-/g, '_').toLowerCase();
}

// Helper for getting a prioritized, normalized list of relevant locale ids from a specific locale id.
// For instance, 'en_US' produces ['en_us', 'en']
function expandLocaleIdToPrioritizedList(localeId) {
    if (!localeId) {
        return [];
    }
    localeId = normalizeLocaleId(localeId);
    var localeIds = [ localeId ];
    while (/_[^_]+$/.test(localeId)) {
        localeId = localeId.replace(/_[^_]+$/, '');
        localeIds.push(localeId);
    }
    return localeIds;
}

function tokenizePattern(pattern) {
    if (typeof pattern !== 'string') {
        var valueString = pattern;
        try {
            valueString = JSON.stringify(pattern);
        } catch (e) {}
        throw new Error('i18nTools.tokenizePattern: Value must be a string: ' + valueString);
    }
    var tokens = [],
        fragments = pattern.split(/(\{\d+\})/);
    for (var i = 0 ; i < fragments.length ; i += 1) {
        var fragment = fragments[i];
        if (fragment.length > 0) {
            var matchPlaceHolder = fragment.match(/^\{(\d+)\}$/);
            if (matchPlaceHolder) {
                tokens.push({
                    type: 'placeHolder',
                    value: parseInt(matchPlaceHolder[1], 10)
                });
            } else {
                tokens.push({
                    type: 'text',
                    value: fragment
                });
            }
        }
    }
    return tokens;
}

function eachI18nTagInHtmlDocument(document, lambda, nestedTemplateLambda) {
    var ELEMENT_NODE = 1,
        TEXT_NODE = 3,
        queue = [document],
        i;
    while (queue.length) {
        var node = queue.shift(),
            parentNode = node.parentNode,
            nodeStillInDocument = true;
        if (parentNode && node.nodeType === ELEMENT_NODE) {
            if (node.hasAttribute && node.hasAttribute('data-i18n')) { // In IE7 the HTML node doesn't have a hasAttribute method?
                var i18nStr = node.getAttribute('data-i18n'),
                    i18nObj;

                if (i18nStr.indexOf(':') !== -1) {
                    try {
                        i18nObj = eval('({' + i18nStr + '})'); // eslint-disable-line no-eval
                    } catch (e) {
                        throw new Error('i18nTools.eachI18nTagInHtmlDocument: Error evaluating data-i18n attribute: ' + i18nStr + '\n' + e.stack);
                    }
                } else {
                    i18nObj = {text: i18nStr};
                }

                if (i18nObj.attr) {
                    var attributeNames = Object.keys(i18nObj.attr);
                    for (i = 0 ; i < attributeNames.length ; i += 1) {
                        var attributeName = attributeNames[i],
                            key = i18nObj.attr[attributeName] || null;
                        if (lambda({type: 'i18nTagAttribute', attributeName: attributeName, node: node, key: key, defaultValue: node.getAttribute(attributeName)}) === false) {
                            return;
                        }
                    }
                }

                if (typeof i18nObj.text !== 'undefined') {
                    var defaultValue = '',
                        placeHolders = [],
                        nextPlaceHolderNumber = 0;

                    for (i = 0 ; i < node.childNodes.length ; i += 1) {
                        var childNode = node.childNodes[i];
                        if (childNode.nodeType === TEXT_NODE) {
                            defaultValue += childNode.nodeValue;
                        } else {
                            defaultValue += '{' + nextPlaceHolderNumber + '}';
                            nextPlaceHolderNumber += 1;
                            placeHolders.push(childNode);
                        }
                    }
                    defaultValue = defaultValue.replace(/^[ \n\t]+|[ \n\t]+$/g, ''); // Trim leading and trailing whitespace, except non-breaking space chars
                    defaultValue = defaultValue.replace(/[ \n\t]+/g, ' '); // Compress and normalize sequences of 1+ spaces to one ' '
                    if (lambda({type: 'i18nTagText', node: node, key: i18nObj.text || null, defaultValue: defaultValue, placeHolders: placeHolders}) === false) {
                        return;
                    }
                } else {
                    // A tag with a data-i18n tag, but no language key for the text contents.
                    // Give the lambda a chance to clean up the tag anyway:
                    lambda({node: node});
                }
                if (!node.parentNode) {
                    nodeStillInDocument = false;
                    queue.unshift(parentNode);
                }
            }
            // Give the caller a chance to do something about nested <script type="text/html">...</script> templates (used by TRHTML in the browser):
            if (nestedTemplateLambda && node.nodeName.toLowerCase() === 'script' && node.getAttribute('type') === 'text/html') {
                nestedTemplateLambda(node);
            }
        }
        if (nodeStillInDocument && node.childNodes) {
            for (i = node.childNodes.length - 1 ; i >= 0 ; i -= 1) {
                queue.unshift(node.childNodes[i]);
            }
        }
    }
}

function createI18nTagReplacer(options) {
    var TEXT_NODE = 3,
        allKeysForLocale = options.allKeysForLocale,
        keepI18nAttributes = options.keepI18nAttributes,
        keepSpans = options.keepSpans;

    return function i18nTagReplacer(options) {
        var key = options.key,
            node = options.node,
            value = allKeysForLocale[key],
            removeNode = !keepSpans && options.type !== 'i18nTagAttribute' && node.nodeName.toLowerCase() === 'span' && node.attributes.length === 1;

        if (key !== null) { // An empty string or null means explicitly "do not translate"
            if (/^i18nTag/.test(options.type) && value === null || typeof value === 'undefined') {
                value = options.defaultValue || '[!' + key + '!]';
            }
            if (options.type === 'i18nTagAttribute') {
                node.setAttribute(options.attributeName, value);
            } else if (options.type === 'i18nTagText') {
                while (node.childNodes.length) {
                    node.removeChild(node.firstChild);
                }
                tokenizePattern(value).forEach(function (token) {
                    var nodeToInsert;
                    if (token.type === 'text') {
                        nodeToInsert = node.ownerDocument.createTextNode(token.value);
                    } else {
                        var placeHolder = options.placeHolders[token.value];
                        if (placeHolder) {
                            nodeToInsert = placeHolder;
                            if (nodeToInsert.parentNode) {
                                nodeToInsert = nodeToInsert.cloneNode(true);
                            }
                        } else {
                            nodeToInsert = node.ownerDocument.createTextNode('[!{' + token.value + '}!]');
                        }
                    }
                    if (removeNode) {
                        if (nodeToInsert.nodeType === TEXT_NODE && node.previousSibling && node.previousSibling.nodeType === TEXT_NODE) {
                            // Splice with previous text node
                            node.previousSibling.nodeValue += nodeToInsert.nodeValue;
                        } else {
                            node.parentNode.insertBefore(nodeToInsert, node);
                        }
                    } else {
                        node.appendChild(nodeToInsert);
                    }
                });
            }
        }
        if (removeNode) {
            node.parentNode.removeChild(node);
        } else if (!keepI18nAttributes && options.type !== 'i18nTagAttribute') {
            node.removeAttribute('data-i18n');
        }
    };
}

function createTr(localeData) {
    function tokenizePattern(pattern) {
        if (typeof pattern !== 'string') {
            var valueString = pattern;
            try {
                valueString = JSON.stringify(pattern);
            } catch (e) {}
            throw new Error('i18nTools.tokenizePattern: Value must be a string: ' + valueString);
        }
        var tokens = [],
            fragments = pattern.split(/(\{\d+\})/);
        for (var i = 0 ; i < fragments.length ; i += 1) {
            var fragment = fragments[i];
            if (fragment.length > 0) {
                var matchPlaceHolder = fragment.match(/^\{(\d+)\}$/);
                if (matchPlaceHolder) {
                    tokens.push({
                        type: 'placeHolder',
                        value: parseInt(matchPlaceHolder[1], 10)
                    });
                } else {
                    tokens.push({
                        type: 'text',
                        value: fragment
                    });
                }
            }
        }
        return tokens;
    }

    var TR = function (key, defaultValue) {
        return localeData[key] || defaultValue || '[!' + key + '!]';
    };

    TR.PAT = function (key, defaultPattern) {
        var pattern = TR(key, defaultPattern), tokens = tokenizePattern(pattern);
        return function () {
            // placeHolderValue, ...
            var placeHolderValues = arguments, renderedString = '';
            for (var i = 0; i < tokens.length; i += 1) {
                var token = tokens[i];
                if (token.type === 'placeHolder') {
                    renderedString += placeHolderValues[token.value];
                } else {
                    // token.type === 'text'
                    renderedString += token.value;
                }
            }
            return renderedString;
        };
    };

    TR.HTML = function (htmlString) {
        var div = document.createElement('div');
        div.innerHTML = htmlString;
        eachI18nTagInHtmlDocument(div, createI18nTagReplacer({
            allKeysForLocale: localeData,
            keepI18nAttributes: true,
            keepSpans: true
        }), function nestedTemplateHandler(node) {
            if (node.firstChild && node.firstChild.nodeType === node.TEXT_NODE) {
                // Use window.TRHTML instead of TRHTML to prevent the recursive call from being recognized as a relation:
                node.firstChild.nodeValue = window.TR.HTML(node.firstChild.nodeValue);
            }
        });
        return div.innerHTML;
    };

    return TR;
}

function gatherKeysForLocale(source, locale) {
    var prioritizedLocale = expandLocaleIdToPrioritizedList(locale);
    return Object.keys(source).reduce(function (data, key) {
        for (var i = 0 ; i < prioritizedLocale.length ; i += 1) {
            var value = source[key][prioritizedLocale[i]];
            if (typeof value !== 'undefined') {
                data[key] = value;
                break;
            }
        }
        return data;
    }, {});
}

module.exports = {
    // These are maintained here because we haven't been able to work out how
    // to use relative requires in a system.js plugin:
    tokenizePattern: tokenizePattern,
    eachI18nTagInHtmlDocument: eachI18nTagInHtmlDocument,
    createI18nTagReplacer: createI18nTagReplacer,

    // fetch: sideeffect: load relevant parts of i18n file filtered by locale
    fetch: function (load, fetch) {
        load.metadata.newAddress = load.address.replace(/\.([^.]+)\.i18n/, function (str, matchedLocale) {
            load.metadata.locale = matchedLocale;
            return '.i18n';
        });
        return fetch({address: load.metadata.newAddress, metadata: {}});
    },

    translate: function (load) {
        if (this.builder) {
            load.metadata.format = 'cjs';
            load.metadata.originalSource = load.source;
            return 'module.exports = (' + createTr.toString() + ')(' + JSON.stringify(gatherKeysForLocale(JSON.parse(load.source), load.metadata.locale)) + ');';
        }
    },

    instantiate: function (load) {
        if (!this.builder) {
            return createTr(gatherKeysForLocale(JSON.parse(load.source), load.metadata.locale));
        }
    },

    listAssets: function (loads) {
        var isSeenByNewAddress = {};
        var i18nAssets = [];
        loads.forEach(function (load) {
            if (!isSeenByNewAddress[load.metadata.newAddress]) {
                isSeenByNewAddress[load.metadata.newAddress] = true;
                i18nAssets.push({
                    url: load.metadata.newAddress,
                    source: load.metadata.originalSource,
                    type: 'i18n'
                });
            }
        });
        return i18nAssets;
    }
};
<commit_msg>Revert "fix it"<commit_after>// System.js plugin
function normalizeLocaleId(localeId) {
    return localeId && localeId.replace(/-/g, '_').toLowerCase();
}

// Helper for getting a prioritized, normalized list of relevant locale ids from a specific locale id.
// For instance, 'en_US' produces ['en_us', 'en']
function expandLocaleIdToPrioritizedList(localeId) {
    if (!localeId) {
        return [];
    }
    localeId = normalizeLocaleId(localeId);
    var localeIds = [ localeId ];
    while (/_[^_]+$/.test(localeId)) {
        localeId = localeId.replace(/_[^_]+$/, '');
        localeIds.push(localeId);
    }
    return localeIds;
}

function tokenizePattern(pattern) {
    if (typeof pattern !== 'string') {
        var valueString = pattern;
        try {
            valueString = JSON.stringify(pattern);
        } catch (e) {}
        throw new Error('i18nTools.tokenizePattern: Value must be a string: ' + valueString);
    }
    var tokens = [],
        fragments = pattern.split(/(\{\d+\})/);
    for (var i = 0 ; i < fragments.length ; i += 1) {
        var fragment = fragments[i];
        if (fragment.length > 0) {
            var matchPlaceHolder = fragment.match(/^\{(\d+)\}$/);
            if (matchPlaceHolder) {
                tokens.push({
                    type: 'placeHolder',
                    value: parseInt(matchPlaceHolder[1], 10)
                });
            } else {
                tokens.push({
                    type: 'text',
                    value: fragment
                });
            }
        }
    }
    return tokens;
}

function eachI18nTagInHtmlDocument(document, lambda, nestedTemplateLambda) {
    var ELEMENT_NODE = 1,
        TEXT_NODE = 3,
        queue = [document],
        i;
    while (queue.length) {
        var node = queue.shift(),
            parentNode = node.parentNode,
            nodeStillInDocument = true;
        if (parentNode && node.nodeType === ELEMENT_NODE) {
            if (node.hasAttribute && node.hasAttribute('data-i18n')) { // In IE7 the HTML node doesn't have a hasAttribute method?
                var i18nStr = node.getAttribute('data-i18n'),
                    i18nObj;

                if (i18nStr.indexOf(':') !== -1) {
                    try {
                        i18nObj = eval('({' + i18nStr + '})'); // eslint-disable-line no-eval
                    } catch (e) {
                        throw new Error('i18nTools.eachI18nTagInHtmlDocument: Error evaluating data-i18n attribute: ' + i18nStr + '\n' + e.stack);
                    }
                } else {
                    i18nObj = {text: i18nStr};
                }

                if (i18nObj.attr) {
                    var attributeNames = Object.keys(i18nObj.attr);
                    for (i = 0 ; i < attributeNames.length ; i += 1) {
                        var attributeName = attributeNames[i],
                            key = i18nObj.attr[attributeName] || null;
                        if (lambda({type: 'i18nTagAttribute', attributeName: attributeName, node: node, key: key, defaultValue: node.getAttribute(attributeName)}) === false) {
                            return;
                        }
                    }
                }

                if (typeof i18nObj.text !== 'undefined') {
                    var defaultValue = '',
                        placeHolders = [],
                        nextPlaceHolderNumber = 0;

                    for (i = 0 ; i < node.childNodes.length ; i += 1) {
                        var childNode = node.childNodes[i];
                        if (childNode.nodeType === TEXT_NODE) {
                            defaultValue += childNode.nodeValue;
                        } else {
                            defaultValue += '{' + nextPlaceHolderNumber + '}';
                            nextPlaceHolderNumber += 1;
                            placeHolders.push(childNode);
                        }
                    }
                    defaultValue = defaultValue.replace(/^[ \n\t]+|[ \n\t]+$/g, ''); // Trim leading and trailing whitespace, except non-breaking space chars
                    defaultValue = defaultValue.replace(/[ \n\t]+/g, ' '); // Compress and normalize sequences of 1+ spaces to one ' '
                    if (lambda({type: 'i18nTagText', node: node, key: i18nObj.text || null, defaultValue: defaultValue, placeHolders: placeHolders}) === false) {
                        return;
                    }
                } else {
                    // A tag with a data-i18n tag, but no language key for the text contents.
                    // Give the lambda a chance to clean up the tag anyway:
                    lambda({node: node});
                }
                if (!node.parentNode) {
                    nodeStillInDocument = false;
                    queue.unshift(parentNode);
                }
            }
            // Give the caller a chance to do something about nested <script type="text/html">...</script> templates (used by TRHTML in the browser):
            if (nestedTemplateLambda && node.nodeName.toLowerCase() === 'script' && node.getAttribute('type') === 'text/html') {
                nestedTemplateLambda(node);
            }
        }
        if (nodeStillInDocument && node.childNodes) {
            for (i = node.childNodes.length - 1 ; i >= 0 ; i -= 1) {
                queue.unshift(node.childNodes[i]);
            }
        }
    }
}

function createI18nTagReplacer(options) {
    var TEXT_NODE = 3,
        allKeysForLocale = options.allKeysForLocale,
        keepI18nAttributes = options.keepI18nAttributes,
        keepSpans = options.keepSpans;

    return function i18nTagReplacer(options) {
        var key = options.key,
            node = options.node,
            value = allKeysForLocale[key],
            removeNode = !keepSpans && options.type !== 'i18nTagAttribute' && node.nodeName.toLowerCase() === 'span' && node.attributes.length === 1;

        if (key !== null) { // An empty string or null means explicitly "do not translate"
            if (/^i18nTag/.test(options.type) && value === null || typeof value === 'undefined') {
                value = options.defaultValue || '[!' + key + '!]';
            }
            if (options.type === 'i18nTagAttribute') {
                node.setAttribute(options.attributeName, value);
            } else if (options.type === 'i18nTagText') {
                while (node.childNodes.length) {
                    node.removeChild(node.firstChild);
                }
                tokenizePattern(value).forEach(function (token) {
                    var nodeToInsert;
                    if (token.type === 'text') {
                        nodeToInsert = node.ownerDocument.createTextNode(token.value);
                    } else {
                        var placeHolder = options.placeHolders[token.value];
                        if (placeHolder) {
                            nodeToInsert = placeHolder;
                            if (nodeToInsert.parentNode) {
                                nodeToInsert = nodeToInsert.cloneNode(true);
                            }
                        } else {
                            nodeToInsert = node.ownerDocument.createTextNode('[!{' + token.value + '}!]');
                        }
                    }
                    if (removeNode) {
                        if (nodeToInsert.nodeType === TEXT_NODE && node.previousSibling && node.previousSibling.nodeType === TEXT_NODE) {
                            // Splice with previous text node
                            node.previousSibling.nodeValue += nodeToInsert.nodeValue;
                        } else {
                            node.parentNode.insertBefore(nodeToInsert, node);
                        }
                    } else {
                        node.appendChild(nodeToInsert);
                    }
                });
            }
        }
        if (removeNode) {
            node.parentNode.removeChild(node);
        } else if (!keepI18nAttributes && options.type !== 'i18nTagAttribute') {
            node.removeAttribute('data-i18n');
        }
    };
}

function createTr(localeData) {
    function tokenizePattern(pattern) {
        if (typeof pattern !== 'string') {
            var valueString = pattern;
            try {
                valueString = JSON.stringify(pattern);
            } catch (e) {}
            throw new Error('i18nTools.tokenizePattern: Value must be a string: ' + valueString);
        }
        var tokens = [],
            fragments = pattern.split(/(\{\d+\})/);
        for (var i = 0 ; i < fragments.length ; i += 1) {
            var fragment = fragments[i];
            if (fragment.length > 0) {
                var matchPlaceHolder = fragment.match(/^\{(\d+)\}$/);
                if (matchPlaceHolder) {
                    tokens.push({
                        type: 'placeHolder',
                        value: parseInt(matchPlaceHolder[1], 10)
                    });
                } else {
                    tokens.push({
                        type: 'text',
                        value: fragment
                    });
                }
            }
        }
        return tokens;
    }

    var TR = function (key, defaultValue) {
        return localeData[key] || defaultValue || '[!' + key + '!]';
    };

    TR.PAT = function (key, defaultPattern) {
        var pattern = TR(key, defaultPattern), tokens = tokenizePattern(pattern);
        return function () {
            // placeHolderValue, ...
            var placeHolderValues = arguments, renderedString = '';
            for (var i = 0; i < tokens.length; i += 1) {
                var token = tokens[i];
                if (token.type === 'placeHolder') {
                    renderedString += placeHolderValues[token.value];
                } else {
                    // token.type === 'text'
                    renderedString += token.value;
                }
            }
            return renderedString;
        };
    };

    TR.HTML = function (htmlString) {
        var div = document.createElement('div');
        div.innerHTML = htmlString;
        require('./lib/eachI18nTagInHtmlDocument')(div, require('./lib/createI18nTagReplacer')({
            allKeysForLocale: localeData,
            keepI18nAttributes: true,
            keepSpans: true
        }), function nestedTemplateHandler(node) {
            if (node.firstChild && node.firstChild.nodeType === node.TEXT_NODE) {
                // Use window.TRHTML instead of TRHTML to prevent the recursive call from being recognized as a relation:
                node.firstChild.nodeValue = window.TR.HTML(node.firstChild.nodeValue);
            }
        });
        return div.innerHTML;
    };

    return TR;
}

function gatherKeysForLocale(source, locale) {
    var prioritizedLocale = expandLocaleIdToPrioritizedList(locale);
    return Object.keys(source).reduce(function (data, key) {
        for (var i = 0 ; i < prioritizedLocale.length ; i += 1) {
            var value = source[key][prioritizedLocale[i]];
            if (typeof value !== 'undefined') {
                data[key] = value;
                break;
            }
        }
        return data;
    }, {});
}

module.exports = {
    // These are maintained here because we haven't been able to work out how
    // to use relative requires in a system.js plugin:
    tokenizePattern: tokenizePattern,
    eachI18nTagInHtmlDocument: eachI18nTagInHtmlDocument,
    createI18nTagReplacer: createI18nTagReplacer,

    // fetch: sideeffect: load relevant parts of i18n file filtered by locale
    fetch: function (load, fetch) {
        load.metadata.newAddress = load.address.replace(/\.([^.]+)\.i18n/, function (str, matchedLocale) {
            load.metadata.locale = matchedLocale;
            return '.i18n';
        });
        return fetch({address: load.metadata.newAddress, metadata: {}});
    },

    translate: function (load) {
        if (this.builder) {
            load.metadata.format = 'cjs';
            load.metadata.originalSource = load.source;
            return 'module.exports = (' + createTr.toString() + ')(' + JSON.stringify(gatherKeysForLocale(JSON.parse(load.source), load.metadata.locale)) + ');';
        }
    },

    instantiate: function (load) {
        if (!this.builder) {
            return createTr(gatherKeysForLocale(JSON.parse(load.source), load.metadata.locale));
        }
    },

    listAssets: function (loads) {
        var isSeenByNewAddress = {};
        var i18nAssets = [];
        loads.forEach(function (load) {
            if (!isSeenByNewAddress[load.metadata.newAddress]) {
                isSeenByNewAddress[load.metadata.newAddress] = true;
                i18nAssets.push({
                    url: load.metadata.newAddress,
                    source: load.metadata.originalSource,
                    type: 'i18n'
                });
            }
        });
        return i18nAssets;
    }
};
<|endoftext|>