HIT Forker

Monitors mturk.com for HITs

当前为 2017-12-19 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         HIT Forker
// @version      0.3.0
// @description  Monitors mturk.com for HITs
// @author       ThisPoorGuy
// @icon         http://nopurpose.org/stuff/avatars/Lj21396.gif
// @include      https://worker.mturk.com/?finder_beta
// @include      https://worker.mturk.com/?hit_forker
// @grant        GM_log
// @grant        GM_setClipboard
// @grant        GM_xmlhttpRequest
// @connect      turkerview.com
// @require      https://code.jquery.com/jquery-3.1.0.min.js
// @namespace https://greasyfork.org/users/163167
// ==/UserScript==

// Acknowledgements
// The core of this script was forked/stolen/adapted from Kadauchi's Hit Finder Beta script. Coding assistance in spots
// provided by Salem Beats and ChrisTurk. TurkerView was created by ChrisTurk. This script hooks into JR Panda Crazy

// Changelog
// 0.3.0 - Under the hood changes, removed code for running on www, added new launch URL, old ?finder_beta will be phased out eventually
// 0.2.9 - Now acceptable to people with red/green color blindness!
// 0.2.6 - Fixed a minor error which caused colors to not work properly.
// 0.2.5 - Changed Coloration to respect TV reviews FIRST and then fall back on TO Values. Also changed colors.
// 0.2.0 - Added TurkerView Hourly ratings to HIT results, fixed export links.
// 0.1.5 - Some minor UI tweaks
// 0.1.4 - Added some indication that you have already clicked a button to send HIT to PC. Only works in log currently.
// 0.1.3 - Fixed issue with the Panda buttons in the HIT log not having the right GID
// 0.1.2 - Fixed an issue with HITs that have double quotes in the title not working with the ignore hit by title button. I think.
// 0.1.1 - Cleaned up the header, removed unused audio files
// 0.1.0 - Made modifications to launch links with worker website. Added buttons to send information to PandaCrazy directly instead of copying link
// TODO:
// Remove www code
// Clean up interface

var worker = true;

var _config     = JSON.parse(localStorage.getItem('_finder'))    || {};
var blocklist   = JSON.parse(localStorage.getItem('_finder_bl')) || {};
var includelist = JSON.parse(localStorage.getItem('_finder_il')) || {};

// Compatability check
if (_config.version !== '1.1') { _config = {}; }

var config = {
  version  : _config.version  || '1.1',
  delay    : _config.delay    || '3',
  type     : _config.type     || 'LastUpdatedTime%3A1&pageSize=',
  size     : _config.size     || '25',
  rew      : _config.rew      || '0.00',
  avail    : _config.avail    || '0',
  mto      : _config.mto      || '0.00',
  alert    : _config.alert    || '0',
  qual     : _config.hasOwnProperty('qual') ? _config.qual : true,
  new      : _config.hasOwnProperty('new')  ? _config.new  : true,
  newaudio : _config.newaudio || 'beep',
  pb       : _config.hasOwnProperty('pb')   ? _config.pb   : false,
  to       : _config.hasOwnProperty('to')   ? _config.to   : true,
  nl       : _config.hasOwnProperty('nl')   ? _config.nl   : false,
  bl       : _config.hasOwnProperty('bl')   ? _config.bl   : false,
  m        : _config.hasOwnProperty('m')    ? _config.m    : false,
  push     : _config.push     || 'access_token_here',
  theme    : _config.theme    || 'default',
  custom   : _config.custom   ||  {main: 'FFFFFF', primary: 'CCCCCC', secondary: '111111', text: '000000', link: '0000EE', visited: '551A8B', prop : false},
  to_theme : _config.to_theme || '1'
};

var themes = {
  'default' : {main: 'FFFFFF', primary: 'CCCCCC', secondary: '111111', menu: '373b44', menutext: 'FFFFFF', text: '000000', link: '0000EE', visited: '551A8B', prop : true},
  'light'   : {main: 'FFFFFF', primary: 'CCCCCC', secondary: '111111', menu: '373b44', menutext: 'FFFFFF', text: '000000', link: '0000EE', visited: '551A8B', prop : true},
  'dark'    : {main: '404040', primary: '666666', secondary: 'FFFFFF', menu: '202020', menutext: 'FFFFFF', text: 'FFFFFF', link: 'FFFFFF', visited: 'B3B3B3', prop : true},
  'darker'  : {main: '000000', primary: '262626', secondary: 'FFFFFF', menu: '373b44', menutext: 'FFFFFF', text: 'FFFFFF', link: 'FFFFFF', visited: 'B3B3B3', prop : true},
  'custom'  : config.custom
};

var hitdb = { db: null };
var tukerview = { };
var turkerview_update = 0;

/*window.indexedDB.open('HITDB').onsuccess = function() {
  hitdb.db = this.result;
};*/

var searches    = 0,
    logged      = 0,
    hitlog      = {},
    noti_delay  = [],
    push_delay = [];

// General Configuration variables
var url, upd, num, rew, minrew, searchqual, pandaurl;

url    = 'https://worker.mturk.com/?';
pandaurl = 'https://worker.mturk.com';
upd    = '&sort=updated_desc&page_size=';
num    = '&sort=num_hits_desc&page_size=';
rew    = '&sort=reward_desc&page_size=';
minrew = '&filters%5Bmin_reward%5D=';
searchqual = '&filters%5Bqualified=';

$('head').html(
  '<title>HIT Forker</title>' +
  '<link rel="icon" type="image/jpg" href="http://nopurpose.org/stuff/avatars/Lj21396.gif">' +
  '<base target="_blank">' +

  '<audio id="audio_1"><source src="http://www.soundjay.com/button/sounds/button-1.mp3" type="audio/mpeg"></audio>' +
  '<audio id="audio_2"><source src="http://www.soundjay.com/button/sounds/button-3.mp3" type="audio/mpeg"></audio>' +
  '<audio id="audio_3"><source src="http://www.soundjay.com/button/sounds/button-4.mp3" type="audio/mpeg"></audio>' +
  '<audio id="audio_4"><source src="http://www.soundjay.com/button/sounds/button-5.mp3" type="audio/mpeg"></audio>' +
  '<audio id="audio_beep"><source src="http://www.soundjay.com/button/sounds/beep-21.mp3" type="audio/mpeg"></audio>' +
  '<audio id="audio_beepbeep"><source src="http://www.soundjay.com/button/sounds/beep-24.mp3" type="audio/mpeg"></audio>' +
  '<audio id="audio_click"><source src="http://www.soundjay.com/button/sounds/button-20.mp3" type="audio/mpeg"></audio>' +

  '<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">' +
  '<style id="css" type="text/css">'
);

