<commit_before>/*

This is a custom js for the TutorStudy website.

By: Ryan Ngo

*/

/* General Get Functions for data loading */
function getMajors(){
    //note: needed 2 different methods because select2 does not allow multiple dropdown parents
    $.ajax({
        type: "GET",
        dataType: "json",
        url: "http://52.38.218.199/TutorStudyServlet/GetMajors",
        success:function(data){
            $("#studentMajorSelect").select2({
                data :  $.map(data, function(data){
                            return{
                                id: data.id,
                                text: data.major
                            }
                        }),
                dropdownParent:$("#registerModal"),
                createTag: function(){
                    return null;
                }

            });
            $("#tutorMajorSelect").select2({
                data :  $.map(data, function(data){
                            return{
                                id: data.id,
                                text: data.major
                            }
                        }),
                dropdownParent:$("#registerModal"),
                createTag: function(){
                    return null;
                }
            });
        }
    })
}
/* End General Get Functions */

/* General Load Functions */
/* End General Load Functions */

/*Form Functions*/
function changeRegisterForm(type){
    var accountType = type.value;
    getMajors();
    switch(accountType){
        case("Student"):
            $("#tutorRegistrationForm").hide();
            $("#studentRegistrationForm").show("slow");
            console.log("student form loaded");
            break;
        case("Tutor"):
            $("#studentRegistrationForm").hide();
            $("#tutorRegistrationForm").show("slow");
            console.log("tutor form loaded");
            break;
        default:
            console.log("Error: Account Type not found");
    }
}
/*End Form Functions */

/*Register Functions*/
function registerTutor(){
    var fields = $("#tutorRegistrationForm").serializeArray();
    if (!verifyFields(fields))
        return;
    fields = $("#tutorRegistrationForm").serialize();
    $.ajax({
        type: "POST",
        url: "http://52.38.218.199/TutorStudyServlet/RegisterTutor",
        data: fields,
        success: function(data){
            $("#registerInfo").removeClass("alert-danger");
            $("#registerInfo").removeClass("alert-success");
            $("#registerInfo").addClass("alert-info");
            $("#alertRegisterInfo").text(data);
            $("#registerInfo").show('fast');
        }
    });
}

function registerStudent(){
    var fields =$("#studentRegistrationForm").serializeArray();
    if (!verifyFields(fields))
        return;
    fields = $("#studentRegistrationForm").serialize();
    $.ajax({
        type: "POST",
        url: "http://52.38.218.199/TutorStudyServlet/RegisterStudent",
        data: fields,
        success: function(data){
            $("#registerInfo").removeClass("alert-danger");
            $("#registerInfo").removeClass("alert-success");
            $("#registerInfo").addClass("alert-info");
            $("#alertRegisterInfo").text(data);
            $("#registerInfo").show('fast');
        }
    });
}

function verifyFields(fields){
    for(var i in fields){
        if(fields[i].value==null || fields[i].value==""){
            $("#registerInfo").removeClass("alert-success");
            $("#registerInfo").addClass("alert-danger");
            $("#alertRegisterInfo").text("Please fill in all required information. You are missing your " +fields[i].name+".");
            $("#registerInfo").show('fast');
            return false;
        }
    }
    var lsuEmail = new RegExp("[a-z]+[0-9]*@lsu.edu$");
    if (!lsuEmail.test(fields[1].value)){
        $("#registerInfo").removeClass("alert-success");
        $("#registerInfo").addClass("alert-danger");
        $("#alertRegisterInfo").text("Please enter in a valid LSU email.");
        $("#registerInfo").show('fast');
        return false;
    }
    if(fields[2].value!=fields[3].value){
        $("#registerInfo").removeClass("alert-success");
        $("#registerInfo").addClass("alert-danger");
        $("#alertRegisterInfo").text("Passwords do not match.");
        $("#registerInfo").show('fast');
        return false;
    }
    return true;
}

/* End Register Functions*/
/* Login Functions */
function Login(){
    var lsuEmail = new RegExp("[a-z]+[0-9]*@lsu.edu$");
    if (!lsuEmail.test($("#loginForm input[name=email]").val())){
        $("#loginInfo").removeClass("alert-success");
        $("#loginInfo").addClass("alert-danger");
        $("#alertLoginInfo").text("Please enter in a valid LSU email.");
        $("#loginInfo").show('fast');
    }else{
        var fields = $("#loginForm").serialize();
        $.ajax({
            type: "POST",
            url: "http://52.38.218.199/TutorStudyServlet/Login",
            data: fields,
            success: function(data){
                $("#loginInfo").removeClass("alert-danger");
                $("#loginInfo").removeClass("alert-success");
                $("#loginInfo").addClass("alert-info");
                $("#alertLoginInfo").text(data);
                $("#loginInfo").show('fast');
                loadUser();
            }
        });
    }
}
/* End Login Functions */

/* Document Load Functions */
$(document).ready(function(){
    loadUser();
});
/* End Document Load Functions */

/* Misc User Functions */
function loadUser(){
    $.ajax({
        type: "GET",
        url: "http://52.38.218.199/TutorStudyServlet/GetUserName",
        success: function(data){
            console.log("User: "+ data);
            $("#username").text(data);
            if (data.substring(0,5) == "Guest"){
                $(".userOptions").hide();
            }else{
                $(".userOptions").show();
            }
        }
    });
}

function logout(){
    $.ajax({
        type: "GET",
        url: "http://52.38.218.199/TutorStudyServlet/Logout"
    });
    window.location.replace("http://52.38.218.199/TutorStudy");
}
/* End Misc User Functions */<commit_msg>even more cheeky changes<commit_after>/*

This is a custom js for the TutorStudy website.

By: Ryan Ngo

*/

/* General Get Functions for data loading */
function getMajors(){
    //note: needed 2 different methods because select2 does not allow multiple dropdown parents
    $.ajax({
        type: "GET",
        dataType: "json",
        url: "http://52.38.218.199/TutorStudyServlet/GetMajors",
        success:function(data){
            $("#studentMajorSelect").select2({
                data :  $.map(data, function(data){
                            return{
                                id: data.id,
                                text: data.major
                            }
                        }),
                dropdownParent:$("#registerModal"),
                createTag: function(){
                    return null;
                }

            });
            $("#tutorMajorSelect").select2({
                data :  $.map(data, function(data){
                            return{
                                id: data.id,
                                text: data.major
                            }
                        }),
                dropdownParent:$("#registerModal"),
                createTag: function(){
                    return null;
                }
            });
        }
    })
}
/* End General Get Functions */

/* General Load Functions */
/* End General Load Functions */

/*Form Functions*/
function changeRegisterForm(type){
    var accountType = type.value;
    getMajors();
    switch(accountType){
        case("Student"):
            $("#tutorRegistrationForm").hide();
            $("#studentRegistrationForm").show("slow");
            console.log("student form loaded");
            break;
        case("Tutor"):
            $("#studentRegistrationForm").hide();
            $("#tutorRegistrationForm").show("slow");
            console.log("tutor form loaded");
            break;
        default:
            console.log("Error: Account Type not found");
    }
}
/*End Form Functions */

/*Register Functions*/
function registerTutor(){
    var fields = $("#tutorRegistrationForm").serializeArray();
    if (!verifyFields(fields))
        return;
    fields = $("#tutorRegistrationForm").serialize();
    $.ajax({
        type: "POST",
        url: "http://52.38.218.199/TutorStudyServlet/RegisterTutor",
        data: fields,
        success: function(data){
            $("#registerInfo").removeClass("alert-danger");
            $("#registerInfo").removeClass("alert-success");
            $("#registerInfo").addClass("alert-info");
            $("#alertRegisterInfo").text(data);
            $("#registerInfo").show('fast');
        }
    });
}

function registerStudent(){
    var fields =$("#studentRegistrationForm").serializeArray();
    if (!verifyFields(fields))
        return;
    fields = $("#studentRegistrationForm").serialize();
    $.ajax({
        type: "POST",
        url: "http://52.38.218.199/TutorStudyServlet/RegisterStudent",
        data: fields,
        success: function(data){
            $("#registerInfo").removeClass("alert-danger");
            $("#registerInfo").removeClass("alert-success");
            $("#registerInfo").addClass("alert-info");
            $("#alertRegisterInfo").text(data);
            $("#registerInfo").show('fast');
        }
    });
}

