// ==UserScript==
// @name Recipe Counter
// @namespace kol.interface.unfinished
// @description Counts known recipes and tracks missing recipes in your crafting discovery pages in Kingdom of Loathing.
// @include https://*kingdomofloathing.com/craft.php*
// @include https://*.kingdomofloathing.com/account.php
// @include http://kol.coldfront.net/thekolwiki/index.php/Cocktailcrafting_Discoveries*
// @include http://kol.coldfront.net/thekolwiki/index.php/Cooking_Discoveries*
// @include http://kol.coldfront.net/thekolwiki/index.php/Meat-Pasting_Discoveries*
// @include http://kol.coldfront.net/thekolwiki/index.php/Meatsmithing_Discoveries*
// @include http://kol.coldfront.net/thekolwiki/index.php/Miscellaneous_Discoveries*
// @version 3.989
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_xmlhttpRequest
// ==/UserScript==
//Version 3.989
// - Murderbots
//Version 3.988
// - Robortender
//Version 3.987
// - more eldritch essentials
//Version 3.986
// - eldritch essentials
//Version 3.985
// - fix thanksgetting
//Version 3.984
// - thanksgetting
//Version 3.983
// - change to data uri for images used
//Version 3.982
// - fix overzealous use of https
//Version 3.981
// - change to https
//Version 3.98
// - spurious smithing, gunpasting, hi-yo silver
//Version 3.97
// - patent medicines
//Version 3.96
// - perfect cocktails
//Version 3.95
// - guncraft
//Version 3.94
// - heavy metallurgy
//Version 3.93
// - velvetry
//Version 3.92
// - retro-electrical
//Version 3.91
// - add baking, and retire jewelry, moving recipes to meat-pasting
//Version 3.90
// - cool winery
//Version 3.89
// - add Crimbo stuff
//Version 3.88
// - add Post-Apocalyptica
//Version 3.87
// - add @grant, switch GM_log to console.log, remove auto-update
//Version 3.86
// - spookyraven stuff, crash-site stuff, June/2014 familiar stuff
//Version 3.85
// - sugar cubans
//Version 3.84
// - spring break beach stuff
//Version 3.83
// - V11 stuff
//Version 3.82
// - added lynrd stuff
//Version 3.81
// - add Sugar Scale Structures to miscellaneous
//Version 3.80
// - add Smiths-ing to cocktails, cooking, meatpasting, meatsmithing
// - add Weapons: Swords to meatpasting, Loathsome Smithery to meatsmithing
//Version 3.79
// - added tin-kering to miscellaneous
//Version 3.78
// - added cluster stuff to miscellanous, cooking, cocktails
//Version 3.77
// - added Aquatic Jewelry
// - added Sea Leatherworking
//Version 3.76
// - added Cosmic Potions to miscellaneous
// - added Papier-Mache to cooking
//Version 3.75
// - added Oil Rigging to miscellaneous
//Version 3.74
// - added 'tonstruction and Wax Wear to miscellaneous
//Version 3.73
// - added Papier Mache to miscellaneous
//Version 3.72
// - added Hot Daubery to miscellaneous
//Version 3.71
// - added category Confectionery to meatsmithing and cocktailcrafting
// - added Peppermints to meatpasting and miscellaneous
//Version 3.70
// - added category Confectionery to cooking
//Version 3.69
// - added categories: Confectionery to jewelry and meat-pasting,
// and Festive Crimbo Cocktails to cocktailcrafting.
//Version 3.68
// - added sticky paper and rough stuff category to meatpasting discoveries
//Version 3.674
// - fix suddenly re-broken Humpy Dumplings
//Version 3.673
// - added honey stuff
//Version 3.672
// - added knob cake
//Version 3.671
// - more Amazing Ideas
//Version 3.67
// - added new recipe sections from April 2011 IOTM
//Version 3.665
// - fix https/http issue in auto-update
//Version 3.66
// - fix weirdness with vial of jus de larmes, due to it's italicization
// - update shared account-menu tab code
//Version 3.65
// - incorporate Charon the Hand's code for a shared account menu tab
//Version 3.64
// - fix account menu so it works with the new account menu update
//Version 3.63
// - added an account menu entry to update recipe lists manually.
//Version 3.62
// - more robust when an auto-check fails or is incomplete
//Version 3.61
// - added Paperclip Paraphernalia
//Version 3.6
// - improved new discovery detection, based on md5 sums of the wiki table
// text rather than last edit date of the page.
//Version 3.5
// - fix to work around kol's fuzzy matching system which would sometimes
// cause the script to wrongly report info in the mouse-over text and
// miscolour the item text after clicking on a missing recipe.
//Version 3.4
// - now checks and lets you know if wiki discovery pages (list of recipes)
// has been updated so you can revisit it to refresh the recipes list.
//Version 3.3
// - sped up missing ingredient checking considerably and
// it also retrieves the item counts, but only if you have
// (ever) enabled chat (you do not need to be in chat).
// Slower route is used when chat commands cannot be used.
//Version 3.2
// - added auto-update checking
//Version 3.1.1
// - updated Cooking recipe sections with Popsicles.
//Version 3.1
// - added ability to check inventory for ingredients of missing recipes.
// Click on the item name and it looks through through your inventory, changing
// the colour the item to either gray or black depending on whether you have
// all the ingredients. Mouseover text shows which ingredient is missing if
// just one.
//Version 3.0.1
// - added Smoked Pottery to miscellaneous
//Version 3.0
// - added crafting links for missing recipes, which take you to the appropriate
// crafting page, with the selection boxes filled if you have the items.
// - script state is now persistent, with counts and any displayed missing recipes
// not disappearing if you actually craft something.
// - The "show missing" button is now a toggle instead of a one-time button, and
// so can be applied by default as you switch discovery pages.
//Version 2.0
// - added gathering and display of missing recipes
//Version 1.3
// - add sub-counts for sections
//Version 1.2
// - add miscellaneous discoveries
//Version 1.1
// current page title if at a kol discoveries page
var knownPage='';
var pageLinks={'Meat-Pasting Discoveries:':'craft.php?mode=combine',
'Cocktailcrafting Discoveries:':'craft.php?mode=cocktail',
'Meatsmithing Discoveries:':'craft.php?mode=smith',
'Cooking Discoveries:':'craft.php?mode=cook',
'Miscellaneous Discoveries:':'craft.php?mode=discoveries'};
function doPage() {
// find table root of area interested in
var node,root;
var listing = document.getElementsByTagName('b');
for (var i=0;i<listing.length;i++) {
var node = listing[i];
if (node.firstChild && pageLinks[node.firstChild.data]) {
root = node.parentNode;
knownPage = node.firstChild.data; // ugh
while (root && root.tagName!='TABLE')
root = root.parentNode;
break;
}
}
if (root) {
GM_setValue('missinga','');
GM_setValue('missingb','');
// count
var count = document.evaluate('.//img[contains(@onclick,"descitem")]',root,null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null).snapshotLength;
node.firstChild.data = node.firstChild.data.substr(0,node.firstChild.data.length-1)+
' ('+count+' known):';
addButton(node);
addSubcounts(root);
if (GM_getValue('showmissing',''))
showMissing();
} else {
// direct crafting page?
var a = document.getElementById('a');
var b = document.getElementById('b');
if (a && b) {
var ma = GM_getValue('missinga');
var mb = GM_getValue('missingb');
if (ma) {
selectOption(a,ma);
selectOption(b,mb);
GM_setValue('missinga','');
GM_setValue('missingb','');
}
}
}
}
function selectOption(sbox,txt) {
for (var i=0;i<sbox.options.length;i++) {
if (sbox.options[i].text.indexOf(txt)==0 &&
sbox.options[i].text.replace(/\s*\([0-9]+\)\s*/,'')==txt) {
sbox.selectedIndex = i;
return;
}
}
}
function addButton(node) {
var v = document.createElement('a');
v.setAttribute('href','#');
v.setAttribute('id','showmissingbutton');
v.setAttribute('style','font-size:x-small;color:white;vertical-align:middle;');
fixupButton(v);
v.addEventListener('click',bHandler,false);
var p = knownPage.replace(/:.*$/,'').replace(/ /g,'_');
v.setAttribute('discoveries_page',p);
node.parentNode.appendChild(document.createTextNode('\u00a0\u00a0\u00a0'));
node.parentNode.appendChild(v);
if (GM_getValue(p+'_oldmd5',0)!=GM_getValue(p+'_newmd5',-1)) {
node.parentNode.appendChild(document.createTextNode('\u00a0\u00a0\u00a0'));
v = document.createElement('a');
v.setAttribute('href','http://kol.coldfront.net/thekolwiki/index.php/'+p);
v.setAttribute('style','font-size:x-small;color:yellow;vertical-align:middle;');
v.setAttribute('title','Updated discoveries list detected!');
v.setAttribute('id','recipecountdisoveriesnotice');
v.setAttribute('target','_blank');
v.appendChild(document.createTextNode('Click to update discoveries list'));
node.parentNode.appendChild(v);
} else {
v = document.getElementById('recipecountdiscoveriesnotice');
if (v) {
v.parentNode.removeChild(v);
}
}
}
function fixupButton(v) {
if (GM_getValue('showmissing','')) {
v.setAttribute('title','Click to hide all missing recipes on this page.');
if (v.firstChild)
v.replaceChild(document.createTextNode('[Hide Missing]'),v.firstChild);
else
v.appendChild(document.createTextNode('[Hide Missing]'));
} else {
v.setAttribute('title','Click to display all missing recipes on this page.');
if (v.firstChild)
v.replaceChild(document.createTextNode('[Show Missing]'),v.firstChild);
else
v.appendChild(document.createTextNode('[Show Missing]'));
}
}
function showMissing() {
var v = document.getElementById('showmissingbutton');
if (GM_getValue('showmissing','')) {
if (!missing()) {
var page = v.getAttribute('discoveries_page');
var pages = page.replace(/_/g,' ');
var goWiki = document.createElement('a');
goWiki.setAttribute('title','Click to go to the full list of '+pages+' recipes on the KoL wiki.');
goWiki.setAttribute('target','_blank');
goWiki.setAttribute('style','font-size:x-small;color:white;vertical-align:middle;');
goWiki.setAttribute('href','http://kol.coldfront.net/thekolwiki/index.php/'+page);
goWiki.appendChild(document.createTextNode('[Load all '+pages+']'));
v.parentNode.appendChild(goWiki);
}
} else {
var xx = document.getElementsByClassName('showmissingaddition');
for (var i=xx.length-1;i>=0;i--) {
var x = xx[i];
x.parentNode.removeChild(x);
}
}
fixupButton(v);
}
function bHandler(e) {
var b = GM_getValue('showmissing','');
GM_setValue('showmissing', (b ? '' : 'true'));
showMissing();
}
function addSubcounts(root) {
var tbls = document.evaluate( './/table', root, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
for (var i=tbls.snapshotLength-1;i>=0;i--) {
var tbl = tbls.snapshotItem(i);
var id = tbl.getAttribute('id');
if (id && id.indexOf('table_')==0) {
// found one
var count=0;
var listing = tbl.getElementsByTagName('img');
for (var j=0;j<listing.length;j++) {
var imgnode = listing[j];
var click;
if (click=imgnode.getAttribute('onclick')) {
if (click.indexOf('descitem')==0) {
count++;
}
}
}
// count the images
if (tbl.previousSibling) {
var hdr = tbl.previousSibling.previousSibling;
if (hdr && hdr.tagName=='CENTER' && hdr.firstChild) {
var f = document.createElement('font');
f.setAttribute('style','font-size:x-small;');
f.appendChild(document.createTextNode(' ('+count+' recipe'+((count==1)? '' : 's')+')'));
hdr.firstChild.appendChild(f);
}
}
}
}
}
var rlists = [{title:'Cocktailcrafting Discoveries',
sections:['Amazing Ideas','Confectionery','Clustercocktails','Cool Winery','Distillations','Eldritch Essentials','Evil Fruity Girl Drinks',
'Eww','Extra-Fruity Girl Drinks',
'Fancy Garnishes','Festive Crimbo Cocktails','Fruity Girl Drinks','Hilarious Jokes','Infused Wines',
'Miscellaneous','Miscellaneous Boozery','Mushroom Wines','Perfect Cocktails','Post-Apocalyptica', 'Premium Cocktails','Schnapps',
'Robortender Recipes','Simple Cocktails','Smiths-ing','Specialty Beers','Tiny Plastic Sword Drinks',
'Underwater Cocktails']},
{title:'Cooking Discoveries',
sections:['Advanced Sauceror Potions','Amazing Ideas','Baking','Brownies','Casseroles','Clusterbaking','Confectionery',
'Confections','Dirty Exploits','Eldritch Essentials','Evil Noodle Dishes','Evil Sauceror Potions','Familiar',
'High-Pressure Potions','Kabobs','Key Limes','Miscellaneous','Miscellaneous Cookery', 'Miscellaneous Potions',
'Nemesis Quest Slimes','Noodle Dishes','Papier-Mache','Patent Medicines','Pies','Pizzas','Popsicles','Pork Gem Potions','Post-Apocalyptica',
'Quest Items','Sauceror Potions','Secret Sauces','Smiths-ing','Space Foods','Stir-Fries','Tempura','Tex-Mex',
'Tex-Mex-Italian','Thanksgarden Creations','Transmutations']},
{title:'Meat-Pasting Discoveries',
sections:['Amazing Ideas','Aquatic Jewelry','Campground Items','Clusterbombs','Confectionery','Decoys','Elemental Jewelry','Expensive Pork Elf Jewelry',
'Familiars','Gear','Genetic Engineering','Guncraft','Gunpasting','Hi-Yo Silver','Hilarious Jokes','Horrifying Jewelry','Miscellaneous',
'Miscellaneous Jewelry','Murderbot Technology','Parts','Parts for Campground Items',
'Parts for Familiars','Peppermints','Pork Elf Jewelry','Post-Apocalyptica','Primordial Soup','Quest Items','Rainbow Pearl Jewelry','Retro-Electrical','Rough Stuff',
'Smiths-ing','Spacetime Bending','Usable Items','Vampire Pearl Jewelry','Weapons: Swords']},
{title:'Meatsmithing Discoveries',
sections:['Armor: Accessories','Armor: Advanced Accessories','Armor: Advanced Hats',
'Armor: Advanced Pants','Armor: Advanced Shields', 'Armor: Advanced Shirts', 'Armor: Hats',
'Armor: Pants','Armor: Shields','Armor: Shirts','Campground Items', 'Confectionery','Depleted Grimacite', 'Gear','Ghast Irony',
'Ingredients','Loathsome Smithery','Miscellaneous Smithery','Post-Apocalyptica','Quest Weapons','Sea Leatherworking','Slimy Things',
'Smiths-ing','Spacetime Bending','Spurious Smithing','Weapons: Advanced Crossbows',
'Weapons: Advanced Staves','Weapons: Advanced Swords','Weapons: Clubs',
'Weapons: Crossbows','Weapons: Miscellaneous','Weapons: Staves',
'Weapons: Swords','Weapons: Utensils','Weapons: Whips']},
{title:'Miscellaneous Discoveries',
sections:["'tonstruction",'BRICKO Beasts','BRICKO Bits','Balloon Bendings','Clingfilm Creations',
'Cold Comforts','Cosmic Potions','Duct Tape Designs','Eldritch Essentials','Heavy Metallurgy','Honey Stuff','Hot Daubery','Mummy Wrapping Manufacturings',
'Oil Rigging','Palm-Frond Preparations','Paperclip Paraphernalia','Papier-Mache','Peppermints','Plaiddery','Smoked Pottery',
'Snailmail Structures','Spacetime Bending','Spooky Bark Surprises','Sugar Cubans','Sugar Scale Structures','Tin-kering',
'Turtlemail Treasures','Velvetry','Wax Wear','Wumpus Hair Weavings']}];
// locate all missing recipes
function missing() {
var s = knownPage;
//console.log('knownPage='+s);
if (!s) {
return;
}
for (var i=0;i<rlists.length;i++) {
if (s.indexOf(rlists[i].title)>=0) {
var r = missingInPage(retrieveCopy(rlists[i].title));
if (!r)
return false;
insertMissing(r);
return true;
}
}
}
// set by missingInPage and used by insertMissing
var secMap = {};
// uses the secMap and the given list of missing recipes to create fake versions
function insertMissing(r) {
for (var s in r) {
var tbl = secMap[s];
var lastr = null;
if (tbl && tbl.rows.length>0 && tbl.rows[tbl.rows.length-1].cells.length<3) {
lastr = tbl.rows[tbl.rows.length-1];
}
for (var e in r[s]) {
if (r[s][e]) {
for (var j=0;j<r[s][e].length;j++) {
if (lastr) {
createMissing(lastr,e,r[s][e][j]);
lastr = null;
} else {
// TBD: what if tbl is null?
if (!tbl) {
if (secMap['last_table']) {
tbl = insertMissingTable(secMap['last_table'].nextSibling,s);
} else {
var root = document.evaluate( '//td[contains(text(),"You haven\'t made any discoveries in this field yet")]/text()', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE,null);
tbl = insertMissingTable(root.singleNodeValue.nextSibling,s);
}
secMap[s] = tbl;
}
lastr = tbl.insertRow(-1);
lastr.setAttribute('class','showmissingaddition');
createMissing(lastr,e,r[s][e][j]);
}
// console.log('missing in '+s+': '+e+' = '+r[s][e][j]);
}
}
}
}
}
// creates a table for a section s
function insertMissingTable(root,s) {
var c = document.createElement('center');
var tbl = document.createElement('table');
var b = document.createElement('b');
var br1 = document.createElement('br');
var br2 = document.createElement('br');
c.setAttribute('class','showmissingaddition');
tbl.setAttribute('class','showmissingaddition');
br1.setAttribute('class','showmissingaddition');
br2.setAttribute('class','showmissingaddition');
b.innerHTML = s;
b.setAttribute('style','color:red;');
c.appendChild(b);
root.parentNode.insertBefore(br1,root);
root.parentNode.insertBefore(c,root);
root.parentNode.insertBefore(br2,root);
root.parentNode.insertBefore(tbl,root);
return tbl;
}
// locate missing recipes in the current kol discoveries page, given a list of recipes
function missingInPage(r) {
if (!r) {
alert('You need to visit the KoL Wiki discoveries pages (http://kol.coldfront.net/thekolwiki/index.php/Discoveries) to initialize the recipe list. Visit each of the 6 pages of Recipes on the wiki, then re-open a recipe page in the game and try again.');
return;
}
secMap = {};
var tbls = document.evaluate( '//table', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
for (var i=0;i<tbls.snapshotLength;i++) {
var tbl = tbls.snapshotItem(i);
var id = (tbl) ? tbl.getAttribute('id') : null;
if (id && id.indexOf('table_')==0) {
// found one
// figure out which section this represents
var sec = tbl.previousSibling;
while (sec && sec.tagName!='CENTER')
sec = sec.previousSibling;
if (sec) {
sec = sec.firstChild.firstChild.innerHTML;
}
var es = document.evaluate( './/td', tbl, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
for (var j=0;j<es.snapshotLength;j+=2) {
var e = es.snapshotItem(j);
var f = es.snapshotItem(j+1);
var item = (f.firstChild.firstChild.nodeType==3) ? f.firstChild.firstChild.data : f.firstChild.firstChild.innerHTML;
if (!item) continue;
var itemr = f.firstChild.nextSibling;
if (itemr.tagName!='FONT') itemr = itemr.nextSibling;
var components = '';
for (var k=0;k<itemr.childNodes.length;k++) {
if (itemr.childNodes[k].nodeType==3) {
components += itemr.childNodes[k].data;
} else if (itemr.childNodes[k].tagName=='I') {
components += '<i>'+itemr.childNodes[k].innerHTML+'</i>';
}
}
components = components.replace(/\([0-9]+\)/g,'').replace(/\+[\s]*$/,'').replace(/ /g,' ').replace(/\s\s+/,' ').replace(/ *$/,'').replace(/^ */,'');
// check that we have a section
if (sec) {
if (r && r[sec] && r[sec][item]) {
var hi = hasRecipe(r[sec][item],components);
if (hi>=0) {
r[sec][item].splice(hi,1);
}
}
} else if (r) {
for (var s in r) {
if (r[s][item]) {
var hi = hasRecipe(r[s][item],components);
if (hi>=0) {
r[s][item].splice(hi,1);
sec = s;
break;
}
}
}
}
}
secMap[sec] = tbl; // store for later
secMap['last_table'] = tbl;
}
}
return r;
}
// check the given list for a recipe combination, and return the index or -1
function hasRecipe(clist,c) {
if (!clist)
return -1;
var c2 = c.match(/(^[^+]*)\+(.*$)/);
if (c2) {
c2 = c2[2] +' + '+c2[1];
c2 = c2.replace(/\+[\s]*$/,'').replace(/ /g,' ').replace(/ *$/,'').replace(/^ */,'');
}
for (var i=0;i<clist.length;i++) {
if (clist[i] == c || (c2 && clist[i] == c2)) {
return i;
}
}
return -1;
}
// creates a new entry for a missing title+components, and
// attaches the resulting td's to the given tr
function createMissing(tr,title,components) {
var td1 = tr.insertCell(-1);
var td2 = tr.insertCell(-1);
td1.setAttribute('class','showmissingaddition');
td2.setAttribute('class','showmissingaddition');
td1.setAttribute('valign','center');
td2.setAttribute('valign','top');
var i = document.createElement('img');
i.setAttribute('class','hand');
i.setAttribute('src','data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAABEklEQVRIie2WyxHDMAhE0xR10Q6NUAK1UALHzYl8haXIljOZyR5laR6flfAFX9LlJ8DuDhGBiMDMzgGLCIjoBiYiMPNacGb6ukZEcPd1YACIiO+AH5WlVtVmgMwMZm5+nwZnpqr6VgUAMLMnH1QmLMFmBmZuHnztdyURKQ3YBGe5VBVE1Mysp4go21GC82BloK1AIuLpulV7S3BlIGbeLHUGKyKbAZbgyhiVqVJmNnTNyh6v6u0meO/jMBJwWepeSdPxI9l9BO7J3eHuYGYQ0W09H5BlYOCe9aMJM5gpsLt3+5Qmmp3LTfDorF0ynXqZpPMPzXhUp8/j1Cx0N3iPpsGqOvVwHAIe/SE4FLxXf/BpugJUkH7bCBPJ3QAAAABJRU5ErkJggg==');
td1.appendChild(i);
var b = document.createElement('b');
b.setAttribute('style','color:red;');
b.innerHTML = title;
td2.appendChild(b);
var f = document.createElement('font');
f.setAttribute('size','1');
f.setAttribute('color','red');
if (knownPage!='Miscellaneous Discoveries:') {
var f2 = document.createElement('font');
f2.setAttribute('size','2');
f2.setAttribute('color','red');
var ia = document.createElement('a');
ia.appendChild(document.createTextNode('make?'));
ia.setAttribute('title','Click to go the crafting page for this missing recipe');
ia.setAttribute('href','#');
ia.setAttribute('missinga',components.replace(/\s*\+.*/,''));
ia.setAttribute('missingb',((components.indexOf('+')>0) ? components.replace(/[^+]*\+\s*/,'') : ''));
ia.addEventListener('click',missingButtonHandler,false);
f2.appendChild(document.createTextNode('\u00A0['));
f2.appendChild(ia);
f2.appendChild(document.createTextNode(']'));
f.appendChild(f2);
b.setAttribute('missinga',components.replace(/\s*\+.*/,''));
b.setAttribute('missingb',((components.indexOf('+')>0) ? components.replace(/[^+]*\+\s*/,'') : ''));
b.setAttribute('title','click to check for ingredients');
b.addEventListener('click',checkIngredientsHandler,false);
}
f.appendChild(document.createElement('br'));
f.appendChild(document.createTextNode(components));
td2.appendChild(f);
}
function missingButtonHandler() {
GM_setValue('missinga',this.getAttribute('missinga').replace(/<[^>]+>/g,''));
GM_setValue('missingb',this.getAttribute('missingb').replace(/<[^>]+>/g,''));
window.location.href = pageLinks[knownPage];
}
// return a new copy of the master recipes
function retrieveCopy(page) {
var r = JSON.parse(GM_getValue('recipes','{}'));
return r[page];
}
// scrape data from a kol wiki page
function gather(m5) {
var recipes = JSON.parse(GM_getValue('recipes','{}'));
var s = window.location.pathname.replace(/_/g,' ');
//console.log('Gathering...'+s);
for (var i=0;i<rlists.length;i++) {
if (s.indexOf(rlists[i].title)>=0) {
gatherRecipes(rlists[i],recipes);
var p = rlists[i].title.replace(/:.*$/,'').replace(/ /g,'_');
GM_setValue(p+'_oldmd5',m5);
GM_setValue(p+'_newmd5',m5);
}
}
GM_setValue('recipes',JSON.stringify(recipes));
}
// scrape data from a specific kol wiki page
function gatherRecipes(rlist,recipes) {
var s = {};
for (var i=0;i<rlist.sections.length;i++) {
var r = gatherRecipesSection(rlist.sections[i]);
s[rlist.sections[i]] = r;
}
recipes[rlist.title] = s;
// var p = rlist.title.replace(/:.*$/,'').replace(/ /g,'_')+'_last';
// GM_setValue(p,(new Date()).toUTCString());
//console.log('setting '+p+' to '+GM_getValue(p));
}
// scrapte data for the given section of a kol wiki page
function gatherRecipesSection(section) {
var r = {};
var sec = document.evaluate( '//span[@class="mw-headline"]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
//var sec = document.evaluate( '//span[text()="'+section+'"]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
// console.log('gathering for section '+section);
var rx = new RegExp('','');
for (var j=0;j<sec.snapshotLength;j++) {
var sn = sec.snapshotItem(j).innerHTML;
if (sn.replace(/^ */,'').replace(/ *$/,'')==section) {
var hp = sec.snapshotItem(j).parentNode;
if (hp && hp.tagName=='H2') {
hp = hp.nextSibling.nextSibling;
while (hp && hp.tagName!='H2') {
var i;
var tbls = document.evaluate( './/td', hp, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
for (i=0;i<tbls.snapshotLength-1;i+=2) {
var e = tbls.snapshotItem(i);
var f = tbls.snapshotItem(i+1);
var n = f.firstChild.firstChild.innerHTML;
var c = '';
for (var k=0;k<f.firstChild.nextSibling.nextSibling.childNodes.length;k++) {
var s = f.firstChild.nextSibling.nextSibling.childNodes[k];
if (s.innerHTML)
c += s.innerHTML;
else if (s.nodeType==3)
c += s.data;
else if (c)
c += ' + ';
}
c = c.replace(/\+[\s]*$/,'').replace(/ /g,' ').replace(/ *$/,'').replace(/^ */,'');
if (c) {
// console.log('found recipe for '+n+', consisting of: '+c);
if (r[n]) r[n][r[n].length] = c;
else r[n] = [c];
}
}
if (i>0)
return r;
hp = hp.nextSibling;
}
}
}
}
return r;
}
// called when the confused image is clicked on.
function checkIngredientsHandler(e) {
this.removeEventListener('click',checkIngredientsHandler,false);
checkIngredientsFast(this,this.getAttribute('missinga'),this.getAttribute('missingb'));
}
// utility function, stolen from other scripts
function GM_get(dest, callback)
{ GM_xmlhttpRequest({
method: 'GET',
url: dest,
//onerror:function(error) { console.log("GM_get Error: " + error); },
onload:function(details) {
if( typeof(callback)=='function' ){
callback(details.responseText);
} } }); }
// if chat not enabled use the slow route
function checkIngredientsSlow(item,ing1,ing2) {
//item.setAttribute('style','color:pink;');
//item.setAttribute('title','checking...');
var r1b = false;
var r2b = false;
GM_get('http://'+window.location.host+'/inventory.php?which=1',function(response){
if(response!=''){
var r1 = new RegExp('<b[^>]*>'+ing1+'</b>','gm');
var r2 = new RegExp('<b[^>]*>'+ing2+'</b>','gm');
if (!r1b) r1b = r1.test(response);
if (!r2b) r2b = r2.test(response);
if (r1b && r2b) {
item.setAttribute('style','color:black;');
item.addEventListener('click',checkIngredientsHandler,false);
item.setAttribute('title','Ingredients found in inventory at last check. Click to check again.');
} else {
GM_get('http://'+window.location.host+'/inventory.php?which=2',function(response){
if(response!=''){
if (!r1b) r1b = r1.test(response);
if (!r2b) r2b = r2.test(response);
if (r1b && r2b) {
item.setAttribute('style','color:black;');
item.addEventListener('click',checkIngredientsHandler,false);
item.setAttribute('title','Ingredients found in inventory at last check. Click to check again.');
} else {
GM_get('http://'+window.location.host+'/inventory.php?which=3',function(response){
if(response!=''){
if (!r1b) r1b = r1.test(response);
if (!r2b) r2b = r2.test(response);
if (r1b && r2b) {
item.setAttribute('style','color:black;');
item.setAttribute('title','Ingredients found in inventory at last check. Click to check again.');
} else {
item.setAttribute('style','color:gray;');
if (r1b)
item.setAttribute('title','Ingredient '+ing2+' not found in inventory. Click to check again.');
else if (r2b)
item.setAttribute('title','Ingredient '+ing1+' not found in inventory. Click to check again.');
else
item.setAttribute('title','Ingredients not found in inventory. Click to check again.');
}
item.addEventListener('click',checkIngredientsHandler,false);
}});
}
}});
}
}});
}
// faster checking but requires chat is enabled
function checkIngredientsFast(item,ing1,ing2) {
item.setAttribute('style','color:pink;');
item.setAttribute('title','checking...');
if (ing1.match(/<[^>]+>/) || ing2.match(/<[^>]+>/))
return checkIngredientsSlow(item,ing1,ing2);
var pd = findPwdhash();
if (!pd) {
console.log('cound not find pwd or playerid');
return;
}
//console.log('pwd='+pd.pwd);
//console.log('pid='+pd.pid);
GM_get('http://'+window.location.host+'/submitnewchat.php?playerid='+pd.pid+'&pwd='+pd.pwd+'&graf=/count '+encodeURI(ing1),
function(response) {
if(response!='') {
//console.log('response: '+response);
var r1 = response.match(/(<[^>]*>)*You have ([0-9]*) ([^<]*)\./);
GM_get('http://'+window.location.host+'/submitnewchat.php?playerid='+pd.pid+'&pwd='+pd.pwd+'&graf=/count '+encodeURI(ing2),
function(response) {
if(response!='') {
var r2 = response.match(/(<[^>]*>)*You have ([0-9]*) ([^<]*)\./);
if (r1 && r2) {
verifyItems(item,ing1,ing2,pd,r1,r2);
} else {
setItemState(item,r1,r2,ing1,ing2);
}
}});
} else {
checkIngredientsSlow(item,ing1,ing2);
}});
}
function setItemState(item,r1,r2,ing1,ing2) {
if (r1 && r2) {
item.setAttribute('style','color:black;');
item.setAttribute('title','Found '+r1[2]+' '+r1[3]+' and '+r2[2]+' '+r2[3]+' at last check. Click to check again.');
} else {
item.setAttribute('style','color:gray;');
if (r1)
item.setAttribute('title','Found '+r1[2]+' '+r1[3]+' but no '+ing2+' in your inventory. Click to check again.');
else if (r2)
item.setAttribute('title','Found '+r2[2]+' '+r2[3]+' but no '+ing1+' in your inventory. Click to check again.');
else
item.setAttribute('title','Neither ingredient is in your inventory. Click to check again.');
}
item.addEventListener('click',checkIngredientsHandler,false);
}
function verifyItems(item,ing1,ing2,pd,r1,r2) {
GM_get('http://'+window.location.host+'/submitnewchat.php?playerid='+pd.pid+'&pwd='+pd.pwd+'&graf=/examine '+encodeURI(ing1),
function(response) {
var r3 = response.match(/^<[^>]*>Examining: ([^<]*)/);
if (r3) r3 = (r3[1]==ing1) ? r3 : null;
GM_get('http://'+window.location.host+'/submitnewchat.php?playerid='+pd.pid+'&pwd='+pd.pwd+'&graf=/examine '+encodeURI(ing2),
function(response) {
var r4 = response.match(/^<[^>]*>Examining: ([^<]*)/);
if (r4) r4 = (r4[1]==ing2) ? r4 : null;
setItemState(item,(r3) ? r1 : null,(r4) ? r2 : null,ing1,ing2);
});
});
}
function checkDiscoveries() {
for (p in pageLinks) {
var purl = p.replace(/:.*$/,'').replace(/ /g,'_');
GM_xmlhttpRequest({
method: 'GET',
url: 'http://kol.coldfront.net/thekolwiki/index.php/'+purl,
onload: function(details) {
var q = this.url.replace(/[^/]*\//g,'');
if (details.responseText) {
var mdf = getPageMD5(details.responseText);
//console.log('new md5 for '+q+': '+mdf);
GM_setValue(q+'_newmd5',mdf);
}
}
});
}
}
function getPageMD5(raw) {
var text = '';
var j,i = raw.indexOf('<table>');
while(raw && i>=0) {
raw = raw.substr(i+7);
j = raw.indexOf('</table>');
if (j<0)
break; // bad parse?
text = text + raw.substr(0,j);
raw = raw.substr(j);
i = raw.indexOf('<table>');
}
text = text.replace(/<[^>]*>/g,'');
text = text.replace(/[\s\n]+/g,'');
var m = MD5(text);
//console.log('md5 of '+text);
return m;
}
function findPwdhash() {
var somef=window.parent.frames;
var goo = null;
for(var j=0;j<somef.length;j++) {
if (somef[j].name=="charpane") {
goo=somef[j];
var page = goo.document.documentElement.innerHTML;
var pwdh = page.match(/pwdhash\s*=\s*\"([a-f0-9]+)\"/);
if (pwdh) {
var plid = page.match(/playerid\s*=\s*([a-f0-9]+)/);
if (plid) {
return {pwd:pwdh[1],pid:plid[1]};
}
}
}
}
}
/**
*
* MD5 (Message-Digest Algorithm)
* http://www.webtoolkit.info/
*
**/
var MD5 = function (string) {
function RotateLeft(lValue, iShiftBits) {
return (lValue<<iShiftBits) | (lValue>>>(32-iShiftBits));
}
function AddUnsigned(lX,lY) {
var lX4,lY4,lX8,lY8,lResult;
lX8 = (lX & 0x80000000);
lY8 = (lY & 0x80000000);
lX4 = (lX & 0x40000000);
lY4 = (lY & 0x40000000);
lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF);
if (lX4 & lY4) {
return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
}
if (lX4 | lY4) {
if (lResult & 0x40000000) {
return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
} else {
return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
}
} else {
return (lResult ^ lX8 ^ lY8);
}
}
function F(x,y,z) { return (x & y) | ((~x) & z); }
function G(x,y,z) { return (x & z) | (y & (~z)); }
function H(x,y,z) { return (x ^ y ^ z); }
function I(x,y,z) { return (y ^ (x | (~z))); }
function FF(a,b,c,d,x,s,ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
};
function GG(a,b,c,d,x,s,ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
};
function HH(a,b,c,d,x,s,ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
};
function II(a,b,c,d,x,s,ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
};
function ConvertToWordArray(string) {
var lWordCount;
var lMessageLength = string.length;
var lNumberOfWords_temp1=lMessageLength + 8;
var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64;
var lNumberOfWords = (lNumberOfWords_temp2+1)*16;
var lWordArray=Array(lNumberOfWords-1);
var lBytePosition = 0;
var lByteCount = 0;
while ( lByteCount < lMessageLength ) {
lWordCount = (lByteCount-(lByteCount % 4))/4;
lBytePosition = (lByteCount % 4)*8;
lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount)<<lBytePosition));
lByteCount++;
}
lWordCount = (lByteCount-(lByteCount % 4))/4;
lBytePosition = (lByteCount % 4)*8;
lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition);
lWordArray[lNumberOfWords-2] = lMessageLength<<3;
lWordArray[lNumberOfWords-1] = lMessageLength>>>29;
return lWordArray;
};
function WordToHex(lValue) {
var WordToHexValue="",WordToHexValue_temp="",lByte,lCount;
for (lCount = 0;lCount<=3;lCount++) {
lByte = (lValue>>>(lCount*8)) & 255;
WordToHexValue_temp = "0" + lByte.toString(16);
WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2);
}
return WordToHexValue;
};
function Utf8Encode(string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
};
var x=Array();
var k,AA,BB,CC,DD,a,b,c,d;
var S11=7, S12=12, S13=17, S14=22;
var S21=5, S22=9 , S23=14, S24=20;
var S31=4, S32=11, S33=16, S34=23;
var S41=6, S42=10, S43=15, S44=21;
string = Utf8Encode(string);
x = ConvertToWordArray(string);
a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
for (k=0;k<x.length;k+=16) {
AA=a; BB=b; CC=c; DD=d;
a=FF(a,b,c,d,x[k+0], S11,0xD76AA478);
d=FF(d,a,b,c,x[k+1], S12,0xE8C7B756);
c=FF(c,d,a,b,x[k+2], S13,0x242070DB);
b=FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE);
a=FF(a,b,c,d,x[k+4], S11,0xF57C0FAF);
d=FF(d,a,b,c,x[k+5], S12,0x4787C62A);
c=FF(c,d,a,b,x[k+6], S13,0xA8304613);
b=FF(b,c,d,a,x[k+7], S14,0xFD469501);
a=FF(a,b,c,d,x[k+8], S11,0x698098D8);
d=FF(d,a,b,c,x[k+9], S12,0x8B44F7AF);
c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);
b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE);
a=FF(a,b,c,d,x[k+12],S11,0x6B901122);
d=FF(d,a,b,c,x[k+13],S12,0xFD987193);
c=FF(c,d,a,b,x[k+14],S13,0xA679438E);
b=FF(b,c,d,a,x[k+15],S14,0x49B40821);
a=GG(a,b,c,d,x[k+1], S21,0xF61E2562);
d=GG(d,a,b,c,x[k+6], S22,0xC040B340);
c=GG(c,d,a,b,x[k+11],S23,0x265E5A51);
b=GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA);
a=GG(a,b,c,d,x[k+5], S21,0xD62F105D);
d=GG(d,a,b,c,x[k+10],S22,0x2441453);
c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681);
b=GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8);
a=GG(a,b,c,d,x[k+9], S21,0x21E1CDE6);
d=GG(d,a,b,c,x[k+14],S22,0xC33707D6);
c=GG(c,d,a,b,x[k+3], S23,0xF4D50D87);
b=GG(b,c,d,a,x[k+8], S24,0x455A14ED);
a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905);
d=GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8);
c=GG(c,d,a,b,x[k+7], S23,0x676F02D9);
b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);
a=HH(a,b,c,d,x[k+5], S31,0xFFFA3942);
d=HH(d,a,b,c,x[k+8], S32,0x8771F681);
c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122);
b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C);
a=HH(a,b,c,d,x[k+1], S31,0xA4BEEA44);
d=HH(d,a,b,c,x[k+4], S32,0x4BDECFA9);
c=HH(c,d,a,b,x[k+7], S33,0xF6BB4B60);
b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);
a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6);
d=HH(d,a,b,c,x[k+0], S32,0xEAA127FA);
c=HH(c,d,a,b,x[k+3], S33,0xD4EF3085);
b=HH(b,c,d,a,x[k+6], S34,0x4881D05);
a=HH(a,b,c,d,x[k+9], S31,0xD9D4D039);
d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);
c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);
b=HH(b,c,d,a,x[k+2], S34,0xC4AC5665);
a=II(a,b,c,d,x[k+0], S41,0xF4292244);
d=II(d,a,b,c,x[k+7], S42,0x432AFF97);
c=II(c,d,a,b,x[k+14],S43,0xAB9423A7);
b=II(b,c,d,a,x[k+5], S44,0xFC93A039);
a=II(a,b,c,d,x[k+12],S41,0x655B59C3);
d=II(d,a,b,c,x[k+3], S42,0x8F0CCC92);
c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D);
b=II(b,c,d,a,x[k+1], S44,0x85845DD1);
a=II(a,b,c,d,x[k+8], S41,0x6FA87E4F);
d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);
c=II(c,d,a,b,x[k+6], S43,0xA3014314);
b=II(b,c,d,a,x[k+13],S44,0x4E0811A1);
a=II(a,b,c,d,x[k+4], S41,0xF7537E82);
d=II(d,a,b,c,x[k+11],S42,0xBD3AF235);
c=II(c,d,a,b,x[k+2], S43,0x2AD7D2BB);
b=II(b,c,d,a,x[k+9], S44,0xEB86D391);
a=AddUnsigned(a,AA);
b=AddUnsigned(b,BB);
c=AddUnsigned(c,CC);
d=AddUnsigned(d,DD);
}
var temp = WordToHex(a)+WordToHex(b)+WordToHex(c)+WordToHex(d);
return temp.toLowerCase();
}
// --------------------------------------------
// ---------- account menu option -------------
// --------------------------------------------
// Charon's code
function buildPrefs() {
if (!document.querySelector('#privacy'))
return;
if (!document.querySelector('#scripts')) {
//scripts tab is not built, do it here
var scripts = document.querySelector('ul').appendChild(document.createElement('li'));
scripts.id = 'scripts';
var a = scripts.appendChild(document.createElement('a'));
a.href = '#';
var img = a.appendChild(document.createElement('img'));
img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAACOElEQVRIibWXu9HsIAyFCQkpgCbUiFpRO2qFBiiAAkgVEjo8N7gjxvZi7/P3jGZfhs96HbEBH1y9dxARiAilFPTeMcZ4a4/wCZSZkVKCiICZQURg5r8Dt9YQY0QIASGEt2Efg5l5Qt1U9W/B27Yh54wQAnLOM9wxxrfz+xa41oqcM1QVtVZs2wZVnfkVEdRafws2M4jINFWFmYGZp+f+2lr7DdjMZusQEcYY6L1DVQ8e+30i8huwt0wpBTlnpJRmjpl5fkdECCG8HO6n4FLKbCERQe/94Z7WGkRktti2bd+DVRUpJZRSlhv23iEiyDkfCu0rsFdyjHEWkKoeFCvGiBjjhKkqYoxP+/sSrKrIOUNEZtF4OB3MzLPQiGhGZ69sV2Ffgkspc7GHkIhQa0UI4dDD/j6EgJTSAe5FaGbPwWOMqVBnc8l0jx3mv6nqUlZXOX8A+9OvNNnz6q3jHnlPr9a5nb0+gPd6vDdXJM/x2XLOMw376XU3TA5gM7sMMYDp6Qp89dBXI/QAvgqX5+gODOAyIk/BrbXbMD0D77vhbER0X1yrzR185VFKCWZ2C77N8eqp9yp0V7mttbn2XGArIbkUkPPk2bYNInJQpjNYRJbQlwRkde3FfwVOKU1ddxgz347Il8DMjBjjHBir4tqr2k/GYu/9Abb6HGN8qNyPwWZ2mdO76v3aY5fBO/PRue/Xrw8CZjbDSkTLHKeUDlHxI/BXYOB/a7mouDf+R83MMMaYk8sr/5UD/j/2nAi155cMxQAAAABJRU5ErkJggg==';
img.align = 'absmiddle';
img.border = '0';
img.style.paddingRight = '10px';
a.appendChild(document.createTextNode('Scripts'));
a.addEventListener('click', function (e) {
//make our new tab active when clicked, clear out the #guts div and add our settings to it
e.stopPropagation();
document.querySelector('.active').className = '';
document.querySelector('#scripts').className = 'active';
document.querySelector('#guts').innerHTML = '<div class="scaffold"></div>';
document.querySelector('#guts').appendChild(getSettings());
}, false);
} else {
//script tab already exists
document.querySelector('#scripts').firstChild.addEventListener('click', function (e) {
//some other script is doing the activation work, just add our settings
e.stopPropagation();
document.querySelector('#guts').appendChild(getSettings());
}, false);
}
}
function getSettings() {
//build our settings and return them for appending
var contents = document.createElement('div');
contents.id = 'recipecounterprefs';
var fieldset = contents.appendChild(document.createElement('fieldset'));
fieldset.setAttribute('style', 'width:33%; margin-top:20px');
var legend = fieldset.appendChild(document.createElement('legend'));
legend.className = 'subhead';
legend.textContent = 'Recipe Counter';
var section = fieldset.appendChild(document.createElement('div'));
section.className = 'indent';
section.appendChild(buildSettings());
return contents;
}
function buildSettings() {
//var ul = document.createElement('ul');
//var li = document.createElement('li');
var ar = document.createElement('a');
ar.setAttribute('href','#');
ar.appendChild(document.createTextNode('Update all recipe lists'));
ar.addEventListener('click',openAll,false);
ar.setAttribute('title','Note that this opens up 6 new windows.');
//li.appendChild(ar);
//ul.appendChild(li);
return ar;
}
function openAll() {
window.open('http://kol.coldfront.net/thekolwiki/index.php/Cocktailcrafting_Discoveries','Cocktailcrafting Discoveries');
window.open('http://kol.coldfront.net/thekolwiki/index.php/Cooking_Discoveries','Cooking Discoveries');
window.open('http://kol.coldfront.net/thekolwiki/index.php/Meat-Pasting_Discoveries','Meat-Pasting Discoveries');
window.open('http://kol.coldfront.net/thekolwiki/index.php/Meatsmithing_Discoveries','Meatsmithing Discoveries');
window.open('http://kol.coldfront.net/thekolwiki/index.php/Miscellaneous_Discoveries','Miscellaneous Discoveries');
}
if (window.location.href.indexOf('http://kol.coldfront.net/thekolwiki/index.php/')>=0) {
gather(getPageMD5(document.body.innerHTML));
} else if (window.location.pathname.indexOf('/account.php')==0) {
buildPrefs();
} else {
checkDiscoveries();
doPage();
}