$('body').html(
  // Main
  '<div style="margin-bottom: 5px; text-align:right;" id="menubar">' +
  '<div style="position: absolute; top: 32px width: 100px; font-size: 14pt; font-weight: bold;" id="menu_title">HIT Forker</div>'+
  '<div style="line-height: 30px; margin-right:5px;">'+
  '<button id="scan_button" style="margin-right: 5px;">Start</button>' +
  '<button id="bloc_button" style="margin-right: 5px;">Block List</button>' +
  '<button id="incl_button" style="margin-right: 5px;">Include List</button>' +
  '<button id="sett_button" style="margin-right: 5px;">Advanced Settings</button>' +
  '<button id="conf_button" style="margin-right: 5px;">Show Config</button>' +
  '<button id="logg_button" style="margin-right: 0px;">Hide Logged HITs</button>' +
  '</div></div>' +

  // Config
  '<div id="config" style="position: absolute; top: 37px; right: 5px; margin-bottom: 5px;" class="hidden">' +

  '<div style="margin-bottom: 5px;">' +
  '<label style="margin-right: 5px; display: inline-block; border-bottom: 1px solid;" title="Delay in seconds between searches.">Search Delay: ' +
  '<input id="delay" style="width: 50px;" type="number" step="1" min="1" value="' + config.delay + '">' +
  '</label>' +

  '<label style="margin-right: 5px; display: inline-block; border-bottom: 1px solid;" title="Filter HITs by minimum reward.">Min Reward: ' +
  '<input id="min_rew" style="width: 50px;" type="number" step="0.01" min="0" value="' + config.rew + '">' +
  '</label>' +

  '<label style="margin-right: 5px; display: inline-block; border-bottom: 1px solid;" title="Filter HITs by minimum available.">Min Avail: ' +
  '<input id="min_avail" style="width: 50px;" type="number" step="1" min="0" value="' + config.avail + '">' +
  '</label>' +

  '<label style="margin-right: 5px; display: inline-block; border-bottom: 1px solid;" title="Filter HITs by minimum TO pay.">Min TO: ' +
  '<input id="min_to" style="width: 50px;" type="number" step="0.1" min="0" max="5" value="' + config.mto + '">' +
  '</label>' +

  '<label style="margin-right: 5px; display: inline-block; border-bottom: 1px solid;" title="Search for this many HITs.">Size: ' +
  '<input id="size" style="width: 50px;" type="number" step="1" min="1" max="100" value="' + config.size + '">' +
  '</label>' +

  '<label style="margin-right: 5px; display: inline-block; border-bottom: 1px solid;" title="Sort HITs by (Latest / Most Available / Highest Reward)">Sort by: ' +
  '<select id="type" value="' + config.type + '">' +
  '<option value="' + upd + '">Latest</option>' +
  '<option value="' + num + '">Most Available</option>' +
  '<option value="' + rew + '">Reward (Most)</option>' +
  '</select>' +
  '</label>' +

  '<label style="margin-right: 0px; display: inline-block; border-bottom: 1px solid;" title="Only show HITs that you are  for.">Qualified' +
  '<input id="qual" type="checkbox" ' + (config.qual ? 'checked' : '') + '>' +
  '</label>' +
  '</div>' +

  '<div style="margin-bottom: 5px;">' +
  '<label style="margin-right: 5px; display: inline-block; border-bottom: 1px solid;" title="Delay in seconds between desktop notifications and sound alerts for an include list match.">Alert Delay: ' +
  '<input id="alert_delay" style="width: 50px;" type="number" step="1" min="0" value="' + config.alert + '">' +
  '</label>' +

  '<label style="margin-right: 5px; display: inline-block; border-bottom: 1px solid;" title="Make a sound when a new HIT is found.">Sound On New HIT ' +
  '<input id="new_sound" type="checkbox" ' + (config.new ? 'checked' : '') + '>' +
  '<select id="new_audio" value="' + config.newaudio + '">' +
  //'<option value="default">Default</option>' +
  '<option value="beep">Beep</option>' +
  '<option value="beepbeep">Beep Beep</option>' +
  //'<option value="ding">Ding</option>' +
  //'<option value="squee">Squee</option>' +
  '<option value="click">Click</option>' +
  '</select>' +
  '</label>' +

  '<label style="margin-right: 5px; display: inline-block; border-bottom: 1px solid;" title="Allow inludelist matches to send Pushbullet notifications if enabled for that match.">Pushbullet ' +
  '<input id="pb" type="checkbox" ' + (config.pb ? 'checked' : '') + '>' +
  '</label>' +

  '<label style="margin-right: 5px; display: inline-block; border-bottom: 1px solid;" title="Use turkopticon.">Enable TO ' +
  '<input id="to" type="checkbox" ' + (config.to ? 'checked' : '') + '>' +
  '</label>' +

  '<label style="margin-right: 5px; display: inline-block; border-bottom: 1px solid;" title="Hide all HITs that do not match your include list.">Hide Non Include List ' +
  '<input id="nl_hide" type="checkbox" ' + (config.nl ? 'checked' : '') + '>' +
  '</label>' +

  '<label style="margin-right: 5px; display: inline-block; border-bottom: 1px solid;" title="Hide HITs that match your block list.">Hide Block List ' +
  '<input id="bl_hide" type="checkbox" ' + (config.bl ? 'checked' : '') + '>' +
  '</label>' +

  '<label style="margin-right: 0px; display: inline-block; border-bottom: 1px solid;" title="Hide masters HITs.">Hide Masters ' +
  '<input id="m_hide" type="checkbox" ' + (config.m ? 'checked' : '') + '>' +
  '</label>' +
  '</div>' +

  '</div>' +

  // HITs
  '<div id="latest_hits">' +
  '<div style="border-bottom: 3px solid; margin-bottom: 5px;">' +
  '<span style="font-size: 20px; font-weight: bold;">HITs</span>' +
  '<span id="hits_data" style="font-size: 11px;"></span>' +
  '</div>' +

  '<div>' +
  '<div style="overflow: hidden; white-space: nowrap;">' +
  '<div style="float: left; width: calc(100% - 330px);">' +
  '<span style="width: 34%; float: left;  display:inline-block; overflow: hidden;">Requester</span>' +
  '<span style="width: 64%; float: right; display:inline-block; overflow: hidden;">Project</span>' +
  '</div>' +
  '<div style="float: right;">' +
  '<span style="width: 60px; display:inline-block; text-align: center;">Tasks</span>' +
  '<span style="width: 60px; display:inline-block; text-align: center;">Accept</span>' +
    '<span style="width: 60px; display:inline-block; text-align: center;">TV</span>' +
  '<span style="width: 60px; display:inline-block; text-align: center;">TO</span>' +
  '<span style="width: 30px; display:inline-block; text-align: center;">M</span>' +
  '<span style="width: 60px; display:inline-block; text-align: center;">PANDA</span>' +
  '</div>' +
  '</div>' +
  '</div>' +
  '<div id="new_hits"></div>' +
  '</div>' +

  '<br>' +

  //Logged HITs
  '<div id="logged_hits">' +
  '<div style="border-bottom: 3px solid; margin-bottom: 5px;">' +
  '<span style="font-size: 20px; font-weight: bold;">Logged HITs</span>' +
  '<span id="logged_hits_data" style="font-size: 11px;"></span>' +
  '</div>' +

  '<div>' +
  '<div style="overflow: hidden; white-space: nowrap;">' +

  '<div style="float: left;">' +
  '<span style="width: 80px; display:inline-block;">Time</span>' +
  '</div>' +

  '<div style="float: left; width: calc(100% - 3500px);">' +
  '<span style="width: 34%; float: left;  display:inline-block; overflow: hidden;">Requester</span>' +
  '<span style="width: 64%; float: right; display:inline-block; overflow: hidden;">Project</span>' +

  '</div>' +
  '<div style="float: right;">' +
  '<span style="width: 60px; display:inline-block; text-align: center;">Accept</span>' +
  '<span style="width: 60px; display:inline-block; text-align: center;">TV</span>' +
  '<span style="width: 60px; display:inline-block; text-align: center;">TO</span>' +
  '<span style="width: 30px; display:inline-block; text-align: center;">M</span>' +
  '<span style="width: 60px; display:inline-block; text-align: center;">PANDA</span>' +
  '</div>' +
  '</div>' +
  '</div>' +
  '<div id="log_hits"></div>' +
  '</div>' +

  // Block List
  '<div id="bl_div" style="z-index: 99; position: fixed; width: 80%; height: 80%; left: 10%; top: 300px; margin-top: -250px; display: none;">' +
  '<div style="position: relative; width: 80%; left: 10%; border-bottom: 3px solid; padding: 2px; text-align: center;">Block List</div>' +
  '<div id="bl_items"></div>' +
  '<div style="text-align: center;">' +
  '<button id="bl_add"    style="margin-right: 5px;">Add</button>' +
  '<button id="bl_close"  style="margin-right: 5px;">Close</button>' +
  '<button id="bl_import" style="margin-right: 5px;">Import</button>' +
  '<button id="bl_export" style="margin-right: 0px;">Export</button>' +
  '</div>' +
  '</div>' +

  // Add Block List Popup
  '<div id="bl" class="add" style="z-index: 100; position: fixed; width: 520px; top: 300px; left: 50%; margin: -250px; padding: 5px; text-align: center; display: none;">' +
  '<div style="position: relative; width: 80%; left: 10%; border-bottom: 3px solid; padding: 2px; text-align: center;">Add To Block List</div>' +

  '<div>' +
  '<p><label>Term: </label><input id="bl_term" value=""></p>' +
  '<p><label>Name: </label><input id="bl_name" value=""></p>' +
  '</div>' +

  '<div>' +
  '<button id="bl_add_save"   style="margin-right: 5px;">Save</button>' +
  '<button id="bl_add_cancel" style="margin-right: 0px;">Cancel</button>' +
  '</div>' +
  '</div>' +

  // Edit Block List Popup
  '<div id="edit_bl" class="add" class="add" style="z-index: 100; position: fixed; width: 520px; top: 300px; left: 50%; margin: -250px; padding: 5px; text-align: center; display: none;">' +
  '<div style="position: relative; width: 80%; left: 10%; border-bottom: 3px solid; padding: 2px; text-align: center;">Edit Block List Item</div>' +

  '<div>' +
  '<p><label>Term: </label><input id="edit_bl_term"  value=""disabled></p>' +
  '<p><label>Name: </label><input id="edit_bl_name" value=""></p>' +
  '</div>' +

  '<div>' +
  '<button id="edit_bl_save"   style="margin-right: 5px;">Save</button>' +
  '<button id="edit_bl_delete" style="margin-right: 5px;">Delete</button>' +
  '<button id="edit_bl_cancel" style="margin-right: 0px;">Cancel</button>' +
  '</div>' +
  '</div>' +

  // Include List
  '<div id="il_div" style="z-index: 99; position: fixed; width: 80%; height: 80%; left: 10%; top: 300px; margin-top: -250px; display: none;">' +
  '<div style="position: relative; width: 80%; left: 10%; border-bottom: 3px solid; padding: 2px; text-align: center;">Include List</div>' +
  '<div id="il_items"></div>' +
  '<div style="text-align: center;">' +
  '<button id="il_add"    style="margin-right: 5px;">Add</button>' +
  '<button id="il_close"  style="margin-right: 5px;">Close</button>' +
  '<button id="il_import" style="margin-right: 5px;">Import</button>' +
  '<button id="il_export" style="margin-right: 0px;">Export</button>' +
  '</div>' +
  '</div>' +

  // Add Include List Popup
  '<div id="il" class="add" style="z-index: 100; position: fixed; width: 520px; top: 300px; left: 50%; margin: -250px; padding: 5px; text-align: center; display: none;">' +
  '<div style="position: relative; width: 80%; left: 10%; border-bottom: 3px solid; padding: 2px; text-align: center;">Add To Include List</div>' +

  '<div>' +
  '<p><label>Term: </label><input id="il_term" value=""></p>' +
  '<p><label>Name: </label><input id="il_name" value=""></p>' +
  '</div>' +

  '<div style="position: relative; width: 80%; left: 10%; border-bottom: 3px solid; padding: 2px; text-align: center;">Alerts</div>' +

  '<p>' +
  '<label style="margin-right: 5px; display: inline-block; border-bottom: 1px solid;">Sound: ' +
  '<select id="il_sound">' +
  '<option value="1">Sound 1</option>' +
  '<option value="2">Sound 2</option>' +
  '<option value="3">Sound 3</option>' +
  '<option value="4">Sound 4</option>' +
  '</select>' +
  '</label>' +

  '<label style="margin-right: 5px; display: inline-block; border-bottom: 1px solid;">Desktop Notifications' +
  '<input id="il_noti_cb" type="checkbox">' +
  '</label>' +

  '<label style="margin-right: 5px; display: inline-block; border-bottom: 1px solid;">Play Sound' +
  '<input id="il_sound_cb" type="checkbox">' +
  '</label>' +

  '<label style="margin-right: 5px; display: inline-block; border-bottom: 1px solid;">Send Pushbullet' +
  '<input id="il_push_cb" type="checkbox">' +
  '</label>' +
  '</p>' +

  '<div>' +
  '<button id="il_add_save"   style="margin-right: 5px;">Save</button>' +
  '<button id="il_add_cancel" style="margin-right: 0px;">Cancel</button>' +
  '</div>' +
  '</div>' +

  // Edit Include List Popup
  '<div id="edit_il" class="add" style="z-index: 100; position: fixed; width: 520px; top: 300px; left: 50%; margin: -250px; padding: 5px; text-align: center; display: none;">' +
  '<div style="position: relative; width: 80%; left: 10%; border-bottom: 3px solid; padding: 2px; text-align: center;">Edit Include List Item</div>' +

  '<div>' +
  '<p><label>Term: </label><input id="edit_il_term" value="" disabled></p>' +
  '<p><label>Name: </label><input id="edit_il_name" value=""></p>' +
  '</div>' +

  '<div style="position: relative; width: 80%; left: 10%; border-bottom: 3px solid; padding: 2px; text-align: center;"">Alerts</div>' +

  '<p>' +
  '<label style="margin-right: 5px; display: inline-block; border-bottom: 1px solid;">Sound: ' +
  '<select id="edit_il_sound">' +
  '<option value="1">Sound 1</option>' +
  '<option value="2">Sound 2</option>' +
  '<option value="3">Sound 3</option>' +
  '<option value="4">Sound 4</option>' +
  '</select>' +
  '</label>' +

  '<label style="margin-right: 5px; display: inline-block; border-bottom: 1px solid;">Desktop Notifications' +
  '<input id="edit_il_noti_cb" type="checkbox">' +
  '</label>' +

  '<label style="margin-right: 5px; display: inline-block; border-bottom: 1px solid;">Play Sound' +
  '<input id="edit_il_sound_cb" type="checkbox">' +
  '</label>' +

  '<label style="margin-right: 0px; display: inline-block; border-bottom: 1px solid;">Send Pushbullet' +
  '<input id="edit_il_push_cb" type="checkbox">' +
  '</label>' +
  '</p>' +

  '<div>' +
  '<button id="edit_il_save"   style="margin-right: 5px;">Save</button>' +
  '<button id="edit_il_delete" style="margin-right: 5px;">Delete</button>' +
  '<button id="edit_il_cancel" style="margin-right: 0px;">Cancel</button>' +
  '</div>' +
  '</div>' +

  // Advanced Settings
  '<div id="sett" class="add" style="z-index: 100; position: fixed; width: 520px; top: 300px; left: 50%; margin: -250px; padding: 5px; text-align: center; display: none;">' +
  '<div style="position: relative; width: 80%; left: 10%; border-bottom: 3px solid; padding: 2px; text-align: center;">Advanced Settings</div>' +

  '<div>' +
  '<p><label>Pushbullet Token: </label><input id="push" value="' + config.push + '"></p>' +
  '</div>' +

  '<div style="position: relative; width: 80%; left: 10%; border-bottom: 3px solid; padding: 2px; text-align: center;">Theme</div>' +

  '<p>' +
  '<label style="margin-right: 5px; display: inline-block; border-bottom: 1px solid;">Theme: ' +
  '<select id="adv_theme" value="' + config.theme + '">' +
  '<option value="default">Default (Light)</option>' +
  '<option value="light">Pastel</option>' +
  '<option value="dark">Dark</option>' +
  '<option value="darker">Darker</option>' +
  '<option value="custom">Custom</option>' +
  '</select>' +
  '</label>' +

  '<label style="margin-right: 0px; display: inline-block; border-bottom: 1px solid;">TO Theme: ' +
  '<select id="to_theme" value="' + config.to_theme + '">' +
  '<option value="1">Default</option>' +
  '<option value="2">Column Only</option>' +
  '<option value="3">Text Only</option>' +
  '</select>' +
  '</label>' +
  '</p>' +

  '<p>' +
  '<label style="width: 150px; margin-right: 5px; display: inline-block; border-bottom: 1px solid; text-align: left;">Main: #' +
  '<input id="theme_main" style="width: 55px; float: right;" maxlength="6">' +
  '</label>' +

  '<label style="width: 150px; margin-right: 5px; display: inline-block; border-bottom: 1px solid; text-align: left;">Primary: #' +
  '<input id="theme_primary" style="width: 55px; float: right;" maxlength="6">' +
  '</label>' +

  '<label style="width: 150px; margin-right: 0px; display: inline-block; border-bottom: 1px solid; text-align: left;">Secondary: #' +
  '<input id="theme_secondary" style="width: 55px; float: right;" maxlength="6">' +
  '</label>' +
  '</p>' +

  '<p>' +
  '<label style="width: 150px; margin-right: 5px; display: inline-block; border-bottom: 1px solid; text-align: left;">Text: #' +
  '<input id="theme_text" style="width: 55px; float: right;" maxlength="6">' +
  '</label>' +

  '<label style="width: 150px; margin-right: 5px; display: inline-block; border-bottom: 1px solid; text-align: left;">Link: #' +
  '<input id="theme_link" style="width: 55px; float: right;" maxlength="6">' +
  '</label>' +

  '<label style="width: 150px; margin-right: 0px; display: inline-block; border-bottom: 1px solid; text-align: left;">Visited: #' +
  '<input id="theme_visited" style="width: 55px; float: right;" maxlength="6">' +
  '</label>' +
  '</p>' +

  '<div>' +
  '<button id="sett_save"  style="margin-right: 5px;">Save</button>' +
  '<button id="sett_close" style="margin-right: 0px;">Close</button>' +
  '</div>' +
  '</div>'
);