function verifyFields(fields){
    for(var i in fields){
        if(fields[i].value==null || fields[i].value==""){
            $("#registerInfo").removeClass("alert-success");
            $("#registerInfo").addClass("alert-danger");
            $("#alertRegisterInfo").text("Please fill in all required information. You are missing your " +fields[i].name+".");
            $("#registerInfo").show('fast');
            return false;
        }
    }
    var lsuEmail = new RegExp("[a-z]+[0-9]*@lsu.edu$");
    if (!lsuEmail.test(fields[1].value)){
        $("#registerInfo").removeClass("alert-success");
        $("#registerInfo").addClass("alert-danger");
        $("#alertRegisterInfo").text("Please enter in a valid LSU email.");
        $("#registerInfo").show('fast');
        return false;
    }
    if(fields[2].value!=fields[3].value){
        $("#registerInfo").removeClass("alert-success");
        $("#registerInfo").addClass("alert-danger");
        $("#alertRegisterInfo").text("Passwords do not match.");
        $("#registerInfo").show('fast');
        return false;
    }
    return true;
}

/* End Register Functions*/
/* Login Functions */
function Login(){
    var lsuEmail = new RegExp("[a-z]+[0-9]*@lsu.edu$");
    if (!lsuEmail.test($("#loginForm input[name=email]").val())){
        $("#loginInfo").removeClass("alert-success");
        $("#loginInfo").addClass("alert-danger");
        $("#alertLoginInfo").text("Please enter in a valid LSU email.");
        $("#loginInfo").show('fast');
    }else{
        var fields = $("#loginForm").serialize();
        $.ajax({
            type: "POST",
            url: "http://52.38.218.199/TutorStudyServlet/Login",
            data: fields,
            success: function(data){
                $("#loginInfo").removeClass("alert-danger");
                $("#loginInfo").removeClass("alert-success");
                $("#loginInfo").addClass("alert-info");
                $("#alertLoginInfo").text(data);
                $("#loginInfo").show('fast');
                loadUser();
            }
        });
    }
}
/* End Login Functions */

/* Document Load Functions */
$(document).ready(function(){
    loadUser();
});
/* End Document Load Functions */

/* Misc User Functions */
function loadUser(){
    $.ajax({
        type: "GET",
        url: "http://52.38.218.199/TutorStudyServlet/GetUserName",
        success: function(data){
            console.log("User: "+ data);
            $("#username").text(data);
            if (data.substring(0,data.length()) == "Guest"){
                $(".userOptions").hide();
            }else{
                $(".userOptions").show();
            }
        }
    });
}

function logout(){
    $.ajax({
        type: "GET",
        url: "http://52.38.218.199/TutorStudyServlet/Logout"
    });
    window.location.replace("http://52.38.218.199/TutorStudy");
}
/* End Misc User Functions */<|endoftext|>


<commit_before>$('a.page-scroll').bind('click', function(event) {
    var $anchor = $(this);
    $('html, body').stop().animate({
        scrollTop: ($($anchor.attr('href')).offset().top - 50)
    }, 1250, 'easeInOutExpo');
    event.preventDefault();
});

// Highlight top nav bar when user starts scrolling
$('body').scrollspy({
    target: '.navbar-fixed-top',
    offset: 51
});

// Closes the Responsive Menu on Menu Item Click
$('.navbar-collapse ul li a').click(function(){
    $('.navbar-toggle:visible').click();
});

// Offset for Main Navigation
$('#mainNav').affix({
    offset: {
        top: 100
}});

var nuhacksmodule = angular.module('hacks', []);

nuhacksmodule.controller('hacksController',function ($http, $q, $scope) {
    $scope.teamdata = [];
    $scope.rules = [];
    $scope.sponsors = [];
    var faqjson = $http.get('js/faq.json');
    var teamjson = $http.get('js/team.json');
    var sponsorsjson = $http.get('js/sponsors.json');
    $q.all([faqjson,teamjson,sponsorsjson]).then(function(allpromises){
        $scope.rules = allpromises[0].data;
        $scope.teamdata = allpromises[1].data;
        $scope.sponsors = allpromises[2].data;
    });

});

