[Www] [Worker] Mturk Dashboard

Modifies the Www and Worker MTurk dashboard.

目前為 2017-12-07 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         [Www] [Worker] Mturk Dashboard
// @namespace    http://kadauchi.com/
// @version      1.8.1
// @description  Modifies the Www and Worker MTurk dashboard.
// @author       Kadauchi
// @icon         http://i.imgur.com/oGRQwPN.png
// @include      https://www.mturk.com/mturk/dashboard*
// @grant        GM_log
// @grant        GM_setClipboard
// @require      https://code.jquery.com/jquery-3.0.0-beta1.min.js
// @include      https://worker.mturk.com/dashboard*
// @grant        GM_xmlhttpRequest
// @connect      mturk.com
// ==/UserScript==

if (location.href.indexOf(`https://www.mturk.com/mturk/dashboard`) !== -1) {
	var LOADED = $("#total_earnings_amount").length;
	if (LOADED){

		// Functions that can be commented out if you don't want it to run.
		Todays_Projected_Earnings();
		Todays_Bonuses();
		Best_Worst_Case();
		Real_Stats();
		Changes();
		Yearly();
		Goal();

	}
}

if (location.href.indexOf(`https://worker.mturk.com/dashboard`) !== -1) {
	initialize();

	// Functions that can be commented out if you don't want it to run.
	allApprovedRate();
	allRejectedRate();
	fourDigitPercents();
	rejectionsBelow99();
	rejectionsBelow95();
	totalLast45Days();
	hitStatusChanges(); // partially working
	todaysActivity();
}

