<commit_before>/*
 Copyright 2017 Credential Engine and other contributing parties.

 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 repo;

EcRepository.caching = true;
EcRepository.cachingSearch = false;

var frameworkId = "";

var servers = ["https://dev.cassproject.org/api/"];
var repo;

if (queryParams.server != null)
    servers = [queryParams.server];

var webSocketBackoff = 100;
var webSocketConnection = false;

openWebSocket = function (r) {
    var connection;
    // Instead of /ws/custom, will be /ws in next release.
    if (queryParams.webSocketOverride == null || queryParams.webSocketOverride === undefined)
        connection = new WebSocket(r.selectedServer.replace(/http/, "ws").replace(/api\//, "ws/custom"));
    else
        connection = new WebSocket(queryParams.webSocketOverride);

    connection.onopen = function () {
        console.log("WebSocket open.");
        webSocketConnection = true;
    };

    connection.onerror = function (error) {
        console.log(error);
    };

    //Re-establish connection on close.
    connection.onclose = function (evt) {
        console.log(evt);
        webSocketBackoff *= 2;
        webSocketConnection = false;
        setTimeout(function () {
            openWebSocket(r);
        }, webSocketBackoff);
    };

    connection.onmessage = function (e) {
        console.log('Server: ' + e.data);
        if (framework == null) return;
        EcRepository.get(e.data, function (wut) {
            delete EcRepository.cache[wut.id];
            delete EcRepository.cache[wut.shortId()];

            if (new ConceptScheme().isA(wut.getFullType()))
                if (framework != null)
                    if (framework.shortId() == wut.shortId()) {
                        framework = new ConceptScheme();
                        framework.copyFrom(wut);
                        populateFramework();
                    }

            if (new EcFramework().isA(wut.getFullType()))
                if (framework != null)
                    if (framework.shortId() == wut.shortId()) {
                        framework = new EcFramework();
                        framework.copyFrom(wut);
                        populateFramework();
                    }

            if (new Concept().isA(wut.getFullType())) {
                if (framework != null)
                    if ($("[id=\"" + wut.shortId() + "\"]").length > 0) {
                        var com = new Concept();
                        com.copyFrom(wut);
                        $("#tree [id='" + com.shortId() + "']").remove();
                        if (com.narrows != null)
                            for (var i = 0; i < com.narrows.length; i++) {

                                window.fetches++;
                                refreshCompetency(com).appendTo($("[id=\"" + com.narrows[i] + "\"]>ul"));
                            }
                        if (com.topConceptOf != null)
                            refreshCompetency(com);
                        if (selectedCompetency != null)
                            if (selectedCompetency.shortId() == wut.shortId()) {
                                selectedCompetency = com;
                                refreshSidebar();
                            }
                    }
            }
            if (new EcCompetency().isA(wut.getFullType())) {
                if (framework != null)
                    if (framework.competency != null)
                        if (EcArray.has(framework.competency, wut.shortId()) || EcArray.has(framework.competency, wut.shortId()) || JSON.stringify(framework.competency).indexOf(EcCrypto.md5(wut.id)) != -1) {
                            var com = new EcCompetency();
                            com.copyFrom(wut);
                            window.fetches++;
                            refreshCompetency(com);
                            if (selectedCompetency != null)
                                if (selectedCompetency.shortId() == wut.shortId()) {
                                    selectedCompetency = com;
                                    refreshSidebar();
                                }
                        }
            }

            if (new EcLevel().isA(wut.getFullType())) {
                if (framework != null)
                    if (framework.level != null)
                        if (EcArray.has(framework.level, wut.shortId()) || EcArray.has(framework.level, wut.shortId())) {
                            var com = new EcLevel();
                            com.copyFrom(wut);
                            window.fetches++;
                            refreshCompetency(com);
                            if (selectedCompetency != null)
                                if (selectedCompetency.shortId() == wut.shortId()) {
                                    selectedCompetency = com;
                                    refreshSidebar();
                                }
                        }
            }

        }, error);
    };

}

function cappend(event) {
    if (event.data.message == "selected") {
        console.log("I got " + event.data.selected.length + " selected items from the iframe");
        console.log(event.data.selected);
        if (JSON.stringify(event.data.selected).indexOf("Concept") != -1) {
            attachUrlProperties(event.data.selected);
            backPage();
            backPage();
        } else showCopyOrLinkDialog(function (copy) {
            if (copy === true) {
                copyCompetencies(event.data.selected);
            } else {
                appendCompetencies(event.data.selected);
            }
            hideCopyOrLinkDialog();
            backPage();
        });
    } else if (event.data.message == "back")
        backPage();
}

for (var i = 0; i < servers.length; i++) {
    var r = new EcRepository();
    r.selectedServer = servers[i];
    r.autoDetectRepository();
    servers[i] = r;
    repo = r;

    try {
        window.addEventListener('message', cappend, false);
    } catch (e) {
        console.error(e);
    }

    openWebSocket(r);
}

var iframeRoot = queryParams.editorRoot;
if (iframeRoot == null || iframeRoot === undefined)
    iframeRoot = "";
var iframePath = iframeRoot + "index.html?select=Add&selectRelations=true&view=true&iframeRoot=" + iframeRoot + "&origin=" + window.location.origin + (queryParams.server == null ? "" : "&server=" + queryParams.server);
if (queryParams.webSocketOverride != null && queryParams.webSocketOverride !== undefined)
    iframePath += "&webSocketOverride=" + queryParams.webSocketOverride;
if (queryParams.view != "true")
    $("#findCompetencyIframe").attr("src", iframePath);

var iframeConceptPath = iframeRoot + "index.html?select=Add&concepts=true&iframeRoot=" + iframeRoot + "&ceasnDataFields=" + queryParams.ceasnDataFields + "&origin=" + window.location.origin + (queryParams.server == null ? "" : "&server=" + queryParams.server);
if (queryParams.webSocketOverride != null && queryParams.webSocketOverride !== undefined)
    iframeConceptPath += "&webSocketOverride=" + queryParams.webSocketOverride;
if (queryParams.view != "true")
    $("#selectConceptIframe").attr("src", iframeConceptPath);

loadIdentity = function (callback) {
    if (queryParams.user == "self") {
        EcIdentityManager.readIdentities();
        EcIdentityManager.readContacts();
        if (EcIdentityManager.ids.length == 0) {
            loading("Generating identity...");
            EcPpk.generateKeyAsync(
                function (p1) {
                    identity = new EcIdentity();
                    identity.ppk = p1;
                    identity.displayName = "You";
                    EcIdentityManager.onIdentityChanged = EcIdentityManager.saveIdentities;
                    EcIdentityManager.addIdentity(identity);
                    callback();
                }
            );
        } else
            callback();
    } else if (queryParams.user == "wait") {
        var fun = function (evt) {
            var data = evt.data;
            if (data != null)
                data = JSON.parse(data);
            if (data.action == "identity") {
                identity = new EcIdentity();
                identity.ppk = EcPpk.fromPem(data.identity);
                identity.displayName = "You";
                EcIdentityManager.addIdentity(identity);
                callback();
            }
        };
        if (window.addEventListener) {
            window.addEventListener("message", fun, false);
        } else {
            window.attachEvent("onmessage", fun);
        }
    } else
        callback();
}
<commit_msg>Increased reliability of concept selection.<commit_after>/*
 Copyright 2017 Credential Engine and other contributing parties.

 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 repo;

EcRepository.caching = true;
EcRepository.cachingSearch = false;

var frameworkId = "";

var servers = ["https://dev.cassproject.org/api/"];
var repo;

if (queryParams.server != null)
    servers = [queryParams.server];

var webSocketBackoff = 100;
var webSocketConnection = false;

openWebSocket = function (r) {
    var connection;
    // Instead of /ws/custom, will be /ws in next release.
    if (queryParams.webSocketOverride == null || queryParams.webSocketOverride === undefined)
        connection = new WebSocket(r.selectedServer.replace(/http/, "ws").replace(/api\//, "ws/custom"));
    else
        connection = new WebSocket(queryParams.webSocketOverride);

    connection.onopen = function () {
        console.log("WebSocket open.");
        webSocketConnection = true;
    };

    connection.onerror = function (error) {
        console.log(error);
    };

    //Re-establish connection on close.
    connection.onclose = function (evt) {
        console.log(evt);
        webSocketBackoff *= 2;
        webSocketConnection = false;
        setTimeout(function () {
            openWebSocket(r);
        }, webSocketBackoff);
    };

    connection.onmessage = function (e) {
        console.log('Server: ' + e.data);
        if (framework == null) return;
        EcRepository.get(e.data, function (wut) {
            delete EcRepository.cache[wut.id];
            delete EcRepository.cache[wut.shortId()];

            if (new ConceptScheme().isA(wut.getFullType()))
                if (framework != null)
                    if (framework.shortId() == wut.shortId()) {
                        framework = new ConceptScheme();
                        framework.copyFrom(wut);
                        populateFramework();
                    }

            if (new EcFramework().isA(wut.getFullType()))
                if (framework != null)
                    if (framework.shortId() == wut.shortId()) {
                        framework = new EcFramework();
                        framework.copyFrom(wut);
                        populateFramework();
                    }

            if (new Concept().isA(wut.getFullType())) {
                if (framework != null)
                    if ($("[id=\"" + wut.shortId() + "\"]").length > 0) {
                        var com = new Concept();
                        com.copyFrom(wut);
                        $("#tree [id='" + com.shortId() + "']").remove();
                        if (com.narrows != null)
                            for (var i = 0; i < com.narrows.length; i++) {

                                window.fetches++;
                                refreshCompetency(com).appendTo($("[id=\"" + com.narrows[i] + "\"]>ul"));
                            }
                        if (com.topConceptOf != null)
                            refreshCompetency(com);
                        if (selectedCompetency != null)
                            if (selectedCompetency.shortId() == wut.shortId()) {
                                selectedCompetency = com;
                                refreshSidebar();
                            }
                    }
            }
            if (new EcCompetency().isA(wut.getFullType())) {
                if (framework != null)
                    if (framework.competency != null)
                        if (EcArray.has(framework.competency, wut.shortId()) || EcArray.has(framework.competency, wut.shortId()) || JSON.stringify(framework.competency).indexOf(EcCrypto.md5(wut.id)) != -1) {
                            var com = new EcCompetency();
                            com.copyFrom(wut);
                            window.fetches++;
                            refreshCompetency(com);
                            if (selectedCompetency != null)
                                if (selectedCompetency.shortId() == wut.shortId()) {
                                    selectedCompetency = com;
                                    refreshSidebar();
                                }
                        }
            }

            if (new EcLevel().isA(wut.getFullType())) {
                if (framework != null)
                    if (framework.level != null)
                        if (EcArray.has(framework.level, wut.shortId()) || EcArray.has(framework.level, wut.shortId())) {
                            var com = new EcLevel();
                            com.copyFrom(wut);
                            window.fetches++;
                            refreshCompetency(com);
                            if (selectedCompetency != null)
                                if (selectedCompetency.shortId() == wut.shortId()) {
                                    selectedCompetency = com;
                                    refreshSidebar();
                                }
                        }
            }

        }, error);
    };

}

function cappend(event) {
    if (event.data.message == "selected") {
        console.log("I got " + event.data.selected.length + " selected items from the iframe");
        console.log(event.data.selected);
        if (JSON.stringify(event.data.selected).indexOf("Concept") != -1) {
            attachUrlProperties(event.data.selected);
            $("#selectConceptSection").hide();
            $("#editFrameworkSection").show();
        } else showCopyOrLinkDialog(function (copy) {
            if (copy === true) {
                copyCompetencies(event.data.selected);
            } else {
                appendCompetencies(event.data.selected);
            }
            hideCopyOrLinkDialog();
            backPage();
        });
    } else if (event.data.message == "back")
        backPage();
}

for (var i = 0; i < servers.length; i++) {
    var r = new EcRepository();
    r.selectedServer = servers[i];
    r.autoDetectRepository();
    servers[i] = r;
    repo = r;

    try {
        window.addEventListener('message', cappend, false);
    } catch (e) {
        console.error(e);
    }

    openWebSocket(r);
}

var iframeRoot = queryParams.editorRoot;
if (iframeRoot == null || iframeRoot === undefined)
    iframeRoot = "";
var iframePath = iframeRoot + "index.html?select=Add&selectRelations=true&view=true&iframeRoot=" + iframeRoot + "&origin=" + window.location.origin + (queryParams.server == null ? "" : "&server=" + queryParams.server);
if (queryParams.webSocketOverride != null && queryParams.webSocketOverride !== undefined)
    iframePath += "&webSocketOverride=" + queryParams.webSocketOverride;
if (queryParams.view != "true")
    $("#findCompetencyIframe").attr("src", iframePath);

var iframeConceptPath = iframeRoot + "index.html?select=Add&concepts=true&iframeRoot=" + iframeRoot + "&ceasnDataFields=" + queryParams.ceasnDataFields + "&origin=" + window.location.origin + (queryParams.server == null ? "" : "&server=" + queryParams.server);
if (queryParams.webSocketOverride != null && queryParams.webSocketOverride !== undefined)
    iframeConceptPath += "&webSocketOverride=" + queryParams.webSocketOverride;
if (queryParams.view != "true")
    $("#selectConceptIframe").attr("src", iframeConceptPath);

loadIdentity = function (callback) {
    if (queryParams.user == "self") {
        EcIdentityManager.readIdentities();
        EcIdentityManager.readContacts();
        if (EcIdentityManager.ids.length == 0) {
            loading("Generating identity...");
            EcPpk.generateKeyAsync(
                function (p1) {
                    identity = new EcIdentity();
                    identity.ppk = p1;
                    identity.displayName = "You";
                    EcIdentityManager.onIdentityChanged = EcIdentityManager.saveIdentities;
                    EcIdentityManager.addIdentity(identity);
                    callback();
                }
            );
        } else
            callback();
    } else if (queryParams.user == "wait") {
        var fun = function (evt) {
            var data = evt.data;
            if (data != null)
                data = JSON.parse(data);
            if (data.action == "identity") {
                identity = new EcIdentity();
                identity.ppk = EcPpk.fromPem(data.identity);
                identity.displayName = "You";
                EcIdentityManager.addIdentity(identity);
                callback();
            }
        };
        if (window.addEventListener) {
            window.addEventListener("message", fun, false);
        } else {
            window.attachEvent("onmessage", fun);
        }
    } else
        callback();
}
<|endoftext|>


<commit_before>/* Magic Mirror
 * Server
 *
 * By Michael Teeuw https://michaelteeuw.nl
 * MIT Licensed.
 */
