NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Agent Stats Calendar Maker // @namespace http://ingress.agent-stats.operuserjs/ // @version 0.9.0 // @description See your daily progress in a more clean way // @author Mori // @match https://www.agent-stats.com/export.php // @require https://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js // @grant none // ==/UserScript== (function(_, $) { // Taken from http://stackoverflow.com/a/2901298 var numberWithCommas = function(x) { if(!x) { x = 0; } return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); }; var userData = { 'level': 1, 'medalCount': { 'medals': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'unofficialMedals': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0} }, 'medals': { 'explorer': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'seer': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'trekker': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'builder': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'connector': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'mind-controller': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'illuminator': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'recharger': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'liberator': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'pioneer': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'engineer': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'purifier': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'guardian': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'specops': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'hacker': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'recruiter': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'translator': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'sojourner': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0} }, 'unofficialMedals': { 'collector': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'mastermind': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'binder': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'country-master': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'neutralizer': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'disruptor': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'salvator': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'smuggler': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'link-master': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'controller': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'field-master': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0}, 'hackathon': {'bronze': 0, 'silver': 0, 'gold': 0, 'platinum': 0, 'black': 0} } }; var requirements = { 'levels': [ {'ap': 0, 'medals': null}, {'ap': 2500, 'medals': null}, {'ap': 20000, 'medals': null}, {'ap': 70000, 'medals': null}, {'ap': 150000, 'medals': null}, {'ap': 300000, 'medals': null}, {'ap': 600000, 'medals': null}, {'ap': 1200000, 'medals': null}, {'ap': 2400000, 'medals': {'silver': 4, 'gold': 1}}, {'ap': 4000000, 'medals': {'silver': 5, 'gold': 2}}, {'ap': 6000000, 'medals': {'silver': 6, 'gold': 4}}, {'ap': 8400000, 'medals': {'silver': 7, 'gold': 6}}, {'ap': 12000000, 'medals': {'platinum': 1, 'gold': 7}}, {'ap': 17000000, 'medals': {'platinum': 2}}, {'ap': 24000000, 'medals': {'platinum': 3}}, {'ap': 40000000, 'medals': {'platinum': 4, 'black': 2}} ], 'medals': { 'explorer': {'bronze': 100, 'silver': 1000, 'gold': 2000, 'platinum': 10000, 'black': 30000}, 'seer': {'bronze': 10, 'silver': 50, 'gold': 200, 'platinum': 500, 'black': 5000}, 'trekker': {'bronze': 10, 'silver': 100, 'gold': 300, 'platinum': 1000, 'black': 2500}, 'builder': {'bronze': 2000, 'silver': 10000, 'gold': 30000, 'platinum': 100000, 'black': 200000}, 'connector': {'bronze': 50, 'silver': 1000, 'gold': 5000, 'platinum': 25000, 'black': 100000}, 'mind-controller': {'bronze': 100, 'silver': 500, 'gold': 2000, 'platinum': 10000, 'black': 40000}, 'illuminator': {'bronze': 5000, 'silver': 50000, 'gold': 250000, 'platinum': 1000000, 'black': 4000000}, 'recharger': {'bronze': 100000, 'silver': 1000000, 'gold': 3000000, 'platinum': 10000000, 'black': 25000000}, 'liberator': {'bronze': 100, 'silver': 1000, 'gold': 5000, 'platinum': 15000, 'black': 40000}, 'pioneer': {'bronze': 20, 'silver': 200, 'gold': 1000, 'platinum': 5000, 'black': 20000}, 'engineer': {'bronze': 150, 'silver': 1500, 'gold': 5000, 'platinum': 20000, 'black': 50000}, 'purifier': {'bronze': 2000, 'silver': 10000, 'gold': 30000, 'platinum': 100000, 'black': 200000}, 'guardian': {'bronze': 3, 'silver': 10, 'gold': 20, 'platinum': 90, 'black': 150}, 'specops': {'bronze': 5, 'silver': 25, 'gold': 100, 'platinum': 200, 'black': 500}, 'hacker': {'bronze': 2000, 'silver': 10000, 'gold': 30000, 'platinum': 100000, 'black': 200000}, 'recruiter': {'bronze': 2, 'silver': 10, 'gold': 25, 'platinum': 50, 'black': 100}, 'translator': {'bronze': 200, 'silver': 2000, 'gold': 6000, 'platinum': 20000, 'black': 50000}, 'sojourner': {'bronze': 15, 'silver': 30, 'gold': 60, 'platinum': 180, 'black': 360} }, 'unofficialMedals': { 'collector': {'bronze': 100000, 'silver': 1000000, 'gold': 10000000, 'platinum': 100000000, 'black': 200000000}, 'mastermind': {'bronze': 100000, 'silver': 1000000, 'gold': 10000000, 'platinum': 50000000, 'black': 100000000}, 'binder': {'bronze': 10, 'silver': 200, 'gold': 800, 'platinum': 1300, 'black': 1800}, 'country-master': {'bronze': 5000, 'silver': 30000, 'gold': 100000, 'platinum': 1000000, 'black': 5000000}, 'neutralizer': {'bronze': 100, 'silver': 1000, 'gold': 5000, 'platinum': 15000, 'black': 40000}, 'disruptor': {'bronze': 50, 'silver': 1000, 'gold': 5000, 'platinum': 25000, 'black': 100000}, 'salvator': {'bronze': 100, 'silver': 500, 'gold': 2000, 'platinum': 10000, 'black': 40000}, 'smuggler': {'bronze': 1, 'silver': 5, 'gold': 10, 'platinum': 45, 'black': 75}, 'link-master': {'bronze': 1, 'silver': 10, 'gold': 50, 'platinum': 200, 'black': 1000}, 'controller': {'bronze': 1, 'silver': 3, 'gold': 8, 'platinum': 30, 'black': 50}, 'field-master': {'bronze': 5000, 'silver': 40000, 'gold': 150000, 'platinum': 400000, 'black': 1000000}, 'hackathon': {'bronze': 5, 'silver': 30, 'gold': 75, 'platinum': 150, 'black': 200} } }; var medalCategories = { 'medals': 'Official', 'unofficialMedals': 'Unofficial' }; var specialMedals = { 'engineer': '2014-12-15', 'specops': '2014-12-15', 'trekker': '2014-12-15', 'innovator': '2014-11-15', 'recharger': '2014-02-06', 'recruiter': '2015-01-15', 'translator': '2015-01-29', 'illuminator': '2015-02-26', 'sojourner': '2015-03-06' }; var medalTypes = ['bronze', 'silver', 'gold', 'platinum', 'black']; var dataHarverster = function () { var fieldNames = _.map($('#StatsExport thead tr th'), function(element) { return $(element).text().trim(); }); fieldNames.splice(0, 1); var points = _.map($('#StatsExport tbody tr'), function(line) { return $(line); }); var dates = {}; _.each(points, function(point) { var cells = $(point).find('td'); var date = $(cells[0]).text().trim().split(' ')[0]; cells.splice(0, 1); dates[date] = {}; _.each(cells, function(pointValue, index) { dates[date][fieldNames[index]] = $(pointValue).text().trim(); }); }); drawCalendar(dates); }; var congratulateOnMedal = function(medalName, medalType) { return $('<span>Congratulations on gaining '+medalType+' '+cleanName(medalName)+' medal!</span><br />'); }; var congratulateOnLevel = function(level) { return $('<span>Congratulations on reaching '+level+' level!</span><br />'); }; var calculateDifference = function(data, previousDay, index) { return previousDay ? numberWithCommas(data[index] - previousDay[index]) : numberWithCommas(data[index]); }; var calculateLevelsAndMedals = function(data, day) { var updates = $('<div></div>'); updates.addClass('levelsAndMedalsUpdates'); if(userData.innovator && day >= '2014-11-15') { _.each(medalTypes, function(medalType) { userData.medalCount.medals[medalType]++; if(medalType === userData.innovator) { updates.append(congratulateOnMedal('innovator', medalType)); delete userData.innovator; return false; } return true; }); } _.each(medalCategories, function(medalCategoryName, medalCategoryIndex) { _.each(Object.keys(requirements[medalCategoryIndex]), function(medalName) { if(specialMedals[medalName] && specialMedals[medalName] > day) { return true; } _.each(medalTypes, function(medalType) { if(userData[medalCategoryIndex][medalName][medalType] !== 0) { return true; } else { if(data[medalName] >= requirements[medalCategoryIndex][medalName][medalType]) { userData[medalCategoryIndex][medalName][medalType] = 1; userData.medalCount[medalCategoryIndex][medalType]++; updates.append(congratulateOnMedal(medalName, medalType)); return true; } else { return false; } } }); }); }); _.each(requirements.levels, function(levelRequirements, level) { if(level > 7 && day < '2014-05-08') { return false; } if(userData.level < (level+1)) { if(data.ap >= levelRequirements.ap) { if(levelRequirements.medals === null) { updates.append(congratulateOnLevel(level+1)); userData.level++; return true; } else { var eligible = true; _.each(levelRequirements.medals, function(medalCount, medalType) { if(userData.medalCount.medals[medalType] < medalCount) { eligible = false; return false; } }); if(eligible) { updates.append(congratulateOnLevel(level+1)); userData.level++; return true; } else { return false; } } } } else { return true; } return false; }); return updates; }; var cleanName = function(name) { return name.replace('-', ' ').replace(/^([a-z\u00E0-\u00FC])|\s+([a-z\u00E0-\u00FC])/g, function($1) { return $1.toUpperCase(); }); }; var drawCalendar = function (dates) { var calendar = $('<div id="calendar"><h2>Calendar</h2></div>'); calendar.attr('style', 'box-sizing: border-box;'); var previousDay = null; _.each(dates, function(data, day) { var singleDay = $('<fieldset></fieldset>'); singleDay.attr('id', 'day-'+day).addClass('float').attr('style', 'box-sizing: border-box; width: 48%; float: left; margin: 0px 1%; padding: 0px 5px;'); singleDay.append('<legend>'+day+'</legend>'); _.each(medalCategories, function(medalCategoryName, medalCategoryIndex) { var medalFieldsetHolder = $('<fieldset></fieldset>'); medalFieldsetHolder.addClass('float').attr('style', 'box-sizing: border-box; float: left; width: 48%; margin: 0 1% 30px;'); medalFieldsetHolder.append('<legend>'+medalCategoryName+'</legend>'); var medalTable = $('<table></table>'); medalTable.attr('style', 'width: 90%'); medalTable.append('<thead><tr><th>Stat</th><th>Value</th><th>Change</th></tr></thead>'); if(medalCategoryIndex === 'medals') { medalTable.append('<tr><td>AP</td> <td>'+numberWithCommas(data.ap)+'</td> <td>'+calculateDifference(data, previousDay, 'ap')+'</td></tr>'); } _.each(Object.keys(requirements[medalCategoryIndex]), function(medalName) { medalTable.append('<tr><td>'+cleanName(medalName)+'</td> <td>'+numberWithCommas(data[medalName])+'</td> <td>'+calculateDifference(data, previousDay, medalName)+'</td></tr>'); }); medalFieldsetHolder.append(medalTable); singleDay.append(medalFieldsetHolder); }); singleDay.append(calculateLevelsAndMedals(data, day)); calendar.append(singleDay); previousDay = data; }); var medalSummary = $('<fieldset></fieldset>'); medalSummary.attr('id', 'medalSummary').addClass('float').attr('style', 'box-sizing: border-box; width: 48%; float: left; margin: 0px 1%; padding: 0px 5px;'); medalSummary.append('<legend>Medal summary</legend>'); _.each(medalCategories, function(medalCategoryName, medalCategoryIndex) { var medalFieldsetHolder = $('<fieldset></fieldset>'); medalFieldsetHolder.addClass('float').attr('style', 'box-sizing: border-box;'); medalFieldsetHolder.append('<legend>'+medalCategoryName+'</legend>'); var medalsSummaryTable = $('<table></table>'); medalsSummaryTable.attr('style', 'width: 90%'); medalsSummaryTable.append('<thead><tr><th>Stat</th><th>Count</th></tr></thead>'); _.each(medalTypes, function(medalType) { medalsSummaryTable.append('<tr><td>'+cleanName(medalType)+'</td> <td>'+numberWithCommas(userData.medalCount[medalCategoryIndex][medalType])+'</td></tr>'); }); medalFieldsetHolder.append(medalsSummaryTable); medalSummary.append(medalFieldsetHolder); }); calendar.append(medalSummary); calendar.append('<div style="clear: both;"></div>'); calendar.insertAfter('#myheader'); }; var parseInnovatorMedal = function() { var innovator = window.localStorage.innovator; if(innovator) { userData.innovator = innovator; } }; $(document).ready(function() { parseInnovatorMedal(); dataHarverster(); }); })(_, jQuery);