// Click functions
$('#scan_button').click(function () {
  if ($(this).text() === 'Start') {
    $(this).text('Stop');
    _scan();
  }
  else {
    $(this).text('Start');
  }
});

$('#sett_button').click(function () {
  $('#sett').toggle();
});

$('#conf_button').click(function () {
  if ($(this).text() === 'Hide Config') {
    $(this).text('Show Config');
  }
  else {
    $(this).text('Hide Config');
  }
  $('#config').toggleClass('hidden');
});

$('#logg_button').click(function () {
  if ($(this).text() === 'Hide Logged HITs') {
    $(this).text('Show Logged HITs');
    $('#logged_hits').hide();
  }
  else {
    $(this).text('Hide Logged HITs');
    $('#logged_hits').show();
  }
});

$('#bloc_button').click(function () {
  $('#bl_div').toggle();
});

$('#bl_add').click(function () {
  $('#bl').show();
});

$('#bl_close').click(function () {
  $('#bl_div').hide();
});

$('#bl_import').click(function () {
  _import_block();
});

$('#bl_export').click(function () {
  _export_block();
});

$('#bl_add_save').click(function () {
  var obj = {
    term : $('#bl_term').val(),
    name : $('#bl_name').val() === '' ? $('#bl_term').val() : $('#bl_name').val()
  };

  _add_block(obj);

  $('#bl_term, #bl_name').val('');
  $('#bl').hide();
});