var express = require("express");
var app = require("express")();
var path = require("path");
var ipfilter = require("express-ipfilter").IpFilter;
var fs = require("fs");
var helmet = require("helmet");

var Log = require("./logger.js");
var Utils = require("./utils.js");

var Server = function (config, callback) {
	var port = config.port;
	if (process.env.MM_PORT) {
		port = process.env.MM_PORT;
	}

	var server = null;
	if (config.useHttps) {
		var options = {
			key: fs.readFileSync(config.httpsPrivateKey),
			cert: fs.readFileSync(config.httpsCertificate)
		};
		server = require("https").Server(options, app);
	} else {
		server = require("http").Server(app);
	}
	var io = require("socket.io")(server);

	Log.log("Starting server on port " + port + " ... ");

	server.listen(port, config.address ? config.address : "localhost");

	if (config.ipWhitelist instanceof Array && config.ipWhitelist.length === 0) {
		Log.warn(Utils.colors.warn("You're using a full whitelist configuration to allow for all IPs"));
	}

	app.use(function (req, res, next) {
		var result = ipfilter(config.ipWhitelist, { mode: config.ipWhitelist.length === 0 ? "deny" : "allow", log: false })(req, res, function (err) {
			if (err === undefined) {
				return next();
			}
			Log.log(err.message);
			res.status(403).send("This device is not allowed to access your mirror.
 Please check your config.js or config.js.sample to change this.");
		});
	});
	app.use(helmet({ contentSecurityPolicy: false }));

	app.use("/js", express.static(__dirname));
	var directories = ["/config", "/css", "/fonts", "/modules", "/vendor", "/translations", "/tests/configs"];
	var directory;
	for (var i in directories) {
		directory = directories[i];
		app.use(directory, express.static(path.resolve(global.root_path + directory)));
	}

	app.get("/version", function (req, res) {
		res.send(global.version);
	});

	app.get("/config", function (req, res) {
		res.send(config);
	});

	app.get("/", function (req, res) {
		var html = fs.readFileSync(path.resolve(global.root_path + "/index.html"), { encoding: "utf8" });
		html = html.replace("#VERSION#", global.version);

		var configFile = "config/config.js";
		if (typeof global.configuration_file !== "undefined") {
			configFile = global.configuration_file;
		}
		html = html.replace("#CONFIG_FILE#", configFile);

		res.send(html);
	});

	if (typeof callback === "function") {
		callback(app, io);
	}
};

module.exports = Server;
<commit_msg>clean up server<commit_after>/* Magic Mirror
 * Server
 *
 * By Michael Teeuw https://michaelteeuw.nl
 * MIT Licensed.
 */
const express = require("express");
const app = require("express")();
const path = require("path");
const ipfilter = require("express-ipfilter").IpFilter;
const fs = require("fs");
const helmet = require("helmet");

const Log = require("./logger.js");
const Utils = require("./utils.js");

function Server(config, callback) {
	const port = process.env.MM_PORT || config.port;

	let server = null;
	if (config.useHttps) {
		const options = {
			key: fs.readFileSync(config.httpsPrivateKey),
			cert: fs.readFileSync(config.httpsCertificate)
		};
		server = require("https").Server(options, app);
	} else {
		server = require("http").Server(app);
	}
	const io = require("socket.io")(server);

	Log.log(`Starting server on port ${port} ... `);

	server.listen(port, config.address || "localhost");

	if (config.ipWhitelist instanceof Array && config.ipWhitelist.length === 0) {
		Log.warn(Utils.colors.warn("You're using a full whitelist configuration to allow for all IPs"));
	}

	app.use(function (req, res, next) {
		ipfilter(config.ipWhitelist, { mode: config.ipWhitelist.length === 0 ? "deny" : "allow", log: false })(req, res, function (err) {
			if (err === undefined) {
				return next();
			}
			Log.log(err.message);
			res.status(403).send("This device is not allowed to access your mirror.
 Please check your config.js or config.js.sample to change this.");
		});
	});
	app.use(helmet({ contentSecurityPolicy: false }));

	app.use("/js", express.static(__dirname));

	const directories = ["/config", "/css", "/fonts", "/modules", "/vendor", "/translations", "/tests/configs"];
	for (const directory of directories) {
		app.use(directory, express.static(path.resolve(global.root_path + directory)));
	}

	app.get("/version", function (req, res) {
		res.send(global.version);
	});

	app.get("/config", function (req, res) {
		res.send(config);
	});

	app.get("/", function (req, res) {
		let html = fs.readFileSync(path.resolve(`${global.root_path}/index.html`), { encoding: "utf8" });
		html = html.replace("#VERSION#", global.version);

		let configFile = "config/config.js";
		if (typeof global.configuration_file !== "undefined") {
			configFile = global.configuration_file;
		}
		html = html.replace("#CONFIG_FILE#", configFile);

		res.send(html);
	});

	if (typeof callback === "function") {
		callback(app, io);
	}
}

module.exports = Server;
<|endoftext|>


<commit_before>splasha.innerHTML = "Prossimo incontro: 31 maggio - prof. Frolli
New: Badge autismo.";
splashb.innerHTML = "Prossimo incontro: 31 maggio - prof. Frolli
New: Badge autismo.";
splashc.innerHTML = "Prossimo incontro: 31 maggio - prof. Frolli
New: Badge autismo.";
<commit_msg>Update splash.js<commit_after>splasha.innerHTML = "Prossimo incontro: 31 maggio - prof. Frolli
NewMateriali e Badge DSA-PDP.";
splashb.innerHTML = "Prossimo incontro: 31 maggio - prof. Frolli
NewMateriali e Badge DSA-PDP.";
splashc.innerHTML = "Prossimo incontro: 31 maggio - prof. Frolli
NewMateriali e Badge DSA-PDP.";
<|endoftext|>


<commit_before>globalTopicsDictionary = {};
function nameFromId(id) {
  return globalTopicsDictionary[id] || id || "";
}
function renderDataPoint(topic, dataPoint) {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'points/' + dataPoint + '.json', true);
  xhr.onreadystatechange = function () {
    if (xhr.readyState == 4) {
      if (xhr.status == 200) {
        var obj, badge, icon, sign, service, score, tldr, discussion, terms, privacy, source;
        try {
          obj = JSON.parse(xhr.responseText);
        } catch (e) {
          alert('Could not load data for data point ' + dataPoint + ', sorry! Refreshing the page might sometimes help.');
          return;
        }

        if (obj.tosdr.point == 'good') {
          badge = 'badge-success';
        } else if (obj.tosdr.point == 'mediocre') {
          badge = 'badge-warning';
        } else if (obj.tosdr.point == 'alert') {
          badge = 'badge-important';
          obj.tosdr.score += 100;
        } else if (obj.tosdr.point == 'not bad') {
          badge = 'badge-neutral';
        } else {
          badge = '';
        }

        document.getElementById('point-' + topic + '-' + dataPoint).innerHTML = ''
          + obj.tosdr.score + ' '
          + ''
          + '' + obj.name + '   '
          + '
' + obj.tosdr.tldr + ' Discussion

';
      }
    }
  };
  xhr.send();
}
var topicObjects = {};
function getTopicObject(name, cb) {
  if (topicObjects[name]) {
    cb(topicObjects[name]);
  } else {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'topics/' + name + '.json', true);
    xhr.onreadystatechange = function () {
      if (xhr.readyState == 4) {
        if (xhr.status == 200) {
          var obj;
          try {
            obj = JSON.parse(xhr.responseText);
            topicObjects[name] = obj;
          } catch (e) {
            console.log(xhr.responseText);
            console.log(JSON.parse(xhr.responseText));
            alert('Could not load data for ' + name + ', sorry! Refreshing the page might sometimes help.');
          }
          if (obj) {
            cb(obj);
          }
        }
      }
    };
    xhr.send();
  }
}
function renderDetails(name, points) {
  console.log('renderDetails ' + name);
  console.log(points);
  getTopicObject(name, function (obj) {
    if (obj.id && obj.id) globalTopicsDictionary[obj.id] = obj.name;
    document.getElementById('jump-to').innerHTML += '
' + obj.name + '
 ';
    var header = '

' + obj.name + ' ' + (obj.subtitle || "") + '

';
    var rating;
    var ratingText = {
      0:"We haven't sufficiently reviewed the terms yet. Please contribute to our group.",
      "false":"We haven't sufficiently reviewed the terms yet. Please contribute to our group.",
      "A":"The terms of topic pay specific care towards the user and the operator of the topic follows the best practices.",
      "B":"The terms of topics are fair towards the user but they could be improved.",
      "C":"The terms of topic are okay but some issues need your consideration.",
      "D":"The terms of topic are very uneven or there are some important issues that need your attention.",
      "E":"We strongly discourage you from signing up to this topic. The terms of topic raise serious concerns."
    };
    // [FIXME] We don't need ratings for topics. But it would be useful if instead of the class we could display the description.
    if (!obj.tosdr) {
      obj.tosdr = {rated:false};
    }
    if (obj.tosdr.rated) {
      rating = '';
    } else {
      rating = '';
    }
    var description = '';
    if (obj.description) {
      description = '

' + obj.description;
    }
    var parent = '

';
    if (obj.parent) {
      parent = ' (Category: ' + obj.parent + ')

';
    }
    var issues = '

'
    for (var i = 0; i < points.length; i++) {
      issues += '

';
    }
    issues += '
';
    document.getElementById(name).innerHTML = header + description + parent + issues +
      '
';
    for (var i = 0; i < points.length; i++) {
      renderDataPoint(name, points[i]);
    }
    $('.skipToCategory').each(function () {
      $(this).text(nameFromId($(this).text()))
    });
  });
}
function go() {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'index/topics.json', true);
  xhr.onreadystatechange = function () {
    if (xhr.readyState == 4) {
      if (xhr.status == 200) {
        try {
          var topics = JSON.parse(xhr.responseText);
          console.log(topics);
          var last;
          for (var i in topics) {
            // document.getElementById('jump-to').innerHTML += ''+i+'; ';
          }
          if (last) {
            // document.getElementById('jump-to').innerHTML += ''+last+'. ';
          } else {
            last = i;
          }
          for (var i in topics) {
            if (last) {
              document.getElementById('topics-list').innerHTML += '

'
                + '

'
                + '
';
              renderDetails(last, topics[last]);
              renderDetails(i, topics[i]);
              last = undefined;
            } else {
              last = i;
            }
            document.getElementById('popups').innerHTML +=
              '

';
          }
          if (last) {
            document.getElementById('topics-list').innerHTML += '

';
            renderDetails(last, topics[i]);
          }
        } catch (e) {
        }
      }
    }
  };
  xhr.send();
}
<commit_msg>Missing ; in topics.js<commit_after>globalTopicsDictionary = {};
function nameFromId(id) {
  return globalTopicsDictionary[id] || id || "";
}
function renderDataPoint(topic, dataPoint) {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'points/' + dataPoint + '.json', true);
  xhr.onreadystatechange = function () {
    if (xhr.readyState == 4) {
      if (xhr.status == 200) {
        var obj, badge, icon, sign, service, score, tldr, discussion, terms, privacy, source;
        try {
          obj = JSON.parse(xhr.responseText);
        } catch (e) {
          alert('Could not load data for data point ' + dataPoint + ', sorry! Refreshing the page might sometimes help.');
          return;
        }

        if (obj.tosdr.point == 'good') {
          badge = 'badge-success';
        } else if (obj.tosdr.point == 'mediocre') {
          badge = 'badge-warning';
        } else if (obj.tosdr.point == 'alert') {
          badge = 'badge-important';
          obj.tosdr.score += 100;
        } else if (obj.tosdr.point == 'not bad') {
          badge = 'badge-neutral';
        } else {
          badge = '';
        }

        document.getElementById('point-' + topic + '-' + dataPoint).innerHTML = ''
          + obj.tosdr.score + ' '
          + ''
          + '' + obj.name + '   '
          + '
' + obj.tosdr.tldr + ' Discussion

';
      }
    }
  };
  xhr.send();
}
var topicObjects = {};
function getTopicObject(name, cb) {
  if (topicObjects[name]) {
    cb(topicObjects[name]);
  } else {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'topics/' + name + '.json', true);
    xhr.onreadystatechange = function () {
      if (xhr.readyState == 4) {
        if (xhr.status == 200) {
          var obj;
          try {
            obj = JSON.parse(xhr.responseText);
            topicObjects[name] = obj;
          } catch (e) {
            console.log(xhr.responseText);
            console.log(JSON.parse(xhr.responseText));
            alert('Could not load data for ' + name + ', sorry! Refreshing the page might sometimes help.');
          }
          if (obj) {
            cb(obj);
          }
        }
      }
    };
    xhr.send();
  }
}
function renderDetails(name, points) {
  console.log('renderDetails ' + name);
  console.log(points);
  getTopicObject(name, function (obj) {
    if (obj.id && obj.id) globalTopicsDictionary[obj.id] = obj.name;
    document.getElementById('jump-to').innerHTML += '
' + obj.name + '
 ';
    var header = '

' + obj.name + ' ' + (obj.subtitle || "") + '

';
    var rating;
    var ratingText = {
      0:"We haven't sufficiently reviewed the terms yet. Please contribute to our group.",
      "false":"We haven't sufficiently reviewed the terms yet. Please contribute to our group.",
      "A":"The terms of topic pay specific care towards the user and the operator of the topic follows the best practices.",
      "B":"The terms of topics are fair towards the user but they could be improved.",
      "C":"The terms of topic are okay but some issues need your consideration.",
      "D":"The terms of topic are very uneven or there are some important issues that need your attention.",
      "E":"We strongly discourage you from signing up to this topic. The terms of topic raise serious concerns."
    };
    // [FIXME] We don't need ratings for topics. But it would be useful if instead of the class we could display the description.
    if (!obj.tosdr) {
      obj.tosdr = {rated:false};
    }
    if (obj.tosdr.rated) {
      rating = '';
    } else {
      rating = '';
    }
    var description = '';
    if (obj.description) {
      description = '

' + obj.description;
    }
    var parent = '

';
    if (obj.parent) {
      parent = ' (Category: ' + obj.parent + ')

';
    }
    var issues = '

';
    for (var i = 0; i < points.length; i++) {
      issues += '

';
    }
    issues += '
';
    document.getElementById(name).innerHTML = header + description + parent + issues +
      '
';
    for (var i = 0; i < points.length; i++) {
      renderDataPoint(name, points[i]);
    }
    $('.skipToCategory').each(function () {
      $(this).text(nameFromId($(this).text()))
    });
  });
}
function go() {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'index/topics.json', true);
  xhr.onreadystatechange = function () {
    if (xhr.readyState == 4) {
      if (xhr.status == 200) {
        try {
          var topics = JSON.parse(xhr.responseText);
          console.log(topics);
          var last;
          for (var i in topics) {
            // document.getElementById('jump-to').innerHTML += ''+i+'; ';
          }
          if (last) {
            // document.getElementById('jump-to').innerHTML += ''+last+'. ';
          } else {
            last = i;
          }
          for (var i in topics) {
            if (last) {
              document.getElementById('topics-list').innerHTML += '

'
                + '

'
                + '
';
              renderDetails(last, topics[last]);
              renderDetails(i, topics[i]);
              last = undefined;
            } else {
              last = i;
            }
            document.getElementById('popups').innerHTML +=
              '

';
          }
          if (last) {
            document.getElementById('topics-list').innerHTML += '

';
            renderDetails(last, topics[i]);
          }
        } catch (e) {
        }
      }
    }
  };
  xhr.send();
}
<|endoftext|>


