-
-
Save sirkro/8509968718280dfbc98d1050968fbc8f to your computer and use it in GitHub Desktop.
Reversewigo autosolver - Tampermonkey script to automatically solve reverse wherigos on geocaching.com page
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Reversewigo solver ✓🐵 | |
// @namespace http://tampermonkey.net/ | |
// @version 0.12 | |
// @description Reversewigo solver ✓🐵 - solve reverse wherigo automatically on cache page. Solver code originated from Rick Rickhardson's reverse-wherigo source (public domain). Also, creates show source button for mystery cacahes. | |
// @author mrummuka@hotmail.com | |
// @grant GM_registerMenuCommand | |
// @grant GM_getValue | |
// @grant GM_setValue | |
// @grant GM_setClipboard | |
// @include https://www.geocaching.com/geocache/* | |
// @require https://openuserjs.org/src/libs/sizzle/GM_config.js | |
// ==/UserScript== | |
/* jshint esversion: 8 */ | |
// placeholder for calculated reverse wherigo coordinates | |
// used by pollDOM to update them to popup dialog | |
// TODO: definitely not the best practise but a quick hack that seems to work (for now) | |
var newCoordinates = ""; | |
GM_registerMenuCommand("Configure", () => { GM_config.open(); }, "C"); | |
GM_config.init( | |
{ | |
'id': 'MyConfig', // The id used for this instance of GM_config | |
'title': 'Script Settings', // Panel Title | |
'fields': // Fields object | |
{ | |
'OutputDD': | |
{ | |
'label': 'Show dd (decimal degrees) format (60.12345 25.4321) coordinates in output', // Appears next to field | |
'type': 'checkbox', // Makes this setting a checkbox input | |
'default': false // Default value if user doesn't change it | |
}, | |
'OutputCodes': | |
{ | |
'label': 'Show wherigo codes in output', // Appears next to field | |
'type': 'checkbox', // Makes this setting a checkbox input | |
'default': false // Default value if user doesn't change it | |
}, | |
'OutputDistance': | |
{ | |
'label': 'Show distance to bogus in output', // Appears next to field | |
'type': 'checkbox', // Makes this setting a checkbox input | |
'default': false // Default value if user doesn't change it | |
} | |
} | |
}); | |
/* async */ function dd2dm(latdd, londd) { | |
var lat = latdd; | |
var lon = londd; | |
var latResult, lonResult, dmsResult; | |
lat = parseFloat(lat); | |
lon = parseFloat(lon); | |
latResult = /* await */ lat_dd2dm(lat); | |
lonResult = /* await */ lon_dd2dm(lon); | |
// Joining both variables and separate them with a space. | |
dmsResult = latResult + ' ' + lonResult; | |
// Return the resultant string | |
return { result: dmsResult, lat: latResult, lon: lonResult }; | |
} | |
/* async */ function lat_dd2dm(val) { | |
var valDeg, valMin, result; | |
val = Number(val); | |
result = (val >= 0)? 'N' : 'S'; | |
result += " "; | |
val = Math.abs(val); | |
valDeg = Math.floor(val); | |
if( valDeg < 10 ) { | |
result += "0" + valDeg; | |
} | |
else { | |
result += valDeg; | |
} | |
result += "\xB0"; | |
result += " "; | |
valMin = ((val - valDeg) * 60).toFixed(3); | |
if( valMin < 10) { | |
result += "0" + valMin; | |
} | |
else { | |
result += valMin; | |
} | |
return result; | |
} | |
/* async */ function lon_dd2dm(val) { | |
var valDeg, valMin, result; | |
val = Number(val); | |
result = (val >= 0)? 'E' : 'W'; | |
result += " "; | |
val = Math.abs(val); | |
valDeg = Math.floor(val); | |
if( valDeg < 10 ) { | |
result += "00" + valDeg; | |
} | |
else if( valDeg < 100) { | |
result += "0" + valDeg; | |
} | |
else { | |
result += valDeg; | |
} | |
result += "\xB0"; | |
result += " "; | |
valMin = ((val - valDeg) * 60).toFixed(3); | |
if( valMin < 10) { | |
result += "0" + valMin; | |
} | |
else { | |
result += valMin; | |
} | |
return result; | |
} | |
/* async */ function code2LatLon(varA, varB, varC) { | |
let latSign, lonSign, lonValue, latValue; | |
console.debug("Converting [" + varA + ", " + varB + ", " + varC + "] to LatLon" ); | |
// 123456 => digit 1 (d1) = 6; digit 2 (d2) = 5; ... | |
// syntax for varA => digit 1 var A = A1; digit 2 varA = A2; ... | |
// A3 | |
if ((varA % 1000 - varA % 100) / 100 == 1) { | |
latSign = 1; | |
lonSign = 1; | |
} | |
// A3 | |
else if ((varA % 1000 - varA % 100) / 100 == 2) { | |
latSign = -1; | |
lonSign = 1; | |
} | |
// A3 | |
else if ((varA % 1000 - varA % 100) / 100 == 3) { | |
latSign = 1; | |
lonSign = -1; | |
} | |
// A3 | |
else if ((varA % 1000 - varA % 100) / 100 == 4) { | |
latSign = -1; | |
lonSign = -1; | |
} | |
//T41140 / Q1TQ01 / 14S4RS | |
// A6 B3 B4 B6 C1 C2 C4 | |
// TODO: how to iterate only these, not full range ?? | |
// C (d5 + d2) eli C5 + C2 = parillinen | |
if ( ((varC % 100000 - varC % 10000) / 10000 + (varC % 100 - varC % 10) / 10) % 2 === 0) { | |
// A4 B2 B5 C3 A6 C2 A1 | |
latValue = Number(((varA % 10000 - varA % 1000) / 1000 * 10 + (varB % 100 - varB % 10) / 10 + (varB % 100000 - varB % 10000) / 10000 * 0.1 + (varC % 1000 - varC % 100) / 100 * 0.01 + (varA % 1000000 - varA % 100000) / 100000 * 0.001 + (varC % 100 - varC % 10) / 10 * 1.0E-4 + varA % 10 * 1.0E-5)); | |
// A5 C6 C1 B3 B6 A2 C5 B1 | |
lonValue = Number(((varA % 100000 - varA % 10000) / 10000 * 100 + (varC % 1000000 - varC % 100000) / 100000 * 10 + varC % 10 + (varB % 1000 - varB % 100) / 100 * 0.1 + (varB % 1000000 - varB % 100000) / 100000 * 0.01 + (varA % 100 - varA % 10) / 10 * 0.001 + (varC % 100000 - varC % 10000) / 10000 * 1.0E-4 + varB % 10 * 1.0E-5)); | |
} | |
// C (d5 + d2) eli C5+C2= pariton | |
else if ( ((varC % 100000 - varC % 10000) / 10000 + (varC % 100 - varC % 10) / 10) % 2 !== 0) { | |
// B6 A1 A4 C6 C3 C2 A6 | |
latValue = Number(((varB % 1000000 - varB % 100000) / 100000 * 10 + varA % 10 + (varA % 10000 - varA % 1000) / 1000 * 0.1 + (varC % 1000000 - varC % 100000) / 100000 * 0.01 + (varC % 1000 - varC % 100) / 100 * 0.001 + (varC % 100 - varC % 10) / 10 * 1.0E-4 + (varA % 1000000 - varA % 100000) / 100000 * 1.0E-5)); | |
// B2 C1 A2 A5 B3 B1 C5 B5 | |
lonValue = Number(((varB % 100 - varB % 10) / 10 * 100 + varC % 10 * 10 + (varA % 100 - varA % 10) / 10 + (varA % 100000 - varA % 10000) / 10000 * 0.1 + (varB % 1000 - varB % 100) / 100 * 0.01 + varB % 10 * 0.001 + (varC % 100000 - varC % 10000) / 10000 * 1.0E-4 + (varB % 100000 - varB % 10000) / 10000 * 1.0E-5)); | |
} | |
// B4 C4 = ALWAYS ignore | |
latValue = latSign * latValue; | |
lonValue = lonSign * lonValue; | |
return { lat: latValue, lon: lonValue }; | |
} | |
function fix(v, left, right) { | |
return (v < 0 ? '-' : ' ') + Math.abs(v).toFixed(right).padStart(left + right + 1, '0'); | |
} | |
function haversineDistance(lat1,lon1,lat2,lon2) { | |
const R = 6371e3; // metres | |
const φ1 = lat1 * Math.PI/180; // φ, λ in radians | |
const φ2 = lat2 * Math.PI/180; | |
const Δφ = (lat2-lat1) * Math.PI/180; | |
const Δλ = (lon2-lon1) * Math.PI/180; | |
const a = Math.sin(Δφ/2) * Math.sin(Δφ/2) + | |
Math.cos(φ1) * Math.cos(φ2) * | |
Math.sin(Δλ/2) * Math.sin(Δλ/2); | |
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); | |
const d = R * c; // in metres | |
return d; | |
} | |
function dm2dd( nsew, deg, min ) { | |
let sign; | |
if( nsew == 'N' || nsew == 'E' ) { | |
sign = 1; | |
} | |
else { | |
sign = -1; | |
} | |
let numdeg = parseInt(deg); | |
let nummin = parseFloat(min); | |
let dd = sign * (numdeg + nummin/60); | |
return dd; | |
} | |
function createShowSourceButton() { | |
let mybutton = document.createElement("srcbutton"); | |
mybutton.innerHTML = "View source"; | |
mybutton.setAttribute("style", "-webkit-appearance: button;-moz-appearance: button;appearance: button; background-color: green; color: white; border: none; text-align: center; display: inline-block; padding: 3px 10px; border: 1px solid black; cursor: pointer;"); | |
let noteref = document.getElementsByClassName("minorCacheDetails Clear")[0]; | |
noteref.appendChild(mybutton); | |
mybutton.addEventListener("click", function() { | |
var desc1 = document.getElementById("ctl00_ContentBody_ShortDescription").innerHTML; | |
var desc2 = document.getElementById("ctl00_ContentBody_LongDescription").innerHTML; | |
alert( desc1 + desc2 ); | |
}); | |
} | |
function createShowSolveREReverseButton() { | |
// let mybutton = document.createElement("solvebutton"); | |
let mybutton = document.createElement("a"); | |
mybutton.innerHTML = "Solve Regexp"; | |
mybutton.className = "mybtn"; | |
//css | |
mybutton.setAttribute("style", "-webkit-appearance: button;-moz-appearance: button;appearance: button; background-color: green; color: white; border: none; text-align: center; display: inline-block; padding: 3px 10px; border: 1px solid black; cursor: pointer;"); | |
let noteref = document.getElementsByClassName("minorCacheDetails Clear")[0]; | |
noteref.appendChild(mybutton); | |
mybutton.addEventListener("click", function() { | |
solveReverseRE(); | |
}); | |
/* | |
mybutton.addEventListener("click", function() { | |
$( function() { | |
$( "#dialog" ).dialog({width: "auto"}) | |
.next(".ui-widget-overlay") | |
.css({ | |
opacity: 1.0, | |
filter: "Alpha(Opacity=100)", | |
backgroundColor: "black" | |
}); | |
} ); | |
solveReverseRE(); | |
}); | |
*/ | |
} | |
function createDialog( ) { | |
let mydialog = document.createElement("div"); | |
mydialog.id = "dialog"; | |
mydialog.title = "Results"; | |
let resultmsg = document.createElement("p"); | |
resultmsg.id = "resultmsg"; | |
mydialog.appendChild(resultmsg); | |
// let noteref = document.getElementsByClassName("minorCacheDetails Clear")[0]; | |
let noteref = document.getElementById("ctl00_ContentBody_detailWidget"); | |
noteref.appendChild(mydialog); | |
} | |
// TODO: definitely not the best practice, but works (for now) | |
function pollDOM() { | |
const newCrd = document.getElementById('newCoordinates'); | |
if (newCrd != null) { | |
// Do something with el | |
newCrd.value = newCoordinates; | |
let submitBtn = document.getElementsByClassName("btn-cc-parse")[0]; | |
//ssubmitBtn.click(); | |
} else { | |
setTimeout(pollDOM, 300); // try again in 300 milliseconds | |
} | |
} | |
function updateCoordinates( newCoords ) { | |
let crd = document.getElementById("uxLatLonLink"); | |
crd.click(); | |
newCoordinates = newCoords; | |
pollDOM(); | |
console.debug("XX: " + newCoords); | |
} | |
// retrieve bogus coordinates in ddm | |
// returns array [ lat side (N/S), lat deg, lat mindec, lon side (E/W), lon deg, lon mindec ]; | |
function getBogusCoordsFromPage() { | |
let coords = document.getElementById("uxLatLon").textContent.split(" "); | |
if( coords.length != 6 ) { | |
console.error("Error parsing coordinates"); | |
return; | |
} | |
return coords; | |
} | |
// convert latitude longitude array [ lat side (N/S), lat deg, lat mindec, lon side (E/W), lon deg, lon mindec ] to dd | |
// return { lat: latitude dd , lon: longitude dd } | |
function latLonDmArr2dd( latLonDmArray ) { | |
// convert bogus coordinates from deg-mindec to deg-dec | |
let bogusLat = dm2dd( latLonDmArray[0], latLonDmArray[1], latLonDmArray[2] ); | |
let bogusLon = dm2dd( latLonDmArray[3], latLonDmArray[4], latLonDmArray[5] ); | |
return { lat : bogusLat, lon : bogusLon }; | |
} | |
// htmlsnip = html snippet in string | |
// replace = boolean; true = replace existing html fully | |
function addHTMLtoPage( htmlsnip, replace ) { | |
let docEl = document.getElementsByClassName("Note Disclaimer")[0]; | |
if( replace ) { | |
docEl.innerHTML = htmlsnip; | |
} | |
else { | |
docEl.innerHTML = docEl.innerHTML + htmlsnip; | |
} | |
} | |
function onlyUnique(value, index, self) { | |
return self.indexOf(value) === index; | |
} | |
function* makeRangeIterator(start = 0, end = 100, step = 1) { | |
let iterationCount = 0; | |
for (let i = start; i < end; i += step) { | |
iterationCount++; | |
yield i; | |
} | |
return iterationCount; | |
} | |
function* makeRangeIterator2(variables = 1, start = 0, end = 100, step = 1) { | |
let iterationCount = 0; | |
for (let i = start; i < end; i += step) { | |
iterationCount++; | |
yield i; | |
} | |
return iterationCount; | |
} | |
function testGenerator() { | |
const it = makeRangeIterator(0, 9, 1); | |
let result = it.next(); | |
while (!result.done) { | |
console.log(result.value); // 0 1 2 3 4 5 6 7 8 9 | |
result = it.next(); | |
} | |
} | |
// Works in Chrome devtools console | |
function* codeGenerator ( codes, vars ) { | |
// check if no variables left => return final codes | |
console.debug("Vars.length = " + vars.length); | |
if( vars == null || vars.length == 0 ) { | |
console.debug("Yield" + JSON.stringify(codes)); | |
yield codes; | |
} | |
else { | |
// generate regexp to replace VAR => number | |
let replRE = new RegExp("/"+vars[0]+"/g"); | |
console.debug("RE " + JSON.stringify(replRE)); | |
// for each var value [0,9] | |
for(let i=0; i<10; i++ ) { | |
let c = []; | |
c[0] = codes[0].replace(vars[0], i.toString()); | |
c[1] = codes[1].replace(vars[0], i.toString()); | |
c[2] = codes[2].replace(vars[0], i.toString()); | |
console.debug("/"+vars[0]+"/g -> " + JSON.stringify(c)); | |
// recursively get the other variables processed | |
yield* codeGenerator( c, vars.slice(1) ); | |
} | |
} | |
} | |
// replace char at position index for string with replacement | |
String.prototype.replaceAt = function(index, replacement) { | |
return this.substr(0, index) + replacement + this.substr(index + replacement.length); | |
}; | |
/* async */ function solveReverseRE() { | |
console.debug("Attempting to parse codes from note."); | |
let resultmsg = document.getElementsByClassName("Note Disclaimer")[0]; | |
let codes = parseCodesFromNote(); | |
if(codes.length != 3) { | |
console.error("Error: >3 or <3 codes found:" + JSON.stringify(codes)); | |
} | |
// cleanse | |
for(let i=0; i<3; i++) { | |
codes[i] = codes[i].trim(); | |
} | |
console.debug("Parsed: " + JSON.stringify(codes)); | |
// TODO: remove vars from non meaningful items : B4 C4 = ALWAYS ignore | |
console.log("Emptying non-meaninful digits B4 C4"); | |
codes[1] = codes[1].replaceAt( 6-4, "0"); //reset B4 | |
codes[2] = codes[2].replaceAt( 6-4, "0"); //reset C4 | |
console.debug("Cleansed: " + JSON.stringify(codes)); | |
// calculate # of variables/unknowns per code | |
let vars = []; | |
for(let i=0; i<3; i++) { | |
let matching = codes[i].match(/[A-Za-z]/g); | |
if(matching != null) | |
vars = vars.concat( matching ); | |
} | |
console.debug("Vars: " + JSON.stringify(vars)); | |
let uniqVars = vars.filter(onlyUnique); | |
console.log(uniqVars.length + " unique variables"); | |
console.warn("Possible total combos: " + 10**uniqVars.length); | |
let bogusLatLonArr = getBogusCoordsFromPage(); | |
// convert bogus coordinates from deg-min-dec to deg-dec | |
let bogusDD = latLonDmArr2dd(bogusLatLonArr); | |
let bogusLat = bogusDD.lat; | |
let bogusLon = bogusDD.lon; | |
console.debug("Parsed coords: " + JSON.stringify(bogusLatLonArr)); | |
console.debug("Converted coords: " + bogusLat + " " + bogusLon); | |
console.debug("Iterating..."); | |
console.log("code1,code2,code3,lat(dd),lon(dd),lat(gps),lon(gps),dist(m)"); | |
let counter = 0; | |
let codeGen = codeGenerator( codes, uniqVars ); | |
let nextCode = codeGen.next(); | |
console.debug(JSON.stringify(nextCode)); | |
while (!nextCode.done) { | |
// convert to dd | |
let ddlatlon = code2LatLon( parseInt( nextCode.value[0] ), parseInt( nextCode.value[1] ) , parseInt( nextCode.value[2]) ); | |
console.debug("Convertion results: " + JSON.stringify(ddlatlon)); | |
if( ddlatlon.lat == NaN || ddlatlon.lon == NaN ) continue; | |
else { | |
let dist = haversineDistance( bogusLat, bogusLon, ddlatlon.lat, ddlatlon.lon ); | |
if( dist < 3220 ) { | |
counter = counter+1; | |
let dmlatlon = /* await */ dd2dm( ddlatlon.lat, ddlatlon.lon); | |
let result = nextCode.value[0] + "," + nextCode.value[1] + "," + nextCode.value[2] + "," + fix(ddlatlon.lat, 2, 6) + "," + fix(ddlatlon.lon, 3, 6) + "," + dmlatlon.lat + "," + dmlatlon.lon + "," + dist.toFixed(0) ; | |
console.log(result); | |
let result2 = ""; | |
// if config output DD on, print also DD coords to output (makes it easier to deduce some variables) | |
if( GM_config.get('OutputDD') ) { | |
result2 = fix(ddlatlon.lat, 2, 6) + " " + fix(ddlatlon.lon, 3, 6) + " | "; | |
} | |
// default output | |
result2 = result2 + dmlatlon.lat + " " + dmlatlon.lon; | |
// if config option OutputCodes = true, output also calculated wigo codes | |
if( GM_config.get('OutputCodes') ) { | |
result2 = result2 + " [" + nextCode.value[0] + "," + nextCode.value[1] + "," + nextCode.value[2] + "]" ; | |
} | |
if( GM_config.get('OutputDistance') ) { | |
result2 = result2 + " ⟼ " + dist.toFixed(0) + " m"; | |
} | |
resultmsg.innerText = resultmsg.innerText + "\n" + result2; | |
} | |
/* else { | |
let dmlatlon = dd2dm( ddlatlon.lat, ddlatlon.lon); | |
let result = nextCode.value[0] + "," + nextCode.value[1] + "," + nextCode.value[2] + "," + fix(ddlatlon.lat, 2, 6) + "," + fix(ddlatlon.lon, 3, 6) + "," + dmlatlon.lat + "," + dmlatlon.lon + "," + dist.toFixed(0) + "out of range" ; | |
console.warn(result); | |
} */ | |
} | |
nextCode = codeGen.next(); | |
} | |
console.log("Total hits in range: " + counter); | |
} | |
function addBogusDDToPage() { | |
let bogusLatLonArr = getBogusCoordsFromPage(); | |
// convert bogus coordinates from deg-min-dec to deg-dec | |
let bogusDD = latLonDmArr2dd(bogusLatLonArr); | |
let bogusLat = bogusDD.lat; | |
let bogusLon = bogusDD.lon; | |
console.debug("Parsed coords: " + JSON.stringify(bogusLatLonArr)); | |
console.debug("Converted coords: " + bogusLat + " " + bogusLon); | |
// add bogus dd coordinates on page | |
addHTMLtoPage( "<strong> Bogus: " + bogusLat + " " + bogusLon + " </strong>", true ); | |
/*let locnode = document.getElementById("ctl00_ContentBody_LocationSubPanel"); | |
locnode.textContent = bogusLat + " " + bogusLon; | |
locnode.appendChild( document.createElement("br")); | |
*/ | |
} | |
// takes wigo codes as strings (may consist not numbers (variables) e.g. 022345 042x21 924ab9) | |
// returns resulting coordinate (DD) string | |
function evalPartialReverseWigo(codeA, codeB, codeC) { | |
// validate that these are numbers | |
console.debug("Input: " + codeA + ", " + codeB + ", " + codeC); | |
if( isNaN( codeC[6-5] ) == false && isNaN( codeC[6-2] ) == false ) { | |
// C5 + C2 = parillinen | |
if( (Number(codeC[6-5]) + Number(codeC[6-2])) % 2 === 0 ) { | |
console.debug("parillinen"); | |
// A4 B2 B5 C3 A6 C2 A1 | |
let resLat = "" + codeA[6-4] + codeB[6-2] + "." + codeB[6-5] + codeC[6-3] + codeA[6-6] + codeC[6-2] + codeA[6-1]; | |
// A5 C6 C1 B3 B6 A2 C5 B1 | |
let resLon = "" + codeA[6-5] + codeC[6-6] + codeC[6-1] + "." + codeB[6-3] + codeB[6-6] + codeA[6-2] + codeC[6-5] + codeB[6-1]; | |
console.debug(resLat + " " + resLon); | |
return resLat + " " + resLon; | |
} | |
// C (d5 + d2) eli C5+C2= pariton | |
else if ( (Number(codeC[6-5]) + Number(codeC[6-2])) %2 !== 0 ) { | |
console.debug("pariton"); | |
// B6 A1 A4 C6 C3 C2 A6 | |
let resLat = "" + codeB[6-6] + codeA[6-1] + "." + codeA[6-4] + codeC[6-6] + codeC[6-3] + codeC[6-2] + codeA[6-6]; | |
// B2 C1 A2 A5 B3 B1 C5 B5 | |
let resLon = "" + codeB[6-2] + codeC[6-1] + codeA[6-2] + "." + codeA[6-5] + codeB[6-3] + codeB[6-1] + codeC[6-5] + codeB[6-5]; | |
console.debug(resLat + " " + resLon); | |
return resLat + " " + resLon; | |
} | |
} | |
else { | |
console.debug("parillinen tai pariton"); | |
console.warn("Cannot deduce which equation to use - showing both results"); | |
let resLat1 = "" + codeA[6-4] + codeB[6-2] + "." + codeB[6-5] + codeC[6-3] + codeA[6-6] + codeC[6-2] + codeA[6-1]; | |
// A5 C6 C1 B3 B6 A2 C5 B1 | |
let resLon1 = "" + codeA[6-5] + codeC[6-6] + codeC[6-1] + "." + codeB[6-3] + codeB[6-6] + codeA[6-2] + codeC[6-5] + codeB[6-1]; | |
let resLat2 = "" + codeB[6-6] + codeA[6-1] + "." + codeA[6-4] + codeC[6-6] + codeC[6-3] + codeC[6-2] + codeA[6-6]; | |
// B2 C1 A2 A5 B3 B1 C5 B5 | |
let resLon2 = "" + codeB[6-2] + codeC[6-1] + codeA[6-2] + "." + codeA[6-5] + codeB[6-3] + codeB[6-1] + codeC[6-5] + codeB[6-5]; | |
console.debug( resLat1 + " " + resLon1 + "\n OR \n" + resLat2 + " " + resLon2 ); | |
return resLat1 + " " + resLon1 + " <br>OR<br> " + resLat2 + " " + resLon2; | |
} | |
// A3 B4 C4 = ALWAYS ignore | |
} | |
// parse reverse wherigo codes from note | |
function parseCodesFromNote() { | |
let re1 = /RWIGO:/g; | |
let re2 = /[0-9A-Za-z]{6}/g; | |
console.log("Trying to find codes from user note:"); | |
let text = document.getElementById("viewCacheNote").innerText; | |
if( text.match( re1 ) ) { | |
console.debug("Match found (RWIGO:)"); | |
let codes = text.match( re2 ); | |
console.debug( JSON.stringify( codes ) ); | |
return codes; | |
} | |
else { | |
console.debug("No codes found from Personal Note"); | |
return null; | |
} | |
} | |
// parse codes from cache description | |
function parseCodesFromDescription() { | |
let re = /[0-9]{6}/g; | |
let codes = document.getElementsByClassName("UserSuppliedContent")[1].innerText.match( re ); | |
return codes; | |
} | |
(/* async */ function() { | |
'use strict'; | |
let from, result; | |
let cacheType = document.getElementsByClassName("cacheImage")[0].title; | |
createShowSourceButton(); | |
addBogusDDToPage(); | |
if( cacheType == "Wherigo Cache" ) { | |
createShowSolveREReverseButton(); | |
createDialog(); | |
let codes = parseCodesFromNote(); | |
// Codes found from Personal Note | |
if( codes !== null && codes.length >= 3 ) { | |
console.debug("Match: " + codes[0] + "," + codes[1] + "," + codes[2] ); | |
let reverseRes = evalPartialReverseWigo( codes[0], codes[1], codes[2] ); | |
addHTMLtoPage("<br><strong>Codes with variables converted to coordinates: <br>"+reverseRes+"</strong>", false); | |
// TODO: how to check if code 2 coords conversion is valid => only show if it is | |
let ddlatlon = /* await */ code2LatLon( codes[0], codes[1], codes[2] ); | |
let dmlatlon = /* await */ dd2dm( ddlatlon.lat, ddlatlon.lon); | |
from = codes[0] + " " + codes[1] + " " + codes[2] + " => "; | |
let resultDD = fix(ddlatlon.lat, 2, 6) + " " + fix(ddlatlon.lon, 3, 6); | |
let resultDMD = dmlatlon.lat + " " + dmlatlon.lon; | |
result = resultDMD; | |
console.log( from + " " + resultDD + " = " + resultDMD ); | |
addHTMLtoPage("<br><strong> Reversewigo final coordinates = " + result + " </strong>", false); | |
if( result != "S NaN° NaN W NaN° NaN") | |
updateCoordinates( resultDMD ); | |
} | |
// No codes in Personal Note - trying to retrieve directly from description | |
else { | |
console.log("Trying to find codes from UserSuppliedContent"); | |
codes = parseCodesFromDescription(); | |
if( codes !== null && (codes.length == 3 || codes.length == 6 || codes.length == 9) ) { | |
console.debug("Parsed codes from UserSuppliedContent: " + JSON.stringify(codes) ); | |
let reverseRes = evalPartialReverseWigo( codes[0], codes[1], codes[2] ); | |
addHTMLtoPage("<br><strong>Reverse results = "+reverseRes+"</strong>", false); | |
let ddlatlon = /* await */ code2LatLon( codes[0], codes[1], codes[2] ); | |
let dmlatlon = /* await */ dd2dm( ddlatlon.lat, ddlatlon.lon); | |
from = codes[0] + " " + codes[1] + " " + codes[2] + " => "; | |
let resultDD = fix(ddlatlon.lat, 2, 6) + " " + fix(ddlatlon.lon, 3, 6); | |
let resultDMD = dmlatlon.lat + " " + dmlatlon.lon; | |
result = resultDMD; | |
console.debug( from + " " + resultDD + " = " + resultDMD ); | |
addHTMLtoPage("<br><strong> Reversewigo final coordinates = " + result + " </strong>", false); | |
if( result != "S NaN° NaN W NaN° NaN") { | |
GM_setClipboard( result, "text" ); | |
updateCoordinates( resultDMD ); | |
} | |
} | |
else { | |
result = "Error: Reverse wherigo codes not found from description/note. <br>Enter codes to Personal Note as shown below, save and reload. <br>RWIGO:<br>123ABC<br>23D45G<br>423444"; | |
console.log( result ); | |
addHTMLtoPage("<br><strong>" + result + " </strong>", false); | |
} | |
} | |
} | |
})(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment