JR Mturk Panda Crazy

Collects panda's for you at a certain cycle instead of timers. Lot of organizing of panda's and grouping them together to start and stop them at once.

As of 2016-08-25. See the latest version.

// ==UserScript==
// @name        JR Mturk Panda Crazy
// @version     0.3.5
// @description Collects panda's for you at a certain cycle instead of timers. Lot of organizing of panda's and grouping them together to start and stop them at once.
// @author      (JohnnyRS on mturkgrind.com and mturkcrowd.com) johnnyrs@allbyjohn.com
// @include     http*://www.mturk.com/mturk/welcome?pandacrazy=on*
// @require     http://code.jquery.com/jquery-2.1.4.min.js
// @require     http://code.jquery.com/ui/1.11.4/jquery-ui.min.js
// @require     https://cdnjs.cloudflare.com/ajax/libs/jquery-layout/1.3.0-rc-30.79/jquery.layout.min.js
// @resource    jQueryUICSS          http://code.jquery.com/ui/1.11.4/themes/pepper-grinder/jquery-ui.css
// @resource    jQueryLayoutCSS      https://cdnjs.cloudflare.com/ajax/libs/jquery-layout/1.3.0-rc-30.79/layout-default.css
// @connect     allbyjohn.com
// @connect     mturk.com
// @connect     tiny.cc
// @connect     ibotta.com
// @grant       GM_getValue
// @grant       GM_setValue
// @grant       GM_deleteValue
// @grant       GM_addStyle
// @grant 		GM_xmlhttpRequest
// @grant       GM_getResourceText
// @grant       GM_setClipboard
// @namespace   https://greasyfork.org/users/6406
// ==/UserScript==

var gScriptVersion = "0.3.5";
var gScriptName = "pandacrazy";
var gDatabaseVersion = "JRAPR16-1.1-1.1.1"; // JR[Date]-[requesters DB Reset].[Alarms DB reset]-[requesters DB Version].[Options DB Version].[Tabs DB Version]
var gResetDBVersion = gDatabaseVersion.split("-")[1];
var gDefaultDBVersion = gDatabaseVersion.split("-")[2];
var gLocation = window.location.href;
var gSlowDownAuto = true;
var gResetAllData = false;
var gDelayedSave = false;
var gScriptStatus = "normal";
var gNotification = true;
var gFullQueue = false;
var gFullQueueTimer = null;
var gSavedSearchArea = "", gSavedAddUrl = "";
var gMyLayout = null, gAcceptedLogTab = null, gStatusLogTab = null, gQueueWatchTab = null, mCoinSound = [];
var gMainData = {"hitCollection":{},"displayInfo":"1","accepted":0,"skipped":0,"errors":0,"searched":0,"noHits":0,"fullQueue":0,"orphan":0,"tooFast":0,"savedCycleNum":1,
                 "hitsInQueue":0,"queueStatus":null,"notQual":0,"lastElapsed":0,"jobs":0,"payCounter":0,"projectedEarnings":0,"missed":0};
var gMainMenu = [{"name":"Main","theobject":null}];
var gDefaultRequestersOptions = {};
var gDefaultLayout = {};
var gDefaultSounds = {};
var gHitBgColor="#AFEEEE", gFilteredHitBgColor="#D1E5E5", gSearchesHitBgColor="#AED2D2", gButtonOffBgColor="#FFFFF0", gButtonOnBgColor="#008000";
var gButtonDelayHamBgColor="#00A3CC", gButtonDisabledBgColor="#D3D3D3", gHitMutedColor="#8B4513", gBlockedBgColor="#3D3D3D";
var gTitleColor="#000080", gButtonOffColor="black", gButtonOnColor="white", gButtonDisabledColor="#808080", gNotQualedBgColor="#DDA0DD", gBlockedColor = "#FFF5EE";
var gHitMutedBorderStyle="dotted", gHitBorderStyle="solid", gHitTextColor="#000000", gHitShortIdColor = "#551A8B";
var gZingOptions = {
    "0.01":{"SearchGroupAllowed":1,"TallyCountTotalAllowed":0,"MaxProductsSearch":0,"AcceptCodesSearching":false,"MaxReceiptImages":3},
    "0.03":{"SearchGroupAllowed":2,"TallyCountTotalAllowed":0,"MaxProductsSearch":2,"AcceptCodesSearching":true,"MaxReceiptImages":3},
    "0.05":{"SearchGroupAllowed":3,"TallyCountTotalAllowed":0,"MaxProductsSearch":4,"AcceptCodesSearching":true,"MaxReceiptImages":4},
    "0.07":{"SearchGroupAllowed":7,"TallyCountTotalAllowed":0,"MaxProductsSearch":5,"AcceptCodesSearching":true,"MaxReceiptImages":8}
};
var gZingFuncOptions = {
    "1":{"filterName":"Parse Zing Hit Page","functionName":parseZingHitPage}
};
var gAlarmSounds = {
    "less2":{"nameVar":"JR_PANDA_Soundless2","default":"http://tiny.cc/c6c1ay","audio":null,"desc":"Hits paying less than |: ","payRate":"0.02","lessMinutes":"99","base64":null},
    "less2Short":{"nameVar":"JR_PANDA_Soundless2Short","default":"http://tiny.cc/kyh1ay","audio":null,"desc":"Hits paying less than | with a short timer less than | minute(s): ","payRate":"0.02","lessMinutes":"2","base64":null},
    "less5":{"nameVar":"JR_PANDA_Soundless5","default":"http://tiny.cc/g7h1ay","audio":null,"desc":"Hits paying less than |: ","payRate":"0.05","lessMinutes":"99","base64":null},
    "less5Short":{"nameVar":"JR_PANDA_Soundless5Short","default":"http://tiny.cc/99h1ay","audio":null,"desc":"Hits paying less than | with a short timer less than | minute(s): ","payRate":"0.05","lessMinutes":"5","base64":null},
    "less15":{"nameVar":"JR_PANDA_Soundless15","default":"http://tiny.cc/qai1ay","audio":null,"desc":"Hits paying less than |: ","payRate":"0.15","lessMinutes":"99","base64":null},
    "less15Short":{"nameVar":"JR_PANDA_Soundless15Short","default":"http://tiny.cc/uai1ay","audio":null,"desc":"Hits paying less than | with a short timer less than | minute(s): ","payRate":"0.15","lessMinutes":"8","base64":null},
    "less99":{"nameVar":"JR_PANDA_Soundless99","default":"http://tiny.cc/gbi1ay","audio":null,"desc":"Hits paying MORE than |: ","payRate":"0.15","lessMinutes":"99","base64":null},
    "fullQueue":{"nameVar":"JR_PANDA_FullQueue","default":"http://tiny.cc/wietby","audio":null,"desc":"You have a full queue!","payRate":"","lessMinutes":"99","base64":null},
    "queueAlert":{"nameVar":"JR_PANDA_QueueAlert","default":"http://tiny.cc/cnxyby","audio":null,"desc":"Lowest timed hit in queue is less than || minutes.","payRate":"","lessMinutes":"5","base64":null},
    "hasToPause":{"nameVar":"JR_PANDA_hasToPause","default":"http://tiny.cc/w823by","audio":null,"desc":"Logged out or captcha alarm!","payRate":"","lessMinutes":"99","base64":null},
};
var gSoundOptions = null;
var gLastAlarm = "";
var gSoundFile = null;
var gTabIndex = 0;
var gMouseDownTimeoutId = null;
var gPressAndHold = false;
var gQueueData = [];
var gQueueCount = {};
var gMuteQueueWatch = false;
var gGroupings = {};
var gGroupingsSort = [];
var gGroupingData = {"JR First":{"theNumber":"0","description":"First grouping by default.","grouping":[],"delayed":[]}};
var gDefaultGroupingData = {"JR First":{"theNumber":"0","description":"First grouping by default.","grouping":[],"delayed":[]}};
var gTabsInfo = {};
var gDefaultTabsInfo = {"nextTabNumber":"4","tabCount":"3"};
var gTabsData = [];
var gDefaultTabsData = [{"tabName":"Main","tabNumber":"1","positions":null},{"tabName":"Daily Hits","tabNumber":"2","positions":null},{"tabName":"Rare Hits","tabNumber":"3","positions":null}];
var gMainOptions = {};
var gDefaultMainOptions = {"cycleNumber":980,"HamCycleNumber":700,"autoSlowDown":true,"cycleAutoIncrease":10,"alarmVolume":80,"cycleIncrease":10,"cycleDecrease":10,"cycleAdding":650,"queueTimer":40000,"hamDelayTimer":20,"showHelpTooltips":true,"cycleNumber2":1400,"cycleNumber3":2100,"disableCaptchaAlert":false,"disableQueueAlert":false,"disableNotifications":false,"debugger":0};
var gRequestersData = {};
var jobDataDefault = {"requesterName":"","requesterId":"","groupId":"","pay":"","title":"","duration":"0","hitsAvailable":0,"timeLeft":"",
		"continueURL":"","returnURL":"","durationParsed":null,"jobNumber":"-1","friendlyRName":"","friendlyTitle":""};
var gDefaultRequestersData = {
    "0":{"requesterName":gDatabaseVersion,"requesterId":28,"action":"","groupId":"","pay":"","qual":"","title":"","queueLimit":0,"duration":"0","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":"1","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":20,"friendlyRName":"","friendlyTitle":"","queueHitLimit":0,"weight":0},
    "4":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"38MNOT6KWI2RBQGVM0MBPUP6RVH0T8","pay":"0.01","qual":"ibotta","title":"Are these the same?","queueLimit":0,"duration":"0","audioforce":"less2","dailyLimit":0,"mute":false,"position":null,"tabNumber":"2","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":20,"friendlyRName":"","friendlyTitle":"","queueHitLimit":15,"weight":0},
    "5":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"3XLZDG4M7280UYEGHLXC92IBFQGZL0","pay":"0.01","qual":"","title":"Are these the same?","queueLimit":0,"duration":"0","audioforce":"less2","dailyLimit":0,"mute":false,"position":null,"tabNumber":"2","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":20,"friendlyRName":"","friendlyTitle":"","queueHitLimit":15,"weight":0},
    "6":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"3ZXRRTK2NDCB5NW5M24C9P2OWG41OF","pay":"0.01","qual":"ibotta","title":"Does this receipt contain the following products?","queueLimit":0,"duration":"0","audioforce":"less2","dailyLimit":0,"mute":false,"position":null,"tabNumber":"2","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":20,"friendlyRName":"","friendlyTitle":"","queueHitLimit":8,"weight":0},
    "7":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"3NYGPW9OTYRQLJTE9DQJQJRQJ2IZPS","pay":"0.01","qual":"","title":"Does this receipt contain the following products?","queueLimit":0,"duration":"0","audioforce":"less2","dailyLimit":0,"mute":false,"position":null,"tabNumber":"2","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":20,"friendlyRName":"","friendlyTitle":"","queueHitLimit":8,"weight":0},
    "8":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"3R35RPFD7JUTQN8612HRYP7E6LZ1PV","pay":"0.03","qual":"ibotta","title":"Does this receipt contain the following products?","queueLimit":0,"duration":"0","audioforce":"less2","dailyLimit":0,"mute":false,"position":null,"tabNumber":"2","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":20,"friendlyRName":"","friendlyTitle":"","queueHitLimit":8,"weight":0},
    "9":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"3ZXRRTK2NDCB5NW5M24C9P2OVF61OE","pay":"0.03","qual":"","title":"Does this receipt contain the following products?","queueLimit":0,"duration":"0","audioforce":"less2","dailyLimit":0,"mute":false,"position":null,"tabNumber":"2","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":20,"friendlyRName":"","friendlyTitle":"","queueHitLimit":8,"weight":0},
    "10":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"3CRC4NO2BIQQWQ3GX0HLFPTFOD30SA","pay":"0.05","qual":"ibotta","title":"Does this receipt contain the following products?","queueLimit":0,"duration":"60 minutes","audioforce":"less2","dailyLimit":0,"mute":false,"position":null,"tabNumber":"2","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":20,"friendlyRName":"","friendlyTitle":"","queueHitLimit":12,"weight":0},
    "11":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"3787DLY3Y49RIF1DIJQB3Z8BUNP1T2","pay":"0.05","qual":"","title":"Does this receipt contain the following products?","queueLimit":0,"duration":"0","audioforce":"less2","dailyLimit":0,"mute":false,"position":null,"tabNumber":"2","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":20,"friendlyRName":"","friendlyTitle":"","queueHitLimit":12,"weight":0},
    "13":{"requesterName":"Viral Mturk","requesterId":"A2UFLDVZ75JD9M","action":"Panda","groupId":"3ZXEP6UEGGA75UPGRQ2UPK3XA4YO8B","pay":"0.25","qual":"","title":"Rate the quality of ads on YouTube","queueLimit":0,"duration":"0","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":"1","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":20,"friendlyRName":"","friendlyTitle":"","queueHitLimit":0,"weight":0},
    "14":{"requesterName":"MyLikes","requesterId":"A239M0XNXTKQZ7","action":"Panda","groupId":"3EGCY5R6XY0PS57S4R2H1KZW7LSAYC","pay":"0.01","qual":"","title":"Identify Images with Mature Content","queueLimit":0,"duration":"0","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":"1","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":20,"friendlyRName":"","friendlyTitle":"","queueHitLimit":0,"weight":0},
    "15":{"requesterName":"MyLikes","requesterId":"A239M0XNXTKQZ7","action":"Panda","groupId":"3USMLONC9E5D7T4TWRD6UWVBJLN85E","pay":"0.03","qual":"","title":"Identify Images with Mature Content","queueLimit":0,"duration":"0","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":"1","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":20,"friendlyRName":"","friendlyTitle":"","queueHitLimit":0,"weight":0},
    "16":{"requesterName":"MyLikes","requesterId":"A239M0XNXTKQZ7","action":"Panda","groupId":"37G59K9AEU0BNMXNCLOH5POEZUC9YI","pay":"0.03","qual":"","title":"Identify Videos with Mature Content","queueLimit":0,"duration":"15 minutes","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":"1","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":20,"friendlyRName":"","friendlyTitle":"","queueHitLimit":0,"weight":0},
    "17":{"requesterName":"Steven Snow","requesterId":"A3GAVAUPTHM0B8","action":"Panda","groupId":"3X19M43Z4VULD73G1I2N3GGRYF10D8","pay":"0.06","qual":"","title":"steven snow search 3X..D8","queueLimit":0,"duration":"0","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":3,"once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":20,"friendlyRName":"","friendlyTitle":"","queueHitLimit":0,"weight":0},
    "18":{"requesterName":"Steven Snow","requesterId":"A3GAVAUPTHM0B8","action":"Panda","groupId":"3TJJ8HSJVIVGSMA3ZXVL0CV5EGV28D","pay":"0.05","qual":"","title":"steven snow url 3T..8D","queueLimit":0,"duration":"0","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":"3","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":20,"friendlyRName":"","friendlyTitle":"","queueHitLimit":0,"weight":0},
    "19":{"requesterName":"Venue Quality","requesterId":"A14AT838CPSKA6","action":"Panda","groupId":"3EM4DVSA8U8J6KF08Q5EM8I2NYE308","pay":"0.01","qual":"","title":"locations same","queueLimit":0,"duration":"0","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":"1","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":20,"friendlyRName":"","friendlyTitle":"","queueHitLimit":0,"weight":0},
    "20":{"requesterName":"Venue Quality","requesterId":"A14AT838CPSKA6","action":"Panda","groupId":"3D8O2NKTAGFJD90I499E0D26RON13W","pay":"0.01","qual":"","title":"locations adult","queueLimit":0,"duration":"5 minutes","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":"1","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":20,"friendlyRName":"","friendlyTitle":"","queueHitLimit":0,"weight":0},
    "21":{"requesterName":"Venue Quality","requesterId":"A14AT838CPSKA6","action":"Panda","groupId":"ZZAWVTYW3Z9ZTAX43ZD0","pay":"0.01","qual":"","title":"locations family","queueLimit":0,"duration":"0","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":"1","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":20,"friendlyRName":"","friendlyTitle":"","queueHitLimit":0,"weight":0},
    "22":{"requesterName":"Annabel","requesterId":"A3HB3KPJ2RZ2K8","action":"Panda","groupId":"3CVHT3IKTXQR8KSLQHD2N8KOQZPR06","pay":"0.50","qual":"","title":"Comparing two statements with each other","queueLimit":0,"duration":"60 minutes","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":"1","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":20,"friendlyRName":"","friendlyTitle":"","queueHitLimit":0,"weight":0},
    "23":{"requesterName":"Rob Grady","requesterId":"AM07BBZNC6UTQ","action":"Panda","groupId":"33X7UBO5WUFB78Y5WJ3MVC35LFMU05","pay":"0.03","qual":"","title":"Transcribe Waffle House Guest Check","queueLimit":0,"duration":"5 minutes","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":"1","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":20,"friendlyRName":"","friendlyTitle":"","queueHitLimit":0,"weight":0}
};
var gExcludeIds = ["38FT9G80DL83PUCSQBVANJBIKGSLHM"];
var jqUI_CssSrc = GM_getResourceText("jQueryUICSS");
var jqLayout_CssSrc = GM_getResourceText("jQueryLayoutCSS");

Date.prototype.stdTimezoneOffset = function() {
    var jan = new Date(this.getFullYear(), 0, 1);
    var jul = new Date(this.getFullYear(), 6, 1);
    return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset());
};

Date.prototype.dst = function() {
    return this.getTimezoneOffset() < this.stdTimezoneOffset();
};
function formatAMPM(theFormat,theDate,theTimeZone) {
    var d = (theDate) ? theDate : new Date();
    if (theTimeZone == "mturk") {
        var mturkTZOffset = -8;
        var today = new Date();
        if (today.dst()) mturkTZOffset++;
        var utc = d.getTime() + (d.getTimezoneOffset() * 60000);
        var MturkTime = utc + (3600000 * mturkTZOffset);
        d = new Date(MturkTime);
    }
    var minutes = d.getMinutes().toString().length == 1 ? '0'+d.getMinutes() : d.getMinutes(),
        hours = d.getHours().toString().length == 1 ? '0'+d.getHours() : d.getHours(),
        ampm = d.getHours() >= 12 ? 'pm' : 'am',
        months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
        days = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
    if (theFormat=="short") return ('0' + (d.getMonth()+1)).slice(-2) + '-' + ('0' + d.getDate()).slice(-2) + '-' + d.getFullYear() + '(' + hours + ':' + minutes + ampm + ')';
    else if (theFormat=="onlydate") return ('0' + (d.getMonth()+1)).slice(-2) + '-' + ('0' + d.getDate()).slice(-2) + '-' + d.getFullYear();
    else return days[d.getDay()]+' '+months[d.getMonth()]+' '+d.getDate()+' '+d.getFullYear()+' '+hours+':'+minutes+ampm;
}
function formatTimeZone(theFormat,theDate,theTimeZone) {
    return formatAMPM(theFormat,theDate,theTimeZone);
}
function getTimeLeft(theTime) {
    if (theTime!==null) {
        var tempArray = (theTime.indexOf("second") != -1) ? theTime.split("second")[0].trim().split(" ") : null;
		var seconds = (tempArray) ? parseInt(tempArray[tempArray.length-1]) : 0;
		tempArray = (theTime.indexOf("minute") != -1) ? theTime.split("minute")[0].trim().split(" ") : null;
		var minutes = (tempArray) ? parseInt(tempArray[tempArray.length-1]) : 0;
		tempArray = (theTime.indexOf("hour") != -1) ? theTime.split("hour")[0].trim().split(" ") : null;
		var hours = (tempArray) ? parseInt(tempArray[tempArray.length-1]) : 0;
		tempArray = (theTime.indexOf("day") != -1) ? theTime.split("day")[0].trim().split(" ") : null;
		var days = (tempArray) ? parseInt(tempArray[tempArray.length-1]) : 0;
		tempArray = (theTime.indexOf("week") != -1) ? theTime.split("week")[0].trim().split(" ") : null;
		var weeks = (tempArray) ? parseInt(tempArray[tempArray.length-1]) : 0;
		return( {"weeks":weeks,"days":days,"hours":hours,"minutes":minutes,"seconds":seconds} );
    } else return null;
}

function checkNotifications() {
  // Let's check if the browser supports notifications
  if (!("Notification" in window)) return false;
  else if (Notification.permission === "granted") return true;
  else if (Notification.permission !== 'denied') {
    Notification.requestPermission(function (permission) {
      if (permission === "granted") return true;
    });
  }
  return false;
}
function showNotification( title, message, tag, groupId ) {
	if (gMainOptions.disableNotifications) return;
	showNotification.tagNumber = showNotification.tagNumber || 0;
	showNotification.lastGroupID = showNotification.lastGroupID || "0";
	if (showNotification.lastGroupID != groupId) showNotification.tagNumber++;
	showNotification.lastGroupID = groupId;
    var n = new Notification(title, {
        body: message,
        icon: "http://www.allbyjohn.com/mturk/Messaging-Online-icon.png",
        tag: tag+showNotification.tagNumber});
    if (navigator.userAgent.search("Chrome") >= 0) n.onshow = function () { setTimeout(n.close.bind(n), 28000); };
}

// Database using setValue and getValue
function convertDatabase(theDataBase) {
    var newDataBase = {};
    $.each(theDataBase, function( index, value ) {
        newDataBase[index] = value;
		if (newDataBase[index].action == "preta") newDataBase[index].action = "pantha";
		if (newDataBase[index].requesterId == "30B721SJLR5BYYBNQJ0CVKJESN00OC") newDataBase[index].requesterId = "38MNOT6KWI2RBQGVM0MBPUP6RVH0T8";
		if (newDataBase[index].requesterId == "30B721SJLR5BYYBNQJ0CVKJEQOZ0OB") newDataBase[index].requesterId = "3XLZDG4M7280UYEGHLXC92IBFQGZL0";
    });
    newDataBase[0].requesterName = gDatabaseVersion;
    return newDataBase;
}
function convertTabDatabase() {
	if (gTabsData[0].tabName == "Holder") { // temporary for testing computer
		var newDataBase = [];
		gTabInfo = {"nextTabNumber":"" + gTabsData[0].tabNumber,"tabCount":"" + gTabsData.length};
		$.each(gTabsData, function( index, value ) {
			if (index>0) newDataBase.push(value);
		});
		gTabsData = newDataBase;
	}
}
function getBase64Audio(theData) {
    var base64AudioData = new Uint8Array(theData);
    var i = base64AudioData.length;
    var binaryString = new Array(i);
    while (i--) { binaryString[i] = String.fromCharCode(base64AudioData[i]); }
    var data = binaryString.join('');
    return(window.btoa(data));
}
function fillInSoundOptions(soundOptions) {
	$.each(soundOptions, function( index, value ) {
		gAlarmSounds[index].payRate = value.payRate;
		gAlarmSounds[index].lessMinutes = value.lessMinutes;
		if (value.base64!==null) {
			gAlarmSounds[index].audio = new Audio("data:audio/wav;base64," + JSON.parse(value.base64));
			GM_setValue(gAlarmSounds[index].nameVar,JSON.stringify(value.base64));
		}
	});
}
function loadSoundFiles(soundNumber,keyArray,resetMe) {
	resetMe = resetMe || false;
	var savedDBVersion = gRequestersData[0].requesterName;
	var resetDBVersion = savedDBVersion.split("-")[1];
    if (soundNumber < keyArray.length) {
        if ((gResetDBVersion.split(".")[1] > resetDBVersion.split(".")[1]) || gResetAllData) GM_deleteValue(gAlarmSounds[keyArray[soundNumber]].nameVar);
        var gotBase64 = (resetMe) ? null : GM_getValue(gAlarmSounds[keyArray[soundNumber]].nameVar,null);
        this.firstTime = this.firstTime || false;
        if (gotBase64 === null) {
            if (!this.firstTime) addToWaitDialog("For your first time this might take a few seconds.<br>Loading Alarms ",false);
            this.firstTime = true;
            requestUrl(gAlarmSounds[keyArray[soundNumber]].default,0,function(theResult,theNumber,data1,data2) {
				addToWaitDialog(" .",false);
                var base64 = getBase64Audio(theResult.response);
                GM_setValue(gAlarmSounds[keyArray[soundNumber]].nameVar,JSON.stringify(base64));
                gAlarmSounds[keyArray[soundNumber]].audio = new Audio("data:audio/wav;base64," + base64);
                loadSoundFiles(soundNumber+1,keyArray,resetMe);
            },function() { errorRequest(); }, "", "", "arraybuffer");
        } else {
            gAlarmSounds[keyArray[soundNumber]].audio = new Audio("data:audio/wav;base64," + JSON.parse(gotBase64));
            loadSoundFiles(soundNumber+1,keyArray,resetMe);
        }
    } else continueLoading();
}

function fillInGroupings() {
    $.each(gGroupingData, function( index, value ) {
        if (!value.grouping) value.grouping = [];
        gGroupings[index] = {"data":value,"collecting":false};
        gGroupingsSort.push(index);
		defaultFillIn(value,gDefaultGroupingData["JR First"]);
    });
}
function defaultFillIn(data,defaultData) {
	$.each(defaultData, function( index, value ) {
		if (!(index in data)) { data[index] = value; }
	});
}
function loadInDBVersions(passedDatabase) {
	var tempData = null;
	if (passedDatabase) tempData = passedDatabase;
	else tempData = JSON.parse(GM_getValue("JR_PANDA_RequestersData",JSON.stringify(gDefaultRequestersData)));
	var savedDBVersion = tempData[0].requesterName;
	var resetDBVersion = savedDBVersion.split("-")[1];
	var defaultDBVersion = savedDBVersion.split("-")[2];
	if (gResetDBVersion.split(".")[0] > resetDBVersion.split(".")[0]) {
		GM_deleteValue("JR_PANDA_RequestersData");
		tempData = JSON.parse(GM_getValue("JR_PANDA_RequestersData",JSON.stringify(gDefaultRequestersData)));
	}
	tempData = convertDatabase(tempData);
    $.each(tempData, function( index, value ) { defaultFillIn(value,gDefaultRequestersData[0]); });
	return tempData;
}
function changeOldSettings() {
	if (gMainOptions.cycleIncrease==5) gMainOptions.cycleIncrease = 10;
	if (gMainOptions.cycleDecrease==5) gMainOptions.cycleDecrease = 10;
}
function setupSoundOptions(base64) {
	base64 = base64 || false;
	var soundOptions = {};
	$.each(gAlarmSounds, function( index, value ) {
		var theBase64 = (base64) ? GM_getValue(value.nameVar,null) : null;
		soundOptions[index] = {"payRate":value.payRate,"lessMinutes":value.lessMinutes,"base64":theBase64};
	});
	return soundOptions;
}
function loadSettings() {
	var defaultSoundOptions = setupSoundOptions();
	if (gResetAllData) GM_deleteValue("JR_PANDA_RequestersData");
	gRequestersData = loadInDBVersions();
    if (gResetAllData) GM_deleteValue("JR_PANDA_MainOptions");
    gMainOptions = JSON.parse(GM_getValue("JR_PANDA_MainOptions",JSON.stringify(gDefaultMainOptions)));
	defaultFillIn(gMainOptions,gDefaultMainOptions);
    if (gResetAllData) GM_deleteValue("JR_PANDA_TabsData");
    gTabsData = JSON.parse(GM_getValue("JR_PANDA_TabsData",JSON.stringify(gDefaultTabsData)));
    gTabsInfo = JSON.parse(GM_getValue("JR_PANDA_TabsInfo",JSON.stringify(gDefaultTabsInfo)));
	convertTabDatabase();
    $.each(gTabsData, function( index, value ) { defaultFillIn(value,gDefaultTabsData[0]); });
    if (gResetAllData) GM_deleteValue("JR_PANDA_GroupingData");
    gGroupingData = JSON.parse(GM_getValue("JR_PANDA_GroupingData",JSON.stringify(gDefaultGroupingData)));
    fillInGroupings();
    gSoundOptions = JSON.parse(GM_getValue("JR_PANDA_SoundOptions",JSON.stringify(defaultSoundOptions)));
    loadSoundFiles(0,Object.keys(gAlarmSounds));
	fillInSoundOptions(gSoundOptions);
	changeOldSettings();
}
function saveSettings(doAfter) {
	var soundOptions = setupSoundOptions();
    GM_setValue("JR_PANDA_RequestersData",JSON.stringify(gRequestersData));
    GM_setValue("JR_PANDA_MainOptions",JSON.stringify(gMainOptions));
    GM_setValue("JR_PANDA_TabsData",JSON.stringify(gTabsData));
    GM_setValue("JR_PANDA_TabsInfo",JSON.stringify(gTabsInfo));
    GM_setValue("JR_PANDA_GroupingData",JSON.stringify(gGroupingData));
    GM_setValue("JR_PANDA_SoundOptions",JSON.stringify(soundOptions));
    if (doAfter) setTimeout( function() { doAfter(); },200);
}
function checkDelayedSave() { if (gDelayedSave) saveSettings(); }