<commit_before>/**
 * Created by Tarek AlQaddy on 4/10/2017.
 */
$(document).ready(function () {
    $('#button-collapse').sideNav();
    $('#slick1').slick({
        dots: true,
        autoplay: true
    });
    $('#slick2').slick({
        dots: true,
        autoplay: true
    });
    $('#slick3').slick({
        dots: true,
        autoplay: true
    });
    var prog = $("#prog-title");
    var robo = $("#robotics-title");
    var auto = $("#auto-title");
    var options = [
        {
            selector: '#prog-title', offset: 300, callback: function () {
                prog.addClass("active");
            }
        },
        {
            selector: '#robotics-title', offset: 300, callback: function () {
                robo.addClass("active");
            }
        },
        {
            selector: '#auto-title', offset: 300, callback: function () {
                auto.addClass("active")
            }
        }
    ];

    Materialize.scrollFire(options);
});<commit_msg>increase tracks slider speed<commit_after>/**
 * Created by Tarek AlQaddy on 4/10/2017.
 */
$(document).ready(function () {
    $('#button-collapse').sideNav();
    $('#slick1').slick({
        dots: true,
        autoplay: true,
        autoplaySpeed: 6000
    });
    $('#slick2').slick({
        dots: true,
        autoplay: true,
        autoplaySpeed: 6000
    });
    $('#slick3').slick({
        dots: true,
        autoplay: true,
        autoplaySpeed: 6000
    });
    var prog = $("#prog-title");
    var robo = $("#robotics-title");
    var auto = $("#auto-title");
    var options = [
        {
            selector: '#prog-title', offset: 300, callback: function () {
                prog.addClass("active");
            }
        },
        {
            selector: '#robotics-title', offset: 300, callback: function () {
                robo.addClass("active");
            }
        },
        {
            selector: '#auto-title', offset: 300, callback: function () {
                auto.addClass("active")
            }
        }
    ];

    Materialize.scrollFire(options);
});<|endoftext|>