// Don't touch anything below here.
function Todays_Projected_Earnings(){
	var TPEhitLOG = {}; var TPEdetailsLOG = {}; var pe = 0;

	var today = $("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).prop("href");

	var $peTR = $('<div id="TPE_div" class="even" style="display:table-row">');
	var $peTD1 = $('<td class="metrics-table-first-value">');
	var $peTD2 = $('<td>');
	var $peA = $('<a href="javascript:void(0)">Today\'s Projected Earnings</a>');
	var $TPE_details = $('<span style="color: blue; font-size: 10px; cursor: pointer; float: right;">Details<img style="margin-left: 5px;" src="/media/more.gif" border="0/"></span>');
	var $peSPAN = $('<span class="reward">$0.00</span>');
	$("td.metrics-table-first-value:contains(Total Earnings)").parent().after($peTR);
	$peTR.append($peTD1.append($peA,$TPE_details),$peTD2.append($peSPAN));

	var $TPED_table = $('<table style="display: none;" width="760" align="center" cellspacing="0" cellpadding="0">');
	var $TPED_tboday = $('<tbody>');
	var $TPED_tr_1 = $('<tr id="TPE_tr"  height="25px"><td width="10" bgcolor="#7fb4cf" style="padding-left: 10px;"></td><td width="100%" bgcolor="#7fb4cf" class="white_text_14_bold">Today\'s Projected Earnings Details&nbsp;&nbsp;<a id="fourmEXPORT" href="javascript:void(0)" class="whatis" >(Forum Export)</a></td><td width="10" align="right" bgcolor="#7fb4cf"></td></tr>');
	var $TPED_tr_2 = $('<tr><td class="container-content" colspan="3"><table class="metrics-table" width="100%"><tbody><tr><td width="100%"><table class="metrics-table" width="100%"><tbody id="tbody2"></tbody></table></td></tr></tbody></table></td></tr>');
	var $TPED_tr_h = $('<tr class="metrics-table-header-row"><th class="metrics-table-first-header">Requester</th><th>Submitted</th><th>Projected</th></tr>');

	$("#subtabs_and_searchbar").next().next().after($TPED_table);
	$TPED_table.append($TPED_tboday);
	$TPED_tboday.append($TPED_tr_1,$TPED_tr_2);
	$("#tbody2").append($TPED_tr_h);

	$("#fourmEXPORT").click(function(){
		var exportcode = "";
		var bonus = $("#bonus").text();
		if (bonus !== "$0.00"){
			var total = (Number(pe)+Number(bonus.replace(/[^0-9.]/g, ""))).toFixed(2);
			exportcode += "[b]Today's Projected Earnings: $"+Number(pe).toFixed(2)+" + Bonuses: "+bonus+" = $"+total+"[/b]\n";

		}
		else {
			exportcode += "[b]Today's Projected Earnings: $"+Number(pe).toFixed(2)+"[/b]\n";
		}

		var today_submitted   = $("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().text();
		var today_approved    = $("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().text();
		var today_rejected    = $("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().next().text();
		var today_pending     = $("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().next().next().text();


		exportcode +=
			'[spoiler=Today\'s Projected Earnings Overview][table]' +
			'[tr][td]Submitted[/td][td]' + today_submitted + '[/td][/tr]' +
			'[tr][td]Approved[/td][td]' + today_approved + '[/td][/tr]' +
			'[tr][td]Rejected[/td][td]' + today_rejected + '[/td][/tr]' +
			'[tr][td]Pending[/td][td]' + today_pending + '[/td][/tr]' +
			'[/table][/spoiler]';


		GM_setClipboard(exportcode);
		alert("Forum Export copied to your clipboard.");
	});

	$peA.click(function(){
		if ($peA.text() === "Today's Projected Earnings"){
			var confirmation = confirm("Are you sure you want to recalculate Today's Projected Earnings?");
			if (confirmation === true){
				TPEhitLOG = {}; TPEdetailsLOG = {}; pe = 0;
				$("#tbody2").find("tr.odd, tr.even").remove();
				getDATA(today);
				$peSPAN.text("$0.00");
			}
		}
	});

	$TPE_details.click(function(){
		$TPE_details.find("img").attr("src", ($TPE_details.find("img").attr("src") === "/media/more.gif") ? "/media/less.gif" : "/media/more.gif");
		$TPED_table.toggle();
	});

	if (today){
		var date = today.split("encodedDate=")[1];
		if (date === localStorage.TPE_date){
			if (localStorage.TPEhitLOG){
				TPEhitLOG = JSON.parse(localStorage.TPEhitLOG);
			}
			pe = Number(localStorage.TPE_pe) || 0;
			$peSPAN.text("$"+Number(pe).toFixed(2));
			getDATA(localStorage.TPE_lastpage);
		}
		else {
			localStorage.TPE_date = date;
			localStorage.Goal_progress = 0;
			TPEhitLOG = {}; pe = 0;
			$peSPAN.text("$0.00");
			getDATA(today);
		}
	}

	function getDATA(URL){
		var page = URL.match(/Number=([0-9]*)/g);
		if (page){
			$peA.text("Calculating Page "+page.toString().replace(/[^0-9.]/g, ""));
		}
		else {
			localStorage.removeItem("TPEhitLOG");
			localStorage.Goal_progress = 0;
			$peA.text("Calculating Page 1");
		}

		$.get(URL, function(data){
			var $data = $(data);
			var $hits = $data.find("#dailyActivityTable").find("tr[valign='top']");
			var pagereqerr = $data.find("td.error_title:contains(You have exceeded the maximum allowed page request rate for this website.)").length;
			var noactivity = $data.find("#dailyActivityTable").find("td:contains(You have no HIT activity on this day matching the selected status.)").length;
			if ($hits.length){
				console.log("hit length");
				var url = $data.find("a:contains(Next)[href*=statusdetail]").eq(0).prop("href");
				for (var i = 0; i < $hits.length; i++){
					var req = $hits.eq(i).find("td.statusdetailRequesterColumnValue").text().trim();
					var title = $hits.eq(i).find("td.statusdetailTitleColumnValue").text().trim();
					var reward = $hits.eq(i).find("td.statusdetailAmountColumnValue").text().trim();
					var status = $hits.eq(i).find("td.statusdetailStatusColumnValue").text().trim();
					var reqid = $hits.eq(i).find("a").prop("href").split("requesterId=")[1].split("&")[0];
					var hitid = $hits.eq(i).find("a").prop("href").split("HIT+")[1];

					if (!TPEhitLOG[hitid]){
						TPEhitLOG[hitid] = {
							req    : req,
							title  : title,
							reward : reward,
							status : status,
							reqid  : reqid,
							hitid  : hitid
						};
					}
				}
				if (url){
					getDATA(url);
				}
				else {
					pe = 0;
					for(var key in TPEhitLOG){
						if (TPEhitLOG[key].status !== "Rejected"){
							pe += parseFloat(TPEhitLOG[key].reward.replace(/[^0-9.]/g, ""));
						}
						if (!TPEdetailsLOG[TPEhitLOG[key].reqid]){
							TPEdetailsLOG[TPEhitLOG[key].reqid] = {
								req    : TPEhitLOG[key].req,
								submit : 1,
								reward : parseFloat(TPEhitLOG[key].reward.replace(/[^0-9.]/g, "")),
								reqid  : TPEhitLOG[key].reqid
							};
						}
						else {
							TPEdetailsLOG[TPEhitLOG[key].reqid].submit = TPEdetailsLOG[TPEhitLOG[key].reqid].submit + 1;
							TPEdetailsLOG[TPEhitLOG[key].reqid].reward = TPEdetailsLOG[TPEhitLOG[key].reqid].reward + parseFloat(TPEhitLOG[key].reward.replace(/[^0-9.]/g, ""));
						}
					}

					if (!TPEdetailsLOG.bonuses && $("#bonus").length){
						TPEdetailsLOG.bonuses  = {
							req    : "Bonuses",
							submit : "N/A",
							reward : parseFloat($("#bonus").text().replace(/[^0-9.]/g, "")),
							reqid  : "N/A"
						};
					}
					else if ($("#bonus").length){
						TPEdetailsLOG.bonuses.reward = parseFloat($("#bonus").text().replace(/[^0-9.]/g, ""));
					}

					var d_sorted = Object.keys(TPEdetailsLOG).sort(function(a,b){return TPEdetailsLOG[a].reward - TPEdetailsLOG[b].reward;});
					var oddeven = true;
					for (var j = d_sorted.length-1; j > -1; j--){
						var dkey = d_sorted[j];
						var d_req = TPEdetailsLOG[dkey].req;
						var d_submitted = TPEdetailsLOG[dkey].submit;
						var d_reward = Number(TPEdetailsLOG[dkey].reward).toFixed(2);
						if (oddeven){
							oddeven = false;
							$("#tbody2").append('<tr class="odd"><td class="metrics-table-first-value">'+d_req+'</td><td>'+d_submitted+'</td><td><span class="reward">$'+d_reward+'</span></td></tr>');
						}
						else {
							oddeven = true;
							$("#tbody2").append('<tr class="even"><td class="metrics-table-first-value">'+d_req+'</td><td>'+d_submitted+'</td><td><span class="reward">$'+d_reward+'</span></td></tr>');
						}
					}
					localStorage.TPEhitLOG = JSON.stringify(TPEhitLOG);
					localStorage.TPE_lastpage = URL;
					localStorage.TPE_pe = pe;
					$peA.text("Today's Projected Earnings");
					$peSPAN.text("$"+Number(pe).toFixed(2));
					localStorage.Goal_percent = ((Number(localStorage.TPE_pe)/Number(localStorage.Goal_goal))*100);
					localStorage.Goal_progress = Number(pe)-Number(localStorage.Goal_goal);
					if ($("#goalDIV").length){
						$("#progress").width(Number(localStorage.Goal_percent)+"%");
						$("#progressper").text(Number(localStorage.Goal_progress).toFixed(2));
					}
					Unsynced();
				}
			}
			else if (noactivity){
				console.log("no activity");
				localStorage.TPE_lastpage = URL;
				localStorage.TPE_pe = 0;
				localStorage.Goal_progress = 0;
				$peA.text("Today's Projected Earnings");
				$peSPAN.text("$0.00");
			}
			else if (pagereqerr) {
				console.log("set timeout");
				setTimeout(function(){ getDATA(URL); }, 2000);
			}
		});
	}

	function Unsynced(){
		var hitscalced = Object.keys(TPEhitLOG).length;
		var submitted  = Number($("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().text());

		if (hitscalced < submitted){
			$peSPAN.css({backgroundColor:"red"});
		}
		else {
			$peSPAN.css({backgroundColor:""});
		}
	}
}

function Goal(){
	if (!localStorage.Goal_percent){
		localStorage.Goal_percent = 0;
	}
	if (!localStorage.Goal_progress){
		localStorage.Goal_progress = 0;
	}
	if (!localStorage.Goal_goal){
		localStorage.Goal_goal = 25.00;
	}
	if ($("#bonusDIV").length){
		var $goalDIV0 = $('<div id="goalDIV" class="even" style="display:table-row">');
		$($goalDIV0).append('<td class="metrics-table-first-value"><div id="progressbar" style="width: 100%; height: 7px; border: 1px solid #7fb4cf; border-radius: 3px; overflow: hidden; margin-top: 3px; text-align: center; -webkit-user-select: none; -moz-user-select: none;"><div id="progress" style="height: 100%; background-color: #7fb4cf; -webkit-user-select: none; -moz-user-select: none;"></div></div></td><td><span id="progressper" class="reward">0%</span></td>');
		$("#bonusDIV").after($goalDIV0);
	}
	else {
		var $goalDIV1 = $('<div id="goalDIV" class="odd" style="display:table-row">');
		$($goalDIV1).append('<td class="metrics-table-first-value"><div id="progressbar" style="width: 100%; height: 7px; border: 1px solid #7fb4cf; border-radius: 3px; overflow: hidden; margin-top: 3px; text-align: center; -webkit-user-select: none; -moz-user-select: none;"><div id="progress" style="height: 100%; background-color: #7fb4cf; -webkit-user-select: none; -moz-user-select: none;"></div></div></td><td><span id="progressper" class="reward">0%</span></td>');
		$("#TPE_div").after($goalDIV1);
	}

	$("#progress").width(Number(localStorage.Goal_percent)+"%");
	$("#progressper").text(Number(localStorage.Goal_progress).toFixed(2));

	$("#progressbar").dblclick(function(e){
		e.preventDefault();
		var goal = prompt("Please enter your goal", localStorage.Goal_goal);
		if (goal !== null) {
			localStorage.Goal_goal = goal.replace(/[^0-9.]/g, "");
			localStorage.Goal_percent = ((Number(localStorage.TPE_pe)/Number(localStorage.Goal_goal))*100);
			localStorage.Goal_progress = Number(localStorage.TPE_pe)-Number(localStorage.Goal_goal);
			$("#progress").width(Number(localStorage.Goal_progress)+"%");
			$("#progressper").text(Number(localStorage.Goal_progress).toFixed(2));
		}
	});
}

function Todays_Bonuses(){
	var today = $("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).prop("href");

	var $bonusDIV = $('<div id="bonusDIV" class="odd" style="display:table-row">');
	$($bonusDIV).append('<td class="metrics-table-first-value"><a href="javascript:void(0)">Today\'s Bonuses</a></td><td><span id="bonus" class="reward">$0.00</span></td>');
	$("#TPE_div").after($bonusDIV);

	if (today){
		var date = today.split("encodedDate=")[1];
		if (date === localStorage.TB_date){
			if (!localStorage.today_start_bonuses){
				localStorage.today_start_bonuses = Number($("#bonus_earnings_amount").text().replace(/[^0-9.]/g, ""));
			}
			Bonuses(localStorage.today_start_bonuses);
		}
		else {
			var today_approved = Number($("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().text());
			if (today_approved === 0){
				localStorage.today_start_bonuses = (Number($("#bonus_earnings_amount").text().replace(/[^0-9.]/g, ""))-Number($("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().next().next().next().text().replace(/[^0-9.]/g, "")));
			}
			else {
				localStorage.today_start_bonuses = Number($("#bonus_earnings_amount").text().replace(/[^0-9.]/g, ""));
			}
			localStorage.TB_date = date;
			Bonuses(localStorage.today_start_bonuses);
		}
	}

	function Bonuses(starting_bonus){
		var total_bonuses  = $("#bonus_earnings_amount").text().replace(/[^0-9.]/g, "");
		$("#bonus").text("$"+(Math.round((Number(total_bonuses)-Number(starting_bonus))*100)/100).toFixed(2));
	}
}

function Real_Stats(){
	var approved = Number($("td.metrics-table-first-value:contains(... Approved)").next().text());
	var rejected = Number($("td.metrics-table-first-value:contains(... Rejected)").next().text());

	$("td.metrics-table-first-value:contains(... Approved)").next().next().text(Math.round(((approved)/(approved+rejected))*1000000)/10000+"%");
	$("td.metrics-table-first-value:contains(... Rejected)").next().next().text(Math.round(((rejected)/(approved+rejected))*1000000)/10000+"%");
}

function Best_Worst_Case(){
	var submitted = Number($("td.metrics-table-first-value:contains(HITs Submitted)").next().text());
	var rejected  = Number($("td.metrics-table-first-value:contains(... Rejected)").next().text());
	var approved  = Number($("td.metrics-table-first-value:contains(... Approved)").next().text());
	var pending   = Number($("td.metrics-table-first-value:contains(... Pending)").next().text());

	var $under99 = $('<span style="color: orange;"> ('+Math.round((rejected-((1.0 - 99/100)*submitted))/((1.0 - 99/100)-1))+' ≥ 99%)</span>');
	var $under95 = $('<span style="color: red;"> ('+Math.round((rejected-((1.0 - 95/100)*submitted))/((1.0 - 95/100)-1))+' ≥ 95%)</span>');
	var $worst   = $('<span style="color: red;">\n'+Math.round(approved/(approved+rejected+pending) * 1000000)/10000+'%</span>');

	$("td.metrics-table-first-value:contains(... Pending)").append($under99,$under95);
	$("td.metrics-table-first-value:contains(... Pending)").next().next().text(Math.round(((submitted-rejected)/submitted)*1000000)/10000+"%").css({"color": "green"}).append($worst);
}

function Changes(){
	var today = $("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).prop("href");

	if (today){
		var date = today.split("encodedDate=")[1];
		if (date !== localStorage.Changes_date){
			localStorage.Changes_date = date;
			localStorage.today_submitted = 0;
			localStorage.today_approved  = 0;
			localStorage.today_rejected  = 0;
			localStorage.today_pending   = 0;
		}
	}

	var earnings_hits     = Number($("#approved_hits_earnings_amount").text().replace(/[^0-9.]/g, ""));
	var earnings_bonuses  = Number($("#bonus_earnings_amount").text().replace(/[^0-9.]/g, ""));
	var earnings_total    = Number($("#total_earnings_amount").text().replace(/[^0-9.]/g, ""));
	var earnings_transfer = Number($("#transfer_earnings").text().replace(/[^0-9.]/g, ""));
	var hits_submitted    = Number($("td.metrics-table-first-value:contains(HITs Submitted)").next().text());
	var hits_approved     = Number($("td.metrics-table-first-value:contains(... Approved)").next().text());
	var hits_rejected     = Number($("td.metrics-table-first-value:contains(... Rejected)").next().text());
	var hits_pending      = Number($("td.metrics-table-first-value:contains(... Pending)").next().text());
	var today_submitted   = Number($("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().text());
	var today_approved    = Number($("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().text());
	var today_rejected    = Number($("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().next().text());
	var today_pending     = Number($("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().next().next().text());

	if (Number(localStorage.earnings_hits) !== earnings_hits){
		$("#approved_hits_earnings_amount").prev().append('<span id="earnings_hits" style="float:right;">+$'+(Math.round((earnings_hits-Number(localStorage.earnings_hits))*100)/100).toFixed(2)+'</span>');
		localStorage.earnings_hits = earnings_hits;
	}
	if (Number(localStorage.earnings_bonuses) !== earnings_bonuses){
		$("#bonus_earnings_amount").prev().append('<span id="earnings_bonuses" style="float:right;">+$'+(Math.round((earnings_bonuses-Number(localStorage.earnings_bonuses))*100)/100).toFixed(2)+'</span>');
		localStorage.earnings_bonuses = earnings_bonuses;
	}
	if (Number(localStorage.earnings_total) !== earnings_total){
		$("#total_earnings_amount").prev().append('<span id="earnings_total" style="float:right;">+$'+(Math.round((earnings_total-Number(localStorage.earnings_total))*100)/100).toFixed(2)+'</span>');
		localStorage.earnings_total = earnings_total;
	}
	if (Number(localStorage.earnings_transfer) !== earnings_transfer){
		if (Number(localStorage.earnings_transfer) > earnings_transfer){
			$("#transfer_earnings").prev().append('<span id="earnings_transfer" style="float:right;">-$'+(Math.round((Number(localStorage.earnings_transfer)-earnings_transfer)*100)/100).toFixed(2)+'</span>');
		}
		else {
			$("#transfer_earnings").prev().append('<span id="earnings_transfer" style="float:right;">+$'+(Math.round((earnings_transfer-Number(localStorage.earnings_transfer))*100)/100).toFixed(2)+'</span>');
		}
		localStorage.earnings_transfer = earnings_transfer;
	}
	if (Number(localStorage.hits_submitted) !== hits_submitted){
		$("td.metrics-table-first-value:contains(HITs Submitted)").append('<span id="hits_submitted" style="float:right;">+'+(hits_submitted-Number(localStorage.hits_submitted))+'</span>');
		localStorage.hits_submitted = hits_submitted;
	}
	if (Number(localStorage.hits_approved) !== hits_approved){
		$("td.metrics-table-first-value:contains(... Approved)").append('<span id="hits_approved" style="float:right;">+'+(hits_approved-Number(localStorage.hits_approved))+'</span>');
		localStorage.hits_approved = hits_approved;
	}
	if (Number(localStorage.hits_rejected) !== hits_rejected){
		$("td.metrics-table-first-value:contains(... Rejected)").append('<span id="hits_rejected" style="float:right;">+'+(hits_rejected-Number(localStorage.hits_rejected))+'</span>');
		localStorage.hits_rejected = hits_rejected;
	}
	if (Number(localStorage.hits_pending) !== hits_pending){
		if (Number(localStorage.hits_pending) > hits_pending){
			$("td.metrics-table-first-value:contains(... Pending)").append('<span id="hits_pending" style="float:right;">-'+(Number(localStorage.hits_pending)-hits_pending)+'</span>');
		}
		else {
			$("td.metrics-table-first-value:contains(... Pending)").append('<span id="hits_pending" style="float:right;">+'+(hits_pending-Number(localStorage.hits_pending))+'</span>');
		}
		localStorage.hits_pending = hits_pending;
	}
	if (Number(localStorage.today_submitted) !== today_submitted){
		$("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().append('<span id="today_submitted" style="float:left;">+'+(today_submitted-Number(localStorage.today_submitted))+'</span>');
		localStorage.today_submitted = today_submitted;
	}
	if (Number(localStorage.today_approved) !== today_approved){
		$("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().append('<span id="today_approved" style="float:left;">+'+(today_approved-Number(localStorage.today_approved))+'</span>');
		localStorage.today_approved = today_approved;
	}
	if (Number(localStorage.today_rejected) !== today_rejected){
		$("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().next().append('<span id="today_rejected" style="float:left;">+'+(today_rejected-Number(localStorage.today_rejected))+'</span>');
		localStorage.today_rejected = today_rejected;
	}
	if (Number(localStorage.today_pending) !== today_pending){
		if (Number(localStorage.today_pending) > today_pending){
			$("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().next().next().append('<span id="today_pending" style="float:left;">-'+(Number(localStorage.today_pending)-today_pending)+'</span>');
		}
		else {
			$("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().next().next().append('<span id="today_pending" style="float:left;">+'+(today_pending-Number(localStorage.today_pending))+'</span>');
		}
		localStorage.today_pending = today_pending;
	}
}

function Yearly(){
	var totalearnings = Number($("#total_earnings_amount").text().replace(/[^0-9.]/g, ""));
	var $reward = $("#table_yearly_earnings").find("span.reward");

	for (var i = 0; i < $reward.length; i++){
		totalearnings -= Number($reward.eq(i).text().replace(/[^0-9.]/g, ""));
	}

	var earnings2016 = Number((totalearnings).toFixed(2)).toLocaleString("en");

	var $thisyear = $('<tr class="odd"><td class="metrics-table-first-value">2017</td><td id="yearly_earnings_amount"><span class="reward">$'+earnings2016+'</span></td></tr>');
	$("#table_yearly_earnings").find("tr.metrics-table-header-row").after($thisyear);
}

function Hide_HIT_DB(pending, PEday, PEweek){
	var tbody    = $("#approved_hits_earnings_amount").parent().parent().addClass("tbody");
	var $css = '<style type="text/css">\n';
	if (pending){
		$css += ".tbody > .odd:nth-child(8), .even:nth-child(8) {display: none;}\n";
	}
	if (PEday){
		$css += ".tbody > .odd:nth-child(9), .even:nth-child(9) {display: none;}\n";
	}
	if (PEweek){
		$css += ".tbody > .odd:nth-child(10), .even:nth-child(10) {display: none;}\n";
	}
	$("head").append($css);
}

function initialize() {
	Object.assign(String.prototype, {
		number () {
			return Number(this.replace(/[^0-9.]/g, ``));
		}
	});

	const rows = document.getElementById(`dashboard-hits-overview`).getElementsByClassName(`row`);

	window.dashboard = {
		hits_overview: {
			approved: rows[0].getElementsByClassName(`text-xs-right`)[0].textContent.number(),
			pending: rows[2].getElementsByClassName(`text-xs-right`)[0].textContent.number(),
			rejected: rows[3].getElementsByClassName(`text-xs-right`)[0].textContent.number(),
		},
		daily_hit_statistics_overview: {
			total: {
				submitted: 0,
				approved: 0,
				rejected: 0,
				pending: 0,
				earnings: 0,
			}
		},
		earnings_to_date: {
			bonuses: document.getElementById(`dashboard-earnings-to-date`).getElementsByClassName(`text-xs-right`)[2].textContent.number()
		}
	};

	for (const row of document.getElementsByClassName(`daily_hit_statuses`)) {
		const col = row.children;
		const date = col[0].children[0].href.match(/([0-9])+/)[0];

		window.dashboard.daily_hit_statistics_overview[date] = {};

		[`submitted`, `approved`, `rejected`, `pending`, `earnings`].forEach((currentValue, index) => {
			const value = col[index + 1].textContent.number();

			window.dashboard.daily_hit_statistics_overview[date][currentValue] = value;
			window.dashboard.daily_hit_statistics_overview.total[currentValue] += value;
		});
	}
}

function allApprovedRate() {
	const overview = dashboard.hits_overview;

	const row = document.createElement(`div`);
	row.className = `row m-b-sm`;

	const col1 = document.createElement(`div`);
	col1.className = `col-xs-7`;
	row.appendChild(col1);

	const strong = document.createElement(`strong`);
	strong.textContent = `All Approved Rate`;
	col1.appendChild(strong);

	const col2 = document.createElement(`div`);
	col2.className = `col-xs-5 text-xs-right`;
	col2.textContent = `${((overview.approved + overview.pending) / (overview.approved + overview.pending + overview.rejected) * 100).toFixed(4)}%`;
	row.appendChild(col2);

	const additional = document.getElementById(`HitsOverviewAdditionalInfo`);
	additional.parentNode.insertBefore(row, additional);
}

function allRejectedRate() {
	const overview = dashboard.hits_overview;

	const row = document.createElement(`div`);
	row.className = `row m-b-sm`;

	const col1 = document.createElement(`div`);
	col1.className = `col-xs-7`;
	row.appendChild(col1);

	const strong = document.createElement(`strong`);
	strong.textContent = `All Rejected Rate`;
	col1.appendChild(strong);

	const col2 = document.createElement(`div`);
	col2.textContent = `${(overview.approved / (overview.approved + overview.rejected + overview.pending) * 100).toFixed(4)}%`;
	col2.className = `col-xs-5 text-xs-right`;
	row.appendChild(col2);

	const additional = document.getElementById(`HitsOverviewAdditionalInfo`);
	additional.parentNode.insertBefore(row, additional);
}

function fourDigitPercents() {
	const overview = dashboard.hits_overview;

	for (const row of document.getElementById(`dashboard-hits-overview`).getElementsByClassName(`row`)) {
		if (row.textContent.indexOf(`Approval Rate`) !== -1) {
			row.getElementsByClassName(`text-xs-right`)[0].textContent = `${(overview.approved / (overview.approved + overview.rejected) * 100).toFixed(4)}%`;
		}
		if (row.textContent.indexOf(`Rejection Rate`) !== -1) {
			row.getElementsByClassName(`text-xs-right`)[0].textContent = `${(overview.rejected / (overview.approved + overview.rejected) * 100).toFixed(4)}%`;
		}
	}
}

function rejectionsBelow99() {
	const overview = dashboard.hits_overview;

	const row = document.createElement(`div`);
	row.className = `row m-b-sm`;

	const col1 = document.createElement(`div`);
	col1.className = `col-xs-7`;
	row.appendChild(col1);

	const strong = document.createElement(`strong`);
	strong.textContent = `Rejections ≤ 99%`;
	col1.appendChild(strong);

	const col2 = document.createElement(`div`);
	col2.textContent = Math.round((overview.rejected - (0.01 * (overview.approved + overview.rejected + overview.pending))) / -0.99).toLocaleString();
	col2.className = `col-xs-5 text-xs-right`;
	row.appendChild(col2);

	const additional = document.getElementById(`HitsOverviewAdditionalInfo`);
	additional.insertBefore(row, additional.lastChild);
}

function rejectionsBelow95() {
	const overview = dashboard.hits_overview;

	const row = document.createElement(`div`);
	row.className = `row m-b-sm`;

	const col1 = document.createElement(`div`);
	col1.className = `col-xs-7`;
	row.appendChild(col1);

	const strong = document.createElement(`strong`);
	strong.textContent = `Rejections ≤ 95%`;
	col1.appendChild(strong);

	const col2 = document.createElement(`div`);
	col2.textContent = Math.round((overview.rejected - (0.05 * (overview.approved + overview.rejected + overview.pending))) / -0.95).toLocaleString();
	col2.className = `col-xs-5 text-xs-right`;
	row.appendChild(col2);

	const additional = document.getElementById(`HitsOverviewAdditionalInfo`);
	additional.insertBefore(row, additional.lastChild);
}

function totalLast45Days() {
	const table = document.querySelector(`.mturk-table.hits-statuses`);

	const row = table.insertRow(1);
	row.className = `daily_hit_statuses`;

	const date = row.insertCell(0);
	date.textContent = `Total`;
	date.className = `hidden-xs-down col-sm-2 col-md-2`;

	const submitted = row.insertCell(1);
	submitted.textContent = window.dashboard.daily_hit_statistics_overview.total.submitted;
	submitted.className = `text-xs-right col-xs-3 col-sm-2 col-md-2`;

	const approved = row.insertCell(2);
	approved.textContent = window.dashboard.daily_hit_statistics_overview.total.approved;
	approved.className = `text-xs-right col-xs-3 col-sm-2 col-md-2`;

	const rejected = row.insertCell(3);
	rejected.textContent = window.dashboard.daily_hit_statistics_overview.total.rejected;
	rejected.className = `text-xs-right col-xs-3 col-sm-2 col-md-2`;

	const pending = row.insertCell(4);
	pending.textContent = window.dashboard.daily_hit_statistics_overview.total.pending;
	pending.className = `text-xs-right col-xs-3 col-sm-2 col-md-2`;

	const earnings = row.insertCell(5);
	earnings.textContent = `$${window.dashboard.daily_hit_statistics_overview.total.earnings.toLocaleString(`en-US`, { minimumFractionDigits: 2 })}`;
	earnings.className = `text-xs-right col-xs-3 col-sm-2 col-md-2`;
}

function hitStatusChanges() {
	const oldDashboard = localStorage.dashboard ? JSON.parse(localStorage.dashboard) : null;
	localStorage.dashboard = JSON.stringify(dashboard);

	for (const row of document.getElementsByClassName(`daily_hit_statuses`)) {
		const col = row.children;
		const date = col[0].children[0] ? col[0].children[0].href.match(/([0-9])+/)[0] : `total`;

		[`submitted`, `approved`, `rejected`, `pending`, `earnings`].forEach((currentValue, index) => {
			const value = col[index + 1].textContent.number();
			const oldValue = oldDashboard ? oldDashboard.daily_hit_statistics_overview[date][currentValue] : 0;

			if (value !== oldValue) {
				const change = value - oldValue;
				const changeString = change.toFixed(2).toString().replace(`.00`, ``);

				if (Math.round(change * 100) !== 0) {
					const span = document.createElement(`span`);
					span.textContent = change > 0 ? `+${changeString}` : changeString;
					span.style.float = `left`;
					span.style.fontSize = `70%`;
					col[index + 1].appendChild(span);
				}
			}
		});
	}
}

function todaysActivity() {
	const container = document.createElement(`div`);
	container.className = `row m-b-xl`;

	const col = document.createElement(`div`);
	col.className = `col-xs-12`;
	container.appendChild(col);

	const h2 = document.createElement(`h2`);
	h2.className = `m-b-md`;
	h2.textContent = `Today's Activity`;
	col.appendChild(h2);

	const row = document.createElement(`div`);
	row.className = `row`;
	col.appendChild(row);

	const col2 = document.createElement(`div`);
	col2.className = `col-xs-12`;
	row.appendChild(col2);

	const border = document.createElement(`div`);
	border.className = `border-gray-lightest p-a-sm`;
	col2.appendChild(border);

	const earningsRow = document.createElement(`div`);
	earningsRow.className = `row m-b-sm`;
	border.appendChild(earningsRow);

	const earningsText = document.createElement(`div`);
	earningsText.className = `col-xs-7 col-sm-6 col-lg-7`;
	earningsRow.appendChild(earningsText);

	const earningsStrong = document.createElement(`strong`);
	earningsStrong.textContent = `Projected Earnings`;
	earningsText.appendChild(earningsStrong);

	const earningsValue = document.createElement(`div`);
	earningsValue.className = `col-xs-5 col-sm-6 col-lg-5 text-xs-right`;
	earningsValue.textContent = localStorage.todaysearnings || `$0.00`;
	earningsRow.appendChild(earningsValue);

	const bonusesRow = document.createElement(`div`);
	bonusesRow.className = `row m-b-sm`;
	border.appendChild(bonusesRow);

	const bonusesText = document.createElement(`div`);
	bonusesText.className = `col-xs-7 col-sm-6 col-lg-7`;
	bonusesRow.appendChild(bonusesText);

	const bonusesStrong = document.createElement(`strong`);
	bonusesStrong.textContent = `Bonuses`;
	bonusesText.appendChild(bonusesStrong);

	const bonusesValue = document.createElement(`div`);
	bonusesValue.className = `col-xs-5 col-sm-6 col-lg-5 text-xs-right`;
	bonusesValue.textContent = localStorage.todaysbonuses || `$0.00`;
	bonusesRow.appendChild(bonusesValue);

	const collapse = document.createElement(`div`);
	collapse.id = `TodaysActivityAdditionalInfo`;
	collapse.className = `collapse`;
	border.appendChild(collapse);

	const hr = document.createElement(`hr`);
	hr.className = `m-b-sm m-t-0`;
	collapse.appendChild(hr);

	const hr2 = document.createElement(`hr`);
	hr2.className = `m-b-sm m-t-0`;
	border.appendChild(hr2);

	const control = document.createElement(`a`);
	control.className = `collapse-more-less`;
	control.href = `#TodaysActivityAdditionalInfo`;
	control.setAttribute(`aria-controls`, `TodaysActivityAdditionalInfo`);
	control.setAttribute(`aria-expanded`, `false`);
	control.setAttribute(`data-toggle`, `collapse`);
	border.appendChild(control);

	const more = document.createElement(`span`);
	more.className = `more`;
	control.appendChild(more);

	const plus = document.createElement(`i`);
	plus.className = `fa fa-plus-circle`;
	more.appendChild(plus);

	const moreText = document.createTextNode(`\nMore\n`);
	more.appendChild(moreText);

	const less = document.createElement(`span`);
	less.className = `less`;
	control.appendChild(less);

	const minus = document.createElement(`i`);
	minus.className = `fa fa-minus-circle`;
	less.appendChild(minus);

	const lessText = document.createTextNode(`\nLess\n`);
	less.appendChild(lessText);

	const side = document.querySelector(`.col-md-push-8`);
	side.insertBefore(container, side.firstChild);

	const today = document.querySelector(`a[href^="/status_details/"]`);

    console.log(`today b`)
	if (today.textContent === `Today`) {
        console.log(`today a`)
		const date = today.href.match(/([0-9])+/)[0];

		if (date === localStorage.WMTD_date) {
			if (!localStorage.WMTD_bonusStart) {
				localStorage.WMTD_bonusStart = window.dashboard.earnings_to_date.bonuses;
			}
		}
		else {
			if (window.dashboard.daily_hit_statistics_overview[date].approved === 0) {
				localStorage.WMTD_bonusStart = dashboard.earnings_to_date.bonuses - dashboard.daily_hit_statistics_overview[date].earnings;
			}
			else {
				localStorage.WMTD_bonusStart = dashboard.earnings_to_date.bonuses;
			}
		}

		bonusesValue.textContent = `$${(dashboard.earnings_to_date.bonuses - localStorage.WMTD_bonusStart).toLocaleString(`en-US`, { minimumFractionDigits: 2 })}`;

		const hitLog = date === localStorage.WMTD_date ? localStorage.WMTD_hitLog ? JSON.parse(localStorage.WMTD_hitLog) : {} : {};

		const get = async (url, rescan) => {
			try {
				const page = url.match(/Number=([0-9]*)/);

				earningsValue.textContent = `Calculating Page ${page ? page[1] : `1`}`;

				const response = await new Promise((resolve) => {
					GM_xmlhttpRequest({
						method: `GET`,
						url: url,
						onload: resolve
					});
				});
				const text = response.responseText;

				if (text.indexOf(`You have exceeded the maximum allowed page request rate for this website.`) !== -1) {
					return setTimeout(get, 2000, url, rescan);
				}

				if (text.indexOf(`You have no HIT activity on this day matching the selected status.`) !== -1) {
					return false;
				}

				localStorage.WMTD_lastPage = url;

				const doc = new DOMParser().parseFromString(text, `text/html`);

				const hits = doc.getElementById(`dailyActivityTable`).querySelectorAll(`tr[valign="top"]`);

				if (hits.length) {
					for (const hit of hits) {
						const td = hit.children;
						const obj = {
							req: td[0].textContent.trim(),
							tit: td[1].textContent.trim(),
							rew: td[2].textContent.trim().number(),
							sta: td[3].textContent.trim(),
							rid: td[0].getElementsByTagName(`a`)[0].href.match(/requesterId=([A-Z0-9]+)/)[1],
							hid: td[0].getElementsByTagName(`a`)[0].href.match(/hitId=([A-Z0-9]+)/)[1]
						};

						hitLog[obj.hid] = obj;
					}

					const logLength = Object.keys(hitLog).length;
					const expectedLength = (page ? page[1].number() * 25 - 25 : 0) + hits.length;

					if (!rescan && logLength !== expectedLength) {
						return get(today.href, true);
					}
					else {
						localStorage.WMTD_hitLog = JSON.stringify(hitLog);
					}

					const next = doc.querySelector(`img[src="/media/right_arrow.gif"]`);

					if (next) {
						return get(next.parentElement.href.replace(`worker`, `www`), rescan);
					}
					else {

						let projectedEarnings = 0;
						const reqLog = {};

						for (const key in hitLog) {
							if (hitLog[key].status !== `Rejected`) {
								projectedEarnings += hitLog[key].rew;
							}
							if (!reqLog[hitLog[key].rid]){
								reqLog[hitLog[key].rid] = {
									req: hitLog[key].req,
									submit: 1,
									reward: hitLog[key].rew,
									reqid: hitLog[key].rid
								};
							}
							else {
								reqLog[hitLog[key].rid].submit += 1;
								reqLog[hitLog[key].rid].reward += hitLog[key].rew;
							}
						}

						const sort = Object.keys(reqLog).sort((a, b) => reqLog[a].reward - reqLog[b].reward);

						const fragment = document.createDocumentFragment();

						for (let i = sort.length - 1; i > -1; i--) {
							const key = sort[i];
							const req = reqLog[key].req;
							const submit = reqLog[key].submit;
							const reward = `$${reqLog[key].reward.toLocaleString(`en-US`, { minimumFractionDigits: 2 })}`;

							const reqRow = document.createElement(`div`);
							reqRow.className = `row m-b-sm`;
							fragment.appendChild(reqRow);

							const requester = document.createElement(`div`);
							requester.className = `col-xs-6`;
							reqRow.appendChild(requester);

							const requesterStrong = document.createElement(`strong`);
							requesterStrong.textContent = req;
							requester.appendChild(requesterStrong);

							const submitValue = document.createElement(`div`);
							submitValue.className = `col-xs-3 text-xs-right`;
							submitValue.textContent = submit;
							reqRow.appendChild(submitValue);

							const rewardValue = document.createElement(`div`);
							rewardValue.className = `col-xs-3 text-xs-right`;
							rewardValue.textContent = reward;
							reqRow.appendChild(rewardValue);
						}

						collapse.appendChild(fragment);

						earningsValue.textContent = `$${projectedEarnings.toLocaleString(`en-US`, { minimumFractionDigits: 2 })}`;
					}
				}
			}
			catch (error) {
				console.error(error);
			}
		};

		get(date === localStorage.WMTD_date ? localStorage.WMTD_lastPage ? localStorage.WMTD_lastPage : today.href : today.href, false);

		localStorage.WMTD_date = date;
	}
	else {
		earningsValue.textContent = `N/A`;
		bonusesValue.textContent = `N/A`;
	}
}