$(window).load(function() {
    "use strict";
    $(".loader").delay(500).fadeOut();
    $("#mask").delay(500).fadeOut("slow");

    $(function() {
        var fr = new FilmRoll({
            container: '#film_roll',
            height: 210
        });
    });
<commit_msg>Update background.js<commit_after>$('a.page-scroll').bind('click', function(event) {
    var $anchor = $(this);
    $('html, body').stop().animate({
        scrollTop: ($($anchor.attr('href')).offset().top - 50)
    }, 1250, 'easeInOutExpo');
    event.preventDefault();
});

// Highlight top nav bar when user starts scrolling
$('body').scrollspy({
    target: '.navbar-fixed-top',
    offset: 51
});

// Closes the Responsive Menu on Menu Item Click
$('.navbar-collapse ul li a').click(function(){
    $('.navbar-toggle:visible').click();
});

// Offset for Main Navigation
$('#mainNav').affix({
    offset: {
        top: 100
}});

var nuhacksmodule = angular.module('hacks', []);

nuhacksmodule.controller('hacksController',function ($http, $q, $scope) {
    $scope.teamdata = [];
    $scope.rules = [];
    $scope.sponsors = [];
    var faqjson = $http.get('js/faq.json');
    var teamjson = $http.get('js/team.json');
    var sponsorsjson = $http.get('js/sponsors.json');
    $q.all([faqjson,teamjson,sponsorsjson]).then(function(allpromises){
        $scope.rules = allpromises[0].data;
        $scope.teamdata = allpromises[1].data;
        $scope.sponsors = allpromises[2].data;
    });

});

$(window).load(function() {
    "use strict";
    $(".loader").delay(500).fadeOut();
    $("#mask").delay(500).fadeOut("slow");

    $(function() {
        var fr = new FilmRoll({
            container: '#film_roll',
            height: 210
        });
    });
});
<|endoftext|>


<commit_before>var LOCALHOST = '127.0.0.1';
var dnsCache = {};
var tunnelDnsCache = {};
var count = 1;
var isShowIp = localStorage.showIp;
var hasShowIpMenu;

function checkWhistleVersion() {
	var xhr = new XMLHttpRequest();
	index = count++;
	xhr.timeout = 10000;
	xhr.open('GET', 'http://local.whistlejs.com/cgi-bin/server-info', true);
	xhr.onreadystatechange = function() {
		if (xhr.readyState != 4) {
			return;
		}
		hasShowIpMenu = false;
		try {
			var version = JSON.parse(xhr.responseText).server.version.split('.');
			hasShowIpMenu = version[0] >= 0 && version[1] >= 7;
		} catch(e) {}
	};
	xhr.send();
}
checkWhistleVersion();

var util = (function() {

	return {
		parseJSON: function(str) {
			try {
				return JSON.parse(str) || {};
			} catch(e) {}

			return {};
		}
	};
})();

var proxy = (function() {
	var proxyConfig = util.parseJSON(localStorage.proxyConfig);
	var proxies = {};
	var list;

	if (!$.isArray(proxyConfig.list)) {
		list = proxyConfig.list = [];
	}

	if (!localStorage.init) {
		list.push({
			name: 'whistle',
			host: LOCALHOST,
			port: 8899,
			active: true
		}, {
			name: 'aeproxy',
			host: LOCALHOST,
			port: 9527
		});
		localStorage.init = true;
		store();
	}

	list = proxyConfig.list = proxyConfig.list.filter(function(item) {
		if (!item || !item.name) {
			return false;
		}
		proxies[item.name] = item;
		return true;
	});

	function store() {
		localStorage.proxyConfig = JSON.stringify(proxyConfig);
		showHostIpInResHeaders(isShowIp);
		checkWhistleVersion();
	}

	function cleartSelection() {
		proxyConfig.system = false;
		proxyConfig.direct = false;
		list.forEach(function(item) {
			item.active = false;
		});
	}

	function active(host, port, callback) {
		host = host || LOCALHOST;
		port = parseInt(port) || 8899;
		chrome.proxy.settings.set({value: {
		    mode: 'fixed_servers',
		    rules: {
		        proxyForHttp: {
		            scheme: 'http',
		            host: host,
		            port: port
		        },
		        proxyForHttps: {
		            scheme: 'http',
		            host: host,
		            port: port
		        }
		    }
		}}, callback);

	}

	function enable(name, callback) {
		var item = proxies[name];
		if (!item) {
			return;
		}
		cleartSelection();
		item.active = true;
		active(item.host, item.port, callback);
		chrome.browserAction.setTitle({
			title: name + '(' + (item.host || LOCALHOST) + ':' + (item.port || 8899) + ')'
		});
		store();
	}

	function save(name, host, port) {
		if (!name) {
			return;
		}

		var item = proxies[name];
		if (item) {
			item.host = host;
			item.port = port;
		} else {
			proxies[name] = item = {
					name: name,
					host: host,
					port: port
			};
			list.push(item);
		}
		store();
	}

	function rename(name, newName) {
		if (!name || !newName || !proxies[name] || name == newName) {
			return;
		}
		var item = proxies[name];
		delete proxies[name];
		item.name = newName;
		proxies[newName] = item;
		store();
	}

	return {
		setDirect: function(callback) {
			chrome.proxy.settings.set({value: {mode: 'direct'}}, callback);
			cleartSelection();
			proxyConfig.direct = true;
			store();
			chrome.browserAction.setTitle({
				title: '直接请求'
			});
		},
		setSystem: function(callback) {
			chrome.proxy.settings.set({value: {mode: 'system'}}, callback);
			cleartSelection();
			proxyConfig.system = true;
			store();
			chrome.browserAction.setTitle({
				title: '系统代理'
			});
		},
		removeProxy: function(name) {
			var item = proxies[name];
			if (!item) {
				return false;
			}

			list.splice(list.indexOf(item), 1);
			store();
			return true;
		},
		saveProxy: save,
		setProxy: function(name, host, port) {
			save(name);
			enable(name);
		},
		renameProxy: rename,
		enableProxy: enable,
		getProxy: function(name) {
			return proxies[name];
		},
		getProxyConfig: function() {
			return proxyConfig; //只是内部使用，不用副本
		}
	};
})();

function openWhistlePage(name) {
	openWindow(getWhistlePageUrl(name), true);
}

function getWhistlePageUrl(name) {
	return 'http://local.whistlejs.com/#' + name;
}

function openOptions() {
    openWindow(chrome.extension.getURL('options.html'));
}

function openAbout() {
	openWindow(chrome.extension.getURL('about.html'));
}

function openWindow(url, pinned) {
	chrome.tabs.getAllInWindow(null, function (tabs) {
        for (var i = 0, len = tabs.length; i < len; i++) {
        	var tab = tabs[i];
            if (getUrl(tab.url) == getUrl(url)) {
            	var options = {selected: true};
            	if (tab.url != url) {
            		options.url = url;
            	}
                chrome.tabs.update(tab.id, options);
                return;
            }
        }

        chrome.tabs.query({active: true}, function(tabs){
		    var tab = tabs[0];
		    chrome.tabs.create({
			    index: tab ? tab.index + 1 : 100,
			    url: url,
			    active: true,
			    pinned: !!pinned
			});
		});
    });
}

function hideIp() {
	isShowIp = null;
	localStorage.removeItem('showIp');
	dnsCache = {};
	tunnelDnsCache = {};
	showHostIpInResHeaders();
}

function showIp() {
	isShowIp = true;
	localStorage.showIp = 1;
	showHostIpInResHeaders(true);
}

function showHostIpInResHeaders(show) {
	var xhr = new XMLHttpRequest();
	xhr.open('POST', 'http://local.whistlejs.com/cgi-bin/show-host-ip-in-res-headers', true);
	xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	xhr.send('showHostIpInResHeaders=' + (show ? 1 : 0));
}

chrome.webRequest.onHeadersReceived.addListener(
	  function(info) {
		  if (!isShowIp) {
			  return;
		  }
		  var headers = info.responseHeaders || [];
		  for (var i = 0, len = headers.length; i < len; i++) {
			  var header = headers[i];
			  if (header.name == 'x-host-ip') {
				  if (header.value) {
					  dnsCache[info.url] = header.value;
				  }
				  return;
			  }
		  }
	  }, {urls: [], types: []}, ['responseHeaders']
);

chrome.runtime.onMessage.addListener(
		function(request, sender, sendResponse) {
			var type = request && request.type;
			if (!isShowIp || type != 'getIp') {
				return;
			}
			var url = sender.url;
			var ip = dnsCache[url];
			if (ip) {
				sendResponse(ip);
			} else if (/^https:\/\//i.test(url)) {
				var index = request.index;
				if (!index) {
					var xhr = new XMLHttpRequest();
					index = count++;
					xhr.timeout = 10000;
					xhr.open('GET', 'http://local.whistlejs.com/cgi-bin/lookup-tunnel-dns?url=' + encodeURIComponent(url.substring(0, 512)), true);
					xhr.onreadystatechange = function() {
						if (xhr.readyState != 4) {
							return;
						}
						try {
							if (ip = JSON.parse(xhr.responseText).host) {
								tunnelDnsCache[index] = ip;
								return;
							}
						} catch(e) {}
						tunnelDnsCache[index] = -1;
					};
					xhr.send();
					sendResponse(index);
				} else if (tunnelDnsCache[index]) {
					sendResponse(tunnelDnsCache[index]);
					delete tunnelDnsCache[index];
				} else {
					sendResponse(index);
				}
			}
		}
);

function getUrl(url) {

	return url && url.replace(/#.*$/, '');
}

function init() {
	var config = proxy.getProxyConfig();
	if (config.direct) {
		proxy.setDirect();
	} else if(config.system) {
		proxy.setSystem();
	} else {
		config.list.forEach(function(item) {
			item.active && proxy.enableProxy(item.name);
		});
	}
}

init();
<commit_msg>prevent cache<commit_after>var LOCALHOST = '127.0.0.1';
var dnsCache = {};
var tunnelDnsCache = {};
var count = 1;
var isShowIp = localStorage.showIp;
var hasShowIpMenu;

function checkWhistleVersion() {
	var xhr = new XMLHttpRequest();
	index = count++;
	xhr.timeout = 10000;
	xhr.open('GET', 'http://local.whistlejs.com/cgi-bin/server-info?' + Date.now(), true);
	xhr.onreadystatechange = function() {
		if (xhr.readyState != 4) {
			return;
		}
		hasShowIpMenu = false;
		try {
			var version = JSON.parse(xhr.responseText).server.version.split('.');
			hasShowIpMenu = version[0] >= 0 && version[1] >= 7;
		} catch(e) {}
	};
	xhr.send();
}
checkWhistleVersion();

var util = (function() {

	return {
		parseJSON: function(str) {
			try {
				return JSON.parse(str) || {};
			} catch(e) {}

			return {};
		}
	};
})();

var proxy = (function() {
	var proxyConfig = util.parseJSON(localStorage.proxyConfig);
	var proxies = {};
	var list;

	if (!$.isArray(proxyConfig.list)) {
		list = proxyConfig.list = [];
	}

	if (!localStorage.init) {
		list.push({
			name: 'whistle',
			host: LOCALHOST,
			port: 8899,
			active: true
		}, {
			name: 'aeproxy',
			host: LOCALHOST,
			port: 9527
		});
		localStorage.init = true;
		store();
	}

	list = proxyConfig.list = proxyConfig.list.filter(function(item) {
		if (!item || !item.name) {
			return false;
		}
		proxies[item.name] = item;
		return true;
	});

	function store() {
		localStorage.proxyConfig = JSON.stringify(proxyConfig);
		showHostIpInResHeaders(isShowIp);
		checkWhistleVersion();
	}

	function cleartSelection() {
		proxyConfig.system = false;
		proxyConfig.direct = false;
		list.forEach(function(item) {
			item.active = false;
		});
	}

	function active(host, port, callback) {
		host = host || LOCALHOST;
		port = parseInt(port) || 8899;
		chrome.proxy.settings.set({value: {
		    mode: 'fixed_servers',
		    rules: {
		        proxyForHttp: {
		            scheme: 'http',
		            host: host,
		            port: port
		        },
		        proxyForHttps: {
		            scheme: 'http',
		            host: host,
		            port: port
		        }
		    }
		}}, callback);

	}

	function enable(name, callback) {
		var item = proxies[name];
		if (!item) {
			return;
		}
		cleartSelection();
		item.active = true;
		active(item.host, item.port, callback);
		chrome.browserAction.setTitle({
			title: name + '(' + (item.host || LOCALHOST) + ':' + (item.port || 8899) + ')'
		});
		store();
	}

	function save(name, host, port) {
		if (!name) {
			return;
		}

		var item = proxies[name];
		if (item) {
			item.host = host;
			item.port = port;
		} else {
			proxies[name] = item = {
					name: name,
					host: host,
					port: port
			};
			list.push(item);
		}
		store();
	}

	function rename(name, newName) {
		if (!name || !newName || !proxies[name] || name == newName) {
			return;
		}
		var item = proxies[name];
		delete proxies[name];
		item.name = newName;
		proxies[newName] = item;
		store();
	}

	return {
		setDirect: function(callback) {
			chrome.proxy.settings.set({value: {mode: 'direct'}}, callback);
			cleartSelection();
			proxyConfig.direct = true;
			store();
			chrome.browserAction.setTitle({
				title: '直接请求'
			});
		},
		setSystem: function(callback) {
			chrome.proxy.settings.set({value: {mode: 'system'}}, callback);
			cleartSelection();
			proxyConfig.system = true;
			store();
			chrome.browserAction.setTitle({
				title: '系统代理'
			});
		},
		removeProxy: function(name) {
			var item = proxies[name];
			if (!item) {
				return false;
			}

			list.splice(list.indexOf(item), 1);
			store();
			return true;
		},
		saveProxy: save,
		setProxy: function(name, host, port) {
			save(name);
			enable(name);
		},
		renameProxy: rename,
		enableProxy: enable,
		getProxy: function(name) {
			return proxies[name];
		},
		getProxyConfig: function() {
			return proxyConfig; //只是内部使用，不用副本
		}
	};
})();

function openWhistlePage(name) {
	openWindow(getWhistlePageUrl(name), true);
}

function getWhistlePageUrl(name) {
	return 'http://local.whistlejs.com/#' + name;
}

function openOptions() {
    openWindow(chrome.extension.getURL('options.html'));
}

function openAbout() {
	openWindow(chrome.extension.getURL('about.html'));
}

function openWindow(url, pinned) {
	chrome.tabs.getAllInWindow(null, function (tabs) {
        for (var i = 0, len = tabs.length; i < len; i++) {
        	var tab = tabs[i];
            if (getUrl(tab.url) == getUrl(url)) {
            	var options = {selected: true};
            	if (tab.url != url) {
            		options.url = url;
            	}
                chrome.tabs.update(tab.id, options);
                return;
            }
        }

        chrome.tabs.query({active: true}, function(tabs){
		    var tab = tabs[0];
		    chrome.tabs.create({
			    index: tab ? tab.index + 1 : 100,
			    url: url,
			    active: true,
			    pinned: !!pinned
			});
		});
    });
}

function hideIp() {
	isShowIp = null;
	localStorage.removeItem('showIp');
	dnsCache = {};
	tunnelDnsCache = {};
	showHostIpInResHeaders();
}

function showIp() {
	isShowIp = true;
	localStorage.showIp = 1;
	showHostIpInResHeaders(true);
}

function showHostIpInResHeaders(show) {
	var xhr = new XMLHttpRequest();
	xhr.open('POST', 'http://local.whistlejs.com/cgi-bin/show-host-ip-in-res-headers', true);
	xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	xhr.send('showHostIpInResHeaders=' + (show ? 1 : 0));
}

chrome.webRequest.onHeadersReceived.addListener(
	  function(info) {
		  if (!isShowIp) {
			  return;
		  }
		  var headers = info.responseHeaders || [];
		  for (var i = 0, len = headers.length; i < len; i++) {
			  var header = headers[i];
			  if (header.name == 'x-host-ip') {
				  if (header.value) {
					  dnsCache[info.url] = header.value;
				  }
				  return;
			  }
		  }
	  }, {urls: [], types: []}, ['responseHeaders']
);

chrome.runtime.onMessage.addListener(
		function(request, sender, sendResponse) {
			var type = request && request.type;
			if (!isShowIp || type != 'getIp') {
				return;
			}
			var url = sender.url;
			var ip = dnsCache[url];
			if (ip) {
				sendResponse(ip);
			} else if (/^https:\/\//i.test(url)) {
				var index = request.index;
				if (!index) {
					var xhr = new XMLHttpRequest();
					index = count++;
					xhr.timeout = 10000;
					xhr.open('GET', 'http://local.whistlejs.com/cgi-bin/lookup-tunnel-dns?url=' + encodeURIComponent(url.substring(0, 512)), true)+ '&' + Date.now();
					xhr.onreadystatechange = function() {
						if (xhr.readyState != 4) {
							return;
						}
						try {
							if (ip = JSON.parse(xhr.responseText).host) {
								tunnelDnsCache[index] = ip;
								return;
							}
						} catch(e) {}
						tunnelDnsCache[index] = -1;
					};
					xhr.send();
					sendResponse(index);
				} else if (tunnelDnsCache[index]) {
					sendResponse(tunnelDnsCache[index]);
					delete tunnelDnsCache[index];
				} else {
					sendResponse(index);
				}
			}
		}
);

function getUrl(url) {

	return url && url.replace(/#.*$/, '');
}

function init() {
	var config = proxy.getProxyConfig();
	if (config.direct) {
		proxy.setDirect();
	} else if(config.system) {
		proxy.setSystem();
	} else {
		config.list.forEach(function(item) {
			item.active && proxy.enableProxy(item.name);
		});
	}
}

init();
<|endoftext|>


<commit_before>/* global Handlebars, Gallery */
(function ($, OC, t, Gallery) {
	"use strict";

	var TEMPLATE =
		'{{#each crumbs}}' +
		'
' +
		'	{{#if link}}' +
		'		' +
		'		{{#if img}}' +
		'			{{#with img}}' +
		'			' +
		'			{{/with}}' +
		'		{{else}}' +
		'			{{name}}' +
		'		{{/if}}' +
		'		' +
		'	{{else}}' +
		'		{{name}}' +
		'	{{/if}}' +
		'
' +
		'{{/each}}';

	/**
	 * Breadcrumbs that represent the path to the current album
	 *
	 * @constructor
	 */
	var Breadcrumb = function () {
		this.breadcrumbsElement = $('#breadcrumbs');
	};

	Breadcrumb.prototype = {
		breadcrumbs: [],
		breadcrumbsElement: null,
		ellipsis: null,
		albumPath: null,
		availableWidth: 0,
		onClick: null,
		droppableOptions: {
			accept: "#gallery > .row > a",
			activeClass: 'breadcrumbs-droppable',
			hoverClass: 'breadcrumbs-droppable-hover',
			tolerance: 'pointer'
		},

		/**
		 * Initialises the breadcrumbs for the current album
		 *
		 * @param {string} albumPath
		 * @param {int} availableWidth
		 */
		init: function (albumPath, availableWidth) {
			this.albumPath = albumPath;
			this.availableWidth = availableWidth;
			this.breadcrumbs = [];
			if (!this._template) {
				this._template = Handlebars.compile(TEMPLATE);
			}
			this._build();
			this._resize(this.availableWidth);
		},

		/**
		 * Defines the maximum available width in which we can build the breadcrumb and resizes it
		 *
		 * @param {int} availableWidth
		 */
		setMaxWidth: function (availableWidth) {
			if (this.availableWidth > availableWidth || this.ellipsis.is(":visible")) {
				this.availableWidth = availableWidth;
				this._resize(this.availableWidth);
			}
		},

		/**
		 * Processes UI elements dropped on the breadcrumbs
		 *
		 * @param event
		 * @param ui
		 */
		onDrop: function (event, ui) {
			var $item = ui.draggable;
			var $clone = ui.helper;
			var $target = $(event.target);
			if (!$target.is('.crumb')) {
				$target = $target.closest('.crumb');
			}
			var targetPath = $(event.target).data('dir').toString();
			var dir = Gallery.currentAlbum;

			while (dir.substr(0, 1) === '/') {//remove extra leading /'s
				dir = dir.substr(1);
			}
			dir = '/' + dir;
			if (dir.substr(-1, 1) !== '/') {
				dir = dir + '/';
			}
			// Do nothing if dragged on current dir
			if (targetPath === dir || targetPath + '/' === dir) {
				return;
			}
			var filePath = $item.data('path').toString();
			var fileName = OC.basename(filePath);

			$clone.fadeOut("normal", function () {
				Gallery.move($item, fileName, filePath, $target, targetPath);
			});
		},

		/**
		 * Shows the dark spinner on the crumb
		 */
		showLoader: function () {
			$(this).addClass("icon-loading-small-dark");
		},

		/**
		 * Builds the breadcrumbs array
		 *
		 * @private
		 */
		_build: function () {
			var i, crumbs, name, path, currentAlbum;
			var albumName = $('#content').data('albumname');
			if (!albumName) {
				albumName = t('gallery', 'Gallery');
			}
			path = '';
			name = '';
			crumbs = this.albumPath.split('/');
			currentAlbum = crumbs.pop();

			// This adds the home button
			this._addHome(albumName, currentAlbum);
			// We always add a hidden ellipsis
			this._pushCrumb('...', '', null, 'ellipsis');

			if (currentAlbum) {
				// This builds the crumbs between home and the current folder
				var crumbsLength = crumbs.length;
				if (crumbsLength > 0) {
					// We add all albums to the breadcrumbs array
					for (i = 0; i < crumbsLength; i++) {
						if (crumbs[i]) {
							name = crumbs[i];
							if (path) {
								path += '/' + crumbs[i];
							} else {
								path += crumbs[i];
							}
							this._pushCrumb(name, path, null, '');
						}
					}
				}
				// We finally push the current folder
				this._pushCrumb(currentAlbum, '', null, 'last');
			}

			this._render();
		},

		/**
		 * Adds the Home button
		 *
		 * @param {string} albumName
		 * @param {string} currentAlbum
		 * @private
		 */
		_addHome: function (albumName, currentAlbum) {
			var crumbImg = {
				imageSrc: OC.imagePath('core', 'places/home'),
				title: albumName
			};
			var cssClass = 'home';
			if (!currentAlbum) {
				cssClass += ' last';
			}

			this._pushCrumb('', '', crumbImg, cssClass);
		},

		/**
		 * Pushes crumb objects to the breadcrumbs array
		 *
		 * @param {string} name
		 * @param {string|boolean} link
		 * @param {Object} img
		 * @param {string} cssClass
		 * @private
		 */
		_pushCrumb: function (name, link, img, cssClass) {
			var hash = '';

			// Prevent the last crumb from getting a link unless the last crumb is 'home'.
			if ( cssClass.indexOf('last') === -1 || cssClass.indexOf('home') > -1 ) {
				hash = '#' + encodeURIComponent(link);
			}

			this.breadcrumbs.push({
				name: name,
				dir: link,
				link: hash,
				img: img,
				cssClass: cssClass
			});
		},

		/**
		 * Renders the full breadcrumb based on crumbs we have collected
		 *
		 * @private
		 */
		_render: function () {
			this.breadcrumbsElement.children().remove();

			var breadcrumbs = this._template({
				crumbs: this.breadcrumbs
			});

			this.breadcrumbsElement.append(breadcrumbs);

			this.droppableOptions.drop = this.onDrop.bind(this);
			this.breadcrumbsElement.find('.crumb:not(.last)').droppable(this.droppableOptions);
		},

		/**
		 * Alters the breadcrumb to make it fit within the asked dimensions
		 *
		 * @param {int} availableWidth
		 *
		 * @private
		 */
		_resize: function (availableWidth) {
			var crumbs = this.breadcrumbsElement.children();
			var shorten = false;
			var ellipsisPath = '';
			var self = this;

			// Hide everything first, so that we can check the width after adding each crumb
			crumbs.hide();

			// We go through the array in reverse order
			var crumbsElement = crumbs.get().reverse();
			$(crumbsElement).each(function () {
				if ($(this).hasClass('home')) {
					$(this).show();
					return;
				}
				// 1st sub-album has no-parent and the breadcrumbs contain home, ellipsis and last
				if (self.breadcrumbs.length > 3) {
					$(this).click(self.showLoader);
				}
				if ($(this).hasClass('ellipsis')) {
					self.ellipsis = $(this);
					return;
				}
				if (!shorten) {
					$(this).show();
				}

				// If we've reached the maximum width, we start hiding crumbs
				if (self.breadcrumbsElement.width() > availableWidth) {
					shorten = true;
					$(this).hide();
					if (!ellipsisPath) {
						ellipsisPath = $(this).data('dir');
					}
				}
			});

			// If we had to hide crumbs, we add a way to go to the parent folder
			if (shorten) {
				this.ellipsis.show();

				if (!ellipsisPath) {
					ellipsisPath = OC.dirname(this.albumPath);
				}

				this.ellipsis.children('a').attr('href', '#' + encodeURIComponent(ellipsisPath));
				this.ellipsis.attr('data-original-title', ellipsisPath).tooltip({
					fade: true,
					placement: 'bottom',
					delay: {
						hide: 5
					}
				});
			}
		}
	};

	Gallery.Breadcrumb = Breadcrumb;
})(jQuery, OC, t, Gallery);
<commit_msg>Re-activate spinner on home when not on home (cherry picked from commit dd9affe)<commit_after>/* global Handlebars, Gallery */
(function ($, OC, t, Gallery) {
	"use strict";

	var TEMPLATE =
		'{{#each crumbs}}' +
		'
' +
		'	{{#if link}}' +
		'		' +
		'		{{#if img}}' +
		'			{{#with img}}' +
		'			' +
		'			{{/with}}' +
		'		{{else}}' +
		'			{{name}}' +
		'		{{/if}}' +
		'		' +
		'	{{else}}' +
		'		{{name}}' +
		'	{{/if}}' +
		'
' +
		'{{/each}}';

	/**
	 * Breadcrumbs that represent the path to the current album
	 *
	 * @constructor
	 */
	var Breadcrumb = function () {
		this.breadcrumbsElement = $('#breadcrumbs');
	};

	Breadcrumb.prototype = {
		breadcrumbs: [],
		breadcrumbsElement: null,
		ellipsis: null,
		albumPath: null,
		availableWidth: 0,
		onClick: null,
		droppableOptions: {
			accept: "#gallery > .row > a",
			activeClass: 'breadcrumbs-droppable',
			hoverClass: 'breadcrumbs-droppable-hover',
			tolerance: 'pointer'
		},

		/**
		 * Initialises the breadcrumbs for the current album
		 *
		 * @param {string} albumPath
		 * @param {int} availableWidth
		 */
		init: function (albumPath, availableWidth) {
			this.albumPath = albumPath;
			this.availableWidth = availableWidth;
			this.breadcrumbs = [];
			if (!this._template) {
				this._template = Handlebars.compile(TEMPLATE);
			}
			this._build();
			this._resize(this.availableWidth);
		},

		/**
		 * Defines the maximum available width in which we can build the breadcrumb and resizes it
		 *
		 * @param {int} availableWidth
		 */
		setMaxWidth: function (availableWidth) {
			if (this.availableWidth > availableWidth || this.ellipsis.is(":visible")) {
				this.availableWidth = availableWidth;
				this._resize(this.availableWidth);
			}
		},

		/**
		 * Processes UI elements dropped on the breadcrumbs
		 *
		 * @param event
		 * @param ui
		 */
		onDrop: function (event, ui) {
			var $item = ui.draggable;
			var $clone = ui.helper;
			var $target = $(event.target);
			if (!$target.is('.crumb')) {
				$target = $target.closest('.crumb');
			}
			var targetPath = $(event.target).data('dir').toString();
			var dir = Gallery.currentAlbum;

			while (dir.substr(0, 1) === '/') {//remove extra leading /'s
				dir = dir.substr(1);
			}
			dir = '/' + dir;
			if (dir.substr(-1, 1) !== '/') {
				dir = dir + '/';
			}
			// Do nothing if dragged on current dir
			if (targetPath === dir || targetPath + '/' === dir) {
				return;
			}
			var filePath = $item.data('path').toString();
			var fileName = OC.basename(filePath);

			$clone.fadeOut("normal", function () {
				Gallery.move($item, fileName, filePath, $target, targetPath);
			});
		},

		/**
		 * Shows the dark spinner on the crumb
		 */
		showLoader: function () {
			$(this).addClass("icon-loading-small-dark");
		},

		/**
		 * Builds the breadcrumbs array
		 *
		 * @private
		 */
		_build: function () {
			var i, crumbs, name, path, currentAlbum;
			var albumName = $('#content').data('albumname');
			if (!albumName) {
				albumName = t('gallery', 'Gallery');
			}
			path = '';
			name = '';
			crumbs = this.albumPath.split('/');
			currentAlbum = crumbs.pop();

			// This adds the home button
			this._addHome(albumName, currentAlbum);
			// We always add a hidden ellipsis
			this._pushCrumb('...', '', null, 'ellipsis');

			if (currentAlbum) {
				// This builds the crumbs between home and the current folder
				var crumbsLength = crumbs.length;
				if (crumbsLength > 0) {
					// We add all albums to the breadcrumbs array
					for (i = 0; i < crumbsLength; i++) {
						if (crumbs[i]) {
							name = crumbs[i];
							if (path) {
								path += '/' + crumbs[i];
							} else {
								path += crumbs[i];
							}
							this._pushCrumb(name, path, null, '');
						}
					}
				}
				// We finally push the current folder
				this._pushCrumb(currentAlbum, '', null, 'last');
			}

			this._render();
		},

		/**
		 * Adds the Home button
		 *
		 * @param {string} albumName
		 * @param {string} currentAlbum
		 * @private
		 */
		_addHome: function (albumName, currentAlbum) {
			var crumbImg = {
				imageSrc: OC.imagePath('core', 'places/home'),
				title: albumName
			};
			var cssClass = 'home';
			if (!currentAlbum) {
				cssClass += ' last';
			}

			this._pushCrumb('', '', crumbImg, cssClass);
		},

		/**
		 * Pushes crumb objects to the breadcrumbs array
		 *
		 * @param {string} name
		 * @param {string|boolean} link
		 * @param {Object} img
		 * @param {string} cssClass
		 * @private
		 */
		_pushCrumb: function (name, link, img, cssClass) {
			var hash = '';

			// Prevent the last crumb from getting a link unless the last crumb is 'home'.
			if ( cssClass.indexOf('last') === -1 || cssClass.indexOf('home') > -1 ) {
				hash = '#' + encodeURIComponent(link);
			}

			this.breadcrumbs.push({
				name: name,
				dir: link,
				link: hash,
				img: img,
				cssClass: cssClass
			});
		},

		/**
		 * Renders the full breadcrumb based on crumbs we have collected
		 *
		 * @private
		 */
		_render: function () {
			this.breadcrumbsElement.children().remove();

			var breadcrumbs = this._template({
				crumbs: this.breadcrumbs
			});

			this.breadcrumbsElement.append(breadcrumbs);

			this.droppableOptions.drop = this.onDrop.bind(this);
			this.breadcrumbsElement.find('.crumb:not(.last)').droppable(this.droppableOptions);
		},

		/**
		 * Alters the breadcrumb to make it fit within the asked dimensions
		 *
		 * @param {int} availableWidth
		 *
		 * @private
		 */
		_resize: function (availableWidth) {
			var crumbs = this.breadcrumbsElement.children();
			var shorten = false;
			var ellipsisPath = '';
			var self = this;

			// Hide everything first, so that we can check the width after adding each crumb
			crumbs.hide();

			// We go through the array in reverse order
			var crumbsElement = crumbs.get().reverse();
			$(crumbsElement).each(function () {
				if ($(this).hasClass('home')) {
					$(this).show();
					if (self.breadcrumbs.length > 2) {
						$(this).click(self.showLoader);
					}
					return;
				}
				// 1st sub-album has no-parent and the breadcrumbs contain home, ellipsis and last
				if (self.breadcrumbs.length > 3) {
					$(this).click(self.showLoader);
				}
				if ($(this).hasClass('ellipsis')) {
					self.ellipsis = $(this);
					return;
				}
				if (!shorten) {
					$(this).show();
				}

				// If we've reached the maximum width, we start hiding crumbs
				if (self.breadcrumbsElement.width() > availableWidth) {
					shorten = true;
					$(this).hide();
					if (!ellipsisPath) {
						ellipsisPath = $(this).data('dir');
					}
				}
			});

			// If we had to hide crumbs, we add a way to go to the parent folder
			if (shorten) {
				this.ellipsis.show();

				if (!ellipsisPath) {
					ellipsisPath = OC.dirname(this.albumPath);
				}

				this.ellipsis.children('a').attr('href', '#' + encodeURIComponent(ellipsisPath));
				this.ellipsis.attr('data-original-title', ellipsisPath).tooltip({
					fade: true,
					placement: 'bottom',
					delay: {
						hide: 5
					}
				});
			}
		}
	};

	Gallery.Breadcrumb = Breadcrumb;
})(jQuery, OC, t, Gallery);
<|endoftext|>


<commit_before>"use strict";

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

const Exchange = require ('./base/Exchange')
const { ExchangeError } = require ('./base/errors')

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

module.exports = class btcmarkets extends Exchange {

    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'btcmarkets',
            'name': 'BTC Markets',
            'countries': 'AU', // Australia
            'rateLimit': 1000, // market data cached for 1 second (trades cached for 2 seconds)
            'hasCORS': false,
            'hasFetchOrder': true,
            'hasFetchOrders': true,
            'hasFetchClosedOrders': true,
            'hasFetchOpenOrders': true,
            'has': {
                'fetchOrder': true,
                'fetchOrders': true,
                'fetchClosedOrders': 'emulated',
                'fetchOpenOrders': true,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/29142911-0e1acfc2-7d5c-11e7-98c4-07d9532b29d7.jpg',
                'api': 'https://api.btcmarkets.net',
                'www': 'https://btcmarkets.net/',
                'doc': 'https://github.com/BTCMarkets/API',
            },
            'api': {
                'public': {
                    'get': [
                        'market/{id}/tick',
                        'market/{id}/orderbook',
                        'market/{id}/trades',
                    ],
                },
                'private': {
                    'get': [
                        'account/balance',
                        'account/{id}/tradingfee',
                    ],
                    'post': [
                        'fundtransfer/withdrawCrypto',
                        'fundtransfer/withdrawEFT',
                        'order/create',
                        'order/cancel',
                        'order/history',
                        'order/open',
                        'order/trade/history',
                        'order/createBatch', // they promise it's coming soon...
                        'order/detail',
                    ],
                },
            },
            'markets': {
                'BTC/AUD': { 'id': 'BTC/AUD', 'symbol': 'BTC/AUD', 'base': 'BTC', 'quote': 'AUD', 'maker': 0.0085, 'taker': 0.0085 },
                'LTC/AUD': { 'id': 'LTC/AUD', 'symbol': 'LTC/AUD', 'base': 'LTC', 'quote': 'AUD', 'maker': 0.0085, 'taker': 0.0085 },
                'ETH/AUD': { 'id': 'ETH/AUD', 'symbol': 'ETH/AUD', 'base': 'ETH', 'quote': 'AUD', 'maker': 0.0085, 'taker': 0.0085 },
                'ETC/AUD': { 'id': 'ETC/AUD', 'symbol': 'ETC/AUD', 'base': 'ETC', 'quote': 'AUD', 'maker': 0.0085, 'taker': 0.0085 },
                'XRP/AUD': { 'id': 'XRP/AUD', 'symbol': 'XRP/AUD', 'base': 'XRP', 'quote': 'AUD', 'maker': 0.0085, 'taker': 0.0085 },
                'BCH/AUD': { 'id': 'BCH/AUD', 'symbol': 'BCH/AUD', 'base': 'BCH', 'quote': 'AUD', 'maker': 0.0085, 'taker': 0.0085 },
                'LTC/BTC': { 'id': 'LTC/BTC', 'symbol': 'LTC/BTC', 'base': 'LTC', 'quote': 'BTC', 'maker': 0.0022, 'taker': 0.0022 },
                'ETH/BTC': { 'id': 'ETH/BTC', 'symbol': 'ETH/BTC', 'base': 'ETH', 'quote': 'BTC', 'maker': 0.0022, 'taker': 0.0022 },
                'ETC/BTC': { 'id': 'ETC/BTC', 'symbol': 'ETC/BTC', 'base': 'ETC', 'quote': 'BTC', 'maker': 0.0022, 'taker': 0.0022 },
                'XRP/BTC': { 'id': 'XRP/BTC', 'symbol': 'XRP/BTC', 'base': 'XRP', 'quote': 'BTC', 'maker': 0.0022, 'taker': 0.0022 },
                'BCH/BTC': { 'id': 'BCH/BTC', 'symbol': 'BCH/BTC', 'base': 'BCH', 'quote': 'BTC', 'maker': 0.0022, 'taker': 0.0022 },
            },
        });
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        let balances = await this.privateGetAccountBalance ();
        let result = { 'info': balances };
        for (let b = 0; b < balances.length; b++) {
            let balance = balances[b];
            let currency = balance['currency'];
            let multiplier = 100000000;
            let total = parseFloat (balance['balance'] / multiplier);
            let used = parseFloat (balance['pendingFunds'] / multiplier);
            let free = total - used;
            let account = {
                'free': free,
                'used': used,
                'total': total,
            };
            result[currency] = account;
        }
        return this.parseBalance (result);
    }

    async fetchOrderBook (symbol, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let orderbook = await this.publicGetMarketIdOrderbook (this.extend ({
            'id': market['id'],
        }, params));
        let timestamp = orderbook['timestamp'] * 1000;
        return this.parseOrderBook (orderbook, timestamp);
    }

    parseTicker (ticker, market = undefined) {
        let timestamp = ticker['timestamp'] * 1000;
        let symbol = undefined;
        if (market)
            symbol = market['symbol'];
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': undefined,
            'low': undefined,
            'bid': parseFloat (ticker['bestBid']),
            'ask': parseFloat (ticker['bestAsk']),
            'vwap': undefined,
            'open': undefined,
            'close': undefined,
            'first': undefined,
            'last': parseFloat (ticker['lastPrice']),
            'change': undefined,
            'percentage': undefined,
            'average': undefined,
            'baseVolume': parseFloat (ticker['volume24h']),
            'quoteVolume': undefined,
            'info': ticker,
        };
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let ticker = await this.publicGetMarketIdTick (this.extend ({
            'id': market['id'],
        }, params));
        return this.parseTicker (ticker, market);
    }

    parseTrade (trade, market) {
        let timestamp = trade['date'] * 1000;
        return {
            'info': trade,
            'id': trade['tid'].toString (),
            'order': undefined,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'type': undefined,
            'side': undefined,
            'price': trade['price'],
            'amount': trade['amount'],
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.publicGetMarketIdTrades (this.extend ({
            // 'since': 59868345231,
            'id': market['id'],
        }, params));
        return this.parseTrades (response, market, since, limit);
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let multiplier = 100000000; // for price and volume
        // does BTC Markets support market orders at all?
        let orderSide = (side == 'buy') ? 'Bid' : 'Ask';
        let order = this.ordered ({
            'currency': market['quote'],
        });
        order['currency'] = market['quote'];
        order['instrument'] = market['base'];
        order['price'] = parseInt (price * multiplier);
        order['volume'] = parseInt (amount * multiplier);
        order['orderSide'] = orderSide;
        order['ordertype'] = this.capitalize (type);
        order['clientRequestId'] = this.nonce ().toString ();
        let response = await this.privatePostOrderCreate (order);
        return {
            'info': response,
            'id': response['id'].toString (),
        };
    }

    async cancelOrders (ids) {
        await this.loadMarkets ();
        return await this.privatePostOrderCancel ({ 'order_ids': ids });
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        return await this.cancelOrders ([ id ]);
    }

    parseOrderTrade (trade, market) {
        let multiplier = 100000000;
        let timestamp = trade['creationTime'];
        let side = (trade['side'] == 'Bid') ? 'buy' : 'sell';
        return {
            'info': trade,
            'id': trade['id'].toString (),
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'type': undefined,
            'side': side,
            'price': trade['price'] / multiplier,
            'fee': trade['fee'] / multiplier,
            'amount': trade['volume'] / multiplier,
        };
    }

    parseOrder (order, market = undefined) {
        let multiplier = 100000000;
        let side = (order['orderSide'] == 'Bid') ? 'buy' : 'sell';
        let type = (order['ordertype'] == 'Limit') ? 'limit' : 'market';
        let timestamp = order['creationTime'];
        if (!market) {
            market = this.market(order['instrument'] + "/" + order['currency']);
        }
        let status = 'open';
        if (order['status'] == 'Failed' || order['status'] == 'Cancelled' || order['status'] == 'Partially Cancelled' || order['status'] == 'Error') {
            status = 'canceled';
        } else if (order['status'] == "Fully Matched" || order['status'] == "Partially Matched") {
            status = 'closed';
        }
        let price = this.safeFloat (order, 'price') / multiplier;
        let amount = this.safeFloat (order, 'volume') / multiplier;
        let remaining = this.safeFloat (order, 'openVolume', 0.0) / multiplier;
        let filled = amount - remaining;
        let cost = price * amount;
        let trades = [];
        for (let i=0; i< order['trades'].length; i++) {
            trades.push(this.parseOrderTrade(order['trades'][i], market));
        }
        let result = {
            'info': order,
            'id': order['id'].toString (),
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'type': type,
            'side': side,
            'price': price,
            'cost': cost,
            'amount': amount,
            'filled': filled,
            'remaining': remaining,
            'status': status,
            'trades': trades,
        };
        return result;
    }

    async fetchOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        let response = await this.privatePostOrderDetail (this.extend ({ 'orderIds': [id] }, params));
        if (response['orders'].length == 0) {
            throw new OrderNotFound (this.id + ' No matching order found: ' + id);
        }
        return this.parseOrder (response['orders'][0]);
    }

    async prepRequest (market, since = undefined, limit = undefined, params = {}) {
        let request = this.ordered({
            'currency': market['quote'],
            'instrument': market['base'],
        });
        if (limit) {
            request['limit'] = limit;
        } else {
            request['limit'] = 100;
        }
        if (since) {
            request['since'] = since;
        } else {
            request['since'] = 0;
        }
        return request;
    }

    async fetchOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets();
        let market = undefined;
        if (!symbol) {
            throw new NotSupported (this.id + ': fetchOrders requires a `symbol` parameter.');
        }
        market = this.market(symbol);
        let request = this.prepRequest(market, since, limit, params)
        let response = await this.privatePostOrderHistory (this.extend (request, params));
        return this.parseOrders (response['orders'], market);
    }

    async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets();
        let market = undefined;
        if (!symbol) {
            throw new NotSupported (this.id + ': fetchOrders requires a `symbol` parameter.');
        }
        market = this.market(symbol);
        let request = this.prepRequest(market, since, limit, params)
        let response = await this.privatePostOrderOpen (this.extend (request, params));
        return this.parseOrders (response['orders'], market);
    }

    async fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        let orders = await this.fetchOrders (symbol, params);
        return this.filterBy (orders, 'status', 'closed');
        return [];
    }

    nonce () {
        return this.milliseconds ();
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let uri = '/' + this.implodeParams (path, params);
        let url = this.urls['api'] + uri;
        if (api == 'public') {
            if (Object.keys (params).length)
                url += '?' + this.urlencode (params);
        } else {
            this.checkRequiredCredentials ();
            let nonce = this.nonce ().toString ();
            let auth = uri + "\n" + nonce + "\n";
            headers = {
                'Content-Type': 'application/json',
                'apikey': this.apiKey,
                'timestamp': nonce,
            };
            if (method == 'POST') {
                body = this.json (params);
                auth += body;
            }
            let secret = this.base64ToBinary (this.secret);
            let signature = this.hmac (this.encode (auth), secret, 'sha512', 'base64');
            headers['signature'] = this.decode (signature);
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let response = await this.fetch2 (path, api, method, params, headers, body);
        if (api == 'private') {
            if ('success' in response)
                if (!response['success'])
                    throw new ExchangeError (this.id + ' ' + this.json (response));
            return response;
        }
        return response;
    }
}
<commit_msg>Fix php semicolon error<commit_after>"use strict";

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