$('#bl_add_cancel').click(function () {
  $('#bl_term, #bl_name').val('');
  $('#bl').hide();
});

$('#edit_bl_save').click(function () {
  _update_block($(this).val());
  $('#edit_bl_term, #edit_bl_name').val('');
  $('#edit_bl').hide();
});

$('#edit_bl_delete').click(function () {
  _delete_block($(this).val());
  $('#edit_bl_term, #edit_bl_name').val('');
  $('#edit_bl').hide();
});

$('#edit_bl_cancel').click(function () {
  $('#edit_bl_term, #edit_bl_name').val('');
  $('#edit_bl').hide();
});

$('#incl_button').click(function () {
  $('#il_div').toggle();
});

$('#il_add').click(function () {
  $('#il').show();
});

$('#il_close').click(function () {
  $('#il_div').hide();
});

$('#il_import').click(function () {
  _import_include();
});

$('#il_export').click(function () {
  _export_include();
});

$('#il_add_save').click(function () {
  var obj = {
    term     : $('#il_term').val().trim(),
    name     : $('#il_name').val().trim() === '' ? $('#il_term').val().trim() : $('#il_name').val().trim(),
    sound    : $('#il_sound').val(),
    noti_cb  : $('#il_noti_cb').prop('checked'),
    sound_cb : $('#il_sound_cb').prop('checked'),
    push_cb : $('#il_push_cb').prop('checked')
  };

  _add_include(obj);

  $('#il_term, #il_name').val('');
  $('#il').hide();
});

$('#il_add_cancel').click(function () {
  $('#il_term, #il_name').val('');
  $('#il').hide();
});

$('#edit_il_save').click(function () {
  _update_include($(this).val());
  $('#edit_il_term, #edit_il_name, #edit_il_sound').val('');
  $('#edit_il_noti_cb, #edit_il_sound_cb, #edit_il_push_cb').prop('checked', false);
  $('#edit_il').hide();
});

$('#edit_il_delete').click(function () {
  _delete_include($(this).val());
  $('#edit_il_term, #edit_il_name, #edit_il_sound').val('');
  $('#edit_il_noti_cb, #edit_il_sound_cb, #edit_il_push_cb').prop('checked', false);
  $('#edit_il').hide();
});

$('#edit_il_cancel').click(function () {
  $('#edit_il_term, #edit_il_name, #edit_il_sound').val('');
  $('#edit_il_noti_cb, #edit_il_sound_cb, #edit_il_push_cb').prop('checked', false);
  $('#edit_il').hide();
});

$('.on, .off').click(function () {
  $(this).toggleClass('on off');
  _save();
});

$('#sett_save').click(function () {
  _save('custom');
  _theme();
});

$('#sett_close').click(function () {
  $('#sett').hide();
});

$('#time').click(function () {
  $('.new').removeClass('new');
});

// Delegated click functions
$('body').on('click', '.blockit', function () {
  _edit_block($(this).val());
});

$('body').on('click', '.includeit', function () {
  _edit_include($(this).val());
});

$('body').on('click', '.rt', function () {
  _block($(this).data('term'), $(this).data('name'));
});

$('body').on('click', '.pc', function () {
  _panda($(this).data('term'), $(this).data('name'));
    $(this).addClass("clicked");
});

$('body').on('click', '.vb', function () {
  _export_vb($(this).val());
});

$('body').on('click', '.irc', function () {
  _export_irc($(this).val());
});

$('body').on('click', '.details', function () {
  $(this).toggleClass('fa-plus-circle fa-minus-circle');
  $('.info[value="' + $(this).val() + '"]').toggle();
});

// Delegated mouseover functions
$('body').on('mouseover', '.new', function () {
  $(this).removeClass('new');
});

// On change events
$('#new_audio').change(function () {
  _save();
  _sound('new');
});

$('#il_sound').change(function () {
  _sound('il');
});

$('#edit_il_sound').change(function () {
  _sound('il_edit');
});

$('#type, #size, #adv_theme, #to_theme, #c_theme, :checkbox').change(function () {
  _save();
});

$('#adv_theme, #to_theme, #c_theme').change(function () {
  _theme();
});

// On input events
$('#delay, #min_rew, #min_avail, #min_to, #alert_delay').on('input', function () {
  _save();
});

function _scan () {
  var searchqualvar
  searchqualvar = (config.qual ? 'on' : 'off');
  

  if ($('#scan_button').text() === 'Stop') {
    var _url = url + $('#type').val() + $('#size').val() + minrew + $('#min_rew').val() + searchqual + searchqualvar;

    var date = new Date(), h = date.getHours(), m = date.getMinutes(), s = date.getSeconds(), ampm = h >= 12 ? 'pm' : 'am';
    h = h % 12; h = h ? h : 12; m = m < 10 ? '0' + m : m; s = s < 10 ? '0' + s : s;
    var timeis = [h, m, s, ampm];

    $.get(_url, function (data) {
      _scrape_new(data, timeis);
    }).fail(function () {
      setTimeout(function () { _scan(); }, 2500);
    });
  }
  
  if (turkerview_update > 700 ) {
      turkerview_update = 0;
      _loadTVData();
  }
  else {
      turkerview_update += 1;
  }
  console.log(turkerview_update);
}