// Jquery Creating HTML elements Functions --------
function toggleButton(thisButton,doThisOn,doThisOff,mode,modeStatus) {
	// dothison = status on function, dothisOff = status off function, mode = status mode to force change to, modestatus = force on or off function
    var theStatus = $(thisButton).data("status"); // Get status of the button
    var doStatus = (modeStatus) ? modeStatus : (theStatus != "on" && theStatus!=mode) ? "on" : "off";
    if (mode && theStatus!=mode) $(thisButton).data("status",mode);
    else $(thisButton).data("status",doStatus);
    if (doStatus=="on" && doThisOn) doThisOn($(thisButton).data("theNumber"),thisButton,mode);
    if (doStatus=="off" && doThisOff) doThisOff($(thisButton).data("theNumber"),thisButton,mode);
    updateHitColors($(thisButton).data("theNumber"),thisButton);
}
function toggleButtonOff(thisButton,doThisOn,doThisOff,passedMode) {
    $(thisButton).data("status","off");
    updateHitColors($(thisButton).data("theNumber"),thisButton);
    if (doThisOff) doThisOff($(thisButton).data("theNumber"),thisButton,passedMode);
}
function toggleButtonOn(thisButton,doThisOn,doThisOff) {
	if ($(thisButton).data("status") == "off") {
		$(thisButton).data("status","on");
		updateHitColors($(thisButton).data("theNumber"),thisButton);
		if (doThisOn) doThisOn($(thisButton).data("theNumber"),thisButton);
	}
}
function checkButtonsStatus() {
    if (gScriptStatus == "normal") return true;
    else return false;
}
function createDiv(theHtml) { var inner = (theHtml) ? theHtml : ""; return $('<div>').html(inner); }
function createSpan(theHtml) { var inner = (theHtml) ? theHtml : ""; return $('<span>').html(inner); }
function createTextInput(theValue) { return $("<input>").attr({ "type": "text", "value": theValue }); }
function createCheckbox(theValue) { return $("<input>").attr({ "type": "checkbox", "value": theValue }); }
function createRadioButton(theName,theValue) { return $("<input>").attr({ "type": "radio", "name": theName, "value": theValue }); }
function createLink(theText,theUrl,theTarget,theTitle) { return $('<a>',{text: theText,target: theTarget,title: theTitle,href: theUrl}); }
function createSpanButton(toDo,theHtml,theBackgroundColor,theColor,theFontSize) {
    var backgroundColor = (theBackgroundColor) ? theBackgroundColor : "initial";
    var textColor = (theColor) ? theColor : "initial";
    var fontSize = (theFontSize) ? theFontSize : "9px";
    var theButton = createSpan(theHtml).data({"backgroundColor":backgroundColor,"status":"off","textColor":textColor,"htmlText":theHtml})
        .disableSelection()
        .dblclick(function(e) { e.stopPropagation(); })
        .css({"font-size":fontSize,"padding":"0px 2px","background-color":backgroundColor,"color":textColor,"border":"2px groove red","cursor":"default","margin":"0px 1px"});
    if (toDo) theButton.click( function(e) {
        if (checkButtonsStatus()) {toDo(e);}
    });
    return theButton;
}
function createContainer() {
    var containerDiv = createDiv();
    containerDiv.css({"padding-left":"3px", "padding-right":"3px","padding-top":"0px","padding-bottom":"1px"});
    return containerDiv;
}
function createPanels(goAppend) {
    var panelContainer = createContainer()
        .attr("id","panelContainer")
        .appendTo(goAppend);
    return panelContainer;
}
function createPanel(goAppend) {
    var panel = createContainer().appendTo(goAppend);
    return panel;
}
function createTabs(goAppend,isSortable,idName) {
    var tabList = $("<ul>");
    var tabsContainer = createContainer()
        .attr("id",idName)
        .css({"height":"99%"})
        .appendTo(goAppend);
    tabList.appendTo(tabsContainer);
    tabsContainer.tabs().delegate( "span.ui-icon-close", "click", function(e) {
		var currentTab = $(e.target).closest("li");
		var currentIndex = $(currentTab).index();
		$("#JRMainTabs").tabs("option", "active", currentIndex);
		var returnValue = confirm("Are you sure you want to delete this Tab?\nAll hits inside the tab will be moved to the Main Tab.\nNo Hits will be lost.");
		if (returnValue) {
			var currentAriaTab = $("#" + (currentTab.attr("aria-controls")));
			var mainAriaTab = $("#" + ($("#JRTab_1").attr("aria-controls")));
			var currentData = $(currentTab).data("tabData");
			if (currentData.positions.length>0) {
				for (var i=0, len=currentData.positions.length; i<len; i++) {
					$(mainAriaTab).find(".tabContents").append($(currentAriaTab).find("#JRCellNum_" + currentData.positions[i]));
					gRequestersData[currentData.positions[i]].tabNumber = 1;
					gTabsData[0].positions.push(currentData.positions[i]); // Push hits on main tab
				}
			}
			currentData.positions.splice(0,currentData.positions.length);
			$(currentTab).remove();
			gTabsData.splice(gTabsData.indexOf(currentData),1);
			saveSettings();
			$("#JRMainTabs").tabs( "refresh" );
		}
    });
    if (isSortable) tabList.sortable({placeholder:"sortable-placeholder",delay:300,"items":"li:not(.ui-not-sortable)",dropOnEmpty: true});
    return tabsContainer;
}
function moveToTab(event,ui) {
	if (ui.draggable.data("sameTab")) return;
	var thisTabData = gTabsData[$( "#JRMainTabs" ).tabs( "option", "active" )];
	ui.draggable.data("received",true);
	setTimeout( function() {
		gTabsData[ui.draggable.data("hitInfo").tabIndex].positions.splice(ui.draggable.data("oldPosition"), 1);
		thisTabData.positions.push(ui.draggable.data("theNumber"));
		ui.draggable.data("hitInfo").tabIndex = $(gTabsData).index(thisTabData);
		ui.draggable.data("hitData").tabNumber = thisTabData.tabNumber;
		ui.draggable.detach().appendTo($("#" + $("#JRTab_" + thisTabData.tabNumber).closest( "li" ).attr("aria-controls")).find(".tabContents:first"));
		saveSettings();
	},0);
}
function createTab(tabContainer,theTitle,isSortable,theID,tabData,appendClose) {
    var theClasses = (!appendClose) ? "ui-not-sortable" : "";
    var theLabelClasses = (!appendClose) ? "JRTabLabel" : "JRTabLabel hasHelptip";
    var theLabelTitle = (!appendClose) ? "" : "Right click on tab to edit label for this tab. You can also move this tab. Click on the X to remove this tab.";
    var theTabDiv = createContainer().attr("id","tabs-" + (++gTabIndex));
    var theTabLi = $("<li>").html("<a href=\"#tabs-" + gTabIndex + "\" class=\"" + theLabelClasses + "\"" +
		" title=\"" + theLabelTitle + "\">" + theTitle + "</a>")
        .attr({"id":theID,"class":theClasses})
        .css({"font-size":"10px"})
		.data({"tabData":tabData})
        .appendTo( tabContainer.find("ul") );
    if (appendClose) {
		theTabLi.append(createSpan("Remove Tab").attr({"class":"ui-icon ui-icon-close","role":"presentation"}));
		theTabLi.bind("contextmenu", function(e) {
			if ($(e.target).closest("li").index() > 0) {
				var returnName = prompt("Enter Tab Label : ", $(e.target).html());
				if (returnName && returnName!=="") {
					$(e.target).html(returnName);
					$(e.target).closest("li").data("tabData").tabName = returnName;
					saveSettings();
				}
			}
			e.preventDefault();
			return false;
        });
	}
    theTabDiv.data({"tabData":tabData}).appendTo(tabContainer);
    if (isSortable) {
        theTabLi.click( function() { $(this).focus(); $("#" + $(this).attr("aria-controls")).find(".tabContents").focus(); })
            .droppable({ tolerance: 'pointer', drop: moveToTab,
                over: function( event, ui ) {
					var inTabId = $(event.target).attr("aria-controls");
                    $("#JRMainTabs").tabs("option", "active", $(event.target).index());
                    $(event.target).focus(); $("#" + inTabId).find(".tabContents").focus();
					ui.draggable.data("sameTab",false);
                }
            });
        theTabDiv.html("<br clear='all' class='cleartab'></br>");
    }
    tabContainer.tabs("refresh");
    return theTabDiv;
}
// Alarm function -----------
function playThisSound( keyName ) {
	gLastAlarm = keyName;
    gAlarmSounds[keyName].audio.pause();
    gAlarmSounds[keyName].audio = gAlarmSounds[keyName].audio;
    gAlarmSounds[keyName].audio.currentTime = 0;
    gAlarmSounds[keyName].audio.volume = gMainOptions.alarmVolume/100;
    gAlarmSounds[keyName].audio.play();
}
function playNewSound( AudioObject ) {
    if (gSoundFile) gSoundFile.pause();
    gSoundFile = AudioObject;
    gSoundFile.currentTime = 0;
    gSoundFile.volume = gMainOptions.alarmVolume/100;
    gSoundFile.play();
}

// Main cycler class that handles all timers, queues, pauses, and hams
var theCycler = (function() {
    var privateVars = {
        _timers: [],
        _theQueue: [],
        _theFrontOfTheLineQueue: [],
        _theFrontOfTheLineTimer: [],
        _before: new Date(),
		_lastRemoved: -1,
        _theCycle: 500,
        _realCycle: 500,
        _theCycleElapsed: 0,
        _theCycleSkipping: 0,
        _paused: false,
		_doHam: null,
        _timeoutVar: null
    };

    var privateFunctions = {
        _getInTimer: function(theNumber) {
             for (var i=0, len=privateVars._timers.length; i<len; i++) {if (privateVars._timers[i].theNumber == theNumber) return(privateVars._timers[i]);}
            return null;
       },
        _checkInQueue: function(theNumber) {
            for (var i=0, len=privateVars._theQueue.length; i<len; i++) { if (privateVars._theQueue[i][0].theNumber == theNumber.toString()) return(i); }
            return -1;
        },
        _removeFromQueue: function(theNumber) {
            var foundNumber = privateFunctions._checkInQueue(theNumber);
            if (foundNumber != -1) return privateVars._theQueue.splice(foundNumber, 1)[0];
            else return null;
        },
        _goFrontOfTheLineTimer: function() {
            var frontOfTheLineNumber = privateVars._theFrontOfTheLineTimer.shift();
            var frontOfTheLineItem = privateFunctions._getInTimer(frontOfTheLineNumber);
			if (gMainOptions.debugger>2) console.log("Frontofthelinetimer: " + JSON.stringify(frontOfTheLineItem));
            if (frontOfTheLineItem) {
                frontOfTheLineItem.runFunction.apply("frontoftheline",[frontOfTheLineItem.elapsed,frontOfTheLineItem.theNumber] );
				frontOfTheLineItem.elapsed = 0;
                return true;
            } else return false;
        },
        _goFrontOfTheLine: function() {
            var frontOfTheLineNumber = privateVars._theFrontOfTheLineQueue.shift(), thisItem=null;
            var frontOfTheLineQueue = privateFunctions._removeFromQueue(frontOfTheLineNumber);
            if (frontOfTheLineQueue) {
				if (gMainOptions.debugger>2) console.log("Frontofthelinequeue: " + JSON.stringify(frontOfTheLineQueue));
				for (var c=0, len=frontOfTheLineQueue.length; c<len; c++) { if (frontOfTheLineQueue[c].weightStatus=="item")  thisItem = frontOfTheLineQueue[c]; }
				if (thisItem) {
					if (!thisItem.doOnce) privateVars._theQueue.push(frontOfTheLineQueue);
					thisItem.runFunction.apply("frontoftheline",[privateVars._theCycleElapsed,thisItem.theNumber] );
					return true;
				}
            }
			return false;
        },
        _goHam: function() {
            var hamCalled = false, thisItem=null;
			if (gMainOptions.debugger>2) console.log("Ham: " + JSON.stringify(privateVars._doHam));
			for (var c=0, len=privateVars._doHam.length; c<len; c++) { if (privateVars._doHam[c].weightStatus=="item") thisItem = privateVars._doHam[c]; }
			if (thisItem) hamCalled = thisItem.runFunction.apply("goham",[privateVars._theCycleElapsed,thisItem.theNumber] );
            return hamCalled;
        },
        _doTimers: function() {
            var returnStatus = false;
            for(var i=0, len=privateVars._timers.length; i<len; i++) {
                privateVars._timers[i].elapsed += privateVars._theCycleElapsed;
                if (privateVars._timers[i].elapsed >= privateVars._timers[i].milliSeconds) {
                    returnStatus = privateVars._timers[i].runFunction.apply("timer",[privateVars._timers[i].elapsed,privateVars._timers[i].theNumber] );
                    privateVars._timers[i].elapsed = 0;
                }
            }
            return returnStatus;
        },
        _doQueue: function() {
            var skipThis = true, queueItem = null, counter=0, doOnce=false, weighted=false, weightedRan=false, removed=false;
			if (gMainOptions.debugger>2) console.log("Queue: " + JSON.stringify(privateVars._theQueue));
            do {
                queueItem = privateVars._theQueue[counter];
				if (queueItem.length>1) weighted=true;
				if (queueItem[0].weightStatus=="item") { // check to see if this item is not null for weighted items. Non weighted items will never have nulls.
					try { skipThis = !queueItem[0].runFunction.apply("queue",[privateVars._theCycleElapsed,queueItem[0].theNumber] ); }
					catch(e) { console.log('JRPanda: An error has occurred: '+e.message); }
					doOnce = queueItem[0].doOnce;
					if (privateVars._lastRemoved==queueItem[0].theNumber) removed=true; // Was this item removed already?
					if (!removed) privateVars._theQueue.splice(counter,1); // remove from queue because item was either done or skipped.
					weightedRan=true;
				} else weightedRan=false;
				if (weighted && !removed) queueItem.push(queueItem.shift()); // Take from top of item queue and place on bottom to keep null weight items.
				if (weighted && !weightedRan && !removed) privateVars._theQueue.splice(counter,1,queueItem); // Replace item in same place if this was skipped because of null weight item.
				if ( (!weighted && !doOnce && !removed) || (weighted && weightedRan && !removed) ) privateVars._theQueue.push(queueItem);
				counter++; weighted=false;
            } while (privateVars._theQueue.length > 0 && skipThis && counter < privateVars._theQueue.length);
			privateVars._lastRemoved = -1; // Reset last removed so everything is fresh.
        },
        _theLoop: function() {
            var continueCheck = true;
            var elapsed = new Date().getTime() - privateVars._before.getTime();
            if (elapsed >= privateVars._realCycle) {
                privateVars._theCycleElapsed = elapsed;
                privateVars._before = new Date();
                if (privateVars._theFrontOfTheLineTimer.length > 0) continueCheck = !privateFunctions._goFrontOfTheLineTimer();
                if (privateVars._theFrontOfTheLineQueue.length > 0) continueCheck = !privateFunctions._goFrontOfTheLine();
                if (continueCheck && privateVars._timers.length>0) continueCheck = !privateFunctions._doTimers();
                if (continueCheck && privateVars._doHam) { continueCheck = false; privateFunctions._goHam(); }
                if (continueCheck && privateVars._theQueue.length>0) { privateFunctions._doQueue(); }
            }
            privateVars._timeoutVar = setTimeout(privateFunctions._theLoop, 5);
        }
    };
    var output = {
        addJob: function(func, theNumber, milliSeconds, doOnce, weight) {
            if (typeof func === 'function' && !isNaN(milliSeconds)) {
				doOnce = doOnce || false; weight = weight || 0;
                if (privateFunctions._checkInQueue(theNumber)!=-1) return;
                for(var i=0, len=privateVars._timers.length; i<len; i++) { if (privateVars._timers[i].theNumber == theNumber) return; }
                var jobData = [{'theNumber':theNumber,'runFunction': func,'milliSeconds':milliSeconds,'weightStatus':"item",'cycleWeight':weight,'elapsed':milliSeconds,'doOnce':doOnce}];
                if (milliSeconds === 0) {
					for (var ii=0; ii<weight; ii++) { jobData.unshift({'theNumber':theNumber,'weightStatus':"null",'doOnce':doOnce}); }
					privateVars._theQueue.unshift(jobData);
				}
                else if (milliSeconds > 0) privateVars._timers.unshift(jobData[0]);
            }
            if (privateVars._timeoutVar===null) { privateVars._before = new Date(); privateFunctions._theLoop(); }
        },
        removeJob: function(theNumber) {
            var returnValue = false;
            if (privateFunctions._removeFromQueue(theNumber)) privateVars._lastRemoved = theNumber;
            for (var i=0, len=privateVars._timers.length; i<len; i++) {
                if (privateVars._timers[i].theNumber == theNumber) {
                    privateVars._timers.splice(i, 1);
					privateVars._lastRemoved = theNumber;
                    returnValue=true;
                    break;
                }
            }
            if (privateVars._theQueue.length === 0 && privateVars._timers.length === 0) { clearTimeout(privateVars._timeoutVar); privateVars._timeoutVar = null; }
            return returnValue;
        },
        pause: function() {
            privateVars._paused = true;
            clearTimeout(privateVars._timeoutVar);
        },
        isPaused: function() { return privateVars._paused; },
        unpause: function() {
            privateVars._paused = false;
			privateVars._before = new Date();
            if (privateVars._timers.length>0 || privateVars._theQueue.length>0)
                privateVars._timeoutVar = setTimeout(privateFunctions._theLoop, 0);
        },
        frontOfTheLineTimer: function( theNumber ) { privateVars._theFrontOfTheLineTimer.push(theNumber); },
        frontOfTheLine: function( theNumber ) { privateVars._theFrontOfTheLineQueue.push(theNumber); },
        changeWeight: function( theNumber, newWeight ) {
			var foundNumber = privateFunctions._checkInQueue(theNumber), thisItem=null;
            if (foundNumber != -1) {
				var itemQueue = privateVars._theQueue.splice(foundNumber, 1)[0];
				for (var c=0, len=itemQueue.length; c<len; c++) { if (itemQueue[c].weightStatus=="item")  thisItem = itemQueue[c]; }
				if (thisItem) {
					thisItem.cycleWeight = newWeight;
					var jobData = [thisItem];
					for (var i=0; i<newWeight; i++) { jobData.unshift({'theNumber':theNumber,'weightStatus':"null"}); }
					privateVars._theQueue.splice(foundNumber,0,jobData);
					if (gMainOptions.debugger>2) console.log(JSON.stringify(privateVars._theQueue));
				}
			}
		},
        hamOn: function( theNumber ) {
			var hamData = privateFunctions._removeFromQueue(theNumber);
			if (hamData) privateVars._doHam = hamData;
		},
        hamOff: function() {
			if (privateVars._doHam) privateVars._theQueue.push(privateVars._doHam);
			privateVars._doHam = null;
		},
        isHamOn: function() { return (privateVars._doHam) ? true : false; },
        jobs: function() { return privateVars._theQueue.length; },
        skippingReset: function() { privateVars._theCycleSkipping = 0; privateVars._realCycle = privateVars._theCycle; },
        cycleIncrease: function(increaseNumber) {
            increaseNumber = increaseNumber || gMainOptions.cycleIncrease;
            privateVars._theCycleSkipping += parseInt(increaseNumber);
            privateVars._realCycle += parseInt(increaseNumber);
        },
        cycleDecrease: function(decreaseNumber) {
            decreaseNumber = decreaseNumber || gMainOptions.cycleDecrease;
            privateVars._theCycleSkipping = (privateVars._theCycleSkipping > 0) ?
                privateVars._theCycleSkipping -= parseInt(decreaseNumber) : 0;
            privateVars._realCycle = privateVars._theCycle + privateVars._theCycleSkipping;
        },
        cycle: function() { return privateVars._theCycle; },
        cycleSkipping: function() { return privateVars._theCycleSkipping; },
        cycleChange: function(newSkipping) {
            privateVars._theCycleSkipping = newSkipping; privateVars._realCycle = privateVars._theCycle + privateVars._theCycleSkipping;
        },
        cycleAdd: function(newSkipping) {
            privateVars._theCycleSkipping += newSkipping; privateVars._realCycle = privateVars._theCycle + privateVars._theCycleSkipping;
        },
        cycleResetChange: function(newCycle) {
            privateVars._theCycle = newCycle; privateVars._theCycleSkipping = 0; privateVars._realCycle = newCycle;
        }
    };
    return output;
})();

// status on UI to show info to user.
function displayMainStatus() {
    var statusText = "", theMode="";
    var theJobs = (gMainData.jobs===0) ? "-- No Jobs to Search. " : "-- Running: " + gMainData.jobs + " jobs ";
    $("#JRJobsArea").html(theJobs);
    theMode = $("#JRCycleInfoArea").data("mode");
    var theCycle = (theMode=="Elapsed") ? "[ Elapsed Time: " + gMainData.lastElapsed + "ms | " :
        (theMode=="Cycle") ? "[ Cycling every: " + theCycler.cycle() + "ms | " :
        (theMode=="CycleSkipping") ? "[ Cycling Slowed: " + theCycler.cycleSkipping() + "ms | " :
        (theMode=="Hamcycle") ? "[ Min Ham Cycle: " + gMainOptions.HamCycleNumber + "ms | " : "";
    if (isActiveMenu(gMainMenu,"Cycler")) {
        theCycle = "[ Elapsed Time: " + gMainData.lastElapsed + "ms | Cycling every: " + theCycler.cycle() + "ms | Cycling Slowed: " +
            theCycler.cycleSkipping() + "ms | Min Ham Cycle: " + gMainOptions.HamCycleNumber + "ms ]";
        $("#JRCycleInfoArea").html(theCycle);
        $("#JRResultAccSkipArea").html("");
        $("#JRErrorArea").html("");
        //$("#JRSearchedArea").html("");
        $("#JRPayArea").html("");
    } else {
        $("#JRCycleInfoArea").html(theCycle);
        theMode = $("#JRResultAccSkipArea").data("mode");
        var theAccSkip = (theMode=="Accepted") ? "Accepted: " + gMainData.accepted + " | " :
            (theMode=="Skipped") ? "Skipped: " + gMainData.skipped + " | " :
			(theMode=="Missed") ? "Missed: " + gMainData.missed + " | " :
			(theMode=="Searched") ? "Total Searched: " + gMainData.searched + " | " : "";
        $("#JRResultAccSkipArea").html(theAccSkip);
        theMode = $("#JRErrorArea").data("mode");
        var theErrors = (theMode=="Errors") ? "Errors: " + gMainData.errors + " | " :
            (theMode=="TooFast") ? "PRE'S: " + gMainData.tooFast + " | " : "";
        $("#JRErrorArea").html(theErrors);
        theMode = $("#JRPayArea").data("mode");
        var thePay = (theMode=="PayAccepted") ? "Pay Accepted: $" + gMainData.payCounter.toFixed(2) + " ]" :
            (theMode=="Projected") ? "Projected Earnings: $" + gMainData.projectedEarnings.toFixed(2) + " ]" : "";
        $("#JRPayArea").html(thePay);
    }
}
function createQueueLinks(returnUrl,continueUrl) {
	var theLinks = createSpan(createLink("Return",returnUrl,"_blank","Return").attr({"class":"JRQueueReturn"})
		.click( function(e) {
			gAlarmSounds.queueAlert.audio.pause();
			showYesNoDialog("Are you sure you want to return this hit?",function() {
				var theHeight=window.outerHeight-80, theWidth=window.outerWidth-10;
				window.open($(e.target).attr("href"),"_blank","width=" + theWidth + ",height=" +  theHeight + ",scrollbars=yes,toolbar=yes,menubar=yes,location=yes");
			});
			return false;
		})).append(createSpan(" :: "));
	theLinks = theLinks.append(createSpan(createLink("Continue Work",continueUrl,"_blank","Continue Work").attr({"class":"JRQueueContinue"})
		.click( function(e) {
			gAlarmSounds.queueAlert.audio.pause();
			var theHeight=window.outerHeight-80, theWidth=window.outerWidth-10;
			window.open($(e.target).attr("href"),"_blank","width=" + theWidth + ",height=" +  theHeight + ",scrollbars=yes,toolbar=yes,menubar=yes,location=yes");
			return false;
		})));
	return theLinks;
}
function displayQueueStatus() {
	addToQueueWatchLog(createSpan(""),true);
	var lessThanAlarm = false;
	gQueueData.reverse();
	if (gQueueData.length>0) {
		for (var i=0, len=gQueueData.length; i<len; i++) {
			if (gQueueData[i].timeLeft.indexOf("second") == -1) gQueueData[i].timeLeft = gQueueData[i].timeLeft + " 0 seconds";
			addToQueueWatchLog(createSpan("(" + gQueueData[i].requesterName + ") [$" + gQueueData[i].pay + "] - <span style='color: cyan;'>" +
				gQueueData[i].timeLeft + "</span> - " + gQueueData[i].title + " :: ").data("thisData",gQueueData[i])
					.append(createQueueLinks(gQueueData[i].returnURL,gQueueData[i].continueURL)));
			if (!gMainOptions.disableQueueAlert) {
				var theTimeLeft = getTimeLeft(gQueueData[i].timeLeft);
				if (!lessThanAlarm && theTimeLeft.weeks < 1 && theTimeLeft.days < 1 && theTimeLeft.hours < 1 && theTimeLeft.minutes < parseInt(gAlarmSounds.queueAlert.lessMinutes)) {
					lessThanAlarm = true;
					if (!$("#muteQueueWatchAlarm").is(":checked")) {
						playThisSound("queueAlert");
						$("#JRQueueWatchLog").css({"background-color":"#8A0000"});
						$("#JRQueueWatchLog").animate({"backgroundColor":"#000000"}, 10000, function() {
								$("#JRQueueWatchLog").css({"background-color":"#8A0000"});
								$("#JRQueueWatchLog").animate({"backgroundColor":"#000000"}, 10000);
							});
					}
				}
			}
		}
	} else {
		addToQueueWatchLog(createDiv("You have no hits in your queue at this time. Click on the black background to refresh your queue.<br>" +
			"An alarm will be heard if a hit has " + gAlarmSounds.queueAlert.lessMinutes + " minutes left. Mute the alarm to the right if not needed.<br>" +
			"This window gets updated every " + gMainOptions.queueTimer + "ms.")
		.css({"font-size":"16px","color":"#7FFFD4","margin-top":"12px","text-align":"center","line-height":"18px"}));
	}
	$("#JRStatusTab_2 .JRTabLabel:first").html("Queue Watch - " + ((gMainData.hitsInQueue <=25) ? gMainData.hitsInQueue : "25"));
}

function fullQueueTimer() { gFullQueue = false; }
function displayHitStatus( theNumber ) {
    var hitInfo = gMainData.hitCollection[theNumber];
    var hitStatus = hitInfo.status;
	var skippedStatus = (hitInfo.data.action.toLowerCase().indexOf("filter") != -1) ? "Skip: " + hitStatus.skipped + " | " : "";
	var missedStatus = (hitInfo.data.action.toLowerCase().indexOf("pantha") != -1) ? "Miss: " + hitStatus.missed + " | " : "";
    var statusText = "[ Acc: " + hitStatus.accepted + " | " + skippedStatus + missedStatus + "Srch: " + hitStatus.searched + " ]";
    $("#JRCellStatus_" + theNumber).html( statusText );
    displayMainStatus();
}
function processResults( theNumber, result, finalUrl ) {
    var hitInfo = (theNumber>0) ? gMainData.hitCollection[theNumber] : null;
    var hitData = (hitInfo) ? hitInfo.data : null;
    var hitStatus = (hitInfo) ? hitInfo.status : null;
	var hitDataActionSix = (hitData) ? hitData.action.toLowerCase().substring(0,6) : "";
    switch(result) {
        case "NOTQUALIFIED":
            if (hitStatus) hitStatus.notQual++;
			hitInfo.hitCell.data("status","off");
			toggleButtonOff( hitInfo.hitCell.find(".JRCollectButton"),startCollecting,stopCollecting);
            updateHitCell(theNumber);
			break;
        case "BLOCKED": // stop collecting this job. Change background to error color.
            if (hitStatus) hitStatus.blocked++;
			hitInfo.hitCell.data("status","off");
			toggleButtonOff( hitInfo.hitCell.find(".JRCollectButton"),startCollecting,stopCollecting);
            updateHitCell(theNumber);
			break;
        case "NOACCEPT": // Missed a hit because someone else took it. So mad.
            if (hitDataActionSix == "search" || hitDataActionSix == "pantha") { hitStatus.missed++; hitStatus.noHits++; gMainData.missed++; }
            break;
        case "NOMORE":
            if (hitStatus) hitStatus.noHits++;
            gMainData.noHits++;
            break;
        case "TOOFAST":
            if (hitStatus) hitStatus.tooFast++;
            gMainData.tooFast++;
            if (gSlowDownAuto) theCycler.cycleIncrease(gMainOptions.cycleAutoIncrease);
			if (finalUrl) {
				var acceptPage = (finalUrl.indexOf("mturk/accept") != -1);
				var previewPage = (finalUrl.indexOf("mturk/preview") != -1);
				if (acceptPage || previewPage) {
					if (hitDataActionSix == "search" || (hitDataActionSix == "pantha" && acceptPage)) {
						if (gMainOptions.debugger>0) console.log("got a PRE for a search or pantha on: " + finalUrl);
						hitInfo.goToUrl.push({"url":finalUrl,"theNumber":theNumber});
					}
				}
			}
            break;
        case "LOGGEDOFF":
            if (!theCycler.isPaused()) {
				var addText = createDiv("You are logged out of Amazon.<br><br>Can't accept hits so pausing.<br><br>Please log back in!")
					.css({"margin-top":"30px","font-size":"17px","text-align":"center","color":"red"})
					.append(createDiv(createLink("Go to Mturk Page","https://www.mturk.com/mturk/myhits","_blank","https://www.mturk.com/mturk/myhits")
						.click( function() {
							window.open("https://www.mturk.com/mturk/myhits","_blank","width=" + 1000 + ",height=" +  800 + ",scrollbars=yes,toolbar=yes,menubar=yes,location=yes");
							return false;
						})).css({"color":"blue","margin-top":"15px"}));
				showWaitDialog("Logged Out!!","",function() {
					theCycler.unpause();
					$("#JRPauseButton").html("Pause").css({"background-color":"ivory","color":"black"});
				},null,addText,true);
				theCycler.pause();
				$("#JRPauseButton").html("Resume").css({"background-color":"red","color":"white"});
				playThisSound("hasToPause");
			}
            break;
        case "DAILYLIMIT":
            theCycler.pause();
            $("#JRPauseButton").html("Resume").css({"background-color":"red","color":"white"});
            alert("Congratulations!! You have reached your daily limit. Wait for tomorrow.");
            break;
        case "NOTCOMPLETED":
        case "ERROR":
            if (hitStatus) hitStatus.error++;
            gMainData.error++;
            break;
        case "QUEUEMAX":
            if (hitStatus) hitStatus.fullQueue++;
			if (!gFullQueue) {
				playThisSound("fullQueue");
				gFullQueueTimer = setTimeout( function() { fullQueueTimer(); }, 240000 );
			}
			gFullQueue = true;
            gMainData.fullQueue++;
            break;
        case "SKIPPED":
            if (hitStatus) hitStatus.skipped++;
            gMainData.skipped++;
            break;
        case "ACCEPTED":
            if (hitStatus) hitStatus.accepted++;
			if (hitInfo.ham == "ontimed") hitInfo.lastAccept = new Date();
            var newDate = new Date().setHours(0,0,0,0);
            if (hitData.dailyLimit && hitData.dailyLimit>0) hitData.dailyDone = (newDate == hitData.day) ? hitData.dailyDone + 1 : 1;
            if (hitData.once) hitData.dailyDone = 1;
            hitData.day = newDate;
            gMainData.accepted++;
            gMainData.hitsInQueue++;
			thisKey = hitData.requesterName + ":" + hitData.title;
			gQueueCount[thisKey] = (thisKey in gQueueCount) ? gQueueCount[thisKey]+1 : 1;
			if (hitData.duration.indexOf("second") == -1) hitData.duration = hitData.duration + " 0 seconds";
			addToQueueWatchLog(createSpan("(" + hitData.requesterName + ") [$" + hitData.pay + "] - <span style='color: cyan;'>" +
				hitData.duration + "</span> - " + hitData.title + " :: ").data("thisData",hitData).append(createQueueLinks(returnLink(hitInfo.hitId),continueLink(hitInfo.hitId))),
				(gMainData.hitsInQueue>1) ? false : true);
			$("#JRStatusTab_2 .JRTabLabel:first").html("Queue Watch - " + ((gMainData.hitsInQueue <=25) ? gMainData.hitsInQueue : "25"));
            var hitPay = parseFloat(hitData.pay);
            gMainData.payCounter = Math.round( (gMainData.payCounter + hitPay) * 100) / 100;
            gMainData.projectedEarnings = Math.round( (gMainData.projectedEarnings + hitPay) * 100) / 100;
            var theDuration = hitInfo.minutes;
            if (theDuration===0 && hitData.duration!="0") {
                theDuration = (hitData.duration.indexOf("weeks")!=-1) ? 5000 : (hitData.duration.indexOf("day")!=-1) ? 1500 : (hitData.duration.indexOf("hours")!=-1) ? 200 :
                    (hitData.duration.indexOf("hour")!=-1) ? 60 : (hitData.duration.indexOf("minutes")!=-1) ? parseInt(hitData.duration.split("minutes")[0]) : 1;
				hitInfo.durationParsed = getTimeLeft(hitData.duration);
                hitInfo.minutes = theDuration;
            }
            var theSoundFile = "less99";
            var notificationTitle = "Accepted Hit From: " + hitData.requesterName;
            var notificationMessage = "Pay: " + hitData.pay + "\nDuration: " + hitData.duration + "\nTitle: " + hitData.title;
            if (!hitData.mute) {
                if ( hitPay < parseFloat(gAlarmSounds.less2.payRate) ) {
					theSoundFile = (theDuration !== 0 && theDuration<=parseInt(gAlarmSounds.less2Short.lessMinutes)) ? "less2Short" : "less2";
				} else if ( hitPay <= parseFloat(gAlarmSounds.less5.payRate) ) {
					theSoundFile =  (theDuration !== 0 && theDuration<=parseInt(gAlarmSounds.less5Short.lessMinutes)) ? "less5Short" : "less5";
				} else if ( hitPay <= parseFloat(gAlarmSounds.less15.payRate) ) {
					theSoundFile = (theDuration !== 0 && theDuration<=parseInt(gAlarmSounds.less15Short.lessMinutes)) ? "less15Short" : "less15";
                } else if ( hitPay < parseFloat(gAlarmSounds.less99.payRate) ) { theSoundFile = "less99"; }
                if (hitData.audioforce !== "") theSoundFile = hitData.audioforce;
                playThisSound(theSoundFile);
            }
            if (gScriptStatus == "normal") {
				$("#JRCellNum_" + theNumber).stop(true,true);
				$("#JRCellNum_" + theNumber).css({"background-color":"yellow"});
				$("#JRCellNum_" + theNumber).animate({"backgroundColor": $("#JRCellNum_" + theNumber).data("backgroundColor")}, 40000);
			}
            if (gNotifications) showNotification( notificationTitle, notificationMessage, "accepted", hitData.groupId);
            if ( hitInfo.ham == "paused" ) { toggleButton($("#JRHamB_" + theNumber),hamOn,hamOff); }
            addToAcceptedLog( hitData.requesterName + " - <a href='" + pandaLink(hitData.groupId) + "' target='_blank' style='color:cyan;'>" + hitData.groupId + "</a> - " + hitData.title );
            updateHitCell(theNumber);
            break;
    }
    if (theNumber > 0) displayHitStatus(theNumber);
}

function requestUrl(theUrl, theNumber, theFunction, errorFunction, data1, data2, theResponseType) {
    theResponseType = theResponseType || "";
    if (gMainOptions.debugger>2) console.log("JR going to get: " + theUrl);
    GM_xmlhttpRequest({
        method: "GET",
        url: theUrl,
        responseType: theResponseType,
        onload: function(response) { if (typeof theFunction == 'function') theFunction(response,theNumber,data1,data2); },
        onerror: function(response) { if (typeof errorFunction == 'function') errorFunction(response,theNumber); }
    });
}
function errorRequest(res,theNumber) {
	if (res && res.statusText) {
		console.log("error: " + res.statusText);
		if (res.statusText == "Forbidden") processResults( theNumber, "LOGGEDOFF" );
	}
    //setStatusText(theNumber,"...... Searching - Error .....","errors");
}