<commit_before>var Upvote = (function (window, document) {

	that = this;

	// endEvent = hasTouch ? 'touchend' : 'mouseup',

	Upvote = function (opts) {

		that = this;

		this.current_category = 'us';

		// ---------------------------------------------------------
		// Muench launch
		// ---------------------------------------------------------

		// Options from user
		for (i in opts) this.options[i] = opts[i];

		// ---------------------------------------------------------
		// Skimmin launch
		// ---------------------------------------------------------

        	$('.upvote-container').on('click', this.fn_tap_upvote.bind(this));
        	$('.category-container').on('click', this.fn_change_category.bind(this));

		window.addEventListener('load', function() {
		    FastClick.attach(document.body);
		}, false);

		this.fn_hide_rendering_icons();
		this.fn_loading();
       		this.fn_reveal_content();

    	};

	Upvote.prototype = {

		// ------------------------------------------------------
		// Skimmin Core Functions
		// ------------------------------------------------------

        	// primarily used to hide slow rendering
        	fn_loading: function() {

            	that = this;

            	$('#L').fadeIn(0);
            	$('#L').addClass('animated zoomIn');

            	setTimeout(function() {
            		$('#O').fadeIn(0);
            		$('#O').addClass('animated zoomIn');
            	}, 100);

            	setTimeout(function() {
            		$('#A').fadeIn(0);
            		$('#A').addClass('animated zoomIn');
            	}, 200);

            	setTimeout(function() {
            		$('#D').fadeIn(0);
            		$('#D').addClass('animated zoomIn');
            	}, 300);

            	setTimeout(function() {
            		$('#I').fadeIn(0);
            		$('#I').addClass('animated zoomIn');
            	}, 400);

            	setTimeout(function() {
            		$('#N').fadeIn(0);
            		$('#N').addClass('animated zoomIn');
            	}, 500);

            	setTimeout(function() {
            		$('#G').fadeIn(0);
            		$('#G').addClass('animated zoomIn');
            	}, 600);

            	int_loading_count = 0;
            	arr_colors = Array('rgba(52, 152, 219, 1)', 'rgba(255, 140, 0, 1)', 'rgba(231, 76, 60, 1)', 'rgba(0, 128, 0, .9)', 'rgba(0, 154, 136, .9)', 'rgba(164, 121, 228, 1)');

            	// bool_kill_next_loop = false;

        		// $('#loading-circle').addClass('animated pulse');

        	pulsing_circle_interval = setInterval(function() {

        			// $('#L').fadeOut(0);
        			// $('#L').addClass('zoomOut');
        			$('#L').css('opacity', '.7');

        			setTimeout(function() {
        				$('#L').css('opacity', '1');
        				$('#O').css('opacity', '.7');
        			}, 100);

        			setTimeout(function() {
        				$('#O').css('opacity', '1');
        				$('#A').css('opacity', '.7');
        			}, 200);

        			setTimeout(function() {
        				$('#A').css('opacity', '1');
        				$('#D').css('opacity', '.7');
        			}, 300);

        			setTimeout(function() {
        				$('#D').css('opacity', '1');
        				$('#I').css('opacity', '.7');
        			}, 400);

        			setTimeout(function() {
        				$('#I').css('opacity', '1');
        				$('#N').css('opacity', '.7');
        			}, 500);

        			setTimeout(function() {
        				$('#N').css('opacity', '1');
        				$('#G').css('opacity', '.7');
        			}, 600);

        			setTimeout(function() {
        				$('#G').css('opacity', '1');
        			}, 700);

        			// $('#loading-circle').css('background-color', arr_colors[int_loading_count]);
        			int_loading_count += 1;
        			if (int_loading_count == 4) {
        				clearInterval(pulsing_circle_interval);
        				setTimeout(function() {
        					$('#loading-container').addClass('animated slideOutUp');
        					$('#loading-container').fadeOut(300);
        				}, 500);
        				setTimeout(function() {
        					$('#content').fadeIn(300);
        					$('#content').addClass('animated slideInUp');
        				}, 750);
        			}

        			/*setTimeout(function() {
        				$('#loading-circle').css('opacity', '1');
        			}, 500);*/

        		}, 1000);

        	},

        	fn_reveal_content: function() {

        		/*setTimeout(function() {
        			$('#loading-circle').addClass('animated zoomOut');
        			$('#content').addClass('animated slideInUp');
        		}, 300);*/

        	},

        	fn_hide_rendering_icons: function() {

        		setTimeout(function() {
        			$('.rendering-container').addClass('display-none');
        		}, 3000);

        	},

        	fn_change_category: function(e) {

        		if (this.current_category == 'world') {
        			$('#category-container').removeClass('world')
        			$('#category-container').addClass('us');
        			$('#category-text').html('us');
        			this.current_category = 'us';
        		}

        		else if (this.current_category == 'us') {
        			$('#category-container').removeClass('us')
        			$('#category-container').addClass('sports');
        			$('#category-text').html('sports');
        			this.current_category = 'sports';
        		}

        		else if (this.current_category == 'sports') {
        			$('#category-container').removeClass('sports')
        			$('#category-container').addClass('business');
        			$('#category-text').html('business');
        			this.current_category = 'business';
        		}

        		else if (this.current_category == 'business') {
        			$('#category-container').removeClass('business')
        			$('#category-container').addClass('technology');
        			$('#category-text').html('technology');
        			this.current_category = 'technology';
        		}

        		else if (this.current_category == 'technology') {
        			$('#category-container').removeClass('technology')
        			$('#category-container').addClass('entertainment');
        			$('#category-text').html('entertainment');
        			this.current_category = 'entertainment';
        		}

        		else {
        			$('#category-container').removeClass('entertainment')
        			$('#category-container').addClass('world');
        			$('#category-text').html('world');
        			this.current_category = 'world';
        		}

        		if ($('.upvote-container').hasClass('upvoted') == true) {
        			$('.upvote-container').removeClass('us world sports business technology entertainment');
        			$('.upvote-text').removeClass('us world sports business technology entertainment');
        			$('.upvote-icon').removeClass('us world sports business technology entertainment');
        			$('.upvote-container').addClass(this.current_category);
        			$('.upvote-text').addClass(this.current_category);
        			$('.upvote-icon').addClass(this.current_category);
        		}

        	},

		fn_tap_upvote: function() {

			if ($('.upvote-container').hasClass('upvoted') == true) {

				$('.upvote-container').removeClass('upvoted');

				setTimeout(function() {
        				$('.upvote-container').removeClass('tapped us world sports business technology entertainment');
        				$('.upvote-text').removeClass('us world sports business technology entertainment');
        				$('.upvote-text').html(30);
        				$('.upvote-icon').removeClass('us world sports business technology entertainment');
        			}, 300);
        		}

			else {

				$('.upvote-container').addClass('upvoted');
    				setTimeout(function() {
        				$('.upvote-container').addClass('tapped ' + that.current_category);
        				$('.upvote-text').addClass(that.current_category);
        				$('.upvote-text').html(31);
        				$('.upvote-icon').addClass(that.current_category);
    				}, 300);
			}

		},

	};

	return Upvote;

})(window, document);
<commit_msg>Update upvote.js<commit_after>var Upvote = (function (window, document) {

	that = this;

	// endEvent = hasTouch ? 'touchend' : 'mouseup',

	Upvote = function (opts) {

		that = this;

		this.current_category = 'us';

		// ---------------------------------------------------------
		// Muench launch
		// ---------------------------------------------------------

		// Options from user
		for (i in opts) this.options[i] = opts[i];

		// ---------------------------------------------------------
		// Skimmin launch
		// ---------------------------------------------------------

        	$('.upvote-container').on('click', this.fn_tap_upvote.bind(this));
        	$('.category-container').on('click', this.fn_change_category.bind(this));

		window.addEventListener('load', function() {
		    FastClick.attach(document.body);
		}, false);

		this.fn_hide_rendering_icons();
		this.fn_loading();
       		this.fn_reveal_content();

    	};

	Upvote.prototype = {

		// ------------------------------------------------------
		// Skimmin Core Functions
		// ------------------------------------------------------

        	// primarily used to hide slow rendering
        	fn_loading: function() {

            	that = this;

            	$('#L').fadeIn(0);
            	$('#L').addClass('animated zoomIn');

            	setTimeout(function() {
            		$('#O').fadeIn(0);
            		$('#O').addClass('animated zoomIn');
            	}, 100);

            	setTimeout(function() {
            		$('#A').fadeIn(0);
            		$('#A').addClass('animated zoomIn');
            	}, 200);

            	setTimeout(function() {
            		$('#D').fadeIn(0);
            		$('#D').addClass('animated zoomIn');
            	}, 300);

            	setTimeout(function() {
            		$('#I').fadeIn(0);
            		$('#I').addClass('animated zoomIn');
            	}, 400);

            	setTimeout(function() {
            		$('#N').fadeIn(0);
            		$('#N').addClass('animated zoomIn');
            	}, 500);

            	setTimeout(function() {
            		$('#G').fadeIn(0);
            		$('#G').addClass('animated zoomIn');
            	}, 600);

            	int_loading_count = 0;
            	arr_colors = Array('rgba(52, 152, 219, 1)', 'rgba(255, 140, 0, 1)', 'rgba(231, 76, 60, 1)', 'rgba(0, 128, 0, .9)', 'rgba(0, 154, 136, .9)', 'rgba(164, 121, 228, 1)');

            	// bool_kill_next_loop = false;

        		// $('#loading-circle').addClass('animated pulse');

        	pulsing_circle_interval = setInterval(function() {

        			// $('#L').fadeOut(0);
        			// $('#L').addClass('zoomOut');
        			$('#L').css('opacity', '.5');

        			setTimeout(function() {
        				$('#L').css('opacity', '1');
        				$('#O').css('opacity', '.5');
        			}, 100);

        			setTimeout(function() {
        				$('#O').css('opacity', '1');
        				$('#A').css('opacity', '.5');
        			}, 200);

        			setTimeout(function() {
        				$('#A').css('opacity', '1');
        				$('#D').css('opacity', '.5');
        			}, 300);

        			setTimeout(function() {
        				$('#D').css('opacity', '1');
        				$('#I').css('opacity', '.5');
        			}, 400);

        			setTimeout(function() {
        				$('#I').css('opacity', '1');
        				$('#N').css('opacity', '.5');
        			}, 500);

        			setTimeout(function() {
        				$('#N').css('opacity', '1');
        				$('#G').css('opacity', '.5');
        			}, 600);

        			setTimeout(function() {
        				$('#G').css('opacity', '1');
        			}, 700);

        			// $('#loading-circle').css('background-color', arr_colors[int_loading_count]);
        			int_loading_count += 1;
        			if (int_loading_count == 4) {
        				clearInterval(pulsing_circle_interval);
        				setTimeout(function() {
        					$('#loading-container').addClass('animated slideOutUp');
        					$('#loading-container').fadeOut(300);
        				}, 500);
        				setTimeout(function() {
        					$('#content').fadeIn(300);
        					$('#content').addClass('animated slideInUp');
        				}, 750);
        			}

        			/*setTimeout(function() {
        				$('#loading-circle').css('opacity', '1');
        			}, 500);*/

        		}, 1000);

        	},

        	fn_reveal_content: function() {

        		/*setTimeout(function() {
        			$('#loading-circle').addClass('animated zoomOut');
        			$('#content').addClass('animated slideInUp');
        		}, 300);*/

        	},

        	fn_hide_rendering_icons: function() {

        		setTimeout(function() {
        			$('.rendering-container').addClass('display-none');
        		}, 3000);

        	},

        	fn_change_category: function(e) {

        		if (this.current_category == 'world') {
        			$('#category-container').removeClass('world')
        			$('#category-container').addClass('us');
        			$('#category-text').html('us');
        			this.current_category = 'us';
        		}

        		else if (this.current_category == 'us') {
        			$('#category-container').removeClass('us')
        			$('#category-container').addClass('sports');
        			$('#category-text').html('sports');
        			this.current_category = 'sports';
        		}

        		else if (this.current_category == 'sports') {
        			$('#category-container').removeClass('sports')
        			$('#category-container').addClass('business');
        			$('#category-text').html('business');
        			this.current_category = 'business';
        		}

        		else if (this.current_category == 'business') {
        			$('#category-container').removeClass('business')
        			$('#category-container').addClass('technology');
        			$('#category-text').html('technology');
        			this.current_category = 'technology';
        		}

        		else if (this.current_category == 'technology') {
        			$('#category-container').removeClass('technology')
        			$('#category-container').addClass('entertainment');
        			$('#category-text').html('entertainment');
        			this.current_category = 'entertainment';
        		}

        		else {
        			$('#category-container').removeClass('entertainment')
        			$('#category-container').addClass('world');
        			$('#category-text').html('world');
        			this.current_category = 'world';
        		}

        		if ($('.upvote-container').hasClass('upvoted') == true) {
        			$('.upvote-container').removeClass('us world sports business technology entertainment');
        			$('.upvote-text').removeClass('us world sports business technology entertainment');
        			$('.upvote-icon').removeClass('us world sports business technology entertainment');
        			$('.upvote-container').addClass(this.current_category);
        			$('.upvote-text').addClass(this.current_category);
        			$('.upvote-icon').addClass(this.current_category);
        		}

        	},

		fn_tap_upvote: function() {

			if ($('.upvote-container').hasClass('upvoted') == true) {

				$('.upvote-container').removeClass('upvoted');

				setTimeout(function() {
        				$('.upvote-container').removeClass('tapped us world sports business technology entertainment');
        				$('.upvote-text').removeClass('us world sports business technology entertainment');
        				$('.upvote-text').html(30);
        				$('.upvote-icon').removeClass('us world sports business technology entertainment');
        			}, 300);
        		}

			else {

				$('.upvote-container').addClass('upvoted');
    				setTimeout(function() {
        				$('.upvote-container').addClass('tapped ' + that.current_category);
        				$('.upvote-text').addClass(that.current_category);
        				$('.upvote-text').html(31);
        				$('.upvote-icon').addClass(that.current_category);
    				}, 300);
			}

		},

	};

	return Upvote;

})(window, document);
<|endoftext|>