function _scrape_new (data, timeis) {
  var keys = [], log_keys = [], to = [], logged_in = true;

  var hits = data.results;

  for (var i = 0; i < hits.length; i ++) {
    var hit = hits[i],
        req_name  = hit.requester_name,
        req_id    = hit.requester_id,
        req_link  = hit.requester_url,
        //req_link  = 'https://www.mturk.com/mturk/searchbar?selectedSearchType=hitgroups&requesterId=' + hit.requester_id,
        con_link  = 'https://www.mturk.com/mturk/contact?requesterId=' + hit.requester_id,
        group_id  = hit.hit_set_id,
        prev_link = hit.project_tasks_url,
        //prev_link = 'https://www.mturk.com/mturk/preview?groupId=' + hit.hit_set_id,
        pand_link = hit.accept_project_task_url,
        //pand_link = 'https://www.mturk.com/mturk/previewandaccept?groupId=' + hit.hit_set_id,
        title     = hit.title,
        safetitle = title.replace(/"/g, "&quot;" ),
        desc      = hit.description,
        time      = _convert_seconds(hit.assignment_duration_in_seconds),
        reward    = '$' + hit.monetary_reward.amount_in_dollars.toFixed(2),
        avail     = hit.assignable_hits_count;

    var key = req_id + title + reward + group_id;
    keys.push(key);


    var qualif = 'None';
    var quals = hit.project_requirements;

    if (quals.length) {
      qualif = ''
      for (var j = 0; j < quals.length; j ++) {
        var q_comp = quals[j].comparator + ' ';
        var q_name = quals[j].qualification_type.name + ' ';

        var q_valu = quals[j].qualification_values;
        var q_values = '';
        for (var k = 0; k < quals.length; k ++) {
          if (quals[j].qualification_values[k]) {
            q_values += quals[j].qualification_values[k];
            q_values += k === quals.length ? ', ' : '';
          }
        }
        qualif += (q_name + q_comp + q_values).trim() + '; ';
      }
    }

    console.log(qualif);


    if (!hitlog[key]) {
      hitlog[key] = {
        reqname  : req_name,
        reqid    : req_id,
        reqlink  : req_link,
        conlink  : con_link,
        groupid  : group_id,
        prevlink : prev_link,
        pandlink : pand_link,
        title    : title,
        safetitle: safetitle,
        desc     : desc,
        time     : time,
        reward   : reward,
        avail    : avail,
        quals    : qualif.trim(),
        masters  : '?',
        key      : key,
        tolink   : 'https://turkopticon.ucsd.edu/' + req_id,
        to       : { comm : 'N/A', fair : 'N/A', fast : 'N/A', pay  : 'N/A' },
        rcolor   : '#F08080',
        tcolor   : '#F08080'
      };
      to.push([key, req_id]);
      log_keys.push(key);
    }
    else {
      hitlog[key].avail = avail;
    }
  }
  _to(keys, log_keys, logged_in, to, timeis);
}

function _loadTVData () {
    GM_xmlhttpRequest ({
        method: "GET",
        url: 'https://turkerview.com/api/v1/hindsight/?t=30',
        onload: function(response) {
            var tvdata = response.responseText;
            turkerview = JSON.parse(tvdata);
        }
    });
}

function _getTVHourly( reqid ) {
    var tvHourly;
    if( reqid in turkerview ) {
        tvHourly = '$' + turkerview[reqid]['ratings']['hourly'];
    }
    else {
        tvHourly = 'N/A';
    }
    
    return tvHourly;
}

function _to (keys, log_keys, logged_in, to, timeis) {
  var ids = [];

  if (logged_in && to.length && config.to) {
    for (var i = 0; i < to.length; i++) {
      ids.push(to[i][1]);
    }
    $.get('https://turkopticon.ucsd.edu/api/multi-attrs.php?ids=' + ids, function (data) {
      var to_data = JSON.parse(data);

      for (i = 0; i < to.length; i++) {
        if (!to_data[to[i][1]].length && typeof to_data[to[i][1]].attrs != 'undefined') {
          hitlog[to[i][0]].to = to_data[to[i][1]].attrs;
        }
      }
    }).always(function () {
      _build(keys, log_keys, timeis);
    });
  }
  else {
    _build(keys, log_keys, timeis);
  }
}

function _build (keys, log_keys, timeis) {
  var hit_html = '', log_html = '';
  var tvHourly;

  for (var i = 0; i < keys.length; i++) {
    var hit = hitlog[keys[i]], blocked = _check_block(hit), included = _check_include(hit), remove = false, classes, tvHourly;
        
      tvHourly = _getTVHourly( hit.reqid ); 

        // Figure out color
        if (tvHourly != 'N/A') {
            rowcolor = _color_tv(tvHourly.replace(/\$/g, ''));
        }
        else {
            rowcolor = _color_to(hit);
        }

        
        classes = rowcolor;

    if (hit.masters === 'Y') {
      classes += config.m ? ' m_hidden' : ' m';
    }

    if (Number(config.avail) > Number(hit.avail) || Number(config.mto) > Number(hit.to.pay)) {
      classes += ' hidden';
      remove = true;
    }

    if (blocked) {
      classes += config.bl ? ' bl_hidden' : ' bl';
      remove = true;
    }
    if (included) {
      classes += ' il';
      _included(included, hit);
    }
    else {
      classes += config.nl ? ' nl_hidden' : ' nl';
    }
    
    if( hit.reqid in turkerview ) {
        tvHourly = '$' + turkerview[hit.reqid]['ratings']['hourly'];
    }
    else {
        tvHourly = 'N/A';
    }
      
    hit_html +=
      '<div class="cont" style="margin-bottom: 2px;">' +
      '<div class="' + classes + ' " style="overflow: hidden; white-space: nowrap; margin-bottom: 2px;">' +

      '<div style="float: left; width: calc(100% - 330px);">' +

      '<span style="width: 34%; float: left; display:inline-block; overflow: hidden;">' +
      '<button data-term="' + hit.reqid + '" data-name="' + hit.reqname + '" class="rt">R</button>' +
      '<button data-term="' + hit.safetitle + '" data-name="' + hit.safetitle + '" class="rt">T</button>' +
      '<a href="' + hit.reqlink + '">' + hit.reqname + '</a>' +
      '</span>' +

      '<span style="width: 64%; float: right; display:inline-block; overflow: hidden;">' +
      '<button value="' + hit.key + '" class="vb">vB</button>' +
      '<button value="' + hit.key + '" class="irc">IRC</button>' +
      '<a href="' + hit.prevlink + '">' + hit.title + '</a>' +
      '</span>' +

      '</div>' +

      '<div style="float: right;">' +

      '<span style="width: 60px; display:inline-block; text-align: center;">' +
      hit.avail +
      '</span>' +

      '<span style="width: 60px; display:inline-block; text-align: center;">' +
      '<a href="' + hit.pandlink + '">' + hit.reward + '</a>' +
      '</span>' +
    
      '<span class="to" style="width: 60px; display:inline-block; text-align: center;">' +
      '<a href="https://turkerview.com/requesters/' + hit.reqid + '">' + tvHourly + '</a>' +
      '</span>' +

      '<span class="to" style="width: 60px; display:inline-block; text-align: center;">' +
      '<a href="' + hit.tolink + '">' + hit.to.pay + '</a>' +
      '</span>' +

      '<span style="width: 30px; display:inline-block; text-align: center;">' +
      hit.masters +
      '</span>' +

      '<span style="width: 60px; display:inline-block; text-align: center;">' +
      '<button data-term="' + hit.groupid + '" data-name="panda" class="pc">P</button>' +
      '<button data-term="' + hit.groupid + '" data-name="once" class="pc">O</button>' +
      '</span>' +

      '</div>' +
      '</div>' +
      '</div>'
    ;

    if (remove) {
      var index = log_keys.indexOf(keys[i]);

      if (index > -1) {
        log_keys.splice(index, 1);
      }
    }
  }

  if (log_keys.length) {
    for (var j = 0; j < log_keys.length; j ++) {
      var hit_log = hitlog[log_keys[j]], included_log = _check_include(hit_log), rowcolor, classes_log, tvHourly;
        
        if( hit_log.reqid in turkerview ) {
            tvHourly = '$' + turkerview[hit_log.reqid]['ratings']['hourly'];
        }
        else {
            tvHourly = 'N/A';
        }

        // Figure out color
        if (tvHourly != 'N/A') {
            rowcolor = _color_tv(tvHourly.replace(/\$/g, ''));
        }
        else {
            rowcolor = _color_to(hit_log);
        }

        
        classes_log = rowcolor;

      if (hit_log.masters === 'Y') {
        classes_log += config.m ? ' m_hidden' : ' m';
      }

      if (included_log) {
        classes_log += ' il';
      }
      else {
        classes_log += config.nl ? ' nl_hidden' : ' nl';
      }

      var quals = hit_log.quals.split(';');
      var qualif = '';

      for (var k = 0; k < quals.length; k ++) {
        if (quals[k] !== '') {
          qualif += '<li style="padding: 2px;">' + quals[k] + '</li>';
        }
      }
        
      

      log_html +=
        '<div class="cont" style="margin-bottom: 2px;">' +
        '<div class="' + classes_log + '" style="overflow: hidden; white-space: nowrap;">' +

        '<div style="float: left;">' +
        '<span style="width: 80px; display:inline-block;">' +
        '<button class="fa fa-plus-circle fa-2 details" aria-hidden="true" value="' + hit_log.key + '" style="background-color: transparent; border: 0px; padding: 1px;"></button>' +
        timeis[0] + ':' + timeis[1]  + timeis[3] + '</span>' +
        '</div>' +

        '<div style="float: left; width: calc(100% - 350px);">' +

        '<span style="width: 34%; float: left; display:inline-block; overflow: hidden;">' +
        '<button data-term="' + hit_log.reqid + '" data-name="' + hit_log.reqname + '" class="rt">R</button>' +
        '<button data-term="' + hit_log.safetitle + '" data-name="' + hit_log.safetitle + '" class="rt">T</button>' +
        '<a href="' + hit_log.reqlink + '">' + hit_log.reqname + '</a>' +
        '</span>' +

        '<span style="width: 64%; float: right; display:inline-block; overflow: hidden;">' +
        '<button value="' + hit_log.key + '" class="vb">vB</button>' +
        '<button value="' + hit_log.key + '" class="irc">IRC</button>' +
        '<a href="' + hit_log.prevlink + '">' + hit_log.title + '</a>' +
        '</span>' +

        '</div>' +

        '<div style="float: right;">' +

        '<span style="width: 60px; display: inline-block; text-align: center;">' +
        '<a href="' + hit_log.pandlink + '">' + hit_log.reward + '</a>' +
        '</span>' +

        '<span class="to" style="width: 60px; display:inline-block; text-align: center;">' +
        '<a href="https://turkerview.com/requesters/' + hit_log.reqid + '">' + tvHourly + '</a>' +
          '</span>' +
          
        '<span class="to" style="width: 60px; display:inline-block; text-align: center;">' +
        '<a href="' + hit_log.tolink + '">' + hit_log.to.pay + '</a>' +
        '</span>' +

        '<span style="width: 30px; display:inline-block; text-align: center;">' +
        hit_log.masters +
        '</span>' +

        '<span style="width: 60px; display:inline-block; text-align: center;">' +
        '<button data-term="' + hit_log.groupid + '" data-name="panda" class="pc">P</button>' +
        '<button data-term="' + hit_log.groupid + '" data-name="once" class="pc">O</button>' +
        '</span>' +

        '</div>' +
        '</div>'+

        '<div class="info ' + rowcolor + '" value="' + hit_log.key + '" style="overflow: hidden; display: none; font-size: 11px;">' +

        '<div style="border-bottom: 1px solid #000000;"></div>' +

        '<span style="width: 33%; float: left; display:inline-block; padding: 5px;">' +
        '<span style="text-decoration: underline;">Description</span>' +
        '<div style="padding: 2px;">' + hit_log.desc +'</div>' +
        '<span style="text-decoration: underline;">Time</span>' +
        '<div style="padding: 2px;">' + hit_log.time +'</div>' +
        '</span>' +

        '<span style="width: 33%; float: left; display:inline-block; padding: 5px;">' +
        '<span style="text-decoration: underline;">Qualifications</span>' +
        qualif +
        '</span>' +

        '<span style="width: calc(34% - 30px); float: right; display:inline-block; padding: 5px;">' +
        '<span style="text-decoration: underline;">Turkopticon</span>' +
        '<br>' +
        '<span style="width: 70px; display:inline-block; padding: 2px;">Pay  : ' + hit_log.to.pay +'</span>' +
        '<span style="width: 70px; display:inline-block; padding: 2px;">Fair : ' + hit_log.to.fair +'</span>' +
        '<br>' +
        '<span style="width: 70px; display:inline-block; padding: 2px;">Comm : ' + hit_log.to.comm +'</span>' +
        '<span style="width: 70px; display:inline-block; padding: 2px;">Fast : ' + hit_log.to.fast +'</span>' +
        '</span>' +

        '</div>' +
        '</div>';

      logged ++;
    }
    if (config.new) {
      _sound('new');
    }
  }
  $('#new_hits').html(hit_html);
  $('#log_hits').prepend(log_html);

  searches ++;
  var hits_data = '<span> ' + timeis[0] + ':' + timeis[1] + ':' + timeis[2] + timeis[3] + ' Scanned HITs: ' + keys.length + '</span><span style="float: right;">' + searches + '</span>';
  var logged_hits_data = '<span style="float: right;">' + logged + '</span>';

  $('#hits_data').html(hits_data);
  $('#logged_hits_data').html(logged_hits_data);

  if ($('#scan_button').text() === 'Stop') {
    setTimeout(function () {
      _scan();
    }, $('#delay').val() * 1000);
  }
}

function _sound (sound) {
  if (sound === 'new')     { $('#audio_' + config.newaudio)           [0].play(); }
  if (sound === 'include') { $('#audio_' + config.newaudio)           [0].play(); }
  if (sound === 'il')      { $('#audio_' + $('#il_sound').val())      [0].play(); }
  if (sound === 'il_edit') { $('#audio_' + $('#edit_il_sound').val()) [0].play(); }
}

function _check_block (hit) {
  for (var key in blocklist) {
    var obj = blocklist[key];
    if (obj.term.toLowerCase() === hit.reqname.toLowerCase() || obj.term.toLowerCase() === hit.title.toLowerCase() || obj.term.toLowerCase() === hit.reqid.toLowerCase() || obj.term.toLowerCase() === hit.groupid.toLowerCase()) {
      return obj;
    }
  }
}

function _check_include (hit) {
  for (var key in includelist) {
    var obj = includelist[key];
    if (obj.term.toLowerCase() === hit.reqname.toLowerCase() || obj.term.toLowerCase() === hit.title.toLowerCase() || obj.term.toLowerCase() === hit.reqid.toLowerCase() || obj.term.toLowerCase() === hit.groupid.toLowerCase()) {
      return obj;
    }
  }
}

function _included (obj, hit) {
  var check = noti_delay.indexOf(hit.key) !== -1;
  var pushcheck = push_delay.indexOf(hit.key) !== -1;

  if (!check) {
    noti_delay.unshift(hit.key);
    setTimeout(function () { noti_delay.pop(); }, config.alert * 1000);
  }
  if (obj.noti_cb && !check) {
    Notification.requestPermission();
    var n = new Notification(hit.reqname + ' | ' + hit.reward, {
      icon : 'http://kadauchi.com/avatar4.jpg',
      body : hit.title,
    });
    setTimeout(n.close.bind(n), 5000);

    n.onclick = function(e) {
      e.preventDefault();
      window.open(hit.prevlink, '_blank');
    };

  }
  if (obj.sound_cb && !check) {
    $('#audio_' + obj.sound)[0].play();
  }
  if (obj.push_cb && !pushcheck && config.pb) {
    push_delay.unshift(hit.key);
    setTimeout(function () { push_delay.pop(); }, 900000);

    var push = {};

    push['type'] = 'note';
    push['title'] = 'HIT Finder';
    push['body'] = '[' + hit.reqname + ']\n[' + hit.title + ']\n[' + hit.reward + ']\n[' + hit.prevlink + ']';

    $.ajax({
      type    : 'POST',
      headers : {'Authorization': 'Bearer ' + config.push},
      url     : 'https://api.pushbullet.com/v2/pushes',
      data    : push
    });

  }
}

function _color_tv(tvHourly) {
    if (config.theme == "light") {
      if (tvHourly >= 10.00) { return 'tvHigh'; }
      else if (tvHourly >= 7.25) { return 'tvFair'; }
      else { return 'tvLow'; }
    }
    else {
      if (tvHourly >= 10.00) { return 'toHigh'; }
      else if (tvHourly >= 7.25) { return 'toAverage'; }
      else { return 'toLow'; }
      
    }
  }

function _color_to (hit) {
  var to = hit.to.pay;
  
  if (config.theme == "light") {
    if      (to > 4) { return 'tvHigh';    }
    else if (to > 2.5) { return 'tvFair';    }
    else if (to > 0) { return 'tvLow'; }
    else             { return 'tvNone';    }
  }
  else {
    if      (to > 4) { return 'toHigh';    }
    else if (to > 3) { return 'toGood';    }
    else if (to > 2) { return 'toAverage'; }
    else if (to > 1) { return 'toLow';     }
    else if (to > 0) { return 'toPoor';    }
    else             { return 'toNone';    }
    
  }
}

function _color_db (hit) {
  if (hitdb.db && hitdb.db.objectStoreNames.contains('HIT')) {
    hitdb.db.transaction('HIT', 'readonly').objectStore('HIT').index('title').get(hit.title).onsuccess = function (e) {
      if (e.target.result) {
        hitlog[hit.key].tcolor = '#90EE90';
      }
    };
    hitdb.db.transaction('HIT', 'readonly').objectStore('HIT').index('requesterId').get(hit.reqid).onsuccess = function (e) {
      if (e.target.result) {
        hitlog[hit.key].rcolor = '#90EE90';
      }
    };
  }
}

function _convert_seconds (seconds) {
  seconds = Number(seconds);
  var h = Math.floor(seconds / 3600);
  var m = Math.floor(seconds % 3600 / 60);
  var s = Math.floor(seconds % 3600 % 60);
  var time = '';
  if (h > 0) { time += h + ' hour(s) ';    }
  if (m > 0) { time += m + ' minutes(s) '; }
  if (s > 0) { time += s + ' seconds(s)';  }
  return time;
}

function _block (term, name) {
  $('#bl_term') .val(term);
  $('#bl_name') .val(name);
  $('#bl')      .show();
}

function _panda(term, name) {
    if ( name == "panda" ) {
        localStorage.setItem("JR_message_pandacrazy", JSON.stringify({"time":(new Date().getTime()),"command":"addJob","data":{"groupId":term} }));
    }
    else if ( name == "once" ) {
        localStorage.setItem("JR_message_pandacrazy", JSON.stringify({"time":(new Date().getTime()),"command":"addOnceJob","data":{"groupId":term} }));
    }
}


function _add_block (obj) {
  if (!blocklist[obj.term]) {
    blocklist[obj.term] = obj;
    _init_lists();
  }
}

function _edit_block (term) {
  var obj = blocklist[term];
  $('#edit_bl_term')   .val(obj.term) .text(obj.term);
  $('#edit_bl_name')   .val(obj.name);
  $('#edit_bl_save')   .val(obj.term);
  $('#edit_bl_delete') .val(obj.term);
  $('#edit_bl')        .show();
}

function _update_block (block) {
  var obj = blocklist[block];
  obj.name = $('#edit_bl_name').val();
  _init_lists();
}

function _delete_block (block) {
  delete blocklist[block];
  _init_lists();
}

function _add_include (obj) {
  if (!includelist[obj.term]) {
    includelist[obj.term] = obj;
    _init_lists();
  }
}

function _edit_include (term) {
  var obj = includelist[term];

  $('#edit_il_term')  .val(obj.term) .text(obj.term);
  $('#edit_il_name')  .val(obj.name);
  $('#edit_il_sound') .val(obj.sound);

  $('#edit_il_noti_cb')  .prop('checked', obj.noti_cb);
  $('#edit_il_sound_cb') .prop('checked', obj.sound_cb);
  $('#edit_il_push_cb') .prop('checked', obj.push_cb);

  $('#edit_il_save')   .val(obj.term);
  $('#edit_il_delete') .val(obj.term);

  $('#edit_il').show();
}

function _update_include (term) {
  var obj = includelist[term];
  obj.name     = $('#edit_il_name')  .val().trim();
  obj.sound    = $('#edit_il_sound') .val().trim();
  obj.noti_cb  = $('#edit_il_noti_cb')  .prop('checked');
  obj.sound_cb = $('#edit_il_sound_cb') .prop('checked');
  obj.push_cb = $('#edit_il_push_cb') .prop('checked');
  _init_lists();
}

function _delete_include (term) {
  delete includelist[term];
  _init_lists();
}

function _init_lists () {
  var bl_sort = [], il_sort = [], bl_html = '', il_html = '';

  for (var bl_key in blocklist) {
    bl_sort.push([bl_key, blocklist[bl_key].name]);
  }

  bl_sort.sort(function (a, b) {
    if (a[1].toLowerCase() < b[1].toLowerCase()) return -1;
    if (a[1].toLowerCase() > b[1].toLowerCase()) return 1;
    return 0;
  });

  for (var i = 0; i < bl_sort.length; i ++) {
    var bl_obj = blocklist[bl_sort[i][0]];
    bl_html += '<button class="blockit" style="margin: 2px;" value="' + bl_obj.term + '" title="' + bl_obj.term + '">' + bl_obj.name + '</button>';
  }

  for (var il_key in includelist) {
    il_sort.push([il_key, includelist[il_key].name]);
  }

  il_sort.sort(function (a, b) {
    if (a[1].toLowerCase() < b[1].toLowerCase()) return -1;
    if (a[1].toLowerCase() > b[1].toLowerCase()) return 1;
    return 0;
  });

  for (var j = 0; j < il_sort.length; j ++) {
    var il_obj = includelist[il_sort[j][0]];
    il_html += '<button class="includeit" style="margin: 2px;" value="' + il_obj.term + '" title="' + il_obj.term + '">' + il_obj.name + '</button>';
  }

  $('#bl_items') .html(bl_html);
  $('#il_items') .html(il_html);
  _save('init');
}

function _import_block () {
  var import_bl  = prompt(
    'Block List Import\n\n' +
    'You can import from HIT Finder or HIT Scraper.\n\n' +
    'This will not delete your current block list, only add to it.\n\n' +
    'Please enter your block list here.',
    ''
  );

  if (import_bl) {
    var json = _json_validator(import_bl);

    if (json) {
      var _bl_obj = JSON.parse(import_bl);
      for (var key in _bl_obj) {
        if (_bl_obj[key].hasOwnProperty('term') && _bl_obj[key].hasOwnProperty('name') && !_bl_obj[key].hasOwnProperty('sound')) {
          if (!blocklist[key]) {
            blocklist[key] = {
              term : _bl_obj[key].term,
              name : _bl_obj[key].name
            };
          }
        }
        else {
          alert('An error occured while importing.\n\n Please check if you have a valid import and try again.');
          break;
        }
      }
      _init_lists();
    }
    else if (import_bl.match(/^/)) {
      var _bl_arr = import_bl.trim().split('^');
      for (var i = 0; i < _bl_arr.length; i ++) {
        if (!blocklist[_bl_arr[i]]) {
          blocklist[_bl_arr[i]] = {
            term : _bl_arr[i],
            name : _bl_arr[i]
          };
        }
      }
      _init_lists();
    }
  }
  else {
    alert('An error occured while importing.\n\n Please check if you have a valid import and try again.');
  }
}

function _export_block () {
  GM_setClipboard(localStorage.getItem('_finder_bl'));
  alert('Your block list has been copied to your clipboard.');
}

function _import_include () {
  var import_il  = prompt(
    'Include List Import\n\n' +
    'You can import from HIT Finder or HIT Scraper.\n\n' +
    'This will not delete your current include list, only add to it.\n\n' +
    'Please enter your include list here.',
    ''
  );

  if (import_il) {
    var json = _json_validator(import_il);

    if (json) {
      var _il_obj = JSON.parse(import_il);

      for (var key in _il_obj) {
        if (_il_obj[key].hasOwnProperty('term') && _il_obj[key].hasOwnProperty('name') && _il_obj[key].hasOwnProperty('sound')) {
          if (!includelist[key]) {
            includelist[key] = {
              term     : _il_obj[key].term,
              name     : _il_obj[key].name,
              sound    : _il_obj[key].sound,
              noti_cb  : _il_obj[key].noti_cb,
              sound_cb : _il_obj[key].sound_cb,
              push_cb  : _il_obj[key].push_cb
            };
          }
        }
        else {
          alert('An error occured while importing.\n\n Please check that you have a valid import and try again.');
          break;
        }
      }
      _init_lists();
    }
    else if (import_il.match(/^/)) {
      var _il_arr = import_il.split('^');

      for (var i = 0; i < _il_arr.length; i ++) {
        if (!includelist[_il_arr[i]]) {
          includelist[_il_arr[i]] = {
            term     : _il_arr[i],
            name     : _il_arr[i],
            sound    : '1',
            noti_cb  : true,
            sound_cb : true,
            push_cb  : false
          };
        }
      }
      _init_lists();
    }
  }
  else {
    alert('An error occured while importing.\n\n Please check that you have a valid import and try again.');
  }
}

function _export_include () {
  GM_setClipboard(localStorage.getItem('_finder_il'));
  alert('Your include list has been copied to your clipboard.');
}

function _export_vb (key) {
  var hit = hitlog[key];

  var pay = hit.to.pay,  _pay = '#B30000';
  if      (pay > 3.99) { _pay = '#00B300'; }
  else if (pay > 2.99) { _pay = '#B3B300'; }
  else if (pay > 1.99) { _pay = '#B37400'; }

  var fair = hit.to.fair, _fair = '#B30000';
  if      (fair > 3.99) { _fair = '#00B300'; }
  else if (fair > 2.99) { _fair = '#B3B300'; }
  else if (fair > 1.99) { _fair = '#B37400'; }

  var comm = hit.to.comm, _comm = '#B30000';
  if      (comm > 3.99) { _comm = '#00B300'; }
  else if (comm > 2.99) { _comm = '#B3B300'; }
  else if (comm > 1.99) { _comm = '#B37400'; }

  var fast = hit.to.fast, _fast = '#B30000';
  if      (fast > 3.99) { _fast = '#00B300'; }
  else if (fast > 2.99) { _fast = '#B3B300'; }
  else if (fast > 1.99) { _fast = '#B37400'; }

  var exportcode = '[table][tr][td]'+
      '[b]Title:[/b] [URL=' + pandaurl + hit.prevlink + ']' + hit.title + '[/URL] | [URL=' + pandaurl + hit.pandlink + ']PANDA[/URL]\n' +
      '[b]Requester:[/b] [URL=' + pandaurl + hit.reqlink + ']' + hit.reqname + '[/URL] [' + hit.reqid + '] ([URL=' + pandaurl + hit.conlink + ']Contact[/URL])\n' +
      '([URL='+hit.tolink+']TO[/URL]):'+
      '[b] \[Pay: [COLOR=' + _pay + ']' + pay + '[/COLOR]\][/b]'+
      '[b] \[Fair: [COLOR=' + _fair + ']' + fair + '[/COLOR]\][/b]' +
      '[b] \[Comm: [COLOR=' + _comm +']' + comm + '[/COLOR]\][/b]' +
      '[b] \[Fast: [COLOR=' + _fast + ']' + fast + '[/COLOR]\][/b]\n' +
      '[b]Description:[/b] ' + hit.desc + '\n' +
      '[b]Time:[/b] ' + hit.time + '\n' +
      '[b]HITs Available:[/b] ' + hit.avail + '\n' +
      '[b]Reward:[/b] [COLOR=green][b] ' + hit.reward + '[/b][/COLOR]\n' +
      '[b]Qualifications:[/b] ' + hit.quals + '\n' +
      '[/td][/tr][/table]';

  GM_setClipboard(exportcode);
  alert('Forum export has been copied to your clipboard.');
}

function _export_irc (key) {
  var hit = hitlog[key];

  $.get('https://ns4t.net/yourls-api.php?action=bulkshortener&title=MTurk&signature=39f6cf4959&urls[]=' + hit.prevlink + '&urls[]=' + hit.pandlink, function (data) {
    var urls = data.split(';'),
        preview = urls[0],
        panda   = urls[1];

    var exportcode = hit.masters === 'Y' ? 'MASTERS ■ Req: ' + hit.reqname + ' ■ Title: ' + hit.title + ' ■ Reward: ' + hit.reward : 'Req: ' + hit.reqname + ' ■ Title: ' + hit.title + ' ■ Reward: ' + hit.reward;
    exportcode += preview !== panda ? ' ■ Prev: ' + preview + ' ■ PandA: '+ panda : ' ■ Search: ' + preview;
    exportcode += ' ■ TO: (Pay: ' + hit.to.pay + ') (Fair: ' + hit.to.fair + ') (Comm: ' + hit.to.comm + ') (Fast: ' + hit.to.fast + ')';

    GM_setClipboard(exportcode);
    alert('IRC export has been copied to your clipboard.');

  }).fail(function () {
    alert('Failed to shorten links.');
  });
}

function _json_validator (data) {
  try {
    JSON.parse(data);
    return true;
  }
  catch (e) {
    return false;
  }
}

function _save (type) {
  if (type !== 'init' && type !== 'custom') {
    config.delay    = $('#delay')       .val();
    config.rew      = $('#min_rew')     .val();
    config.avail    = $('#min_avail')   .val();
    config.mto      = $('#min_to')      .val();
    config.alert    = $('#alert_delay') .val();
    config.type     = $('#type')        .val();
    config.size     = $('#size')        .val();
    config.newaudio = $('#new_audio')   .val();
    config.theme    = $('#adv_theme')   .val();
    config.to_theme = $('#to_theme')    .val();

    config.new  = $('#new_sound') .prop('checked');
    config.pb   = $('#pb')        .prop('checked');
    config.to   = $('#to')        .prop('checked');
    config.qual = $('#qual')      .prop('checked');
    config.nl   = $('#nl_hide')   .prop('checked');
    config.bl   = $('#bl_hide')   .prop('checked');
    config.m    = $('#m_hide')    .prop('checked');
    console.log($('#push').val());

  }
  if (type === 'custom' && $('#adv_theme').val() === 'custom') {
    config.custom = {
      main      : $('#theme_main')      .val(),
      primary   : $('#theme_primary')   .val(),
      secondary : $('#theme_secondary') .val(),
      text      : $('#theme_text')      .val(),
      link      : $('#theme_link')      .val(),
      visited   : $('#theme_visited')   .val(),
      prop      : false
    };
    themes.custom = config.custom;
  }
  config.push     = $('#push').val();

  localStorage.setItem('_finder', JSON.stringify(config));
  localStorage.setItem('_finder_bl', JSON.stringify(blocklist));
  localStorage.setItem('_finder_il', JSON.stringify(includelist));

  if (config.nl) { $('.nl').toggleClass('nl nl_hidden');        }
  else           { $('.nl_hidden').toggleClass('nl nl_hidden'); }

  if (config.bl) { $('.bl').toggleClass('bl bl_hidden');        }
  else           { $('.bl_hidden').toggleClass('bl bl_hidden'); }

  if (config.m) { $('.m').toggleClass('m m_hidden');        }
  else          { $('.m_hidden').toggleClass('m m_hidden'); }
}

function _theme () {
  var theme = themes[config.theme];

  $('#theme_main')      .val(theme.main)      .prop('disabled', theme.prop);
  $('#theme_primary')   .val(theme.primary)   .prop('disabled', theme.prop);
  $('#theme_secondary') .val(theme.secondary) .prop('disabled', theme.prop);
  $('#theme_text')      .val(theme.text)      .prop('disabled', theme.prop);
  $('#theme_link')      .val(theme.link)      .prop('disabled', theme.prop);
  $('#theme_visited')   .val(theme.visited)   .prop('disabled', theme.prop);
  _write_theme();
}

function _write_theme () {
  var css  = _to_theme(), theme = themes[config.theme];

  css +=
    'html {color: #' + theme.text + '; background-color: #' + theme.main + '; line-height: 1.5; font-family: "Roboto", sans-serif; font-size: 15px; font-weight: normal;}' +
    'body {margin: 0px;}' +
    '#menubar { background-color: #' + theme.menu + '; margin: 0px; padding: 3px; height:30px; color: #' + theme.menutext + ' }' +
    '#latest_hits { margin: 5px; }' +
    '#logged_hits { margin: 5px; }' +
    '#config { background-color: #' + theme.primary + '; border: 2px #' + theme.text + ' solid; padding: 2px;}' +

    '#bl_items, #il_items {background-color: #'+theme.main+'; height: calc(100% - 64px); overflow-y: scroll;}' +
    '#bl_div, #il_div {background-color: #'+theme.primary+'; border: 2px solid #'+theme.secondary+';}' +

    '.add {background-color: #'+theme.primary+'; border: 2px solid #'+theme.secondary+';}' +

    '.bl {border: 2px solid  #FF0000;}' +
    '.il {border: 2px solid  #009900;}' +
    '.hidden, .nl_hidden, .bl_hidden, .m_hidden {display: none;}' +
    'button:focus {outline: none !important;}';

    if (config.theme == 'light' ) {
      css += 
      '.tvHigh    {background-color: rgba(0,128,0,0.3); }' +
      '.tvFair    {background-color: rgba(255,165, 0, 0.3);}' +
      '.tvLow     {background-color: rgba(255,0,0,0.3); }' +
      '.tvNone    {background-color: rgba(128,128,128, 0.3); }'
    }

  $('#css').html(css);
}

function _to_theme () {
  var to, theme = themes[config.theme], color = '';
  console.log(config.to_theme);
  if (config.theme === 'default') {
    color = 'd9d9d9';
  }
  else {
    color = '262626';
  }

  switch (config.to_theme) {
    case '1':
      to =
        'td {font-weight: bold;}' +
        '.cont, .hit, .details {color: #000000;}' +
        '.toHigh    {background-color: #33cc59;}' +
        '.toGood    {background-color: #a6cc33;}' +
        '.toAverage {background-color: #cccc33;}' +
        '.toLow     {background-color: #cca633;}' +
        '.toPoor    {background-color: #cc3333;}' +
        '.toNone    {background-color: #cccccc;}' +
        '.rt, .pc   {width: 20px; height: 20px; background-color: transparent; margin: 1px;  border: 1px solid  #000000; font-size: 80%; padding: 1px;}' +
        '.vb, .irc {width: 25px; height: 20px; background-color: transparent; margin: 1px;  border: 1px solid  #000000; font-size: 80%; padding: 1px;}' +
        '.clicked   {background-color:grey;}';
      ;
      return to;
    case '2':
      to =
        'a         {color: #'+theme.link+';}' +
        'a:visited {color: #'+theme.visited+';}' +
        'tbody td  {color: #'+theme.text+';}' +
        '.to a {color: #000000;}' +

        '.cont, .details {color: #'+theme.text+';}' +
        '.toHigh    {background-color: #'+color+';}' +
        '.toGood    {background-color: #'+color+';}' +
        '.toAverage {background-color: #'+color+';}' +
        '.toLow     {background-color: #'+color+';}' +
        '.toPoor    {background-color: #'+color+';}' +
        '.toNone    {background-color: #'+color+';}' +

        '.toHigh    .to {background-color: #33cc59;}' +
        '.toGood    .to {background-color: #a6cc33;}' +
        '.toAverage .to {background-color: #cccc33;}' +
        '.toLow     .to {background-color: #cca633;}' +
        '.toPoor    .to {background-color: #cc3333;}' +
        '.toNone    .to {background-color: #cccccc;}' +
        '.rt, .pc   {width: 20px; height: 20px; color: #'+theme.text+'; background-color: transparent; margin: 1px;  border: 1px solid  #'+theme.text+'; font-size: 80%; padding: 1px;}' +
        '.vb, .irc {width: 25px; height: 20px; color: #'+theme.text+'; background-color: transparent; margin: 1px;  border: 1px solid  #'+theme.text+'; font-size: 80%; padding: 1px;}' +
        '.clicked   {background-color:grey;}';
      ;
      return to;
    case '3':
      to =
        'a         {color: #'+theme.link+';}' +
        'a:visited {color: #'+theme.visited+';}' +
        'tbody td  {color: #'+theme.text+';}' +

        '.cont, .details {color: #'+theme.text+';}' +
        '.toHigh    {background-color: #'+color+';}' +
        '.toGood    {background-color: #'+color+';}' +
        '.toAverage {background-color: #'+color+';}' +
        '.toLow     {background-color: #'+color+';}' +
        '.toPoor    {background-color: #'+color+';}' +
        '.toNone    {background-color: #'+color+';}' +

        '.toHigh    .to a {color: #33cc59;}' +
        '.toGood    .to a {color: #a6cc33;}' +
        '.toAverage .to a {color: #cccc33;}' +
        '.toLow     .to a {color: #cca633;}' +
        '.toPoor    .to a {color: #cc3333;}' +
        '.toNone    .to a {color: #cccccc;}' +
        '.rt, .pc   {width: 20px; height: 20px; color: #'+theme.text+'; background-color: transparent; margin: 1px;  border: 1px solid  #'+theme.text+'; font-size: 80%; padding: 1px;}' +
        '.vb, .irc {width: 25px; height: 20px; color: #'+theme.text+'; background-color: transparent; margin: 1px;  border: 1px solid  #'+theme.text+'; font-size: 80%; padding: 1px;}' +
        '.clicked   {background-color:grey;}';
      ;
      return to;
  }
}

$('#type option[value="' + config.type + '"]')          .prop('selected', true);
$('#size option[value="' + config.size + '"]')          .prop('selected', true);
$('#new_audio option[value="' + config.newaudio + '"]') .prop('selected', true);
$('#adv_theme option[value="' + config.theme + '"]')    .prop('selected', true);
$('#to_theme option[value="' + config.to_theme + '"]')  .prop('selected', true);

_theme();
_init_lists();
_loadTVData();