function pandaLink(theGroupId) { return "https://www.mturk.com/mturk/previewandaccept?groupId=" + theGroupId; }
function pandaLinkNew(theGroupId) { return "http://worker.mturk.com/projects/" + theGroupId + "/tasks/accept_random?ref=w_pl_prvw"; }
function previewLink(theGroupId) { return "https://www.mturk.com/mturk/preview?groupId=" + theGroupId; }
function previewLinkNew(theGroupId) { return "http://worker.mturk.com/projects/" + theGroupId + "/tasks?ref=w_pl_prvw"; }
function continueLink(theHitId) { return "https://www.mturk.com/mturk/continue?hitId=" + theHitId; }
function returnLink(theHitId) { return "https://www.mturk.com/mturk/return?hitId=" + theHitId + "&inPipeline=false"; }
function requesterSearch(theRequester) { return "https://www.mturk.com/mturk/searchbar?selectedSearchType=hitgroups&qualifiedFor=on&pageSize=10&sortType=Reward%3A1&requesterId=" + theRequester; }
function requesterSearchNew(theRequesterID) { return "http://worker.mturk.com/requesters/" + theRequesterID + "/projects?ref=w_pl_prvw"; }
function termSearchNew(theTerm,theSize,theSort,qualified) {
	qualified = qualified || "true";
	return "https://worker.mturk.com/?filters%5Bsearch_term%5D=" + theTerm + "&page_size=" + theSize + "&page_number=1&sort=" + theSort + "&filters%5Bqualified%5D=" + qualified;
}
function acceptLink(theHitData) { return "https://www.mturk.com/mturk/accept?hitId=" + theHitData.hitId + "&prevHitSubmitted=" + theHitData.prevHitSubmitted +
    "&prevRequester=" + theHitData.prevRequester + "&prevReward=" + theHitData.prevReward + "&requesterId=" + theHitData.requesterId + "&groupId=" +
    theHitData.groupId + "&signature=" + theHitData.signature;
}
function checkLimits(theNumber) {
    //console.log("JR checking " + theNumber + " for their limits.");
    var hitInfo = gMainData.hitCollection[theNumber];
    var hitData = hitInfo.data;
    var returnValue = false;
	var theKey = hitData.requesterName + ":" + hitData.title;
    if (hitData.queueLimit === 0 && hitData.queueHitLimit === 0 && hitData.dailyLimit === 0 && !hitData.once) returnValue = true;
	else if (hitData.once && hitData.dailyDone>0) {
        if (hitInfo.hitCell.data("status")=="on") hitInfo.hitCell.data("status","off");
        toggleButtonOff( hitInfo.hitCell.find(".JRCollectButton"),startCollecting,stopCollecting);
		returnValue = false; }
	else if (hitData.queueHitLimit > 0 && (gQueueCount[theKey] === "undefined" || gQueueCount[theKey] >= hitData.queueHitLimit)) returnValue = false;
    else if (hitData.queueLimit > 0 && hitData.queueLimit <= gMainData.hitsInQueue) returnValue = false;
    else if (hitData.dailyLimit > 0 && hitData.dailyLimit < gMainData.dailyDone) returnValue = false;
    else returnValue = true;
    return returnValue;
}
function searchRequestersInfo( theNumber, hitNumber, requestersInfo ) {
    var hitInfo = gMainData.hitCollection[hitNumber];
    var hitData = hitInfo.data;
    if (hitInfo.collecting != "off") {
        hitInfo.status.searched++;
        displayHitStatus(hitNumber);
        for (var i=0, len=requestersInfo.data.length; i<len; i++) {
            if ( requestersInfo.data[i].groupId == hitData.groupId ) { return i; }
        }
    }
    return -1;
}
function doSortResultsTable(thisDoc) {
	var sortResultsTable = $(thisDoc).find("#sortresults_form").next("table");
	var jobDatas = [];
	$(sortResultsTable).find("> tbody > tr").each(function(i, row) {
		var jobData = jQuery.extend(true, {}, jobDataDefault);
		var titleElement = $(row).find("#capsule" + i + "-0");
		if (titleElement.length) {
			jobData.title = $(titleElement).text().trim();
			var titleLink = $(titleElement).closest("tr").find(".capsulelink a:first");
			jobData.groupId = (titleLink.length) ? $(titleLink).attr("href").split("groupId=")[1] : "";
			var returnLink = $(titleElement).closest("tr").find("a:contains('Return this HIT'):first");
			jobData.returnURL = (returnLink.length) ? "https://www.mturk.com" + $(returnLink).attr("href") : "";
			var continueLink = $(titleElement).closest("tr").find("a:contains('Continue work on this HIT'):first");
			jobData.continueURL = (continueLink.length) ? "https://www.mturk.com" + $(continueLink).attr("href") : "";
			var requesterElement = $(row).find(".requesterIdentity:first");
			jobData.requesterName = (requesterElement.length) ? $(requesterElement).text().trim() : "";
			var contactRequesterUrl = $(row).find("#capsule" + i + "target").find("a:contains('Contact the Requester of this HIT'):first");
			jobData.requesterId = (contactRequesterUrl.length) ? $(contactRequesterUrl).attr("href").split("requesterId=")[1].split("&")[0] : "";
			var durationToComplete = $(row).find("#duration_to_complete\\.tooltip--" + i);
			jobData.duration = (durationToComplete.length) ? $(durationToComplete).closest("tr").find(".capsule_field_text").text().trim() : "";
			jobData.durationParsed = getTimeLeft(jobData.duration);
			var timeLeft = $(row).find("#time_left\\.tooltip--" + i);
			jobData.timeLeft = (timeLeft.length) ? $(timeLeft).closest("tr").find(".capsule_field_text").text().trim() : "";
			var hitsAvailable = $(row).find("#number_of_hits\\.tooltip--" + i);
			jobData.hitsAvailable = (hitsAvailable.length) ? $(hitsAvailable).closest("tr").find(".capsule_field_text").text().trim() : "";
			var rewardElement = $(row).find("#reward\\.tooltip--" + i);
			jobData.pay = (rewardElement.length) ? $(rewardElement).closest("tr").find(".reward").text().replace("$","").trim() : "";
			jobDatas.push(jobData);
		}
	});
	return jobDatas;
}
function createHitRow(theData,buttons,fromWhere) {
	var durationTime = (theData.duration != "Time") ? getTimeLeft(theData.duration) : theData.duration;
	var durationText = (theData.duration != "Time") ? durationTime.hours + ":" + ("0" + durationTime.minutes).slice(-2) : theData.duration;
	var payText = (theData.pay == "Pay") ? theData.pay : "$" + theData.pay;
	var dialogWidth = $("#JREditDialog").width();
	var titleWidth = (fromWhere=="jobs") ? 500 : 450;
	var hitInfo = (theData.jobNumber != "-1") ? gMainData.hitCollection[parseInt(theData.jobNumber)] : null;
	var hitRow = createDiv().attr({"class":"hitRow"}).data("hitData",theData);
	if (fromWhere=="jobs") hitRow.append(createCheckbox().css({"margin":"-15px 2px 0 0","padding":"0","display":"inline-block"}).data({"hitData":theData}));
	hitRow.append(createSpan((theData.friendlyRName!=="") ? theData.friendlyRName : theData.requesterName).attr({"class":"aHitColumn"})
			.css({"background-color":"#FBF5E6","width":"140px","text-align":"right","border":"1px solid black"}))
		.append(createSpan((theData.friendlyTitle!=="") ? theData.friendlyTitle : theData.title).attr({"class":"aHitColumn"})
			.css({"background-color":"#FCF6CF","width":(dialogWidth - titleWidth) + "px","text-decoration":"underline","cursor":"pointer"})
			.click( function(e) {
				var thisData = $(e.target).closest(".hitRow").data("hitData");
				var theHeight=window.outerHeight-80; var theWidth=window.outerWidth-10;
				window.open(previewLink(thisData.groupId),"_blank","width=" + theWidth + ",height=" +  theHeight + ",scrollbars=yes,toolbar=yes,menubar=yes,location=yes");
			}))
		.append(createSpan(durationText).attr({"class":"aHitColumn"}).css({"background-color":"#F5F5DC","width":"35px"}));
	if (fromWhere=="mturk") hitRow.append(createSpan(theData.hitsAvailable).attr({"class":"aHitColumn"}).css({"background-color":"#F0FFFF","width":"40px"}));
	hitRow.append(createSpan(payText).attr({"class":"aHitColumn"}).css({"background-color":"#7FFFD4","width":"40px"}));
	if (fromWhere=="jobs") {
		if (theData.duration != "Time") {
			var theStatus = hitInfo.hitCell.data("status");
			var theCell = hitInfo.hitCell;
			var thisBgColor = $(theCell).find(".JRCollectButton").css("background-color");
			var thisColor = $(theCell).find(".JRCollectButton").css("color");
			hitRow.append(createSpanButton(function(e) {
					hitInfo.hitCell.find(".JRCollectButton").click();
					var theClone = $(e.target).data("clone");
					$(e.target).css({"background-color":theClone.css("background-color"),"color":theClone.css("color")});
				},"Collect",$(theCell).find(".JRCollectButton").css("background-color"),$(theCell).find(".JRCollectButton").css("color"),"10px")
				.css({"white-space":"nowrap","overflow":"hidden","display":"inline-block"}).data({"status":theStatus,"clone":$(theCell).find(".JRCollectButton")}));
			hitRow.append(createSpanButton(function(e) {
					showEditHitDialog(theData.jobNumber,$(e.target),function() { showSearchingDialog($("#JREditDialog").data("savedButton"),"jobs"); });
				},"Details",gButtonOffBgColor,gButtonOffColor,"10px").css({"white-space":"nowrap","overflow":"hidden","display":"inline-block"}).data({"status":theStatus}));
		} else {
		}
	}
	if (buttons) hitRow.append(createSpanButton( function(e) {
				var thisData = $(e.target).closest(".hitRow").data("hitData");
				var newNumber = fillNewHitData(thisData.requesterName, thisData.requesterId, thisData.groupId, thisData.pay,
					thisData.title, thisData.duration, false, true, true);
				gMainData.hitCollection[newNumber].numberHits = thisData.hitsAvailable;
			},"Panda",gButtonOffBgColor,gButtonOffColor,"10px").css({"white-space":"nowrap","overflow":"hidden","display":"inline-block"}))
		.append(createSpanButton( function(e) {
				var thisData = $(e.target).closest(".hitRow").data("hitData");
				var newNumber = fillNewHitData(thisData.requesterName, thisData.requesterId, thisData.groupId, thisData.pay,
					thisData.title, thisData.duration, true, true, true);
				gMainData.hitCollection[newNumber].numberHits = thisData.hitsAvailable;
			},"Once",gButtonOffBgColor,gButtonOffColor,"10px").css({"white-space":"nowrap","overflow":"hidden","display":"inline-block"}));
	if (theData.duration == "Time") $(hitRow).find("input").click( function(e) {
		$(e.target).closest(".searchingResultsArea").find("input").prop("checked",$(e.target).prop("checked"));
	});
	return hitRow;
}
function parseHitSearchPage(theResult,theNumber,searchWhere) {
    var hitInfo = (theNumber>0) ? gMainData.hitCollection[theNumber] : null;
    var hitData = (hitInfo) ? hitInfo.data : null;
	var finalUrl = theResult.finalUrl;
    var parser = new DOMParser();
    var xmlDoc = parser.parseFromString(theResult.responseText,"text/html");
    var errorTitle_Array = xmlDoc.getElementsByClassName("error_title");
    var errorTitle = (errorTitle_Array.length) ? errorTitle_Array[0] : null;
	var searchArea = (searchWhere=="mturk") ? $("#JRSavedMturkArea") : $("#JRSavedJobsArea");
    if (errorTitle && errorTitle.innerHTML.indexOf("You have exceeded the maximum allowed page request rate") != -1) {
        processResults( theNumber, "TOOFAST", finalUrl );
        return;
    } else if (errorTitle && errorTitle.innerHTML.indexOf("Your search did not match any HITs") != -1) {
		if (theNumber<=0) {
			$(searchArea).find(".searchingResultsArea").html("");
			$(searchArea).find(".searchingResultsArea").append(createDiv("Nothing Found! Sorry.").css({"font-size":"25px","margin-top":"200px","text-align":"center"}));
			gSavedSearchArea = "";
		}
        return;
    } else {
		var requestersInfo = doSortResultsTable(xmlDoc);
		if (requestersInfo.length > 0) {
			//console.log("JR HitsearchPage : I found some hits: " + requestersInfo.length);
			var goUrl = "";
			if (theNumber<=0) {
				$(searchArea).find(".searchingResultsArea").html("");
				var captions = {"requesterName":"Requester Name","title":"Hit Title","duration":"Time","hitsAvailable":"# Hits","pay":"Pay","collect":"caption"};
				var dialogWidth = $("#JREditDialog").width();
				$(searchArea).find(".searchingResultsArea").append(createHitRow(captions,false,searchWhere));
				$(searchArea).find(".searchingResultsArea").append(createDiv()
					.css({"margin-left":"5px","margin-top":"0px","background-color":"black","height":"6px","width":(dialogWidth - 145) + "px"}));
				for (var ii=0, len1=requestersInfo.length; ii<len1; ii++) {
					$(searchArea).find(".searchingResultsArea").append(createHitRow(requestersInfo[ii],true,searchWhere));
					gSavedSearchArea = $(searchArea).find(".searchingResultsArea").html();
				}
			} else {
				for (var i=0, len=requestersInfo.length; (i<len && i<3); i++) { // Only go to the first 3 highest paid hits for requester.
					goUrl = (hitData.action.toLowerCase()=="searchandfilter" || hitData.action.toLowerCase()=="searchpantha") ?
						previewLink(requestersInfo[i].groupId) : pandaLink(requestersInfo[i].groupId);
					hitInfo.goToUrl.push({"url":goUrl,"theNumber":theNumber,"groupId":requestersInfo[i].groupId,"title":requestersInfo[i].title});
					updateHitCell(theNumber);
				}
				hitData.groupId = requestersInfo[0].groupId;
				hitInfo.pandaUrl = pandaLink(hitData.groupId);
				hitInfo.previewUrl = previewLink(hitData.groupId);
				hitInfo.newTitle = requestersInfo[0].title;
				if ( hitInfo.ham == "paused" && requestersInfo.length==1 ) {
					saveGroupIdSearching(hitInfo,true);
					toggleButton($("#JRHamB_" + theNumber),hamOn,hamOff);
				}
				theCycler.frontOfTheLine(theNumber);
			}
		} else if (theNumber<=0) {
			$(searchArea).find(".searchingResultsArea").html("");
			$(searchArea).find(".searchingResultsArea").append(createDiv("Nothing Found"));
		}
    }
}
function parseQueuePage(theResult,theNumber) {
    var parser = new DOMParser();
	var finalUrl = theResult.finalUrl;
    var xmlDoc = parser.parseFromString(theResult.responseText,"text/html");
    var errorTitle = xmlDoc.getElementsByClassName("error_title")[0];
	if (errorTitle) {
        var errorTitleHTML = errorTitle.innerHTML; 
		if ( errorTitleHTML.indexOf("There are currently no HITs") != -1 ||
			errorTitleHTML.indexOf("You do not currently have any HITs") != -1) { 
				gMainData.hitsInQueue = 0;
				gQueueData.splice(0,gQueueData.length);
				$.each(gQueueCount, function( index, value ) { delete gQueueCount[index]; });
		} else if ( errorTitleHTML.indexOf("You have exceeded the maximum allowed page request rate") != -1 ) {
			processResults( theNumber, "TOOFAST", finalUrl );
			return;
		}
	} else {
		var titleOrangeText = xmlDoc.getElementsByClassName("title_orange_text")[0];
		var thisKey = "", newValue=0;
		if (titleOrangeText) {
			var words = titleOrangeText.innerHTML.trim().split(' ');
			if ($.isNumeric(words[words.length - 2])) gMainData.hitsInQueue = parseInt(words[words.length - 2]);
		}
		gQueueData.splice(0,gQueueData.length);
		$.each(gQueueCount, function( index, value ) { delete gQueueCount[index]; });
		gQueueData = doSortResultsTable(xmlDoc);
		for (var i=0,len=gQueueData.length; i<len; i++) {
			thisKey = gQueueData[i].requesterName + ":" + gQueueData[i].title;
			gQueueCount[thisKey] = (thisKey in gQueueCount) ? gQueueCount[thisKey]+1 : 1;
		}
    }
	if (gMainData.hitsInQueue <=20) {
		gFullQueue = false;
		if (gFullQueueTimer) clearTimeout(gFullQueueTimer);
	}
	displayMainStatus();
	displayQueueStatus();
}
function parseZingHitPage(theResult,theNumber,formData) {
    var parser = new DOMParser();
    var xmlDoc = parser.parseFromString(theResult.responseText,"text/html");
    var hitInfo = gMainData.hitCollection[theNumber];
    var hitData = hitInfo.data;
	var finalUrl = theResult.finalUrl;
    var thisZingOptions = gZingOptions[hitData.pay];
    thisZingOptions = (gZingOptions[hitData.pay]) ? gZingOptions[hitData.pay] : gZingOptions["0.01"];
    
    var goAccept = false;
    var theSearching = $(xmlDoc).find(".row-fluid .span6").eq(0);
    var receiptItemsCount = $(theSearching).find(".receipt_items .fieldswrapper").length;
    var inputCount = $(theSearching).find("input[type=text]").length;
    var multipleQuantityCount = $(theSearching).find("input[type=text].multiple_quantity").length;
    var codesCount = inputCount - 1 - multipleQuantityCount;
    var thePicturesCount = $(xmlDoc).find(".receipt_images").eq(0).find("img").length;
    
    var limitReceptItems = thisZingOptions.SearchGroupAllowed;
    var limitTallyCount = thisZingOptions.TallyCountTotalAllowed;
    var limitCodes = (thisZingOptions.AcceptCodesSearching) ? 10 : 0;
    var limitImages = thisZingOptions.MaxReceiptImages;
    if (receiptItemsCount <= limitReceptItems && multipleQuantityCount <= limitTallyCount && codesCount <= limitCodes && thePicturesCount <= limitImages) goAccept = true;
    if ( goAccept ) {
        if (checkLimits(theNumber)) {
            var acceptHitURL = acceptLink(formData);
            hitInfo.goToUrl.push({"url":acceptHitURL,"theNumber":theNumber});
            theCycler.frontOfTheLine(theNumber);
		} else if (gScriptStatus == "normal") {
            $("#JRCellNum_" + theNumber).stop(true,true);
            $("#JRCellNum_" + theNumber).css({"background-color":"#FF9999"});
            $("#JRCellNum_" + theNumber).animate({"backgroundColor": $("#JRCellNum_" + theNumber).data("backgroundColor")}, 40000);
        }
    } else processResults( theNumber, "SKIPPED", finalUrl );
}
function parseMturkHitPage(theResult,theNumber) {
    var hitInfo = gMainData.hitCollection[theNumber];
    var hitData = hitInfo.data;
    var parser = new DOMParser();
	var finalUrl = theResult.finalUrl;
    var xmlDoc = parser.parseFromString(theResult.responseText,"text/html");
    var alertBoxHeader = xmlDoc.getElementById("alertboxHeader");
    var dailyLimit = false;
    var errorTitle = xmlDoc.getElementsByClassName("error_title")[0];
    if (errorTitle && errorTitle.innerHTML.indexOf("You have exceeded the maximum allowed page request") != -1) {  processResults( theNumber, "TOOFAST", finalUrl ); return; }
    var loggedOff1 = xmlDoc.getElementById("ap_signin_custom_message");
    var loggedOff2 = xmlDoc.getElementById("lnkWorkerSignin");
    var loggedOff3 = xmlDoc.getElementById("signin-slot");
    if (loggedOff1 || loggedOff2 || loggedOff3) { processResults( theNumber, "LOGGEDOFF", finalUrl ); return; }
    if (alertBoxHeader) {
        var alertHeaderHTML = alertBoxHeader.innerHTML;
        if (alertHeaderHTML.indexOf("There are no more available HITs") != -1 || alertHeaderHTML.indexOf("There are no HITs in this group") != -1) {
            processResults( theNumber, "NOMORE", finalUrl );
            return;
        } else if (alertHeaderHTML.indexOf("has chosen to prevent you from working on any of this Requester") != -1) {
            processResults( theNumber, "BLOCKED", finalUrl );
            return;
        } else if (alertHeaderHTML.indexOf("You have accepted the maximum number of HITs allowed") != -1) {
            processResults( theNumber, "QUEUEMAX", finalUrl );
            return;
        } else if (alertHeaderHTML.indexOf("You have already accepted this HIT") != -1) {
            processResults( theNumber, "ALREADYACCEPT", finalUrl );
            return;
        } else if (alertHeaderHTML.indexOf("The HIT you were viewing could not be accepted") != -1) {
            processResults( theNumber, "NOACCEPT", finalUrl );
            return;
        } else if (alertHeaderHTML.indexOf("You are not qualified to accept") != -1 || alertHeaderHTML.indexOf("Your Qualifications do not meet the") != -1) {
            processResults( theNumber, "NOTQUALIFIED", finalUrl );
            return;
        }
        dailyLimit = (alertHeaderHTML.indexOf("There are no HITs available for you at this time") != -1);
    }
	hitInfo.status.notQual = 0; hitInfo.status.blocked = 0;
	if (xmlDoc.getElementsByName("userCaptchaResponse").length) {
		if (!gMainOptions.disableCaptchaAlert) {
			var addText = createDiv("Found a captcha.<br>Pausing.")
				.css({"margin-top":"30px","font-size":"17px","text-align":"center","color":"red"})
				.append(createDiv(createLink("Go to Mturk Page",hitInfo.pandaUrl,"_blank",hitInfo.pandaUrl)
					.click( function(e) {
						window.open($(e.target).attr("href"),"_blank","width=" + 1200 + ",height=" +  900 + ",scrollbars=yes,toolbar=yes,menubar=yes,location=yes");
						return false;
					})).css({"color":"blue","margin-top":"15px"}));
			showWaitDialog("Captcha Alert!!","",function() {
				theCycler.unpause();
				$("#JRPauseButton").html("Pause").css({"background-color":"ivory","color":"black"});
			},null,addText,true);
			if (!theCycler.isPaused()) {
				theCycler.pause();
				$("#JRPauseButton").html("Resume").css({"background-color":"red","color":"white"});
				playThisSound("hasToPause");
			}
		}
		return;
	}
    var hitAccepted = $(xmlDoc).find("img[src$='/media/return_hit.gif']");
    var notAccepted = $(xmlDoc).find("input[src$='/media/accept_hit.gif']");
    if (errorTitle && errorTitle.innerHTML.indexOf("Your request was not completed successfully") != -1) {
        processResults( theNumber, "NOTCOMPLETED", finalUrl );
    } else if (dailyLimit) {
        processResults( theNumber, "DAILYLIMIT", finalUrl );
    } else if (hitAccepted.length) {
        var updated = false;
        var hitGroupId = ($(xmlDoc).find("form[name='hitForm']").length) ? $(xmlDoc).find("form[name='hitForm']").eq(0).find("input[name='groupId']").eq(0).val() : "";
        hitData.groupId = hitGroupId;
		hitInfo.pandaUrl = pandaLink(hitData.groupId);
		hitInfo.previewUrl = previewLink(hitData.groupId);
        hitInfo.hitId = ($(xmlDoc).find("form[name='hitForm']").length) ? $(xmlDoc).find("form[name='hitForm']").eq(0).find("input[name='hitId']").eq(0).val() : "";
        var capsuleNode = $(xmlDoc).find("td.capsulelink_bold:first div").eq(0);
        var theTitle = (capsuleNode.length) ? $(capsuleNode).html().trim() : hitData.title;
        if (hitData.title != theTitle) { hitData.title = theTitle; updated=true; }
        var timeLeft = $(xmlDoc).find("a#time_left\\.tooltip");
        var theDuration = (timeLeft.length) ? timeLeft.parent().next().html().trim() : hitData.duration;
        if (hitData.duration != theDuration) { hitData.duration = theDuration; updated=true; }
        var requesterTip = $(xmlDoc).find("#requester\\.tooltip");
        var requesterNameNode = (requesterTip.length) ? $(requesterTip).parent().next() : null;
        var theRequesterName = (requesterNameNode.length) ? ( ($(requesterNameNode).find("a").length) ? $(requesterNameNode).find("a").html().trim() : $(requesterNameNode).html().trim() ) : "";
        theRequesterName = (theRequesterName) ? theRequesterName : hitData.requesterName;
        if (hitData.requesterName != theRequesterName) { hitData.requesterName = theRequesterName; updated=true; }
        var numberHitsTip = $(xmlDoc).find("#number_of_hits\\.tooltip");
        var theNumberHits = (numberHitsTip.length) ? numberHitsTip.parent().next().html().trim() : hitInfo.numberHits;
        hitInfo.numberHits = theNumberHits;
        var rewardTip = $(xmlDoc).find("#reward\\.tooltip");
        var theReward = (rewardTip.length) ? rewardTip.parent().next().find("span").html().replace("$","").trim() : hitData.pay;
        if (hitData.pay != theReward) { hitData.pay = theReward; updated=true; }
        processResults( theNumber, "ACCEPTED", finalUrl );
        if (updated) gDelayedSave = true;
        if (gMainOptions.debugger>1) console.log("accepted: " + theNumber + " | updated: " + updated + " | groupId: " + hitGroupId);
    } else if (notAccepted.length) {
        var formData = {};
        formData.hitId = $(xmlDoc).find("input[name='hitId']").eq(0).val();
        formData.prevHitSubmitted = $(xmlDoc).find("input[name='prevHitSubmitted']").eq(0).val();
        formData.prevRequester = $(xmlDoc).find("input[name='prevRequester']").eq(0).val();
        formData.requesterId = $(xmlDoc).find("input[name='requesterId']").eq(0).val();
        formData.prevReward = $(xmlDoc).find("input[name='prevReward']").eq(0).val();
        formData.groupId = $(xmlDoc).find("input[name='groupId']").eq(0).val();
        formData.signature = $(xmlDoc).find("input[name='signature']").eq(0).val();
        var iframeSrc = $(xmlDoc).find("iframe").attr("src");
        var acceptHitURL = acceptLink(formData);
		var useAcceptHit = false;
        if (iframeSrc && formData.requesterId=="AGVV5AWLJY7H2") {
			if (hitData.filterMode>0 && hitData.filterMode <= Object.keys(gZingFuncOptions).length) {
				requestUrl(iframeSrc, theNumber, gZingFuncOptions[hitData.filterMode].functionName, errorRequest, formData, "");
			} else { useAcceptHit = true;}
		}
        if (hitData.action.toLowerCase().indexOf("pantha")!=-1 || useAcceptHit) {
			//console.log("Pantha Mode is on or filter mode is on so need to accept after previewed.");
			hitInfo.goToUrl.push({"url":acceptHitURL,"theNumber":theNumber});
			theCycler.frontOfTheLine(theNumber);
			if ( hitInfo.ham == "paused" ) { toggleButton($("#JRHamB_" + theNumber),hamOn,hamOff); }
		}
    } else { processResults( theNumber, "ERROR", finalUrl ); }
}

function makeStatus() { return {"accepted":0,"skipped":0,"errors":0,"tooFast":0,"noHits":0,"fullQueue":0,"hitsStreak":0,
	"noHitsStreak":0,"searched":0,"orphan":0,"hitsResults":0,"notQual":0,"missed":0,"blocked":0}; }