const Exchange = require ('./base/Exchange')
const { ExchangeError } = require ('./base/errors')

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

module.exports = class btcmarkets extends Exchange {

    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'btcmarkets',
            'name': 'BTC Markets',
            'countries': 'AU', // Australia
            'rateLimit': 1000, // market data cached for 1 second (trades cached for 2 seconds)
            'hasCORS': false,
            'hasFetchOrder': true,
            'hasFetchOrders': true,
            'hasFetchClosedOrders': true,
            'hasFetchOpenOrders': true,
            'has': {
                'fetchOrder': true,
                'fetchOrders': true,
                'fetchClosedOrders': 'emulated',
                'fetchOpenOrders': true,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/29142911-0e1acfc2-7d5c-11e7-98c4-07d9532b29d7.jpg',
                'api': 'https://api.btcmarkets.net',
                'www': 'https://btcmarkets.net/',
                'doc': 'https://github.com/BTCMarkets/API',
            },
            'api': {
                'public': {
                    'get': [
                        'market/{id}/tick',
                        'market/{id}/orderbook',
                        'market/{id}/trades',
                    ],
                },
                'private': {
                    'get': [
                        'account/balance',
                        'account/{id}/tradingfee',
                    ],
                    'post': [
                        'fundtransfer/withdrawCrypto',
                        'fundtransfer/withdrawEFT',
                        'order/create',
                        'order/cancel',
                        'order/history',
                        'order/open',
                        'order/trade/history',
                        'order/createBatch', // they promise it's coming soon...
                        'order/detail',
                    ],
                },
            },
            'markets': {
                'BTC/AUD': { 'id': 'BTC/AUD', 'symbol': 'BTC/AUD', 'base': 'BTC', 'quote': 'AUD', 'maker': 0.0085, 'taker': 0.0085 },
                'LTC/AUD': { 'id': 'LTC/AUD', 'symbol': 'LTC/AUD', 'base': 'LTC', 'quote': 'AUD', 'maker': 0.0085, 'taker': 0.0085 },
                'ETH/AUD': { 'id': 'ETH/AUD', 'symbol': 'ETH/AUD', 'base': 'ETH', 'quote': 'AUD', 'maker': 0.0085, 'taker': 0.0085 },
                'ETC/AUD': { 'id': 'ETC/AUD', 'symbol': 'ETC/AUD', 'base': 'ETC', 'quote': 'AUD', 'maker': 0.0085, 'taker': 0.0085 },
                'XRP/AUD': { 'id': 'XRP/AUD', 'symbol': 'XRP/AUD', 'base': 'XRP', 'quote': 'AUD', 'maker': 0.0085, 'taker': 0.0085 },
                'BCH/AUD': { 'id': 'BCH/AUD', 'symbol': 'BCH/AUD', 'base': 'BCH', 'quote': 'AUD', 'maker': 0.0085, 'taker': 0.0085 },
                'LTC/BTC': { 'id': 'LTC/BTC', 'symbol': 'LTC/BTC', 'base': 'LTC', 'quote': 'BTC', 'maker': 0.0022, 'taker': 0.0022 },
                'ETH/BTC': { 'id': 'ETH/BTC', 'symbol': 'ETH/BTC', 'base': 'ETH', 'quote': 'BTC', 'maker': 0.0022, 'taker': 0.0022 },
                'ETC/BTC': { 'id': 'ETC/BTC', 'symbol': 'ETC/BTC', 'base': 'ETC', 'quote': 'BTC', 'maker': 0.0022, 'taker': 0.0022 },
                'XRP/BTC': { 'id': 'XRP/BTC', 'symbol': 'XRP/BTC', 'base': 'XRP', 'quote': 'BTC', 'maker': 0.0022, 'taker': 0.0022 },
                'BCH/BTC': { 'id': 'BCH/BTC', 'symbol': 'BCH/BTC', 'base': 'BCH', 'quote': 'BTC', 'maker': 0.0022, 'taker': 0.0022 },
            },
        });
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        let balances = await this.privateGetAccountBalance ();
        let result = { 'info': balances };
        for (let b = 0; b < balances.length; b++) {
            let balance = balances[b];
            let currency = balance['currency'];
            let multiplier = 100000000;
            let total = parseFloat (balance['balance'] / multiplier);
            let used = parseFloat (balance['pendingFunds'] / multiplier);
            let free = total - used;
            let account = {
                'free': free,
                'used': used,
                'total': total,
            };
            result[currency] = account;
        }
        return this.parseBalance (result);
    }

    async fetchOrderBook (symbol, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let orderbook = await this.publicGetMarketIdOrderbook (this.extend ({
            'id': market['id'],
        }, params));
        let timestamp = orderbook['timestamp'] * 1000;
        return this.parseOrderBook (orderbook, timestamp);
    }

    parseTicker (ticker, market = undefined) {
        let timestamp = ticker['timestamp'] * 1000;
        let symbol = undefined;
        if (market)
            symbol = market['symbol'];
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': undefined,
            'low': undefined,
            'bid': parseFloat (ticker['bestBid']),
            'ask': parseFloat (ticker['bestAsk']),
            'vwap': undefined,
            'open': undefined,
            'close': undefined,
            'first': undefined,
            'last': parseFloat (ticker['lastPrice']),
            'change': undefined,
            'percentage': undefined,
            'average': undefined,
            'baseVolume': parseFloat (ticker['volume24h']),
            'quoteVolume': undefined,
            'info': ticker,
        };
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let ticker = await this.publicGetMarketIdTick (this.extend ({
            'id': market['id'],
        }, params));
        return this.parseTicker (ticker, market);
    }

    parseTrade (trade, market) {
        let timestamp = trade['date'] * 1000;
        return {
            'info': trade,
            'id': trade['tid'].toString (),
            'order': undefined,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'type': undefined,
            'side': undefined,
            'price': trade['price'],
            'amount': trade['amount'],
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.publicGetMarketIdTrades (this.extend ({
            // 'since': 59868345231,
            'id': market['id'],
        }, params));
        return this.parseTrades (response, market, since, limit);
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let multiplier = 100000000; // for price and volume
        // does BTC Markets support market orders at all?
        let orderSide = (side == 'buy') ? 'Bid' : 'Ask';
        let order = this.ordered ({
            'currency': market['quote'],
        });
        order['currency'] = market['quote'];
        order['instrument'] = market['base'];
        order['price'] = parseInt (price * multiplier);
        order['volume'] = parseInt (amount * multiplier);
        order['orderSide'] = orderSide;
        order['ordertype'] = this.capitalize (type);
        order['clientRequestId'] = this.nonce ().toString ();
        let response = await this.privatePostOrderCreate (order);
        return {
            'info': response,
            'id': response['id'].toString (),
        };
    }

    async cancelOrders (ids) {
        await this.loadMarkets ();
        return await this.privatePostOrderCancel ({ 'order_ids': ids });
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        return await this.cancelOrders ([ id ]);
    }

    parseOrderTrade (trade, market) {
        let multiplier = 100000000;
        let timestamp = trade['creationTime'];
        let side = (trade['side'] == 'Bid') ? 'buy' : 'sell';
        return {
            'info': trade,
            'id': trade['id'].toString (),
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'type': undefined,
            'side': side,
            'price': trade['price'] / multiplier,
            'fee': trade['fee'] / multiplier,
            'amount': trade['volume'] / multiplier,
        };
    }

    parseOrder (order, market = undefined) {
        let multiplier = 100000000;
        let side = (order['orderSide'] == 'Bid') ? 'buy' : 'sell';
        let type = (order['ordertype'] == 'Limit') ? 'limit' : 'market';
        let timestamp = order['creationTime'];
        if (!market) {
            market = this.market(order['instrument'] + "/" + order['currency']);
        }
        let status = 'open';
        if (order['status'] == 'Failed' || order['status'] == 'Cancelled' || order['status'] == 'Partially Cancelled' || order['status'] == 'Error') {
            status = 'canceled';
        } else if (order['status'] == "Fully Matched" || order['status'] == "Partially Matched") {
            status = 'closed';
        }
        let price = this.safeFloat (order, 'price') / multiplier;
        let amount = this.safeFloat (order, 'volume') / multiplier;
        let remaining = this.safeFloat (order, 'openVolume', 0.0) / multiplier;
        let filled = amount - remaining;
        let cost = price * amount;
        let trades = [];
        for (let i=0; i< order['trades'].length; i++) {
            trades.push(this.parseOrderTrade(order['trades'][i], market));
        }
        let result = {
            'info': order,
            'id': order['id'].toString (),
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'type': type,
            'side': side,
            'price': price,
            'cost': cost,
            'amount': amount,
            'filled': filled,
            'remaining': remaining,
            'status': status,
            'trades': trades,
        };
        return result;
    }

    async fetchOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        let response = await this.privatePostOrderDetail (this.extend ({ 'orderIds': [id] }, params));
        if (response['orders'].length == 0) {
            throw new OrderNotFound (this.id + ' No matching order found: ' + id);
        }
        return this.parseOrder (response['orders'][0]);
    }

    async prepRequest (market, since = undefined, limit = undefined, params = {}) {
        let request = this.ordered({
            'currency': market['quote'],
            'instrument': market['base'],
        });
        if (limit) {
            request['limit'] = limit;
        } else {
            request['limit'] = 100;
        }
        if (since) {
            request['since'] = since;
        } else {
            request['since'] = 0;
        }
        return request;
    }

    async fetchOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets();
        let market = undefined;
        if (!symbol) {
            throw new NotSupported (this.id + ': fetchOrders requires a `symbol` parameter.');
        }
        market = this.market(symbol);
        let request = this.prepRequest(market, since, limit, params);
        let response = await this.privatePostOrderHistory (this.extend (request, params));
        return this.parseOrders (response['orders'], market);
    }

    async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets();
        let market = undefined;
        if (!symbol) {
            throw new NotSupported (this.id + ': fetchOrders requires a `symbol` parameter.');
        }
        market = this.market(symbol);
        let request = this.prepRequest(market, since, limit, params)
        let response = await this.privatePostOrderOpen (this.extend (request, params));
        return this.parseOrders (response['orders'], market);
    }

    async fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        let orders = await this.fetchOrders (symbol, params);
        return this.filterBy (orders, 'status', 'closed');
        return [];
    }

    nonce () {
        return this.milliseconds ();
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let uri = '/' + this.implodeParams (path, params);
        let url = this.urls['api'] + uri;
        if (api == 'public') {
            if (Object.keys (params).length)
                url += '?' + this.urlencode (params);
        } else {
            this.checkRequiredCredentials ();
            let nonce = this.nonce ().toString ();
            let auth = uri + "\n" + nonce + "\n";
            headers = {
                'Content-Type': 'application/json',
                'apikey': this.apiKey,
                'timestamp': nonce,
            };
            if (method == 'POST') {
                body = this.json (params);
                auth += body;
            }
            let secret = this.base64ToBinary (this.secret);
            let signature = this.hmac (this.encode (auth), secret, 'sha512', 'base64');
            headers['signature'] = this.decode (signature);
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let response = await this.fetch2 (path, api, method, params, headers, body);
        if (api == 'private') {
            if ('success' in response)
                if (!response['success'])
                    throw new ExchangeError (this.id + ' ' + this.json (response));
            return response;
        }
        return response;
    }
}
<|endoftext|>


<commit_before>
function valida_campi(){

  var errore = "err_email";

  //se settati svuoto gli span di errore
  if (document.getElementById(errore) !== "") {
      document.getElementById(errore).innerHTML = "";
  }

  var nome = document.getElementById("nome").value;
  var email=document.getElementById("email").value;
  var quesion = document.getElementById("question").value;

        if (!nome.replace(/^\s+/g, '').length || !email.replace(/^\s+/g, '').length  || !question.replace(/^\s+/g, '').length)
        {
           document.getElementById(errore).innerHTML = "tutti i campi sono obbligatori*";
           return false;
  }
  else if(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email))
         {
            return true

         }else
           { document.getElementById(errore).innerHTML = "indirizzo email non valido*";
            return false
            }

       return true
}
<commit_msg>Delete check_mail.js<commit_after><|endoftext|>