// ==UserScript==
// @name Geoguessr GeoStats Script
// @description Keeps track of various stats in duels games and displays it on an interactive map on your profile
// @author nappyslappy
// @version 2.0.2
// @match https://www.geoguessr.com/*
// @run-at document-start
// @grant none
// @license none
// @icon https://www.google.com/s2/favicons?sz=64&domain=geoguessr.com
// @copyright nappyslappy 2022, (https://greasyfork.org/en/users/922456)
// @namespace https://greasyfork.org/en/users/922456-nappyslappy
// @downloadURL none
// ==/UserScript==
//Published: June 6th, 2022
//Last Update: August 4th, 2022
//**************************** INFORMATION ****************************//
/* */
/* This script was mainly made to keep track */
/* of various stats in duels matches */
/* */
/* The script will monitor your duels guesses and keep a unique record */
/* for each country of the times you guessed it correctly */
/* */
/* If there is a round where you don't make a guess, */
/* it wont count against you. The script will only keep track */
/* of your record when you DO make a guess */
/* */
/* You can view the map showing your percentage score for each */
/* country at the bottom of your profile page */
/* */
/* Some countries are too small to show on the map so there is */
/* a search bar on the left hand side to filter through them */
/* */
/* Double click a country to reset its scores and */
/* to open up more detailed stats */
/* */
/***********************************************************************/
//******************************* SETUP *******************************//
/* */
/* If you haven't already, download the free extension 'tampermonkey' */
/* and then install this script */
/* */
/* This will allow the script to interact with geoguessr */
/* and keep track of your scores */
/* */
/* Go to www.bigdatacloud.com, create a free account, and */
/* go to the credentials tab in your account to find your free API key */
/* */
/* Copy and paste that key below where it says 'API_KEY' */
/* */
/* Go to your profile on Geoguessr and find your user ID under */
/* where it says 'sign out' (The last part after 'user/' is the ID) */
/* */
/* Copy and paste your ID below where it says 'USER_ID' */
/* */
/* Now just play duels and see your new scores updated on your profile */
/* */
/***********************************************************************/
//**************************** INSERT YOUR INFO HERE ****************************//
let API_KEY = ''; //Put your free api key inside ''
let USER_ID = ''; //Put your user id inside ''
//**************************** START OF SCRIPT ****************************//
//Global Variables
let alerted = false;
let profile = false;
let player_index = 0;
let previous_last_guess_number = 0;
//Check for an existing api key and user id
if(API_KEY != ''){
window.localStorage.setItem('duels-country-scores-api-key', API_KEY);
}
if(USER_ID != ''){
window.localStorage.setItem('duels-country-scores-user-id', USER_ID);
}
API_KEY = window.localStorage.getItem('duels-country-scores-api-key');
USER_ID = window.localStorage.getItem('duels-country-scores-user-id');
//Map Colors
let green_range = 0.75;
let yellow_range = 0.25;
let red_range = 0;
if(window.localStorage.getItem(`duels-map-color-left-range-${USER_ID}`)){
green_range = parseInt(window.localStorage.getItem(`duels-map-color-right-range-${USER_ID}`)) * 0.01;
yellow_range = parseInt(window.localStorage.getItem(`duels-map-color-left-range-${USER_ID}`)) * 0.01;
}
else{
window.localStorage.setItem(`duels-map-color-left-range-${USER_ID}`, 25);
window.localStorage.setItem(`duels-map-color-right-range-${USER_ID}`, 75);
}
//Set the healing rounds toggle switch
if(window.localStorage.getItem('allow-healing-rounds') == null){
window.localStorage.setItem('allow-healing-rounds', JSON.stringify({include: true}));
}
//Set the competitive mode toggle switch
if(window.localStorage.getItem('competitive-only-mode') == null){
window.localStorage.setItem('competitive-only-mode', JSON.stringify({include: true}));
}
//Evaluate the new guess
function evaluate(guess,location,distance,userScore,opponentScore,startTime,timerTime,guessTime,opponentDistance){
//If guess is in antarctica (black screen round)
if(guess == 'AQ'){
return;
}
let correct_exists = window.localStorage.getItem(`${location}-number-correct-${USER_ID}`);
let total_exists = window.localStorage.getItem(`${location}-number-total-${USER_ID}`);
let correct_overall = window.localStorage.getItem(`overall-correct-${USER_ID}`);
let total_overall = window.localStorage.getItem(`overall-total-${USER_ID}`);
let correct_value = 1;
let total_value = 1;
//Setting correct value
if(guess === location){
if(correct_exists !== null){
correct_value = parseInt(correct_exists,10);
correct_value = correct_value + 1;
}
window.localStorage.setItem(`${location}-number-correct-${USER_ID}`,correct_value);
}
//Setting overall values
if(total_overall !== null){
if(guess === location){
window.localStorage.setItem(`overall-correct-${USER_ID}`,((parseInt(correct_overall,10))+1));
}
window.localStorage.setItem(`overall-total-${USER_ID}`,((parseInt(total_overall,10))+1));
}
else{
if(guess === location){
window.localStorage.setItem(`overall-correct-${USER_ID}`,1);
}
else{
window.localStorage.setItem(`overall-correct-${USER_ID}`,0);
}
window.localStorage.setItem(`overall-total-${USER_ID}`,1);
}
//Setting total value
if(total_exists !== null){
total_value = parseInt(total_exists,10);
total_value = total_value + 1;
}
window.localStorage.setItem(`${location}-number-total-${USER_ID}`,total_value);
//Setting distance
let distance_average = window.localStorage.getItem(`${location}-distance-average-${USER_ID}`);
let distance_number = window.localStorage.getItem(`${location}-distance-number-${USER_ID}`);
if(distance_average === null && distance_number === null){
window.localStorage.setItem(`${location}-distance-average-${USER_ID}`,distance);
window.localStorage.setItem(`${location}-distance-number-${USER_ID}`,1);
}
else{
distance_number = parseInt(distance_number) + 1;
distance_average = ((distance_average * (distance_number - 1)) + distance) / distance_number;
window.localStorage.setItem(`${location}-distance-average-${USER_ID}`,distance_average);
window.localStorage.setItem(`${location}-distance-number-${USER_ID}`,distance_number);
}
//SETTING ALL OTHER STATS FOR COUNTRY AND OVERALL
let countryStats = {
totalCount: 0,
averageScore: 0,
averageDistance: 0,
closerThanOpponent: 0,
averageTime: 0,
guessedFirst: 0,
total5ks: 0,
countryCorrectStreak: 0,
countryCorrectMax: 0,
countryWrongStreak: 0,
countryWrongMax: 0,
distanceFromOpponent: [0,0],
};
let overallStats = {
//Total
totalCount: 0,
totalWin: 0,
totalLoss: 0,
total5ks: 0,
totalGames: 0,
totalSeconds: 0,
//Average
averageScore: 0,
averageDistance: 0,
averageGameLengthWin: 0,
averageGameLengthLoss: 0,
averageTime: 0,
//Other
guessedFirst: 0,
closerThanOpponent: 0,
countryCorrectStreak: 0,
countryCorrectMax: 0,
countryWrongStreak: 0,
countryWrongMax: 0,
opponentRating: 0,
distanceFromOpponent: [0,0],
};
if(window.localStorage.getItem(`${location}-all-country-stats-${USER_ID}`)){
countryStats = JSON.parse(window.localStorage.getItem(`${location}-all-country-stats-${USER_ID}`));
}
if(window.localStorage.getItem(`overall-country-stats-${USER_ID}`)){
overallStats = JSON.parse(window.localStorage.getItem(`overall-country-stats-${USER_ID}`));
}
//Time String to Seconds
function timeToSeconds(value){
let time = value.slice(11,19);
time = time.split(/[.:]/);
time = (parseInt(time[0]) * 60 * 60) + (parseInt(time[1]) * 60) + parseInt(time[2]);
return time;
}
//Get Correct Time Values
startTime = timeToSeconds(startTime);
timerTime = timeToSeconds(timerTime);
guessTime = timeToSeconds(guessTime);
let timeToGuess = guessTime - startTime;
//Total Count
countryStats.totalCount++;
overallStats.totalCount++;
//Average Score
countryStats.averageScore = ((countryStats.averageScore * (countryStats.totalCount - 1)) + userScore) / countryStats.totalCount;
overallStats.averageScore = ((overallStats.averageScore * (overallStats.totalCount - 1)) + userScore) / overallStats.totalCount;
//Average Distance
countryStats.averageDistance = ((countryStats.averageDistance * (countryStats.totalCount - 1)) + distance) / countryStats.totalCount;
overallStats.averageDistance = ((overallStats.averageDistance * (overallStats.totalCount - 1)) + distance) / overallStats.totalCount;
//Average Time
countryStats.averageTime = ((countryStats.averageTime * (countryStats.totalCount - 1)) + timeToGuess) / countryStats.totalCount;
overallStats.averageTime = ((overallStats.averageTime * (overallStats.totalCount - 1)) + timeToGuess) / overallStats.totalCount;
//Closer Than Opponent
if(userScore >= opponentScore){
countryStats.closerThanOpponent++;
overallStats.closerThanOpponent++;
}
//Guessed First
if(guessTime == timerTime){
countryStats.guessedFirst++;
overallStats.guessedFirst++;
}
//Total 5ks
if(userScore >= 4999){
countryStats.total5ks++;
overallStats.total5ks++;
}
//Country Streak (Correct)
if(guess == location){
//Country
countryStats.countryWrongStreak = 0;
countryStats.countryCorrectStreak++;
if(countryStats.countryCorrectStreak > countryStats.countryCorrectMax){
countryStats.countryCorrectMax = countryStats.countryCorrectStreak;
}
//Overall
overallStats.countryWrongStreak = 0;
overallStats.countryCorrectStreak++;
if(overallStats.countryCorrectStreak > overallStats.countryCorrectMax){
overallStats.countryCorrectMax = overallStats.countryCorrectStreak;
}
}
//Country Streak (Incorrect)
if(guess != location){
//Country
countryStats.countryCorrectStreak = 0;
countryStats.countryWrongStreak++;
if(countryStats.countryWrongStreak > countryStats.countryWrongMax){
countryStats.countryWrongMax = countryStats.countryWrongStreak;
}
//Overall
overallStats.countryCorrectStreak = 0;
overallStats.countryWrongStreak++;
if(overallStats.countryWrongStreak > overallStats.countryWrongMax){
overallStats.countryWrongMax = overallStats.countryWrongStreak;
}
}
//Distance From Opponent
if(opponentDistance != 'DNF'){
let distanceDifference = opponentDistance - distance;
//Country
if(countryStats.distanceFromOpponent){
countryStats.distanceFromOpponent[0]++;
countryStats.distanceFromOpponent[1] = ((countryStats.distanceFromOpponent[1] * (countryStats.distanceFromOpponent[0] - 1)) + distanceDifference) / countryStats.distanceFromOpponent[0];
}
else{
countryStats.distanceFromOpponent = [1,distanceDifference];
}
//Overall
if(overallStats.distanceFromOpponent){
overallStats.distanceFromOpponent[0]++;
overallStats.distanceFromOpponent[1] = ((overallStats.distanceFromOpponent[1] * (overallStats.distanceFromOpponent[0] - 1)) + distanceDifference) / overallStats.distanceFromOpponent[0];
}
else{
overallStats.distanceFromOpponent = [1,distanceDifference];
}
}
//Save Updated Stats
window.localStorage.setItem(`${location}-all-country-stats-${USER_ID}`, JSON.stringify(countryStats));
window.localStorage.setItem(`overall-country-stats-${USER_ID}`, JSON.stringify(overallStats));
};
//Add Stats When Game Is Finished
function gameFinished(opponentRating,userBefore,userAfter,gameId,gameLength,start,end){
if(window.sessionStorage.getItem('current-game-id') == gameId){
return;
}
window.sessionStorage.setItem('current-game-id', gameId);
//Time String to Seconds
function timeToSeconds(value){
let time = value.slice(11,19);
time = time.split(/[.:]/);
time = (parseInt(time[0]) * 60 * 60) + (parseInt(time[1]) * 60) + parseInt(time[2]);
return time;
}
let overallStats = JSON.parse(window.localStorage.getItem(`overall-country-stats-${USER_ID}`));
let gameTime = timeToSeconds(end) - timeToSeconds(start);
//Total Games Played
overallStats.totalGames++;
//Average Opponent Rating
overallStats.opponentRating = ((overallStats.opponentRating * (overallStats.totalGames - 1)) + opponentRating) / overallStats.totalGames;
//Win or Loss
let win = false;
if(userAfter - userBefore >= 0){
win = true;
}
//Game Length (Win)
if(win){
overallStats.totalWin++;
overallStats.averageGameLengthWin = ((overallStats.averageGameLengthWin * (overallStats.totalWin - 1)) + gameLength) / overallStats.totalWin;
}
//Game Length (Loss)
if(!win){
overallStats.totalLoss++;
overallStats.averageGameLengthLoss = ((overallStats.averageGameLengthLoss * (overallStats.totalLoss - 1)) + gameLength) / overallStats.totalLoss;
}
//Total Seconds Played
if(overallStats.totalSeconds){
overallStats.totalSeconds += gameTime;
}
else{
overallStats.totalSeconds = gameTime;
}
//Save Updated Stats
window.localStorage.setItem(`overall-country-stats-${USER_ID}`, JSON.stringify(overallStats));
};
//Get the guess country code
async function getGuessCountryCode(location){
if(location[0] <= -85.05 || location == null){
return 'AQ';
}
else{
let api = "https://api.bigdatacloud.net/data/reverse-geocode?latitude="+location[0]+"&longitude="+location[1]+"&localityLanguage=en&key="+API_KEY;
let country_code = await fetch(api)
.then(res => res.json())
.then((out) => {
return out.countryCode;
})
return country_code;
};
};
//Check if a new guess has been made
async function checkGuess(api){
return new Promise((resolve,reject) => {
fetch(api,{credentials: 'include'})
.then((res) => res.json())
.then((out) => {
if(out.teams[0].players[0].playerId === USER_ID){
player_index = 0;
}
else if(out.teams[1].players[0].playerId === USER_ID){
player_index = 1;
}
else{
if(!alerted){
alert('Duels Record Script:\nMAKE SURE YOU HAVE THE CORRECT USER ID');
alerted = true;
}
return;
}
//If competitve only mode is on
let competitiveOnly = JSON.parse(window.localStorage.getItem('competitive-only-mode'));
if(competitiveOnly.include && !out.options.isRated){
return;
}
let last_guess_number = out.teams[player_index].players[0].guesses.length;
//If the game is finished
if(out.status == 'Finished'){
let opponentIndex = 0;
if(player_index == 0){
opponentIndex = 1;
}
let opponentRatingBefore = out.teams[opponentIndex].players[0].rating;
let userRatingBefore = out.teams[player_index].players[0].progressChange.competitiveProgress.ratingBefore;
let userRatingAfter = out.teams[player_index].players[0].progressChange.competitiveProgress.ratingAfter;
let gameLength = out.currentRoundNumber;
let gameStartTime = out.rounds[0].startTime;
let gameEndTime = out.rounds[gameLength-1].endTime;
gameFinished(opponentRatingBefore,userRatingBefore,userRatingAfter,out.gameId,gameLength,gameStartTime,gameEndTime);
return;
}
//If the round's guesses haven't been sent
if(out.teams[player_index].roundResults.length != last_guess_number){
return;
}
//If a new guess hasn't been made
if(last_guess_number == previous_last_guess_number){
return;
}
else if(out.teams[player_index].players[0].guesses[last_guess_number-1].roundNumber !== out.currentRoundNumber){
return;
}
//If include healing toggle is off
let allowHealing = JSON.parse(window.localStorage.getItem('allow-healing-rounds'));
if(!allowHealing.include && out.rounds[out.currentRoundNumber-1].isHealingRound){
return;
}
let current_guess = [out.teams[player_index].players[0].guesses[last_guess_number-1].lat, out.teams[player_index].players[0].guesses[last_guess_number-1].lng];
//If the player refreshes during the 15 second countdown after making a guess
if(current_guess[0] == window.sessionStorage.getItem('last-guess-lat') && current_guess[1] == window.sessionStorage.getItem('last-guess-lng')){
return;
}
else{
window.sessionStorage.setItem('last-guess-lat', current_guess[0]);
window.sessionStorage.setItem('last-guess-lng', current_guess[1]);
}
//Everything is good
previous_last_guess_number = last_guess_number;
let current_round = out.currentRoundNumber;
getGuessCountryCode(current_guess)
.then((guess) => {
//Get all values
let location_code = out.rounds[current_round-1].panorama.countryCode.toUpperCase();
let distance = out.teams[player_index].players[0].guesses[last_guess_number-1].distance;
let opponent_index = 0;
if(player_index == 0){
opponent_index = 1;
}
let userScore = out.teams[player_index].roundResults[last_guess_number-1].score;
let opponentScore = out.teams[opponent_index].roundResults[last_guess_number-1].score;
let startTime = out.rounds[current_round-1].startTime;
let timerTime = out.rounds[current_round-1].timerStartTime;
let guessTime = out.teams[player_index].players[0].guesses[last_guess_number-1].created;
let opponentDistance = 'DNF';
if(out.teams[opponent_index].players[0].guesses[current_round-1]){
opponentDistance = out.teams[opponent_index].players[0].guesses[current_round-1].distance;
}
//If guess is good
if(guess != undefined){
//Evaluate all values and update stats
evaluate(guess,location_code,distance,userScore,opponentScore,startTime,timerTime,guessTime,opponentDistance);
}
resolve(out);
});
})
.catch((error) => {
reject(error);
});
});
}
//Check if the user is on the profile page
function profileCheck(){
if(location.pathname.endsWith('/profile') && !profile){
if(document.getElementsByClassName('text-input_textInput__HPC_k')[0].value.includes(USER_ID)){
addMapToProfile();
}
}
else if(!location.pathname.endsWith('/profile') && profile){
profile = false;
document.getElementById('map-wrapper-element').remove();
document.getElementById('css-for-map').remove();
}
}
//Check if the user is playing a duels game
function duelsCheck(){
if(!location.pathname.startsWith('/duels/') || location.pathname.endsWith('/summary')){
return;
}
const game_tag = window.location.href.substring(window.location.href.lastIndexOf('/') + 1);
const api_url = "https://game-server.geoguessr.com/api/duels/"+game_tag;
checkGuess(api_url);
};
//Run duelsCheck and profileCheck every half-second
setInterval(duelsCheck,500);
setInterval(profileCheck,500);
//Console Log Script Name
console.log('*** Geoguessr GeoStats v2.0.2 by NappySlappy ***');
/************************************************** MAP STUFF HERE **************************************************/
//Add the map (and related stuff) to the bottom of the profile page
function addMapToProfile(){
profile = true;
const svgMap = document.createElement('div');
svgMap.setAttribute('id','map-wrapper-element');
const cssForMap = document.createElement('style');
cssForMap.setAttribute('id', 'css-for-map');
const scriptForMap = document.createElement('script');
scriptForMap.setAttribute('id', 'script-for-map');
cssForMap.textContent = `
.map-wrapper-element{
position: relative;
left: 0px;
}
#map-title{
font-size: 30px;
text-align: center;
color: var(--ds-color-yellow-50);
font-family: var(--font-neo-sans);
}
#total-percentage-wrapper{
width: 100%;
background-color: gray;
height: 50px;
position: relative;
}
#total-percentage-text-wrapper{
position: absolute;
left: 0;
right: 0;
height: 100%;
}
#total-percentage-text{
display: flex;
font-size: 20px;
height: 100%;
justify-content: center;
align-items: center;
color: black;
}
#total-percentage-bar{
width: 50%;
height: 100%;
background-color: gold;
}
.display-wrapper{
margin: 0 auto;
padding: 10px;
width: fit-content;
font-size: 20px;
}
.display-wrapper #display-country-details{
visibility: show;
color: white;
}
.display-wrapper #display-country-distance{
visibility: show;
font-size: 16px;
display: flex;
align-items: center;
justify-content: center;
}
.map-wrapper{
margin: 0 auto;
pointer-events: none;
padding-bottom: 25px;
}
#world-map {
display: block;
position: relative;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: auto;
transform: scale(1);
transform-origin: 0px 0px;
z-index: 2;
border-top-style: solid;
border-bottom-style: solid;
border-width: 0.5px;
border-color: #fbfafa;
}
#world-map path{
stroke: white;
fill: black;
transition: fill 0.3s ease;
pointer-events: all;
}
#world-map path:hover{
fill: rgb(175, 175, 175);
pointer-events: all;
cursor: pointer;
}
#details-box {
padding: 1rem;
border-radius: 8px;
font-size: 14px;
position: fixed;
color: white;
font-family: "Poppins";
background-color: gray;
width: fit-content;
transform: translateX(-50%);
transition: opacity .4s ease;
z-index: 3;
}
#search-bar-wrapper{
pointer-events: all;
position: absolute;
z-index: 3;
}
#search-bar {
box-sizing: border-box;
z-index: 3;
}
#search-bar-list {
list-style: none;
display: none;
z-index: 3;
}
#search-bar-list li {
padding: 10px;
width: 73.5%;
border-bottom: 2px solid #ffffff;
z-index: 3;
text-align: center;
}
#search-bar-list li:hover {
background: #ffffff;
color: #000000;
cursor: pointer;
}
#overall-stats-page-wrapper{
}
#overall-stats-display-details{
color: var(--ds-color-yellow-50);
margin: 0 auto;
width: fit-content;
font-size: 30px;
padding: 20px;
}
#overall-stats-values-progress-circles{
display: flex;
height: 300px;
flex-direction: row;
flex-wrap: wrap;
}
#overall-stats-values-bottom{
border-top: .0625rem solid;
margin-top: 360px;
margin-bottom: 50px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.overall-stats-bottom-elements{
margin: 20px 0;
width: 33.333%;
text-align: center;
display: flex;
flex-direction: column;
}
#overall-stats-distance-from-opponent-value{
font-size: 30px;
width: 50%;
margin: 20px 25%;
}
#overall-stats-total-play-time-value{
font-size: 30px;
width: 50%;
margin: 20px 25%;
}
#country-stats-page-wrapper{
}
#country-stats-display-title{
margin: 0 auto;
padding: 10px;
width: fit-content;
font-size: 20px;
}
#country-stats-display-details{
visibility: show;
color: white;
}
#country-stats-wrapper{
}
#country-stats-values{
display: flex;
height: 300px;
flex-direction: row;
flex-wrap: wrap;
}
.country-stat-wrapper{
width: 33.333%;
height: 50%;
text-align: center;
display: flex;
flex-direction: column;
}
.country-stat-outer-circle{
position: relative;
height: 100px;
width: 100px;
border-radius: 50%;
margin: auto;
}
.country-stat-inner-circle{
position: absolute;
height: 85%;
width: 85%;
border-radius: 50%;
background-color: #1a1a2e;
top: 0; bottom: 0; left: 0; right: 0;
margin: auto;
}
.country-stat-value-wrapper{
display: flex;
align-items: center;
justify-content: center;
color: white;
height: 100%;
}
.country-stat-value{
font-size: 25px;
}
.country-stat-title{
position: relative;
color: #ffffff;
margin: auto;
}
.country-stat-spacing-wrapper{
width: 100%;
height: 25%;
}
#country-stats-reset-btn-wrapper{
padding: 100px;
text-align: center;
}
#country-stats-reset-btn{
border-color: red;
background-color: red;
color: white;
}
#country-stats-reset-btn:hover{
cursor: pointer;
}
#map-settings-wrapper{
var(--font-neo-sans);
text-align: center;
display: none;
}
#map-settings-title{
font-size: 40px;
padding-bottom: 20px;
}
#map-settings-content{
}
#settings-api-and-id-wrapper{
border-top: 2px solid white;
padding-bottom: 50px;
padding-top: 25px;
display: flex;
margin-left: 50px;
margin-right: 50px;
}
#settings-api-key{
background-color: #eee;
flex: 1;
}
#settings-user-id{
background-color: #eee;
flex: 1;
}
#settings-map-color-ranges-wrapper{
border-top: 2px solid white;
padding-bottom: 50px;
padding-top: 25px;
margin-left: 50px;
margin-right: 50px;
}
#map-color-ranges-slider-wrapper{
position: relative;
}
#slider-output-wrapper{
position: relative;
margin-top: 20px;
width: 100%;
}
#left-slider-output{
position: absolute;
left: 50%;
}
#right-slider-output{
position: absolute;
left: 50%;
}
#map-color-ranges-slider{
position: relative;
width: 100%;
height: 100px;
margin-top: 0px;
}
#slider-track{
width: 100%;
height: 5px;
position: absolute;
margin: auto;
top: 0;
bottom: 0;
border-radius: 5px;
}
.map-color-ranges{
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
width: 100%;
outline: none;
position: absolute;
margin: 0px -50%;
top: 0;
bottom: 0;
background-color: transparent;
pointer-events: none;
border-color: transparent;
padding: 0px;
}
.map-color-ranges::-webkit-slider-runnable-track{
-webkit-appearance: none;
height: 5px;
}
.map-color-ranges::-webkit-slider-thumb{
-webkit-appearance: none;
height: 1.7em;
width: 1.7em;
background-color: #ffffff;
cursor: pointer;
margin-top: -9px;
pointer-events: auto;
border-radius: 50%;
border: 1px solid #808080;
}
#settings-toggles-wrapper{
border-top: 2px solid white;
padding-bottom: 50px;
padding-top: 25px;
margin-left: 50px;
margin-right: 50px;
text-align: center;
display: flex;
}
#settings-allow-healing-rounds-wrapper{
flex: 1;
}
#settings-allow-healing-rounds{
height: 0;
width: 0;
visibility: hidden;
}
#label-allow-healing{
cursor: pointer;
text-indent: -9999px;
width: 50px;
height: 25px;
background: gray;
display: block;
border-radius: 25px;
position: relative;
margin: auto;
}
#label-allow-healing:after{
content: '';
position: absolute;
top: 1.25px;
left: 3px;
width: 22.5px;
height: 22.5px;
background: #fff;
border-radius: 22.5px;
transition: 0.3s;
}
#settings-allow-healing-rounds:checked + #label-allow-healing{
background: #bada55;
}
#settings-allow-healing-rounds:checked + #label-allow-healing:after{
left: calc(100% - 5px);
transform: translateX(-100%);
}
#label-allow-healing:active:after{
width: 32.5px;
}
#settings-competitive-only-mode-wrapper{
flex: 1;
}
#settings-competitive-only-mode{
height: 0;
width: 0;
visibility: hidden;
}
#label-competitive-only{
cursor: pointer;
text-indent: -9999px;
width: 50px;
height: 25px;
background: gray;
display: block;
border-radius: 25px;
position: relative;
margin: auto;
}
#label-competitive-only:after{
content: '';
position: absolute;
top: 1.25px;
left: 3px;
width: 22.5px;
height: 22.5px;
background: #fff;
border-radius: 22.5px;
transition: 0.3s;
}
#settings-competitive-only-mode:checked + #label-competitive-only{
background: #bada55;
}
#settings-competitive-only-mode:checked + #label-competitive-only:after{
left: calc(100% - 5px);
transform: translateX(-100%);
}
#label-competitive-only:active:after{
width: 32.5px;
}
#unit-selector{
border-top: 2px solid white;
padding-bottom: 50px;
padding-top: 25px;
margin-left: 50px;
margin-right: 50px;
}
#unit-selector-mi,
#unit-selector-km{
accent-color: #bada55;
}
#unit-selector-mi:hover,
#unit-selector-km:hover{
cursor: pointer;
}
#settings-reset-scores-btn-wrapper{
border-top: 2px solid white;
padding-bottom: 50px;
padding-top: 25px;
margin-left: 50px;
margin-right: 50px;
}
#reset-scores-btn{
border-color: red;
background-color: red;
color: white;
}
#reset-scores-btn:hover{
cursor: pointer;
}
#map-settings-btn-wrapper{
text-align: center;
margin-bottom: 10px;
}
#map-settings-btn{
border-radius: 15px;
background-color: transparent;
color: white;
border-color: white;
padding: 5px 10px 5px 10px;
}
#map-settings-btn:hover{
background-color: white;
color: black;
border-color: black;
cursor: pointer;
}
#footer-wrapper{
display: flex;
}
#version-number{
flex: 1;
font-family: Arial;
padding-left: 10px
}
#feedback-link-wrapper{
flex: 1;
font-family: Arial;
text-align: center;
}
#creator-tag{
flex: 1;
font-family: Arial;
padding-right: 10px;
padding-bottom: 10px;
text-align: right;
}
`;
svgMap.innerHTML = `
Country Name: 0 / 0 (0%)
Average Distance: 0.0 km
OVERALL STATS
Average Rounds Played (Win)
Average Rounds Played (Loss)
AVERAGE DISTANCE FROM OPPONENT
COUNTRY STREAKS
Current:
Highest: Correct | Incorrect
`;
scriptForMap.textContent = `
{
let countries = ['AF','AX','AL','DZ','AS','AD','AO','AI','AQ','AG','AR','AM','AW','AU','AT','AZ','BS','BH','BD','BB','BY','BE','BZ','BJ','BM','BT','BO','BQ','BA','BW','BV','BR','IO','BN','BG','BF','BI','KH','CM','CA','CV','KY','CF','TD','CL','CN','CX','CC','CO','KM','CG','CD','CK','CR','CI','HR','CU','CW','CY','CZ','DK','DJ','DM','DO','EC','EG','SV','GQ','ER','EE','ET','FK','FO','FJ','FI','FR','GF','PF','TF','GA','GM','GE','DE','GH','GI','GR','GL','GD','GP','GU','GT','GG','GN','GW','GY','HT','HM','VA','HN','HK','HU','IS','IN','ID','IR','IQ','IE','IM','IL','IT','JM','JP','JE','JO','KZ','KE','KI','KP','KR','XK','KW','KG','LA','LV','LB','LS','LR','LY','LI','LT','LU','MO','MK','MG','MW','MY','MV','ML','MT','MH','MQ','MR','MU','YT','MX','FM','MD','MC','MN','ME','MS','MA','MZ','MM','NA','NR','NP','NL','NC','NZ','NI','NE','NG','NU','NF','MP','NO','OM','PK','PW','PS','PA','PG','PY','PE','PH','PN','PL','PT','PR','QA','RS','RE','RO','RU','RW','BL','SH','KN','LC','MF','VC','WS','ST','SA','SN','SC','SL','SG','SX','SK','SI','SB','SO','ZA','GS','SS','ES','LK','SD','SR','SJ','SZ','SE','CH','SY','TW','TJ','TZ','TH','TL','TG','TK','TO','TT','TN','TR','TM','TC','TV','UG','UA','AE','GB','US','UM','UY','UZ','VU','VE','VN','VG','VI','WF','EH','YE','ZM','ZW','SM'];
let once = false;
document.getElementById("details-box").style.opacity = "0%";
//UNIT SELECTION
if(window.localStorage.getItem('units-svg-map') === 'mi'){
document.getElementById('unit-selector-mi').checked = true;
}
else if(window.localStorage.getItem('units-svg-map') === 'km'){
document.getElementById('unit-selector-km').checked = true;
}
document.getElementById('unit-selector-mi').addEventListener('click', function(){
window.localStorage.setItem('units-svg-map', 'mi');
});
document.getElementById('unit-selector-km').addEventListener('click', function(){
window.localStorage.setItem('units-svg-map', 'km');
});
//MAP SETUP
document.getElementById('map-wrapper-element').addEventListener('mousemove', function(e){
if(once){
if(window.location.pathname.endsWith('/profile')){
return;
}
once = false;
}
if(!window.location.pathname.endsWith('/profile')){
return;
}
once = true;
//Percentage Bar
let correct_total = parseInt(window.localStorage.getItem('overall-correct-${USER_ID}'));
let total_total = parseInt(window.localStorage.getItem('overall-total-${USER_ID}'));
let percentage_total = Math.floor((correct_total / total_total) * 100);
document.getElementById('total-percentage-bar').style.width = percentage_total + '%';
document.getElementById('total-percentage-text').innerHTML = 'Overall Score: ' + correct_total + ' / ' + total_total + ' (' + percentage_total +'%) ';
if(percentage_total >= 100*${green_range}){
document.getElementById('total-percentage-bar').style.backgroundColor = 'green';
}
else if(percentage_total >= 100*${yellow_range}){
document.getElementById('total-percentage-bar').style.backgroundColor = 'yellow';
}
else if(percentage_total >= 100*${red_range}){
document.getElementById('total-percentage-bar').style.backgroundColor = 'red';
}
//Country colors
countries.forEach(function(country){
let correct = 0;
let total = 0;
if(window.localStorage.getItem(country + '-number-correct-${USER_ID}') !== null){
correct = window.localStorage.getItem(country + '-number-correct-${USER_ID}');
}
if(window.localStorage.getItem(country + '-number-total-${USER_ID}') !== null){
total = window.localStorage.getItem(country + '-number-total-${USER_ID}');
}
let percentage = parseInt(correct) / parseInt(total);
if(correct === 0 && total === 0){
percentage = 'none';
}
let targetCountry = document.getElementById(country);
if(!targetCountry){
return;
}
//Setting the countries to a color based on their percentage
if(percentage >= ${green_range}){
targetCountry.setAttribute('style', 'fill: lightgreen'); //green
}
else if(percentage >= ${yellow_range}){
targetCountry.setAttribute('style', 'fill: rgb(233, 233, 84)'); //yellow
}
else if(percentage >= ${red_range}){
targetCountry.setAttribute('style', 'fill: lightcoral'); //red
}
else{
targetCountry.setAttribute('style', 'fill: black');
}
});
//OVERALL STATS SETUP
let overallStats = JSON.parse(window.localStorage.getItem('overall-country-stats-${USER_ID}'));
let percentage;
let percentageColor;
let totalCount = overallStats.totalCount;
let totalWin = overallStats.totalWin;
let totalLoss = overallStats.totalLoss;
let total5ks = overallStats.total5ks;
let totalGames = overallStats.totalGames;
let averageScore = Math.floor(overallStats.averageScore);
let averageDistance = Math.floor(overallStats.averageDistance/1000);
let gameLengthWin = overallStats.averageGameLengthWin;
let gameLengthLoss = overallStats.averageGameLengthLoss;
let averageTime = Math.floor(overallStats.averageTime);
let guessedFirst = overallStats.guessedFirst;
let closerThanOpponent = overallStats.closerThanOpponent;
let correctStreak = overallStats.countryCorrectStreak;
let correctMax = overallStats.countryCorrectMax;
let wrongStreak = overallStats.countryWrongStreak;
let wrongMax = overallStats.countryWrongMax;
let opponentRating = Math.floor(overallStats.opponentRating);
//Find correct percentage to color the outside circle
function findPercentage(stat, max){
percentage = (stat/max);
if(percentage >= ${green_range}){
percentageColor = 'green';
}
else if(percentage >= ${yellow_range}){
percentageColor = 'yellow';
}
else{
percentageColor = 'red';
}
percentage = 100 * percentage;
if(percentage <= 0){
percentage = 2;
}
};
//Average Score
findPercentage(averageScore, 5000);
document.getElementById('overall-stat-average-score-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('overall-stat-average-score-value').innerText = averageScore;
//Average Distance
findPercentage(2500-averageDistance, 2500);
document.getElementById('overall-stat-average-distance-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
if(window.localStorage.getItem('units-svg-map') == 'mi'){
document.getElementById('overall-stat-average-distance-title').innerText = 'Average Distance (mi)';
averageDistance = Math.floor(averageDistance / 1.609);
}
else{
document.getElementById('country-stat-average-distance-title').innerText = 'Average Distance (km)';
}
document.getElementById('overall-stat-average-distance-value').innerText = averageDistance;
//Closer Than Opponent
findPercentage(closerThanOpponent, totalCount);
document.getElementById('overall-stat-closer-than-opponent-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('overall-stat-closer-than-opponent-value').innerText = Math.floor((100 * (closerThanOpponent/totalCount))) + '%';
//Average Time
findPercentage(120-averageTime, 120);
document.getElementById('overall-stat-average-time-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('overall-stat-average-time-value').innerText = averageTime;
//Guessed First
findPercentage(guessedFirst, totalCount);
document.getElementById('overall-stat-guessed-first-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('overall-stat-guessed-first-value').innerText = Math.floor((100 * (guessedFirst/totalCount))) + '%';
//Total 5ks
findPercentage(total5ks, 100);
document.getElementById('overall-stat-total-5ks-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('overall-stat-total-5ks-value').innerText = total5ks;
//Game Length (Win)
findPercentage(15-gameLengthWin, 15);
document.getElementById('overall-stat-average-game-length-win-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('overall-stat-average-game-length-win-value').innerText = Math.round(10 * gameLengthWin) / 10;
//Game Length (Loss)
findPercentage(gameLengthLoss, 15);
document.getElementById('overall-stat-average-game-length-loss-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('overall-stat-average-game-length-loss-value').innerText = Math.round(10 * gameLengthLoss) / 10;
//Opponent Rating
findPercentage(opponentRating, 1200);
document.getElementById('overall-stat-opponent-rating-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('overall-stat-opponent-rating-value').innerText = opponentRating;
//BOTTOM STATS SETUP
//Distance From Opponent
let distanceFromOpponent = [Math.round(overallStats.distanceFromOpponent[1] / 1000),'km','+','green'];
if(window.localStorage.getItem('units-svg-map') == 'mi'){
distanceFromOpponent[0] = Math.round(distanceFromOpponent[0] / 1.609);
distanceFromOpponent[1] = 'mi';
}
if(distanceFromOpponent[0] < 0){
distanceFromOpponent[0] *= -1;
distanceFromOpponent[2] = '-';
distanceFromOpponent[3] = 'red';
}
document.getElementById('overall-stats-distance-from-opponent-value').style.color = distanceFromOpponent[3];
document.getElementById('overall-stats-distance-from-opponent-value').innerText = distanceFromOpponent[2] + distanceFromOpponent[0] + ' ' + distanceFromOpponent[1];
//Country Streaks
if(overallStats.countryCorrectStreak > 0){
document.getElementById('overall-stats-country-streaks-value-current-value').innerText = overallStats.countryCorrectStreak + ' Correct';
document.getElementById('overall-stats-country-streaks-value-current-value').style.color = 'green';
}
else if(overallStats.countryWrongStreak > 0){
document.getElementById('overall-stats-country-streaks-value-current-value').innerText = overallStats.countryWrongStreak + ' Incorrect';
document.getElementById('overall-stats-country-streaks-value-current-value').style.color = 'red';
}
document.getElementById('overall-stats-country-streaks-value-max-correct-value').innerText = overallStats.countryCorrectMax;
document.getElementById('overall-stats-country-streaks-value-max-wrong-value').innerText = overallStats.countryWrongMax;
//Time Played
let minutesPlayed = Math.floor(Math.floor(overallStats.totalSeconds / 60) % 60);
let hoursPlayed = Math.floor(overallStats.totalSeconds / 3600);
document.getElementById('overall-stats-total-play-time-value').innerText = hoursPlayed + 'h ' + minutesPlayed + 'm ';
});
function mouseOverCountry(country){
if(typeof country.target !== 'undefined'){
country = country.target;
}
if (country.tagName == 'path'){
let content = country.dataset.name;
document.getElementById("details-box").innerHTML = content;
document.getElementById("details-box").style.opacity = "100%";
//Changing the color when you hover over a country
if(country.style.fill == 'lightcoral'){
country.setAttribute('style', 'fill:red');
}
else if(country.style.fill == 'lightgreen'){
country.setAttribute('style', 'fill:green');
}
else if(country.style.fill == 'rgb(233, 233, 84)'){
country.setAttribute('style', 'fill:yellow');
}
else if(country.style.fill == 'black'){
country.setAttribute('style', 'fill:rgb(175, 175, 175)');
}
//Displaying the country and the stats at the top of the page
let countryName = country.dataset.name;
let countryCorrect = 0;
let countryTotal = 0;
let countryPercentage = 0;
let countryDistance = 0.0;
let distanceUnit = 'km';
let target = country.id;
if(window.localStorage.getItem(target + '-number-correct-${USER_ID}') !== null){
countryCorrect = window.localStorage.getItem(target + '-number-correct-${USER_ID}');
}
if(window.localStorage.getItem(target + '-number-total-${USER_ID}') !== null){
countryTotal = window.localStorage.getItem(target + '-number-total-${USER_ID}');
}
if((countryCorrect !== 0) && (countryTotal !== 0)){
countryPercentage = Math.floor(100 * (parseInt(countryCorrect) / parseInt(countryTotal)));
}
if(window.localStorage.getItem(target + '-distance-average-${USER_ID}') !== null){
countryDistance = parseInt(window.localStorage.getItem(target + '-distance-average-${USER_ID}')) / 1000;
if(document.getElementById('unit-selector-mi').checked){
countryDistance = countryDistance / 1.609;
}
countryDistance = round(countryDistance,1);
}
if(document.getElementById('unit-selector-mi').checked){
distanceUnit = 'mi';
}
document.getElementById("display-country-details").textContent = countryName + ": " + countryCorrect + " / " + countryTotal + " (" + countryPercentage + "%)";
document.getElementById("display-country-details").style.visibility = "visible";
document.getElementById("display-country-distance").textContent = 'Average Distance: ' + countryDistance + ' ' + distanceUnit;
document.getElementById("display-country-distance").style.visibility = "visible";
}
else {
document.getElementById("details-box").style.opacity = "0%";
}
};
function mouseOutCountry(country){
if(typeof country.target !== 'undefined'){
country = country.target;
}
if (country.tagName == 'path'){
//Changing the color when you stop hovering over a country
if(country.style.fill == 'red'){
country.setAttribute('style', 'fill:lightcoral');
}
if(country.style.fill == 'green'){
country.setAttribute('style', 'fill:lightgreen');
}
if(country.style.fill == 'yellow'){
country.setAttribute('style', 'fill:rgb(233, 233, 84)');
}
if(country.style.fill == 'rgb(175, 175, 175)'){
country.setAttribute('style', 'fill:black');
}
//Hiding the display at the top when no country is hovering
document.getElementById("display-country-details").style.visibility = "hidden";
document.getElementById("display-country-distance").style.visibility = "hidden";
}
};
//DETAILS BOX
window.onmousemove = function(e){
let detailsBox = document.getElementById('details-box');
let x = e.clientX;
let y = e.clientY;
detailsBox.style.top = (y + 20) + 'px';
detailsBox.style.left = (x) + 'px';
};
function round(value, precision) {
let multiplier = Math.pow(10, precision || 0);
return Math.round(value * multiplier) / multiplier;
};
//REGULAR LISTENERS
document.getElementById('map-wrapper-element').addEventListener('mouseover', mouseOverCountry);
document.getElementById('map-wrapper-element').addEventListener('mouseout', mouseOutCountry);
//SEARCH LIST
function mouseOverList(e){
let temp = e.target.id.toUpperCase();
let target_country = document.getElementById(temp);
mouseOverCountry(target_country);
}
function mouseOutList(e){
let temp = e.target.id.toUpperCase();
let target_country = document.getElementById(temp);
mouseOutCountry(target_country);
}
document.getElementById('search-bar').addEventListener('click', () => {
let search_bar = document.getElementById('search-bar');
let list = document.querySelectorAll('#search-bar-list li');
list.forEach(item => item.addEventListener('mouseover', mouseOverList));
list.forEach(item => item.addEventListener('mouseout', mouseOutList));
search_bar.onkeyup = () => {
let search = search_bar.value.toLowerCase();
let count = 0;
if(search_bar.value !== ''){
document.getElementById('search-bar-list').style.display = 'inline';
}
else{
document.getElementById('search-bar-list').style.display = 'none';
}
//Showing the results that match and hiding those that dont (max 6 items)
for(let i of list){
let item = i.innerHTML.toLowerCase();
if(item.indexOf(search) == -1){
i.style.display = 'none';
}
else{
if(count < 6){
count = count + 1;
i.style.display = 'block';
}
else{
i.style.display = 'none';
}
}
};
};
});
//OPEN AND CLOSE SETTINGS (and get back to homepage from country stats)
document.getElementById('map-settings-btn').addEventListener('click', () => {
if(document.getElementById('map-settings-btn').innerText == 'Back to Map'){
document.getElementById('map-settings-wrapper').style.display = 'none';
document.getElementById("country-stats-page-wrapper").style.display = 'none';
document.getElementById('map-settings-btn').innerText = 'Settings';
document.getElementsByClassName('display-wrapper')[0].style.display = 'block';
document.getElementById('search-bar-wrapper').style.display = 'block';
document.getElementsByClassName('map-wrapper')[0].style.display = 'block';
document.getElementById('overall-stats-page-wrapper').style.display = 'block';
}
else{
document.getElementById('map-settings-wrapper').style.display = 'block';
document.getElementById('map-settings-btn').innerText = 'Back to Map';
document.getElementsByClassName('display-wrapper')[0].style.display = 'none';
document.getElementById('search-bar-wrapper').style.display = 'none';
document.getElementsByClassName('map-wrapper')[0].style.display = 'none';
document.getElementById('overall-stats-page-wrapper').style.display = 'none';
}
});
//DISPLAY API KEY AND USER ID IN SETTINGS
document.getElementById('settings-api-key').value = '${API_KEY}';
document.getElementById('settings-api-key').style.width = '${API_KEY.length + 3}' + 'ch';
document.getElementById('settings-user-id').value = '${USER_ID}';
document.getElementById('settings-user-id').style.width = '${USER_ID.length + 3}' + 'ch';
//SET HEALING ROUNDS TOGGLE IN SETTINGS
let healing = JSON.parse(window.localStorage.getItem('allow-healing-rounds'));
if(healing.include){
document.getElementById('settings-allow-healing-rounds').checked = true;
}
else{
document.getElementById('settings-allow-healing-rounds').checked = false;
}
document.getElementById('settings-allow-healing-rounds').addEventListener('click', () => {
if(document.getElementById('settings-allow-healing-rounds').checked){
window.localStorage.setItem('allow-healing-rounds', JSON.stringify({include: true}));
}
else{
window.localStorage.setItem('allow-healing-rounds', JSON.stringify({include: false}));
}
});
//SET COMPETITIVE ONLY TOGGLE IN SETTINGS
let competitive = JSON.parse(window.localStorage.getItem('competitive-only-mode'));
if(competitive.include){
document.getElementById('settings-competitive-only-mode').checked = true;
}
else{
document.getElementById('settings-competitive-only-mode').checked = false;
}
document.getElementById('settings-competitive-only-mode').addEventListener('click', () => {
if(document.getElementById('settings-competitive-only-mode').checked){
window.localStorage.setItem('competitive-only-mode', JSON.stringify({include: true}));
}
else{
window.localStorage.setItem('competitive-only-mode', JSON.stringify({include: false}));
}
});
//RESET ALL SCORES
document.getElementById('reset-scores-btn').addEventListener('click', () => {
if(confirm('Are you sure you want to reset your stats? This cannot be undone.')){
//Remove country scores
countries.forEach(function(country){
window.localStorage.removeItem(country + '-number-correct-${USER_ID}');
window.localStorage.removeItem(country + '-number-total-${USER_ID}');
window.localStorage.removeItem(country + '-distance-average-${USER_ID}');
window.localStorage.removeItem(country + '-distance-number-${USER_ID}');
window.localStorage.removeItem(country + '-all-country-stats-${USER_ID}');
});
//Remove overall scores
window.localStorage.removeItem('overall-total-${USER_ID}');
window.localStorage.removeItem('overall-correct-${USER_ID}');
window.localStorage.removeItem('overall-country-stats-${USER_ID}');
//Reload the page
location.reload();
}
});
//OPEN COUNTRY STATS PAGE
document.getElementById('map-wrapper-element').addEventListener('dblclick', (e) => {
let countryId = (e.path[0].id).toUpperCase();
if(countryId.length != 2){
return;
}
//Set the stats to the correct values for the country
setCountryStats(countryId);
window.localStorage.setItem('select-country-stats-id', countryId);
document.getElementById('search-bar-wrapper').style.display = 'none';
document.getElementById('overall-stats-page-wrapper').style.display = 'none';
document.getElementsByClassName('map-wrapper')[0].style.display = 'none';
document.getElementsByClassName('display-wrapper')[0].style.display = 'none';
let countryName = e.path[0].dataset.name;
let countryCorrect = 0;
let countryTotal = 0;
let countryPercentage = 0;
if(typeof countryName == 'undefined'){
countryName = e.path[0].textContent;
}
if(window.localStorage.getItem(countryId + '-number-correct-${USER_ID}') !== null){
countryCorrect = window.localStorage.getItem(countryId + '-number-correct-${USER_ID}');
}
if(window.localStorage.getItem(countryId + '-number-total-${USER_ID}') !== null){
countryTotal = window.localStorage.getItem(countryId + '-number-total-${USER_ID}');
}
if((countryCorrect !== 0) && (countryTotal !== 0)){
countryPercentage = Math.floor(100 * (parseInt(countryCorrect) / parseInt(countryTotal)));
}
document.getElementById('country-stats-display-details').textContent = countryName + ": " + countryCorrect + " / " + countryTotal + " (" + countryPercentage + "%)";
document.getElementById('country-stats-reset-btn').textContent = 'Reset All ' + countryName + ' Stats';
document.getElementById("country-stats-page-wrapper").style.display = 'block';
document.getElementById('map-settings-btn').innerText = 'Back to Map';
});
//SET COUNTRY STATS
function setCountryStats(countryCode){
let countryObject = JSON.parse(window.localStorage.getItem(countryCode + '-all-country-stats-${USER_ID}'));
let percentage;
let percentageColor;
//Country Stats
let totalCount = countryObject.totalCount;
let averageScore = Math.floor(countryObject.averageScore);
let averageDistance = Math.floor(countryObject.averageDistance/1000);
let closerThanOpponent = countryObject.closerThanOpponent;
let averageTime = Math.floor(countryObject.averageTime);
let guessedFirst = countryObject.guessedFirst;
let total5ks = countryObject.total5ks;
//Find correct percentage to color the outside circle
function findPercentage(stat, max){
percentage = (stat/max);
if(percentage >= ${green_range}){
percentageColor = 'green';
}
else if(percentage >= ${yellow_range}){
percentageColor = 'yellow';
}
else{
percentageColor = 'red';
}
percentage = 100 * percentage;
if(percentage <= 0){
percentage = 2;
}
};
//Average Score
findPercentage(averageScore, 5000);
document.getElementById('country-stat-average-score-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('country-stat-average-score-value').innerText = averageScore;
//Average Distance
findPercentage(2500-averageDistance, 2500);
document.getElementById('country-stat-average-distance-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
if(window.localStorage.getItem('units-svg-map') == 'mi'){
document.getElementById('country-stat-average-distance-title').innerText = 'Average Distance (mi)';
averageDistance = Math.floor(averageDistance / 1.609);
}
else{
document.getElementById('country-stat-average-distance-title').innerText = 'Average Distance (km)';
}
document.getElementById('country-stat-average-distance-value').innerText = averageDistance;
//Closer Than Opponent
findPercentage(closerThanOpponent, totalCount);
document.getElementById('country-stat-closer-than-opponent-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('country-stat-closer-than-opponent-value').innerText = Math.floor((100 * (closerThanOpponent/totalCount))) + '%';
//Average Time
findPercentage(120-averageTime, 120);
document.getElementById('country-stat-average-time-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('country-stat-average-time-value').innerText = averageTime;
//Guessed First
findPercentage(guessedFirst, totalCount);
document.getElementById('country-stat-guessed-first-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('country-stat-guessed-first-value').innerText = Math.floor((100 * (guessedFirst/totalCount))) + '%';
//Total 5ks
findPercentage(total5ks, 10);
document.getElementById('country-stat-total-5ks-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('country-stat-total-5ks-value').innerText = total5ks;
}
//RESET SCORES FOR SELECTED COUNTRY
document.getElementById('country-stats-reset-btn').addEventListener('click', () => {
let resetId = window.localStorage.getItem('select-country-stats-id');
let countryCorrect = parseInt(window.localStorage.getItem(resetId + '-number-correct-${USER_ID}'));
let countryTotal = parseInt(window.localStorage.getItem(resetId + '-number-total-${USER_ID}'));
let countryStats = JSON.parse(window.localStorage.getItem(resetId + '-all-country-stats-${USER_ID}'));
let overallStats = JSON.parse(window.localStorage.getItem('overall-country-stats-${USER_ID}'));
if(isNaN(countryCorrect)){
countryCorrect = 0;
}
if(isNaN(countryTotal)){
countryTotal = 0;
}
//Reset all scores for country
if(confirm('Are you sure you want to reset your stats? This cannot be undone.')){
//Remove country scores from overall scores
countryCorrect = (parseInt(window.localStorage.getItem('overall-correct-${USER_ID}')) - countryCorrect);
countryTotal = (parseInt(window.localStorage.getItem('overall-total-${USER_ID}')) - countryTotal);
overallStats.totalCount = overallStats.totalCount - countryStats.totalCount;
overallStats.closerThanOpponent = overallStats.closerThanOpponent - countryStats.closerThanOpponent;
overallStats.guessedFirst = overallStats.guessedFirst - countryStats.guessedFirst;
overallStats.total5ks = overallStats.total5ks - countryStats.total5ks;
//Set Stats To New Values
window.localStorage.setItem('overall-correct-${USER_ID}', countryCorrect);
window.localStorage.setItem('overall-total-${USER_ID}', countryTotal);
window.localStorage.setItem('overall-country-stats-${USER_ID}',JSON.stringify(overallStats));
//Remove Country Scores
window.localStorage.removeItem(resetId + '-number-correct-${USER_ID}');
window.localStorage.removeItem(resetId + '-number-total-${USER_ID}');
window.localStorage.removeItem(resetId + '-distance-average-${USER_ID}');
window.localStorage.removeItem(resetId + '-distance-number-${USER_ID}');
window.localStorage.removeItem(resetId + '-all-country-stats-${USER_ID}');
//Reload the page
location.reload();
}
});
//MAP SLIDER RANGES
let leftSlider = document.getElementById("left-slider");
let rightSlider = document.getElementById("right-slider");
let sliderTrack = document.getElementById("slider-track");
let minGap = 5;
leftSlider.value = window.localStorage.getItem('duels-map-color-left-range-${USER_ID}');
rightSlider.value = window.localStorage.getItem('duels-map-color-right-range-${USER_ID}');
//Change Left Slider Value
function calcLeftSlider(){
if(parseInt(rightSlider.value) - parseInt(leftSlider.value) <= minGap){
leftSlider.value = parseInt(rightSlider.value) - minGap;
}
else if(leftSlider.value < 5){
leftSlider.value = 5;
}
document.getElementById('left-slider-output').innerText = leftSlider.value + '%';
document.getElementById('left-slider-output').style.left = findValue(leftSlider.value);
fillColor();
window.localStorage.setItem('duels-map-color-left-range-${USER_ID}', leftSlider.value);
}
//Change Right Slider Value
function calcRightSlider(){
if(parseInt(rightSlider.value) - parseInt(leftSlider.value) <= minGap){
rightSlider.value = parseInt(leftSlider.value) + minGap;
}
else if(rightSlider.value > 95){
rightSlider.value = 95;
}
document.getElementById('right-slider-output').innerText = rightSlider.value + '%';
document.getElementById('right-slider-output').style.left = findValue(rightSlider.value);
fillColor();
window.localStorage.setItem('duels-map-color-right-range-${USER_ID}', rightSlider.value);
}
//Fill The Slider With Colors
function fillColor(){
let percent1 = parseInt(leftSlider.value);
let percent2 = parseInt(rightSlider.value);
sliderTrack.style.background = 'linear-gradient(to right, red 0%, red ' + percent1 + '%, yellow ' + percent1 + '%, yellow ' + percent2 +'%, green ' + percent2 + '%, green 100%)';
}
//Put Value Above Slider Thumb
function findValue(val){
let valueOne = parseInt(val);
let valueTwo = valueOne * 0.2;
let final = 'calc(' + valueOne + '% - ' + valueTwo + 'px)';
return final;
}
//Add Event Listeners
document.getElementById("left-slider").addEventListener('input', calcLeftSlider);
document.getElementById("right-slider").addEventListener('input', calcRightSlider);
calcLeftSlider();
calcRightSlider();
//PANNING AND ZOOMING ON THE MAP
let worldMap = document.getElementById('world-map');
let viewbox = worldMap.viewBox.baseVal;
let pointerDown = false;
let mousePoint;
//Return x and y values from pointer event
function getPointFromEvent(event){
let point = worldMap.createSVGPoint();
point.x = event.clientX;
point.y = event.clientY;
//Get current transformation matrix and inverse it
let invertedSVGMatrix = worldMap.getScreenCTM().inverse();
return point.matrixTransform(invertedSVGMatrix);
}
//When user clicks map to start panning
function onPointerDown(event){
event.preventDefault();
pointerDown = true;
mousePoint = getPointFromEvent(event);
}
//When user drags mouse
function onPointerMove(event){
if (!pointerDown){
return;
}
event.preventDefault();
document.getElementById('world-map').style = 'cursor: grabbing';
document.getElementById('details-box').style.display = 'none';
let pointerPosition = getPointFromEvent(event);
viewbox.x = (viewbox.x - (pointerPosition.x - mousePoint.x));
viewbox.y = (viewbox.y - (pointerPosition.y - mousePoint.y));
checkBounds();
}
//When user lifts mouse up
function onPointerUp(){
event.preventDefault();
pointerDown = false;
document.getElementById('world-map').style = 'cursor: auto';
document.getElementById('details-box').style.display = 'inline';
}
//When user scrolls mouse
function onMouseWheel(event){
let delta = (event.wheelDelta ? event.wheelDelta : -event.deltaY);
mousePoint = getPointFromEvent(event);
//If mouse wheel moves forward
if(delta > 0){
event.preventDefault();
//Zoom In Limit
if(viewbox.width > 325 && viewbox.height > 140){
//Make the viewbox smaller
viewbox.width /= 1.1;
viewbox.height /= 1.1;
//Position the top left accordingly
viewbox.x = (((mousePoint.x - viewbox.x) * viewbox.width) - ((mousePoint.x - viewbox.x) * mousePoint.x) - ((viewbox.x + (viewbox.width * 1.1) - mousePoint.x) * mousePoint.x) ) / ( -((mousePoint.x - viewbox.x) + (viewbox.x + (viewbox.width * 1.1) - mousePoint.x)) );
viewbox.y = (((mousePoint.y - viewbox.y) * viewbox.height) - ((mousePoint.y - viewbox.y) * mousePoint.y) - ((viewbox.y + (viewbox.height * 1.1) - mousePoint.y) * mousePoint.y) ) / ( -((mousePoint.y - viewbox.y) + (viewbox.y + (viewbox.height * 1.1) - mousePoint.y)) );
}
}
//If mouse wheel moves backward
else{
//Zoom Out Limit
if(viewbox.width < 2000 && viewbox.height < 857){
event.preventDefault();
//Make the viewbox bigger
viewbox.width *= 1.1;
viewbox.height *= 1.1;
//Position the top left accordingly
viewbox.x = (((viewbox.x + (viewbox.width / 1.1) - mousePoint.x) * mousePoint.x) - ((mousePoint.x - viewbox.x) * viewbox.width) + ((mousePoint.x - viewbox.x) * mousePoint.x)) / ((mousePoint.x - viewbox.x) + (viewbox.x + (viewbox.width / 1.1) - mousePoint.x));
viewbox.y = (((viewbox.y + (viewbox.height / 1.1) - mousePoint.y) * mousePoint.y) - ((mousePoint.y - viewbox.y) * viewbox.height) + ((mousePoint.y - viewbox.y) * mousePoint.y)) / ((mousePoint.y - viewbox.y) + (viewbox.y + (viewbox.height / 1.1) - mousePoint.y));
}
}
checkBounds();
}
//Check if the map is out of bounds
function checkBounds(){
//Left
if(viewbox.x < 0){
viewbox.x = 0;
}
//Top
if(viewbox.y < 0){
viewbox.y = 0;
}
//Right
if((viewbox.x + viewbox.width) > 2000){
viewbox.x = 2000 - viewbox.width;
}
//Bottom
if((viewbox.y + viewbox.height) > 857){
viewbox.y = 857 - viewbox.height;
}
}
//Add event listeners
worldMap.addEventListener('pointerdown', onPointerDown);
worldMap.addEventListener('pointerup', onPointerUp);
worldMap.addEventListener('pointerleave', onPointerUp);
worldMap.addEventListener('pointermove', onPointerMove);
worldMap.addEventListener('wheel', onMouseWheel);
}`;
let referenceNode = document.getElementsByClassName('version3_main__xNkED')[0];
let siblingNode = document.getElementsByClassName('footer_footer__NmtmJ')[0];
referenceNode.parentNode.insertBefore(svgMap, siblingNode);
document.head.appendChild(cssForMap);
document.getElementById('map-wrapper-element').appendChild(scriptForMap);
};
//**************************** END OF SCRIPT ****************************//