<commit_before>var Upvote = (function (window, document) {

	that = this;

	// endEvent = hasTouch ? 'touchend' : 'mouseup',

	Upvote = function (opts) {

		that = this;

		this.current_category = 'us';

		// ---------------------------------------------------------
		// Muench launch
		// ---------------------------------------------------------

		// Options from user
		for (i in opts) this.options[i] = opts[i];

		// ---------------------------------------------------------
		// Skimmin launch
		// ---------------------------------------------------------

        	$('.upvote-container').on('click', this.fn_tap_upvote.bind(this));
        	$('.category-container').on('click', this.fn_change_category.bind(this));

		window.addEventListener('load', function() {
		    FastClick.attach(document.body);
		}, false);

		this.fn_hide_rendering_icons();
		this.fn_loading();
       		this.fn_reveal_content();

    	};

	Upvote.prototype = {

		// ------------------------------------------------------
		// Skimmin Core Functions
		// ------------------------------------------------------

        	// primarily used to hide slow rendering
        	fn_loading: function() {

            	that = this;

            	$('#L').fadeIn(0);
            	$('#L').addClass('animated zoomIn');

            	setTimeout(function() {
            		$('#O').fadeIn(0);
            		$('#O').addClass('animated zoomIn');
            	}, 75);

            	setTimeout(function() {
            		$('#A').fadeIn(0);
            		$('#A').addClass('animated zoomIn');
            	}, 150);

            	setTimeout(function() {
            		$('#D').fadeIn(0);
            		$('#D').addClass('animated zoomIn');
            	}, 225);

            	setTimeout(function() {
            		$('#I').fadeIn(0);
            		$('#I').addClass('animated zoomIn');
            	}, 300);

            	setTimeout(function() {
            		$('#N').fadeIn(0);
            		$('#N').addClass('animated zoomIn');
            	}, 375);

            	setTimeout(function() {
            		$('#G').fadeIn(0);
            		$('#G').addClass('animated zoomIn');
            	}, 450);

            	/*setTimeout(function() {
            		$('#loading-container').addClass('animated pulse');
            	}, 1500);*/

            	/*setTimeout(function() {
            		$('#L').removeClass('animated zoomIn');
            		$('#O').removeClass('animated zoomIn');
            		$('#A').removeClass('animated zoomIn');
            		$('#D').removeClass('animated zoomIn');
            		$('#I').removeClass('animated zoomIn');
            		$('#N').removeClass('animated zoomIn');
            		$('#G').removeClass('animated zoomIn');
            	}, 1500);*/

            	int_loading_count = 0;
            	arr_colors = Array('rgba(52, 152, 219, 1)', 'rgba(255, 140, 0, 1)', 'rgba(231, 76, 60, 1)', 'rgba(0, 128, 0, .9)', 'rgba(0, 154, 136, .9)', 'rgba(164, 121, 228, 1)');

            	// bool_kill_next_loop = false;

        		// $('#loading-circle').addClass('animated pulse');

        	pulsing_circle_interval = setInterval(function() {

        			$('#L').fadeOut(300);
        			$('#O').fadeOut(300);
        			$('#A').fadeOut(300);
        			$('#D').fadeOut(300);
        			$('#I').fadeOut(300);
        			$('#N').fadeOut(300);
        			$('#G').fadeOut(300);

        			setTimeout(function() {
        				$('#L').removeClass('animated zoomIn');
        				$('#O').removeClass('animated zoomIn');
        				$('#A').removeClass('animated zoomIn');
        				$('#D').removeClass('animated zoomIn');
        				$('#I').removeClass('animated zoomIn');
        				$('#N').removeClass('animated zoomIn');
        				$('#G').removeClass('animated zoomIn');
        			}, 300);

        			setTimeout(function(){
        				$('#L').addClass('animated zoomIn');
        				$('#O').addClass('animated zoomIn');
        				$('#A').addClass('animated zoomIn');
        				$('#D').addClass('animated zoomIn');
        				$('#I').addClass('animated zoomIn');
        				$('#N').addClass('animated zoomIn');
        				$('#G').addClass('animated zoomIn');
        			}, 350);

        			/*if (int_loading_count == 0 || int_loading_count == 2 || int_loading_count == 4 || int_loading_count == 6 || int_loading_count == 8) {
        				$('#L').css('opacity', '0');
        				$('#O').css('opacity', '0');
        				$('#A').css('opacity', '0');
        				$('#D').css('opacity', '0');
        				$('#I').css('opacity', '0');
        				$('#N').css('opacity', '0');
        				$('#G').css('opacity', '0');
        			}
        			else {
        				$('#L').css('opacity', '1');
        				$('#O').css('opacity', '1');
        				$('#A').css('opacity', '1');
        				$('#D').css('opacity', '1');
        				$('#I').css('opacity', '1');
        				$('#N').css('opacity', '1');
        				$('#G').css('opacity', '1');
        			}*/

        			// $('#L').addClass('zoomOut');
        			/*$('#L').css('opacity', '.7');

        			setTimeout(function() {
        				// $('#O').addClass('zoomOut');
        				$('#L').css('opacity', '1');
        				$('#O').css('opacity', '.7');
        			}, 75);

        			setTimeout(function() {
        				$('#O').css('opacity', '1');
        				$('#A').css('opacity', '.7');
        			}, 150);

        			setTimeout(function() {
        				$('#A').css('opacity', '1');
        				$('#D').css('opacity', '.7');
        			}, 225);

        			setTimeout(function() {
        				$('#D').css('opacity', '1');
        				$('#I').css('opacity', '.7');
        			}, 300);

        			setTimeout(function() {
        				$('#I').css('opacity', '1');
        				$('#N').css('opacity', '.7');
        			}, 375);

        			setTimeout(function() {
        				$('#N').css('opacity', '1');
        				$('#G').css('opacity', '.7');
        			}, 450);*/

        			// $('#loading-circle').css('background-color', arr_colors[int_loading_count]);
        			int_loading_count += 1;
        			if (int_loading_count == 8) {
        				clearInterval(pulsing_circle_interval);
        				setTimeout(function() {
        					$('#loading-container').addClass('animated slideOutUp');
        					$('#loading-container').fadeOut(300);
        				}, 500);
        				setTimeout(function() {
        					$('#content').fadeIn(300);
        					$('#content').addClass('animated slideInUp');
        				}, 750);
        			}

        			/*setTimeout(function() {
        				$('#loading-circle').css('opacity', '1');
        			}, 500);*/

        		}, 1500);

        	},

        	fn_reveal_content: function() {

        		/*setTimeout(function() {
        			$('#loading-circle').addClass('animated zoomOut');
        			$('#content').addClass('animated slideInUp');
        		}, 300);*/

        	},

        	fn_hide_rendering_icons: function() {

        		setTimeout(function() {
        			$('.rendering-container').addClass('display-none');
        		}, 3000);

        	},

        	fn_change_category: function(e) {

        		if (this.current_category == 'world') {
        			$('#category-container').removeClass('world')
        			$('#category-container').addClass('us');
        			$('#category-text').html('us');
        			this.current_category = 'us';
        		}

        		else if (this.current_category == 'us') {
        			$('#category-container').removeClass('us')
        			$('#category-container').addClass('sports');
        			$('#category-text').html('sports');
        			this.current_category = 'sports';
        		}

        		else if (this.current_category == 'sports') {
        			$('#category-container').removeClass('sports')
        			$('#category-container').addClass('business');
        			$('#category-text').html('business');
        			this.current_category = 'business';
        		}

        		else if (this.current_category == 'business') {
        			$('#category-container').removeClass('business')
        			$('#category-container').addClass('technology');
        			$('#category-text').html('technology');
        			this.current_category = 'technology';
        		}

        		else if (this.current_category == 'technology') {
        			$('#category-container').removeClass('technology')
        			$('#category-container').addClass('entertainment');
        			$('#category-text').html('entertainment');
        			this.current_category = 'entertainment';
        		}

        		else {
        			$('#category-container').removeClass('entertainment')
        			$('#category-container').addClass('world');
        			$('#category-text').html('world');
        			this.current_category = 'world';
        		}

        		if ($('.upvote-container').hasClass('upvoted') == true) {
        			$('.upvote-container').removeClass('us world sports business technology entertainment');
        			$('.upvote-text').removeClass('us world sports business technology entertainment');
        			$('.upvote-icon').removeClass('us world sports business technology entertainment');
        			$('.upvote-container').addClass(this.current_category);
        			$('.upvote-text').addClass(this.current_category);
        			$('.upvote-icon').addClass(this.current_category);
        		}

        	},

		fn_tap_upvote: function() {

			if ($('.upvote-container').hasClass('upvoted') == true) {

				$('.upvote-container').removeClass('upvoted');

				setTimeout(function() {
        				$('.upvote-container').removeClass('tapped us world sports business technology entertainment');
        				$('.upvote-text').removeClass('us world sports business technology entertainment');
        				$('.upvote-text').html(30);
        				$('.upvote-icon').removeClass('us world sports business technology entertainment');
        			}, 300);
        		}

			else {

				$('.upvote-container').addClass('upvoted');
    				setTimeout(function() {
        				$('.upvote-container').addClass('tapped ' + that.current_category);
        				$('.upvote-text').addClass(that.current_category);
        				$('.upvote-text').html(31);
        				$('.upvote-icon').addClass(that.current_category);
    				}, 300);
			}

		},

	};

	return Upvote;

})(window, document);
<commit_msg>Update upvote.js<commit_after>var Upvote = (function (window, document) {

	that = this;

	// endEvent = hasTouch ? 'touchend' : 'mouseup',

	Upvote = function (opts) {

		that = this;

		this.current_category = 'us';

		// ---------------------------------------------------------
		// Muench launch
		// ---------------------------------------------------------

		// Options from user
		for (i in opts) this.options[i] = opts[i];

		// ---------------------------------------------------------
		// Skimmin launch
		// ---------------------------------------------------------

        	$('.upvote-container').on('click', this.fn_tap_upvote.bind(this));
        	$('.category-container').on('click', this.fn_change_category.bind(this));

		window.addEventListener('load', function() {
		    FastClick.attach(document.body);
		}, false);

		this.fn_hide_rendering_icons();
		this.fn_loading();
       		this.fn_reveal_content();

    	};

	Upvote.prototype = {

		// ------------------------------------------------------
		// Skimmin Core Functions
		// ------------------------------------------------------

        	// primarily used to hide slow rendering
        	fn_loading: function() {

            	that = this;

            	$('#L').fadeIn(0);
            	$('#L').addClass('animated zoomIn');

            	setTimeout(function() {
            		$('#O').fadeIn(0);
            		$('#O').addClass('animated zoomIn');
            	}, 75);

            	setTimeout(function() {
            		$('#A').fadeIn(0);
            		$('#A').addClass('animated zoomIn');
            	}, 150);

            	setTimeout(function() {
            		$('#D').fadeIn(0);
            		$('#D').addClass('animated zoomIn');
            	}, 225);

            	setTimeout(function() {
            		$('#I').fadeIn(0);
            		$('#I').addClass('animated zoomIn');
            	}, 300);

            	setTimeout(function() {
            		$('#N').fadeIn(0);
            		$('#N').addClass('animated zoomIn');
            	}, 375);

            	setTimeout(function() {
            		$('#G').fadeIn(0);
            		$('#G').addClass('animated zoomIn');
            	}, 450);

            	/*setTimeout(function() {
            		$('#loading-container').addClass('animated pulse');
            	}, 1500);*/

            	/*setTimeout(function() {
            		$('#L').removeClass('animated zoomIn');
            		$('#O').removeClass('animated zoomIn');
            		$('#A').removeClass('animated zoomIn');
            		$('#D').removeClass('animated zoomIn');
            		$('#I').removeClass('animated zoomIn');
            		$('#N').removeClass('animated zoomIn');
            		$('#G').removeClass('animated zoomIn');
            	}, 1500);*/

            	int_loading_count = 0;
            	arr_colors = Array('rgba(52, 152, 219, 1)', 'rgba(255, 140, 0, 1)', 'rgba(231, 76, 60, 1)', 'rgba(0, 128, 0, .9)', 'rgba(0, 154, 136, .9)', 'rgba(164, 121, 228, 1)');

            	// bool_kill_next_loop = false;

        		// $('#loading-circle').addClass('animated pulse');

        	pulsing_circle_interval = setInterval(function() {

        			/*$('#L').fadeOut(300);
        			$('#O').fadeOut(300);
        			$('#A').fadeOut(300);
        			$('#D').fadeOut(300);
        			$('#I').fadeOut(300);
        			$('#N').fadeOut(300);
        			$('#G').fadeOut(300);*/

        			if (int_loading_count == 0 || int_loading_count == 2 || int_loading_count == 4 || int_loading_count == 6) {

        				$('#L').fadeIn(0);
            				$('#L').addClass('animated zoomIn');

            				setTimeout(function() {
            					$('#O').fadeIn(0);
            					$('#O').addClass('animated zoomIn');
            				}, 75);

            				setTimeout(function() {
            					$('#A').fadeIn(0);
            					$('#A').addClass('animated zoomIn');
            				}, 150);

            				setTimeout(function() {
            					$('#D').fadeIn(0);
            					$('#D').addClass('animated zoomIn');
            				}, 225);

            				setTimeout(function() {
            					$('#I').fadeIn(0);
            					$('#I').addClass('animated zoomIn');
            				}, 300);

            				setTimeout(function() {
            					$('#N').fadeIn(0);
            					$('#N').addClass('animated zoomIn');
            				}, 375);

            				setTimeout(function() {
            					$('#G').fadeIn(0);
            					$('#G').addClass('animated zoomIn');
            				}, 450);

        				setTimeout(function() {
        					$('#L').removeClass('animated zoomIn');
        					$('#O').removeClass('animated zoomIn');
        					$('#A').removeClass('animated zoomIn');
        					$('#D').removeClass('animated zoomIn');
        					$('#I').removeClass('animated zoomIn');
        					$('#N').removeClass('animated zoomIn');
        					$('#G').removeClass('animated zoomIn');
        				}, 1000);

        				setTimeout(function(){
        					$('#L').addClass('animated zoomOut');
        					$('#O').addClass('animated zoomOut');
        					$('#A').addClass('animated zoomOut');
        					$('#D').addClass('animated zoomOut');
        					$('#I').addClass('animated zoomOut');
        					$('#N').addClass('animated zoomOut');
        					$('#G').addClass('animated zoomOut');
        				}, 1700);

        			/*if (int_loading_count == 0 || int_loading_count == 2 || int_loading_count == 4 || int_loading_count == 6 || int_loading_count == 8) {
        				$('#L').css('opacity', '0');
        				$('#O').css('opacity', '0');
        				$('#A').css('opacity', '0');
        				$('#D').css('opacity', '0');
        				$('#I').css('opacity', '0');
        				$('#N').css('opacity', '0');
        				$('#G').css('opacity', '0');
        			}
        			else {
        				$('#L').css('opacity', '1');
        				$('#O').css('opacity', '1');
        				$('#A').css('opacity', '1');
        				$('#D').css('opacity', '1');
        				$('#I').css('opacity', '1');
        				$('#N').css('opacity', '1');
        				$('#G').css('opacity', '1');
        			}*/

        			// $('#L').addClass('zoomOut');
        			/*$('#L').css('opacity', '.7');

        			setTimeout(function() {
        				// $('#O').addClass('zoomOut');
        				$('#L').css('opacity', '1');
        				$('#O').css('opacity', '.7');
        			}, 75);

        			setTimeout(function() {
        				$('#O').css('opacity', '1');
        				$('#A').css('opacity', '.7');
        			}, 150);

        			setTimeout(function() {
        				$('#A').css('opacity', '1');
        				$('#D').css('opacity', '.7');
        			}, 225);

        			setTimeout(function() {
        				$('#D').css('opacity', '1');
        				$('#I').css('opacity', '.7');
        			}, 300);

        			setTimeout(function() {
        				$('#I').css('opacity', '1');
        				$('#N').css('opacity', '.7');
        			}, 375);

        			setTimeout(function() {
        				$('#N').css('opacity', '1');
        				$('#G').css('opacity', '.7');
        			}, 450);*/

        			// $('#loading-circle').css('background-color', arr_colors[int_loading_count]);
        			int_loading_count += 1;
        			if (int_loading_count == 8) {
        				clearInterval(pulsing_circle_interval);
        				setTimeout(function() {
        					$('#loading-container').addClass('animated slideOutUp');
        					$('#loading-container').fadeOut(300);
        				}, 500);
        				setTimeout(function() {
        					$('#content').fadeIn(300);
        					$('#content').addClass('animated slideInUp');
        				}, 750);
        			}

        			/*setTimeout(function() {
        				$('#loading-circle').css('opacity', '1');
        			}, 500);*/

        		}, 1800);

        	},

        	fn_reveal_content: function() {

        		/*setTimeout(function() {
        			$('#loading-circle').addClass('animated zoomOut');
        			$('#content').addClass('animated slideInUp');
        		}, 300);*/

        	},

        	fn_hide_rendering_icons: function() {

        		setTimeout(function() {
        			$('.rendering-container').addClass('display-none');
        		}, 3000);

        	},

        	fn_change_category: function(e) {

        		if (this.current_category == 'world') {
        			$('#category-container').removeClass('world')
        			$('#category-container').addClass('us');
        			$('#category-text').html('us');
        			this.current_category = 'us';
        		}

        		else if (this.current_category == 'us') {
        			$('#category-container').removeClass('us')
        			$('#category-container').addClass('sports');
        			$('#category-text').html('sports');
        			this.current_category = 'sports';
        		}

        		else if (this.current_category == 'sports') {
        			$('#category-container').removeClass('sports')
        			$('#category-container').addClass('business');
        			$('#category-text').html('business');
        			this.current_category = 'business';
        		}

        		else if (this.current_category == 'business') {
        			$('#category-container').removeClass('business')
        			$('#category-container').addClass('technology');
        			$('#category-text').html('technology');
        			this.current_category = 'technology';
        		}

        		else if (this.current_category == 'technology') {
        			$('#category-container').removeClass('technology')
        			$('#category-container').addClass('entertainment');
        			$('#category-text').html('entertainment');
        			this.current_category = 'entertainment';
        		}

        		else {
        			$('#category-container').removeClass('entertainment')
        			$('#category-container').addClass('world');
        			$('#category-text').html('world');
        			this.current_category = 'world';
        		}

        		if ($('.upvote-container').hasClass('upvoted') == true) {
        			$('.upvote-container').removeClass('us world sports business technology entertainment');
        			$('.upvote-text').removeClass('us world sports business technology entertainment');
        			$('.upvote-icon').removeClass('us world sports business technology entertainment');
        			$('.upvote-container').addClass(this.current_category);
        			$('.upvote-text').addClass(this.current_category);
        			$('.upvote-icon').addClass(this.current_category);
        		}

        	},

		fn_tap_upvote: function() {

			if ($('.upvote-container').hasClass('upvoted') == true) {

				$('.upvote-container').removeClass('upvoted');

				setTimeout(function() {
        				$('.upvote-container').removeClass('tapped us world sports business technology entertainment');
        				$('.upvote-text').removeClass('us world sports business technology entertainment');
        				$('.upvote-text').html(30);
        				$('.upvote-icon').removeClass('us world sports business technology entertainment');
        			}, 300);
        		}

			else {

				$('.upvote-container').addClass('upvoted');
    				setTimeout(function() {
        				$('.upvote-container').addClass('tapped ' + that.current_category);
        				$('.upvote-text').addClass(that.current_category);
        				$('.upvote-text').html(31);
        				$('.upvote-icon').addClass(that.current_category);
    				}, 300);
			}

		},

	};

	return Upvote;

})(window, document);
<|endoftext|>


<commit_before>var sfs;
var config = {};
var roomid = "MainLobby#_@LocalVoip#_@0655795e-9916-4cfc-be1e-81f544d1d7cb#_@public";
var startTime = 0;
var sampleSize = 256;
var userid="1";

var audioCtx = new AudioContext();

navigator.getUserMedia = (
	navigator.getUserMedia ||
	navigator.webkitGetUserMedia ||
	navigator.mozGetUserMedia ||
	navigator.msGetUserMedia
);

// This is a port directly from the USpeak C# source code
function MuLawDecode( mulaw )
{
	var BIAS = 0x84;
	mulaw = ~mulaw;
	var sign = mulaw & 0x80;
	var exponent = ( mulaw & 0x70 ) >> 4;
	var data = mulaw & 0x0F;
	data = data | 0x10;
	data = data << 1;
	data = data + 1;
	data = data << (exponent + 2);
	data = data - BIAS;
	if( sign == 0 )
		return data;
	else
		return -data;
}

function MuLawEncode( /* int */ pcm )
{
	var BIAS = 0x84;
	var MAX = 32635;

	var sign = ( pcm & 0x8000 ) >> 8;
	if( sign != 0 )
		pcm = -pcm;
	if( pcm > MAX )
		pcm = MAX;
	pcm += BIAS;
	var exponent = 7;
	for( expMask = 0x4000; ( pcm & expMask ) == 0; exponent--, expMask >>= 1 )
	{
	}
	var mantissa = ( pcm >> ( exponent + 3 ) ) & 0x0f;
	var mulaw = ( sign | exponent << 4 | mantissa );
	return ~mulaw;
}

function playPCMclip( buffer )
{
	var sampleRate = 8000;
	var audioBuffer = audioCtx.createBuffer(1, buffer.length, sampleRate);
	var source = audioCtx.createBufferSource();
	audioBuffer.getChannelData(0).set(buffer);
	source.buffer = audioBuffer;
	source.connect(audioCtx.destination);
	var delay = 0.1;
	if( startTime == 0 || audioCtx.currentTime > startTime )
	{
		document.getElementById("speaker").style.backgroundColor = "gray";
		startTime = audioCtx.currentTime + delay;
	}
	setTimeout(function() { document.getElementById("speaker").style.backgroundColor = "green"; }, delay*1000);
	source.start(startTime);
	startTime = startTime + audioBuffer.duration;
	setTimeout(function() { document.getElementById("speaker").style.backgroundColor = "gray"; }, (delay+audioBuffer.duration)*1000);
}

function playMuLawClip( data )
{
	var vcdata = new Uint8Array(data.length);
	for( i=0; i<data.length; i++ )
	{
		vcdata[i] = data[i];
	}
	var offset = 0;
	while( offset < vcdata.length )
	{
		var len = vcdata[offset];

		var frame = new Int16Array(len);
		for( i=0; i < frame.length; i++ )
		{
			frame[i] = MuLawDecode(vcdata[offset+i+6]);
		}
		offset = offset+i+6;
		var buffer = new Float32Array(frame.length);
		var divisor = 3267;
		for( i=0; i < frame.length; i++ )
		{
			buffer[i] = frame[i]/divisor;
		}
		playPCMclip(buffer);
	}
}

// SFS handler for connection event
function onConnection(evtParams)
{
	if (evtParams.success)
	{
		console.log("Connected to SmartFoxServer 2X!");
		sfs.send(new SFS2X.Requests.System.LoginRequest("","",config.zone));
	}
	else
		console.log("Connection failed. Is the server running at all?");
}

// SFS handler for connection lost event
function onConnectionLost( evt )
{
	alert("Connection Lost!");
}

// SFS handler for login event
function onLogin( evt )
{
	console.log("Logged In!");
	sfs.send( new SFS2X.Requests.System.JoinRoomRequest(roomid));
}

// SFS handler for login error event
function onLoginError( evt )
{
	alert("Login Error!");
}

// SFS handler for room join event
function onRoomJoin( evt )
{
	console.log("Room Joined!");
	document.getElementById("connect").innerHTML = "Joined Room: '"+roomid+"'";
}

// SFS handler for room join error event
function onRoomJoinError( evt )
{
	alert("Room Not Joined");
}

// SFS handler for Extension Response event
function onExtensionResponse( evt )
{
	setTimeout(function() { document.getElementById("speaker").style.backgroundColor = "green"; }, startTime);
	var requestType = evt.cmd;
	if( requestType == "VoipVCRequest" )
	{
		var params = evt.params;
		if( true ) // params["ui"] != userid )
		{
			var data = params["VCData"];
			console.log(data);
			playMuLawClip(data);
		}
	}
}

// initialization function for this code, used in onload() in the HTML
function connect( host, port, zone, voipRoom )
{
	roomid = voipRoom;
	// Create configuration object
	config.host = host;
	config.port = parseInt(port);
	config.useSSL = false;
	config.zone = zone;
	config.debug = false;

	// Create SmartFox client instance
	sfs = new SmartFox(config);

	// Register for events and assign callbacks
	sfs.addEventListener(SFS2X.SFSEvent.CONNECTION, onConnection, this);
	sfs.addEventListener(SFS2X.SFSEvent.CONNECTION_LOST, onConnectionLost, this);
	sfs.addEventListener(SFS2X.SFSEvent.LOGIN_ERROR, onLoginError, this);
	sfs.addEventListener(SFS2X.SFSEvent.LOGIN, onLogin, this);
//	sfs.addEventListener(SFS2X.SFSEvent.LOGOUT, onLogout, this);
	sfs.addEventListener(SFS2X.SFSEvent.ROOM_JOIN_ERROR, onRoomJoinError, this);
	sfs.addEventListener(SFS2X.SFSEvent.ROOM_JOIN, onRoomJoin, this);
	sfs.addEventListener(SFS2X.SFSEvent.EXTENSION_RESPONSE, onExtensionResponse, this);

	// connect to SFS
	sfs.connect(config.host, config.port );
}

function sendAudio( floats )
{
	var data = new Uint8Array(floats.length+6);
	data[0] = sampleSize-1;
	data[1] = 0;
	data[2] = 0;
	data[3] = 0;
	data[4] = 0;
	data[5] = 0;
	for( i=0; i<floats.length; i++ )
	{
		data[i+6] = MuLawEncode(Math.round(floats[i]*3267));
	}
	var params = {};
	params["ui"] = userid;
	params["VCData"] = data;
	sfs.send(new SFS2X.Requests.System.ExtensionRequest("VoipVCRequest", params));
}

function setupAudioNode( stream )
{
	sourceNode = audioContext.createMediaStreamSource(stream);
	javascriptNode = audioContext.createScriptProcessor(sampleSize, 1, 1);
	javascriptNode.onaudioprocess = function(e)
	{
		sendAudio( new Float32Array(e.inputBuffer.getChannelData(0)));
	}
	sourceNode.connect(javascriptNode);
	javascriptNode.connect(audioContext.destination);
}

function onAudioError(e)
{
	console.log(e);
	alert(e);
}

function initializeMic()
{
	try
	{
		audioContext = new AudioContext();
	}
	catch(e)
	{
		alert('Web Audio API is not supported in this browser');
	}

	try
	{
		navigator.getUserMedia(
			{ video: false, audio: true},
			setupAudioNode,
			onAudioError
		);
	}
	catch (e)
	{
		alert('webkitGetUserMedia threw exception :' + e);
	}
}

function init()
{
	var host = document.getElementById("host").value;
	var port = document.getElementById("port").value;
	var zone = document.getElementById("zone").value;
	var room = document.getElementById("room").value;
	console.log(host, port, zone, room);
	connect(host, port, zone, room);

	initializeMic();
}

<commit_msg>Added a function to downsample the voice recording from firefox being 44100 while uSpeak is transmitting at 8000.<commit_after>var sfs;
var config = {};
var roomid = "MainLobby#_@LocalVoip#_@2ddfec51-80c5-4f47-9803-629d951d949d#_@public";
var startTime = 0;
var sampleSize = 256;
var userid="1";

var audioCtx = new AudioContext();

var sendingAudio = false;

navigator.getUserMedia = (
	navigator.getUserMedia ||
	navigator.webkitGetUserMedia ||
	navigator.mozGetUserMedia ||
	navigator.msGetUserMedia
);

function downsample( buffer, sampleRate, outSampleRate)
{
	if (outSampleRate == sampleRate)
	{
		return buffer;
	}
	if (outSampleRate > sampleRate)
	{
		throw "downsampling rate shall be smaller than original sample rate";
	}
	var sampleRateRatio = sampleRate / outSampleRate;
	var newLength = Math.round(buffer.length / sampleRateRatio);
	var result = new Float32Array(newLength);
	var offsetResult = 0;
	var offsetBuffer = 0;
	while (offsetResult < result.length)
	{
		var nextOffsetBuffer = Math.round((offsetResult + 1) * sampleRateRatio);
		var accum = 0, count = 0;
		for (var i = offsetBuffer; i < nextOffsetBuffer && i < buffer.length; i++)
		{
			accum += buffer[i];
			count++;
		}
		result[offsetResult] = accum/count;
		offsetResult++;
		offsetBuffer = nextOffsetBuffer;
	}
	return result;
}

// This is a port directly from the USpeak C# source code
function MuLawDecode( mulaw )
{
	var BIAS = 0x84;
	mulaw = ~mulaw;
	var sign = mulaw & 0x80;
	var exponent = ( mulaw & 0x70 ) >> 4;
	var data = mulaw & 0x0F;
	data = data | 0x10;
	data = data << 1;
	data = data + 1;
	data = data << (exponent + 2);
	data = data - BIAS;
	if( sign == 0 )
		return data;
	else
		return -data;
}

function MuLawEncode( pcm )
{
	var BIAS = 0x84;
	var MAX = 32635;

	var sign = ( pcm & 0x8000 ) >> 8;
	if( sign != 0 )
		pcm = -pcm;
	if( pcm > MAX )
		pcm = MAX;
	pcm += BIAS;
	var exponent = 7;
	for( expMask = 0x4000; ( pcm & expMask ) == 0; exponent--, expMask >>= 1 )
	{
	}
	var mantissa = ( pcm >> ( exponent + 3 ) ) & 0x0f;
	var mulaw = ( sign | exponent << 4 | mantissa );
	return ~mulaw;
}

function playPCMclip( buffer )
{
	var sampleRate = 8000;
	var audioBuffer = audioCtx.createBuffer(1, buffer.length, sampleRate);
	var source = audioCtx.createBufferSource();
	audioBuffer.getChannelData(0).set(buffer);
	source.buffer = audioBuffer;
	source.connect(audioCtx.destination);
	var delay = 5.0;
	if( startTime == 0 || audioCtx.currentTime > startTime )
	{
		document.getElementById("speaker").style.backgroundColor = "gray";
		startTime = audioCtx.currentTime + delay;
	}
	setTimeout(function() { document.getElementById("speaker").style.backgroundColor = "green"; }, delay*1000);
	source.start(startTime);
	startTime = startTime + audioBuffer.duration;
	setTimeout(function() { document.getElementById("speaker").style.backgroundColor = "gray"; }, (delay+audioBuffer.duration)*1000);
}

function playMuLawClip( vcdata )
{
	var offset = 0;
	while( offset < vcdata.length )
	{
		var len = vcdata[offset];
		var frame = new Int16Array(len);
		for( i=0; i < frame.length; i++ )
		{
			frame[i] = MuLawDecode(vcdata[offset+i+6]);
		}
		offset = offset+i+6;
		var buffer = int16ToFloat32( frame );
		playPCMclip(buffer);
	}
}

// SFS handler for connection event
function onConnection(evtParams)
{
	if (evtParams.success)
	{
		console.log("Connected to SmartFoxServer 2X!");
		sfs.send(new SFS2X.Requests.System.LoginRequest("","",config.zone));
	}
	else
		console.log("Connection failed. Is the server running at all?");
}

// SFS handler for connection lost event
function onConnectionLost( evt )
{
	alert("Connection Lost!");
}

// SFS handler for login event
function onLogin( evt )
{
	console.log("Logged In!");
	sfs.send( new SFS2X.Requests.System.JoinRoomRequest(roomid));
}

// SFS handler for login error event
function onLoginError( evt )
{
	alert("Login Error!");
}

// SFS handler for room join event
function onRoomJoin( evt )
{
	console.log("Room Joined!");
	document.getElementById("connect").innerHTML = "Joined Room: '"+roomid+"'";
}

// SFS handler for room join error event
function onRoomJoinError( evt )
{
	alert("Room Not Joined");
}

// SFS handler for Extension Response event
function onExtensionResponse( evt )
{
	var requestType = evt.cmd;
	if( requestType == "VoipVCRequest" )
	{
		var params = evt.params;
		if( true ) // params["ui"] != userid )
		{
			vcdata = params["VCData"].getSFSArray();
			playMuLawClip(vcdata);
		}
	}
}

// initialization function for this code, used in onload() in the HTML
function connect( host, port, zone, voipRoom )
{
	roomid = voipRoom;
	// Create configuration object
	config.host = host;
	config.port = parseInt(port);
	config.useSSL = false;
	config.zone = zone;
	config.debug = false;

	// Create SmartFox client instance
	sfs = new SmartFox(config);

	// Register for events and assign callbacks
	sfs.addEventListener(SFS2X.SFSEvent.CONNECTION, onConnection, this);
	sfs.addEventListener(SFS2X.SFSEvent.CONNECTION_LOST, onConnectionLost, this);
	sfs.addEventListener(SFS2X.SFSEvent.LOGIN_ERROR, onLoginError, this);
	sfs.addEventListener(SFS2X.SFSEvent.LOGIN, onLogin, this);
//	sfs.addEventListener(SFS2X.SFSEvent.LOGOUT, onLogout, this);
	sfs.addEventListener(SFS2X.SFSEvent.ROOM_JOIN_ERROR, onRoomJoinError, this);
	sfs.addEventListener(SFS2X.SFSEvent.ROOM_JOIN, onRoomJoin, this);
	sfs.addEventListener(SFS2X.SFSEvent.EXTENSION_RESPONSE, onExtensionResponse, this);

	// connect to SFS
	sfs.connect(config.host, config.port );
}
// adapted from http://stackoverflow.com/questions/35234551/javascript-converting-from-int16-to-float32
function float32ToInt16(inputArray)
{
	var output = new Int16Array(inputArray.length);
	for (var i = 0; i < inputArray.length; i++)
	{
		var s = Math.max(-1, Math.min(1, inputArray[i]));
		output[i] = s < 0 ? s * 0x8000 : s * 0x7FFF;
	}
	return output;
}

// adapted from http://stackoverflow.com/questions/35234551/javascript-converting-from-int16-to-float32
function int16ToFloat32(inputArray)
{
	var output = new Float32Array(inputArray.length);
	for (var i = 0; i < inputArray.length; i++)
	{
		var int = inputArray[i];
		// If the high bit is on, then it is a negative number, and actually counts backwards.
		var float = (int >= 0x8000) ? -(0x10000 - int) / 0x8000 : int / 0x7FFF;
		output[i] = float;
	}
	return output;
}

function sendAudio( floats )
{
	if( sendingAudio == true )
	{
		var resampled = downsample(floats, 44100, 8000);
		//console.log("resampled");
		//console.log(resampled);
		var ints = float32ToInt16(resampled);
		var encoded = new Int16Array(ints.length);
		for( i=0; i<ints.length; i++ )
			encoded[i] = MuLawEncode(ints[i]);
		var data = new Int16Array(ints.length+6);
		data[0] = ints.length;
		for( var i=1; i<6; i++ )
			data[i] = 0;
		for( i=0; i<floats.length; i++ )
		{
			data[i+6] = encoded[i];
		}
		//console.log("sendAudio");
		//console.log(data);
		//playMuLawClip(data);
		var params = {};
		params["ui"] = userid;
		params["VCData"] = data;
		sfs.send(new SFS2X.Requests.System.ExtensionRequest("VoipVCRequest", params));
	}
}

function setupAudioNode( stream )
{
	sourceNode = audioContext.createMediaStreamSource(stream);
	javascriptNode = audioContext.createScriptProcessor(sampleSize, 1, 1);
	javascriptNode.onaudioprocess = function(e)
	{
		sendAudio( new Float32Array(e.inputBuffer.getChannelData(0)) );
	}
	sourceNode.connect(javascriptNode);
	javascriptNode.connect(audioContext.destination);
}

function onAudioError(e)
{
	console.log(e);
	alert(e);
}

function initializeMic()
{
	try
	{
		audioContext = new AudioContext();
	}
	catch(e)
	{
		alert('Web Audio API is not supported in this browser');
	}

	try
	{
		navigator.getUserMedia(
			{ video: false, audio: true},
			setupAudioNode,
			onAudioError
		);
	}
	catch (e)
	{
		alert('webkitGetUserMedia threw exception :' + e);
	}
}

function talk()
{
	sendingAudio = true;
}

function stopTalking()
{
	sendingAudio = false;
}

function init()
{
	var host = document.getElementById("host").value;
	var port = document.getElementById("port").value;
	var zone = document.getElementById("zone").value;
	var room = document.getElementById("room").value;
	console.log(host, port, zone, room);
	connect(host, port, zone, room);

	initializeMic();
}

<|endoftext|>