function addHitCollection(theData,theNumber,tabIndex) {
    var pandaUrl = pandaLink(theData.groupId);
    var previewUrl = previewLink(theData.groupId);
    var filterFuncData = (theData.action.toLowerCase().indexOf("filter") != -1) ? ((theData.requesterId=="AGVV5AWLJY7H2") ? gZingFuncOptions : null) : null;
    gMainData.hitCollection[theNumber] =
        {"collecting":"off","pandaUrl":pandaUrl,"previewUrl":previewUrl,"goToUrl":[],"theNumber":theNumber,"data":theData,"status":makeStatus(),"specialOptions":null,
		"hitCell":null,"ham":"off","minutes":0,"newTitle":"","numberHits":"0","once":false,"filterFuncData":filterFuncData,"searching":"off","lastAccept":null,
		"tabIndex":tabIndex,"hitId":"",durationParsed:null,"dateDone":null,"elapsedSeconds":0};
    return theNumber;
}
function addQueueCheck() {
    theCycler.addJob( function( elapsed, theNumber ) {
        gMainData.queueStatus.searched++;
        requestUrl("https://www.mturk.com/mturk/sortmyhits?searchSpec=HITSearch%23T%231%2310%23-1%23T%23!Status!0!rO0ABXQACEFzc2lnbmVk!%23!Deadline!0!%23!&selectedSearchType=hitgroups&searchWords=&sortType=Deadline%3A0&pageSize=25",1,function(theResult,theNumber,data1,data2) {
			displayMainStatus();
            return parseQueuePage(theResult);
        },function() { errorRequest(); } );
        return true;
    }, -1, gMainOptions.queueTimer);
}
function startCollecting(theNumber,thisButton) {
    var hitInfo = gMainData.hitCollection[theNumber];
    var hitData = hitInfo.data;
    if (hitData.once) hitData.dailyDone = 0;
    hitInfo.collecting = "on";
    //console.log("Turning on " + theNumber);
    theCycler.addJob( function( elapsed, theNumber ) {
        var hitInfo = gMainData.hitCollection[theNumber];
        var hitData = hitInfo.data;
		var hitStatus = hitInfo.status;
		var thisNewDate = new Date();
        if (hitInfo.ham == "ontimed") {
            if (hitData.hamTimer > 0 && hitInfo.lastAccept!==null) {
                var accElapsedTime = thisNewDate - hitInfo.lastAccept;
                var theSeconds = accElapsedTime / 1000;
                var offHamMode = (hitInfo.ham == "ontimed") ? "paused" : "off";
                if (theSeconds >= hitData.hamTimer) {
                    toggleButton($("#JRHamB_" + theNumber),hamOn,hamOff,offHamMode);
                    hitInfo.lastAccept = null;
                }
            }
        }
        if ( checkLimits(theNumber) ) {
			var theUrl = "";
			var hitDataAction = hitData.action.toLowerCase();
			hitInfo.elapsedSeconds = (hitInfo.dateDone) ? (Math.round( ((thisNewDate - hitInfo.dateDone)/1000) * 10 ) / 10) : 0;
			hitInfo.dateDone = thisNewDate;
            hitStatus.searched++;
            if (hitInfo.goToUrl.length) {
                //console.log("Found a gotoUrl so I must do Url");
                if ( (hitDataAction.substring(0,6) == "search" || hitDataAction == "filterpanda" || hitDataAction == "pantha") && !hitInfo.hitCell.data("saveSearchGroupId") )
                    theUrl = (hitInfo.goToUrl.shift()).url;
                else theUrl = (hitInfo.goToUrl[0]).url;
            } else {
                theUrl = ( hitDataAction == "panda" ) ? hitInfo.pandaUrl : (hitDataAction.substring(0,6) == "search") ? 
					requesterSearch(hitData.requesterId) : hitInfo.previewUrl;
            }
            gMainData.searched++;
            gMainData.lastElapsed = elapsed;
            if (gMainOptions.debugger>2) console.log("Doing Number: " + theNumber + " | going to: " + theUrl);
            if (theUrl.indexOf("selectedSearchType=hitgroups")!=-1) requestUrl(theUrl,theNumber,parseHitSearchPage,
				errorRequest, hitStatus.searched, "");
            else requestUrl(theUrl,theNumber,parseMturkHitPage, errorRequest, hitStatus.searched, "");
            displayHitStatus(theNumber);
			addToStatusLog(theNumber);
            return true;
		} else if (gScriptStatus == "normal") {
            $("#JRCellNum_" + theNumber).stop(true,true);
            $("#JRCellNum_" + theNumber).css({"background-color":"#FF9999"});
            $("#JRCellNum_" + theNumber).animate({"backgroundColor": $("#JRCellNum_" + theNumber).data("backgroundColor")}, 40000);
            return false;
        }
    }, theNumber, 0, false, hitData.weight);
    gMainData.jobs++;
    //addQueueCheck();
}
function stopCollecting(theNumber,thisButton) {
    if (gMainOptions.debugger>1) console.log("turning off " + theNumber);
    if (gMainData.hitCollection[theNumber].collecting == "on") {
		setTimeout( function() { if (gMainData.hitCollection[theNumber].collecting == "off") removeFromStatusLog(theNumber); },15000);
        gMainData.hitCollection[theNumber].collecting = "off";
        gMainData.hitCollection[theNumber].goToUrl.splice(0,gMainData.hitCollection[theNumber].goToUrl.length);
        theCycler.removeJob(theNumber);
        gMainData.jobs--;
    }
    displayHitStatus(theNumber);
}
function stopAll() {
    $.each(gMainData.hitCollection, function( index, value ) {
        if (value.collecting == "on") {
            toggleButton( $("#JRCollectB_" + index),startCollecting,stopCollecting);
            if (value.collecting=="off" && value.ham != "off") toggleButtonOff($("#JRHamB_" + index),hamOn,hamOff);
        }
    });
}
function hamOn(theNumber,thisButton) {
    var onMode = "on";
    var hitInfo = gMainData.hitCollection[theNumber];
    $(".JRHamButton").each( function() {
        if ( $(this).data("theNumber") != theNumber ) $(this).data("disabled",true);
        updateHitColors($(this).data("theNumber"));
    });
    if (hitInfo.ham == "paused") {
		onMode = "ontimed";
		if (hitInfo.data.hamTimer > 0) hitInfo.lastAccept = new Date();
	}
    hitInfo.ham = onMode;
    theCycler.hamOn(theNumber);
    theCycler.skippingReset();
    theCycler.cycleResetChange(gMainOptions.HamCycleNumber);
}
function hamOff(theNumber,thisButton,theMode) {
    var passedMode = theMode || "";
    var hitInfo = gMainData.hitCollection[theNumber];
    if (hitInfo.ham.substring(0,2) == "on") {
        $(".JRHamButton").each( function() {
            if ( $(this).data("disabled") ) $(this).data("disabled",false);
            updateHitColors($(this).data("theNumber"));
        });
		cycleButtonSelect(gMainOptions.savedCycleNum);
		theCycler.hamOff();
		theCycler.skippingReset();
    }
	hitInfo.lastAccept = null;
    if (passedMode === "" && hitInfo.ham == "ontimed" && hitInfo.collecting != "off") passedMode = "paused";
    gMainData.hitCollection[theNumber].ham = (passedMode==="") ? "off" : passedMode;
	saveGroupIdSearching(hitInfo,false);
}
function muteJob(theNumber) {
    var hitInfo = gMainData.hitCollection[theNumber];
    hitInfo.data.mute = !hitInfo.data.mute;
    hitInfo.hitCell.data("mute",hitInfo.data.mute);
    updateHitColors( theNumber );
    saveSettings();
}
function helpToolTips() {
	if (gMainOptions.showHelpTooltips) $(".hasHelptip").tooltip( "option", "disabled", false );
	else $(".hasHelptip:not(.keepHelptip)").tooltip( "option", "disabled", true );
}
function createBlankDiv() {
	return createDiv("&nbsp;").attr("class","JRHitCell JRHitBlank").css({"border":"3px solid black", "margin":"2px 4px", "float":"left", "width":"206px", "height":"76px"});
}
function addTab(tabContainer,theTitle,isSortable,theID,tabData,appendClose) {
    var theTab = createTab(tabContainer,theTitle,isSortable,theID,tabData,appendClose)
        .data({"tabData":tabData});
    createDiv().insertBefore(theTab.find("br.cleartab"))
        .data({"tabData":tabData})
        .attr({"class":"tabContents connectedSortable"})
        .css({"overflow":"auto"})
		.droppable({ tolerance: 'pointer', drop: moveToTab })
        .sortable({dropOnEmpty: true,delay:400,tolerance: "pointer","items":".JRHitCell:not(.ui-not-sortable)",
            helper:"clone",opacity: 0.9,appendTo:"body",
            start: function( event, ui ) {
                ui.item.addClass('noclick');
                ui.item.data("oldPosition",ui.item.index());
                ui.item.data("sameTab",true);
            },
			stop: function( event, ui ) {
                if (ui.item.data("hitInfo") && !ui.item.data("received")) {
                    var thePositions = gTabsData[ui.item.data("hitInfo").tabIndex].positions;
                    thePositions.splice(ui.item.index(), 0, thePositions.splice(ui.item.data("oldPosition"), 1)[0]);
                    saveSettings();
				}
			}
        });
    return theTab;
}
function fillNewHitData(requesterName, requesterId, groupId, pay, title, duration, onlyOnce, toMain, collectNow) {
	var active = (toMain) ? 0 : $( "#JRMainTabs" ).tabs( "option", "active" );
	var newHitData = jQuery.extend(true, {}, gRequestersData[0]);
	newHitData.action = "panda"; newHitData.qual = ""; newHitData.queueLimit = 0; newHitData.audioforce = ""; newHitData.hitlimit = ""; newHitData.mute = false;
	newHitData.position = null; newHitData.tabNumber = gTabsData[active].tabNumber; newHitData.hamTimer = gMainOptions.hamDelayTimer; newHitData.once = onlyOnce;
	newHitData.requesterName = (requesterName) || ""; newHitData.requesterId = (requesterId) || ""; newHitData.groupId = groupId;
	newHitData.pay = (pay) || "0.00"; newHitData.title = (title) || groupId; newHitData.duration = (duration) || "";
	var newCell = addHitData(newHitData,active);
	if (collectNow) {
		newCell.data("status","on");
		toggleButton( newCell.find(".JRCollectButton"),startCollecting,stopCollecting );
	}
	if (theCycler.isHamOn()) newCell.find(".JRHamButton").data("disabled",true);
	updateHitCell(newCell.data("theNumber"));
	updateHitColors(newCell.data("theNumber"));
	return newCell.data("theNumber");
}
function changeToEdited() { $("#JREditDialog").data("edited",true); $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Save')").button().show(); }
function dataEdited(thisArea,theValue) {
    changeToEdited();
    var inputEdit = createTextInput(theValue).css({"width":"300px"});
	if ($(thisArea).data("doClick")) $(inputEdit).click( function(e) { $(thisArea).data("doClick")(e); });
    $(inputEdit).focus( function(e) {
		if ($(thisArea).data("doFocus") && !$(thisArea).data("focusOff")) $(thisArea).data("doFocus")(e);
		$(e.target).select();
	});
    $(thisArea).find("span:not(.errorEditLine):not(.defaultEdit)").replaceWith(inputEdit);
    $(inputEdit).focus();
}
function dataIncDecNumber(currentNumber,limitNumber) {
	return createSpan().append(createSpanButton( function(e) {
		var numberIncDec = $(e.target).parent().find(".numberIncDec");
		var theNumber = parseInt(numberIncDec.html());
		theNumber = (theNumber>0) ? theNumber-1 : 0;
		numberIncDec.html(theNumber);
		changeToEdited();
	},"<",gButtonOffBgColor,gButtonOffColor,"9px"))
	.append(createSpan(currentNumber.toString()).attr({"class":"numberIncDec"})).append(createSpanButton( function(e) {
		var limitNumber = $(e.target).data("limitNumber");
		var numberIncDec = $(e.target).parent().find(".numberIncDec");
		var theNumber = parseInt(numberIncDec.html());
		theNumber = (theNumber<limitNumber) ? theNumber+1 : limitNumber;
		numberIncDec.html(theNumber);
		changeToEdited();
	},">",gButtonOffBgColor,gButtonOffColor,"9px").data({"limitNumber":limitNumber}));
}
function dataTrueFalse(thisArea,theValue) {
    changeToEdited();
    if (theValue) returnValue=false;
    else returnValue=true;
    $(thisArea).find("span").html(returnValue.toString());
    return returnValue;
}
function dataRadioButtons(theName,theValues,theValue,theChangeFunction) {
	var radioButtons = createSpan().data("changeFunction",theChangeFunction);
	$.each(theValues, function(index, value) {
		var valueID = value.toLowerCase();
		var aRadio = createRadioButton(theName,valueID).attr({"id":valueID + "_radio_" + index}).css({"width":"20px"});
		if (valueID == theValue) aRadio.prop("checked",true);
		else aRadio.prop("checked",false);
		createSpan().append(aRadio).append($("<label for='" + valueID + "_radio_" + index + "'>").attr({"class":"JREditRadioB"}).append(value)
			.data("theValue",valueID)).appendTo(radioButtons);
	});
	$(radioButtons).buttonset();
	$(radioButtons).change( function() { changeToEdited(); ($(this).data("changeFunction"))($(this).find(".JREditRadioB[aria-pressed='true']:first").data("theValue")); });
    return radioButtons;
}
function dataPandaSearch(thisArea,theValue) {
    changeToEdited();
    if (theValue) returnValue=false;
    else returnValue=true;
    $(thisArea).find("span").html(returnValue.toString());
    return returnValue;
}
function saveAlarmsData() {
    $.each(gAlarmSounds, function( index, value ) {
        var importFileID = "importFileInput-" + index;
        value.audio = $("#" + importFileID).data("audio");
        var base64 = $("#" + importFileID).data("base64");
        if (base64) GM_setValue(value.nameVar,JSON.stringify(base64));
    });
    saveSettings();
	return true;
}
function saveOptionsData() {
    var showHelpTooltipsEdit = $("#JREditDialog #showHelpTooltipsEdit input");
    if (showHelpTooltipsEdit.length) gMainOptions.showHelpTooltips = $(showHelpTooltipsEdit).eq(0).val();
	editLineSaveData(function(theKey,theData) { gMainOptions[theKey] = theData; });
	helpToolTips();
    saveSettings();
	cycleButtonSelect(gMainOptions.savedCycleNum);
    displayMainStatus();
	return true;
}
function saveEditedInput(theSelector,theTag) { // inputSelector for the id or class name, returns value.
	if ($(theSelector + ".isInt " + theTag).length) { return parseInt( $(theSelector + " " + theTag).eq(0).val()); }
	else if ($(theSelector + ".isInt .numberIncDec").length) { return parseInt( $(theSelector + ".isInt .numberIncDec").eq(0).html()); }
	else if ($(theSelector + " " + theTag).length) { return $(theSelector + " " + theTag).eq(0).val(); }
	else return null;
}
function editLineSaveData(objectSaveFunction) {
	$("#JREditDialog .editLine").each( function(index,value) {
		var theKey = $(value).data("dataKey");
		if (theKey) {
			tempSave = saveEditedInput("#"+theKey+"Edit","input");
			if (tempSave!==null) objectSaveFunction(theKey,tempSave);
		}
	});
}
function editLineDataCheck() {
	var theReturnValue = true;
	$("#JREditDialog .editLine").each( function(index,value) {
		var newReturnValue = true;
		if ( $(value).find("input").length && $(value).data("dataCheck") ) newReturnValue = ($(value).data("dataCheck"))($(value).find("input"));
		theReturnValue = theReturnValue & newReturnValue;
		if (!theReturnValue) return false;
	});
	return theReturnValue;
}
function saveTimersData() {
	if (!editLineDataCheck()) return false;
	editLineSaveData(function(theKey,theData) { gMainOptions[theKey] = theData; });
	theCycler.removeJob(-1); addQueueCheck(); // Reset queue watch just incase queue timer was changed.
	$("#JrCycleAddingButton").find("span").html("Add " + gMainOptions.cycleAdding); // Change adding button text just in case time was changed.
    saveSettings();
	cycleButtonSelect(gMainOptions.savedCycleNum); // Reset cycleNumber just in case it was changed.
    displayMainStatus();
	return true;
}
function saveJobData() {
	if (!editLineDataCheck()) return false;
    var theNumber = $("#JREditDialog").data("theNumber");
    var hitInfo = gMainData.hitCollection[theNumber];
    var hitData = hitInfo.data;
	var tempSave = saveEditedInput("#filterModeEdit","select");
	editLineSaveData(function(theKey,theData) { hitData[theKey] = theData; });
	if (tempSave!==null) hitData.filterMode = tempSave;
	if (hitInfo.collecting != "off") theCycler.changeWeight(theNumber,hitData.weight);
	hitInfo.pandaUrl = pandaLink(hitData.groupId); hitInfo.previewUrl = previewLink(hitData.groupId); // Reset pandalink and previewlink just in case groupind was changed.
    updateHitCell(theNumber);
    saveSettings();
    updateHitColors( theNumber );
	return true;
}
function saveEditedData() {
    if ( $("#JREditDialog").data("edited") ) {
        if ($("#JREditDialog").data("editing") == "job") return saveJobData();
        else if ($("#JREditDialog").data("editing") == "timers") return saveTimersData();
        else if ($("#JREditDialog").data("editing") == "alarms") return saveAlarmsData();
        else if ($("#JREditDialog").data("editing") == "options") return saveOptionsData();
        else if ($("#JREditDialog").data("editing") == "groupingCreate") return saveGroupingCreateData();
        else if ($("#JREditDialog").data("editing") == "groupingHitsEdit") return saveGroupingHitsData();
    }
}
function saveToFile(theData) {
    var blob = new Blob( [JSON.stringify(theData)], {type: "text/plain"});
    var dl = document.createElement("A");
    dl.href = URL.createObjectURL(blob);
    dl.download = "PandaCrazy_" + formatAMPM("short") + ".json";
    document.body.appendChild(dl);
    dl.click();
    dl.remove();
}
function exportJobs(exportAlarms) {
    //load from database to temp data variable
	exportAlarms = exportAlarms || false;
	showWaitDialog("Exporting Data","",function() {},null,createDiv("Exporting Data. Please Wait....").css({"font-size":"17px","text-align":"center","margin-top":"20px"}));
	setTimeout( function() {
		saveToFile({"Requesters":gRequestersData,"Options":gMainOptions,"Tabsdata":gTabsData,"Grouping":gGroupingData,"Tabsinfo":gTabsInfo,
			"SoundOptions":setupSoundOptions(exportAlarms)});
		appendToWaitDialog(createDiv("Finished exporting the data.").css({"font-size":"17px","text-align":"center","margin-top":"20px"}));
	},1000);
}
function importJobs(theFile) {
    //load json text and verify it's correct data for the database
	showWaitDialog("Importing Your Data","Please wait for importing data",function() { saveSettings(); });
    if (window.File && window.FileReader && window.FileList && window.Blob) {
        var reader = new FileReader();
        reader.onload = function() {
			addToWaitDialog("Loaded file in memory.",true);
            var textData = reader.result;
            setTimeout( function() {
                try {
					addToWaitDialog("Parsing the imported Data.",true);
                    var theData = JSON.parse(textData);
					addToWaitDialog("Stopping all Jobs",true);
                    stopAll();
                    setTimeout( function() {
						addToWaitDialog("Removing all Job Cells",true);
                        $("#JRMainTabs").find(".ui-tabs-panel").each( function() {
                            $(this).find(".JRHitCell").each( function() {
                                $(this).remove();
                            });
                        });
                        setTimeout( function() {
							addToWaitDialog("Removing all Tabs",true);
                            $.each(gTabsData, function( index, value ) {
                                var panelId = $("#JRTab_" + value.tabNumber).closest( "li" ).remove().attr( "aria-controls" );
                                $( "#" + panelId ).remove();
                                $("#JRMainTabs").tabs( "refresh" );
                            });
                            setTimeout( function() {
								addToWaitDialog("Deleting Collection Data",true);
                                $.each(gMainData.hitCollection, function( index, value ) {
                                    delete gMainData.hitCollection[index];
                                });
                                setTimeout( function() {
									addToWaitDialog("Deleting Requesters Data",true);
                                    $.each(gRequestersData, function( index, value ) { delete gRequestersData[index]; });
									addToWaitDialog("Deleting Grouping Data",true);
                                    $.each(gGroupingData, function( index, value ) { delete gGroupingData[index]; });
                                    $.each(gGroupings, function( index, value ) { delete gGroupings[index]; });
                                    gGroupingsSort.splice(0,gGroupingsSort.length);
                                    setTimeout( function() {
										addToWaitDialog("Deleting Tabs",true);
                                        $.each(gTabsData, function( index, value ) {
                                            delete gTabsData[index];
                                        });
										gTabsInfo = {};
										$("#addNewtab").remove();
                                        setTimeout( function() {
											addToWaitDialog("Adding imported data in the database.",true);
											gMainOptions = theData.Options;
											defaultFillIn(gMainOptions,gDefaultMainOptions);
											var soundOptions = {};
											if (theData.SoundOptions) soundOptions = theData.SoundOptions;
											else soundOptions = setupSoundOptions();
											fillInSoundOptions(soundOptions);
											gRequestersData = loadInDBVersions(theData.Requesters);
											gTabsData = theData.Tabsdata;
											if (theData.Tabsinfo) gTabsInfo = theData.Tabsinfo;
											else gTabsInfo = gDefaultTabsInfo;
											convertTabDatabase();
											$.each(gTabsData, function( index, value ) { defaultFillIn(value,gDefaultTabsData[0]); });
                                            if (theData.Grouping) gGroupingData = theData.Grouping;
											else gGroupingData = gDefaultGroupingData;
											$.each(gGroupingData, function( index, value ) { defaultFillIn(value,gDefaultGroupingData["JR First"]); });
                                            fillInGroupings();
                                            $.each(gTabsData, function( index, value ) {
												addTab($("#JRMainTabs"),value.tabName,true,"JRTab_" + value.tabNumber,value,true).css({"overflow":"visible"});
                                            });
                                            fillTabs();
											appendAddTabButton();
                                            setTimeout( function() {
												changeOldSettings();
                                                $("#JRMainTabs").tabs("option", "active", 0);
												appendToWaitDialog(createDiv("Importing is finished.").css({"color":"darkblue","margin-top":"5px","text-align":"center","font-size":"16px"}),true);
                                                $("#JRWaitDialog").dialog("option", "title", "Importing data is now done.");
												$("#JRMainTabs").css({"height":$(".ui-layout-center").innerHeight() - $("#JRTheControls").innerHeight() - 8});
												$("#JRMainTabs").find(".tabContents").css({"height":$(".ui-layout-center").innerHeight() - $("#JRMainTabs")
													.find(".ui-tabs-nav").innerHeight() - $("#JRTheControls").innerHeight() - 8});
                                            },1);
                                        },1);
                                    },1);
                                },1);
                            },1);
                        },1);
                    },1);
                } catch(e) {
                    console.log("Could not parse text in file. Sorry.");
                }
            },50);
        };
        reader.readAsBinaryString(theFile);
        reader.onerror = function() {
            alert('Unable to read ' + file.fileName);
        };
        return true;
    } else {
        alert('The File APIs are not fully supported by your browser. Fallback required.');
        return false;
    }
}
function formatDialog(idName,theHeight,theWidth,theTitle,theButton,editing,theModal) {
	// An all purpose function to reinitialize a dialog for use
    $("#" + idName).dialog("option","height",theHeight);
    $("#" + idName).dialog("option","width",theWidth);
    $("#" + idName).dialog("option", "title", theTitle);
    $("#" + idName).dialog("option", "position", { my: "center", at: "center", of: $("body") });
    $("#" + idName).data({"edited":false,"editing":editing,"theNumber":null,"button":theButton,"closeme":null,"yesFunction":null,
		"NOCloseDialog":false,"nameKey":null,"theGrouping":null,"theDelayed":null});
    $("#" + idName).dialog("option","modal",theModal);
    $(".ui-dialog-titlebar").show();
	$("#JRSavedMturkArea").hide(); $("#JRSavedJobsArea").hide();
    $("div[aria-describedby='" + idName + "'] .ui-dialog-buttonpane button:contains('Yes')").hide();
    $("div[aria-describedby='" + idName + "'] .ui-dialog-buttonpane button:contains('Stop') span").html("No");
    $("div[aria-describedby='" + idName + "'] .ui-dialog-buttonpane button:contains('No')").hide();
    $("div[aria-describedby='" + idName + "'] .ui-dialog-buttonpane button:contains('Create Group')").hide();
    $("div[aria-describedby='" + idName + "'] .ui-dialog-buttonpane button:contains('Save')").hide();
    $("div[aria-describedby='" + idName + "'] .ui-dialog-buttonpane button:contains('Close') span").html("Cancel");
    $("div[aria-describedby='" + idName + "'] .ui-dialog-buttonpane button:contains('Unpause') span").html("Cancel");
    $("div[aria-describedby='" + idName + "'] .ui-dialog-buttonpane button:contains('Cancel')").show();
    $("#" + idName + " .JRContents:first").remove();
}
function checkGroupings(groupingData) {
    if (!groupingData.data) return false;
    if (!groupingData.data.grouping) return false;
    for (var i=0; i<groupingData.data.grouping.length; i++) {
        if ( !gRequestersData[groupingData.data.grouping[i]] ) { groupingData.data.grouping.splice(i, 1); i--; }
        else groupingData.data.grouping[i] = "" + groupingData.data.grouping[i];
    }
    if (groupingData.data.grouping.length===0) return false;
    return true;
}
function saveGroupingHitsData() {
	var nameChanged = $("#groupNameEdit input").length;
	var newName = (nameChanged) ? $("#groupNameEdit input").val().toString() : $("#JREditDialog").data("nameKey");
	if ( nameChanged && newName === "" ) {
		$(".errorEditLine:first").html("Please name this group!");
		return false;
	} else if ( nameChanged && (newName in gGroupingData) ) {
		$(".errorEditLine:first").html("This Name must be Unique!");
		return false;
	} else {
		if (nameChanged && ($("#JREditDialog").data("nameKey") != newName)) {
			var savedData = gGroupingData[$("#JREditDialog").data("nameKey")];
			var savedGroupings = gGroupings[$("#JREditDialog").data("nameKey")];
			delete gGroupingData[$("#JREditDialog").data("nameKey")];
			delete gGroupings[$("#JREditDialog").data("nameKey")];
			var theIndex = gGroupingsSort.indexOf($("#JREditDialog").data("nameKey"));
			gGroupingsSort.splice(theIndex,1,newName);
			gGroupingData[newName] = savedData;
			gGroupings[newName] = savedGroupings;
			$("#JREditDialog").data("nameKey",newName);
		}
		var tempGrouping = [];
		var tempDelayed = [];
		$("#JREditDialog .groupingHitCell").each( function() {
			if (!$(this).data("removeMe")) tempGrouping.push("" + $(this).data("theNumber"));
			if ($(this).data("delayed")) tempDelayed.push("" + $(this).data("theNumber"));
		});
		gGroupingData[$("#JREditDialog").data("nameKey")].grouping = tempGrouping;
		gGroupingData[$("#JREditDialog").data("nameKey")].delayed = tempDelayed;
		if ($("#groupDescriptionEdit input").length) {
			gGroupingData[$("#JREditDialog").data("nameKey")].description = $("#groupDescriptionEdit input").val().toString();
		}
		showGroupingDialog("view",$("#JREditDialog").data("button"));
        saveSettings();
		return true;
	}
}
function saveGroupingCreateData(theName,theDescription) {
    theDescription = theDescription || "";
    theName = theName || "";
	gScriptStatus = "normal";
    if ( theName !== "" && !(gGroupingData[theName]) ) {
        gGroupingData[theName] = {"theNumber":++gGroupingData["JR First"].theNumber,
            "description":theDescription,"grouping":$("#JREditDialog").data("theGrouping"),"delayed":$("#JREditDialog").data("theDelayed")};
        gGroupings[theName] = {"data":gGroupingData[theName],"collecting":false};
        gGroupingsSort.push(theName);
        saveSettings();
        return true;
    } else if ($("#JREditDialog").data("creating") == "add") {
		$(".JRHitCell .JRButton").removeClass("ui-state-disabled");
		$(".JRHitCell").each( function() { updateHitColors($(this).data("theNumber")); });
		var nameKey = $("#JREditDialog").data("nameKey");
		var tempGrouping = [];
		var tempDelayed = [];
		$(".JRHitCell:not('.JRHitDummy')").each( function() {
			if ($(this).data("selected") !== 0) {
				tempGrouping.push("" + $(this).data("theNumber"));
				if ($(this).data("selected") == "2") tempDelayed.push("" + $(this).data("theNumber"));
			}
		});
		gGroupingData[nameKey].grouping = tempGrouping;
		gGroupingData[nameKey].delayed = tempDelayed;
        saveSettings();
		$("#JREditDialog").dialog( "close");
		showGroupingDialog("view",$("#JREditDialog").data("button"));
        return true;
    } else return false;
}
function showWaitDialog(theTitle,theText,closeMeFunction,theButton,appendMe,showUnpause,theHeight,theWidth) {
	theHeight = theHeight || 310;
	theWidth = theWidth || 320;
    $("#JRWaitDialog").dialog("option","height",theHeight);
    $("#JRWaitDialog").dialog("option","width",theWidth);
	$("#JRWaitDialog").dialog("option", "title", theTitle);
	if (appendMe) $("#JRWaitDialog").html("").append(appendMe);
	else $("#JRWaitDialog").html("").append(createDiv(theText));
	if (theButton) $("#JRWaitDialog").data("button",theButton);
	if (closeMeFunction) {
		$("div[aria-describedby='JRWaitDialog'] .ui-dialog-buttonpane button:contains('Cancel') span").html((showUnpause) ? "Unpause" : "Close");
		$("div[aria-describedby='JRWaitDialog'] .ui-dialog-buttonpane button:contains('Close')").show();
		$("div[aria-describedby='JRWaitDialog'] .ui-dialog-buttonpane button:contains('Unpause')").show();
		$("#JRWaitDialog").data("closeme",closeMeFunction);
	}
	if (showUnpause) {
		$("div[aria-describedby='JRWaitDialog'] .ui-dialog-buttonpane button:contains('No') span").html("Stop");
		$("div[aria-describedby='JRWaitDialog'] .ui-dialog-buttonpane button:contains('Stop')").show();
	}
	$("#JRWaitDialog").dialog("open");
    $("#JRWaitDialog").dialog("option", "position", {my: "center", at: "center", of: window});
}
function appendToWaitDialog(appendThis) { $("#JRWaitDialog").append(appendThis);}
function addToWaitDialog(addText,newLine) {
	if (newLine) $("#JRWaitDialog").append(createDiv(addText));
	else $("#JRWaitDialog").append(createSpan(addText));
}
function showPromptDialog(promptQuestion,theValue,theButton,theYesFunction) {
	formatDialog("JRPromptDialog",160,600,"",theButton,"groupingCreate",true);
	$("div[aria-describedby='JRPromptDialog'] .ui-dialog-titlebar").hide();
    $("div[aria-describedby='JRPromptDialog'] .ui-dialog-buttonpane button:contains('Yes')").show();
    $("div[aria-describedby='JRPromptDialog'] .ui-dialog-buttonpane button:contains('Yes') span").html("OK");
	$("#JRPromptDialog").data("yesFunction",function() { theYesFunction($("#JRPromptDialog .textInputField").val()); } );
	createDiv().attr("class","JRContents").appendTo($("#JRPromptDialog"));
	var textInputArea = createDiv().attr("class","textInputArea").css({"margin":"25px 15px"}).appendTo($("#JRPromptDialog .JRContents:first"));
	createDiv().html(promptQuestion).css({"font-size":"15px"}).appendTo(textInputArea);
	createDiv().append(createTextInput(theValue).attr("class","textInputField").select().css({"width":"200px","margin":"5px 0 0 30px","height":"25px"})).appendTo(textInputArea);
	$("#JRPromptDialog").dialog("open");
	$(".textInputField").select();
}
function showYesNoDialog(theQuestion,theYesFunction,data1,data2) {
	$("#JRYesNoDialog").html("");
	$("#JRYesNoDialog").data({"data1":data1,"data2":data2});
	$("#JRYesNoDialog").data("yesFunction", function() { theYesFunction($("#JRYesNoDialog").data("data1"),$("#JRYesNoDialog").data("data2")); $("#JRYesNoDialog").dialog( "close"); });
	createDiv(theQuestion).attr("class","questionArea").css({"margin":"15px 8px","font-size":"19px","text-align":"center","line-height":"20px"}).appendTo($("#JRYesNoDialog"));
	$("#JRYesNoDialog").dialog("open");
}
function createGroup() {
    var creating = $("#JREditDialog").data("creating");
    $("#JREditDialog").dialog( "close");
    $(".ui-dialog-titlebar").show();
    gScriptStatus = "normal";
    $(".JRHitCell .JRButton").removeClass("ui-state-disabled");
    $(".JRHitCell").each( function() { updateHitColors($(this).data("theNumber")); });
    $("div[aria-describedby='JREditDialog']").removeClass("notmodal");
    var theGrouping = [];
    var theDelayed = [];
    $(".JRHitCell").each( function() {
        if (creating=="selection") {
            if ($(this).data("selected")!==0) theGrouping.push("" + $(this).data("theNumber"));
			if ($(this).data("selected")==2) theDelayed.push("" + $(this).data("theNumber"));
        } else {
            if ($(this).data("hitInfo").collecting != "off") {
				theGrouping.push("" + $(this).data("theNumber"));
				var hamStatus = $(this).data("hitInfo").ham;
				if (hamStatus == "paused" || hamStatus == "ontimed") theDelayed.push("" + $(this).data("theNumber"));
			}
        }
        $(this).data("selected",false);
    });
    showGroupingCreateDialog($("#JREditDialog").data("button"),theGrouping,theDelayed,"grouping");
}
function showGroupingCreateDialog(theButton,theGrouping,theDelayed,creating,nameKey) {
    var infoArea = createDiv().attr("class","infoArea").css({"margin":"15px 15px"});
    if (creating=="selection" || creating=="collecting" || creating=="add") {
        formatDialog("JREditDialog",106,600,"Select jobs to your group",theButton,"groupingCreate",false);
        gScriptStatus = "creating groupings";
        $("#JREditDialog").data({"creating":creating,"nameKey":nameKey});
		if (creating!="collecting") {
			$("#JREditDialog").data("NOCloseDialog",true); $(".JRHitCell").stop(true,true);
			$(".JRHitCell:not('.JRHitDummy')").css({"background-color":"#00FFEE"});
			$(".JRHitCell .myFloater").css({"background-color":"#00FFEE"});
			$(".JRHitCell .JRButton").addClass("ui-state-disabled");
			$("div[aria-describedby='JREditDialog']").addClass("notmodal");
		}
        $("#JREditDialog").data("closeme",function() {
            gScriptStatus = "normal";
            $(".JRHitCell .JRButton").removeClass("ui-state-disabled");
            $(".JRHitCell").each( function() { updateHitColors($(this).data("theNumber")); });
			$("#JREditDialog").dialog( "close");
			if (creating=="add") {
				$("#JREditDialog").dialog( "close");
				showGroupingDialog("view",$("#JREditDialog").data("button"));
			} else {
				releaseButton($("#JREditDialog"));
				$("#JREditDialog").dialog( "close");
			}
        });
        $("#JREditDialog").dialog("option", "position", { my: "center top", at: "center top", of: $("body") });
		createDiv().attr("class","JRContents").appendTo($("#JREditDialog"));
        infoArea.css({"margin":"8px 12px"}).appendTo($("#JREditDialog .JRContents:first"));
        if (creating!="add") $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Create Group')").show();
		else $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Save')").show();
        if (creating=="selection" || creating=="add") {
			if (nameKey) {
				var groupingsData = gGroupings[nameKey].data;
                $("#JREditDialog").data("edited",true);
				for (var i=0,len=groupingsData.grouping.length; i<len; i++) {
					$("#JRCellNum_" + groupingsData.grouping[i]).data("selected",0);
					if (groupingsData.delayed.indexOf(groupingsData.grouping[i]) != -1) {
						$("#JRCellNum_" + groupingsData.grouping[i]).css({"background-color":"#33CC66"});
						$("#JRCellNum_" + groupingsData.grouping[i]).data("selected",2);
					} else {
						$("#JRCellNum_" + groupingsData.grouping[i]).css({"background-color":"#ADFF2F"});
						$("#JRCellNum_" + groupingsData.grouping[i]).data("selected",1);
					}
				}
			}
            createDiv().html("Click on the jobs you want in this group below.<br>Right click on the jobs you want to be in Delayed Ham Mode.")
                .css({"font-size":"13px","text-align":"center","margin-top":0}).appendTo(infoArea);
        } else {
            if (gMainData.jobs===0) {
                createDiv().html("Sorry. You need to start collecting hits to create a grouping instantly.")
                    .css({"font-size":"14px","text-align":"center"}).appendTo(infoArea);
                $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Create Group')").hide();
				$("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Save')").hide();
                $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Cancel') span").html("Close");
            } else {
                createDiv().html("Do you really want to create an instant grouping for all the hits collecting now?")
                    .css({"font-size":"14px","text-align":"center"}).appendTo(infoArea);
                $("#JREditDialog").data({"creating":"created"});
            }
        }
        $(".ui-dialog-titlebar").hide();
        $("#JREditDialog").dialog("open");
    } else if ($("#JREditDialog").data("creating") == "created") {
        $("#JREditDialog").data({"theGrouping":theGrouping,"theDelayed":theDelayed});
        saveGroupingCreateData("Instantly Created #" + (gGroupingData["JR First"].theNumber + 1),"Grouping instantly made so no description");
        $("#JREditDialog").data("button",null);
        toggleButton(theButton,null,null);
        $("#JREditDialog").dialog("close");
		showGroupingDialog("view",$("#JREditDialog").data("button"));
    } else if (theGrouping.length>0) {
        formatDialog("JREditDialog",300,620,"Name your grouping to create it:",theButton,"groupingCreate",true);
        $("#JREditDialog").data({"theGrouping":theGrouping,"theDelayed":theDelayed});
		createDiv().attr("class","JRContents").appendTo($("#JREditDialog"));
        var groupingArea = createDiv().attr("class","groupingArea").css({"margin":"15px 15px"}).appendTo($("#JREditDialog .JRContents:first"));
        createDiv().html("").css({"margin":"15px 0 0 20px","font-size":"14px","color":"red","height":"30px"})
            .attr("class","groupingCreateError").appendTo(groupingArea);
        createDiv().html("Type in the name of this grouping:").css({"font-size":"15px"}).appendTo(groupingArea);
        createDiv().append(createTextInput("").attr("class","groupName").css({"width":"200px","margin":"5px 0 0 30px","height":"25px"})).appendTo(groupingArea);
        createDiv().html("Type in the description of this grouping:").css({"font-size":"15px","margin-top":"5px"}).appendTo(groupingArea);
        createDiv().append(createTextInput("").attr("class","groupDesc").css({"width":"350px","margin":"5px 0 0 30px","height":"25px"})).appendTo(groupingArea);
        var addGroupingButtonArea = createDiv().append(createSpanButton( function(e) {
            var theName = $("#JREditDialog").find(".groupName").val().toString();
            var theDescription = $("#JREditDialog").find(".groupDesc").val().toString();
            if (theName!=="") {
                if (saveGroupingCreateData(theName,theDescription)) {
                    $("#JREditDialog").data("button",null);
                    toggleButton(theButton,null,null);
                    $("#JREditDialog").dialog("close");
					showGroupingDialog("view",$("#JREditDialog").data("button"));
                } else {
                    $("#JREditDialog .groupingCreateError:first").html("Error: Found another grouping with this name. Type in a UNIQUE name.");
                }
            } else {
                $("#JREditDialog .groupingCreateError:first").html("Error: You must type in a unique grouping name.");
            }
        },"Create This Named Group",gButtonOffBgColor,gButtonOffColor,"12px"))
            .css({"margin":"10px 0 0 35px"}).appendTo(groupingArea);
        $("#JREditDialog").dialog("open");
    } else {
        var realCreating = $("#JREditDialog").data("creating");
        formatDialog("JREditDialog",106,600,"No groupings selected!",theButton,"groupingCreate",true);
        $("#JREditDialog").data("yesFunction",function() {
            $("#JREditDialog").dialog( "close"); showGroupingCreateDialog($("#JREditDialog").data("button"),[],[],$("#JREditDialog").data("creating"));
        });
        $("#JREditDialog").dialog("option", "position", { my: "center top", at: "center top", of: $("body") });
		createDiv().attr("class","JRContents").appendTo($("#JREditDialog"));
        infoArea.appendTo($("#JREditDialog .JRContents:first"));
        if (realCreating == "selection") {
            createDiv().html("You forgot to select hits for the group. Try again?").css({"font-size":"14px","text-align":"center"}).appendTo(infoArea);
            $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Yes')").show();
            $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('No')").show();
            $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Cancel')").hide();
        } else {
            createDiv().html("There are no hits currently being collected. Start one first.").css({"font-size":"14px","text-align":"center"}).appendTo(infoArea);
        }
        $(".ui-dialog-titlebar").hide();
        $("#JREditDialog").dialog("open");
    }
}
function refreshGroupingHitsDialog(theKey,groupingViewArea) {
    var theGrouping = gGroupings[theKey].data.grouping;
    var theDelayed = gGroupings[theKey].data.delayed;
    for (var i=0,len=theGrouping.length; i<len; i++) {
		var isDelayed = (theDelayed.indexOf(theGrouping[i]) != -1);
		var theBackgroundColorNow = (isDelayed) ? "#33CC66" : "#ADFF2F";
		var thisRequesterName = (gRequestersData[theGrouping[i]].friendlyRName !== "") ? gRequestersData[theGrouping[i]].friendlyRName :
			((gRequestersData[theGrouping[i]].	requesterName !== "") ? gRequestersData[theGrouping[i]].requesterName : gRequestersData[theGrouping[i]].groupId);
        createDiv().attr("class","groupingHitCell")
            .css({"border-color":"MidnightBlue", "border-width":"3px", "border-style":"groove", "margin":"2px 4px","width":"180px","height":"40px",
                "background-color":theBackgroundColorNow, "font-size":"10px", "overflow":"hidden", "float":"left", "white-space":"nowrap", "padding":"3px 3px"})
            .data({"theNumber":theGrouping[i],"removeMe":false,"delayed":isDelayed})
            .append(createDiv(thisRequesterName))
            .append(createDiv(gRequestersData[theGrouping[i]].pay))
            .append(createDiv(gRequestersData[theGrouping[i]].title).css({"font-size":"8px"}))
			.bind("contextmenu", function(e) {
				e.preventDefault();
				var thisCell = $(e.target).closest(".groupingHitCell");
                $("#JREditDialog").data("edited",true);
                $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Save')").show();
				if ($(thisCell).data("delayed")) $(thisCell).data("delayed",false);
				else { $(thisCell).data("delayed",true); $(thisCell).data("removeMe",false); }
                $(thisCell).css("background-color",($(thisCell).data("removeMe")) ? "#F08080" : ($(thisCell).data("delayed")) ? "#33CC66" : "#ADFF2F");
			})
            .click( function(e) {
				var thisCell = $(e.target).closest(".groupingHitCell");
                $("#JREditDialog").data("edited",true);
                $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Save')").show();
				$(thisCell).data({"delayed":false,"removeMe":!$(thisCell).data("removeMe")});
                $(thisCell).css("background-color",($(thisCell).data("removeMe")) ? "#F08080" : "#ADFF2F");
            }).appendTo(groupingViewArea);
    }
    $("<br clear='all' class='cleartab'>").appendTo(groupingViewArea);
}
function refreshGroupingsDialog(groupingViewArea) {
    var returnValue = {"noGrouping":false,"collecting":false};
    $(groupingViewArea).find(".groupingLine").each( function() {
        $(this).remove();
    });
    $.each(gGroupingsSort, function( index, theKey ) {
        var value = gGroupings[theKey];
        if (theKey != "JR First") {
			var addGroupingButtonArea = null;
            var theBackground = "#F1EDC2";
            if (value.collecting) { theBackground = "#66CD00"; returnValue.collecting = true; }
            if (!checkGroupings(value)) { theBackground = "#F08080"; returnValue.noGrouping = true; }
            if (value.data.grouping.length===0) { theBackground = "#F08080"; returnValue.noGrouping = true; }
            var groupingLine = createDiv()
                .css({"margin-top":"2px","background-color":theBackground,"padding":"2px 3px 2px 3px","height":"17px","border":"2px ridge black","cursor":"pointer"})
                .attr({"class":"groupingLine"}).data({"theKey":theKey,"theIndex":index})
                .click( function() {
                    if (value.data.grouping.length>0) {
                        value.collecting = !value.collecting;
                        for (var i=0,len=value.data.grouping.length; i<len; i++) {
                            if ($("#JRCollectB_" + value.data.grouping[i]).length) {
								var thisNumber = value.data.grouping[i];
                                if (value.collecting) {
									toggleButtonOn( $("#JRCollectB_" + thisNumber),startCollecting,stopCollecting);
									if (value.data.delayed.indexOf(thisNumber) != -1) toggleButton($("#JRHamB_" + thisNumber),hamOn,hamOff,"paused","off");
								}
                                else {
									toggleButtonOff( $("#JRCollectB_" + thisNumber),startCollecting,stopCollecting);
									toggleButtonOff( $("#JRHamB_" + thisNumber),hamOn,hamOff);
								}
                            } else console.log("bad button");
                        }
                        if (value.collecting) gGroupingsSort.splice(0, 0, gGroupingsSort.splice(index, 1)[0]);
                        refreshGroupingsDialog($("#JREditDialog .groupingViewArea"));
                    }
                }).appendTo(groupingViewArea);
            createSpan().html(theKey + " - " + value.data.description).appendTo(groupingLine);
            addGroupingButtonArea = createSpanButton( function(e) {
                e.stopPropagation();
				showYesNoDialog("Are you sure you want me to delete this job?<br>" + $(e.target).data("theKey"),function(thisKey,thisIndex) {
                    delete gGroupings[thisKey]; delete gGroupingData[thisKey];
                    gGroupingsSort.splice(thisIndex, 1);
                    saveSettings( function() { refreshGroupingsDialog($("#JREditDialog .groupingViewArea")); });
				}, $(e.target).data("theKey"), $(e.target).data("theIndex"));
            },"Del",gButtonOffBgColor,gButtonOffColor,"12px").data({"theKey":theKey,"theIndex":index})
                .css({"float":"right"}).appendTo(groupingLine);
            addGroupingButtonArea = createSpanButton( function(e) {
                e.stopPropagation();
				$("#JREditDialog").dialog( "close");
				showGroupingCreateDialog($("#JREditDialog").data("button"),[],[],"add",$(e.target).data("theKey"));
            },"Add",gButtonOffBgColor,gButtonOffColor,"12px").data({"theKey":theKey,"theIndex":index})
                .css({"float":"right"}).appendTo(groupingLine);
            addGroupingButtonArea = createSpanButton( function(e) {
                e.stopPropagation();
                var theKey = $(e.target).data("theKey");
                formatDialog("JREditDialog",600,815,"Groupings Edit: " + theKey,$("#JREditDialog").data("button"),"groupingHitsEdit",true);
                $("#JREditDialog").data({"nameKey":theKey,"NOCloseDialog":true});
                $("#JREditDialog").data("closeme",function() { showGroupingDialog("view",$("#JREditDialog").data("button")); });
				createDiv().attr("class","JRContents").appendTo($("#JREditDialog"));
				createDiv().html("Click on the jobs to toggle it from keeping or removing it. [Red = remove] [Bright Green = keep]<br>Right click to make it a delayed Ham mode which will have a dark green background.")
					.css({"font-size":"13px","text-align":"center"}).appendTo($("#JREditDialog .JRContents:first"));
				var editGroupArea = createDiv().attr("class","editGroupArea").css({"margin":"10px 15px"}).appendTo($("#JREditDialog .JRContents:first"));
				createDiv().html("Group Name: ").append(createSpan(theKey.toString())).css("margin-top","4px")
					.attr({"class":"editLine hasHelptip","id":"groupNameEdit"}).appendTo(editGroupArea)
					.click( function() { dataEdited($(this),theKey); })
					.append(createSpan().attr("class","errorEditLine").css({"color":"red","margin-left":"5px"}));
				createDiv().html("Group Description: ").append(createSpan(gGroupingData[theKey].description.toString())).css("margin-top","2px")
					.attr({"class":"editLine hasHelptip","id":"groupDescriptionEdit"}).appendTo(editGroupArea)
					.click( function() { dataEdited($(this),gGroupingData[theKey].description); });
                var groupingViewArea = createDiv().attr("class","groupingViewArea").css({"border":"1px solid grey","margin":"15px 1px","padding":"5px 1px"})
                    .appendTo($("#JREditDialog .JRContents:first"));
                refreshGroupingHitsDialog(theKey,groupingViewArea);
            },"Edit",gButtonOffBgColor,gButtonOffColor,"12px").data({"theKey":theKey,"theIndex":index})
                .css({"float":"right"}).appendTo(groupingLine);
        }
    });
    if (returnValue.collecting) $("#JREditDialog .JRCollectingInstr").html("Groupings which are collecting are in green color.");
    else $("#JREditDialog .JRCollectingInstr").html("");
    if (returnValue.noGrouping) $("#JREditDialog .JREmptyInstr").html("Groupings which have NO hits grouped are in red.");
    else $("#JREditDialog .JREmptyInstr").html("");
}
function showGroupingDialog(doThis,theButton) {
	var dialogHeight = ($(window).height() > 600) ? 600 : $(window).height()-60;
    formatDialog("JREditDialog",600,780,"Groupings List:",theButton,"grouping " + doThis,true);
    $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Cancel') span").html("Close");
	createDiv().attr("class","JRContents").appendTo($("#JREditDialog"));
    var infoArea = createDiv().attr("class","infoArea").css({"margin":"15px 15px","text-align":"center"}).appendTo($("#JREditDialog .JRContents:first"));
    createDiv().html("Click on the Grouping Name you want to start or stop.").css("font-size","14px").appendTo(infoArea);
    createDiv().html("").attr({"class":"JRCollectingInstr"}).css("font-size","14px").appendTo(infoArea);
    createDiv().html("").attr({"class":"JREmptyInstr"}).css("font-size","14px").appendTo(infoArea);
    var groupingViewArea = createDiv().attr("class","groupingViewArea").css({"border":"1px solid grey","margin":"15px 15px","padding":"5px 3px"})
        .appendTo($("#JREditDialog .JRContents:first"));
    refreshGroupingsDialog(groupingViewArea);
    $("#JREditDialog").dialog("open");
}
function showExportImportDialog(porting,theButton) {
    formatDialog("JREditDialog",200,300,porting + " data",theButton,"export and importing",true);
	createDiv().attr("class","JRContents").appendTo($("#JREditDialog"));
    var exportImportArea = createDiv().attr("class","exportImportArea").css("margin","15px 15px").appendTo($("#JREditDialog .JRContents:first"));
    if (porting=="Export") {
        createDiv().append(createCheckbox().attr("class","exportAlarms").prop('checked', false).css("margin-left","25px"))
			.append(createSpan("Export Alarm Sounds Too.")).appendTo(exportImportArea);
        createDiv().css({"margin-top":"15px"}).append(createSpanButton( function(e) { checkDelayedSave();
            var theButton = $("#JREditDialog").data("button");
            $("#JREditDialog").data("button",null);
            toggleButton(theButton,null,null);
            $("#JREditDialog").dialog("close");
			var exportAlarms = $("#JREditDialog .exportAlarms:first").prop('checked');
            exportJobs(exportAlarms);
        },"Export to File",gButtonOffBgColor,gButtonOffColor,"12px")).appendTo(exportImportArea);
    } else {
        createDiv().css({"margin":"5px 0 10px 0"}).append($("<input>").attr({"type":"file","id":"importFileInput"})
            .change( function(event) { $("#importFromFileButton").data("disabled",false).css({"background-color":gButtonOffBgColor}); } )).appendTo(exportImportArea);
        createSpanButton( function(e) { checkDelayedSave();
                if ( !$(e.target).data("disabled") ) importJobs( $("#importFileInput").prop("files")[0] );
                var theButton = $("#JREditDialog").data("button");
                $("#JREditDialog").data("button",null);
                toggleButton(theButton,null,null);
                $("#JREditDialog").dialog("close");
            },"Import From File",gButtonDisabledBgColor,gButtonOffColor,"12px").appendTo(exportImportArea)
            .attr({"id":"importFromFileButton"})
            .data("disabled",true);
    }
    $("#JREditDialog").dialog("open");
}
function searchingFilter(filterOn,index) {
	if (index=="0") return false;
	if (filterOn=="collecting") return (gMainData.hitCollection[parseInt(index)].collecting=="on");
	if (filterOn=="notcollecting") return (gMainData.hitCollection[parseInt(index)].collecting=="off");
	if (filterOn=="search") return (gMainData.hitCollection[parseInt(index)].data.action.substring(0,6)=="search");
	return true;
}
function doSearchNow() {
	var searchWhere = $("#searchingInput").data("searchingFor");
	var searchArea = (searchWhere=="mturk") ? $("#JRSavedMturkArea") : $("#JRSavedJobsArea");
	$(searchArea).find(".searchingResultsArea").html("");
	$(searchArea).find(".searchingResultsArea").append(createDiv("Searching now. Wait Please......").css({"font-size":"25px","margin-top":"200px","text-align":"center"}));
	$("#JREditDialog").data("savedSearch_" + searchWhere,$("#searchingInput").val());
	if (searchWhere=="mturk") {
		var sortingBy = $("#searchControlArea input[name='sortingOn']:checked").val();
		var sortingByText = (sortingBy == "highestNumber") ? "&sortType=NumHITs%3A1" : (sortingBy == "highestAmount") ? "&sortType=Reward%3A1" : "&sortType=LastUpdatedTime%3A1";
		theCycler.addJob( function( elapsed, theNumber ) {
			var theUrl = "https://www.mturk.com/mturk/searchbar?selectedSearchType=hitgroups&searchWords=" + $("#searchingInput").val() +
			"&minReward=0.00&qualifiedFor=on&x=7&y=7&pageSize=50" + sortingByText;
			requestUrl(theUrl,-54,parseHitSearchPage, errorRequest, searchWhere);
			return true;
		}, -54, 0, true);
		theCycler.frontOfTheLine(-54);
	} else {
		var searchingJob = $("#searchControlArea input[name='searchingJob']:checked").val();
		$(searchArea).find(".searchingResultsArea").html("");
		var captions = {"requesterName":"Requester Name","title":"Hit Title","duration":"Time","pay":"Pay","keyno1":"","keyno2":"","keyno3":"","jobNumber":"-1","friendlyRName":"","friendlyTitle":""};
		var dialogWidth = $("#JREditDialog").width();
		$(searchArea).find(".searchingResultsArea").append(createHitRow(captions,false,searchWhere));
		$(searchArea).find(".searchingResultsArea").append(createDiv()
			.css({"margin-left":"20px","margin-top":"0px","background-color":"black","height":"6px","width":(dialogWidth - 245) + "px"}));
		$.each(gRequestersData, function( index, value ) {
			if (searchingFilter(searchingJob,index)) {
				var searchValue = ($("#searchingInput").val()).toLowerCase();
				var fullSearchString = value.requesterName + " , " + value.title + " , " + value.friendlyRName + " , " + value.friendlyTitle;
				if ( (searchValue==="") || (fullSearchString.toLowerCase().indexOf(searchValue) != -1) ) {
					var jobData = jQuery.extend(true, {}, jobDataDefault);
					jobData.requesterName = value.requesterName; jobData.requesterId = value.requesterId; jobData.groupId = value.groupId;
					jobData.friendlyRName = value.friendlyRName; jobData.friendlyTitle = value.friendlyTitle; jobData.pay = value.pay;
					jobData.pay = value.pay; jobData.duration = value.duration; jobData.title = value.title; jobData.jobNumber=index;
					$(searchArea).find(".searchingResultsArea").append(createHitRow(jobData,false,searchWhere));
				}
			}
		});
		gSavedSearchArea = $(searchArea).find(".searchingResultsArea").html();
	}
}
function removeJob(thisNumber) {
	if (thisNumber>0) {
		$("#JRCellNum_" + thisNumber).remove();
		stopCollecting(thisNumber);
		var thePositions = gTabsData[gMainData.hitCollection[thisNumber].tabIndex].positions;
		delete gMainData.hitCollection[thisNumber];
		delete gRequestersData[thisNumber];
		var theIndex = thePositions.indexOf(thisNumber);
		if ( theIndex > -1) thePositions.splice(theIndex, 1);
		saveSettings();
		return true;
	}
	return false;
}
function searchMturk(theArea,savedSearch) {
    createDiv().html("Type in a search word: ").css({"font-size":"15px","text-align":"left"})
		.append(createTextInput(savedSearch).attr("id","searchingInput").css({"width":"400px","margin-left":"10px","line-height":"17px"}).data("searchingFor","mturk")
		.keypress( function(e) { if ( e.which == 13 ) { doSearchNow(); } }))
		.append(createSpanButton( function(e) { doSearchNow(); },"Search",gButtonOffBgColor,gButtonOffColor,"12px")).appendTo(theArea);
	createDiv().append(createRadioButton("sortingOn","newest").attr("checked",true).css({"margin-left":"200px"})).append(createSpan("Newest"))
		.append(createRadioButton("sortingOn","highestAmount").css({"margin-left":"20px"})).append(createSpan("Highest Amount"))
		.append(createRadioButton("sortingOn","highestNumber").css({"margin-left":"20px"})).append(createSpan("Highest Number")).appendTo(theArea);
}
function searchJobs(theArea,savedSearch,theDefault) {
	createDiv().append(createRadioButton("searchingJob","all").attr("checked",(theDefault=="all" ? true : false)).css({"margin-left":"200px"})
		.click( function() { $("#searchingInput").focus(); } )).append(createSpan("All Jobs"))
		.append(createRadioButton("searchingJob","collecting").attr("checked",(theDefault=="collecting" ? true : false)).css({"margin-left":"20px"})
		.click( function() { $("#searchingInput").focus(); } )).append(createSpan("Collecting"))
		.append(createRadioButton("searchingJob","notcollecting").attr("checked",(theDefault=="notcollecting" ? true : false)).css({"margin-left":"20px"})
		.click( function() { $("#searchingInput").focus(); } )).append(createSpan("Not Collecting"))
		.append(createRadioButton("searchingJob","search").attr("checked",(theDefault=="search" ? true : false)).css({"margin-left":"20px"})
		.click( function() { $("#searchingInput").focus(); } )).append(createSpan("Searching Mode")).appendTo(theArea);
    createDiv().html("Type in a search word: ").css({"font-size":"15px","text-align":"left"})
		.append(createTextInput(savedSearch).attr("id","searchingInput").css({"width":"400px","margin-left":"10px","line-height":"17px"}).data("searchingFor","jobs")
		.keypress( function(e) { if ( e.which == 13 ) { doSearchNow(); } }))
		.append(createSpanButton( function(e) { doSearchNow(); },"Search",gButtonOffBgColor,gButtonOffColor,"12px"))
		.append(createSpanButton( function(e) {
			showYesNoDialog("Are you sure you want me to delete the selected jobs?",function() {
				$("#JRSavedJobsArea input").each( function(i,theCheckbox) {
					if ($(theCheckbox).prop("checked")) { if (removeJob(($(theCheckbox).data("hitData")).jobNumber)) $(theCheckbox).closest(".hitRow").remove(); }
				});
			});
		},"Delete Selected",gButtonOffBgColor,gButtonOffColor,"12px")).appendTo(theArea);
}
function showSearchingDialog(theButton,searchFor,theDefault,autoStart) {
	var dialogHeight = ($(window).height() > 700) ? 700 : $(window).height()-60;
	var dialogWidth = ($(window).width() > 1200) ? 1200 : $(window).width()-80;
	theDefault = theDefault || "all"; autoStart = autoStart || false;
    formatDialog("JREditDialog",dialogHeight,dialogWidth,"Search through your pandas or through mturk!",theButton,"searching",true);
	$("#JREditDialog").data("savedButton",theButton);
	var theSavedArea = (searchFor=="mturk") ? $("#JRSavedMturkArea") : $("#JRSavedJobsArea");
	$(theSavedArea).show();
	var savedSearch = ($("#JREditDialog").data("savedSearch_" + searchFor)) ? $("#JREditDialog").data("savedSearch_" + searchFor) : "";
    $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Cancel') span").html("Close");
	createDiv().attr("class","JRContents").prependTo($("#JREditDialog"));
    var searchControlArea = createDiv().attr("id","searchControlArea").css({"margin":"8px 15px"}).appendTo($("#JREditDialog .JRContents:first"));
	if (searchFor=="mturk") searchMturk(searchControlArea,savedSearch);
	else searchJobs(searchControlArea,savedSearch,theDefault);
	var searchingResultsHeight = $("#JREditDialog").height() - 65;
	if (!$(theSavedArea).find(".searchingResultsArea").length) createDiv().attr("class","searchingResultsArea")
		.css({"margin":"10px 2px 0 2px","overflow":"auto","height":searchingResultsHeight}).html("").appendTo($(theSavedArea));
	$("#JREditDialog").on( "dialogresizestop", function( event, ui ) { $(theSavedArea).find(".searchingResultsArea").css({"height":$("#JREditDialog").height() - 65}); } );
	$("#JREditDialog").data("closeme",function() { $("#JREditDialog").off( "dialogresizestop", "**" ); });
    $("#JREditDialog").dialog("open");
	$("#searchingInput").focus();
	$("#searchingInput").select();
	if (autoStart) doSearchNow();
	$('.ui-widget-overlay').bind('click',function() { releaseButton($('#JREditDialog')); $('#JREditDialog').dialog('close'); });
}
function showAddJobsDialog(theButton) {
    formatDialog("JREditDialog",250,600,"Add a new PANDA!",theButton,"add job",true);
	createDiv().attr("class","JRContents").appendTo($("#JREditDialog"));
    var addJobArea = createDiv().attr("class","addJobArea").css("margin","15px 15px").appendTo($("#JREditDialog .JRContents:first"));
    createDiv().html("Below enter the preview or the previewandaccept url.<br>You may enter just the groupID number too or a NS4T.net url.<br>")
        .append(createTextInput("").attr("class","groupIdInput").css({"width":"400px","margin-top":"10px","margin-left":"30px"})
            .keypress(function(e) {
                if(e.which == 13) $("#JREditDialog .JRAddPanda:first span").click();
            }))
        .append(createDiv()
            .append(createCheckbox().attr("class","collectNow").prop('checked', true).css("margin-left","70px")).append(createSpan("Start Collecting"))
            .append(createCheckbox().attr("class","onlyOnce").css("margin-left","20px")).append(createSpan("Collect only once"))).appendTo(addJobArea);
    var addGroupIDButtonArea = createDiv().append(createSpanButton( function(e) {
        var theValue = $("#JREditDialog .groupIdInput:first").val();
        var collectNow = $("#JREditDialog .collectNow:first").prop('checked');
        var onlyOnce = $("#JREditDialog .onlyOnce:first").prop('checked');
        $("#JREditDialog .groupIDError").html("");
        var parsedGroupID = "";
        if (theValue==="") { $("#JREditDialog .groupIDError").html("Please Enter a url or GroupID first."); }
        else if (theValue.indexOf("groupId=")!=-1) {
            parsedGroupID = theValue.split("groupId=")[1];
            if (parsedGroupID.indexOf("&")!=-1) parsedGroupID = parsedGroupID.split("&")[0];
        } else if (theValue.indexOf("ns4t.net/")!=-1) {
			gSavedAddUrl = theValue;
			$("#JREditDialog *").prop('disabled',true);
			theCycler.addJob( function( elapsed, theNumber ) {
				requestUrl(gSavedAddUrl,-99,function(theResult,theNumber) {
					var theFinalUrl = theResult.finalUrl;
					if (theFinalUrl.indexOf("groupId=")!=-1) {
						parsedGroupID = theFinalUrl.split("groupId=")[1];
						if (parsedGroupID.indexOf("&")!=-1) parsedGroupID = parsedGroupID.split("&")[0];
						fillNewHitData("", "", parsedGroupID, "0.00", parsedGroupID, "", onlyOnce, false, collectNow);
						var theButton = $("#JREditDialog").data("button");
						toggleButton(theButton,null,null);
						$("#JREditDialog").dialog("close");
					} else {
						$("#JREditDialog *").prop('disabled',false);
						$("#JREditDialog .groupIDError").html("ERROR: Please Enter a url or GroupID first.");
					}
				}, errorRequest);
				return true;
			}, -99, 0, true);
			theCycler.frontOfTheLine(-99);
        } else if (theValue.indexOf(" ")==-1) {
            parsedGroupID = theValue;
        } else { $("#JREditDialog .groupIDError").html("ERROR: Please Enter a url or GroupID first."); }
        if (parsedGroupID!=="") {
			fillNewHitData("", "", parsedGroupID, "0.00", parsedGroupID, "", onlyOnce, false, collectNow);
            var theButton = $("#JREditDialog").data("button");
            toggleButton(theButton,null,null);
            $("#JREditDialog").dialog("close");
        }
    },"Add Panda for Group ID hit",gButtonOffBgColor,gButtonOffColor,"12px")).attr("class","JRAddPanda")
        .css({"margin":"6px 0 0 35px"}).appendTo(addJobArea);
    createSpan("").attr("class","groupIDError").css({"color":"red","margin-left":"10px"}).appendTo(addGroupIDButtonArea);
    $("#JREditDialog").dialog("open");
}
function alarmReaderEditor(fileInput) {
    $("#JREditDialog").data("edited",true);
    $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Save')").show();
    if (fileInput.prop("files")[0].size > 6000000) return -1;
    var reader = new FileReader();
    reader.onload = function() {
        var readerContents = reader.result;
        var base64Audio = btoa(readerContents);
        var newAudio = new Audio("data:audio/wav;base64," + base64Audio);
        playNewSound( newAudio );
        fileInput.data("base64",base64Audio);
        fileInput.data("audio",newAudio);
    };
    reader.readAsBinaryString(fileInput.prop("files")[0]);
    reader.onerror = function() {
        alert('Unable to read ' + file.fileName);
		return -2;
    };
	return 1;
}
function showAlarmsDialog( theNumber, theButton ) {
	var dialogHeight = ($(window).height() > 700) ? 700 : $(window).height()-60;
    formatDialog("JREditDialog",dialogHeight,740,"Edit your alarms according to what you like:",theButton,"alarms",true);
    $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Cancel')").show();
    $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Cancel') span").html("Close");
	createDiv().attr("class","JRContents").appendTo($("#JREditDialog"));
    var alarmsIntroArea = createDiv().attr("class","alarmsIntroArea").css({"margin":"15px 15px"}).appendTo($("#JREditDialog .JRContents:first"));
    createDiv().html("Alarms must be less than 6MB. I recommend the alarms to be less than 10 seconds.<br>There is no limit to the length because the script doesn't check that.")
        .css({"font-size":"15px","text-align":"center","margin":"6px 15px"})
		.append(createSpan("<br>Due to browser security features, alarms may have not been loaded.<br>").css({"color":"red"})
			.append(createSpan("Click here for some help to load in the default alarms!").css({"cursor":"pointer"}).click( function() {
				$(".alarmsArea:first").css({"display":"none"});
				$(".alarmsHelpArea:first").css({"display":"block"});
			} )))
		.appendTo(alarmsIntroArea);
    var alarmsArea = createDiv().attr("class","alarmsArea").css({"margin":"4px"}).appendTo($("#JREditDialog .JRContents:first"));
    var statusArea = createDiv("Status: ").attr("id","alarmStatusArea").css({"margin":"10px 15px"}).appendTo(alarmsArea);
    $.each(gAlarmSounds, function( index, value ) {
        var importFileID = "importFileInput-" + index;
		var soundDescription = value.desc.split("|");
		var addAppend = createSpan(soundDescription[0]).css({"font-size":"12px","font-weight":"normal"});
		if (soundDescription.length>1 && value.payRate!=="") addAppend = addAppend.append(createSpanButton(function(e) {
				showPromptDialog("Enter the pay rate this alarm will sound when the pay rate is less than this:",
					$(e.target).html().replace("$",""),$("#JREditDialog").data("theButton"),function(theValue) {
						gAlarmSounds[$(e.target).data("theIndex")].payRate = theValue;
						$(e.target).html("$" + theValue);
						$("#JRPromptDialog").dialog("close");
						changeToEdited();
				});
			},"$" + value.payRate,"ivory","black","11px").data("theIndex",index).css({"font-weight":"normal"}))
			.append(createSpan(soundDescription[1]).css({"font-size":"12px","font-weight":"normal"}));
		if (soundDescription.length>2) addAppend = addAppend.append(createSpanButton(function(e) {
				showPromptDialog("Enter the minutes that this alarm will sound if the duration is less than this:",
					$(e.target).html().replace("$",""),$("#JREditDialog").data("theButton"),function(theValue) {
						gAlarmSounds[$(e.target).data("theIndex")].lessMinutes = theValue;
						$(e.target).html(theValue);
						$("#JRPromptDialog").dialog("close");
						changeToEdited();
				});
			},value.lessMinutes,"ivory","black","11px").data("theIndex",index).css({"font-weight":"normal"}))
			.append(createSpan(soundDescription[2]).css({"font-weight":"normal"}));
        createDiv().attr("class","alarmInputEdits").css({"margin-top":"8px"})
            .append(createDiv().append(createSpanButton(function(e) { playNewSound($("#" + importFileID).data("audio")); },
                    "- Play -","ivory","black","11px").css({"margin-right":"6px"}))
				.append(createSpanButton(function(e) { $(e.target).closest(".alarmInputEdits").find(".JRChangingArea:first").css({"display":"block"}); },"Change","ivory","black","11px")
				.css({"margin-right":"12px"}))
                .append(addAppend))
            .append(createDiv().attr({"class":"JRChangingArea"}).html("Change to: ").css({"display":"none"})
				.append($("<input>").attr({"type":"file","id":importFileID,"accept":"audio/*"})
				.data({"audio":value.audio,"base64":null})
                .change( function() {
					var returnValue = alarmReaderEditor($(this));
					if ( returnValue > 0 ) $("#alarmStatusArea").html("Status: Audio File Loaded.").css("color","green");
					else if ( returnValue == -1 ) $("#alarmStatusArea").html("Status: Audio File was way too big. File must be less than 6MB").css("color","red");
					else $("#alarmStatusArea").html("Status: Audio File was not loaded. Are you sure it was an audio file?").css({"font-size":"12px","color":"green"});
				})).css({"font-size":"11px","margin":"5px 0 0 40px"})).appendTo(alarmsArea);
    });
    var alarmsHelpArea = createDiv().attr("class","alarmsHelpArea").css({"margin":"30px 4px 0 4px","display":"none","text-indent":"50px"}).appendTo($("#JREditDialog .JRContents:first"));
	createDiv("Some browsers may stop connecting to other domains when trying to load up the alarms. This will cause the alarms to not load and not play at all. It should have at least ask you to allow @connect connections. You can try to look for any security features in tampermoney or greasemonkey which handles the @connect mode. if this still doesn't work then you can save each alarm below and then load each in the alarm change page. The following default sounds are used below:").css({"font-size":"15px"}).appendTo(alarmsHelpArea);
	var theULArea = createDiv($("<ul>").attr({"id":"alarmHelpUL"})).appendTo(alarmsHelpArea);
    $.each(gAlarmSounds, function( index, value ) {
		var soundDescription = value.desc.split("|");
		var theDescription = soundDescription[0];
		if (soundDescription.length>1) theDescription = theDescription + "$" + value.payRate;
		if (soundDescription.length>2) theDescription = theDescription + soundDescription[1] + value.lessMinutes + soundDescription[2];
		$("<li>").append(createLink(value.default,value.default,"_blank",value.desc))
			.append(createSpan(" - " + theDescription)).appendTo($("#alarmHelpUL"));
    });
	createDiv(createSpanButton( function() {
		$(".alarmsArea:first").css({"display":"block"});
		$(".alarmsHelpArea:first").css({"display":"none"});
	},"Click to go back to alarm options page","ivory","black","15px")).css({"text-align":"center","margin-top":"30px"}).appendTo(alarmsHelpArea);
    $("#JREditDialog").dialog("open");
}
function limitValues(theValue,min,max) {
	if (theValue>=min && theValue<=max) return true; else {
		showWaitDialog("Value must be between " + min + "ms and " + max + "ms","",function() {},null,
			createDiv("Sorry. You can't go under " + min + "ms and can't go over " + max + "ms.")
				.css({"font-size":"18px","text-align":"center","margin":"20px 10px","line-height":"22px"}),false,180,400);
		return false;
	}
}
function showEditOptionsDialog( theNumber, theButton ) {
	var dialogHeight = ($(window).height() > 640) ? 640 : $(window).height()-60;
    formatDialog("JREditDialog",dialogHeight,650,"Change options:",theButton,"options",true);
	createDiv().attr("class","JRContents").appendTo($("#JREditDialog"));
    var optionsArea = createDiv().attr("class","optionsArea").css({"margin":"15px 15px"}).appendTo($("#JREditDialog .JRContents:first"));
    createDiv().html("Click on the options you would like to change below:")
        .css({"font-size":"15px","text-align":"center"}).appendTo(optionsArea);
    createDiv().html("Show Help Tooltips: ").css("margin-top","30px").append(createSpan( gMainOptions.showHelpTooltips.toString() ).css("font-weight","bolder"))
        .attr({"class":"editLine hasHelptip","id":"showHelpTooltipsEdit","title":"Show help tootips on all buttons, tabs or editable options? Sometimes these helpful tips can get in the way especially if you already know how everything works."}).appendTo(optionsArea)
        .click( function() { gMainOptions.showHelpTooltips=dataTrueFalse($(this),gMainOptions.showHelpTooltips); });
    createDiv().html("Disable Captcha Alert: ").css("margin-top","5px").append(createSpan( gMainOptions.disableCaptchaAlert.toString() ).css("font-weight","bolder"))
        .attr({"class":"editLine hasHelptip","id":"disableCaptchaAlertEdit","title":"Disable the captcha alert and let another script deal with it."}).appendTo(optionsArea)
        .click( function() { gMainOptions.disableCaptchaAlert=dataTrueFalse($(this),gMainOptions.disableCaptchaAlert); });
    createDiv().html("Disable Queue Watch Alert: ").css("margin-top","5px").append(createSpan( gMainOptions.disableQueueAlert.toString() ).css("font-weight","bolder"))
        .attr({"class":"editLine hasHelptip","id":"disableQueueAlertEdit","title":"Disable the queue alert that will sound when a hit is lower than a specified time."}).appendTo(optionsArea)
        .click( function() { gMainOptions.disableQueueAlert=dataTrueFalse($(this),gMainOptions.disableQueueAlert); });
    createDiv().html("Disable Desktop Notifications: ").css("margin-top","5px").append(createSpan( gMainOptions.disableNotifications.toString() ).css("font-weight","bolder"))
        .attr({"class":"editLine hasHelptip","id":"disableNotificationsEdit","title":"Disable the Desktop notification that you get when accepting panda's"}).appendTo(optionsArea)
        .click( function() { gMainOptions.disableNotifications=dataTrueFalse($(this),gMainOptions.disableNotifications); });
    createDiv().html("Debugger Level: ").css("margin-top","5px").append(dataIncDecNumber(gMainOptions.debugger,5)).data("dataKey","debugger")
        .attr({"class":"editLine cantEdit isInt hasHelptip","id":"debuggerEdit","title":"Enter in the level to show debugging logs in the console log of your browser for testing purposes."}).appendTo(optionsArea);
	$(".editLine").tooltip({ show: {delay:1000} });
	helpToolTips();
    $("#JREditDialog").dialog("open");
}
function showEditTimersDialog( theNumber, theButton ) {
	var dialogHeight = ($(window).height() > 640) ? 640 : $(window).height()-60;
    formatDialog("JREditDialog",dialogHeight,650,"Edit this hit:",theButton,"timers",true);
	createDiv().attr("class","JRContents").appendTo($("#JREditDialog"));
    var timersArea = createDiv().attr("class","timersArea").css({"margin":"15px 15px"}).appendTo($("#JREditDialog .JRContents:first"));
    createDiv().html("All the timers are measured in Milliseconds except for one.<br>1000 Milliseconds is equal to 1 second.<br>Click on numbers to edit.")
        .css({"font-size":"15px","text-align":"center"}).appendTo(timersArea);
    createDiv().appendTo(timersArea).css("margin-top","20px").append(createSpan("Cycle Timer1: ").append(createSpan(gMainOptions.cycleNumber.toString())).data("dataKey","cycleNumber")
        .attr({"class":"editLine isInt hasHelptip","id":"cycleNumberEdit","title":"This is the number of milliseconds for the script to wait until it checks on the next job. By default 980 should be fast enough to grab hits fast. Limits are: 500ms to 6000ms."})
		.data("dataCheck",function(target) { return limitValues(parseInt($(target).val()),500,8000); } ));
    createDiv().appendTo(timersArea).append(createSpan("Cycle Timer2: ").append(createSpan(gMainOptions.cycleNumber2.toString())).data("dataKey","cycleNumber2")
        .attr({"class":"editLine isInt hasHelptip","id":"cycleNumber2Edit","title":"Second cycle timer to use so you can run other scripts at same time. Limits are: 900ms to 7000ms."})
		.data("dataCheck",function(target) { return limitValues(parseInt($(target).val()),500,8000); } ));
    createDiv().appendTo(timersArea).append(createSpan("Cycle Timer3: ").append(createSpan(gMainOptions.cycleNumber3.toString())).data("dataKey","cycleNumber3")
        .attr({"class":"editLine isInt hasHelptip","id":"cycleNumber3Edit","title":"Third cycle timer to use so you can run other scripts at same time. Limits are: 1200ms to 8000ms."})
		.data("dataCheck",function(target) { return limitValues(parseInt($(target).val()),500,8000); } ));
    createDiv().appendTo(timersArea).append(createSpan("GoHam Cycle Timer: ").append(createSpan(gMainOptions.HamCycleNumber.toString())).data("dataKey","HamCycleNumber")
        .attr({"class":"editLine isInt hasHelptip","id":"HamCycleNumberEdit","title":"This is the number of milliseconds for the script to wait until it checks on the next job when in HAM mode. Limits are: 500ms to 1500ms."})
		.data("dataCheck",function(target) { return limitValues(parseInt($(target).val()),500,1500); } ));
    createDiv().appendTo(timersArea).append(createSpan("Default GoHam Delay Timer (seconds): ").append(createSpan(gMainOptions.hamDelayTimer.toString())).data("dataKey","hamDelayTimer")
        .attr({"class":"editLine isInt hasHelptip","id":"hamDelayTimerEdit","title":"When you change a job mode from normal to Delayed Ham Mode by click and holding the Ham button then this is the time the script will change back to Normal mode when it receives no more hits in Ham Mode. This time in seconds will be used for any NEW jobs. Limits are: 10s to 60s."})
		.data("dataCheck",function(target) { return limitValues(parseInt($(target).val()),10,60); } ));
    createDiv().appendTo(timersArea).append(createSpan("Check Queue Timer Every: ").append(createSpan(gMainOptions.queueTimer.toString())).data("dataKey","queueTimer")
        .attr({"class":"editLine isInt hasHelptip","id":"queueTimerEdit","title":"This is the time you want the script to check your mturk queue. A minute seems fine because it only uses it when you have a limit on a job. If this timer is too low then it can make collecting pandas slower. Limits are: 20000ms to 120000ms."})
		.data("dataCheck",function(target) { return limitValues(parseInt($(target).val()),20000,120000); } ));
    var AdvancedArea = createDiv().attr("class","advancedArea").css({"border":"1px solid grey","margin":"20px 0 0 0","padding":"5px 3px"}).appendTo(timersArea);
    createDiv().html("Advanced Options:").css({"font-size":"15px","text-align":"center"}).appendTo(AdvancedArea);
    createDiv().appendTo(AdvancedArea).css("margin-top","15px").append(createSpan("Cycle Increase Button: ").append(createSpan(gMainOptions.cycleIncrease.toString())).data("dataKey","cycleIncrease")
        .attr({"class":"editLine isInt hasHelptip","id":"cycleIncreaseEdit","title":"The number of milliseconds to add to the cycle when pressing the increase button in the cycler menu. Limits are: 5ms to 100ms."})
		.data("dataCheck",function(target) { return limitValues(parseInt($(target).val()),5,100); } ));
    createDiv().appendTo(AdvancedArea).append(createSpan("Cycle Decrease Button: ").append(createSpan(gMainOptions.cycleDecrease.toString())).data("dataKey","cycleDecrease")
        .attr({"class":"editLine isInt hasHelptip","id":"cycleDecreaseEdit","title":"The number of milliseconds to subtract from the cycle when pressing the decrease button in the cycler menu. Limits are: 5ms to 100ms."})
		.data("dataCheck",function(target) { return limitValues(parseInt($(target).val()),5,100); } ));
    createDiv().appendTo(AdvancedArea).append(createSpan("Cycle Add Time Button: ").append(createSpan(gMainOptions.cycleAdding.toString())).data("dataKey","cycleAdding")
        .attr({"class":"editLine isInt hasHelptip","id":"cycleAddingEdit","title":"The number of milliseconds to add to the cycle when pressing the add to button in the cycler menu. This is for a fast slow down instead of pressing the increase button a lot of times. Limits are: 200ms to 1100ms."})
		.data("dataCheck",function(target) { return limitValues(parseInt($(target).val()),200,1100); } ));
    createDiv().appendTo(AdvancedArea).append(createSpan("Cycle Auto Slowdown Increase: ").append(createSpan(gMainOptions.cycleAutoIncrease.toString())).data("dataKey","cycleAutoIncrease")
        .attr({"class":"editLine isInt hasHelptip","id":"cycleAutoIncreaseEdit","title":"The number of milliseconds to add to the cycle when it has received an exceed error from mturk. Don't want it to slow down too quick so a small number here should be fine. Limits are: 5ms to 100ms."})
		.data("dataCheck",function(target) { return limitValues(parseInt($(target).val()),5,100); } ));
	$(".editLine").tooltip({ show: {delay:1000} }).click(function() {
		dataEdited($(this),gMainOptions[$(this).data("dataKey")]);
	});
	//$(".editLine").after(createSpanButton(function() {},"D",gButtonOffBgColor,gButtonOffColor,"9px").attr("class","defaultEdit").css({"margin-left":"5px"}));
	helpToolTips();
    $("#JREditDialog").dialog("open");
}
function showEditHitDialog( theNumber, theButton, closeFunction ) {
	var dialogHeight = ($(window).height() > 680) ? 680 : $(window).height()-60;
    formatDialog("JREditDialog",dialogHeight,650,"Edit this hit:",theButton,"job",true);
    $("#JREditDialog").data({"theNumber":theNumber,"closeme":closeFunction});
	if (closeFunction) $("#JREditDialog").data("NOCloseDialog",true);
    var hitInfo = gMainData.hitCollection[theNumber];
    var hitData = hitInfo.data;
	createDiv().attr("class","JRContents").appendTo($("#JREditDialog"));
    var requesterArea = createDiv().attr("class","requesterArea").css("margin","15px 8px").appendTo($("#JREditDialog .JRContents:first"));
    createDiv().html("Details of hit. All can be edited except for details in red.<br>Click on details to edit.")
        .css({"font-size":"15px","text-align":"center"}).appendTo(requesterArea);
    createDiv().appendTo(requesterArea).css({"margin-top":"10px"}).append(createSpan("Queue Hit Limit: ").append(dataIncDecNumber(hitData.queueHitLimit,26)).data("dataKey","queueHitLimit")
        .attr({"class":"editLine cantEdit isInt hasHelptip","id":"queueHitLimitEdit","title":"Enter the number of this hit in your queue. Once it has collected this amount of hits in the queue it will stop grabbing hits from this job. It will start grabbing more hits when there is less than this amount. Good for hits that have a limit or a short timer so it won't fill your queue with too many."}));
    createDiv().appendTo(requesterArea).append(createSpan("Queue # Limit: ").append(dataIncDecNumber(hitData.queueLimit,26)).data("dataKey","queueLimit")
        .attr({"class":"editLine cantEdit isInt hasHelptip","id":"queueLimitEdit","title":"Enter the limit of the number of any hits in your queue. It will stop collecting these hits until your queue is less than this number. Doesn't matter what hits are in the queue. It only looks at the total number of the queue. Good when you don't want your queue to be filled."}));
    createDiv().appendTo(requesterArea).append(createSpan("Daily Limit: ").append(dataIncDecNumber(hitData.dailyLimit,3600)).data("dataKey","dailyLimit")
        .attr({"class":"editLine cantEdit isInt hasHelptip","id":"dailyLimitEdit","title":"Enter the number to limit this hit for collection per day. Once it collects this amount of hits from this panda it will stop until the next day. (Not Implemented yet)"}));
    createDiv().appendTo(requesterArea).append(createSpan("Hit Weight: ").append(dataIncDecNumber(hitData.weight,10000)).data("dataKey","weight")
        .attr({"class":"editLine cantEdit isInt hasHelptip","id":"weightEdit","title":"Weight for this hit. If weight is more than 0 than it will skip this number of cycles before it checks."}));
    createDiv().appendTo(requesterArea).append(createSpan("Ham Timer (seconds): ").append(createSpan( hitData.hamTimer.toString() )).data("dataKey","hamTimer")
        .attr({"class":"editLine isInt hasHelptip","id":"hamTimerEdit","title":"Enter the number of seconds this hit should be on Ham after a delayed ham reaction. This only works when you put the ham button in the delayed ham status. When a panda is found it will instantly start hamming this hit at the global ham timer. When it stops seeing any more hits it will wait this amount of seconds to turn off Ham and go back into delayed Ham status."})
		.data("dataCheck",function(target) { return limitValues(parseInt($(target).val()),10,60); } ));
    createDiv().appendTo(requesterArea).append(createSpan("Once: ").append(createSpan( hitData.once.toString() )).data("dataKey","once")
        .attr({"class":"editLine cantEdit hasHelptip","id":"onceEdit","title":"If this is true then it will only collect one hit and then it will stop. You can start it again and it will collect one again. This is very useful for surveys."}).click( function() { hitData.once=dataTrueFalse($(this),hitData.once); }));
    createDiv().appendTo(requesterArea).append(createSpan("Friendly Requester Name: ").append(createSpan(hitData.friendlyRName)).data("dataKey","friendlyRName")
        .attr({"class":"editLine hasHelptip","id":"friendlyRNameEdit","title":"Enter a friendly name for this requester. This name will show on the hit cell instead of the original name. Enter a blank name to show the original name."}));
    createDiv().appendTo(requesterArea).append(createSpan("Friendly Title: ").append(createSpan(hitData.friendlyTitle)).data("dataKey","friendlyTitle")
        .attr({"class":"editLine hasHelptip","id":"friendlyTitleEdit","title":"Enter a friendly title for this hit. This title will show on the hit cell instead of the original title. Useful for long titles so you can shorten it or make it more rememorable. Enter a blank title to show the original title."}));
    var advancedArea = createDiv().attr("class","advancedArea").css({"border":"1px solid grey","margin":"15px 0 0 0","padding":"5px 3px"}).appendTo(requesterArea);
    createDiv().html("Advanced Options most are changed by the script automatically:").css({"font-size":"12px","text-align":"center"}).appendTo(advancedArea);
    createDiv().html("The Number: ").append(createSpan(theNumber)).css({"margin-top":"5px","color":"red"}).appendTo(advancedArea);
    createDiv().html("Action Mode: ").attr({"title":"Panda = Preview and Accept. (Regular mode)\nPantha = Preview and then Accept.\nSearch = Panda first hit from requester. (For hits that have a lot of pandas)"})
		.append(dataRadioButtons("actionMode",["Panda","Pantha","Search","Other"],hitData.action.toLowerCase(),function(thisValue) {
			$("#actionEdit").data("focusOff",true);
			dataEdited($("#actionEdit"),hitData.action);
			if (thisValue != "other") { $("#actionEdit input").val(thisValue); } else { $("#actionEdit input").focus(); }
			$("#actionEdit").data("focusOff",false);
		})).appendTo(advancedArea);
    createDiv().appendTo(advancedArea).append(createSpan("Action: ").append(createSpan(hitData.action)).data("dataKey","action")
        .attr({"class":"editLine hasHelptip","id":"actionEdit","title":"Advanced use only. Should be Panda for normal use."})
		.data("focusOff",false)
		.data("doClick",function() { $("#other_radio_3").prop("checked",true).button("refresh"); })
		.data("doFocus",function() { $("#other_radio_3").prop("checked",true).button("refresh"); })
		.data("dataCheck",function(target) {
			if (!$(target).length) return true;
			var theValue = $(target).val().toLowerCase();
			var acceptableValue = ["panda","search","pantha","searchpantha","searchandfilter","filterpanda"];
			if ($.inArray(theValue,acceptableValue) == -1 ) {
				showWaitDialog("No such mode found.","",function() {},null,
					createDiv("Action Mode was not an accepted mode.<br>Action mode was changed back.")
						.css({"font-size":"18px","text-align":"center","margin":"20px 10px","line-height":"22px"}),
					false,180,400);
				$(target).val( ($.inArray(hitData.action,acceptableValue) == -1) ? "panda" : hitData.action);
				return false;
			} else if (theValue.indexOf("search") != -1) {
				var thisRequesterID = ($("#requesterIdEdit span").length) ? $("#requesterIdEdit span").text() : $("#requesterIdEdit input").val();
				if (thisRequesterID === "") {
					showWaitDialog("No such mode found.","",function() {},null,
						createDiv("Action Mode Search needs a Requester ID to work properly.<br>Action mode was changed back.")
							.css({"font-size":"18px","text-align":"center","margin":"20px 10px","line-height":"22px"}),
						false,180,600);
					$(target).val(($.inArray(hitData.action,acceptableValue) == -1) ? "panda" : hitData.action);
					return false;
				}
			}
			return true;
		})
        .click( function() { if ($(this).find("span:not(.errorEditLine)").length) { $("label[for='other_radio_3']:first").click(); dataEdited($(this),hitData.action); } }));
    createDiv().appendTo(advancedArea).append(createSpan("Requester Name: ").append(createSpan(hitData.requesterName)).data("dataKey","requesterName")
        .attr({"class":"editLine hasHelptip","id":"requesterNameEdit","title":"This is the original title of the hit. Shouldn't edit this because the script will replace it when it finds the hit. Change the friendly name instead."}));
    createDiv().appendTo(advancedArea).append(createSpan("Requester ID: ").append(createSpan(hitData.requesterId)).data("dataKey","requesterId")
        .attr({"class":"editLine hasHelptip","id":"requesterIdEdit","title":"This is the ID of the requester. Script only uses it for search actions so don't worry about it. But if you know the requester ID you can fill it in to complete it or to have it do a search action instead."}));
    createDiv().appendTo(advancedArea).append(createSpan("Group ID: ").append(createSpan(hitData.groupId)).data("dataKey","groupId")
        .attr({"class":"editLine hasHelptip","id":"groupIdEdit","title":"No reason to change this because you can just add a new job a lot faster."}));
    createDiv().appendTo(advancedArea).append(createSpan("Qualifications: ").append(createSpan(hitData.qual)).css("color","red") // Can not be edited.
        .attr({"class":"editLine cantEdit","id":"qualEdit"}));
    createDiv().appendTo(advancedArea).append(createSpan("Force Audio: ").append(createSpan(hitData.audioforce)).data("dataKey","audioforce")
        .attr({"class":"editLine hasHelptip","id":"audioforceEdit","title":"Not implemented yet. Will be used to change the alarm for this hit no matter the pay rate or duration."}));
    if (hitData.action.toLowerCase().indexOf("filter") != -1 && hitInfo.filterFuncData) {
        var filterModeArea = createDiv().html("Filter Mode: ")
            .attr({"class":"editLine hasHelptip","id":"filterModeEdit"}).appendTo(advancedArea)
            .change( function() { dataEdited($(this),hitData.filterMode.toString()); });
        var filterSelection = $("<select>").attr("name","filterMode").appendTo(filterModeArea);
        var selected = "";
        for (var i=0,len=Object.keys(hitInfo.filterFuncData).length; i<len; i++) {
            selected = (hitData.filterMode==i+1) ? " selected='selected'" : "";
            filterSelection.append("<option value=" + Object.keys(hitInfo.filterFuncData)[i] + selected + ">" + hitInfo.filterFuncData[i+1].filterName + "</option>");
        }
        selected = (hitData.filterMode===0) ? " selected='selected'" : "";
        filterSelection.append("<option value=0 " + selected + ">Off</option>");
    }
    var buttonJobArea = createDiv().css({"margin-top":"35px"}).appendTo(requesterArea);
    var muteJobButton = createSpanButton( function(e) { checkDelayedSave();
			var theNumber = $("#JREditDialog").data("theNumber");
			var hitInfo = gMainData.hitCollection[theNumber];
			var hitData = hitInfo.data;
            muteJob(theNumber);
            $(e.target).html( (hitData.mute) ? "Turn on Alarm" : "Mute Alarm" );
        },(hitData.mute) ? "Turn on Alarm" : "Mute Alarm",gButtonOffBgColor,gButtonOffColor,"13px")
        .css({"border-color":"blue"})
        .attr({"class":"editLine hasHelptip","id":"muteJobButton","title":"Turn on or off the alarm. Used when there is a big batch and the alarm is too long or loud each time it accepts it. You can also right click on the hit cell to mute it a lot faster."}).appendTo(buttonJobArea);
    var deleteJobButton = createSpanButton( function(e) { checkDelayedSave();
			var theNumber = $("#JREditDialog").data("theNumber");
			showYesNoDialog("Are you sure you want me to delete this job?",function(thisNumber) { if (removeJob(thisNumber)) $("#JREditDialog").dialog( "close"); },theNumber);
        },"Delete Job",gButtonOffBgColor,gButtonOffColor,"13px")
        .attr({"class":"editLine hasHelptip","id":"deleteJobButton","title":"Delete this job from this script."}).css({"margin-left":"80px"}).appendTo(buttonJobArea);
	$(".editLine").tooltip({ show: {delay:1000} });
	$(".editLine:not('.cantEdit')").click(function() {
		dataEdited($(this),hitData[$(this).data("dataKey")]);
	});
	helpToolTips();
    $("#JREditDialog").dialog("open");
}
function showHelpDialog( theHelpText, theHelpTitle, theButton ) {
	var dialogHeight = ($(window).height() > 680) ? 680 : $(window).height()-60;
    formatDialog("JREditDialog",dialogHeight,750,theHelpTitle,theButton,theHelpText,true);
    $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Cancel') span").html("Close");
	createDiv().attr("class","JRContents").appendTo($("#JREditDialog"));
	var helpArea = createDiv().attr("class","helpArea").css("margin","15px 8px").appendTo($("#JREditDialog .JRContents:first"));
	if (theHelpText == "about") {
		createDiv().html("Panda Crazy is a script that was created when I didn't like putting timers for pandas because it would make it difficult to work from the queue. I also wanted more organization for pandas. First thing to know is that this script uses cycles instead of timers. A cycle is an amount of time the script will check a panda, check a queue or do something else. So instead of having 3 pandas running at 1 second interval this script will search 1 panda each cycle. So in theory if you had 3 pandas on and the cycle timer at 900ms then a panda will be checked every 3*900ms = 2700ms or 2 seconds and 700ms. This script is built with an automatic slow down when it receives exceed errors from mturk which makes it easier to work from queue while still collecting hits in the background.")
			.css({"font-size":"15px","text-align":"left","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("Don't worry if it might not make sense right now but using short timers for pandas can accept more but cause more exceed errors from mturk when working. This script can do a similar thing when you go Ham on a panda. Also setting the cycle timer to a lower time can make it accept more pandas. The default cycle timer is at 980ms which I found the fastest it could go without getting errors. I use the term job to represent a panda so don't get confused because I will use both interchangably.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("Putting a job on Ham means it will pause all other jobs and only collect the current job. When a job is in Ham mode then it will collect at a faster rate which by default is 700ms. The thought process is you should go into Ham mode when a batch just dropped and you want to get as many as you can fast. Once your queue is full you should turn off Ham mode so you can work on your queue with no or little exceed errors.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("This script will automatically slow down when it gets too many exceed errors. This allows you to work while it's collecting hits for you in the background. Check the Elapsed time status text at the top to make sure it's close to it's default cycle timer. If it's running too slow like at 2000ms then you can click on the reset timer button which will make it go back to the default cycle timer. If you are working from queue then the elapsed timer will be slower. I'd recommend leaving it alone until you finish the queue or the queue isn't filling up fast enough. You should have a full queue constantly on a big batch even at 2 seconds cycle.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("* Most browsers hava a limit to how low a timer could go. Most limit it to 1 second but you can stop that by putting this script in a WINDOW of it's own. Don't put it in a tab because then any unfocused tab will limit it to only 1 second. This script can go under 1 second if it's in it's own Window.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
	} else if (theHelpText == "cycler") {
		createDiv().html("The definition of a cycler for this script is an amount of time the script will wait until it does something. Instead of thinking about a timer for each panda you should think about a line in a store. The clerk will wait on one person at a time until the line is finished. Each job you have colleting will be put in a queue for the script to do. The queue is never ending until you stop the script or stop collecting jobs. The script will take care of each job in the queue one at a time at a specific cycle timer. The lower the cycler timer the faster it checks for pandas. You have 3 cycle timers you can choose from 1 being the fastest and 3 being the slowest. These timers can be changed in the options menu. Use the 2nd and 3rd timers so this script can run with other scripts and not give too many request errors.")
			.css({"font-size":"15px","text-align":"left","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("I find at 980ms is the fastest amount of time before getting exceed errors from mturk. If you are doing nothing else on mturk then the elapsed time at the top should be around 980ms. If the script gets some exceed errors it will start slowing down by adding time to the cycle timer. The amount which is added is set in the options menu. The default time added is 10ms so it won't slow down too fast. I find this is a good amount of time so you can work from queue and still collect pandas in the background. You can change this default option but it's not really recommended.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("If you are working from your queue and getting too many exceed errors you can add time to the cycle timer from the cycler menu at the top. You can increase or decrease time by a certain amount set in the timers option menu. This time is at 10ms by default which you can change if you want. You can also add 650ms to the cycle timer if you want it to slow down NOW. Adding 650ms will usually make it slow enough for you to work and still grab jobs as fast as possible. You can change the 650ms in the timers option menu if you want.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("When you finish your queue and find out that the elapsed time that the script is checking for jobs is much more than the default time then you can reset it back by pushing the reset timer button. If you see it at 2000ms, which is about 2 seconds, then it's best to reset it as long as you are doing nothing on mturk. Remember if you are using other scripts that check the search page for hits then this will cause more exceed errors and will slow the script down. ")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("* It's best to let the slow down happen for the best chance at getting pandas. There is an option to stop the slow down and should only be turned off for times you want to get as many pandas as possible on a batch that trickles down slowly. This option does not save because it can cause problems for you when working.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
	} else if (theHelpText == "jobs") {
		createDiv().html("The definition for a job for this script is basically a panda. I use the term job for a panda interchangeably so don't be confused. Click on the add job button to add a job by entering the groupID or the full url of a panda link. You can also enter in the url of a preview link and the script will be able to change it to a panda. Once the job is added you will see a new cell in the current tab with the information for this new job.")
			.css({"font-size":"15px","text-align":"left","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("When you add a new job it won't know a lot of details for this panda until it actually finds one. It will only know the groupID and it uses that for the title and requester name. You may change the title and description by clicking on the details button on the cell. Change the friendly text fields to make it easier to know what that panda is for. The script will fill all the other details when it finds a panda. If you entered a friendly title or requetser name then that will be used first. If you want the original title and requester name then delete what is in the friendly text field.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("To start collecting a job just push the Collect button and it will start searching it per cycle time. The more jobs you have collecting the slower it has time to search for individual jobs because all the jobs go in a queue. They are checked one by one every cycle timer. Best to stay below 5 but you can have good results with more than 5. Just depends on your luck at having it check at the right time. When you add a job you can tell it to only accept one hit. Once it find one then it will stop collecting. You can click on the collect button again and it will get one more. You can do that all day if you want but it will only accept one every time.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("There is a way to save all the jobs, options, tabs and groupings in the jobs menu. The export button will let you save a file on your computer with all the information it needs. Once you have that file you can save it somewhere place or in a cloud so you can use it to import the data and options back in to the script. You can also import it to another computer or browser that has this script. I recommend to backup a lot so you won't lose anything. When you import a file that was exported, the script will delete all the jobs and options in the current run of the script and replace it with everything in the imported file. Be sure you're not losing any new jobs you want to keep.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("* There are other options you can change in the details section for each job and you can read about them in the \"Job Details\" and \"Go Ham\" in the help menu. A job can also be a search panda where it will do a search for any panda under that requester name but that needs the requester name ID which is not provided by mturk on a panda.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("")
			.css({"font-size":"15px","text-align":"left","text-indent":"50px"}).appendTo(helpArea);
	} else if (theHelpText == "jobDetails") {
		createDiv().html("You can change many options in the details section of a job. Some are simple like changing the friendly title and requester name to make it easy for you to remember a panda. The advanced options on the bottom shouldn't be changed because most of them are changed by the script. If you know the Requester ID you can fill that in but that isn't used for pandas.")
			.css({"font-size":"15px","text-align":"left","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("If you don't want a job to collect too many pandas you can change the queue limit. The queue limit will look at the number of hits in a queue and will not go beyond this limit. It doesn't care what hits are in there so it's not useful if you have a lot of hits in your queue already. This is best used for short timed hits where you don't want to fill your queue because you can't finish it in time.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("The daily limit and the daily done are not really implemented yet. They are both used together so you can collect only a limited amount of hits from this job for the day. Similar to the once option but it can grab more and it's limited per day. The once option is not limited per day. It will just grab 1 every time you turn it on.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("The Ham Timer option for each job is a very new feature but I am finding a lot of uses for it. When you put the panda in a Delayed Ham Mode then it will search for a panda regularly allowing other pandas to search also. Once it finds a hit it will go into Ham Mode automatically and search for this amount of seconds. The default number of seconds is 20. So once it doesn't find a hit it will count this many seconds then it will go back into Delayed Ham Mode allowing other pandas to search unless it finds a hit before. This is really great for batches that trickle in instead of all at once. This allows you to get as many hits as possible but will allow you to work from your queue after it gets out of Ham Mode.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("* You can read more about the Ham mode in the \"Go Ham\" help menu. In the future there may be an option to only allow a limit of hits from this job in your queue. This would allow you to grab a limited amount of hits from this job no matter the size of your queue. Great when you have a lot of surveys in your queue but still want to collect the short timed batch hits.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
	} else if (theHelpText == "goHam") {
		createDiv().html("To \"Go Ham\" has nothing to do with the food. Go Ham in this instance means \"Going hard as a motherf**ker!\" Which means you want the script to go as fast as possible to collect as many hits as it can to fill up your queue. Great use for batches that drop during the day. It shouldn't be used for surveys or other hits that continously drop for the whole day. It's best for those batches that you have no idea when they drop.")
			.css({"font-size":"15px","text-align":"left","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("A big thing to remember here is that a panda will always get a hit first before it even reaches the search page. For example virals are good hits that drop at different times. If you turn on a viral panda and it finds one. You can instantly push the GoHam button to grab as many as possible before it gets to the search page where others who are not running a panda will find it. This could give you many seconds or a minute jump on them before competing with everyone else. But remember Ham Mode will stay on until you turn it off so make sure you turn it off if you have other pandas you are waiting for.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("There is a new feature I put in place recently to make Going Ham even better. This is called Delayed Ham Mode which can be turned on by pushing the GoHam button and hold it until the button turns blue. In this mode the job will keep searching for a hit at a normal mode with all the other jobs. But once it finds a panda hit then it will instantly go into Ham Mode. It will keep collecting hits until your queue is full or it doesn't find a hit. Once it stops finding hits it will count down the number of seconds in the Ham Timer option found in the Details section. If that number is 0 then it will stay in Ham Mode until you turn it off. But if that number is greater than 0 then it will wait that amount of seconds and then go back to Delayed Ham Mode only if it finds nothing for that amount of seconds. If it find something then it waits again.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("The Delayed Ham Mode I find useful for batches that trickle in instead of dropping all at once. For example: virals or zoltars. This allows you to get as many hits possible but still allow you to work with little or no exceed errors. You can change the number of seconds to wait for each job in the Details section. By default each job is at 20 seconds because I have found it a lot useful than clicking on the GoHam button all the time. When you have a full queue than this feature is less useful because you can't really do work in the queue faster than the script can check for pandas. So if you have a full queue and can't keep up with it than just turn off Ham Mode and let it collect at a normal speed. You can also slow it down so you will get no exceed errors at all.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
	} else if (theHelpText == "groupings") {
		createDiv().html("Groupings are a way to start and stop a group of jobs all at once. The hits in a group can be from any tab. You can group them in any way you would like. A grouping can be set up for all the regular pandas you turn on in the morning or during the night. You can group all the short timed pandas together so you can easily turn them on or off. You can even group up jobs from the same requester if you wanted to.")
			.css({"font-size":"15px","text-align":"left","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("You can create a grouping in two ways. The create by selection button will let you choose any jobs you want in your group. Just click on the jobs below in any of the tabs. Any job you click on will be added to your group and it will collect hits if you turn on that group. You can also right click on a job to turn it into a Delayed Ham Mode when the group is turned on. Clicking on a job again will toggle it off so you can pick as much or little as possible. Once you select the jobs and click on the create grouping button you will be able to name your grouping. The name must be unique. You can also enter a description of the grouping if you would like.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
	} else if (theHelpText == "tabs") {
		createDiv().html("Tabs are a way for organizing your jobs in different ways. The main tab is permanent and can not be deleted. Also any jobs in tabs which are deleted will be moved to the Main tab. When you first install the script you will see 3 tabs by default just to give you examples. You can delete them or rename them in any way you want. If you want to rename a tab then righ click on the tab. It will bring up a dialog asking you for the new name of the tab. If you want to delete a tab then click on the x on the tab. Remember any hits inside the tab when deleted will be moved to the Main tab.")
			.css({"font-size":"15px","text-align":"left","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("You can also add more tabs and there probably isn't a limit but why would you need a 100 tabs? You can organize the jobs in any way to make it easy for yourself. Just click on the + at the end of the tab. You can put all the low paid jobs in one tab. Maybe you want all jobs from one requester in their own tab? How about a tab for rare jobs you don't see too much. Maybe a morning tab for all the jobs you want to do in the morning? But I truly believe a morning grouping would be a lot better. Tabs are more for organizing jobs in places so you can remember where they are fast. Groupings are for when you want to collect more than one jobs at once.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("Tabs can also be re-arranged by dragging and dropping the tabs to another position. You might want a new tab in front of an older tab because it makes more sense. The Main Tab can never be moved so don't even try.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
	} else if (theHelpText == "options") {
		createDiv().html("The options menu is where all the different changes can be made to the functionality of the script. You can change the timers, alarms or other general options. There is another button to stop the auto slow down of the script when it receives exceed errors. It's best to not touch this button so you can work from queue and still have the script collect pandas without getting too many errors. The whole purpose of this script to allow you to work as it collects hits in the background.")
			.css({"font-size":"15px","text-align":"left","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("The timers menu will let you change the cycle timer. I find 970ms is a good amount of time. Shouldn't have any exceed errors and it's fast enough to grab hits. The GoHam Cycle Timer is the time that ti will collect hits when in Ham Mode. This is so it can collect hits as fast as possible. Expect a lot of exceed errors but this is equivalent to using 2 pandas at 1 second each if you set it at 500ms. I set the default value at 700ms because I find that's fast enough. The Default GoHam Delay Timer is when you put the job in a delayed ham mode. This is the time that it will return to normal after finding no hits. This value gets set for any new jobs you add. You can always change this time individually on each job too. The advanced options shouldn't be changed unless you really need to. These are for the buttons on the cycle menu.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("The alarms button will show a dialog of all the alarms that the script uses. You can change each alarm to any sound file on your computer. When you add your own alarm it will load it in and save it in memory. There is a limit to the size of the file so it doesn't use up a lot of memory. Once the alarm is in memory it doesn't need the sound file anymore.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("There is a thought process for these alarm sounds. The smaller the pay rate for a job the shorter the sound. So by default I added a ding for jobs paying less than 2 cents. If a job is playing over 15 cents then I added a loud music to get my attention. It's now your job to figure out a good plan for yourself. A job with a short timer should have a long and catchy alarm so you can easily know you have to do that one fast. You can also change the different pay rates for each alarm so if you don't like an alarm at 15 cents you can change it to 50 cents. You can also change the short timers alarms for each pay rate also. Any alarm over 15 seconds is a bit much in my opinion but you might want a long alarm so you can hear it while cooking or sleeping. A good hard rock music for an alarm should wake you up or get your attention from another room.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("There is only one general option at this time. Each button, tab or status show a helpful tooltip if you hover your mouse over for a second. You can turn this feature off if you don't need the help anymore. It can get in the way and can be annoying after you know what everything does.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
	} else if (theHelpText == "statustext") {
		createDiv().html("The status text at the top shows a lot of different data so you can know it's working the best possible way. You will use the status to know how many jobs are being collected. You can find out how many pandas have been collected. It also collects the amount of money you will get if you submitted all the collected hits. The script doesn't know if you returned or a hit was abandoned so the pay amount is only an estimation.")
			.css({"font-size":"15px","text-align":"left","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("The first status text shows how many jobs are running. This counts any job being collected from any tab.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("The second status is the Elapsed time which is the most important part to this script. The time is in milliseconds so 1000ms equals 1 second. If you are not wrking from queue on anything and no other script searching then the elapsed time should be around 1000ms. Usually it should be close to 970ms by default. Anything under 970ms will cause more exceed error from mturk. If this time is 1500ms or over than you have another script checking mturk or you are working. This is the what you want to see because the script slows down if it gets exceed erros. This allows you to work while still collecting pandas. Click on the reset timer so it goes back to the default timer.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("Clicking on the elapsed timer will show you the exact cycling time that it's using. Another click will show how many milliseconds is added to the cycle time to slow it down. Another click shows the minimum cycle timer for jobs in ham mode. One more click brings you back to the elapsed time.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("The third status shows the number of hits accepted.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("The fourth status how many exceed errors it has received. The script will slow down each time it receives these errors but you can reset the timer back to default. This number is just a stat you can use to know if it's going to fast. Clicking on this status will show how many other erros it has received.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("The fifth status shows how many hits are in your mturk queue. The script by default checks your queue every 1 minute or 60000ms. This time can be changed in the timer options menu. You really don't want this to be too low because it will slow down collecting pandas. 30 seconds might be good if you need the script to be more accurate with this number. The script uses this number for jobs that have a queue limit. If you click on this status you will force the script to check your queue and update the number.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("The sixth status shows how many jobs have been searched since you started the script.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
		createDiv().html("The seventh status shows the estimated pay amount you will get if you submit all the collected hits. This is an estimate because it doesn't know if you return or abandoned some of the hits.")
			.css({"font-size":"15px","text-align":"left","margin-top":"10px","text-indent":"50px"}).appendTo(helpArea);
	}
    $("#JREditDialog").dialog("open");
}
function releaseButton(thisDialog) {
    if ($(thisDialog).data("button")) {
        toggleButton($(thisDialog).data("button"),null,null);
        $(thisDialog).data("button",null);
    }
}
function createADialog(idName,theTitle,theHeight,theWidth,isModal,saveFunction,theNumber) {
    createContainer().attr("id",idName)
        .data({"button":null,"theNumber":theNumber,"NOCloseDialog":false})
        .appendTo("body")
        .dialog({
            dialogClass: "no-close", autoOpen: false, title: theTitle, height: theHeight, width: theWidth, modal: isModal,
            buttons: {
                "Yes": function() {
                    if ($(this).data("yesFunction")) ($(this).data("yesFunction"))($(this).data("theNumber"));
                },
                "No": function() { releaseButton($(this)); $(this).dialog( "close"); },
                "Create Grouping": function() { createGroup(); },
                "Save": function() {
                    var NOCloseDialog = $(this).data("NOCloseDialog");
					var saveReturn = true;
                    if (saveFunction) saveReturn = saveFunction();
                    if ($(this).data("closeme")) ($(this).data("closeme"))();
                    if (saveReturn && !NOCloseDialog) {
                        releaseButton($(this));
                        $(this).dialog( "close");
                    }
                },
                "Cancel": function() {
                    var NOCloseDialog = $(this).data("NOCloseDialog");
                    if ($(this).data("closeme")) ($(this).data("closeme"))();
                    if (!NOCloseDialog) {
                        releaseButton($(this));
                        $(this).dialog( "close");
                    }
                }
            }
        });
    $("div[aria-describedby='" + idName + "'] .ui-dialog-buttonpane button:contains('Save')").hide();
    $("div[aria-describedby='" + idName + "'] .ui-dialog-buttonpane button:contains('Create Group')").hide();
    $("div[aria-describedby='" + idName + "'] .ui-dialog-buttonpane button:contains('Yes')").hide();
    $("div[aria-describedby='" + idName + "'] .ui-dialog-buttonpane button:contains('No')").hide();
}
function createWaitDialog() {
    createADialog("JRWaitDialog","Please Wait",250,310,true);
    $("div[aria-describedby='JRWaitDialog'] .ui-dialog-buttonpane button:contains('Cancel')").hide();
}
function createEditDialog() {
    createADialog("JREditDialog","Job Details",600,500,true,saveEditedData);
	createDiv().attr("id","JRSavedMturkArea").appendTo($("#JREditDialog")).hide();
	createDiv().attr("id","JRSavedJobsArea").appendTo($("#JREditDialog")).hide();
}
function createPromptDialog() {
    createADialog("JRPromptDialog","Enter your answer:",600,500,true,null,"");
    $("div[aria-describedby='JRPromptDialog'] .ui-dialog-buttonpane button:contains('Yes')").show();
}
function createYesNoDialog() {
    createADialog("JRYesNoDialog","Are you sure?",155,560,true,null,"");
    $("div[aria-describedby='JRYesNoDialog'] .ui-dialog-buttonpane button:contains('Yes')").show();
    $("div[aria-describedby='JRYesNoDialog'] .ui-dialog-buttonpane button:contains('No')").show();
    $("div[aria-describedby='JRYesNoDialog'] .ui-dialog-buttonpane button:contains('Cancel')").hide();
}
function sendPongMessage(url) { localStorage.setItem("JR_message_pong_" + gScriptName, JSON.stringify({"command":"run","url":url,"time":(new Date().getTime())})); }
function mainListener(e) {
	if ( e.key == 'JR_message_' + gScriptName ) {
		var theMessageCommand = JSON.parse(e.newValue).command;
		var theMessageData = JSON.parse(e.newValue).data;
		var onlyOnce = false;
		switch(theMessageCommand) {
			case 'queueData' :
				if (theMessageData.queueLength) gMainData.hitsInQueue = theMessageData.queueLength;
				displayMainStatus();
				break;
			case 'projectedEarnings' :
				if (theMessageData.projectedEarnings) {
					gMainData.projectedEarnings = parseFloat(theMessageData.projectedEarnings);
					$("#JRPayArea").data("mode","Projected").stop(true,true).css({"color":"red"}).animate({"color": "#191970"}, 30000);
					displayMainStatus();
				}
				break;
			case 'addOnceJob' :
				onlyOnce = true;
                /* falls through */
			case 'addJob' :
				var newNumber = fillNewHitData(theMessageData.requesterName, theMessageData.requesterId, theMessageData.groupId, theMessageData.pay,
					theMessageData.title, theMessageData.duration, onlyOnce, true, true);
				gMainData.hitCollection[newNumber].numberHits = theMessageData.hitsAvailable;
				break;
		}
	} else if (e.key == 'JR_message_ping_' + gScriptName) {
		sendPongMessage(e.url);
	}
}
function startMessageListener() {
	window.addEventListener("storage", mainListener, false);
}
function shortGroupID( groupId ) { return groupId.slice(0,2) + ".." + groupId.slice(-4); }
function updateHitCell(theNumber) {
    var hitInfo = gMainData.hitCollection[theNumber];
    var hitData = hitInfo.data;
    var hitCell = $("#JRCellNum_" + theNumber).eq(0);
	var theErrorStatus = (hitInfo.status.blocked > 0) ? "BLOCKED - " : (hitInfo.status.notQual > 0) ? "UNQUALIFIED - " : "";
	var thisRequesterName = (hitData.friendlyRName !== "") ? hitData.friendlyRName : ((hitData.requesterName !== "") ? hitData.requesterName : hitData.groupId);
    $(hitCell).find(".myTitle").html(thisRequesterName).attr({"title":theErrorStatus + thisRequesterName + "\n" + hitData.groupId});
    $(hitCell).find(".myfloater").html("[" + shortGroupID(hitData.groupId) + "]");
	if (hitData.weight>0) $(hitCell).find(".weightStatus").html("W" + hitData.weight);
	else $(hitCell).find(".weightStatus").html("");
    if (gMainData.displayInfo===0) {
        $(hitCell).find(".myExtra").html("");
        $(hitCell).find(".myDescription").html("");
    } else if (gMainData.displayInfo==1) {
		var htmlTitle = (hitData.friendlyTitle !== "") ? hitData.friendlyTitle : ((hitData.title!=="") ? hitData.title : hitData.groupId);
        $(hitCell).find(".myExtra").html(hitData.pay + ( (hitData.qual==="") ? "" : " (" + hitData.qual + ") " ) + ( (hitInfo.numberHits=="0") ? "" : " [" + hitInfo.numberHits + "] " ));
        $(hitCell).find(".myDescription").html(htmlTitle);
    }
}
function updateHitColors(theNumber,thisButton) {
    if (theNumber) {
        var hitInfo = gMainData.hitCollection[theNumber];
        var hitData = hitInfo.data;
        var collectButtonStatus = $("#JRCellNum_" + theNumber).find(".JRCollectButton").data("status");
        $("#JRCellNum_" + theNumber).data("status",collectButtonStatus);
        var gohamButtonStatus = $("#JRCellNum_" + theNumber).find(".JRHamButton").data("status");
        var gohamButtonDisabled = $("#JRCellNum_" + theNumber).find(".JRHamButton").data("disabled");
        var hitCellMute = $("#JRCellNum_" + theNumber).data("mute");
        var hitCellTypeAction = hitData.action.toLowerCase();
		var hitColor = (hitInfo.status.blocked > 0) ? gBlockedColor : gHitTextColor;
		var shortColor = (hitInfo.status.blocked > 0) ? gBlockedColor : gHitShortIdColor;
        var hitBgColor = (hitCellTypeAction.substring(0,6)=="search") ? gSearchesHitBgColor : (hitCellTypeAction=="filterpanda") ? gFilteredHitBgColor :
				(hitInfo.status.notQual > 0) ? gNotQualedBgColor : (hitInfo.status.blocked > 0) ? gBlockedBgColor : gHitBgColor;
        var titleColor = (hitCellMute) ? gHitMutedColor : (hitInfo.status.blocked > 0) ? gBlockedColor : gTitleColor;
        var borderStyle = (hitCellMute) ? gHitMutedBorderStyle : gHitBorderStyle;
        var collectBgColor = (collectButtonStatus=="off") ? gButtonOffBgColor : gButtonOnBgColor;
        var collectColor = (collectButtonStatus=="off") ? gButtonOffColor : gButtonOnColor;
        var gohamBgColor = (gohamButtonDisabled) ? gButtonDisabledBgColor : (gohamButtonStatus=="off") ? gButtonOffBgColor : (gohamButtonStatus=="paused") ? gButtonDelayHamBgColor : gButtonOnBgColor;
        var goHamColor = (gohamButtonDisabled) ? gButtonDisabledColor : (gohamButtonStatus=="off") ? gButtonOffColor : gButtonOnColor;
        $("#JRCellNum_" + theNumber).css({"background-color":hitBgColor,"border-style":borderStyle,"color":hitColor}).data("backgroundColor",hitBgColor);
        $("#JRCellNum_" + theNumber).find(".myTitle").css({"color":titleColor});
        $("#JRCellNum_" + theNumber).find(".JRCollectButton").css({"background-color":collectBgColor,"color":collectColor});
        $("#JRCellNum_" + theNumber).find(".JRHamButton").css({"background-color":gohamBgColor,"color":goHamColor});
        $("#JRCellNum_" + theNumber).find(".myfloater").css({"background-color":hitBgColor,"color":shortColor});
    } else {
        var buttonStatus = $(thisButton).data("status");
        var buttonBgColor = (buttonStatus=="off") ? gButtonOffBgColor : gButtonOnBgColor;
        var buttonColor = (buttonStatus=="off") ? gButtonOffColor : gButtonOnColor;
        $(thisButton).css({"background-color":buttonBgColor});
        $(thisButton).css({"color":buttonColor});
    }
}
function saveGroupIdSearching(thisHitInfo,saveSearchGroupId) {
	var theHitCell = thisHitInfo.hitCell;
	var borderColor = (saveSearchGroupId) ? "#8B0000" : theHitCell.data("borderColor");
	theHitCell.css({"border-color":borderColor});
	theHitCell.data("saveSearchGroupId",saveSearchGroupId);
}
function createHitCell(goAppend,hitData,cellNumber) {
    var theContainer = createContainer();
    var hitInfo = gMainData.hitCollection[cellNumber];
	var hitCellTypeAction = hitData.action.toLowerCase();
    var backgroundColor = (hitCellTypeAction.substring(0,6)=="search") ? gSearchesHitBgColor : (hitCellTypeAction=="filterpanda") ? gFilteredHitBgColor : gHitBgColor;
    var floaterRight = createDiv()
        .attr({"class":"myfloater hasHelptip keepHelptip","title":"Click here to copy panda link. Double Click to open panda link."})
        .data({"hitInfo":hitInfo})
        .click(function(e) { GM_setClipboard ($(e.target).data("hitInfo").pandaUrl); e.stopPropagation();})
		.dblclick(function(e) { window.open($(e.target).data("hitInfo").pandaUrl,"_blank"); })
        .css({"float":"right","margin-right":"-3px","padding":"0 1px 0 3px","font-weight":"900","background-color":backgroundColor,
            "color":gHitShortIdColor,"font-size":"7px","z-index":"999","position":"relative","cursor":"pointer"})
        .html("[" + shortGroupID(hitData.groupId) + "]").appendTo(theContainer);
    var theInfoArea = createDiv();
    var titleColor = (hitData.mute) ? gHitMutedColor : gTitleColor;
	var thisRequesterName = (hitData.friendlyRName !== "") ? hitData.friendlyRName : ((hitData.requesterName !== "") ? hitData.requesterName : hitData.groupId);
    createDiv().html(thisRequesterName).css({"font-weight":"900","color":titleColor,"font-size":"13px"})
        .attr({"class":"myTitle hasTooltip","title":thisRequesterName + "\n" + hitData.groupId})
        .tooltip({ show: {delay:1100} }).appendTo(theContainer);
	var htmlDescription = "";
    if (gMainData.displayInfo==1) htmlDescription = hitData.pay + ( (hitData.qual==="") ? "" : " (" + hitData.qual + ") " );
    var htmlTitle = (hitData.friendlyTitle !== "") ? hitData.friendlyTitle : ((hitData.title!=="") ? hitData.title : hitData.groupId);
    createDiv().html(htmlDescription).attr({"class":"myExtra"})
        .css({"font-size":"11px"}).appendTo(theContainer);
    createDiv().html(htmlTitle).css({"font-size":"10px"})
        .attr({"class":"myDescription hasTooltip","title":(hitData.friendlyTitle==="") ? htmlTitle : hitData.friendlyTitle + "\n" + hitData.title})
		.tooltip({ show: {delay:1100} }).appendTo(theContainer);
    createDiv().html(" ").attr({"class":"myStatus","id":"JRCellStatus_" + cellNumber})
        .css({"font-weight":"300","font-size":".8em"}).appendTo(theContainer);
    var theButtonArea = createDiv().css({"margin-top":"2px","padding":"2px"}).appendTo(theContainer);
    createSpanButton( function(e) { checkDelayedSave();
            var thisHitInfo = $(e.target).data("hitInfo");
            toggleButton( $(e.target),startCollecting,stopCollecting);
            if (thisHitInfo.collecting=="off" && thisHitInfo.ham != "off") toggleButtonOff($("#JRHamB_" + $(e.target).data("theNumber")),hamOn,hamOff);
            e.stopPropagation();
        },"Collect",gButtonOffBgColor,gButtonOffColor,"12px")
        .bind("mousedown", function(e) {
            $(e.target).closest(".tabContents").sortable("disable");})
        .bind("mouseup mouseleave", function(e) {
            $(e.target).closest(".tabContents").sortable("enable");})
        .attr({"id":"JRCollectB_" + cellNumber,"class":"JRCollectButton JRButton JRMButton hasHelptip","title":"Start collecting this panda hit."})
		.tooltip({ show: {delay:1000} })
        .data({"theNumber":cellNumber,"hitCell":theContainer,"hitInfo":hitInfo,"status":"off","disabled":false}).appendTo(theButtonArea);
    createSpanButton( function(e) { checkDelayedSave();
            if ( !$(e.target).data("disabled") && !gPressAndHold ) {
                var thisHitInfo = $(e.target).data("hitInfo");
                if (thisHitInfo.ham == "ontimed") toggleButton($(e.target),hamOn,hamOff,"off");
				else toggleButton($(e.target),hamOn,hamOff);
                if (thisHitInfo.collecting == "off") toggleButton($("#JRCollectB_" + $(e.target).data("theNumber")),startCollecting,stopCollecting,"on");
                gPressAndHold=false;
                e.stopPropagation();
            } else if (gPressAndHold) gPressAndHold=false;
        },"GoHam",gButtonOffBgColor,gButtonOffColor,"12px")
        .bind("mousedown", function(e) {
            var thisButton = $(e.target);
            $(e.target).closest(".tabContents").sortable("disable");
            gMouseDownTimeoutId = setTimeout( function() {
				var thisHitInfo = $(thisButton).data("hitInfo");
                gPressAndHold=true;
                var thisNumber = $(thisButton).data("theNumber");
                if (thisHitInfo.collecting == "off") toggleButton($("#JRCollectB_" + thisNumber),startCollecting,stopCollecting);
                if (thisHitInfo.ham=="off" || thisHitInfo.ham=="ontimed" || thisHitInfo.ham=="on") toggleButton($(thisButton),hamOn,hamOff,"paused","off");
				else toggleButton($(thisButton),hamOn,hamOff,"off","off");
            }, 500);
            e.stopPropagation();
        })
        .bind("mouseup mouseleave", function(e) {
            clearTimeout(gMouseDownTimeoutId);
            if (window.jQuery) { $(e.target).closest(".tabContents").sortable("enable"); }
            e.stopPropagation();
        })
        .attr({"id":"JRHamB_" + cellNumber,"class":"JRHamButton JRButton JRMButton hasHelptip","title":"Try to collect pandas from this hit ONLY! Click and hold for a second to put in delayed Ham Mode which will only go into Ham mode after a panda is found."})
		.tooltip({ show: {delay:1000} })
        .data({"theNumber":cellNumber,"hitCell":theContainer,"hitInfo":hitInfo,"status":"off","disabled":false}).appendTo(theButtonArea);
    createSpanButton( function(e) { checkDelayedSave();
            showEditHitDialog($(e.target).data("theNumber"),$(e.target));
            e.stopPropagation();
        },"details",gButtonOffBgColor,gButtonOffColor,"9px")
        .bind("mousedown", function(e) {
            $(e.target).closest(".tabContents").sortable("disable");})
        .bind("mouseup mouseleave", function(e) {
            $(e.target).closest(".tabContents").sortable("enable");})
        .attr({"id":"JRDetailsB_" + cellNumber,"class":"JRDetailsButton JRButton JRMButton hasHelptip","title":"Display all details and options for this hit. You can also edit any detail or option."})
		.tooltip({ show: {delay:1000} })
        .data({"theNumber":cellNumber,"hitCell":theContainer,"hitInfo":hitInfo,"status":"off","disabled":false}).appendTo(theButtonArea);
	createSpan((hitData.weight>0) ? "W"+hitData.weight : "").css({"margin-left":"2px","font-size":"8px"}).attr({"class":"weightStatus"}).appendTo(theButtonArea);
    var borderStyle = (hitData.mute) ? "dotted" : "solid";
    theContainer.width("200px")
        .attr({"id":"JRCellNum_" + cellNumber,"class":"JRHitCell"})
        .data({"backgroundColor":backgroundColor,"borderColor":"MidnightBlue","titleColor":gTitleColor,"theNumber":cellNumber,"status":"off","color":gHitTextColor,
                "mute":hitData.mute,"saveSearchGroupId":false,"typeAction":hitData.action.toLowerCase(),"hitData":hitData,"hitInfo":hitInfo,"oldPosition":null,"selected":0})
        .css({"border-color":"MidnightBlue", "border-width":"3px", "border-style":borderStyle, "margin":"2px 4px", "color":gHitTextColor,
            "background-color":backgroundColor, "font-size":"11px", "cursor":"move", "overflow":"hidden", "float":"left", "white-space":"nowrap"})
        .bind("contextmenu", function(e) {
			var theHitCell = $(e.target).closest(".JRHitCell");
			e.preventDefault();
            if (gScriptStatus == "normal") {
				if ($(e.target).is(".JRButton")) return;
				muteJob(theHitCell.data("theNumber"));
			} else if (gScriptStatus == "creating groupings") {
                if (theHitCell.data("selected")==2) {
                    theHitCell.css({"background-color":"#ADFF2F"});
                    theHitCell.data("selected",1);
                } else {
                    theHitCell.css({"background-color":"#33CC66"});
                    theHitCell.data("selected",2);
                }
			}
        })
        .bind("mouseup mouseleave", function(e) {
			if (window.jQuery) { if ($(e.target).is(".JRButton")) { e.stopPropagation(); return; } }
        })
        .click( function(e) {
            var theHitCell = $(e.target).closest(".JRHitCell");
            if (gScriptStatus == "normal") {
                if ($(e.target).is(".JRButton")) { e.stopPropagation(); return; }
                if ($(e.target).hasClass('noclick')) {
                    $(e.target).removeClass('noclick');
                } else {
                    var thisHitInfo = theHitCell.data("hitInfo");
                    if ( theHitCell.data("typeAction").substring(0,6) == "search" ) {
						saveGroupIdSearching(thisHitInfo,!theHitCell.data("saveSearchGroupId"));
					}
                }
            } else if (gScriptStatus == "creating groupings") {
                if (theHitCell.data("selected")!==0) {
                    theHitCell.css({"background-color":"#00FFEE"});
                    theHitCell.data("selected",0);
                } else {
                    theHitCell.css({"background-color":"#ADFF2F"});
                    theHitCell.data("selected",1);
                }
            }
        });
    theContainer.appendTo(goAppend);
    displayHitStatus(cellNumber);
    return theContainer;
}
function addHitData(newHitData,tabIndex) {
    var inTabId = "#" + $("#JRTab_" + newHitData.tabNumber).attr("aria-controls");
    gRequestersData[gRequestersData[0].requesterId] = newHitData;
    $(inTabId).data("tabData").positions.push(gRequestersData[0].requesterId);
    var theNumber = addHitCollection(newHitData,gRequestersData[0].requesterId,tabIndex);
    gRequestersData[0].requesterId++;
    newHitCell = createHitCell($(inTabId).find(".tabContents"),newHitData,theNumber).data({"removeMe":false,"pandaHam":"off"});
	$(inTabId).find(".JRStatusText").tooltip({ show: {delay:680} });
	$(inTabId).find(".hasHelptip").tooltip({ show: {delay:1000} });
	helpToolTips();
	gMainData.hitCollection[theNumber].hitCell = newHitCell;
    saveSettings();
    return newHitCell;
}
function addToMenu(theMenuArray,theName,theMenuObject) {
    if (theName=="Main") theMenuArray[0].theobject = theMenuObject;
    else {
        theMenuArray.push({"name":theName,"theobject":theMenuObject});
        $(theMenuObject).hide();
    }
}
function activeMenu(theMenuArray,theName) {
    for (var i=0,len=theMenuArray.length; i<len; i++) {
        if (theMenuArray[i].name == theName) $(theMenuArray[i].theobject).show();
        else $(theMenuArray[i].theobject).hide();
    }
    displayMainStatus();
}
function isActiveMenu(theMenuArray,theName) {
    for (var i=0,len=theMenuArray.length; i<len; i++) {
        if (theMenuArray[i].name == theName && $(theMenuArray[i].theobject).is(":visible")) return true;
    }
    return false;
}
function addToLog(addNode,logNode,limit,resetLog,sort) {
	limit = limit || 3000;
	resetLog = resetLog || false;
	sort = sort || false;
	if (resetLog) { logNode.html(""); return; }
	if (limit) {
		var logLength = logNode.find(".logDiv").length;
		if (logLength > limit) logNode.find(".logDiv:last").remove();
	}
    var firstLogDiv = logNode.find(".logDiv:first");
    if (firstLogDiv.length) firstLogDiv.before(createDiv().css({"margin-left":"18px","text-indent":"-15px"}).attr("class","logDiv").append(addNode));
    else logNode.append(createDiv().css({"margin-left":"18px","text-indent":"-15px"}).attr("class","logDiv").append(addNode));
	$(".logDiv span").click( function() { return false; } );
	return true;
}
function addToAcceptedLog(theText) { addToLog(createSpan(theText.trim()),$("#JRAcceptedLog")); }
function addToStatusLog(theNumber) {
	var hitInfo = gMainData.hitCollection[theNumber];
	var hitData = hitInfo.data, hitStatus = hitInfo.status;
	if ( !($("#JRStatusLog .statusNumber" + theNumber).length) ) $("#JRStatusLog").append(createDiv("").attr("class","statusNumber" + theNumber).css({"color":"white"})
		.append(createSpan("&nbsp;Requester: ").css({"color":"cyan"})).append(createSpan("").attr("class","sRequesterName"))
		.append(createSpan(" | Pay: ").css({"color":"cyan"})).append(createSpan("").attr("class","sPay"))
		.append(createSpan(" | Mode: ").css({"color":"cyan"})).append(createSpan("").attr("class","sMode"))
		.append(createSpan(" | Accepted: ").css({"color":"cyan"})).append(createSpan("").attr("class","sAccepted"))
		.append(createSpan(" | Missed: ").css({"color":"cyan"})).append(createSpan("").attr("class","sMissed"))
		.append(createSpan(" | Checked: ").css({"color":"cyan"})).append(createSpan("").attr("class","sChecked"))
		.append(createSpan(" | Elapsed: ").css({"color":"cyan"})).append(createSpan("").attr("class","sElapsed")));
	$("#JRStatusLog .statusNumber" + theNumber + " .sRequesterName").html(((hitData.friendlyRName!=="") ? hitData.friendlyRName : (hitData.requesterName!=="") ? hitData.requesterName : shortGroupID(hitData.groupId)));
	$("#JRStatusLog .statusNumber" + theNumber + " .sPay").html(hitData.pay);
	$("#JRStatusLog .statusNumber" + theNumber + " .sMode").html(hitData.action);
	$("#JRStatusLog .statusNumber" + theNumber + " .sAccepted").html(hitStatus.accepted);
	$("#JRStatusLog .statusNumber" + theNumber + " .sMissed").html(hitStatus.missed);
	$("#JRStatusLog .statusNumber" + theNumber + " .sChecked").html(hitStatus.searched);
	$("#JRStatusLog .statusNumber" + theNumber + " .sElapsed").html(hitInfo.elapsedSeconds + "s");
}
function removeFromStatusLog(theNumber) {
	if ( ($("#JRStatusLog .statusNumber" + theNumber).length) ) $("#JRStatusLog .statusNumber" + theNumber)[0].remove();
}
function addToQueueWatchLog(theNode,resetLog,sort) {
	resetLog = resetLog || false;
	sort = sort || false;
	if (resetLog) {
		addToLog("",$("#JRQueueWatchLog"),26,true);
		$("#JRQueueWatchLog").append(createDiv().attr("class","muteQueueWatch").css({"float":"right","text-align":"right","height":"60px"}).append(createCheckbox()
			.attr("id","muteQueueWatchAlarm").prop('checked', gMuteQueueWatch)
			.click( function() { gAlarmSounds.queueAlert.audio.pause(); gMuteQueueWatch = $(this).is(":checked"); } ))
			.append(createSpan("Mute Alarm").css({"margin-right":"5px"}))
		.append(createDiv().append(createLink("Open Queue","https://www.mturk.com/mturk/myhits","_blank","Open queue page").css({"color":"cyan","margin-right":"5px"})
			.click( function() {
                var theHeight=window.outerHeight-80, theWidth=window.outerWidth-10;
				window.open("https://www.mturk.com/mturk/myhits","_blank","width=" + theWidth + ",height=" +  theHeight + ",scrollbars=yes,toolbar=yes,menubar=yes,location=yes");
				return false;
			}))));
	}
	addToLog(theNode,$("#JRQueueWatchLog"),26,false,sort);
}
function fillInPositions() { // Initialize positions because they are not set.
    $.each(gRequestersData, function( index, value ) {
        if (index>0) {
            var goInTab = null;
            $.each(gTabsData, function( tabsIndex, tabsValue ) {
				if (goInTab === null) goInTab = tabsValue;
				if (tabsValue.tabNumber == value.tabNumber) goInTab = tabsValue;
            });
            if (goInTab) {
                if (goInTab.positions === null) goInTab.positions = [];
                goInTab.positions.push(index);
                value.tabNumber = goInTab.tabNumber;
            }
        }
    });
}
function fillTabs() {
    var theNumber=0, newHitCell=null, thisTab=null, thisData=null, thisTabControls=null;
    $.each(gTabsData, function( index, value ) {
		thisTab = $("#" + ($("#JRTab_" + value.tabNumber).attr("aria-controls")));
		if (value.positions) {
			for (var ii=0; ii<value.positions.length; ii++) {
				var thisPositionNumber = value.positions[ii];
				if (thisPositionNumber in gRequestersData) {
					thisData = gRequestersData[thisPositionNumber];
					theNumber = addHitCollection(thisData,thisPositionNumber,index);
					newHitCell = createHitCell($(thisTab).find(".tabContents"),thisData,theNumber)
						.data({"removeMe":false,"pandaHam":"off"});
					gMainData.hitCollection[theNumber].hitCell = newHitCell;
					gMainData.hitCollection[theNumber].data.tabNumber = value.tabNumber;
					value.positions[ii] = "" + value.positions[ii];
				} else {
					value.positions.splice(ii, 1);
					ii--;
				}
			}
		} else value.posistions = [];
    });
}
function refreshAllCells() {
    $.each(gMainData.hitCollection, function( index, value ) {
        updateHitCell(index);
    });
}
function showButtonUsed(thisButton) {
    thisButton.css({"background-color":"#CCC6B0"});
    thisButton.stop().animate({"backgroundColor": gButtonOffBgColor,"color":gButtonOffColor}, 500);
}
function appendAddTabButton() {
	$("#JRMainTabs .ui-tabs-nav").append(
		createDiv(
			createSpanButton(function(e) { checkDelayedSave();
				$("#addNewtab").remove();
				var returnName = prompt("Enter Tab Label : ", "Added");
				returnName = (returnName!=="") ? returnName : "Added";
				var nextTabNumber = parseInt(gTabsInfo.nextTabNumber);
				var newTabData = jQuery.extend(true, {}, gTabsData[0]);
				newTabData.tabNumber = nextTabNumber;
				newTabData.tabName = returnName;
				newTabData.positions = [];
				addTab($("#JRMainTabs"),newTabData.tabName,true,"JRTab_" + nextTabNumber,newTabData,true).css({"overflow":"visible"});
				$("#JRTab_" + nextTabNumber).find("a").tooltip({ show: {delay:1000} });
				helpToolTips();
				gTabsInfo.nextTabNumber = nextTabNumber + 1;
				gTabsData.push(newTabData);
				saveSettings();
				appendAddTabButton();
			},"+","ivory","black","12px")
			.attr({"class":"JRMButton hasHelptip","title":"Click to add a new tab. You will have the option to label it to the name you want."})
			.tooltip({ show: {delay:1000} })
			.css({"margin":"5px 0 0 4px","padding":"3px"}))
		.attr("id","addNewtab")
		.css({"padding":"8px 8px 0 0","height":"10px"}));
}
function createMenuButtons(buttonName,appendToControl,tipHelp,doThis,doToggleButton,doActiveMenu) {
	doActiveMenu = doActiveMenu || false;
	var classList = (tipHelp==="") ? "" : "hasHelptip";
	var spanReturn = createSpan().append(createSpanButton(function(e) { checkDelayedSave();
		if (doActiveMenu) activeMenu(gMainMenu,buttonName);
		if (doThis) {
            if (doToggleButton && !doActiveMenu) toggleButton($(e.target),function(theNumber,thisButton) { doThis(thisButton); },null);
			else doThis($(e.target));
		}
	},buttonName,"ivory","black","12px").attr({"class":classList,"title":tipHelp})).css({"margin":"10px 0"}).appendTo(appendToControl);
	return spanReturn;
}
function cycleButtonSelect(thisNumber) {
	$(".JRCycleButton span").css({"background-color":gButtonOffBgColor,"color":gButtonOffColor});
	$("#JRCycle" + thisNumber + "Button span").css({"background-color":gButtonOnBgColor,"color":gButtonOnColor});
	theCycler.cycleResetChange((thisNumber=="1") ? gMainOptions.cycleNumber : (thisNumber=="2") ? gMainOptions.cycleNumber2 : gMainOptions.cycleNumber3);
	gMainOptions.savedCycleNum = thisNumber;
	displayMainStatus();
}
function startPandaCrazy() {
    gMainData.queueStatus = makeStatus();
    var panels = createPanels("body").css({"height":"auto"});
    var northPanel = createPanel("body");
    northPanel.addClass("ui-layout-north");
    var mainControls = createDiv().appendTo(northPanel);
    mainControls.css({"background-color":"aliceblue","font-size":"10px","color":"midnightblue","padding":"5px 4px",
                   "border-color":"black", "border-width":"2px", "border-style":"groove"});
    createSpan("Vol: ").appendTo(mainControls);
    createSpan().attr("id","JRVolumeControl").css({"display":"inline-block","width":"80px","margin":"3px 8px 0px 2px"})
        .slider({range: "min",min: 0,max: 100,value: gMainOptions.alarmVolume,step: 5,
            stop: function(event, ui) {
                gMainOptions.alarmVolume = ui.value;
                gSoundFile.volume = gMainOptions.alarmVolume/100;
				playThisSound("less2");
            }
        })
        .appendTo(mainControls);
	addToWaitDialog("Setting up Menu.",true);
    setTimeout( function() {
        var theMenuArea = createSpan().attr("id","menuArea").appendTo(mainControls);
        var mainMenuControls = createSpan().appendTo(theMenuArea).attr("id","JrMainMenuControls").css({"margin":"10px 0"});
        addToMenu(gMainMenu,"Main",mainMenuControls);
        var jobsMenuControls = createSpan().appendTo(theMenuArea).attr("id","JrJobsMenuArea").css({"margin":"10px 0"});
        addToMenu(gMainMenu,"Jobs",jobsMenuControls);
        var displayMenuControls = createSpan().appendTo(theMenuArea).attr("id","JrDisplayMenuArea").css({"margin":"10px 0"});
        addToMenu(gMainMenu,"Display",displayMenuControls);
        var groupingMenuControls = createSpan().appendTo(theMenuArea).attr("id","JrGroupingMenuArea").css({"margin":"10px 0"});
        addToMenu(gMainMenu,"Grouping",groupingMenuControls);
        var cycleMenuControls = createSpan().appendTo(theMenuArea).attr("id","JrCycleMenuArea").css({"margin":"10px 0"});
        addToMenu(gMainMenu,"Cycler",cycleMenuControls);
        var optionsMenuControls = createSpan().appendTo(theMenuArea).attr("id","JrOptionsMenuArea").css({"margin":"10px 0"});
        addToMenu(gMainMenu,"Options",optionsMenuControls);
        var helpMenuControls = createSpan().appendTo(theMenuArea).attr("id","JrHelpMenuArea").css({"margin":"10px 0"});
        addToMenu(gMainMenu,"Help",helpMenuControls);
        activeMenu(gMainMenu,"Main");

        createSpan(" | ").appendTo(mainMenuControls);

		createMenuButtons("Jobs",mainMenuControls,"Add, Export, Import jobs and options.",null,false,true);
		createMenuButtons("Main",jobsMenuControls,"Back to main menu.",null,false,true);
        createSpan(" -Jobs- ").appendTo(jobsMenuControls);
		createMenuButtons("List",jobsMenuControls,"List all jobs.",function(thisButton) { showSearchingDialog(thisButton,"jobs","all",true); },true);
		createMenuButtons("Add",jobsMenuControls,"Add Panda's to the script.",function(thisButton) { showAddJobsDialog(thisButton); },true);
		createMenuButtons("Export",jobsMenuControls,"Export options, jobs and groupings.",function(thisButton) { showExportImportDialog("Export",thisButton); },true);
		createMenuButtons("Import",jobsMenuControls,"Import options, jobs and groupings.",function(thisButton) { showExportImportDialog("Import",thisButton); },true);

		createMenuButtons("Display",mainMenuControls,"Change how big the job cells are displayed in the tabs.",null,false,true);
		createMenuButtons("Main",displayMenuControls,"Back to main menu.",null,false,true);
        createSpan(" -Display- ").appendTo(displayMenuControls);
		createMenuButtons("Minimum Info",displayMenuControls,"Show requester name, groupid #, stats and buttons.",function(thisButton) { showButtonUsed(thisButton); gMainData.displayInfo=0; refreshAllCells(); },false);
		createMenuButtons("Extended Info",displayMenuControls,"Show requester name, groupid #, pay, description, stats and buttons.",function(thisButton) { showButtonUsed(thisButton); gMainData.displayInfo=1; refreshAllCells(); },false);

		createMenuButtons("Grouping",mainMenuControls,"Turn on jobs by grouping them together.",null,false,true);
		createMenuButtons("Main",groupingMenuControls,"Back to main menu.",null,false,true);
        createSpan(" -Grouping- ").appendTo(groupingMenuControls);
		createMenuButtons("Start/Stop",groupingMenuControls,"Start or stop groupings.",function(thisButton) { showGroupingDialog("collect",thisButton); },true);
		createMenuButtons("Create By Selection",groupingMenuControls,"Create a grouping by selecting the jobs you want in it.",function(thisButton) { showGroupingCreateDialog(thisButton,[],[],"selection"); },true);
		createMenuButtons("Create Instantly",groupingMenuControls,"Create a fast grouping of all jobs collecting now.",function(thisButton) { showGroupingCreateDialog(thisButton,[],[],"collecting"); },true);
		createMenuButtons("View all",groupingMenuControls,"View all the groupings created and start or stop them.",function(thisButton) { showGroupingDialog("view",thisButton); },true);

		createMenuButtons("Cycler",mainMenuControls,"Change the cycler timer by resetting, increasing or descreasing it.",function() { $("#JRCycleInfoArea").stop(true,true).css({"color":"red"}); },false,true);
		createMenuButtons("Main",cycleMenuControls,"Back to main menu.",function() { $("#JRCycleInfoArea").animate({"color": "#191970"}, 30000); },false,true);
        createSpan(" -Cycler- ").appendTo(cycleMenuControls);
		createMenuButtons("Reset",cycleMenuControls,"Reset timer back to normal.",function(thisButton) { showButtonUsed(thisButton); theCycler.skippingReset(); displayMainStatus(); },true);
		createMenuButtons("1",cycleMenuControls,"Use 1st cycle timer.",function(thisButton) { cycleButtonSelect("1"); },false).attr({"id":"JRCycle1Button","class":"JRCycleButton"});
		createMenuButtons("2",cycleMenuControls,"Use 2nd cycle timer. (for running with other scripts)",function(thisButton) { cycleButtonSelect("2"); },false).attr({"id":"JRCycle2Button","class":"JRCycleButton"});
		createMenuButtons("3",cycleMenuControls,"use 3rd cycle timer. (for running with other scripts)",function(thisButton) { cycleButtonSelect("3"); },false).attr({"id":"JRCycle3Button","class":"JRCycleButton"});
		createMenuButtons("Increase",cycleMenuControls,"Add time to timer for less request errors.",function(thisButton) { showButtonUsed(thisButton); theCycler.cycleIncrease(); displayMainStatus(); },true);
		createMenuButtons("Decrease",cycleMenuControls,"Decrease time to timer when finished working from queue.",function(thisButton) { showButtonUsed(thisButton); theCycler.cycleDecrease(); displayMainStatus(); },true);
		createMenuButtons("Add " + gMainOptions.cycleAdding,cycleMenuControls,"Add a large amount of time to timer so it's easier to work from queue.",function(thisButton) {
			showButtonUsed($(e.target)); theCycler.cycleAdd(gMainOptions.cycleAdding); displayMainStatus(); },true);
		createMenuButtons("Edit Cycle Timers",cycleMenuControls,"Change the timers used to grab jobs.",function(thisButton) { showEditTimersDialog("Timers",thisButton); },true);
		createMenuButtons("Help",cycleMenuControls,"Find out what cyclers are and how to use them efficiently.",function(thisButton) { showHelpDialog("cycler","What is a cycler and how do I use it?",thisButton); },true);
		createMenuButtons("1",mainMenuControls,"Use 1st cycle timer: " + gMainOptions.cycleNumber + "ms",function(thisButton) { cycleButtonSelect("1"); },false).attr({"id":"JRCycle1Button","class":"JRCycleButton"});
		createMenuButtons("2",mainMenuControls,"Use 2nd cycle timer: " + gMainOptions.cycleNumber2 + "ms\n(for running with other scripts)",function(thisButton) { cycleButtonSelect("2"); },false).attr({"id":"JRCycle2Button","class":"JRCycleButton"});
		createMenuButtons("3",mainMenuControls,"use 3rd cycle timer: " + gMainOptions.cycleNumber3 + "ms\n(for running with other scripts)",function(thisButton) { cycleButtonSelect("3"); },false).attr({"id":"JRCycle3Button","class":"JRCycleButton"});
		cycleButtonSelect("1");

		createMenuButtons("Options",mainMenuControls,"Change timers, alarms and other options.",null,false,true);
		createMenuButtons("Main",optionsMenuControls,"Back to main menu.",null,false,true);
        createSpan(" -Options- ").appendTo(optionsMenuControls);
		createMenuButtons("Timers",optionsMenuControls,"Change cycler, queue and other timers to make it faster or slower.",function(thisButton) { showEditTimersDialog("Timers",thisButton); },true);
		createMenuButtons("Alarms",optionsMenuControls,"Change the alarm alerts to any sound file and times to alert.",function(thisButton) { showAlarmsDialog("Alarms",thisButton); },true);
		createMenuButtons("General",optionsMenuControls,"Change some general options for the script to work.",function(thisButton) { showEditOptionsDialog("Options",thisButton); },true);
		createMenuButtons("Stop Auto Slowdown",optionsMenuControls,"Stop script from slowing down automatically. (Beware this may cause many requester errros)",function(thisButton) {
			toggleButton(thisButton, function() { gSlowDownAuto=false; }, function() { gSlowDownAuto=true; } );
			if (thisButton.data("status") == "on") thisButton.css({"background-color":"red"}); },false);

		createMenuButtons("Help",mainMenuControls,"Find help and tips for the script to be used efficiently.",null,false,true);
		createMenuButtons("Main",helpMenuControls,"Back to main menu.",null,false,true);
        createSpan(" -Help- ").appendTo(helpMenuControls);
		createMenuButtons("About Script",helpMenuControls,"Find out more about the script that you never thought you needed.",function(thisButton) { showHelpDialog("about","About this script and how to use it efficiently.",thisButton); },true);
		createMenuButtons("Cycler",helpMenuControls,"Find out what a cycler is and how to use them efficiently.",function(thisButton) { showHelpDialog("cycler","What is a cycler and how do I use it?",thisButton); },true);
		createMenuButtons("Jobs",helpMenuControls,"Find out what a job is and hot use it efficiently.",function(thisButton) { showHelpDialog("jobs","What is a job and what can I do with it?",thisButton); },true);
		createMenuButtons("Job Details",helpMenuControls,"Find out what the options in the details section mean.",function(thisButton) { showHelpDialog("jobDetails","What are the other options I can use with jobs?",thisButton); },true);
		createMenuButtons("Go Ham",helpMenuControls,"Find out what Go Ham is and how it can help you get hits faster.",function(thisButton) { showHelpDialog("goHam","What is Go Ham and does it really taste like ham?",thisButton); },true);
		createMenuButtons("Groupings",helpMenuControls,"Find out how to group jobs together so you can start and stop jobs at same time.",function(thisButton) { showHelpDialog("groupings","How do I use groupings and what are they?",thisButton); },true);
		createMenuButtons("Tabs",helpMenuControls,"Find out how to use the tabs.",function(thisButton) { showHelpDialog("tabs","What can I do with the tabs?",thisButton); },true);
		createMenuButtons("Options",helpMenuControls,"Find out about all the options you can change and why you would want to.",function(thisButton) { showHelpDialog("options","What can I do with all these options?",thisButton); },true);
		createMenuButtons("Status Text",helpMenuControls,"Find out about the status text at the top and what it all means.",function(thisButton) { showHelpDialog("statustext","What are the stats at the top mean?",thisButton); },true);

        var mainStatus = createDiv().appendTo(northPanel).attr("id","JrMainStatus");
        mainStatus.css({"background-color":"aliceblue","font-size":"12px","color":"#191970","font-weight":"bold","padding":"5px 5px",
                       "border-color":"black", "border-width":"2px", "border-style":"groove"});
        createSpan().attr({"id":"JRJobsArea","class":"JRStatusText","title":"Click to list all jobs running."})
			.data("mode","Jobs")
			.click( function(e) { checkDelayedSave();
				showSearchingDialog(null,"jobs",(gMainData.jobs===0) ? "all" : "collecting",true);
			}).appendTo(mainStatus);
        createSpan().attr({"id":"JRCycleInfoArea","class":"JRStatusText","title":"Click to Show Elapsed Time, Cycle Time, Added Time for Slow Down or Min Ham Cycle Time."})
			.data("mode","Elapsed")
            .click( function(e) { checkDelayedSave();
                var theMode = $(e.target).data("mode");
                $(e.target).data("mode", (theMode=="Elapsed") ? "Cycle" : (theMode=="Cycle") ? "CycleSkipping" : (theMode=="CycleSkipping") ? "Hamcycle" : "Elapsed")
                    .stop(true,true).css({"color":"red"}).animate({"color": "#191970"}, 30000);
                displayMainStatus();
            }).css({"cursor":"pointer"}).appendTo(mainStatus);
        createSpan().attr({"id":"JRResultAccSkipArea","class":"JRStatusText","title":"Click to Show Accepted, Missed, Skipped or total searched Hits."})
			.data("mode","Accepted")
            .click( function(e) { checkDelayedSave();
                var theMode = $(e.target).data("mode");
                $(e.target).data("mode", (theMode=="Accepted") ? "Searched" : (theMode=="Searched") ? "Missed" : (theMode=="Missed") ? "Skipped" : "Accepted")
					.stop(true,true).css({"color":"red"}).animate({"color": "#191970"}, 30000);
                displayMainStatus();
            }).css({"cursor":"pointer"}).appendTo(mainStatus);
        createSpan().attr({"id":"JRErrorArea","class":"JRStatusText","title":"Click to Show Number of Page Request Errors or other Error."})
			.data("mode","TooFast")
            .click( function(e) { checkDelayedSave();
                var theMode = $(e.target).data("mode");
                $(e.target).data("mode", (theMode=="TooFast") ? "Errors" : "TooFast").stop(true,true).css({"color":"red"}).animate({"color": "#191970"}, 30000);
                displayMainStatus();
            }).css({"cursor":"pointer"}).appendTo(mainStatus);
        createSpan().attr({"id":"JRPayArea","class":"JRStatusText","title":"Click for Payment for accepted hits or Projected Earnings from dashboard. Must have helper script and a script that shows projected earnings on the dashboard."})
			.data("mode","PayAccepted")
			.click( function(e) { checkDelayedSave();
                var theMode = $(e.target).data("mode");
                $(e.target).data("mode", (theMode=="PayAccepted") ? "Projected" : "PayAccepted")
                    .stop(true,true).css({"color":"red"}).animate({"color": "#191970"}, 30000);
                displayMainStatus();
			}).css({"cursor":"pointer"}).appendTo(mainStatus);
        var centerPanel = createPanel("body");
        centerPanel.addClass("ui-layout-center");
        var theControls = createDiv().attr("id","JRTheControls").appendTo(centerPanel);
        theControls.css({"background-color":"aliceblue","font-size":"10px","color":"midnightblue","padding":"5px 4px",
                       "border-color":"black", "border-width":"2px", "border-style":"groove"});
        createSpanButton(function(e) { checkDelayedSave();
            if (theCycler.isPaused()) { theCycler.unpause(); $(e.target).html("Pause").css({"background-color":"ivory","color":"black"}); }
            else { theCycler.pause(); $(e.target).html("Resume").css({"background-color":"red","color":"white"}); }
        },"Pause","ivory","black","12px").attr({"class":"JRMButton hasHelptip","id":"JRPauseButton","title":"Pause collecting all pandas and other hits until clicking this button again."})
			.appendTo(theControls);
        createSpanButton( function(e) { checkDelayedSave();
            toggleButton($(e.target),function(theNumber,thisButton) { showGroupingDialog("start",thisButton); },null);
        },"Start Group","ivory","black","12px").attr({"class":"JRMButton hasHelptip","title":"Start collecting all hits in a grouping which you create in the grouping menu."}).appendTo(theControls);
        createSpanButton( function(e) { checkDelayedSave(); stopAll(); },"Stop All","ivory","black","12px")
			.attr({"class":"JRMButton hasHelptip","title":"Stop collecting all pandas NOW. The script will basically be turned off until you collect a hit again."}).appendTo(theControls);
        createSpanButton( function(e) { checkDelayedSave();
            toggleButton($(e.target),function(theNumber,thisButton) { showAddJobsDialog(thisButton); },null);
        },"Add Job","ivory","black","12px").attr({"class":"JRMButton hasHelptip","title":"Add a new panda to the current tab."}).appendTo(theControls);
        createSpan(" - ").appendTo(theControls);
        createSpanButton( function(e) { checkDelayedSave();
            showButtonUsed($(e.target)); theCycler.skippingReset(); displayMainStatus();
        },"Reset Timer","ivory","black","12px").attr({"class":"JRMButton hasHelptip","title":"Reset the timer back to default if elapsed time is too high."}).appendTo(theControls);
        createSpanButton( function(e) { checkDelayedSave();
            toggleButton($(e.target),function(theNumber,thisButton) {
				showWaitDialog("Saving Database....","",function() {},thisButton);
				setTimeout( function() { saveSettings();
					appendToWaitDialog(createDiv("Database Saved.<br>You may close this dialog.").css({"font-size":"18px","margin-top":"30px","text-align":"center"}));
				}, 500);
            },null);
        },"Save","ivory","black","12px")
			.attr({"class":"JRMButton hasHelptip","title":"Save all jobs, tabs, options and groupings. The script usually will save this stuff as you add or change stuff but some things it will only save when there is user interaction."}).appendTo(theControls);
        createSpanButton( function(e) { checkDelayedSave();
            toggleButton($(e.target),function(theNumber,thisButton) { showSearchingDialog(thisButton,"jobs","all",true); },null);
        },"Search Jobs","ivory","black","12px").attr({"class":"JRMButton hasHelptip","title":"Search through jobs you have saved."}).appendTo(theControls);
        createSpanButton( function(e) { checkDelayedSave();
            toggleButton($(e.target),function(theNumber,thisButton) { showSearchingDialog(thisButton,"mturk"); },null);
        },"Search Mturk","ivory","black","12px").attr({"class":"JRMButton hasHelptip","title":"Search through Mturk.com for hits."}).appendTo(theControls);
		addToWaitDialog("Setting up tabs.",true);
        setTimeout( function() {
            var mainTabs = createTabs(centerPanel,true,"JRMainTabs").css({"overflow":"hidden"}).show();
            if (gTabsData[0].positions === null) fillInPositions();
            var firstTab = true;
            $.each(gTabsData, function( index, value ) {
				addTab(mainTabs,value.tabName,true,"JRTab_" + value.tabNumber,value,!firstTab).css({"overflow":"visible"});
				if (firstTab) firstTab = false;
            });
			appendAddTabButton();

            var southPanel = createPanel("body");
            southPanel.addClass("ui-layout-south");
            var logTabs = createTabs(southPanel,true,"JRStatusTabs");
            gAcceptedLogTab = addTab(logTabs,"Accepted",false,"JRStatusTab_0",null,false);
            gStatusLogTab = addTab(logTabs,"Status log",false,"JRStatusTab_1",null,false);
            gQueueWatchTab = addTab(logTabs,"Queue Watch",false,"JRStatusTab_2",null,false);
            createDiv().appendTo(gAcceptedLogTab)
                .attr({"id":"JRAcceptedLog","class":"JRContents"}).css({"background-color":"black","overflow":"auto","color":"white","font-size":"9px"});
            createDiv().appendTo(gStatusLogTab)
                .attr({"id":"JRStatusLog","class":"JRContents"}).css({"background-color":"black","overflow":"auto","color":"white","font-size":"9px"});
            createDiv().appendTo(gQueueWatchTab)
                .attr({"id":"JRQueueWatchLog","class":"JRContents"}).css({"background-color":"black","overflow":"auto","color":"white","font-size":"9px"}).click( function() {
					checkDelayedSave();
					theCycler.frontOfTheLineTimer(-1);
				});
            logTabs.tabs("option", "active", 2);
			addToWaitDialog("Creating Panda Cells.",true);
            setTimeout( function() {
                fillTabs();
                mainTabs.tabs("option", "active", 0);
                gMyLayout = $('body').layout({
                    center__onresize: function() {
                        var newHeight = $(".ui-layout-south").innerHeight() - 35;
                        gStatusLogTab.find("div.JRContents").css({"height":newHeight});
                        gAcceptedLogTab.find("div.JRContents").css({"height":newHeight});
                        gQueueWatchTab.find("div.JRContents").css({"height":newHeight});
						var mainTabsHeight = $(".ui-layout-center").innerHeight() - $("#JRTheControls").innerHeight() - 8;
						var tabContentsHeight = mainTabsHeight - $("#JRMainTabs").find(".ui-tabs-nav").innerHeight();
                        $("#JRMainTabs").css({"height":mainTabsHeight});
                        $("#JRMainTabs").find(".tabContents").css({"height":tabContentsHeight,"min-height":tabContentsHeight});
                    },
                });
                gMyLayout.sizePane("north", 65);
                gMyLayout.sizePane("south", 180);
                $("#JRStatusLog").css({"height":$(".ui-layout-south").innerHeight() - 35});
                $("#JRAcceptedLog").css({"height":$(".ui-layout-south").innerHeight() - 35});
                $("#JRQueueWatchLog").css({"height":$(".ui-layout-south").innerHeight() - 35});
                theCycler.cycleResetChange(gMainOptions.cycleNumber);
                gNotifications = checkNotifications();
                displayMainStatus();
				addToWaitDialog("Display is done.<br>Starting up script.",true);
                setTimeout( function() {
                    $("#JRWaitDialog").dialog("close");
					$(".JRStatusText").tooltip({ show: {delay:680} });
					$(".hasHelptip").tooltip({ show: {delay:1000} });
					helpToolTips();
					addQueueCheck();
					$( document ).keydown(function( event ) {
					  if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
						$( ".tabContents" ).sortable( "cancel" );
					  }
					});
				},1000);
            },10);
        },10);
    },10);
}
function continueLoading() {
	addToWaitDialog("Creating UI Display.",true);
    setTimeout( function() {
        startPandaCrazy();
    },10);
}

$("body").html("").css("height",screen.height-310);
startMessageListener();
$(function() {
	if (gLocation.indexOf("&resetalldata=yes") != -1) gResetAllData = true;
	document.title = "JR Panda Crazy [" + gScriptVersion + "] for Mturk.com";
    createEditDialog();
    createWaitDialog();
    createYesNoDialog();
	createPromptDialog();    
	showWaitDialog("Please wait. Loading....","Setting up Panda Crazy!");
    setTimeout( function() {
        var nowDate = new Date();
        console.log(formatTimeZone("onlydate",nowDate,"mturk"));
		addToWaitDialog("Loading settings in memory.",true);
        setTimeout( function() {
            loadSettings();
        },10);
    },10);
	window.onbeforeunload = function() { checkDelayedSave(); stopAll(); };
});

/*jshint multistr: true */
GM_addStyle(jqUI_CssSrc);
GM_addStyle(jqLayout_CssSrc);
GM_addStyle( " \
    body, input, select, td, li, div, textarea, p { font-size:11px; line-height: 14px; font-family:verdana,arial,sans-serif; } \
    .sortable-placeholder { height: 1.5em; line-height: 1.2em; background-color:burlywood; } \
    .ui-state-highlight { height: 1.5em; line-height: 1.2em; } \
    .editLine { padding: 2px 0; } \
    .editLine span { font-weight: bold; } \
    .ui-tooltip { white-space: pre-line; font-size:16px !important; max-width: 400px; width:500px; color:darkblue; } \
    .ui-tooltip-content { max-width: 400px; font-size:16px !important; line-height:17px !important; } \
    .ui-dialog.notmodal { border: 3px solid #000; } \
    .no-close .ui-dialog-titlebar-close { display: none; } \
    .ui-button .ui-state-default, .ui-button .ui-state-hover { color: black !important; } \
    .ui-state-hover .ui-icon1, .ui-state-focus .ui-icon1 { background-image: none !important; } \
	.ui-state-active .ui-tabs-anchor, .ui-tabs-active .ui-tabs-anchor { color: #000000 !important; } \
    .ui-state-active .ui-state-hover a, .ui-state-active .ui-state-hover a:link, .ui-state-focus .ui-state-hover a, .ui-state-focus .ui-state-hover a:link	{ \
		color: #FFFFFF !important; \
	} \
	.ui-icon, .ui-widget-content .ui-icon { \
		background-image: url('https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/themes/pepper-grinder/images/ui-icons_222222_256x240.png'); \
	} \
    .ui-state-focus a, .ui-widget-content .ui-state-focus a, .ui-widget-header .ui-state-focus a  { color: #FFFFFF !important; } \
    .ui-state-hover a, .ui-widget-content .ui-state-hover a, .ui-widget-header .ui-state-hover a  { color: #FFFFFF !important; } .ui-state-active .ui-icon1 { \
         background-image: none !important; \
    } \
    .ui-state-default .ui-icon { \
        background-image: url('https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/themes/pepper-grinder/images/ui-icons_b83400_256x240.png') !important; \
    } \
    .ui-widget-content { background: #eceadf none 50% 50% repeat !important; } \
	.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { background: #f8f7f6 none 50% 50% repeat !important; } \
	.ui-widget-content .ui-icon1 { background-image: none !important; } \
	.ui-widget-header { background: #ffffff none 50% 50% repeat !important; } \
	#JREditDialog div { margin-top: 5px; } \
	.hitRow { margin-top: 0 !important; } \
	.JREditRadioB.ui-button-text-only.ui-state-focus { background: #f8f7f6 none 50% 50% repeat !important; padding: 0 3px 0 2px; } \
	.JREditRadioB.ui-button-text-only.ui-state-active, .JREditRadioB.ui-button-text-only.ui-state-focus.ui-state-hover { \
		color: #FFFFFF !important; background: #654b24 none 50% 50% repeat !important; \
	} \
	.JREditRadioB.ui-button-text-only .ui-button-text { color: #000000; padding: .1em .4em; } \
	.JREditRadioB.ui-button-text-only.ui-state-hover .ui-button-text { color: #FFFFFF !important; } \
	.JREditRadioB.ui-button-text-only.ui-state-active .ui-button-text { color: #FFFFFF !important; } \
	.ui-widget-overlay { background: #6e4f1c none 50% 50% repeat !important; } \
	.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { \
		color: #140f06; background: #eceadf none 50% 50% repeat !important; \
	} \
	.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, \
	.ui-widget-header .ui-state-focus { background: #654b24 none 50% 50% repeat !important; } \
    #JRMainTabs li .ui-icon-close { float: left; margin: 0.4em 0.2em 0 0; cursor: pointer; } \
    #JRStatusTabs li .ui-icon-close { float: left; margin: 0.4em 0.2em 0 0; cursor: pointer; } \
	a.JRQueueReturn:link, a.JRQueueContinue:link { color: #3399FF; } \
	a.JRQueueReturn:visited, a.JRQueueContinue:visited { color: #6633FF; } \
	.hitRow .aHitColumn { display: inline-block; padding: 1px 5px; white-space: nowrap; border: 1px solid black; overflow: hidden; } \
");