├── images ├── uniques.png ├── uniques-heatmap-explorer.png ├── uniques-heatmap-pioneer.png └── portal-highlighter-uniques-opacity.png ├── LICENSE ├── dist ├── basemap-seznam.meta.js ├── uniques-gdpr.meta.js ├── uniques-heatmap.meta.js ├── portal-highlighter-uniques-opacity.meta.js ├── basemap-seznam.user.js ├── portal-highlighter-uniques-opacity.user.js ├── uniques-heatmap.user.js └── uniques-gdpr.user.js ├── plugins ├── basemap-seznam.user.js ├── portal-highlighter-uniques-opacity.user.js └── uniques-heatmap.user.js ├── README.md └── external └── leaflet-heat.js /images/uniques.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xificurk/iitc-plugins/HEAD/images/uniques.png -------------------------------------------------------------------------------- /images/uniques-heatmap-explorer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xificurk/iitc-plugins/HEAD/images/uniques-heatmap-explorer.png -------------------------------------------------------------------------------- /images/uniques-heatmap-pioneer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xificurk/iitc-plugins/HEAD/images/uniques-heatmap-pioneer.png -------------------------------------------------------------------------------- /images/portal-highlighter-uniques-opacity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xificurk/iitc-plugins/HEAD/images/portal-highlighter-uniques-opacity.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Petr Morávek 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /dist/basemap-seznam.meta.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @id iitc-plugin-basemap-seznam@xificurk 3 | // @name IITC plugin: Seznam map tiles 4 | // @category Map Tiles 5 | // @version 0.2.0.20230130.201555 6 | // @namespace https://github.com/xificurk/iitc-plugins 7 | // @updateURL https://raw.githubusercontent.com/xificurk/iitc-plugins/master/dist/basemap-seznam.meta.js 8 | // @downloadURL https://raw.githubusercontent.com/xificurk/iitc-plugins/master/dist/basemap-seznam.user.js 9 | // @description [xificurk-2023-01-30-201555] Seznam map tiles. 10 | // @include https://intel.ingress.com/* 11 | // @include http://intel.ingress.com/* 12 | // @match https://intel.ingress.com/* 13 | // @match http://intel.ingress.com/* 14 | // @include https://*.ingress.com/intel* 15 | // @include http://*.ingress.com/intel* 16 | // @match https://*.ingress.com/intel* 17 | // @match http://*.ingress.com/intel* 18 | // @include https://*.ingress.com/mission/* 19 | // @include http://*.ingress.com/mission/* 20 | // @match https://*.ingress.com/mission/* 21 | // @match http://*.ingress.com/mission/* 22 | // @grant none 23 | // ==/UserScript== 24 | -------------------------------------------------------------------------------- /dist/uniques-gdpr.meta.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @id iitc-plugin-uniques-gdpr@xificurk 3 | // @name IITC plugin: show uniques visit/captures based on GDPR game_log 4 | // @category Misc 5 | // @version 0.1.0.20201122.121942 6 | // @namespace https://github.com/xificurk/iitc-plugins 7 | // @updateURL https://raw.githubusercontent.com/xificurk/iitc-plugins/master/dist/uniques-gdpr.meta.js 8 | // @downloadURL https://raw.githubusercontent.com/xificurk/iitc-plugins/master/dist/uniques-gdpr.user.js 9 | // @description [xificurk-2020-11-22-121942] Show uniques visit/captures based on GDPR game_log 10 | // @include https://intel.ingress.com/* 11 | // @include http://intel.ingress.com/* 12 | // @match https://intel.ingress.com/* 13 | // @match http://intel.ingress.com/* 14 | // @include https://*.ingress.com/intel* 15 | // @include http://*.ingress.com/intel* 16 | // @match https://*.ingress.com/intel* 17 | // @match http://*.ingress.com/intel* 18 | // @include https://*.ingress.com/mission/* 19 | // @include http://*.ingress.com/mission/* 20 | // @match https://*.ingress.com/mission/* 21 | // @match http://*.ingress.com/mission/* 22 | // @grant none 23 | // ==/UserScript== 24 | -------------------------------------------------------------------------------- /dist/uniques-heatmap.meta.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @id iitc-plugin-uniques-heatmap@xificurk 3 | // @name IITC plugin: Unique visits/captures heatmap 4 | // @category Layer 5 | // @version 0.2.1.20210207.174711 6 | // @namespace https://github.com/xificurk/iitc-plugins 7 | // @updateURL https://raw.githubusercontent.com/xificurk/iitc-plugins/master/dist/uniques-heatmap.meta.js 8 | // @downloadURL https://raw.githubusercontent.com/xificurk/iitc-plugins/master/dist/uniques-heatmap.user.js 9 | // @description [xificurk-2021-02-07-174711] Display heatmap of all portals that the player did NOT visit/capture. Requires uniques plugin. 10 | // @include https://intel.ingress.com/* 11 | // @include http://intel.ingress.com/* 12 | // @match https://intel.ingress.com/* 13 | // @match http://intel.ingress.com/* 14 | // @include https://*.ingress.com/intel* 15 | // @include http://*.ingress.com/intel* 16 | // @match https://*.ingress.com/intel* 17 | // @match http://*.ingress.com/intel* 18 | // @include https://*.ingress.com/mission/* 19 | // @include http://*.ingress.com/mission/* 20 | // @match https://*.ingress.com/mission/* 21 | // @match http://*.ingress.com/mission/* 22 | // @grant none 23 | // ==/UserScript== 24 | -------------------------------------------------------------------------------- /dist/portal-highlighter-uniques-opacity.meta.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @id iitc-plugin-portal-highlighter-uniques-opacity@xificurk 3 | // @name IITC plugin: Highlight unique visits/captures using opacity 4 | // @category Highlighter 5 | // @version 0.2.1.20230304.150308 6 | // @namespace https://github.com/xificurk/iitc-plugins 7 | // @updateURL https://raw.githubusercontent.com/xificurk/iitc-plugins/master/dist/portal-highlighter-uniques-opacity.meta.js 8 | // @downloadURL https://raw.githubusercontent.com/xificurk/iitc-plugins/master/dist/portal-highlighter-uniques-opacity.user.js 9 | // @description [xificurk-2023-03-04-150308] Use stroke and fill opacity to denote player's unique visits and captures. Requires uniques plugin. 10 | // @include https://intel.ingress.com/* 11 | // @include http://intel.ingress.com/* 12 | // @match https://intel.ingress.com/* 13 | // @match http://intel.ingress.com/* 14 | // @include https://*.ingress.com/intel* 15 | // @include http://*.ingress.com/intel* 16 | // @match https://*.ingress.com/intel* 17 | // @match http://*.ingress.com/intel* 18 | // @include https://*.ingress.com/mission/* 19 | // @include http://*.ingress.com/mission/* 20 | // @match https://*.ingress.com/mission/* 21 | // @match http://*.ingress.com/mission/* 22 | // @grant none 23 | // ==/UserScript== 24 | -------------------------------------------------------------------------------- /plugins/basemap-seznam.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @id iitc-plugin-basemap-seznam@xificurk 3 | // @name IITC plugin: Seznam map tiles 4 | // @category Map Tiles 5 | // @version 0.2.0.@@DATETIMEVERSION@@ 6 | // @namespace https://github.com/xificurk/iitc-plugins 7 | // @updateURL @@UPDATEURL@@ 8 | // @downloadURL @@DOWNLOADURL@@ 9 | // @description [@@BUILDNAME@@-@@BUILDDATE@@] Seznam map tiles. 10 | // @include https://intel.ingress.com/* 11 | // @include http://intel.ingress.com/* 12 | // @match https://intel.ingress.com/* 13 | // @match http://intel.ingress.com/* 14 | // @include https://*.ingress.com/intel* 15 | // @include http://*.ingress.com/intel* 16 | // @match https://*.ingress.com/intel* 17 | // @match http://*.ingress.com/intel* 18 | // @include https://*.ingress.com/mission/* 19 | // @include http://*.ingress.com/mission/* 20 | // @match https://*.ingress.com/mission/* 21 | // @match http://*.ingress.com/mission/* 22 | // @grant none 23 | // ==/UserScript== 24 | 25 | @@PLUGINSTART@@ 26 | //PLUGIN START //////////////////////////////////////////////////////// 27 | 28 | 29 | var setup = function() { 30 | console.error('Seznam map tiles are no longer publicly available - you should remove the plugin.'); 31 | } 32 | 33 | //PLUGIN END ////////////////////////////////////////////////////////// 34 | 35 | @@PLUGINEND@@ 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Unofficial IITC plugins 2 | 3 | 4 | ## Highlight unique visits/captures using opacity [[Install](https://raw.githubusercontent.com/xificurk/iitc-plugins/master/dist/portal-highlighter-uniques-opacity.user.js)] 5 | 6 | Use stroke and fill opacity to denote player's unique visits and captures. Uses NIA intel visits/captures data. 7 | 8 | The standard highlighter from uniques plugin gives you clear overview of un/visited/captured portals, but I do not like the fact that it kind of masks the state of the battlefield, especially when you're zoomed out. 9 | 10 | This highlighter does not use any additional colors, so the Enlightened/Resistance controlled areas remain mostly green/blue. It uses opacity to de-emphasize the areas where you already have unique captures, and on the other hand brings up the areas that you have not visited at all. 11 | 12 | See the example below and compare it with [standard highlighter](images/uniques.png?raw=true). 13 | 14 | ### Example 15 | 16 | ![Uniques opacity plugin highlighting](images/portal-highlighter-uniques-opacity.png?raw=true "Uniques opacity plugin highlighting") 17 | 18 | 19 | ## Unique visits/captures heatmap [[Install](https://raw.githubusercontent.com/xificurk/iitc-plugins/master/dist/uniques-heatmap.user.js)] 20 | 21 | Display heatmap of all portals that the player did NOT visit/capture. Uses NIA intel visits/captures data. 22 | 23 | This plugin adds two additional layers - Explorer heatmap (unvisited portals) and Pioneer heatmap (uncaptured portals), it's great for identifying portal-dense areas that you did not visit/capture. 24 | 25 | See the example heatmaps below and compare it with [standard highlighter](images/uniques.png?raw=true). 26 | 27 | ### Explorer heatmap 28 | 29 | ![Explorer heatmap](images/uniques-heatmap-explorer.png?raw=true "Explorer heatmap") 30 | 31 | ### Pioneer heatmap 32 | 33 | ![Pioneer heatmap](images/uniques-heatmap-pioneer.png?raw=true "Pioneer heatmap") 34 | -------------------------------------------------------------------------------- /dist/basemap-seznam.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @id iitc-plugin-basemap-seznam@xificurk 3 | // @name IITC plugin: Seznam map tiles 4 | // @category Map Tiles 5 | // @version 0.2.0.20230130.201555 6 | // @namespace https://github.com/xificurk/iitc-plugins 7 | // @updateURL https://raw.githubusercontent.com/xificurk/iitc-plugins/master/dist/basemap-seznam.meta.js 8 | // @downloadURL https://raw.githubusercontent.com/xificurk/iitc-plugins/master/dist/basemap-seznam.user.js 9 | // @description [xificurk-2023-01-30-201555] Seznam map tiles. 10 | // @include https://intel.ingress.com/* 11 | // @include http://intel.ingress.com/* 12 | // @match https://intel.ingress.com/* 13 | // @match http://intel.ingress.com/* 14 | // @include https://*.ingress.com/intel* 15 | // @include http://*.ingress.com/intel* 16 | // @match https://*.ingress.com/intel* 17 | // @match http://*.ingress.com/intel* 18 | // @include https://*.ingress.com/mission/* 19 | // @include http://*.ingress.com/mission/* 20 | // @match https://*.ingress.com/mission/* 21 | // @match http://*.ingress.com/mission/* 22 | // @grant none 23 | // ==/UserScript== 24 | 25 | 26 | function wrapper(plugin_info) { 27 | // ensure plugin framework is there, even if iitc is not yet loaded 28 | if(typeof window.plugin !== 'function') window.plugin = function() {}; 29 | 30 | //PLUGIN AUTHORS: writing a plugin outside of the IITC build environment? if so, delete these lines!! 31 | //(leaving them in place might break the 'About IITC' page or break update checks) 32 | plugin_info.buildName = 'xificurk'; 33 | plugin_info.dateTimeVersion = '20230130.201555'; 34 | plugin_info.pluginId = 'basemap-seznam'; 35 | //END PLUGIN AUTHORS NOTE 36 | 37 | 38 | //PLUGIN START //////////////////////////////////////////////////////// 39 | 40 | 41 | var setup = function() { 42 | console.error('Seznam map tiles are no longer publicly available - you should remove the plugin.'); 43 | } 44 | 45 | //PLUGIN END ////////////////////////////////////////////////////////// 46 | 47 | 48 | setup.info = plugin_info; //add the script info data to the function as a property 49 | if(!window.bootPlugins) window.bootPlugins = []; 50 | window.bootPlugins.push(setup); 51 | // if IITC has already booted, immediately run the 'setup' function 52 | if(window.iitcLoaded && typeof setup === 'function') setup(); 53 | } // wrapper end 54 | // inject code into site context 55 | var script = document.createElement('script'); 56 | var info = {}; 57 | if (typeof GM_info !== 'undefined' && GM_info && GM_info.script) info.script = { version: GM_info.script.version, name: GM_info.script.name, description: GM_info.script.description }; 58 | script.appendChild(document.createTextNode('('+ wrapper +')('+JSON.stringify(info)+');')); 59 | (document.body || document.head || document.documentElement).appendChild(script); 60 | 61 | 62 | -------------------------------------------------------------------------------- /plugins/portal-highlighter-uniques-opacity.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @id iitc-plugin-portal-highlighter-uniques-opacity@xificurk 3 | // @name IITC plugin: Highlight unique visits/captures using opacity 4 | // @category Highlighter 5 | // @version 0.2.1.@@DATETIMEVERSION@@ 6 | // @namespace https://github.com/xificurk/iitc-plugins 7 | // @updateURL @@UPDATEURL@@ 8 | // @downloadURL @@DOWNLOADURL@@ 9 | // @description [@@BUILDNAME@@-@@BUILDDATE@@] Use stroke and fill opacity to denote player's unique visits and captures. Requires uniques plugin. 10 | // @include https://intel.ingress.com/* 11 | // @include http://intel.ingress.com/* 12 | // @match https://intel.ingress.com/* 13 | // @match http://intel.ingress.com/* 14 | // @include https://*.ingress.com/intel* 15 | // @include http://*.ingress.com/intel* 16 | // @match https://*.ingress.com/intel* 17 | // @match http://*.ingress.com/intel* 18 | // @include https://*.ingress.com/mission/* 19 | // @include http://*.ingress.com/mission/* 20 | // @match https://*.ingress.com/mission/* 21 | // @match http://*.ingress.com/mission/* 22 | // @grant none 23 | // ==/UserScript== 24 | 25 | @@PLUGINSTART@@ 26 | //PLUGIN START //////////////////////////////////////////////////////// 27 | 28 | 29 | //use own namespace for plugin 30 | window.plugin.portalHighlighterUniquesOpacity = function () {}; 31 | 32 | 33 | window.plugin.portalHighlighterUniquesOpacity.highlight = function(data, styles) { 34 | var portalData = data.portal.options.ent[2] 35 | var uniqueInfo = null; 36 | 37 | if (portalData[18]) { 38 | uniqueInfo = { 39 | captured: ((portalData[18] & 0b10) !== 0), 40 | visited: ((portalData[18] & 0b11) !== 0) 41 | }; 42 | } 43 | 44 | var style = {}; 45 | 46 | if(uniqueInfo) { 47 | if(uniqueInfo.captured) { 48 | // captured (and, implied, visited too) - hide 49 | style = styles.captured; 50 | 51 | } else if(uniqueInfo.visited) { 52 | style = styles.visited; 53 | } 54 | } else { 55 | // no visit data at all 56 | style = styles.unvisited; 57 | } 58 | 59 | data.portal.setStyle(style); 60 | } 61 | 62 | 63 | window.plugin.portalHighlighterUniquesOpacity.highlighter = { 64 | highlight: function(data) { 65 | window.plugin.portalHighlighterUniquesOpacity.highlight( 66 | data, 67 | { 68 | captured: { 69 | fillOpacity: 0, 70 | opacity: 0.25, 71 | }, 72 | visited: { 73 | fillOpacity: 0.2, 74 | opacity: 1, 75 | }, 76 | unvisited: { 77 | fillOpacity: 0.8, 78 | opacity: 1, 79 | }, 80 | } 81 | ); 82 | } 83 | } 84 | 85 | window.plugin.portalHighlighterUniquesOpacity.highlighterInverted = { 86 | highlight: function(data) { 87 | window.plugin.portalHighlighterUniquesOpacity.highlight( 88 | data, 89 | { 90 | captured: { 91 | fillOpacity: 0.8, 92 | opacity: 1, 93 | }, 94 | visited: { 95 | fillOpacity: 0.2, 96 | opacity: 1, 97 | }, 98 | unvisited: { 99 | fillOpacity: 0, 100 | opacity: 0.25, 101 | }, 102 | } 103 | ); 104 | } 105 | } 106 | 107 | 108 | var setup = function() { 109 | window.addPortalHighlighter('Uniques (opacity)', window.plugin.portalHighlighterUniquesOpacity.highlighter); 110 | window.addPortalHighlighter('Uniques (opacity inverted)', window.plugin.portalHighlighterUniquesOpacity.highlighterInverted); 111 | } 112 | 113 | //PLUGIN END ////////////////////////////////////////////////////////// 114 | 115 | @@PLUGINEND@@ 116 | -------------------------------------------------------------------------------- /external/leaflet-heat.js: -------------------------------------------------------------------------------- 1 | /* 2 | (c) 2014, Vladimir Agafonkin 3 | simpleheat, a tiny JavaScript library for drawing heatmaps with Canvas 4 | https://github.com/mourner/simpleheat 5 | */ 6 | !function(){"use strict";function t(i){return this instanceof t?(this._canvas=i="string"==typeof i?document.getElementById(i):i,this._ctx=i.getContext("2d"),this._width=i.width,this._height=i.height,this._max=1,void this.clear()):new t(i)}t.prototype={defaultRadius:25,defaultGradient:{.4:"blue",.6:"cyan",.7:"lime",.8:"yellow",1:"red"},data:function(t,i){return this._data=t,this},max:function(t){return this._max=t,this},add:function(t){return this._data.push(t),this},clear:function(){return this._data=[],this},radius:function(t,i){i=i||15;var a=this._circle=document.createElement("canvas"),s=a.getContext("2d"),e=this._r=t+i;return a.width=a.height=2*e,s.shadowOffsetX=s.shadowOffsetY=200,s.shadowBlur=i,s.shadowColor="black",s.beginPath(),s.arc(e-200,e-200,t,0,2*Math.PI,!0),s.closePath(),s.fill(),this},gradient:function(t){var i=document.createElement("canvas"),a=i.getContext("2d"),s=a.createLinearGradient(0,0,0,256);i.width=1,i.height=256;for(var e in t)s.addColorStop(e,t[e]);return a.fillStyle=s,a.fillRect(0,0,1,256),this._grad=a.getImageData(0,0,1,256).data,this},draw:function(t){this._circle||this.radius(this.defaultRadius),this._grad||this.gradient(this.defaultGradient);var i=this._ctx;i.clearRect(0,0,this._width,this._height);for(var a,s=0,e=this._data.length;e>s;s++)a=this._data[s],i.globalAlpha=Math.max(a[2]/this._max,t||.05),i.drawImage(this._circle,a[0]-this._r,a[1]-this._r);var n=i.getImageData(0,0,this._width,this._height);return this._colorize(n.data,this._grad),i.putImageData(n,0,0),this},_colorize:function(t,i){for(var a,s=3,e=t.length;e>s;s+=4)a=4*t[s],a&&(t[s-3]=i[a],t[s-2]=i[a+1],t[s-1]=i[a+2])}},window.simpleheat=t}(),/* 7 | (c) 2014, Vladimir Agafonkin 8 | Leaflet.heat, a tiny and fast heatmap plugin for Leaflet. 9 | https://github.com/Leaflet/Leaflet.heat 10 | */ 11 | L.HeatLayer=(L.Layer?L.Layer:L.Class).extend({initialize:function(t,i){this._latlngs=t,L.setOptions(this,i)},setLatLngs:function(t){return this._latlngs=t,this.redraw()},addLatLng:function(t){return this._latlngs.push(t),this.redraw()},setOptions:function(t){return L.setOptions(this,t),this._heat&&this._updateOptions(),this.redraw()},redraw:function(){return!this._heat||this._frame||this._map._animating||(this._frame=L.Util.requestAnimFrame(this._redraw,this)),this},onAdd:function(t){this._map=t,this._canvas||this._initCanvas(),t._panes.overlayPane.appendChild(this._canvas),t.on("moveend",this._reset,this),t.options.zoomAnimation&&L.Browser.any3d&&t.on("zoomanim",this._animateZoom,this),this._reset()},onRemove:function(t){t.getPanes().overlayPane.removeChild(this._canvas),t.off("moveend",this._reset,this),t.options.zoomAnimation&&t.off("zoomanim",this._animateZoom,this)},addTo:function(t){return t.addLayer(this),this},_initCanvas:function(){var t=this._canvas=L.DomUtil.create("canvas","leaflet-heatmap-layer leaflet-layer"),i=L.DomUtil.testProp(["transformOrigin","WebkitTransformOrigin","msTransformOrigin"]);t.style[i]="50% 50%";var a=this._map.getSize();t.width=a.x,t.height=a.y;var s=this._map.options.zoomAnimation&&L.Browser.any3d;L.DomUtil.addClass(t,"leaflet-zoom-"+(s?"animated":"hide")),this._heat=simpleheat(t),this._updateOptions()},_updateOptions:function(){this._heat.radius(this.options.radius||this._heat.defaultRadius,this.options.blur),this.options.gradient&&this._heat.gradient(this.options.gradient),this.options.max&&this._heat.max(this.options.max)},_reset:function(){var t=this._map.containerPointToLayerPoint([0,0]);L.DomUtil.setPosition(this._canvas,t);var i=this._map.getSize();this._heat._width!==i.x&&(this._canvas.width=this._heat._width=i.x),this._heat._height!==i.y&&(this._canvas.height=this._heat._height=i.y),this._redraw()},_redraw:function(){var t,i,a,s,e,n,h,o,r,d=[],_=this._heat._r,l=this._map.getSize(),m=new L.Bounds(L.point([-_,-_]),l.add([_,_])),c=void 0===this.options.max?1:this.options.max,u=void 0===this.options.maxZoom?this._map.getMaxZoom():this.options.maxZoom,f=1/Math.pow(2,Math.max(0,Math.min(u-this._map.getZoom(),12))),g=4,p=[],v=this._map._getMapPanePos(),w=v.x%g,y=v.y%g;for(t=0,i=this._latlngs.length;i>t;t++)if(a=this._map.latLngToContainerPoint(this._latlngs[t]),m.contains(a)){e=Math.floor((a.x-w)/g)+2,n=Math.floor((a.y-y)/g)+2;var x=void 0!==this._latlngs[t].alt?this._latlngs[t].alt:void 0!==this._latlngs[t][2]?+this._latlngs[t][2]:1;r=x*f,p[n]=p[n]||[],s=p[n][e],s?(s[0]=(s[0]*s[2]+a.x*r)/(s[2]+r),s[1]=(s[1]*s[2]+a.y*r)/(s[2]+r),s[2]+=r):p[n][e]=[a.x,a.y,r]}for(t=0,i=p.length;i>t;t++)if(p[t])for(h=0,o=p[t].length;o>h;h++)s=p[t][h],s&&d.push([Math.round(s[0]),Math.round(s[1]),Math.min(s[2],c)]);this._heat.data(d).draw(this.options.minOpacity),this._frame=null},_animateZoom:function(t){var i=this._map.getZoomScale(t.zoom),a=this._map._getCenterOffset(t.center)._multiplyBy(-i).subtract(this._map._getMapPanePos());L.DomUtil.setTransform?L.DomUtil.setTransform(this._canvas,a,i):this._canvas.style[L.DomUtil.TRANSFORM]=L.DomUtil.getTranslateString(a)+" scale("+i+")"}}),L.heatLayer=function(t, i){return new L.HeatLayer(t,i)}; -------------------------------------------------------------------------------- /dist/portal-highlighter-uniques-opacity.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @id iitc-plugin-portal-highlighter-uniques-opacity@xificurk 3 | // @name IITC plugin: Highlight unique visits/captures using opacity 4 | // @category Highlighter 5 | // @version 0.2.1.20230304.150308 6 | // @namespace https://github.com/xificurk/iitc-plugins 7 | // @updateURL https://raw.githubusercontent.com/xificurk/iitc-plugins/master/dist/portal-highlighter-uniques-opacity.meta.js 8 | // @downloadURL https://raw.githubusercontent.com/xificurk/iitc-plugins/master/dist/portal-highlighter-uniques-opacity.user.js 9 | // @description [xificurk-2023-03-04-150308] Use stroke and fill opacity to denote player's unique visits and captures. Requires uniques plugin. 10 | // @include https://intel.ingress.com/* 11 | // @include http://intel.ingress.com/* 12 | // @match https://intel.ingress.com/* 13 | // @match http://intel.ingress.com/* 14 | // @include https://*.ingress.com/intel* 15 | // @include http://*.ingress.com/intel* 16 | // @match https://*.ingress.com/intel* 17 | // @match http://*.ingress.com/intel* 18 | // @include https://*.ingress.com/mission/* 19 | // @include http://*.ingress.com/mission/* 20 | // @match https://*.ingress.com/mission/* 21 | // @match http://*.ingress.com/mission/* 22 | // @grant none 23 | // ==/UserScript== 24 | 25 | 26 | function wrapper(plugin_info) { 27 | // ensure plugin framework is there, even if iitc is not yet loaded 28 | if(typeof window.plugin !== 'function') window.plugin = function() {}; 29 | 30 | //PLUGIN AUTHORS: writing a plugin outside of the IITC build environment? if so, delete these lines!! 31 | //(leaving them in place might break the 'About IITC' page or break update checks) 32 | plugin_info.buildName = 'xificurk'; 33 | plugin_info.dateTimeVersion = '20230304.150308'; 34 | plugin_info.pluginId = 'portal-highlighter-uniques-opacity'; 35 | //END PLUGIN AUTHORS NOTE 36 | 37 | 38 | //PLUGIN START //////////////////////////////////////////////////////// 39 | 40 | 41 | //use own namespace for plugin 42 | window.plugin.portalHighlighterUniquesOpacity = function () {}; 43 | 44 | 45 | window.plugin.portalHighlighterUniquesOpacity.highlight = function(data, styles) { 46 | var portalData = data.portal.options.ent[2] 47 | var uniqueInfo = null; 48 | 49 | if (portalData[18]) { 50 | uniqueInfo = { 51 | captured: ((portalData[18] & 0b10) !== 0), 52 | visited: ((portalData[18] & 0b11) !== 0) 53 | }; 54 | } 55 | 56 | var style = {}; 57 | 58 | if(uniqueInfo) { 59 | if(uniqueInfo.captured) { 60 | // captured (and, implied, visited too) - hide 61 | style = styles.captured; 62 | 63 | } else if(uniqueInfo.visited) { 64 | style = styles.visited; 65 | } 66 | } else { 67 | // no visit data at all 68 | style = styles.unvisited; 69 | } 70 | 71 | data.portal.setStyle(style); 72 | } 73 | 74 | 75 | window.plugin.portalHighlighterUniquesOpacity.highlighter = { 76 | highlight: function(data) { 77 | window.plugin.portalHighlighterUniquesOpacity.highlight( 78 | data, 79 | { 80 | captured: { 81 | fillOpacity: 0, 82 | opacity: 0.25, 83 | }, 84 | visited: { 85 | fillOpacity: 0.2, 86 | opacity: 1, 87 | }, 88 | unvisited: { 89 | fillOpacity: 0.8, 90 | opacity: 1, 91 | }, 92 | } 93 | ); 94 | } 95 | } 96 | 97 | window.plugin.portalHighlighterUniquesOpacity.highlighterInverted = { 98 | highlight: function(data) { 99 | window.plugin.portalHighlighterUniquesOpacity.highlight( 100 | data, 101 | { 102 | captured: { 103 | fillOpacity: 0.8, 104 | opacity: 1, 105 | }, 106 | visited: { 107 | fillOpacity: 0.2, 108 | opacity: 1, 109 | }, 110 | unvisited: { 111 | fillOpacity: 0, 112 | opacity: 0.25, 113 | }, 114 | } 115 | ); 116 | } 117 | } 118 | 119 | 120 | var setup = function() { 121 | window.addPortalHighlighter('Uniques (opacity)', window.plugin.portalHighlighterUniquesOpacity.highlighter); 122 | window.addPortalHighlighter('Uniques (opacity inverted)', window.plugin.portalHighlighterUniquesOpacity.highlighterInverted); 123 | } 124 | 125 | //PLUGIN END ////////////////////////////////////////////////////////// 126 | 127 | 128 | setup.info = plugin_info; //add the script info data to the function as a property 129 | if(!window.bootPlugins) window.bootPlugins = []; 130 | window.bootPlugins.push(setup); 131 | // if IITC has already booted, immediately run the 'setup' function 132 | if(window.iitcLoaded && typeof setup === 'function') setup(); 133 | } // wrapper end 134 | // inject code into site context 135 | var script = document.createElement('script'); 136 | var info = {}; 137 | if (typeof GM_info !== 'undefined' && GM_info && GM_info.script) info.script = { version: GM_info.script.version, name: GM_info.script.name, description: GM_info.script.description }; 138 | script.appendChild(document.createTextNode('('+ wrapper +')('+JSON.stringify(info)+');')); 139 | (document.body || document.head || document.documentElement).appendChild(script); 140 | 141 | 142 | -------------------------------------------------------------------------------- /plugins/uniques-heatmap.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @id iitc-plugin-uniques-heatmap@xificurk 3 | // @name IITC plugin: Unique visits/captures heatmap 4 | // @category Layer 5 | // @version 0.2.1.@@DATETIMEVERSION@@ 6 | // @namespace https://github.com/xificurk/iitc-plugins 7 | // @updateURL @@UPDATEURL@@ 8 | // @downloadURL @@DOWNLOADURL@@ 9 | // @description [@@BUILDNAME@@-@@BUILDDATE@@] Display heatmap of all portals that the player did NOT visit/capture. Requires uniques plugin. 10 | // @include https://intel.ingress.com/* 11 | // @include http://intel.ingress.com/* 12 | // @match https://intel.ingress.com/* 13 | // @match http://intel.ingress.com/* 14 | // @include https://*.ingress.com/intel* 15 | // @include http://*.ingress.com/intel* 16 | // @match https://*.ingress.com/intel* 17 | // @match http://*.ingress.com/intel* 18 | // @include https://*.ingress.com/mission/* 19 | // @include http://*.ingress.com/mission/* 20 | // @match https://*.ingress.com/mission/* 21 | // @match http://*.ingress.com/mission/* 22 | // @grant none 23 | // ==/UserScript== 24 | 25 | @@PLUGINSTART@@ 26 | //PLUGIN START //////////////////////////////////////////////////////// 27 | 28 | 29 | //use own namespace for plugin 30 | window.plugin.uniquesHeatmap = function() {}; 31 | 32 | window.plugin.uniquesHeatmap.original_highlighter = window._no_highlighter; 33 | 34 | window.plugin.uniquesHeatmap.HEAT_RADIUS = 60; 35 | window.plugin.uniquesHeatmap.HEAT_BLUR = 90; 36 | window.plugin.uniquesHeatmap.HEAT_MAX_ZOOM = 17; 37 | 38 | 39 | window.plugin.uniquesHeatmap.hidePortalsHightlighter = { 40 | highlight: function(data) { 41 | data.portal.setStyle({ 42 | opacity: 0, 43 | fillOpacity: 0 44 | }); 45 | } 46 | } 47 | 48 | 49 | window.plugin.uniquesHeatmap.updateHeatmap = function(layer) { 50 | 51 | // as this is called every time layers are toggled, there's no point in doing it when the layer is off 52 | if(!map.hasLayer(layer)) { 53 | if(window._current_highlighter === 'Hide portals' && !map.hasLayer(window.plugin.uniquesHeatmap.explorerHeatLayer) && !map.hasLayer(window.plugin.uniquesHeatmap.pioneerHeatLayer)) { 54 | $('#portal_highlight_select').val(window.plugin.uniquesHeatmap.original_highlighter).trigger('change'); 55 | } 56 | return; 57 | } 58 | 59 | if(window._current_highlighter !== 'Hide portals') { 60 | window.plugin.uniquesHeatmap.original_highlighter = window._current_highlighter; 61 | $('#portal_highlight_select').val('Hide portals').trigger('change'); 62 | } 63 | 64 | var points = []; 65 | for(var guid in window.portals) { 66 | var p = window.portals[guid]; 67 | var portalData = p.options.ent[2] 68 | var uniqueInfo = null; 69 | 70 | if (portalData[18]) { 71 | uniqueInfo = { 72 | captured: ((portalData[18] & 0b10) !== 0), 73 | visited: ((portalData[18] & 0b11) !== 0) 74 | }; 75 | } 76 | 77 | if(p._map && (!uniqueInfo || !uniqueInfo.visited || (layer === window.plugin.uniquesHeatmap.pioneerHeatLayer && !uniqueInfo.captured))) { 78 | points.push(p.getLatLng()); 79 | } 80 | } 81 | 82 | layer.setLatLngs(points); 83 | 84 | } 85 | 86 | 87 | // as calculating heatmap can take some time when there's lots of portals shown, we'll do it on 88 | // a short timer. this way it doesn't get repeated so much 89 | window.plugin.uniquesHeatmap.delayedUpdateHeatmap = function(layer, wait) { 90 | if(window.plugin.uniquesHeatmap.timer === undefined) { 91 | window.plugin.uniquesHeatmap.timer = setTimeout(function() { 92 | window.plugin.uniquesHeatmap.timer = undefined; 93 | window.plugin.uniquesHeatmap.updateHeatmap(window.plugin.uniquesHeatmap.pioneerHeatLayer); 94 | window.plugin.uniquesHeatmap.updateHeatmap(window.plugin.uniquesHeatmap.explorerHeatLayer); 95 | }, wait * 1000); 96 | } 97 | } 98 | 99 | 100 | var setup = function() { 101 | // Load leaflet-heat.js 102 | // Note: It seems that on mobile the plugin is loaded before leaflet code, so we need to load leaflet-heat.js here in setup. 103 | @@INCLUDERAW:external/leaflet-heat.js@@ 104 | 105 | // Fix Heatmap layer z-index 106 | $("