// ==UserScript==
// @author DanielOnDiordna
// @name Player Tracker add-on
// @category Addon
// @version 1.3.1.20240209.233200
// @updateURL https://raw.githubusercontent.com/IITC-CE/Community-plugins/master/dist/DanielOnDiordna/player-tracker-addon.meta.js
// @downloadURL https://raw.githubusercontent.com/IITC-CE/Community-plugins/master/dist/DanielOnDiordna/player-tracker-addon.user.js
// @description [danielondiordna-1.3.1.20240209.233200] Add-on to the player tracker plugin: Adjust history limit of 3 hours to another value. Toggle name labels, last action time, toggle/adjust player colors, focus on players, display 1 single player. Integrated Marker Label plugin and Spectrum Colorpicker 1.8.1 plugin. Supports Machina U̶͚̓̍N̴̖̈K̠͔̍͑̂͜N̞̥͋̀̉Ȯ̶̹͕̀W̶̢͚͑̚͝Ṉ̨̟̒̅' player.
// @id player-tracker-addon@DanielOnDiordna
// @namespace https://softspot.nl/ingress/
// @depends player-activity-tracker@breunigs
// @match https://intel.ingress.com/*
// @grant none
// ==/UserScript==
function wrapper(plugin_info) {
// ensure plugin framework is there, even if iitc is not yet loaded
if(typeof window.plugin !== 'function') window.plugin = function() {};
// use own namespace for plugin
window.plugin.playerTrackerAddon = function() {};
var self = window.plugin.playerTrackerAddon;
self.id = 'playerTrackerAddon';
self.title = 'Player Tracker add-on';
self.version = '1.3.1.20240209.233200';
self.author = 'DanielOnDiordna';
self.changelog = `
Changelog:
version 1.3.1.20240209.233200
- minor fix to display player nickname on the labels (fix for Player Tracker version 0.12.3.20240201.073623 IITC-CE 0.37.1 beta)
version 1.3.0.20230514.005600
- added Machina U̶͚̓̍N̴̖̈K̠͔̍͑̂͜N̞̥͋̀̉Ȯ̶̹͕̀W̶̢͚͑̚͝Ṉ̨̟̒̅' icons, player tracker layer and colors
- reversed the changelog order to show last changes at the top
version 1.2.0.20220319.231800
- added new option to hide the "on your portal" actions, which can interfere when viewing remote locations
version 1.0.2.20211011.231300
- added new option to hide the date from the label if it is today, if show date+time is set
- properly replaced the playerTracker publicChatDataAvailable handleData hook
- fixed a console warning about a missing color during updateplayerlist when the menu is not visible
- reformatted the settings menu
version 1.0.1.20210724.002500
- prevent double plugin setup on hook iitcLoaded
version 1.0.1.20210421.190200
- minor fix for IITC CE where runHooks iitcLoaded is executed before addHook is defined in this plugin
version 1.0.1.20210328.000100
- added click event to player tracker icons while name labels are enabled to show history
- changed default settings values
version 1.0.0.20210119.225600
- changed description header
version 1.0.0.20210119.201900
- integrated marker label plugin code, no need anymore for the separate plugin
- integrated Spectrum Colorpicker 1.8.1 plugin code, no need anymore for the separate plugin
- updated plugin wrapper and userscript header formatting to match IITC-CE coding
version 0.0.13.20200131.220500
- problem solved, added better processNewData fix
version 0.0.12.20200130.172600
- problem solved, added processNewData fix
version 0.0.3.20200130.160000
version 0.0.4.20200130.160000
version 0.0.5.20200130.160000
version 0.0.6.20200130.160000
version 0.0.7.20200130.160000
version 0.0.8.20200130.160000
version 0.0.9.20200130.160000
version 0.0.10.20200130.160000
version 0.0.11.20200130.160000
- debugging for IITC CE purposes
version 0.0.2.20190915.135600
- fix for ago display for iOS users
- modified defaults for new users: show labels, apply random colors
- changed menu order and modified some menu labels to make it more clear
version 0.0.1.20181018.104200
- added plugin version on menu
- added option list to set maximum events to display (default 10)
- added choice to display date and time instead of default 'ago'
version 0.0.1.20181030.212900
- intel URL changed from www.ingress.com to *.ingress.com
`;
self.namespace = 'window.plugin.' + self.id + '.';
self.pluginname = 'plugin-' + self.id;
self.localstoragesettings = 'plugin-' + self.id + '-settings';
self.settings = {
limit: 3,
showlabels: true,
applyrandomcolors: true,
showcenter: false,
showlastaction: true,
maxdisplayevents: 10,
showdatetime: true,
hidedatetoday: false,
hideonyourportalactions: false
};
self.displayselectedplayer = false;
self.selectedplayer = '';
self.drawData_backup = '';
self.ago_backup = '';
self.restoresettings = function() {
if (typeof localStorage[self.localstoragesettings] != 'string' || localStorage[self.localstoragesettings] == '') return;
function isObject(element) {
return (typeof element == 'object' && element instanceof Object && !(element instanceof Array));
}
function parseSettings(source,target) {
if (!isObject(source) || !isObject(target)) return;
for (const key in target) {
if (key in source) {
if (isObject(target[key])) {
parseSettings(source[key],target[key]);
} else if (typeof source[key] == typeof target[key]) { // only accept settings from default settings template of same type
target[key] = source[key];
}
}
}
}
try {
let settings = JSON.parse(localStorage[self.localstoragesettings]);
parseSettings(settings,self.settings);
// convert old settings here if needed
let storechanges = false;
if (localStorage['plugin-playerTrackerOverride-limit']) {
self.settings.limit = parseFloat(localStorage['plugin-playerTrackerOverride-limit']);
delete(localStorage['plugin-playerTrackerOverride-limit']);
storechanges = true;
}
if (localStorage['plugin-playerTrackerOverride-showlabels']) {
self.settings.showlabels = localStorage['plugin-playerTrackerOverride-showlabels'] === '1';
delete(localStorage['plugin-playerTrackerOverride-showlabels']);
storechanges = true;
}
if (localStorage['plugin-playerTrackerOverride-color']) {
self.settings.applyrandomcolors = localStorage['plugin-playerTrackerOverride-color'] === '1';
delete(localStorage['plugin-playerTrackerOverride-color']);
storechanges = true;
}
if (!self.settings.limit) { // set a default if missing or zero
self.settings.limit = window.PLAYER_TRACKER_MAX_TIME / (60*60*1000);
storechanges = true;
}
if (storechanges) {
self.storesettings();
}
} catch(e) {
return false;
}
};
self.storesettings = function() {
localStorage[self.localstoragesettings] = JSON.stringify(self.settings);
};
self.setlimit = function(hours) {
hours = parseFloat(hours);
self.settings.limit = hours;
self.storesettings();
window.PLAYER_TRACKER_MAX_TIME = hours * 60*60*1000;
window.plugin.playerTracker.handleData(); // call to processNewData requires data, this is fixed by rewriting that function elsewhere
};
self.setmaxdisplayevents = function(max) {
max = parseInt(max);
self.settings.maxdisplayevents = max;
self.storesettings();
self.resettracks();
};
self.makeoptionshtml = function(options,selection) {
var optionslist = [];
if (typeof selection !== 'string') selection = selection.toString();
if (options instanceof Array) {
var cnt;
for (cnt = 0; cnt < options.length; cnt++) {
if (typeof options[cnt] !== 'string') options[cnt] = options[cnt].toString();
optionslist.push('/g, ">").replace(/' + key.replace(/&/g, "&").replace(/>/g, ">").replace(/');
}
}
return optionslist.join('\n');
};
self.labelsetup = function() {
if (self.settings.showlabels) {
// documentation: https://github.com/jacobtoye/Leaflet.iconlabel
// create a label for each marker, override the original code:
// optional:
// iconSize: new L.Point(24, 24),
// labelClassName: 'custom-label-formatting-class',
if (!self.iconEnl_backup) {
self.iconEnl_backup = window.plugin.playerTracker.iconEnl;
window.plugin.playerTracker.iconEnl = L.Icon.Label.extend({
options: {
iconUrl: window.plugin.playerTracker.iconEnl.prototype.options.iconUrl,
iconRetinaUrl: window.plugin.playerTracker.iconEnl.prototype.options.iconRetinaUrl,
shadowUrl: null,
iconSize: new L.Point(25, 41),
iconAnchor: new L.Point(0, -28),
labelAnchor: new L.Point(16, -18),
wrapperAnchor: new L.Point(12, 13)
}
});
}
if (!self.iconRes_backup) {
self.iconRes_backup = window.plugin.playerTracker.iconRes;
window.plugin.playerTracker.iconRes = L.Icon.Label.extend({
options: {
iconUrl: window.plugin.playerTracker.iconRes.prototype.options.iconUrl,
iconRetinaUrl: window.plugin.playerTracker.iconRes.prototype.options.iconRetinaUrl,
shadowUrl: null,
iconSize: new L.Point(25, 41),
iconAnchor: new L.Point(0, -28),
labelAnchor: new L.Point(16, -18),
wrapperAnchor: new L.Point(12, 13)
}
});
}
if (!self.iconMac_backup) {
self.iconMac_backup = window.plugin.playerTracker.iconMac;
window.plugin.playerTracker.iconMac = window.L.Icon.Label.extend({
options: {
iconUrl: window.plugin.playerTracker.iconMac.prototype.options.iconUrl,
iconRetinaUrl: window.plugin.playerTracker.iconMac.prototype.options.iconRetinaUrl,
shadowUrl: null,
iconSize: new window.L.Point(25, 41),
iconAnchor: new window.L.Point(0, -28),
labelAnchor: new window.L.Point(16, -18),
wrapperAnchor: new window.L.Point(12, 13)
}
});
}
} else {
if (self.iconEnl_backup) {
window.plugin.playerTracker.iconEnl = self.iconEnl_backup;
self.iconEnl_backup = undefined;
}
if (self.iconRes_backup) {
window.plugin.playerTracker.iconRes = self.iconRes_backup;
self.iconRes_backup = undefined;
}
if (self.iconMac_backup) {
window.plugin.playerTracker.iconMac = self.iconMac_backup;
self.iconMac_backup = undefined;
}
}
self.modify_drawData();
};
self.colorsetup = function() {
if (!self.processNewData_backup) {
self.processNewData_backup = window.plugin.playerTracker.processNewData;
var processNewData_override = window.plugin.playerTracker.processNewData.toString();
processNewData_override = processNewData_override.replace('var limit','if (!data) return;\n var limit');
processNewData_override = processNewData_override.replace(/( +)(events: \[newEvent\])/,'$1$2,\n$1color: ' + self.namespace + 'getPlayerColor(plrname,json[2].plext.team)');
eval('window.plugin.playerTracker.processNewData = ' + processNewData_override);
}
// restore
/*
if (self.processNewData_backup) {
eval('window.plugin.playerTracker.processNewData = ' + self.processNewData_backup.toString());
self.processNewData_backup = undefined;
}
}
*/
self.modify_drawData();
};
self.actionssetup = function() {
let processNewData_override = window.plugin.playerTracker.processNewData.toString();
processNewData_override = processNewData_override.replace(/(, address);/,'$1, action;');
processNewData_override = processNewData_override.replace(/( +)(case 'TEXT':)/,'$1$2\n$1 action = markup[1].plain;');
processNewData_override = processNewData_override.replace(/( +)(address: address)/,'$1$2,\n$1actions: [action]');
eval('window.plugin.playerTracker.processNewData = ' + processNewData_override);
};
self.resettracks = function() {
window.plugin.playerTracker.drawnTracesEnl.clearLayers();
window.plugin.playerTracker.drawnTracesRes.clearLayers();
window.plugin.playerTracker.drawnTracesMac.clearLayers();
window.plugin.playerTracker.drawData();
};
self.modify_drawData = function() {
if (!self.drawData_backup) {
self.drawData_backup = window.plugin.playerTracker.drawData.toString();
}
var drawData_override = self.drawData_backup;
if (self.settings.showlabels) {
if (drawData_override.indexOf('iconEnl()') >= 0) {
drawData_override = drawData_override.replace('iconEnl()','iconEnl({ labelText: (plrname || playerData.nick) + (' + self.namespace + 'settings.showlastaction?\', \' + window.plugin.playerTracker.ago(playerData.events[playerData.events.length - 1].time,now):\'\') })');
drawData_override = drawData_override.replace('iconRes()','iconRes({ labelText: (plrname || playerData.nick) + (' + self.namespace + 'settings.showlastaction?\', \' + window.plugin.playerTracker.ago(playerData.events[playerData.events.length - 1].time,now):\'\') })');
}
}
if (drawData_override.indexOf('displayselectedplayer') < 0) {
drawData_override = drawData_override.replace('if(!playerData','if (' + self.namespace + 'displayselectedplayer && plrname !== ' + self.namespace + 'selectedplayer) {\nreturn true;\n}\nif(!playerData');
}
if (drawData_override.indexOf('var polyLineByAgeEnl = [') >= 0) {
drawData_override = drawData_override.replace('var polyLineByAgeEnl = ','var polyLineByAgeEnl = {}; //');
drawData_override = drawData_override.replace('var polyLineByAgeRes = ','var polyLineByAgeRes = {}; //');
drawData_override = drawData_override.replace('polyLineByAgeRes[ageBucket].push(line);','{ if (!polyLineByAgeRes[plrname]) polyLineByAgeRes[plrname] = [[], [], [], []]; polyLineByAgeRes[plrname][ageBucket].push(line); }');
drawData_override = drawData_override.replace('polyLineByAgeEnl[ageBucket].push(line);','{ if (!polyLineByAgeEnl[plrname]) polyLineByAgeEnl[plrname] = [[], [], [], []]; polyLineByAgeEnl[plrname][ageBucket].push(line); }');
drawData_override = drawData_override.replace('$.each(polyLineByAgeEnl, function(i, polyLine) {','$.each(polyLineByAgeEnl, function(plrname, polyLineByAge) {\n$.each(polyLineByAge, function(i, polyLine) {');
drawData_override = drawData_override.replace('color: PLAYER_TRACKER_LINE_COLOUR,','color: window.plugin.playerTracker.stored[plrname].color,');
drawData_override = drawData_override.replace('$.each(polyLineByAgeRes, function(i, polyLine) {','});\n$.each(polyLineByAgeRes, function(plrname, polyLineByAge) {\n$.each(polyLineByAge, function(i, polyLine) {');
drawData_override = drawData_override.replace('color: PLAYER_TRACKER_LINE_COLOUR,','color: window.plugin.playerTracker.stored[plrname].color,');
drawData_override = drawData_override + ');}';
}
drawData_override = drawData_override.replace('for(var i = evtsLength - 2; i >= 0 && i >= evtsLength - 10; i--) {','for(var i = evtsLength - 2; i >= 0 && i >= evtsLength - ' + self.namespace + 'settings.maxdisplayevents; i--) {');
drawData_override = drawData_override.replace(/' ago'/g,'(' + self.namespace + 'settings.showdatetime?\'\':\' ago\')');
if (self.settings.showcenter) {
if (drawData_override.indexOf('var m = L.marker(gllfe(last),') >= 0) {
drawData_override = drawData_override.replace('var m = L.marker(gllfe(last),','var screen = map.getBounds();\n var markerpos = gllfe(last);\n if (screen.contains(markerpos)) markerpos = L.latLng(screen._southWest.lat + (screen._northEast.lat - screen._southWest.lat)/2,screen._southWest.lng + (screen._northEast.lng - screen._southWest.lng)/2);\n var m = L.marker(markerpos,');
}
}
eval('window.plugin.playerTracker.drawData = ' + drawData_override);
};
self.modify_ago = function() {
if (!self.ago_backup) {
self.ago_backup = window.plugin.playerTracker.ago.toString();
}
var ago_override = self.ago_backup;
if (ago_override.indexOf('var returnVal = m') >= 0) {
if (ago_override.indexOf('function(time, now) {') === 0) {
ago_override = ago_override.replace('function(time, now) {','function(time, now) {\nif (' + self.namespace + 'settings.showdatetime) {\n if (!(time instanceof Date)) {\n if (time) {\n time = new Date(time);\n } else {\n time = new Date();\n }\n }\n return (' + self.namespace + 'settings.hidedatetoday && new Date().toDateString() == time.toDateString()?"":[time.getFullYear(),time.getMonth()+1,time.getDate()].join(\'-\') + \' \') + [time.getHours(),(\'0\' + time.getMinutes()).slice(-2)].join(\':\');\n}');
} else if (ago_override.indexOf('function (time, now) {') === 0) { // fix for IITC on iOS
ago_override = ago_override.replace('function (time, now) {','function(time, now) {\nif (' + self.namespace + 'settings.showdatetime) {\n if (!(time instanceof Date)) {\n if (time) {\n time = new Date(time);\n } else {\n time = new Date();\n }\n }\n return (' + self.namespace + 'settings.hidedatetoday && new Date().toDateString() == time.toDateString()?"":[time.getFullYear(),time.getMonth()+1,time.getDate()].join(\'-\') + \' \') + [time.getHours(),(\'0\' + time.getMinutes()).slice(-2)].join(\':\');\n}');
}
}
eval('window.plugin.playerTracker.ago = ' + ago_override);
};
self.centersetup = function() {
self.modify_drawData();
window.plugin.playerTracker.drawData();
};
self.getRandomColor = function(plrname,team) {
// return '#' + (Math.random().toString(16) + '00000000').slice(2, 8).toUpperCase();
if (!plrname) plrname = '';
var hash = 0;
for (var i = 0; i < plrname.length; i++) {
hash = plrname.charCodeAt(i) + ((hash << 5) - hash);
}
hash = Math.abs(hash);
hash %= 200;
hash += 55; // result: number from 55 to 255
var randomcolor = hash.toString(16).toUpperCase();
if (team === 'ENLIGHTENED') {
// random green color
return '#00' + randomcolor + '00';
} else if (team === 'RESISTANCE') {
// random blue color
return '#0000' + randomcolor;
} else if (team === 'NEUTRAL') {
// random red color
return '#' + randomcolor + '0000';
}
return '#' + (hash.toString(16) + '00000000').slice(2, 8).toUpperCase();
};
self.getPlayerColor = function(plrname,team) {
if (window.plugin.playerTracker.stored && window.plugin.playerTracker.stored[plrname]) {
team = window.plugin.playerTracker.stored[plrname].team;
if (window.plugin.playerTracker.stored[plrname].color) return window.plugin.playerTracker.stored[plrname].color;
if (self.settings.applyrandomcolors) {
window.plugin.playerTracker.stored[plrname].color = self.getRandomColor(plrname,team);
return window.plugin.playerTracker.stored[plrname].color;
}
}
if (self.settings.applyrandomcolors) return self.getRandomColor(plrname,team);
return window.PLAYER_TRACKER_LINE_COLOUR;
};
self.showlist = function() {
if (!window.plugin.playerTracker.stored) return;
var resultsE = [];
var resultsR = [];
var resultsU = [];
$.each(window.plugin.playerTracker.stored, function(plrname, player) {
var text = plrname + ' ' + window.plugin.playerTracker.ago(player.events[player.events.length-1].time, new Date().getTime()) + (self.settings.showdatetime?'':' ago') + (player.events.length>1?' (' + player.events.length + ' events)':'');
if (player.team === "ENLIGHTENED") {
resultsE.push(text);
} else if (player.team === "NEUTRAL") {
resultsU.push(text);
} else {
resultsR.push(text);
}
});
alert('ENLIGHTENED:\n' + resultsE.sort(function(a,b) { return (a.toLowerCase() < b.toLowerCase()?-1:(a.toLowerCase() > b.toLowerCase()?1:0)); }).join('\n') + '\n' +
'\nRESISTANCE:\n' + resultsR.sort(function(a,b) { return (a.toLowerCase() < b.toLowerCase()?-1:(a.toLowerCase() > b.toLowerCase()?1:0)); }).join('\n') + '\n' +
'\nU̶͚̓̍N̴̖̈K̠͔̍͑̂͜N̞̥͋̀̉Ȯ̶̹͕̀W̶̢͚͑̚͝Ṉ̨̟̒̅:\n' + resultsU.sort(function(a,b) { return (a.toLowerCase() < b.toLowerCase()?-1:(a.toLowerCase() > b.toLowerCase()?1:0)); }).join('\n'));
};
self.playerselectlist = function(selectedname) {
if (!window.plugin.playerTracker.stored || window.plugin.playerTracker.stored.length === 0) return 'nothing stored';
var list = [];
var players = Object.keys(window.plugin.playerTracker.stored).sort(function(a,b) { return (a.toLowerCase() < b.toLowerCase()?-1:(a.toLowerCase() > b.toLowerCase()?1:0)); });
if (players.length === 0) {
self.selectedplayer = '';
return 'nothing stored';
}
if (!selectedname) selectedname = self.selectedplayer;
if (!selectedname) selectedname = players[0];
var selectednamefound = false;
for (var index in players) {
var plrname = players[index];
list.push('');
if (plrname === selectedname) selectednamefound = true;
}
self.selectedplayer = (selectednamefound?selectedname:'');
return '';
};
self.setSelectedPlayerColor = function(color) {
var plyrname = $('#' + self.id + '_selectplayer option:selected').val();
window.plugin.playerTracker.stored[plyrname].color = color;
$('#' + self.id + '_selectplayer').css('color',color);
$('#' + self.id + '_selectplayer option:selected').css('color',color);
self.resettracks();
};
self.updateplayerlist = function() {
if (!document.getElementById(self.id + '_selectplayer')) return;
var newlist = self.playerselectlist($('#' + self.id + '_selectplayer option:selected').val());
if (newlist !== $('#' + self.id + '_selectplayer').html()) $('#' + self.id + '_selectplayer').replaceWith(newlist);
$('#' + self.id + '_playercolor').spectrum('set',(window.plugin.playerTracker.stored && window.plugin.playerTracker.stored[$('#' + self.id + '_selectplayer option:selected').val()] && window.plugin.playerTracker.stored[$('#' + self.id + '_selectplayer option:selected').val()].color?window.plugin.playerTracker.stored[$('#' + self.id + '_selectplayer option:selected').val()].color:'black'));
};
self.viewselectedplayer = function() {
var plyrname = $('#' + self.id + '_selectplayer option:selected').val();
if (!window.plugin.playerTracker.stored || !window.plugin.playerTracker.stored[plyrname]) return;
var lasteventlatlng = window.plugin.playerTracker.stored[plyrname].events[window.plugin.playerTracker.stored[plyrname].events.length-1].latlngs[0];
// map.fitBounds(window.plugin.quickdrawlinks.drawnItems.getBounds());
var position = new L.LatLng(lasteventlatlng[0],lasteventlatlng[1]);
window.map.setView(position, map.getZoom());
};
self.menu = function() {
var limitchoices = {'30 minutes':0.5,'1 hour':1,'2 hours':2,'3 hours (default)':3,'4 hours':4,'5 hours':5,'6 hours':6,'12 hours':12,'1 day':24,'2 days':48,'3 days':72,'4 days':96,'5 days':120,'6 days':144,'1 week':168};
var maxdisplayeventschoices = {'1':1,'5':5,'10 (default)':10,'15':15,'20':20,'25':25,'30':30,'40':40};
let container = document.createElement('div');
container.className = self.id + 'menu';
let hiddenautofocusinput = container.appendChild(document.createElement('input')); // added to prevent auto focus on first element
hiddenautofocusinput.type = 'hidden';
hiddenautofocusinput.autofocus = 'autofocus';
let showlabelsarea = container.appendChild(document.createElement('label'));
let showlabels = showlabelsarea.appendChild(document.createElement('input'));
showlabels.type = 'checkbox';
showlabels.checked = self.settings.showlabels;
showlabelsarea.appendChild(document.createTextNode('Show player name labels'));
container.appendChild(document.createElement('br'));
let showlastactionarea = container.appendChild(document.createElement('label'));
let showlastaction = showlastactionarea.appendChild(document.createElement('input'));
showlastaction.type = 'checkbox';
showlastaction.checked = self.settings.showlastaction;
showlastaction.disabled = !self.settings.showlabels;
showlastactionarea.appendChild(document.createTextNode('Display time on labels'));
container.appendChild(document.createElement('br'));
let showdatetimearea = container.appendChild(document.createElement('label'));
let showdatetime = showdatetimearea.appendChild(document.createElement('input'));
showdatetime.type = 'checkbox';
showdatetime.checked = self.settings.showdatetime;
showdatetime.disabled = !(self.settings.showlabels && self.settings.showlastaction);
showdatetimearea.appendChild(document.createTextNode("Show date+time instead of 'ago'"));
container.appendChild(document.createElement('br'));
let hidedatetodayarea = container.appendChild(document.createElement('label'));
let hidedatetoday = hidedatetodayarea.appendChild(document.createElement('input'));
hidedatetoday.type = 'checkbox';
hidedatetoday.checked = self.settings.hidedatetoday;
hidedatetoday.disabled = !(self.settings.showlabels && self.settings.showlastaction && self.settings.showdatetime);
hidedatetodayarea.appendChild(document.createTextNode('Hide date if it is today'));
container.appendChild(document.createElement('br'));
let hideonyourportalactionsarea = container.appendChild(document.createElement('label'));
let hideonyourportalactions = hideonyourportalactionsarea.appendChild(document.createElement('input'));
hideonyourportalactions.type = 'checkbox';
hideonyourportalactions.checked = self.settings.hideonyourportalactions;
hideonyourportalactionsarea.appendChild(document.createTextNode('Hide "on your portal" actions'));
showlabels.addEventListener('change', function(e) {
e.preventDefault();
self.settings.showlabels = this.checked;
self.storesettings();
self.labelsetup();
self.resettracks();
showlastaction.disabled = !self.settings.showlabels;
showdatetime.disabled = !(self.settings.showlabels && self.settings.showlastaction);
hidedatetoday.disabled = !(self.settings.showlabels && self.settings.showlastaction && self.settings.showdatetime);
},false);
showlastaction.addEventListener('change', function(e) {
e.preventDefault();
self.settings.showlastaction = this.checked;
self.storesettings();
self.labelsetup();
self.resettracks();
showlastaction.disabled = !self.settings.showlabels;
showdatetime.disabled = !(self.settings.showlabels && self.settings.showlastaction);
hidedatetoday.disabled = !(self.settings.showlabels && self.settings.showlastaction && self.settings.showdatetime);
},false);
showdatetime.addEventListener('change', function(e) {
e.preventDefault();
self.settings.showdatetime = this.checked;
self.storesettings();
self.labelsetup();
self.resettracks();
showlastaction.disabled = !self.settings.showlabels;
showdatetime.disabled = !(self.settings.showlabels && self.settings.showlastaction);
hidedatetoday.disabled = !(self.settings.showlabels && self.settings.showlastaction && self.settings.showdatetime);
},false);
hidedatetoday.addEventListener('change', function(e) {
e.preventDefault();
self.settings.hidedatetoday = this.checked;
self.storesettings();
self.labelsetup();
self.resettracks();
showlastaction.disabled = !self.settings.showlabels;
showdatetime.disabled = !(self.settings.showlabels && self.settings.showlastaction);
hidedatetoday.disabled = !(self.settings.showlabels && self.settings.showlastaction && self.settings.showdatetime);
},false);
hideonyourportalactions.addEventListener('change', function(e) {
e.preventDefault();
self.settings.hideonyourportalactions = this.checked;
self.storesettings();
self.resettracks();
},false);
let othersettings = container.appendChild(document.createElement('div'));
othersettings.className = self.id + 'menu';
othersettings.innerHTML =
'History:
' +
'History lines:
' +
'
' +
' Adjust color for selected player:
' +
self.playerselectlist() + '
' +
'
' +
'
' +
'Focus on selected player' +
'Show list of stored players';
let author = container.appendChild(document.createElement('div'));
author.className = self.id + 'author';
author.textContent = self.title + ' version ' + self.version + ' by ' + self.author;
dialog({
id: 'ui-dialog-' + self.id,
html: container,
dialogClass: 'ui-dialog-' + self.id + 'Set',
title: self.title
}).dialog('option', 'buttons', {
'Changelog': function() { alert(self.changelog); },
'Close': function() { $(this).dialog('close'); }
});
// need to initialise the 'spectrum' color picker
$('#' + self.id + '_playercolor').spectrum({
flat: false,
showInput: true,
showButtons: true,
showPalette: true,
showSelectionPalette: true,
allowEmpty: false,
palette: [
['#004000','#008000','#00C000'],
['#00FF00','#80FF80','#C0FFC0'],
['#000040','#000080','#0000C0'],
['#4040FF','#8080FF','#C0C0FF'],
['#6A3400','#964A00','#C05F00'],
['#E27000','#FF8309','#FFC287',window.PLAYER_TRACKER_LINE_COLOUR],
['#a24ac3','#514ac3','#4aa8c3','#51c34a'],
['#c1c34a','#c38a4a','#c34a4a','#c34a6f'],
['#000000','#666666','#bbbbbb','#ffffff']
],
change: function(color) { self.setSelectedPlayerColor(color.toHexString()); },
color: self.getPlayerColor($('#' + self.id + '_selectplayer option:selected').val()),
});
};
self.setupMarkerlabel = function() {
/*
Leaflet.iconlabel (https://github.com/jacobtoye/Leaflet.iconlabel) Copyright 2012 Jacob Toye
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
L.Icon.Label = L.Icon.extend({
options: {
/*
labelAnchor: (Point) (top left position of the label within the wrapper, default is right)
wrapperAnchor: (Point) (position of icon and label relative to Lat/Lng)
iconAnchor: (Point) (top left position of icon within wrapper)
labelText: (String) (label's text component, if this is null the element will not be created)
*/
/* Icon options:
iconUrl: (String) (required)
iconSize: (Point) (can be set through CSS)
iconAnchor: (Point) (centered by default if size is specified, can be set in CSS with negative margins)
popupAnchor: (Point) (if not specified, popup opens in the anchor point)
shadowUrl: (Point) (no shadow by default)
shadowSize: (Point)
*/
labelClassName: ''
},
initialize: function (options) {
L.Util.setOptions(this, options);
L.Icon.prototype.initialize.call(this, this.options);
},
setLabelAsHidden: function () {
this._labelHidden = true;
},
createIcon: function () {
return this._createLabel(L.Icon.prototype.createIcon.call(this));
},
createShadow: function () {
if (!this.options.shadowUrl) {
return null;
}
var shadow = L.Icon.prototype.createShadow.call(this);
//need to reposition the shadow
if (shadow) {
shadow.style.marginLeft = (-this.options.wrapperAnchor.x) + 'px';
shadow.style.marginTop = (-this.options.wrapperAnchor.y) + 'px';
}
return shadow;
},
updateLabel: function (icon, text) {
if (icon.nodeName.toUpperCase() === 'DIV') {
icon.childNodes[1].innerHTML = text;
this.options.labelText = text;
}
},
showLabel: function (icon) {
if (!this._labelTextIsSet()) {
return;
}
icon.childNodes[1].style.display = 'block';
},
hideLabel: function (icon) {
if (!this._labelTextIsSet()) {
return;
}
icon.childNodes[1].style.display = 'none';
},
_createLabel: function (img) {
if (!this._labelTextIsSet()) {
return img;
}
var wrapper = document.createElement('div'),
label = document.createElement('span');
// set up wrapper anchor
wrapper.style.marginLeft = (-this.options.wrapperAnchor.x) + 'px';
wrapper.style.marginTop = (-this.options.wrapperAnchor.y) + 'px';
wrapper.className = 'leaflet-marker-icon-wrapper leaflet-zoom-animated';
// set up label
label.className = 'leaflet-marker-iconlabel ' + this.options.labelClassName;
label.innerHTML = this.options.labelText;
label.style.marginLeft = this.options.labelAnchor.x + 'px';
label.style.marginTop = this.options.labelAnchor.y + 'px';
if (this._labelHidden) {
label.style.display = 'none';
// Ensure that the pointer cursor shows
img.style.cursor = 'pointer';
}
img.className = 'leaflet-interactive';
//reset icons margins (as super makes them -ve)
img.style.marginLeft = this.options.iconAnchor.x + 'px';
img.style.marginTop = this.options.iconAnchor.y + 'px';
wrapper.appendChild(img);
wrapper.appendChild(label);
return wrapper;
},
_labelTextIsSet: function () {
return typeof this.options.labelText !== 'undefined' && this.options.labelText !== null;
}
});
L.Icon.Label.Default = L.Icon.Label.extend({
options: {
//This is the top left position of the label within the wrapper. By default it will display at the right
//middle position of the default icon. x = width of icon + padding
//If the icon height is greater than the label height you will need to set the y value.
//y = (icon height - label height) / 2
labelAnchor: new L.Point(29, 8),
//This is the position of the wrapper div. Use this to position icon + label relative to the Lat/Lng.
//By default the point of the default icon is anchor
wrapperAnchor: new L.Point(13, 41),
//This is now the top left position of the icon within the wrapper.
//If the label height is greater than the icon you will need to set the y value.
//y = (label height - icon height) / 2
iconAnchor: new L.Point(0, 0),
//label's text component, if this is null the element will not be created
labelText: null,
/* From L.Icon.Default */
iconUrl: L.Icon.Default.imagePath + '/marker-icon.png',
iconSize: new L.Point(25, 41),
popupAnchor: new L.Point(0, -33),
shadowUrl: L.Icon.Default.imagePath + '/marker-shadow.png',
shadowSize: new L.Point(41, 41)
}
});
L.Marker.Label = L.Marker.extend({
updateLabel: function (text) {
this.options.icon.updateLabel(this._icon, text);
},
_initIcon: function () {
if (!(this.options.icon instanceof L.Icon.Label)) {
throw new Error('Icon must be an instance of L.Icon.Label.');
}
// Ensure that the label is hidden to begin with
if (this.options.revealing) {
this.options.icon.setLabelAsHidden();
}
L.Marker.prototype._initIcon.call(this);
},
_removeIcon: function () {
if (this.options.revealing) {
L.DomEvent
.off(this._icon, 'mouseover', this._showLabel)
.off(this._icon, 'mouseout', this._hideLabel);
}
L.Marker.prototype._removeIcon.call(this);
},
_initInteraction: function () {
L.Marker.prototype._initInteraction.call(this);
if (!this.options.revealing) {
return;
}
L.DomEvent
.on(this._icon, 'mouseover', this._showLabel, this)
.on(this._icon, 'mouseout', this._hideLabel, this);
},
_showLabel: function () {
this.options.icon.showLabel(this._icon);
},
_hideLabel: function () {
this.options.icon.hideLabel(this._icon);
}
});
// ' font: 9px/0.5 Arial;' +
// ' font: 12px/1.5 Arial;' +
$('head').append(
'');
}; // end self.setupMarkerlabel
self.setupColorpickerSpectrum = function() {
// source: https://github.com/bgrins/spectrum
// minified with https://www.minifier.org/
// Spectrum Colorpicker v1.8.1
// https://github.com/bgrins/spectrum
// Author: Brian Grinstead
// License: MIT
(function(factory){"use strict";if(typeof define==='function'&&define.amd){define(['jquery'],factory)}else if(typeof exports=="object"&&typeof module=="object"){module.exports=factory(require('jquery'))}else{factory(jQuery)}})(function($,undefined){"use strict";var defaultOpts={beforeShow:noop,move:noop,change:noop,show:noop,hide:noop,color:!1,flat:!1,showInput:!1,allowEmpty:!1,showButtons:!0,clickoutFiresChange:!0,showInitial:!1,showPalette:!1,showPaletteOnly:!1,hideAfterPaletteSelect:!1,togglePaletteOnly:!1,showSelectionPalette:!0,localStorageKey:!1,appendTo:"body",maxSelectionSize:7,cancelText:"cancel",chooseText:"choose",togglePaletteMoreText:"more",togglePaletteLessText:"less",clearText:"Clear Color Selection",noColorSelectedText:"No Color Selected",preferredFormat:!1,className:"",containerClassName:"",replacerClassName:"",showAlpha:!1,theme:"sp-light",palette:[["#ffffff","#000000","#ff0000","#ff8000","#ffff00","#008000","#0000ff","#4b0082","#9400d3"]],selectionPalette:[],disabled:!1,offset:null},spectrums=[],IE=!!/msie/i.exec(window.navigator.userAgent),rgbaSupport=(function(){function contains(str,substr){return!!~(''+str).indexOf(substr)}
var elem=document.createElement('div');var style=elem.style;style.cssText='background-color:rgba(0,0,0,.5)';return contains(style.backgroundColor,'rgba')||contains(style.backgroundColor,'hsla')})(),replaceInput=["