// ==UserScript==
// @name JR Mturk Panda Crazy
// @version 0.2.2
// @description Collects pandas for you at a certain cycle instead of timers. Lot of organizing of pandas and grouping them together to start and stop them at once.
// @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
// @connect *
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_deleteValue
// @grant GM_addStyle
// @grant GM_xmlhttpRequest
// @grant GM_getResourceText
// @grant GM_setClipboard
// @namespace https://gf.qytechs.cn/users/6406
// ==/UserScript==
var gScriptVersion = "0.2.2";
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 = "";
var gMyLayout = null, gAcceptedLogTab = null, gStatusLogTab = null, gQueueWatchTab = null, mCoinSound = [];
var gMainData = {"hitCollection":{},"displayInfo":"1","goToUrl":[],
"accepted":0,"skipped":0,"errors":0,"searched":0,"noHits":0,"fullQueue":0,"orphan":0,"tooFast":0,
"hitsInQueue":0,"queueStatus":null,"notQual":0,"lastElapsed":0,"jobs":0,"payCounter":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";
var gTitleColor="#000080", gButtonOffColor="black", gButtonOnColor="white", gButtonDisabledColor="#808080";
var gHitMutedBorderStyle="dotted", gHitBorderStyle="solid";
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"},
"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"},
"less5":{"nameVar":"JR_PANDA_Soundless5","default":"http://tiny.cc/g7h1ay","audio":null,"desc":"Hits paying less than |: ","payRate":"0.05","lessMinutes":"99"},
"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"},
"less15":{"nameVar":"JR_PANDA_Soundless15","default":"http://tiny.cc/qai1ay","audio":null,"desc":"Hits paying less than |: ","payRate":"0.15","lessMinutes":"99"},
"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"},
"less99":{"nameVar":"JR_PANDA_Soundless99","default":"http://tiny.cc/gbi1ay","audio":null,"desc":"Hits paying MORE than |: ","payRate":"0.15","lessMinutes":"99"},
"fullQueue":{"nameVar":"JR_PANDA_FullQueue","default":"http://tiny.cc/wietby","audio":null,"desc":"You have a full queue!","payRate":"","lessMinutes":"99"},
"queueAlert":{"nameVar":"JR_PANDA_QueueAlert","default":"http://tiny.cc/cnxyby","audio":null,"desc":"Hit in queue is less than 5 minutes.","payRate":"","lessMinutes":"99"},
};
var gLastAlarm = "";
var gSoundFile = null;
var gTabIndex = 0;
var gMouseDownTimeoutId = null;
var gPressAndHold = false;
var gQueueData = [];
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":970,"HamCycleNumber":700,"autoSlowDown":true,"cycleAutoIncrease":5,"alarmVolume":80,"cycleIncrease":5,"cycleDecrease":5,"cycleAdding":650,"queueTimer":40000,"hamDelayTimer":20,"showHelpTooltips":true};
var gRequestersData = {};
var jobDataDefault = {"requesterName":"","requesterId":"","groupId":"","pay":"","title":"","duration":"0","hitsAvailable":0,"timeLeft":"","continueURL":"","returnURL":""};
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},
"4":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"30B721SJLR5BYYBNQJ0CVKJESN00OC","pay":"0.01","qual":"ibotta","title":"Are these the same?","queueLimit":15,"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":0},
"5":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"30B721SJLR5BYYBNQJ0CVKJEQOZ0OB","pay":"0.01","qual":"","title":"Are these the same?","queueLimit":15,"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":0},
"6":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"3ZXRRTK2NDCB5NW5M24C9P2OWG41OF","pay":"0.01","qual":"ibotta","title":"Does this receipt contain the following products?","queueLimit":8,"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":0},
"7":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"3NYGPW9OTYRQLJTE9DQJQJRQJ2IZPS","pay":"0.01","qual":"","title":"Does this receipt contain the following products?","queueLimit":8,"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":0},
"8":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"3R35RPFD7JUTQN8612HRYP7E6LZ1PV","pay":"0.03","qual":"ibotta","title":"Does this receipt contain the following products?","queueLimit":8,"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":0},
"9":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"3ZXRRTK2NDCB5NW5M24C9P2OVF61OE","pay":"0.03","qual":"","title":"Does this receipt contain the following products?","queueLimit":8,"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":0},
"10":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"3CRC4NO2BIQQWQ3GX0HLFPTFOD30SA","pay":"0.05","qual":"ibotta","title":"Does this receipt contain the following products?","queueLimit":12,"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":0},
"11":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"3787DLY3Y49RIF1DIJQB3Z8BUNP1T2","pay":"0.05","qual":"","title":"Does this receipt contain the following products?","queueLimit":12,"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":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},
"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},
"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},
"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},
"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},
"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},
"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},
"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},
"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},
"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},
"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}
};
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) {
var tempArray = (theTime.indexOf("seconds") != -1) ? theTime.split("seconds")[0].trim().split(" ") : null;
var seconds = (tempArray) ? tempArray[tempArray.length-1] : "0";
tempArray = (theTime.indexOf("minute") != -1) ? theTime.split("minute")[0].trim().split(" ") : null;
var minutes = (tempArray) ? tempArray[tempArray.length-1] : "0";
tempArray = (theTime.indexOf("hour") != -1) ? theTime.split("hour")[0].trim().split(" ") : null;
var hours = (tempArray) ? tempArray[tempArray.length-1] : "0";
return( {"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 ) {
var n = new Notification(title, {
body: message,
icon: "http://www.allbyjohn.com/mturk/Messaging-Online-icon.png",
tag: tag});
if (navigator.userAgent.search("Chrome") >= 0) n.onshow = function () { setTimeout(n.close.bind(n), 20000); }
}
// Database using setValue and getValue
function convertDatabase(theDataBase) {
var newDataBase = {};
$.each(theDataBase, function( index, value ) {
newDataBase[index] = value;
});
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 loadSoundFiles(soundNumber,keyArray) {
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);
console.log("JR reset version: " + resetDBVersion + " | new reset version: " + gResetDBVersion);
var gotBase64 = GM_getValue(gAlarmSounds[keyArray[soundNumber]].nameVar,null);
this.firstTime = this.firstTime || false;
if (gotBase64 === null) {
if (!this.firstTime) $("#JRWaitDialog").append(createDiv("For your first time this might take a few seconds.<br>Loading Alarms ").attr({"class":"alarmsLoad"}));
this.firstTime = true;
requestUrl(gAlarmSounds[keyArray[soundNumber]].default,0,function(theResult,theNumber,data1,data2) {
$("#JRWaitDialog .alarmsLoad").append(createSpan(" ."));
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);
},function() { errorRequest(); }, "", "", "arraybuffer");
} else {
gAlarmSounds[keyArray[soundNumber]].audio = new Audio("data:audio/wav;base64," + JSON.parse(gotBase64));
loadSoundFiles(soundNumber+1,keyArray);
}
} 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 loadSettings() {
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();
loadSoundFiles(0,Object.keys(gAlarmSounds));
}
function fillInSoundOptions(soundOptions) {
$.each(soundOptions, function( index, value ) {
gAlarmSounds[index].payRate = value.payRate;
gAlarmSounds[index].lessMinutes = value.lessMinutes;
});
}
function setupSoundOptions() {
var soundOptions = {};
$.each(gAlarmSounds, function( index, value ) {
soundOptions[index] = {"payRate":value.payRate,"lessMinutes":value.lessMinutes};
});
return soundOptions;
}
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) {
var theStatus = $(thisButton).data("status");
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) {
$(thisButton).data("status","off");
updateHitColors($(thisButton).data("theNumber"),thisButton);
if (doThisOff) doThisOff($(thisButton).data("theNumber"),thisButton);
}
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("status","off")
.data("backgroundColor",backgroundColor)
.data("textColor",textColor)
.data("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");
$(currentTab).find(".JRHitDummy").remove();
$(mainAriaTab).find(".JRHitDummy").remove();
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);
$(mainAriaTab).find(".tabContents").append(createDiv(" ").attr("class","JRHitCell JRHitDummy").data("hitInfo",{"tabIndex":0}).css({"height":"160px","width":"200px"}));
saveSettings();
$("#JRMainTabs").tabs( "refresh" );
}
});
if (isSortable) tabList.sortable({placeholder:"sortable-placeholder",delay:300,"items":"li:not(.ui-not-sortable)",dropOnEmpty: true});
return tabsContainer;
}
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})
.bind("contextmenu", function(e) {
if ($(e.target).closest("li").index() > 0) {
var returnName = prompt("Enter Tab Label : ", $(e.target).html());
if (returnName) {
$(e.target).html(returnName);
$(e.target).closest("li").data("tabData").tabName = returnName;
saveSettings();
}
}
e.preventDefault();
return false;
})
.appendTo( tabContainer.find("ul") );
if (appendClose) theTabLi.append(createSpan("Remove Tab").attr({"class":"ui-icon ui-icon-close","role":"presentation"}));
theTabDiv.data({"tabData":tabData}).appendTo(tabContainer);
if (isSortable) {
theTabLi.click( function() { $(this).focus(); $(this).find(".tabContents").focus(); })
.droppable({
tolerance: 'pointer',
over: function( event, ui ) {
$("#JRMainTabs").tabs("option", "active", $(event.target).index());
$(event.target).focus(); $(event.target).find(".tabContents").focus();
}
});
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 thaty handles all timers, queues, pauses, and hams
var theCycler = (function() {
var privateVars = {
_timers: [],
_theQueue: [],
_theEveryCycle: [],
_theFrontOfTheLineQueue: [],
_theFrontOfTheLineTimer: [],
_before: new Date(),
_theCycle: 500,
_realCycle: 500,
_theCycleElapsed: 0,
_theCycleSkipping: 0,
_paused: false,
_hamNumber: 0,
_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].theNumber == theNumber) 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 (frontOfTheLineItem) {
frontOfTheLineItem.runFunction.apply("frontoftheline",[frontOfTheLineItem.elapsed,frontOfTheLineItem.theNumber] );
return true;
} else return false;
},
_goFrontOfTheLine: function() {
var frontOfTheLineNumber = privateVars._theFrontOfTheLineQueue.shift();
var frontOfTheLineItem = privateFunctions._removeFromQueue(frontOfTheLineNumber);
if (frontOfTheLineItem) {
privateVars._theQueue.push(frontOfTheLineItem);
frontOfTheLineItem.runFunction.apply("frontoftheline",[privateVars._theCycleElapsed,frontOfTheLineItem.theNumber] );
return true;
} else return false;
},
_goHam: function() {
var hamCalled = false;
var foundNumber = privateFunctions._checkInQueue(privateVars._hamNumber);
if (foundNumber != -1) {
hamCalled = privateVars._theQueue[foundNumber].runFunction.apply("goham",[privateVars._theCycleElapsed,privateVars._hamNumber] );
}
return hamCalled;
},
_doTimers: function() {
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].miliSeconds) {
var 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;
var firstNumber = privateVars._theQueue[0].theNumber;
do {
var queueItem = privateVars._theQueue.shift();
if (!queueItem.doOnce) privateVars._theQueue.push(queueItem);
skipThis = !queueItem.runFunction.apply("queue",[privateVars._theCycleElapsed,queueItem.theNumber] );
} while (privateVars._theQueue.length > 0 && skipThis && firstNumber != privateVars._theQueue[0].theNumber);
},
_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._hamNumber != 0) { continueCheck = false; privateFunctions._goHam(); }
if (continueCheck && privateVars._theQueue.length>0) {
privateFunctions._doQueue();
}
}
privateVars._timeoutVar = setTimeout(privateFunctions._theLoop, 0);
}
}
var output = {
addJob: function(func, theNumber, miliSeconds, doOnce) {
if (typeof func === 'function' && !isNaN(miliSeconds)) {
doOnce = doOnce || false;
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, 'miliSeconds': miliSeconds, 'cycleCounter': 0, 'elapsed': miliSeconds, 'doOnce': doOnce};
if (miliSeconds == 0) privateVars._theQueue.unshift(jobData);
else if (miliSeconds > 0) privateVars._timers.unshift(jobData);
}
if (privateVars._timeoutVar===null) privateFunctions._theLoop();
},
removeJob: function(theNumber) {
var returnValue = false;
privateFunctions._removeFromQueue(theNumber);
for (var i=0, len=privateVars._timers.length; i<len; i++) {
if (privateVars._timers[i].theNumber == theNumber) {
privateVars._timers.splice(i, 1);
returnValue=true;
break;
}
}
if (privateVars._theQueue.length == 0 && privateVars._timers.length == 0) privateVars._timeoutVar = null;
return returnValue;
},
pause: function() {
privateVars._paused = true;
clearTimeout(privateVars._timeoutVar);
},
isPaused: function() { return privateVars._paused; },
unpause: function() {
privateVars._paused = false;
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); },
hamOn: function( theNumber ) { privateVars._hamNumber = theNumber; },
hamOff: function() { privateVars._hamNumber = 0; },
isHamOn: function() { return (privateVars._hamNumber>0) ? 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 += increaseNumber;
privateVars._realCycle += increaseNumber;
},
cycleDecrease: function() {
privateVars._theCycleSkipping = (privateVars._theCycleSkipping > 0)
? privateVars._theCycleSkipping -= gMainOptions.cycleDecrease : 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,"Cycle")) {
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("");
$("#JRMturkQueueArea").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 + " | " : "";
$("#JRResultAccSkipArea").html(theAccSkip);
theMode = $("#JRErrorArea").data("mode");
var theErrors = (theMode=="Errors") ? "Errors: " + gMainData.errors + " | " :
(theMode=="TooFast") ? "Too Fast: " + gMainData.tooFast + " | " : "";
$("#JRErrorArea").html(theErrors);
$("#JRMturkQueueArea").html("Mturk Queue: " + ((parseInt(gMainData.hitsInQueue)<25) ? gMainData.hitsInQueue : "Full") + " | ");
$("#JRSearchedArea").html("Searched: " + gMainData.searched + " | ");
$("#JRPayArea").html("Pay Accepted: " + gMainData.payCounter.toFixed(2) + " ]");
}
}
function displayQueueStatus() {
addToQueueWatchLog("",true);
var lessThanAlarm = false;
gQueueData.reverse();
for (var i=0, len=gQueueData.length; i<len; i++) {
addToQueueWatchLog("(" + gQueueData[i].requesterName + ") [$" + gQueueData[i].pay + "] - <span style='color: cyan;'>" +
gQueueData[i].timeLeft + "</span> - " + gQueueData[i].title + " :: <a href='" + gQueueData[i].returnURL + "' target='_blank' class='JRQueueReturn'>Return</a>" +
":: <a href='" + gQueueData[i].continueURL + "' target='_blank' class='JRQueueContinue'>Continue work</a>");
var theTimeLeft = getTimeLeft(gQueueData[i].timeLeft);
if (!lessThanAlarm && theTimeLeft.hours < 1 && theTimeLeft.minutes < 5) {
lessThanAlarm = true;
if (!$("#muteQueueWatchAlarm").is(":checked")) playThisSound("queueAlert");
}
}
$(".JRQueueReturn").click( function(e) {
e.stopPropagation();
e.preventDefault();
showYesNoDialog("Are you sure you want to return this hit?",function() { window.open($(e.target).attr("href"),"_blank"); });
});
}
function fullQueueTimer() { gFullQueue = false; }
function displayHitStatus( theNumber ) {
var hitInfo = gMainData.hitCollection[theNumber];
var hitStatus = hitInfo.status;
var statusText = "";
statusText += "[ Acc: " + hitStatus.accepted + " | Skip: " + hitStatus.skipped + " | Srch: " + hitStatus.searched + " ] ";
$("#JRCellStatus_" + theNumber).html( statusText );
displayMainStatus();
}
function processResults( theNumber, result ) {
var hitInfo = (theNumber>0) ? gMainData.hitCollection[theNumber] : null;
var hitData = (hitInfo) ? hitInfo.data : null;
var hitStatus = (hitInfo) ? hitInfo.status : null;
switch(result) {
case "NOTQUALIFIED":
if (hitStatus) hitStatus.notQual++;
gMainData.notQual++;
break;
case "NOMORE":
case "NOACCEPT":
if (hitStatus) hitStatus.noHits++;
gMainData.noHits++;
break;
case "TOOFAST":
if (hitStatus) hitStatus.tooFast++;
gMainData.tooFast++;
if (gSlowDownAuto) theCycler.cycleIncrease(gMainOptions.cycleAutoIncrease);
break;
case "LOGGEDOFF":
if (!theCycler.isPaused()) alert("You are logged out of Amazon. Can't accept hits. Please log back in");
theCycler.pause();
$("#JRPauseButton").html("Resume").css({"background-color":"red","color":"white"});
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 (hitData.hamTimer > 0) 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++;
var hitPay = parseFloat(hitData.pay);
gMainData.payCounter = Math.round( (gMainData.payCounter + 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.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");
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) {
var theResponseType = theResponseType || "";
//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 pandaLink(thegroupId) { return "https://www.mturk.com/mturk/previewandaccept?groupId=" + thegroupId; }
function previewLink(thegroupId) { return "https://www.mturk.com/mturk/preview?groupId=" + thegroupId; }
function requesterSearch(theRequester) { return "https://www.mturk.com/mturk/searchbar?selectedSearchType=hitgroups&qualifiedFor=on&sortType=Reward%3A1&requesterId=" + theRequester; }
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;
if (hitData.queueLimit == 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.dailyLimit > 0 && hitData.dailyLimit < gMainData.dailyDone) returnValue = false;
else if (hitData.queueLimit > 0 && hitData.queueLimit <= gMainData.hitsInQueue) 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");
jobData.groupId = $(titleElement).closest("tr").find(".capsulelink a").attr("href").split("groupId=")[1];
jobData.title = $(titleElement).text().trim();
var requesterElement = $(row).find(".requesterIdentity");
jobData.requesterName = $(requesterElement).text().trim();
jobData.requesterId = $(requesterElement).closest("a").attr("href").split("&requesterId=")[1];
jobData.duration = $(row).find("#duration_to_complete\\.tooltip--" + i).closest("tr").find(".capsule_field_text").text().trim();
jobData.hitsAvailable = $(row).find("#number_of_hits\\.tooltip--" + i).closest("tr").find(".capsule_field_text").text().trim();
var rewardTrTarget = $(row).find("#reward\\.tooltip--" + i).closest("tr");
jobData.pay = $(rewardTrTarget).find(".reward").text().replace("$","").trim();
jobDatas.push(jobData);
});
return jobDatas;
}
function createHitRow(theData,buttons) {
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 hitRow = createDiv().attr({"class":"hitRow"}).data("hitData",theData)
.append(createSpan(theData.requesterName).attr({"class":"aHitColumn"})
.css({"background-color":"#FBF5E6","width":"140px","text-align":"right","border":"1px solid black"}))
.append(createSpan(theData.title).attr({"class":"aHitColumn"})
.css({"background-color":"#FCF6CF","width":(dialogWidth - 450) + "px"}))
.append(createSpan(durationText).attr({"class":"aHitColumn"})
.css({"background-color":"#F5F5DC","width":"35px"}))
.append(createSpan(theData.hitsAvailable).attr({"class":"aHitColumn"})
.css({"background-color":"#F0FFFF","width":"40px"}))
.append(createSpan(payText).attr({"class":"aHitColumn"})
.css({"background-color":"#7FFFD4","width":"40px"}));
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"}));
return hitRow;
}
function parseHitSearchPage(theResult,theNumber) {
var hitInfo = (theNumber>0) ? gMainData.hitCollection[theNumber] : null;
var hitData = (hitInfo) ? hitInfo.data : null;
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;
if (errorTitle && errorTitle.innerHTML.indexOf("You have exceeded the maximum allowed page request rate") != -1) {
processResults( theNumber, "TOOFAST" );
return;
} else if (errorTitle && errorTitle.innerHTML.indexOf("Your search did not match any HITs") != -1) {
if (theNumber<=0) {
$("#JREditDialog .searchingResultsArea").html("").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) {
$("#JREditDialog .searchingResultsArea").html("");
var captions = {"requesterName":"Requester Name","title":"Hit Title","duration":"Time","hitsAvailable":"# Hits","pay":"Pay"};
var dialogWidth = $("#JREditDialog").width();
$("#JREditDialog .searchingResultsArea").append(createHitRow(captions,false));
$("#JREditDialog .searchingResultsArea").append(createDiv()
.css({"margin-left":"5px","background-color":"black","height":"6px","width":(dialogWidth - 145) + "px"}));
for (var i=0, len=requestersInfo.length; i<len; i++) {
$("#JREditDialog .searchingResultsArea").append(createHitRow(requestersInfo[i],true));
gSavedSearchArea = $("#JREditDialog .searchingResultsArea").html();
}
} else {
for (var i=0, len=requestersInfo.length; i<len; i++) {
goUrl = (hitData.action=="SearchAndFilter") ? previewLink(requestersInfo[i].groupId) : pandaLink(requestersInfo[i].groupId);
hitData.groupId = requestersInfo[i].groupId;
hitInfo.newTitle = requestersInfo[i].title
hitInfo.goToUrl.push({"url":goUrl,"theNumber":theNumber});
updateHitCell(theNumber);
}
if (hitData.maxHam!="" && hitData.maxHam!="0" && hitInfo.ham=="on") hamOn(theNumber);
theCycler.frontOfTheLine(theNumber);
}
} else if (theNumber<=0) {
$("#JREditDialog .searchingResultsArea").html("").append(createDiv("Nothing Found"));
}
}
}
function parseQueuePage(theResult,theNumber) {
gQueueData.splice(0,gQueueData.length);
var parser = new DOMParser();
var xmlDoc = parser.parseFromString(theResult.responseText,"text/html");
if ($(xmlDoc).find("td.error_title:contains('There are currently no HITs')").length ||
$(xmlDoc).find("td.error_title:contains('You do not currently have any HITs')").length) {
gMainData.hitsInQueue = 0;
} else {
var numberQueueText = $(xmlDoc).find("td.title_orange_text").html();
if (numberQueueText) {
var words = numberQueueText.trim().split(' ');
if ($.isNumeric(words[words.length - 2])) gMainData.hitsInQueue = parseInt(words[words.length - 2]);
}
var sortResultsTable = $(xmlDoc).find("#sortresults_form").next("table");
$(sortResultsTable).find("> tbody > tr").each(function(i, row) {
var jobData = jQuery.extend(true, {}, jobDataDefault);
var titleElement = $(row).find(".capsulelink:first");
jobData.title = $(titleElement).text().trim();
jobData.returnURL = "https://www.mturk.com" + $(titleElement).closest("tr").find("td:eq(2)").find(".capsulelink:eq(0) a").attr("href");
jobData.continueURL = "https://www.mturk.com" + $(titleElement).closest("tr").find("td:eq(2)").find(".capsulelink:eq(1) a").attr("href");
var requesterElement = $(row).find(".requesterIdentity:first");
jobData.requesterName = $(requesterElement).text().trim();
var contactRequesterUrl = $(row).find("#keywords\\.tooltip--" + i).closest("td").next().next().find("a").attr("href");
jobData.requesterId = (contactRequesterUrl) ? contactRequesterUrl.split("requesterId=")[1].split("&")[0] : "";
jobData.timeLeft = $(row).find("#time_left\\.tooltip--" + i).closest("tr").find(".capsule_field_text").text().trim();
var rewardTrTarget = $(row).find("#reward\\.tooltip--" + i).closest("tr");
jobData.pay = $(rewardTrTarget).find(".reward").text().replace("$","").trim();
gQueueData.push(jobData);
});
}
if (gMainData.hitsInQueue <=20) {
gFullQueue = false;
if (gFullQueueTimer) clearTimeout(gFullQueueTimer);
}
displayMainStatus();
displayQueueStatus();
}
function errorRequest(res,theNumber) {
console.log("error: " + res.statusText);
if (res.statusText == "Forbidden") processResults( theNumber, "LOGGEDOFF" );
//setStatusText(theNumber,"...... Searching - Error .....","errors");
}
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 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" );
}
function parseMturkHitPage(theResult,theNumber) {
var hitInfo = gMainData.hitCollection[theNumber];
var hitData = hitInfo.data;
var parser = new DOMParser();
var xmlDoc = parser.parseFromString(theResult.responseText,"text/html");
var alertBoxHeader = xmlDoc.getElementById("alertboxHeader");
var dailyLimit = false;
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" );
return;
} else if (alertHeaderHTML.indexOf("You have accepted the maximum number of HITs allowed") != -1) {
processResults( theNumber, "QUEUEMAX" );
return;
} else if (alertHeaderHTML.indexOf("The HIT you were viewing could not be accepted") != -1) {
processResults( theNumber, "NOACCEPT" );
return;
} else if (alertHeaderHTML.indexOf("You are not qualified to accept") != -1 || alertHeaderHTML.indexOf("Your Qualifications do not meet the") != -1) {
processResults( theNumber, "NOTQUALIFIED" );
return;
}
dailyLimit = (alertHeaderHTML.indexOf("There are no HITs available for you at this time") != -1);
}
if (xmlDoc.getElementsByName("userCaptchaResponse").length > 0) {
if (!theCycler.isPaused()) {
theCycler.pause();
$("#JRPauseButton").html("Resume").css({"background-color":"red","color":"white"});
alert("Captcha Received");
}
return;
}
var loggedOff1 = xmlDoc.getElementById("ap_signin_custom_message");
var loggedOff3 = xmlDoc.getElementById("signin-slot");
if (loggedOff1 || loggedOff3) {
processResults( theNumber, "LOGGEDOFF" );
return;
}
var errorTitle = $(xmlDoc).find("td.error_title").eq(0);
var hitAccepted = $(xmlDoc).find("img[src$='/media/return_hit.gif']");
var notAccepted = $(xmlDoc).find("input[src$='/media/accept_hit.gif']");
if (errorTitle.length && errorTitle.html().indexOf("You have exceeded the maximum allowed page request rate") != -1) {
processResults( theNumber, "TOOFAST" );
} else if (errorTitle.length && errorTitle.html().indexOf("Your request was not completed successfully") != -1) {
processResults( theNumber, "NOTCOMPLETED" );
} else if (dailyLimit) {
processResults( theNumber, "DAILYLIMIT" );
} 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;
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).eq(0).parent().next() : null;
var theRequesterName = ($(requesterNameNode)) ? ( ($(requesterNameNode).find("a").length) ? $(requesterNameNode).find("a").html().trim() : $(requesterNameNode).html().trim() ) : "";
theRequesterName = (theRequesterName) ? theRequesterName : hitData.requesterName;
if (hitData.requesterName == "" || hitData.requesterName == hitData.groupId) { 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" );
if (updated) gDelayedSave = true;
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);
if (iframeSrc) {
if (formData.requesterId=="AGVV5AWLJY7H2") {
if (hitData.filterMode>0 && hitData.filterMode <= Object.keys(gZingFuncOptions).length) {
requestUrl(iframeSrc, theNumber, gZingFuncOptions[hitData.filterMode].functionName, errorRequest, formData, "");
} else {
console.log("Filter Mode is off");
hitInfo.goToUrl.push({"url":acceptHitURL,"theNumber":theNumber});
theCycler.frontOfTheLine(theNumber);
}
}
}
} else { processResults( theNumber, "ERROR" ); }
}
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}; }
function buttonStatus(buttonName,theData,buttonChange) {
if (buttonName=="collect") {
} else if (buttonName=="ham") {
}
}
function addHitCollection(theData,theNumber,tabIndex) {
var pandaUrl = pandaLink(theData.groupId);
var previewUrl = previewLink(theData.groupId);
var filterFuncData = (theData.action.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};
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) {
return parseQueuePage(theResult);
},function() { errorRequest(); } );
displayMainStatus();
return true;
}, -1, gMainOptions.queueTimer);
}
function startCollecting(theNumber,thisButton) {
var hitInfo = gMainData.hitCollection[theNumber], theUrl = "";
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;
if (hitInfo.ham == "ontimed") {
if (hitData.hamTimer > 0 && hitInfo.lastAccept) {
var nowTime = new Date();
var elapsedTime = nowTime - hitInfo.lastAccept;
var theSeconds = elapsedTime / 1000;
var theMinutes = Math.floor(theSeconds / 60);
var offHamMode = (hitInfo.ham == "ontimed") ? "paused" : "off";
if (theSeconds >= hitData.hamTimer) {
toggleButton($("#JRHamB_" + theNumber),hamOn,hamOff,offHamMode);
hitInfo.lastAccept = null;
}
}
}
if ( checkLimits(theNumber) ) {
hitInfo.status.searched++;
if (hitInfo.goToUrl.length) {
console.log("Found a gotoUrl so I must do Url");
if ( (hitInfo.data.action.substring(0,6) == "Search" || hitInfo.data.action == "FilterPanda") && !hitInfo.hitCell.data("firstPanda") )
theUrl = (hitInfo.goToUrl.shift()).url;
else theUrl = (hitInfo.goToUrl[0]).url;
} else {
theUrl = ( hitInfo.data.action == "Panda" ) ? hitInfo.pandaUrl : (hitInfo.data.action.substring(0,6) == "Search") ? requesterSearch(hitData.requesterId) : hitInfo.previewUrl;
}
gMainData.searched++;
gMainData.lastElapsed = elapsed;
//console.log("Doing Number: " + theNumber + " | going to: " + theUrl);
if (theUrl.indexOf("selectedSearchType=hitgroups")!=-1) requestUrl(theUrl,theNumber,parseHitSearchPage, errorRequest, hitInfo.status.searched, "");
else requestUrl(theUrl,theNumber,parseMturkHitPage, errorRequest, hitInfo.status.searched, "");
displayHitStatus(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);
gMainData.jobs++;
//addQueueCheck();
}
function stopCollecting(theNumber,thisButton) {
//console.log("turning off " + theNumber);
if (gMainData.hitCollection[theNumber].collecting == "on") {
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";
$(".JRHamButton").each( function() {
if ( $(this).data("theNumber") != theNumber ) $(this).data("disabled",true);
updateHitColors($(this).data("theNumber"));
});
if (gMainData.hitCollection[theNumber].ham == "paused") onMode = "ontimed";
gMainData.hitCollection[theNumber].ham = onMode;
theCycler.hamOn(theNumber);
theCycler.skippingReset();
theCycler.cycleResetChange(gMainOptions.HamCycleNumber);
}
function hamOff(theNumber,thisButton,theMode) {
var passedMode = theMode || "off";
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"));
});
}
if (hitInfo.ham == "ontimed") passedMode = "paused";
gMainData.hitCollection[theNumber].ham = passedMode;
$("#JRCellNum_" + theNumber).data("firstPanda",false);
theCycler.hamOff();
theCycler.skippingReset();
theCycler.cycleResetChange(gMainOptions.cycleNumber);
}
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").tooltip( "option", "disabled", true );
}
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"})
.sortable({dropOnEmpty: true,delay:400,connectWith: ".connectedSortable",tolerance: "pointer","items":".JRHitCell:not(.ui-not-sortable)",
helper:"clone",opacity: 0.9,appendTo:"body",
start: function( event, ui ) {
//$(".hasTooltip").tooltip("disable");
ui.item.addClass('noclick');
ui.item.data("oldPosition",ui.item.index());
ui.item.data("received",false);
},
receive: function( event, ui ) {
ui.item.data("received",true);
$(event.target).find(".JRHitDummy").remove();
gTabsData[ui.item.data("hitInfo").tabIndex].positions.splice(ui.item.data("oldPosition"), 1);
$(event.target).data("tabData").positions.splice(ui.item.index(), 0, ui.item.data("theNumber"));
ui.item.data("hitInfo").tabIndex = $(gTabsData).index($(event.target).data("tabData"));
ui.item.data("hitData").tabNumber = $(event.target).data("tabData").tabNumber;
$(event.target).append(createDiv(" ").attr("class","JRHitCell JRHitDummy").data("hitInfo",{"tabIndex":0}).css({"height":"160px","width":"200px"}));
saveSettings();
},
stop: function( event, ui ) {
if (ui.item.data("hitInfo") && !ui.item.data("received")) {
$(event.target).find(".JRHitDummy").remove();
var thePositions = gTabsData[ui.item.data("hitInfo").tabIndex].positions;
thePositions.splice(ui.item.index(), 0, thePositions.splice(ui.item.data("oldPosition"), 1)[0]);
$(event.target).append(createDiv(" ").attr("class","JRHitCell JRHitDummy").data("hitInfo",{"tabIndex":0}).css({"height":"160px","width":"200px"}));
saveSettings();
}
$(".hasTooltip").tooltip("enable");
}
});
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);
updateHitCell(newCell.data("theNumber"));
if (collectNow) {
newCell.data("status","on");
toggleButton( newCell.find(".JRCollectButton"),startCollecting,stopCollecting );
}
return newCell.data("theNumber");
}
function dataEdited(thisArea,theValue) {
$("#JREditDialog").data("edited",true);
$("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Save')").button().show();
var inputEdit = createTextInput(theValue).css({"width":"300px"});
$(inputEdit).focus( function() { $(this).select(); });
$(thisArea).find("span:not(.errorEditLine)").replaceWith(inputEdit);
$(inputEdit).focus();
}
function dataTrueFalse(thisArea,theValue) {
$("#JREditDialog").data("edited",true);
$("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Save')").button().show();
if (theValue) returnValue=false;
else returnValue=true;
$(thisArea).find("span").html(returnValue.toString());
return returnValue;
}
function dataPandaSearch(thisArea,theValue) {
$("#JREditDialog").data("edited",true);
$("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Save')").button().show();
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();
helpToolTips();
saveSettings();
theCycler.cycleResetChange(gMainOptions.cycleNumber);
displayMainStatus();
return true;
}
function saveTimersData() {
var cycleEdit = $("#JREditDialog #timersCycleEdit input");
if (cycleEdit.length) gMainOptions.cycleNumber = parseInt($(cycleEdit).eq(0).val());
var goHamEdit = $("#JREditDialog #timersGoHamEdit input");
if (goHamEdit.length) gMainOptions.HamCycleNumber = parseInt($(goHamEdit).eq(0).val());
var hamDelayEdit = $("#JREditDialog #timersHamDelayEdit input");
if (hamDelayEdit.length) gMainOptions.hamDelayTimer = parseInt($(hamDelayEdit).eq(0).val());
var checkQueueEdit = $("#JREditDialog #timersCheckQueueEdit input");
if (checkQueueEdit.length) {
gMainOptions.queueTimer = parseInt($(checkQueueEdit).eq(0).val());
theCycler.removeJob(-1); addQueueCheck();
}
var cycleIncreaseEdit = $("#JREditDialog #timersCycleIncreaseEdit input");
if (cycleIncreaseEdit.length) gMainOptions.cycleIncrease = parseInt($(cycleIncreaseEdit).eq(0).val());
var cycleDecreaseEdit = $("#JREditDialog #timersCycleDecreaseEdit input");
if (cycleDecreaseEdit.length) gMainOptions.cycleDecrease = parseInt($(cycleDecreaseEdit).eq(0).val());
var cycleAddingEdit = $("#JREditDialog #timersCycleAddingEdit input");
if (cycleAddingEdit.length) {
gMainOptions.cycleAdding = parseInt($(cycleAddingEdit).eq(0).val());
$("#JrCycleAddingButton").find("span").html("Add " + gMainOptions.cycleAdding);
}
var cycleAutoIncreaseEdit = $("#JREditDialog #timersCycleAutoIncreaseEdit input");
if (cycleAutoIncreaseEdit.length) gMainOptions.cycleAutoIncrease = parseInt($(cycleAutoIncreaseEdit).eq(0).val());
saveSettings();
theCycler.cycleResetChange(gMainOptions.cycleNumber);
displayMainStatus();
return true;
}
function saveJobData() {
var theNumber = $("#JREditDialog").data("theNumber");
var hitInfo = gMainData.hitCollection[theNumber];
var hitData = hitInfo.data;
var requesterNameEdit = $("#JREditDialog #requesterNameEdit input");
if (requesterNameEdit.length) hitData.requesterName = $(requesterNameEdit).eq(0).val();
var friendlyRNameEdit = $("#JREditDialog #friendlyRNameEdit input");
if (friendlyRNameEdit.length) hitData.friendlyRName = $(friendlyRNameEdit).eq(0).val();
var requesterIdEdit = $("#JREditDialog #requesterIdEdit input");
if (requesterIdEdit.length) hitData.requesterId = $(requesterIdEdit).eq(0).val();
var actionEdit = $("#JREditDialog #actionEdit input");
if (actionEdit.length) hitData.action = $(actionEdit).eq(0).val();
var groupIdEdit = $("#JREditDialog #groupIdEdit input");
if (groupIdEdit.length) {
hitData.groupId = $(groupIdEdit).eq(0).val();
hitInfo.pandaUrl = pandaLink(hitData.groupId);
hitInfo.previewUrl = previewLink(hitData.groupId);
}
var payEdit = $("#JREditDialog #payEdit input");
if (payEdit.length) hitData.pay = $(payEdit).eq(0).val();
var qualEdit = $("#JREditDialog #qualEdit input");
if (qualEdit.length) hitData.qual = $(qualEdit).eq(0).val();
var titleEdit = $("#JREditDialog #titleEdit input");
if (titleEdit.length) hitData.title = $(titleEdit).eq(0).val();
var friendlyTitleEdit = $("#JREditDialog #friendlyTitleEdit input");
if (friendlyTitleEdit.length) hitData.friendlyTitle = $(friendlyTitleEdit).eq(0).val();
var durationEdit = $("#JREditDialog #durationEdit input");
if (durationEdit.length) hitData.duration = $(durationEdit).eq(0).val();
var queueLimitEdit = $("#JREditDialog #queueLimitEdit input");
if (queueLimitEdit.length) hitData.queueLimit = Number($(queueLimitEdit).eq(0).val());
var dailyLimitEdit = $("#JREditDialog #dailyLimitEdit input");
if (dailyLimitEdit.length) hitData.dailyLimit = Number($(dailyLimitEdit).eq(0).val());
var onceEdit = $("#JREditDialog #onceEdit input");
if (onceEdit.length) hitData.once = $(onceEdit).eq(0).val();
var hamTimerEdit = $("#JREditDialog #hamTimerEdit input");
if (hamTimerEdit.length) hitData.hamTimer = $(hamTimerEdit).eq(0).val();
var dailyDoneEdit = $("#JREditDialog #dailyDoneEdit input");
if (dailyDoneEdit.length) hitData.dailyDone = $(dailyDoneEdit).eq(0).val();
var audioforceEdit = $("#JREditDialog #audioforceEdit input");
if (audioforceEdit.length) hitData.audioforce = $(audioforceEdit).eq(0).val();
var filterModeEdit = $("#JREditDialog #filterModeEdit select");
if (filterModeEdit.length) hitData.filterMode = $(filterModeEdit).eq(0).val();
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() {
//load from database to temp data variable
$("#JRWaitDialog").html("");
$("#JRWaitDialog").dialog("open");
saveToFile({"Requesters":gRequestersData,"Options":gMainOptions,"Tabsdata":gTabsData,"Grouping":gGroupingData,"Tabsinfo":gTabsInfo,"SoundOptions":setupSoundOptions()});
$("#JRWaitDialog").dialog("close");
}
function importJobs(theFile) {
//load json text and verify it's correct data for the database
$("div[aria-describedby='JRWaitDialog'] .ui-dialog-buttonpane button:contains('Cancel') span").html("Close");
$("#JRWaitDialog").data("closeme",function() { saveSettings(); });
$("#JRWaitDialog").html("");
$("#JRWaitDialog").dialog("open");
$("#JRWaitDialog").dialog("option", "title", "Please wait for importing data");
if (window.File && window.FileReader && window.FileList && window.Blob) {
var reader = new FileReader();
reader.onload = function() {
$("#JRWaitDialog").append(createDiv("Loaded file in memory."))
var textData = reader.result;
setTimeout( function() {
try {
$("#JRWaitDialog").append(createDiv("Parsing the imported Data."))
var theData = JSON.parse(textData);
$("#JRWaitDialog").append(createDiv("Stopping all Jobs"))
stopAll();
setTimeout( function() {
$("#JRWaitDialog").append(createDiv("Removing all Job Cells"))
$("#JRMainTabs").find(".ui-tabs-panel").each( function() {
$(this).find(".JRHitCell").each( function() {
$(this).remove();
});
});
setTimeout( function() {
$("#JRWaitDialog").append(createDiv("Removing all Tabs"))
$.each(gTabsData, function( index, value ) {
var panelId = $("#JRTab_" + value.tabNumber).closest( "li" ).remove().attr( "aria-controls" );
$( "#" + panelId ).remove();
$("#JRMainTabs").tabs( "refresh" );
});
setTimeout( function() {
$("#JRWaitDialog").append(createDiv("Deleting Collection Data"))
$.each(gMainData.hitCollection, function( index, value ) {
delete gMainData.hitCollection[index];
});
setTimeout( function() {
$("#JRWaitDialog").append(createDiv("Deleting Requesters Data"))
$.each(gRequestersData, function( index, value ) { delete gRequestersData[index]; });
$("#JRWaitDialog").append(createDiv("Deleting Grouping Data"))
$.each(gGroupingData, function( index, value ) { delete gGroupingData[index]; });
$.each(gGroupings, function( index, value ) { delete gGroupings[index]; });
gGroupingsSort.splice(0,gGroupingsSort.length);
setTimeout( function() {
$("#JRWaitDialog").append(createDiv("Deleting Tabs"))
$.each(gTabsData, function( index, value ) {
delete gTabsData[index];
});
gTabsInfo = {};
$("#addNewtab").remove();
setTimeout( function() {
$("#JRWaitDialog").append(createDiv("Adding imported data in the database."))
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() {
$("#JRMainTabs").tabs("option", "active", 0);
$("#JRWaitDialog").append(createDiv("Importing is finished."))
$("#JRWaitDialog").dialog("option", "title", "Importing data is now done.");
$("div[aria-describedby='JRWaitDialog'] .ui-dialog-buttonpane button:contains('Close')").show();
$("#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 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 formatDialog(idName,theHeight,theWidth,theTitle,theButton,editing,theModal) {
$("#" + 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();
$("div[aria-describedby='" + idName + "'] .ui-dialog-buttonpane button:contains('Yes')").hide();
$("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('Cancel')").show();
$("#" + idName).html("");
}
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()) } );
var textInputArea = createDiv().attr("class","textInputArea").css({"margin":"25px 15px"}).appendTo($("#JRPromptDialog"));
createDiv().html(promptQuestion).css({"font-size":"15px"}).appendTo(textInputArea);
createDiv().append(createTextInput(theValue).attr("class","textInputField").css({"width":"200px","margin":"5px 0 0 30px","height":"25px"})).appendTo(textInputArea);
$("#JRPromptDialog").dialog("open");
}
function showYesNoDialog(theQuestion,theYesFunction,data1,data2) {
$("#JRYesNoDialog").html("");
$("#JRYesNoDialog").data("data1",data1);
$("#JRYesNoDialog").data("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:not('.JRHitDummy')").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) {
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});
$("#JREditDialog").data({"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") });
var infoArea = createDiv().attr("class","infoArea").css({"margin":"8px 12px"}).appendTo($("#JREditDialog"));
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});
$("#JREditDialog").data({"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});
$("#JREditDialog").data({"theDelayed":theDelayed});
var groupingArea = createDiv().attr("class","groupingArea").css({"margin":"15px 15px"}).appendTo($("#JREditDialog"));
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") });
var infoArea = createDiv().attr("class","infoArea").css({"margin":"15px 15px"}).appendTo($("#JREditDialog"));
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]).data("removeMe",false).data("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);
$(thisCell).data("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 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);
var 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);
var 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);
var 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);
$("#JREditDialog").data("closeme",function() { showGroupingDialog("view",$("#JREditDialog").data("button")); });
$("#JREditDialog").data("NOCloseDialog",true);
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"));
var editGroupArea = createDiv().attr("class","editGroupArea").css({"margin":"10px 15px"}).appendTo($("#JREditDialog"));
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"));
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");
var infoArea = createDiv().attr("class","infoArea").css({"margin":"15px 15px","text-align":"center"}).appendTo($("#JREditDialog"));
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"));
refreshGroupingsDialog(groupingViewArea);
$("#JREditDialog").dialog("open");
}
function showExportImportDialog(porting,theButton) {
formatDialog("JREditDialog",200,300,porting + " data",theButton,"export and importing",true);
var exportImportArea = createDiv().attr("class","exportImportArea").css("margin","15px 15px").appendTo($("#JREditDialog"));
if (porting=="Export") {
createSpanButton( function(e) { checkDelayedSave();
var theButton = $("#JREditDialog").data("button");
$("#JREditDialog").data("button",null);
toggleButton(theButton,null,null);
$("#JREditDialog").dialog("close");
exportJobs();
},"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 doSearchNow() {
var sortingBy = $("#searchControlArea input[name='sortingOn']:checked").val();
var sortingByText = (sortingBy == "highestNumber") ? "&sortType=NumHITs%3A1" : (sortingBy == "highestAmount") ? "&sortType=Reward%3A1" : "&sortType=LastUpdatedTime%3A1";
$("#JREditDialog .searchingResultsArea").html("").append(createDiv("Searching now. Wait Please......").css({"font-size":"25px","margin-top":"200px","text-align":"center"}));
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);
}, -54, 0, true);
}
function showSearchingDialog(theButton) {
var dialogHeight = ($(window).height() > 700) ? 700 : $(window).height()-60;
var dialogWidth = ($(window).width() > 1200) ? 1200 : $(window).width()-80;
formatDialog("JREditDialog",dialogHeight,dialogWidth,"Search through your pandas or through mturk!",theButton,"searching",true);
$("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Cancel') span").html("Close");
var searchControlArea = createDiv().attr("id","searchControlArea").css({"margin":"8px 15px"}).appendTo($("#JREditDialog"));
createDiv().append(createRadioButton("searchingFor","pandas","").css({"margin-left":"200px"})).append(createSpan("Panda's"))
.append(createRadioButton("searchingFor","mturk","").attr("checked",true).css({"margin-left":"20px"})).append(createSpan("Mturk.com")).appendTo(searchControlArea);
createDiv().html("Type in a search word: ").css({"font-size":"15px","text-align":"left"})
.append(createTextInput("").attr("id","searchingInput").css({"width":"400px","margin-left":"10px"}).keypress( function(e) {
if ( e.which == 13 ) { doSearchNow(); }
}))
.append(createSpanButton( function(e) { doSearchNow(); },"Search",gButtonOffBgColor,gButtonOffColor,"12px")).appendTo(searchControlArea);
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(searchControlArea);
createDiv().attr("class","searchingResultsArea").css({"margin":"10px 2px"}).html(gSavedSearchArea).appendTo(searchControlArea);
$("#JREditDialog").dialog("open");
}
function showAddJobsDialog(theButton) {
formatDialog("JREditDialog",250,600,"Add a new PANDA!",theButton,"add job",true);
var addJobArea = createDiv().attr("class","addJobArea").css("margin","15px 15px").appendTo($("#JREditDialog"));
createDiv().html("Below enter the preview or the previewandaccept url.<br>You may enter just the groupID number too. This is needed for panda jobs.<br>")
.append(createTextInput("").attr("class","groupIdInput").css({"width":"400px","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("mturk.com")==-1) {
parsedGroupID = theValue;
} else { $("#JREditDialog .groupIDError").html("Please Enter a url or GroupID first."); }
if (parsedGroupID!="") {
console.log("found GroupID: " + 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");
var alarmsArea = createDiv().attr("class","alarmsArea").css({"margin":"15px 15px"}).appendTo($("#JREditDialog"));
createDiv().html("Alarms must be less than 6MB. I recommend the alarms to be less than 10 seconds. There is no limit to the length because the script doesn't check that.")
.css({"font-size":"13px","text-align":"center","margin":"6px 15px"}).appendTo(alarmsArea);
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":"10px","font-weight":"bolder","textDecoration":"underline"});
if (soundDescription.length>1) 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");
});
},"$" + value.payRate,"ivory","black","10px").data("theIndex",index).css({"font-weight":"normal"}))
.append(createSpan(soundDescription[1]).css({"font-size":"10px","font-weight":"bolder","textDecoration":"underline"}));
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");
});
},value.lessMinutes,"ivory","black","10px").data("theIndex",index).css({"font-weight":"normal"}))
.append(createSpan(soundDescription[2]).css({"font-weight":"bolder","textDecoration":"underline"}));
createDiv().attr("class","alarmInputEdits")
.append(createDiv().append(createSpanButton(function(e) { playNewSound($("#" + importFileID).data("audio")); }
,"- Play -","ivory","black","9px").css({"margin-right":"20px"}))
.append(addAppend)
.css({"margin-top":"5px"}))
.append(createDiv().html("Change to: ").append($("<input>").attr({"type":"file","id":importFileID,"accept":"audio/*"})
.data("audio",value.audio).data("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":"10px","color":"green"});
})).css({"font-size":"10px","margin":"5px 0 0 40px"})).appendTo(alarmsArea);
});
$("#JREditDialog").dialog("open");
}
function showEditOptionsDialog( theNumber, theButton ) {
var dialogHeight = ($(window).height() > 640) ? 640 : $(window).height()-60;
formatDialog("JREditDialog",dialogHeight,650,"Change options:",theButton,"options",true);
var optionsArea = createDiv().attr("class","optionsArea").css({"margin":"15px 15px"}).appendTo($("#JREditDialog"));
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); });
$(".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);
var timersArea = createDiv().attr("class","timersArea").css({"margin":"15px 15px"}).appendTo($("#JREditDialog"));
createDiv().html("All the timers on this page is measured in Milliseconds.<br>1000 Milliseconds is equal to 1 second.<br>Click on numbers to edit.")
.css({"font-size":"15px","text-align":"center"}).appendTo(timersArea);
createDiv().html("Cycle Timer: ").append(createSpan(gMainOptions.cycleNumber.toString())).css("margin-top","30px")
.attr({"class":"editLine hasHelptip","id":"timersCycleEdit","title":"This is the number of milliseconds for the script to wait until it checks on the next job. By default 970 should be fast enough to grab hits fast."}).appendTo(timersArea)
.click( function() { dataEdited($(this),gMainOptions.cycleNumber); });
createDiv().html("GoHam Cycle Timer: ").append(createSpan(gMainOptions.HamCycleNumber.toString())).css("margin-top","10px")
.attr({"class":"editLine hasHelptip","id":"timersGoHamEdit","title":"This is the number of milliseconds for the script to wait until it checks on the next job when in HAM mode. By default I have set it at 700 but 500 can be good too."}).appendTo(timersArea)
.click( function() { dataEdited($(this),gMainOptions.HamCycleNumber); });
createDiv().html("Default GoHam Delay Timer: ").append(createSpan(gMainOptions.hamDelayTimer.toString())).css("margin-top","10px")
.attr({"class":"editLine hasHelptip","id":"timersHamDelayEdit","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 is used for any NEW jobs. The current jobs will have their own timer set when it was created."}).appendTo(timersArea)
.click( function() { dataEdited($(this),gMainOptions.hamDelayTimer); });
createDiv().html("Check Queue Timer Every: ").append(createSpan(gMainOptions.queueTimer.toString())).css("margin-top","10px")
.attr({"class":"editLine hasHelptip","id":"timersCheckQueueEdit","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."}).appendTo(timersArea)
.click( function() { dataEdited($(this),gMainOptions.queueTimer); });
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().html("Cycle Increase Button: ").append(createSpan(gMainOptions.cycleIncrease.toString())).css("margin-top","15px")
.attr({"class":"editLine hasHelptip","id":"timersCycleIncreaseEdit","title":"The number of milliseconds to add to the cycle when pressing the increase button in the cycler menu."}).appendTo(AdvancedArea)
.click( function() { dataEdited($(this),gMainOptions.cycleIncrease); });
createDiv().html("Cycle Decrease Button: ").append(createSpan(gMainOptions.cycleDecrease.toString())).css("margin-top","10px")
.attr({"class":"editLine hasHelptip","id":"timersCycleDecreaseEdit","title":"The number of milliseconds to subtract from the cycle when pressing the decrease button in the cycler menu."}).appendTo(AdvancedArea)
.click( function() { dataEdited($(this),gMainOptions.cycleDecrease); });
createDiv().html("Cycle Add Time Button: ").append(createSpan(gMainOptions.cycleAdding.toString())).css("margin-top","10px")
.attr({"class":"editLine hasHelptip","id":"timersCycleAddingEdit","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."}).appendTo(AdvancedArea)
.click( function() { dataEdited($(this),gMainOptions.cycleAdding); });
createDiv().html("Cycle Auto Slowdown Increase: ").append(createSpan(gMainOptions.cycleAutoIncrease.toString())).css("margin-top","10px")
.attr({"class":"editLine hasHelptip","id":"timersCycleAutoIncreaseEdit","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."}).appendTo(AdvancedArea)
.click( function() { dataEdited($(this),gMainOptions.cycleAutoIncrease); });
$(".editLine").tooltip({ show: {delay:1000} });
helpToolTips();
$("#JREditDialog").dialog("open");
}
function showEditHitDialog( theNumber, theButton ) {
var dialogHeight = ($(window).height() > 640) ? 640 : $(window).height()-60;
formatDialog("JREditDialog",dialogHeight,600,"Edit this hit:",theButton,"job",true);
$("#JREditDialog").data("theNumber",theNumber);
var hitInfo = gMainData.hitCollection[theNumber];
var hitData = hitInfo.data;
var requesterArea = createDiv().attr("class","requesterArea").css("margin","15px 8px").appendTo($("#JREditDialog"));
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().html("Queue Limit: ").append(createSpan( hitData.queueLimit.toString() )).css({"margin-top":"10px"})
.attr({"class":"editLine hasHelptip","id":"queueLimitEdit","title":"Enter the limit of the number of any hits in your queue. It will stop collecting 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."})
.appendTo(requesterArea)
.click( function() { dataEdited($(this),hitData.queueLimit.toString()); });
createDiv().html("Daily Limit: ").append(createSpan( hitData.dailyLimit.toString() ))
.attr({"class":"editLine 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)"})
.appendTo(requesterArea)
.click( function() { dataEdited($(this),hitData.dailyLimit.toString()); });
createDiv().html("Daily Done: ").append(createSpan(hitData.dailyDone.toString()))
.attr({"class":"editLine hasHelptip","id":"dailyDoneEdit"}).appendTo(requesterArea)
.click( function() { dataEdited($(this),hitData.dailyDone.toString()); });
createDiv().html("Ham Timer (seconds): ").append(createSpan( hitData.hamTimer.toString() ))
.attr({"class":"editLine 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."})
.appendTo(requesterArea)
.click( function() { dataEdited($(this),hitData.hamTimer.toString()); });
createDiv().html("Once: ").append(createSpan( hitData.once.toString() ))
.attr({"class":"editLine 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."})
.appendTo(requesterArea)
.click( function() { hitData.once=dataTrueFalse($(this),hitData.once); });
createDiv().html("Friendly Requester Name: ").append(createSpan(hitData.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."})
.appendTo(requesterArea)
.click( function() { dataEdited($(this),hitData.friendlyRName); });
createDiv().html("Friendly Title: ").append(createSpan(hitData.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."})
.appendTo(requesterArea)
.click( function() { dataEdited($(this),hitData.friendlyTitle); });
var advancedArea = createDiv().attr("class","advancedArea").css({"border":"1px solid grey","margin":"20px 0 0 0","padding":"5px 3px"}).appendTo(requesterArea);
createDiv().html("Advanced Options most are changed by the script automatically:").css({"font-size":"15px","text-align":"center"}).appendTo(advancedArea);
createDiv().html("The Number: ").append(createSpan(theNumber)).appendTo(advancedArea).css({"margin-top":"5px","color":"red"});
createDiv().html("Action: ").append(createSpan(hitData.action))
.attr({"class":"editLine hasHelptip","id":"actionEdit","title":"Advanced use only. Should be Panda for normal use."}).appendTo(advancedArea)
.click( function() { dataEdited($(this),hitData.action); });
createDiv().html("Requester Name: ").append(createSpan(hitData.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."}).appendTo(advancedArea)
.click( function() { dataEdited($(this),hitData.requesterName); });
createDiv().html("Requester ID: ").append(createSpan(hitData.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."}).appendTo(advancedArea)
.click( function() { dataEdited($(this),hitData.requesterId); });
createDiv().html("Group ID: ").append(createSpan(hitData.groupId))
.attr({"class":"editLine hasHelptip","id":"groupIdEdit","title":"No reason to change this because you can just add a new job a lot faster."}).appendTo(advancedArea)
.click( function() { dataEdited($(this),hitData.groupId); });
createDiv().html("Pay: ").append(createSpan(hitData.pay))
.attr({"class":"editLine hasHelptip","id":"payEdit","title":"Shows the pay rate for this hit. No need to change it because the script will fill it in automatically."}).appendTo(advancedArea)
.click( function() { dataEdited($(this),hitData.pay); });
createDiv().html("Qualifications: ").append(createSpan(hitData.qual)).css("color","red") // Can not be edited.
.attr({"class":"editLine hasHelptip","id":"qualEdit"}).appendTo(advancedArea);
createDiv().html("Title: ").append(createSpan(hitData.title))
.attr({"class":"editLine hasHelptip","id":"titleEdit","title":"Shows the title of the hit. No need to change it because the script will fill it in automatically. Change the friendly title instead."}).appendTo(advancedArea)
.click( function() { dataEdited($(this),hitData.title); });
createDiv().html("Duration: ").append(createSpan(hitData.duration))
.attr({"class":"editLine hasHelptip","id":"durationEdit","title":"Displays the duration for this hit. The script will fill it in automatically when it finds it's first panda."}).appendTo(advancedArea)
.click( function() { dataEdited($(this),hitData.duration); });
createDiv().html("Force Audio: ").append(createSpan(hitData.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."}).appendTo(advancedArea)
.click( function() { dataEdited($(this),hitData.audioforce); });
if (hitData.action.indexOf("Filter") != -1) {
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>");
}
var 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) {
$("#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( function() { $("#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} });
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");
var helpArea = createDiv().attr("class","helpArea").css("margin","15px 8px").appendTo($("#JREditDialog"));
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 970ms 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 for 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.")
.css({"font-size":"15px","text-align":"left","text-indent":"50px"}).appendTo(helpArea);
createDiv().html("I find at 970ms 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 970ms. 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 5ms 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 5ms by default which you can change if you eant. 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 (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);
}
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' :
gMainData.hitsInQueue = theMessageData.queueLength;
displayMainStatus();
break;
case 'addOnceJob' :
onlyOnce = true;
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 thisRequesterName = (hitData.friendlyRName != "") ? hitData.friendlyRName : ((hitData.requesterName != "") ? hitData.requesterName : hitData.groupId);
$(hitCell).find(".myTitle").html(thisRequesterName).attr({"title":thisRequesterName + "\n" + hitData.groupId});
$(hitCell).find(".myfloater").html(".. " + shortGroupID(hitData.groupId));
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;
var hitBgColor = (hitCellTypeAction.substring(0,6)=="Search") ? gSearchesHitBgColor : (hitCellTypeAction=="FilterPanda") ? gFilteredHitBgColor : gHitBgColor;
var titleColor = (hitCellMute) ? gHitMutedColor : 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});
$("#JRCellNum_" + theNumber).css({"border-style":borderStyle});
$("#JRCellNum_" + theNumber).find(".myTitle").css({"color":titleColor});
$("#JRCellNum_" + theNumber).find(".JRCollectButton").css({"background-color":collectBgColor});
$("#JRCellNum_" + theNumber).find(".JRCollectButton").css({"color":collectColor});
$("#JRCellNum_" + theNumber).find(".JRHamButton").css({"background-color":gohamBgColor});
$("#JRCellNum_" + theNumber).find(".JRHamButton").css({"color":goHamColor});
$("#JRCellNum_" + theNumber).find(".myfloater").css({"background-color":hitBgColor});
} 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 createHitCell(goAppend,hitData,cellNumber) {
var theContainer = createContainer();
var hitInfo = gMainData.hitCollection[cellNumber];
var backgroundColor = (hitData.action.substring(0,6)=="Search") ? gSearchesHitBgColor : (hitData.action=="FilterPanda") ? gFilteredHitBgColor : gHitBgColor;
var floaterRight = createDiv()
.attr({"class":"myfloater"})
.data({"hitInfo":hitInfo})
.click(function(e) { GM_setClipboard ($(e.target).data("hitInfo").pandaUrl); e.stopPropagation();})
.css({"float":"right","margin-right":"-3px","padding":"0 1px 0 3px","font-weight":"900","background-color":backgroundColor,
"color":"purple","font-size":"7px","z-index":"999","position":"relative"})
.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);
if (gMainData.displayInfo==0) {
var htmlDescription = "";
} else if (gMainData.displayInfo==1) {
var 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({"color":"darkred","font-weight":"400","font-size":"10px"}).appendTo(theContainer);
var theButtonArea = createDiv().css({"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.collecting == "off") toggleButton($("#JRCollectB_" + $(e.target).data("theNumber")),startCollecting,stopCollecting);
if (thisHitInfo.ham == "paused") toggleButtonOff($(e.target),hamOn,hamOff);
else toggleButton($(e.target),hamOn,hamOff);
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() {
gPressAndHold=true;
var thisNumber = $(thisButton).data("theNumber");
if ($(thisButton).data("hitInfo").collecting == "off") toggleButton($("#JRCollectB_" + thisNumber),startCollecting,stopCollecting);
toggleButton($(thisButton),hamOn,hamOff,"paused","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);
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",
"mute":hitData.mute,"firstPanda":false,"typeAction":hitData.action,"hitData":hitData,"hitInfo":hitInfo,"oldPosition":null,"selected":0})
.css({"border-color":"MidnightBlue", "border-width":"3px", "border-style":borderStyle, "margin":"2px 4px",
"background-color":backgroundColor, "font-size":"11px", "cursor":"move", "overflow":"hidden", "float":"left", "white-space":"nowrap"})
.bind("contextmenu", function(e) {
e.preventDefault();
if (gScriptStatus == "normal") {
if ($(e.target).is(".JRButton")) return;
var theHitCell = $(e.target).closest(".JRHitCell");
muteJob(theHitCell.data("theNumber"));
} else if (gScriptStatus == "creating groupings") {
var theHitCell = $(e.target).closest(".JRHitCell");
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) {
if (gScriptStatus == "normal") {
if ($(e.target).is(".JRButton")) { e.stopPropagation(); return; }
if ($(e.target).hasClass('noclick')) {
$(e.target).removeClass('noclick');
} else {
var theHitCell = $(e.target).closest(".JRHitCell");
var thisHitInfo = theHitCell.data("hitInfo");
if ( theHitCell.data("typeAction").substring(0,6) == "Search" ) {
var firstPanda = !(theHitCell.data("firstPanda"));
var borderColor = (firstPanda) ? "red" : theHitCell.data("borderColor");
thisHitInfo.goToUrl.splice(0,thisHitInfo.goToUrl.length);
theHitCell.css({"border-color":borderColor});
theHitCell.data("firstPanda",firstPanda);
}
}
} else if (gScriptStatus == "creating groupings") {
var theHitCell = $(e.target).closest(".JRHitCell");
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++;
$(inTabId).find(".JRHitDummy").remove();
newHitCell = createHitCell($(inTabId).find(".tabContents"),newHitData,theNumber).data({"removeMe":false,"pandaHam":"off"});
$(inTabId).append(createDiv(" ").attr("class","JRHitCell JRHitDummy").data("hitInfo",{"tabIndex":0}).css({"height":"160px","width":"200px"}));
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,theNumber) {
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) {
limit = (limit) || 3000;
resetLog = (resetLog) || false;
if (resetLog) { logNode.html(""); return true; }
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));
return true;
}
function addToStatusLog(theText) { addToLog(createSpan(theText.trim()),$("#JRStatusLog")); }
function addToAcceptedLog(theText) { addToLog(createSpan(theText.trim()),$("#JRAcceptedLog")); }
function addToQueueWatchLog(theText,resetLog) {
resetLog = (resetLog) || false;
addToLog(createSpan(theText.trim()),$("#JRQueueWatchLog"),26,resetLog);
if (resetLog) $("#JRQueueWatchLog").append(createDiv().attr("class","muteQueueWatch").css({"float":"right"}).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"})));
}
function addToMturkgrindLog(thisStuff) {
$("#JRMTGTab").css("background-color","#DEB887");
$("#JRMturkgrindLog").one('mouseover', function() { $("#JRMTGTab").css("background-color",""); })
addToLog(thisStuff,$("#JRMturkgrindLog"));
}
function addToMturkforumLog(theText) { addToLog(createSpan(theText),$("#JRMturkforumLog")); }
function addToHWTFLog(thisStuff) {
$("#JRHWTFTab").css("background-color","#DEB887");
$("#JRHWTFLog").one('mouseover', function() { $("#JRHWTFTab").css("background-color",""); })
addToLog(thisStuff,$("#JRHWTFLog"));
}
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 = [];
$(thisTab).find(".tabContents").append(createDiv(" ").attr("class","JRHitCell JRHitDummy").data("hitInfo",{"tabIndex":index}).css({"height":"160px","width":"200px"}));
});
}
function refreshAllCells() {
$.each(gMainData.hitCollection, function( index, value ) {
updateHitCell(index);
});
}
function showButtonUsed(thisButton) {
thisButton.css({"background-color": "#CCC6B0"});
thisButton.animate({"background-color": gButtonOffBgColor}, 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).attr("aria-controls"))).find(".tabContents").append(createDiv(" ")
.attr("class","JRHitCell JRHitDummy").data("hitInfo",{"tabIndex":gTabIndex}).css({"height":"160px","width":"200px"}));
$("#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 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;
if (gSoundFile.paused == true) {
gSoundFile = gAlarmSounds["less2"].audio;
gSoundFile.currentTime = 0;
gSoundFile.play();
}
}
})
.appendTo(mainControls);
$("#JRWaitDialog").append(createDiv("Setting up Menu."));
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,"Cycle",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);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
activeMenu(gMainMenu,"Jobs"); },"Jobs","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(mainMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
activeMenu(gMainMenu,"Main"); },"Main","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(jobsMenuControls);
createSpan(" -Jobs- ").appendTo(jobsMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
toggleButton($(e.target),function(theNumber,thisButton) { showAddJobsDialog(thisButton); },null);
},"Add","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(jobsMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
toggleButton($(e.target),function(theNumber,thisButton) { showExportImportDialog("Export",thisButton); },null);
},"Export","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(jobsMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
toggleButton($(e.target),function(theNumber,thisButton) { showExportImportDialog("Import",thisButton); },null);
},"Import","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(jobsMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
activeMenu(gMainMenu,"Display"); },"Display","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(mainMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
activeMenu(gMainMenu,"Main"); },"Main","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(displayMenuControls);
createSpan(" -Display- ").appendTo(displayMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
showButtonUsed($(e.target)); gMainData.displayInfo=0; refreshAllCells();
},"Minimum Info","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(displayMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
showButtonUsed($(e.target)); gMainData.displayInfo=1; refreshAllCells();
},"Extended Info","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(displayMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
activeMenu(gMainMenu,"Grouping"); },"Grouping","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(mainMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
activeMenu(gMainMenu,"Main"); },"Main","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(groupingMenuControls);
createSpan(" -Grouping- ").appendTo(groupingMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
toggleButton($(e.target),function(theNumber,thisButton) { showGroupingDialog("collect",thisButton); },null);
},"Start/Stop","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(groupingMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
toggleButton($(e.target),function(theNumber,thisButton) { showGroupingCreateDialog(thisButton,[],[],"selection"); },null);
},"Create By Selection","ivory","black","12px")).css({"margin":"10px 0"}).data("creating","see").appendTo(groupingMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
toggleButton($(e.target),function(theNumber,thisButton) { showGroupingCreateDialog(thisButton,[],[],"collecting"); },null);
},"Create Instantly","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(groupingMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
toggleButton($(e.target),function(theNumber,thisButton) { showGroupingDialog("view",thisButton); },null);
},"View all","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(groupingMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
activeMenu(gMainMenu,"Cycle");
$("#JRCycleInfoArea").stop(true,true);
$("#JRCycleInfoArea").css({"color":"red"});
},"Cycler","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(mainMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
activeMenu(gMainMenu,"Main"); $("#JRCycleInfoArea").stop(true,true);
$("#JRCycleInfoArea").animate({"color": "#191970"}, 30000);
},"Main","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(cycleMenuControls);
createSpan(" -Cycler- ").appendTo(cycleMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
showButtonUsed($(e.target)); theCycler.skippingReset(); displayMainStatus();
},"Reset","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(cycleMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
showButtonUsed($(e.target)); theCycler.cycleIncrease(); displayMainStatus();
},"Increase","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(cycleMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
showButtonUsed($(e.target)); theCycler.cycleDecrease(); displayMainStatus();
},"Decrease","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(cycleMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
showButtonUsed($(e.target)); theCycler.cycleAdd(gMainOptions.cycleAdding); displayMainStatus();
},"Add " + gMainOptions.cycleAdding,"ivory","black","12px")).css({"margin":"10px 0"}).attr("id","JrCycleAddingButton").appendTo(cycleMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
toggleButton($(e.target),function(theNumber,thisButton) { showEditTimersDialog("Timers",thisButton); },null);
},"Edit Cycle Timers","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(cycleMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
toggleButton($(e.target),function(theNumber,thisButton) { showHelpDialog("cycler","What is a cycler and how do I use it?",thisButton); },null);
},"Help","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(cycleMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
activeMenu(gMainMenu,"Options"); },"Options","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(mainMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
activeMenu(gMainMenu,"Main"); },"Main","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(optionsMenuControls);
createSpan(" -Options- ").appendTo(optionsMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
toggleButton($(e.target),function(theNumber,thisButton) { showEditTimersDialog("Timers",thisButton); },null);
},"Timers","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(optionsMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
toggleButton($(e.target),function(theNumber,thisButton) { showAlarmsDialog("Alarms",thisButton); },null);
},"Alarms","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(optionsMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
toggleButton($(e.target),function(theNumber,thisButton) { showEditOptionsDialog("Alarms",thisButton); },null);
},"General","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(optionsMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
toggleButton($(e.target), function() { gSlowDownAuto=true; }, function() { gSlowDownAuto=false; } );
if ($(e.target).data("status") == "on") $(e.target).css({"background-color":"red"});
},"Stop Auto Slowdown","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(optionsMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
activeMenu(gMainMenu,"Help"); },"Help","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(mainMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
activeMenu(gMainMenu,"Main"); },"Main","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(helpMenuControls);
createSpan(" -Help- ").appendTo(helpMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
toggleButton($(e.target),function(theNumber,thisButton) { showHelpDialog("about","About this script and how to use it efficiently.",thisButton); },null);
},"About Script","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(helpMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
toggleButton($(e.target),function(theNumber,thisButton) { showHelpDialog("cycler","What is a cycler and how do I use it?",thisButton); },null);
},"Cycler","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(helpMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
toggleButton($(e.target),function(theNumber,thisButton) { showHelpDialog("jobs","What is a job and what can I do with it?",thisButton); },null);
},"Jobs","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(helpMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
toggleButton($(e.target),function(theNumber,thisButton) { showHelpDialog("jobDetails","What are the other options I can use with jobs?",thisButton); },null);
},"Job Details","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(helpMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
toggleButton($(e.target),function(theNumber,thisButton) { showHelpDialog("goHam","What is Go Ham and does it really taste like ham?",thisButton); },null);
},"Go Ham","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(helpMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
toggleButton($(e.target),function(theNumber,thisButton) { showHelpDialog("groupings","How do I use groupings and what are they?",thisButton); },null);
},"Groupings","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(helpMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
toggleButton($(e.target),function(theNumber,thisButton) { showHelpDialog("tabs","What can I do with the tabs?",thisButton); },null);
},"Tabs","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(helpMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
toggleButton($(e.target),function(theNumber,thisButton) { showHelpDialog("options","What can I do with all these options?",thisButton); },null);
},"Options","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(helpMenuControls);
createSpan().append(createSpanButton(function(e) { checkDelayedSave();
toggleButton($(e.target),function(theNumber,thisButton) { showHelpDialog("statustext","What are the stats at the top mean?",thisButton); },null);
},"Status Text","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(helpMenuControls);
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 hasHelptip","title":"Click to Show Number of Panda, Searches or Filtered Jobs."}).data("mode","Jobs").appendTo(mainStatus);
createSpan().attr({"id":"JRCycleInfoArea","class":"JRStatusText hasHelptip","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 hasHelptip","title":"Click to Show Accepted or Skipped Hits."})
.data("mode","Accepted")
.click( function(e) { checkDelayedSave();
var theMode = $(e.target).data("mode");
$(e.target).data("mode", (theMode=="Accepted") ? "Skipped" : "Accepted")
.stop(true,true)
.css({"color":"red"})
.animate({"color": "#191970"}, 30000);
displayMainStatus();
}).css({"cursor":"pointer"}).appendTo(mainStatus);
createSpan().attr({"id":"JRErrorArea","class":"JRStatusText hasHelptip","title":"Click to Show Number of Too Fast or Error Pages."})
.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":"JRMturkQueueArea","class":"JRStatusText hasHelptip","title":"Number of Hits in Mturk Queue. Only verifies queue after specified time in options."})
.data("mode","Queue")
.appendTo(mainStatus).click( function() { checkDelayedSave();
theCycler.frontOfTheLineTimer(-1);
}).css({"cursor":"pointer"}).appendTo(mainStatus);
createSpan().attr({"id":"JRSearchedArea","class":"JRStatusText hasHelptip","title":"Number of Searched Hits."})
.data("mode","Searched")
.appendTo(mainStatus);
createSpan().attr({"id":"JRPayArea","class":"JRStatusText hasHelptip","title":"Total Amount for Accepted Hits."})
.data("mode","Pay")
.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) {
$("#JRWaitDialog").data("button",thisButton);
$("#JRWaitDialog").html("");
$("#JRWaitDialog").dialog("open");
saveSettings();
createDiv("Database Saved.<br>You may close this dialog.").css({"font-size":"18px","margin-top":"30px","text-align":"center"}).appendTo($("#JRWaitDialog"));
$("div[aria-describedby='JRWaitDialog'] .ui-dialog-buttonpane button:contains('Cancel') span").html("Close")
$("div[aria-describedby='JRWaitDialog'] .ui-dialog-buttonpane button:contains('Close')").show();
},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); },null);
},"Search","ivory","black","12px").attr({"class":"JRMButton hasHelptip","title":"Search through pandas or Mturk."}).appendTo(theControls);
$("#JRWaitDialog").append(createDiv("Setting up tabs."));
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"});
logTabs.tabs("option", "active", 2)
$("#JRWaitDialog").append(createDiv("Creating Panda Cells."));
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});
$("#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})
},
});
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();
$("#JRWaitDialog").append(createDiv("Display is done.<br>Starting up script."));
setTimeout( function() {
$("#JRWaitDialog").dialog("close");
$(".JRStatusText").tooltip({ show: {delay:680} })
$(".hasHelptip").tooltip({ show: {delay:1000} });
helpToolTips();
addQueueCheck();
},1000);
},10);
},10);
},10);
}
function continueLoading() {
$("#JRWaitDialog").append(createDiv("Creating UI Display."));
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();
$("#JRWaitDialog").html("Setting up Panda Crazy!");
$("#JRWaitDialog").dialog("open");
$("#JREditDialog").dialog("option","height",310);
$("#JREditDialog").dialog("option","width",320);
$("#JRWaitDialog").dialog('option', 'position', 'center');
$("#JRWaitDialog").dialog("option", "title", "Please wait. Loading....");
setTimeout( function() {
var nowDate = new Date();
console.log(formatTimeZone("onlydate",nowDate,"mturk"));
$("#JRWaitDialog").append(createDiv("Loading settings in memory."));
setTimeout( function() {
loadSettings();
},10);
},10);
});
/*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; \
} \
.ui-dialog.notmodal { \
border: 3px solid #000; \
} \
.no-close .ui-dialog-titlebar-close { \
display: none; \
} \
.ui-state-hover .ui-icon { \
background-image: url('https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/themes/pepper-grinder/images/ui-icons_ffffff_256x240.png') !important; \
} \
.ui-state-active .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-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'); \
} \
.ui-widget-content { \
background: #eceadf url('https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/themes/pepper-grinder/images/ui-bg_fine-grain_10_eceadf_60x60.png') 50% 50% repeat; \
} \
#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; } \
");