NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @namespace https://openuserjs.org/users/SadBubFurry // @name Getting Started with a User Script // @description SadBubFurry // @version 0.0.3 // @license MIT // @include https://www.example.com/* // ==/UserScript== // ==OpenUserJS== // @author SadBubFurry // ==/OpenUserJS== /** * * Please begin typing or paste your User script now. * */ "use strict"; function excludePokemon(e) { $selectExclude.val($selectExclude.val().concat(e)).trigger("change") } function notifyAboutPokemon(e) { $selectPokemonNotify.val($selectPokemonNotify.val().concat(e)).trigger("change") } function removePokemonMarker(e) { mapData.pokemons[e].marker.rangeCircle && (mapData.pokemons[e].marker.rangeCircle.setMap(null), delete mapData.pokemons[e].marker.rangeCircle), mapData.pokemons[e].marker.setMap(null), mapData.pokemons[e].hidden = !0 } function initMap() { console.log("locname: " + locname); var e = 0; $.ajax({ url: "static/data/cords.json", dataType: "json", async: !1, success: function t(a) { for (var o = 0, n = a.length; o < n; o++) if (a[o].regio == locname) { centerLat = a[o].lat, centerLng = a[o].long, console.log(locname + " gevonden:"), e = 1; break } } }), 1 != e && console.log("stad : " + locname + " niet gevonden!"), centerLat = parseFloat(centerLat), centerLng = parseFloat(centerLng), map = new google.maps.Map(document.getElementById("map"), { center: { lat: centerLat, lng: centerLng }, zoom: null == zoom ? Store.get("zoomLevel") : zoom, minZoom: minZoom, fullscreenControl: !0, streetViewControl: !1, mapTypeControl: !1, clickableIcons: !1, mapTypeControlOptions: { style: google.maps.MapTypeControlStyle.DROPDOWN_MENU, position: google.maps.ControlPosition.RIGHT_TOP, mapTypeIds: [google.maps.MapTypeId.ROADMAP, google.maps.MapTypeId.SATELLITE, google.maps.MapTypeId.HYBRID, "nolabels_style", "dark_style", "style_light2", "style_pgo", "dark_style_nl", "style_light2_nl", "style_pgo_nl", "style_pgo_day", "style_pgo_night", "style_pgo_dynamic"] } }); var t = new google.maps.StyledMapType(noLabelsStyle, { name: "No Labels" }); map.mapTypes.set("nolabels_style", t); var a = new google.maps.StyledMapType(darkStyle, { name: "Dark" }); map.mapTypes.set("dark_style", a); var o = new google.maps.StyledMapType(light2Style, { name: "Light2" }); map.mapTypes.set("style_light2", o); var n = new google.maps.StyledMapType(pGoStyle, { name: "PokemonGo" }); map.mapTypes.set("style_pgo", n); var i = new google.maps.StyledMapType(darkStyleNoLabels, { name: "Dark (No Labels)" }); map.mapTypes.set("dark_style_nl", i); var s = new google.maps.StyledMapType(light2StyleNoLabels, { name: "Light2 (No Labels)" }); map.mapTypes.set("style_light2_nl", s); var r = new google.maps.StyledMapType(pGoStyleNoLabels, { name: "PokemonGo (No Labels)" }); map.mapTypes.set("style_pgo_nl", r); var l = new google.maps.StyledMapType(pGoStyleDay, { name: "PokemonGo Day" }); map.mapTypes.set("style_pgo_day", l); var d = new google.maps.StyledMapType(pGoStyleNight, { name: "PokemonGo Night" }); map.mapTypes.set("style_pgo_night", d); var c = (new Date).getHours(), m = c >= 6 && c < 19 ? l : d; map.mapTypes.set("style_pgo_dynamic", m), map.addListener("maptypeid_changed", function(e) { Store.set("map_style", this.mapTypeId) }), map.setMapTypeId(Store.get("map_style")), map.addListener("idle", updateMap), map.addListener("zoom_changed", function() { !0 === storeZoom ? Store.set("zoomLevel", this.getZoom()) : storeZoom = !0, redrawPokemon(mapData.pokemons), redrawPokemon(mapData.lurePokemons) }), createMyLocationButton(), initSidebar() } function updateLocationMarker(e) { return e in searchMarkerStyles && (locationMarker.setIcon(searchMarkerStyles[e].icon), Store.set("locationMarkerStyle", e)), locationMarker } function createLocationMarker() { var e = Store.get("followMyLocationPosition"), t = "lat" in e ? e.lat : centerLat, a = "lng" in e ? e.lng : centerLng, o = new google.maps.Marker({ map: map, animation: google.maps.Animation.DROP, position: { lat: t, lng: a }, draggable: !1, icon: null, optimized: !1, zIndex: google.maps.Marker.MAX_ZINDEX + 2 }); return o.setIcon(searchMarkerStyles[Store.get("locationMarkerStyle")].icon), o.infoWindow = new google.maps.InfoWindow({ content: "<div><b>My Location</b></div>", disableAutoPan: !0 }), addListeners(o), google.maps.event.addListener(o, "dragend", function() { var e = o.getPosition(); Store.set("followMyLocationPosition", { lat: e.lat(), lng: e.lng() }) }), o } function initSidebar() { if ($("#gyms-switch").prop("checked", Store.get("showGyms")), $("#gym-sidebar-switch").prop("checked", Store.get("useGymSidebar")), $("#gyms-filter-wrapper").toggle(Store.get("showGyms")), $("#team-gyms-only-switch").val(Store.get("showTeamGymsOnly")), $("#open-gyms-only-switch").prop("checked", Store.get("showOpenGymsOnly")), $("#raids-switch").prop("checked", Store.get("showRaids")), $("#raids-filter-wrapper").toggle(Store.get("showRaids")), $("#min-level-gyms-filter-switch").val(Store.get("minGymLevel")), $("#max-level-gyms-filter-switch").val(Store.get("maxGymLevel")), $("#min-level-raids-filter-switch").val(Store.get("minRaidLevel")), $("#max-level-raids-filter-switch").val(Store.get("maxRaidLevel")), $("#last-update-gyms-switch").val(Store.get("showLastUpdatedGymsOnly")), $("#pokemon-switch").prop("checked", Store.get("showPokemon")), $("#pokestops-switch").prop("checked", Store.get("showPokestops")), $("#lured-pokestops-only-switch").val(Store.get("showLuredPokestopsOnly")), $("#lured-pokestops-only-wrapper").toggle(Store.get("showPokestops")), $("#start-at-user-location-switch").prop("checked", Store.get("startAtUserLocation")), $("#start-at-last-location-switch").prop("checked", Store.get("startAtLastLocation")), $("#follow-my-location-switch").prop("checked", Store.get("followMyLocation")), $("#spawn-area-switch").prop("checked", Store.get("spawnArea")), $("#scanned-switch").prop("checked", Store.get("showScanned")), $("#spawnpoints-switch").prop("checked", Store.get("showSpawnpoints")), $("#ranges-switch").prop("checked", Store.get("showRanges")), $("#sound-switch").prop("checked", Store.get("playSound")), document.getElementById("next-location")) { var e = new google.maps.places.Autocomplete(document.getElementById("next-location")); $("#next-location").css("background-color", $("#geoloc-switch").prop("checked") ? "#e0e0e0" : "#ffffff"), e.addListener("place_changed", function() { var t = e.getPlace(); if (t.geometry) { var a = t.geometry.location; changeLocation(a.lat(), a.lng()) } }) } var t = $("#pokemon-icons"); $.each(pokemonSprites, function(e, a) { t.append($("<option></option>").attr("value", e).text(a.name)) }), t.val(pokemonSprites[Store.get("pokemonIcons")] ? Store.get("pokemonIcons") : "highres"), $("#pokemon-icon-size").val(Store.get("iconSizeModifier")) } function pad(e) { return e <= 99 ? ("0" + e).slice(-2) : e } function getTypeSpan(e) { return '<span style="padding: 2px 5px; text-transform: uppercase; color: white; margin-right: 2px; border-radius: 4px; font-size: 0.8em; vertical-align: text-bottom; background-color: ' + e.color + ';">' + e.type + "</span>" } function openMapDirections(e, t) { var a = "https://www.google.com/maps/?daddr=" + e + "," + t; window.open(a, "_blank") } function getDateStr(e) { var t = "Unknown"; return e && (t = moment(e).format("DD-MM-YYYY, HH:mm:ss")), t } function getTimeStr(e) { var t = "Unknown"; return e && (t = moment(e).format("HH:mm:ss")), t } function toggleOtherPokemon(e) { 0 === (onlyPokemon = 0 === onlyPokemon ? e : 0) ? (lastpokemon = !1, updateMap()) : clearStaleMarkers() } function isTemporaryHidden(e) { return 0 !== onlyPokemon && e !== onlyPokemon } function pokemonLabel(e) { var t = e.pokemon_name, a = e.pokemon_rarity ? "(" + e.pokemon_rarity + ")" : "", o = e.pokemon_types, n = "", i = e.encounter_id, s = e.pokemon_id, r = e.latitude, l = e.longitude, d = e.disappear_time, c = new Date(d), m = e.individual_attack, p = e.individual_defense, g = e.individual_stamina, u = void 0 !== moves[e.move_1] ? i8ln(moves[e.move_1].name) : "gen/unknown", y = void 0 !== moves[e.move_2] ? i8ln(moves[e.move_2].name) : "gen/unknown", v = e.weight, k = e.height, f = e.gender, h = e.form, w = e.cp, _ = e.cp_multiplier, S = e.level; $.each(o, function(e, t) { n += getTypeSpan(t) }); var M = ""; if (null != w) { if (M = "<div>IV: " + getIv(m, p, g).toFixed(1) + "% (" + m + "/" + p + "/" + g + ")</div>", null != w && (null != _ || null != S)) { var L; M += "<div>CP: " + w + " | Level: " + (L = null != S ? S : getPokemonLevel(_)) + "</div>" } M += "<div>Moves: " + u + " / " + y + "</div>" } null != f && (M += "<div>Gender: " + genderType[f - 1], null != v && null != k && (M += " | Weight: " + v.toFixed(2) + "kg | Height: " + k.toFixed(2) + "m"), M += "</div>"); var b = "<div><b>" + t + "</b>"; return 201 === s && null !== h && h > 0 && (b += " (" + unownForm[e.form] + ")"), b += '<span> - </span><small><a href="https://pokemon.gameinfo.io/en/pokemon/' + s + '" target="_blank" title="View in Pokedex">#' + s + "</a></small><span> " + a + "</span><span> - </span><small>" + n + "</small></div><div>Disappears at " + pad(c.getHours()) + ":" + pad(c.getMinutes()) + ":" + pad(c.getSeconds()) + '<span class="label-countdown" disappears-at="' + d + '">(00m00s)</span></div><div>Location: <a href="javascript:void(0)" onclick="javascript:openMapDirections(' + r + ", " + l + ')" title="View in Maps">' + r.toFixed(6) + ", " + l.toFixed(7) + "</a></div>" + M + '<div><a href="javascript:excludePokemon(' + s + ')">Exclude</a>  <a href="javascript:notifyAboutPokemon(' + s + ')">Notify</a>  <a href="javascript:removePokemonMarker(\'' + i + '\')">Remove</a>  <a href="javascript:void(0);" onclick="javascript:toggleOtherPokemon(' + s + ');" title="Toggle display of other Pokemon">Toggle Others</a></div>' } function gymLabel(e) { var t = gymTypes[e.team_id], a = e.team_id, o = e.latitude, n = e.longitude, i = e.last_scanned, s = e.last_modified, r = e.name, l = e.pokemon, d = null != e.raid_level, c = null != e.raid_pokemon_id, m = "", p = ""; if (d && e.raid_end > Date.now()) { var g = ""; for (k = 0; k < e.raid_level; k++) g += "★"; if (m = '<h3 style="margin-bottom: 0">Raid ' + g, c) { var u = ""; null != e.raid_pokemon_cp && (u = " CP " + e.raid_pokemon_cp), m += "<br>" + e.raid_pokemon_name + u } if (m += "</h3>", c && null != e.raid_pokemon_move_1 && null != e.raid_pokemon_move_2 && (m += "<div><b>" + (void 0 !== moves[e.raid_pokemon_move_1] ? i8ln(moves[e.raid_pokemon_move_1].name) : "gen/unknown") + " / " + (void 0 !== moves[e.raid_pokemon_move_2] ? i8ln(moves[e.raid_pokemon_move_2].name) : "gen/unknown") + "</b></div>"), m += '<div style="margin-bottom: 10px">Time: <b>' + getTimeStr(e.raid_start) + "</b> - <b>" + getTimeStr(e.raid_end) + "</b></div>", c) p = '<i class="pokemon-large-sprite n' + e.raid_pokemon_id + '"></i>'; else { var y = ""; p = '<img src="static/raids/egg_' + (y = e.raid_level <= 2 ? "normal" : e.raid_level <= 4 ? "rare" : "legendary") + '.png">' } } for (var v = "", k = 0; k < l.length; k++) v += '<span class="gym-member" title="' + l[k].pokemon_name + " | " + l[k].trainer_name + " (Lvl " + l[k].trainer_level + ')"><i class="pokemon-sprite n' + l[k].pokemon_id + '"></i><span class="cp team-' + a + '">' + l[k].pokemon_cp + "</span></span>"; var f = ""; null != i && (f = "<div>Last Scanned: " + getDateStr(i) + "</div>"); var h = getDateStr(s), w = r ? "<div>" + r + "</div>" : "", _ = ["0, 0, 0, .4", "74, 138, 202, .6", "240, 68, 58, .6", "254, 217, 40, .6"], S; if (0 === a) S = '<div><center><div><b style="color:rgba(' + _[a] + ')">' + t + '</b><br><img height="70px" style="padding: 5px;" src="static/forts/' + t + '_large.png">' + p + "</div>" + w + m + '<div>Location: <a href="javascript:void(0);" onclick="javascript:openMapDirections(' + o + "," + n + ');" title="View in Maps">' + o.toFixed(6) + " , " + n.toFixed(7) + "</a></div><div>" + f + "</div><div>Last Modified: " + h + "</div></center></div>"; else { var M = e.slots_available, L = ""; null != e.total_gym_cp && (L = "<div>Total Gym CP: <b>" + e.total_gym_cp + "</b></div>"), S = '<div><center><div style="padding-bottom: 2px">Gym owned by:</div><div><b style="color:rgba(' + _[a] + ')">Team ' + t + '</b><br><img height="70px" style="padding: 5px;" src="static/forts/' + t + '_large.png">' + p + "</div>" + w + m + "<div><b>" + M + " Free Slots</b></div>" + L + "<div>" + v + '</div><div>Location: <a href="javascript:void(0);" onclick="javascript:openMapDirections(' + o + "," + n + ');" title="View in Maps">' + o.toFixed(6) + " , " + n.toFixed(7) + "</a></div><div>" + f + "</div><div>Last Modified: " + h + "</div></center></div>" } return S } function pokestopLabel(e, t, a) { var o; if (e) { var n = new Date(e); o = "<div><b>Lured Pokéstop</b></div><div>Lure expires at " + pad(n.getHours()) + ":" + pad(n.getMinutes()) + ":" + pad(n.getSeconds()) + '<span class="label-countdown" disappears-at="' + e + '">(00m00s)</span></div><div>Location: <a href="javascript:void(0)" onclick="javascript:openMapDirections(' + t + "," + a + ')" title="View in Maps">' + t.toFixed(6) + ", " + a.toFixed(7) + "</a></div>" } else o = '<div><b>Pokéstop</b></div><div>Location: <a href="javascript:void(0)" onclick="javascript:openMapDirections(' + t + "," + a + ')" title="View in Maps">' + t.toFixed(6) + ", " + a.toFixed(7) + "</a></div>"; return o } function formatSpawnTime(e) { return ("0" + Math.floor((e + 3600) % 3600 / 60)).substr(-2) + ":" + ("0" + e % 60).substr(-2) } function spawnpointLabel(e) { var t = "<div><b>Spawn Point</b></div><div>Every hour from " + formatSpawnTime(e.time) + " to " + formatSpawnTime(e.time + 900) + "</div>"; return e.special && (t += "<div>May appear as early as " + formatSpawnTime(e.time - 1800) + "</div>"), t } function addRangeCircle(e, t, a, o) { var n = null, i = new google.maps.LatLng(e.position.lat(), e.position.lng()), s = ["#999999", "#0051CF", "#FF260E", "#FECC23"], r = s[0]; o && (r = s[o]); var l, d; switch (a) { case "pokemon": d = "#C233F2", l = 40; break; case "pokestop": d = "#3EB0FF", l = 40; break; case "gym": d = r, l = 40 } t && (n = t); var c = { map: n, radius: l, strokeWeight: 1, strokeColor: d, strokeOpacity: .9, center: i, fillColor: d, fillOpacity: .3 }; return new google.maps.Circle(c) } function isRangeActive(e) { return !(e.getZoom() < 16) && Store.get("showRanges") } function getIv(e, t, a) { return null !== e && 100 * (e + t + a) / 45 } function getPokemonLevel(e) { if (e < .734) var t = 58.35178527 * e * e - 2.838007664 * e + .8539209906; else t = 171.0112688 * e - 95.20425243; return t = 2 * Math.round(t) / 2 } function lpad(e, t, a) { return Array(Math.max(t - String(e).length + 1, 0)).join(a) + e } function repArray(e, t, a) { for (var o = 0; o < t.length; o++) e = e.replace(t[o], a[o]); return e } function getTimeUntil(e) { var t = +new Date, a = e - t, o = Math.floor(a / 1e3 % 60), n = Math.floor(a / 1e3 / 60 % 60); return { total: a, hour: Math.floor(a / 36e5 % 24), min: n, sec: o, now: t, ttime: e } } function getNotifyText(e) { var t = getIv(e.individual_attack, e.individual_defense, e.individual_stamina), a = ["<prc>", "<pkm>", "<atk>", "<def>", "<sta>"], o = [t ? t.toFixed(1) : "", e.pokemon_name, e.individual_attack, e.individual_defense, e.individual_stamina], n = repArray(t ? notifyIvTitle : notifyNoIvTitle, a, o), i = new Date(e.disappear_time).toLocaleString([], { hour: "2-digit", minute: "2-digit", second: "2-digit", hour12: !1 }), s = getTimeUntil(e.disappear_time), r = s.hour > 0 ? s.hour + ":" : ""; return r += lpad(s.min, 2, 0) + "m" + lpad(s.sec, 2, 0) + "s", { fav_title: n, fav_text: repArray(notifyText, a = ["<dist>", "<udist>"], o = [i, r]) } } function customizePokemonMarker(e, t, a) { if (e.addListener("click", function() { this.setAnimation(null), this.animationDisabled = !0 }), !e.rangeCircle && isRangeActive(map) && (e.rangeCircle = addRangeCircle(e, map, "pokemon")), e.infoWindow = new google.maps.InfoWindow({ content: pokemonLabel(t), disableAutoPan: !0 }), (notifiedPokemon.indexOf(t.pokemon_id) > -1 || notifiedRarity.indexOf(t.pokemon_rarity) > -1) && (a || (Store.get("playSound") && audio.play(), sendNotification(getNotifyText(t).fav_title, getNotifyText(t).fav_text, "static/icons/" + t.pokemon_id + ".png", t.latitude, t.longitude)), !0 !== e.animationDisabled && e.setAnimation(google.maps.Animation.BOUNCE)), null != t.individual_attack) { var o = getIv(t.individual_attack, t.individual_defense, t.individual_stamina); notifiedMinPerfection > 0 && o >= notifiedMinPerfection && (a || (Store.get("playSound") && audio.play(), sendNotification(getNotifyText(t).fav_title, getNotifyText(t).fav_text, "static/icons/" + t.pokemon_id + ".png", t.latitude, t.longitude)), !0 !== e.animationDisabled && e.setAnimation(google.maps.Animation.BOUNCE)) } addListeners(e) } function getGymMarkerIcon(e) { var t = e.raid_level, a = ""; if (a = 0 === e.team_id ? gymTypes[e.team_id] : gymTypes[e.team_id] + "_" + t, null != e.raid_pokemon_id && e.raid_end > Date.now()) return '<div style="position:relative;"><img src="static/forts/' + Store.get("gymMarkerStyle") + "/" + a + '.png" style="width:55px;height:auto;"/><i class="pokemon-raid-sprite n' + e.raid_pokemon_id + '"></i></div>'; if (null !== e.raid_level && e.raid_end > Date.now()) { var o = ""; return o = e.raid_level <= 2 ? "normal" : e.raid_level <= 4 ? "rare" : "legendary", '<div style="position:relative;"><img src="static/forts/' + Store.get("gymMarkerStyle") + "/" + a + '.png" style="width:55px;height:auto;"/><img src="static/raids/egg_' + o + '.png" style="width:30px;height:auto;position:absolute;top:8px;right:12px;"/></div>' } return '<div><img src="static/forts/' + Store.get("gymMarkerStyle") + "/" + gymTypes[e.team_id] + '.png" style="width:48px;height: auto;"/></div>' } function setupGymMarker(e) { var t = new RichMarker({ position: new google.maps.LatLng(e.latitude, e.longitude), map: map, content: getGymMarkerIcon(e), flat: !0, anchor: RichMarkerPosition.MIDDLE }); !t.rangeCircle && isRangeActive(map) && (t.rangeCircle = addRangeCircle(t, map, "gym", e.team_id)), t.infoWindow = new google.maps.InfoWindow({ content: gymLabel(e), disableAutoPan: !0, pixelOffset: new google.maps.Size(0, -20) }); var a = e.raid_level; if (a >= Store.get("remember_raid_notify") && e.raid_end > Date.now() && 0 !== Store.get("remember_raid_notify")) { Store.get("playSound") && audio.play(); var o = "Raid level: " + a, n = getTimeStr(e.raid_start) + " - " + getTimeStr(e.raid_end), i; if (null != e.raid_pokemon_id) i = "static/icons/" + e.raid_pokemon_id + ".png"; else { var s = ""; i = "static/raids/egg_" + (s = e.raid_level <= 2 ? "normal" : e.raid_level <= 4 ? "rare" : "legendary") + ".png" } sendNotification(o, n, i, e.latitude, e.longitude) } return Store.get("useGymSidebar") ? (t.addListener("click", function() { var t = document.querySelector("#gym-details"); t.getAttribute("data-id") === e.gym_id && t.classList.contains("visible") ? t.classList.remove("visible") : (t.setAttribute("data-id", e.gym_id), showGymDetails(e.gym_id)) }), google.maps.event.addListener(t.infoWindow, "closeclick", function() { t.persist = null }), isMobileDevice() || isTouchDevice() || t.addListener("mouseover", function() { t.infoWindow.open(map, t), clearSelection(), updateLabelDiffTime() }), t.addListener("mouseout", function() { t.persist || t.infoWindow.close() })) : addListeners(t), t } function updateGymMarker(e, t) { t.setContent(getGymMarkerIcon(e)), t.infoWindow.setContent(gymLabel(e)); var a = e.raid_level; if (a >= Store.get("remember_raid_notify") && e.raid_end > Date.now() && 0 !== Store.get("remember_raid_notify")) { var o = mapData.gyms[e.gym_id].raid_pokemon_id; if (e.raid_pokemon_id !== o) { Store.get("playSound") && audio.play(); var n = "Raid level: " + a, i = getTimeStr(e.raid_start) + " - " + getTimeStr(e.raid_end), s; if (null != e.raid_pokemon_id) s = "static/icons/" + e.raid_pokemon_id + ".png"; else { var r = ""; s = "static/raids/egg_" + (r = e.raid_level <= 2 ? "normal" : e.raid_level <= 4 ? "rare" : "legendary") + ".png" } sendNotification(n, i, s, e.latitude, e.longitude) } } return t } function updateGymIcons() { $.each(mapData.gyms, function(e, t) { mapData.gyms[e].marker.setContent(getGymMarkerIcon(mapData.gyms[e])) }) } function setupPokestopMarker(e) { var t = e.lure_expiration ? "PstopLured" : "Pstop", a = new google.maps.Marker({ position: { lat: e.latitude, lng: e.longitude }, map: map, zIndex: 2, icon: "static/forts/" + t + ".png" }); return !a.rangeCircle && isRangeActive(map) && (a.rangeCircle = addRangeCircle(a, map, "pokestop")), a.infoWindow = new google.maps.InfoWindow({ content: pokestopLabel(e.lure_expiration, e.latitude, e.longitude), disableAutoPan: !0 }), addListeners(a), a } function getColorByDate(e) { var t = (Date.now() - e) / 1e3 / 60 / 15; return t > 1 && (t = 1), ["hsl(", (120 * (1 - t)).toString(10), ",100%,50%)"].join("") } function setupScannedMarker(e) { var t = new google.maps.LatLng(e.latitude, e.longitude); return new google.maps.Circle({ map: map, clickable: !1, center: t, radius: 70, fillColor: getColorByDate(e.last_modified), fillOpacity: .1, strokeWeight: 1, strokeOpacity: .5 }) } function getColorBySpawnTime(e) { var t = new Date, a = 60 * t.getMinutes() + t.getSeconds(); a < 900 && e > 2700 ? a += 3600 : a > 2700 && e < 900 && (e += 3600); var o = a - e, n = 275; return o >= 0 && o <= 900 ? n = 120 * (1 - o / 60 / 15) : o < 0 && o > -300 && (n = 50 * (1 - -o / 60 / 5) + 200), n = 5 * Math.round(n / 5) } function changeSpawnIcon(e, t) { var a = ""; a = 275 === e ? "./static/icons/hsl-275-light.png" : "./static/icons/hsl-" + e + ".png"; var o = 1.6, n = 1, i = Math.round(1.6 * (t - 10)); return i < 1 && (i = 1), { url: a, scaledSize: new google.maps.Size(i, i), anchor: new google.maps.Point(i / 2, i / 2) } } function spawnPointIndex(e) { var t = 1, a = 0; return e >= 0 && e <= 120 ? t = 100 + 100 * (a = e / 120) : e >= 200 && e <= 250 && (t = 100 * (a = (e - 200) / 50)), t } function setupSpawnpointMarker(e) { var t = new google.maps.LatLng(e.latitude, e.longitude), a = getColorBySpawnTime(e.time), o = map.getZoom(), n = new google.maps.Marker({ map: map, position: t, icon: changeSpawnIcon(a, o), zIndex: spawnPointIndex(a) }); return n.infoWindow = new google.maps.InfoWindow({ content: spawnpointLabel(e), disableAutoPan: !0, position: t }), addListeners(n), n } function clearSelection() { document.selection ? document.selection.empty() : window.getSelection && window.getSelection().removeAllRanges() } function addListeners(e) { return e.addListener("click", function() { e.infoWindowIsOpen ? (e.persist = null, e.infoWindow.close(), e.infoWindowIsOpen = !1) : (e.infoWindow.open(map, e), clearSelection(), updateLabelDiffTime(), e.persist = !0, e.infoWindowIsOpen = !0) }), google.maps.event.addListener(e.infoWindow, "closeclick", function() { e.persist = null }), isMobileDevice() || isTouchDevice() || e.addListener("mouseover", function() { e.infoWindow.open(map, e), clearSelection(), updateLabelDiffTime() }), e.addListener("mouseout", function() { e.persist || e.infoWindow.close() }), e } function clearStaleMarkers() { $.each(mapData.pokemons, function(e, t) { (mapData.pokemons[e].disappear_time < (new Date).getTime() || excludedPokemon.indexOf(mapData.pokemons[e].pokemon_id) >= 0 || isTemporaryHidden(mapData.pokemons[e].pokemon_id)) && (mapData.pokemons[e].marker.rangeCircle && (mapData.pokemons[e].marker.rangeCircle.setMap(null), delete mapData.pokemons[e].marker.rangeCircle), mapData.pokemons[e].marker.setMap(null), delete mapData.pokemons[e]) }), $.each(mapData.lurePokemons, function(e, t) { (mapData.lurePokemons[e].lure_expiration < (new Date).getTime() || excludedPokemon.indexOf(mapData.lurePokemons[e].pokemon_id) >= 0) && (mapData.lurePokemons[e].marker.setMap(null), delete mapData.lurePokemons[e]) }), $.each(mapData.scanned, function(e, t) { mapData.scanned[e].last_modified < (new Date).getTime() - 9e5 && (mapData.scanned[e].marker.setMap(null), delete mapData.scanned[e]) }) } function showInBoundsMarkers(e, t) { $.each(e, function(a, o) { var n = e[a].marker, i = !1; e[a].hidden || ("function" == typeof n.getBounds ? map.getBounds().intersects(n.getBounds()) && (i = !0) : "function" == typeof n.getPosition && map.getBounds().contains(n.getPosition()) && (i = !0)), i && -1 !== rangeMarkers.indexOf(t) && (n.rangeCircle ? isRangeActive(map) ? n.rangeCircle.setMap(map) : n.rangeCircle.setMap(null) : isRangeActive(map) && (n.rangeCircle = "gym" === t ? addRangeCircle(n, map, t, e[a].team_id) : addRangeCircle(n, map, t))), i && !n.getMap() ? (n.setMap(map), n.setAnimation && n.oldAnimation && n.setAnimation(n.oldAnimation)) : !i && n.getMap() && (n.getAnimation && (n.oldAnimation = n.getAnimation()), n.rangeCircle && n.rangeCircle.setMap(null), n.setMap(null)) }) } function loadRawData() { var e = Store.get("showPokemon"), t = Store.get("showGyms") || Store.get("showRaids") ? "true" : "false", a = Store.get("showPokestops"), o = Store.get("showScanned"), n = Store.get("showSpawnpoints"), i = Boolean(Store.get("showLuredPokestopsOnly")), s = map.getBounds(), r = s.getSouthWest(), l = s.getNorthEast(), d = r.lat(), c = r.lng(), m = l.lat(), p = l.lng(); return $.ajax({ url: "raw_data", type: "GET", timeout: 3e5, data: { timestamp: timestamp, pokemon: e, lastpokemon: lastpokemon, pokestops: a, lastpokestops: lastpokestops, luredonly: i, gyms: t, lastgyms: lastgyms, scanned: o, lastslocs: lastslocs, spawnpoints: n, lastspawns: lastspawns, swLat: d, swLng: c, neLat: m, neLng: p, oSwLat: oSwLat, oSwLng: oSwLng, oNeLat: oNeLat, oNeLng: oNeLng, reids: String(reincludedPokemon), eids: String(excludedPokemon) }, dataType: "json", cache: !1, beforeSend: function e() { if (rawDataIsLoading) return !1; rawDataIsLoading = !0 }, error: function e() { toastr.error("Please check connectivity or reduce marker settings.", "Error getting data"), toastr.options = { closeButton: !0, debug: !1, newestOnTop: !0, progressBar: !1, positionClass: "toast-top-right", preventDuplicates: !0, onclick: null, showDuration: "300", hideDuration: "1000", timeOut: "25000", extendedTimeOut: "1000", showEasing: "swing", hideEasing: "linear", showMethod: "fadeIn", hideMethod: "fadeOut" } }, complete: function e() { rawDataIsLoading = !1 } }) } function isInteresting (p) { var iv = p.individual_attack + p.individual_defense + p.individual_stamina; var interestingId = [106, 107, 113, 130, 131, 142, 143, 149, 201, 237, 242, 246, 247, 248]; if (iv == 45) return true; if (iv >= 43 && p.level >= 20) return true; if (iv >= 40 && p.level >= 25) return true; if (iv >= 37 && p.level >= 30) return true; if (interestingId.indexOf(p.pokemon_id) >= 0) return true; return false; } function processPokemons(e, t) { if (!Store.get("showPokemon")) return !1; !(t.encounter_id in mapData.pokemons) && excludedPokemon.indexOf(t.pokemon_id) < 0 && isInteresting(t) && t.disappear_time > Date.now() && !isTemporaryHidden(t.pokemon_id) && (t.marker && t.marker.setMap(null), t.hidden || (t.marker = setupPokemonMarker(t, map), customizePokemonMarker(t.marker, t), mapData.pokemons[t.encounter_id] = t)) } function processPokestops(e, t) { if (!Store.get("showPokestops")) return !1; if (Store.get("showLuredPokestopsOnly") && !t.lure_expiration) return !0; if (mapData.pokestops[t.pokestop_id]) { var a = mapData.pokestops[t.pokestop_id]; !!t.lure_expiration != !!a.lure_expiration && (a.marker && a.marker.rangeCircle && a.marker.rangeCircle.setMap(null), a.marker.setMap(null), t.marker = setupPokestopMarker(t), mapData.pokestops[t.pokestop_id] = t) } else t.marker && t.marker.rangeCircle && t.marker.rangeCircle.setMap(null), t.marker && t.marker.setMap(null), t.marker = setupPokestopMarker(t), mapData.pokestops[t.pokestop_id] = t } function updatePokestops() { if (!Store.get("showPokestops")) return !1; var e = [], t = (new Date).getTime(); $.each(mapData.pokestops, function(e, a) { a.lure_expiration && a.lure_expiration < t && (a.lure_expiration = null, a.marker && a.marker.rangeCircle && a.marker.rangeCircle.setMap(null), a.marker.setMap(null), a.marker = setupPokestopMarker(a)) }), Store.get("showLuredPokestopsOnly") && ($.each(mapData.pokestops, function(t, a) { a.lure_expiration || e.push(t) }), $.each(e, function(e, t) { mapData.pokestops[t] && mapData.pokestops[t].marker && (mapData.pokestops[t].marker.rangeCircle && mapData.pokestops[t].marker.rangeCircle.setMap(null), mapData.pokestops[t].marker.setMap(null), delete mapData.pokestops[t]) })) } function processGyms(e, t) { if (!Store.get("showGyms") && !Store.get("showRaids")) return !1; var a = t.slots_available, o = t.raid_level, n = function e(t) { mapData.gyms[t] && mapData.gyms[t].marker && (mapData.gyms[t].marker.rangeCircle && mapData.gyms[t].marker.rangeCircle.setMap(null), mapData.gyms[t].marker.setMap(null), delete mapData.gyms[t]) }; if (!Store.get("showGyms") && Store.get("showRaids") && void 0 === t.raid_end) return n(t.gym_id), !0; if (!Store.get("showGyms") && Store.get("showRaids") && t.raid_end < Date.now()) return n(t.gym_id), !0; if (Store.get("showGyms") && !Store.get("showRaids") && t.raid_end > Date.now()) return n(t.gym_id), !0; if (o < Store.get("minRaidLevel") && t.raid_end > Date.now()) return n(t.gym_id), !0; if (o > Store.get("maxRaidLevel") && t.raid_end > Date.now()) return n(t.gym_id), !0; if (Store.get("showOpenGymsOnly") && 0 === t.slots_available && (void 0 === t.raid_end || t.raid_end < Date.now())) return n(t.gym_id), !0; if (Store.get("showTeamGymsOnly") && Store.get("showTeamGymsOnly") !== t.team_id && (void 0 === t.raid_end || t.raid_end < Date.now())) return n(t.gym_id), !0; if (Store.get("showLastUpdatedGymsOnly")) { var i = new Date; if (null == t.last_scanned) { if (3600 * Store.get("showLastUpdatedGymsOnly") * 1e3 + t.last_modified < i.getTime() && (void 0 === t.raid_end || t.raid_end < Date.now())) return n(t.gym_id), !0 } else if (3600 * Store.get("showLastUpdatedGymsOnly") * 1e3 + t.last_scanned < i.getTime() && (void 0 === t.raid_end || t.raid_end < Date.now())) return n(t.gym_id), !0 } return a < Store.get("minGymLevel") && (void 0 === t.raid_end || t.raid_end < Date.now()) ? (n(t.gym_id), !0) : a > Store.get("maxGymLevel") && (void 0 === t.raid_end || t.raid_end < Date.now()) ? (n(t.gym_id), !0) : (t.gym_id in mapData.gyms ? t.marker = updateGymMarker(t, mapData.gyms[t.gym_id].marker) : t.marker = setupGymMarker(t), void(mapData.gyms[t.gym_id] = t)) } function processScanned(e, t) { if (!Store.get("showScanned")) return !1; var a = t.latitude + "|" + t.longitude; a in mapData.scanned ? mapData.scanned[a].last_modified = t.last_modified : (t.marker && t.marker.setMap(null), t.marker = setupScannedMarker(t), mapData.scanned[a] = t) } function updateScanned() { if (!Store.get("showScanned")) return !1; $.each(mapData.scanned, function(e, t) { map.getBounds().intersects(t.marker.getBounds()) && t.marker.setOptions({ fillColor: getColorByDate(t.last_modified) }) }) } function processSpawnpoints(e, t) { if (!Store.get("showSpawnpoints")) return !1; var a = t.spawnpoint_id; a in mapData.spawnpoints || (t.marker && t.marker.setMap(null), t.marker = setupSpawnpointMarker(t), mapData.spawnpoints[a] = t) } function updateSpawnPoints() { if (!Store.get("showSpawnpoints")) return !1; var e = map.getZoom(); $.each(mapData.spawnpoints, function(t, a) { if (map.getBounds().contains(a.marker.getPosition())) { var o = getColorBySpawnTime(a.time); a.marker.setIcon(changeSpawnIcon(o, e)), a.marker.setZIndex(spawnPointIndex(o)) } }) } function updateMap() { var e = map.getCenter(); Store.set("startAtLastLocationPosition", { lat: e.lat(), lng: e.lng() }), loadRawData().done(function(e) { $.each(e.pokemons, processPokemons), $.each(e.pokestops, processPokestops), $.each(e.gyms, processGyms), $.each(e.scanned, processScanned), $.each(e.spawnpoints, processSpawnpoints), showInBoundsMarkers(mapData.pokemons, "pokemon"), showInBoundsMarkers(mapData.lurePokemons, "pokemon"), showInBoundsMarkers(mapData.gyms, "gym"), showInBoundsMarkers(mapData.pokestops, "pokestop"), showInBoundsMarkers(mapData.scanned, "scanned"), showInBoundsMarkers(mapData.spawnpoints, "inbound"), clearStaleMarkers(), updateScanned(), updateSpawnPoints(), updatePokestops(), $("#stats").hasClass("visible") && countMarkers(map), oSwLat = e.oSwLat, oSwLng = e.oSwLng, oNeLat = e.oNeLat, oNeLng = e.oNeLng, lastgyms = e.lastgyms, lastpokestops = e.lastpokestops, lastpokemon = e.lastpokemon, lastslocs = e.lastslocs, lastspawns = e.lastspawns, (reids = e.reids) instanceof Array && (reincludedPokemon = reids.filter(function(e) { return this.indexOf(e) < 0 }, reincludedPokemon)), timestamp = e.timestamp, lastUpdateTime = Date.now() }) } function drawScanPath(e) { var t = []; $.each(e, function(e, a) { t.push({ lat: a.latitude, lng: a.longitude }) }), scanPath && scanPath.setMap(null), scanPath = new google.maps.Polyline({ path: t, geodesic: !0, strokeColor: "#FF0000", strokeOpacity: 1, strokeWeight: 2, map: map }) } function redrawPokemon(e) { var t = !0; $.each(e, function(t, a) { var o = e[t]; if (!o.hidden) { o.marker.rangeCircle && o.marker.rangeCircle.setMap(null); var n = setupPokemonMarker(o, map, this.marker.animationDisabled); customizePokemonMarker(n, o, !0), o.marker.setMap(null), e[t].marker = n } }) } function getPointDistance(e, t) { return google.maps.geometry.spherical.computeDistanceBetween(e, t) } function sendNotification(e, t, a, o, n) { if (!("Notification" in window)) return !1; if ("granted" !== Notification.permission) Notification.requestPermission(); else { var i = new Notification(e, { icon: a, body: t, sound: "sounds/ding.mp3" }); i.onclick = function() { window.focus(), i.close(), centerMap(o, n, 20) } } } function createMyLocationButton() { var e = document.createElement("div"), t = document.createElement("button"); t.style.backgroundColor = "#fff", t.style.border = "none", t.style.outline = "none", t.style.width = "28px", t.style.height = "28px", t.style.borderRadius = "2px", t.style.boxShadow = "0 1px 4px rgba(0,0,0,0.3)", t.style.cursor = "pointer", t.style.marginRight = "10px", t.style.padding = "0px", t.title = "My Location", e.appendChild(t); var a = document.createElement("div"); a.style.margin = "5px", a.style.width = "18px", a.style.height = "18px", a.style.backgroundImage = "url(static/mylocation-sprite-1x.png)", a.style.backgroundSize = "180px 18px", a.style.backgroundPosition = "0px 0px", a.style.backgroundRepeat = "no-repeat", a.id = "current-location", t.appendChild(a), t.addEventListener("click", function() { centerMapOnLocation() }), e.index = 1, map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(e), google.maps.event.addListener(map, "dragend", function() { document.getElementById("current-location").style.backgroundPosition = "0px 0px" }) } function centerMapOnLocation() { var e = document.getElementById("current-location"); if (null !== e) var t = "0", a = setInterval(function() { t = "-18" === t ? "0" : "-18", e.style.backgroundPosition = t + "px 0" }, 500); navigator.geolocation ? navigator.geolocation.getCurrentPosition(function(t) { var o = new google.maps.LatLng(t.coords.latitude, t.coords.longitude); locationMarker.setPosition(o), map.setCenter(o), Store.set("followMyLocationPosition", { lat: t.coords.latitude, lng: t.coords.longitude }), clearInterval(a), null !== e && (e.style.backgroundPosition = "-144px 0px") }) : (clearInterval(a), null !== e && (e.style.backgroundPosition = "0px 0px")) } function changeLocation(e, t) { var a = new google.maps.LatLng(e, t); map.setCenter(a) } function centerMap(e, t, a) { var o = new google.maps.LatLng(e, t); map.setCenter(o), a && (storeZoom = !1, map.setZoom(a)) } function i8ln(e) { return $.isEmptyObject(i8lnDictionary) && "en" !== language && languageLookups < languageLookupThreshold && $.ajax({ url: "static/dist/locales/" + language + ".min.json", dataType: "json", async: !1, success: function e(t) { i8lnDictionary = t }, error: function e(t, a, o) { console.log("Error loading i8ln dictionary: " + o), languageLookups++ } }), e in i8lnDictionary ? i8lnDictionary[e] : e } function updateGeoLocation() { navigator.geolocation && Store.get("followMyLocation") && navigator.geolocation.getCurrentPosition(function(e) { var t = e.coords.latitude, a = e.coords.longitude, o = new google.maps.LatLng(t, a); if (Store.get("followMyLocation") && void 0 !== locationMarker && getPointDistance(locationMarker.getPosition(), o) >= 5) { if (map.panTo(o), locationMarker.setPosition(o), Store.get("spawnArea")) { locationMarker.rangeCircle && (locationMarker.rangeCircle.setMap(null), delete locationMarker.rangeCircle); var n = { map: map, radius: 35, strokeWeight: 1, strokeColor: "#FF9200", strokeOpacity: .9, center: o, fillColor: "#FF9200", fillOpacity: .3 }; locationMarker.rangeCircle = new google.maps.Circle(n) } Store.set("followMyLocationPosition", { lat: t, lng: a }) } }) } function createUpdateWorker() { try { if (isMobileDevice() && window.Worker) { var e = new Blob(["onmessage = function(e) {\n var data = e.data\n if (data.name === 'backgroundUpdate') {\n self.setInterval(function () {self.postMessage({name: 'backgroundUpdate'})}, 5000)\n }\n }"]), t = window.URL.createObjectURL(e); (updateWorker = new Worker(t)).onmessage = function(e) { var t = e.data; document.hidden && "backgroundUpdate" === t.name && Date.now() - lastUpdateTime > 2500 && (updateMap(), updateGeoLocation()) }, updateWorker.postMessage({ name: "backgroundUpdate" }) } } catch (e) { console.log("Webworker error: " + e.message) } } function showGymDetails(e) { var t = document.querySelector("#gym-details"), a; t.classList.add("visible"), $.ajax({ url: "gym_data", type: "GET", timeout: 3e5, data: { id: e }, dataType: "json", cache: !1 }).done(function(e) { var o = getDateStr(e.last_modified), n = ""; null != e.last_scanned && (n = '<div style="font-size: .7em">Last Scanned: ' + getDateStr(e.last_scanned) + "</div>"); var i = void 0 !== e.pokemon ? e.pokemon : [], s = e.slots_available, r = ""; 0 !== e.team_id && (r = '<center class="team-' + e.team_id + '-text"><b class="team-' + e.team_id + '-text">' + s + " Free Slots</b></center>"); var l = null != e.raid_level, d = null != e.raid_pokemon_id, c = "", m = ""; if (l && e.raid_end > Date.now()) { for (var p = "", g = 0; g < e.raid_level; g++) p += "★"; if (c = '<h3 style="margin-bottom: 0">Raid ' + p, d) { var u = ""; null != e.raid_pokemon_cp && (u = " CP " + e.raid_pokemon_cp), c += "<br>" + e.raid_pokemon_name + u } if (c += "</h3>", d && null != e.raid_pokemon_move_1 && null != e.raid_pokemon_move_2 && (c += "<div><b>" + (void 0 !== moves[e.raid_pokemon_move_1] ? i8ln(moves[e.raid_pokemon_move_1].name) : "gen/unknown") + " / " + (void 0 !== moves[e.raid_pokemon_move_2] ? i8ln(moves[e.raid_pokemon_move_2].name) : "gen/unknown") + "</b></div>"), c += '<div style="margin-bottom: 10px">Time: <b>' + getTimeStr(e.raid_start) + "</b> - <b>" + getTimeStr(e.raid_end) + "</b></div>", d) m = '<i class="pokemon-large-sprite n' + e.raid_pokemon_id + '"></i>'; else { var y = ""; m = '<img src="static/raids/egg_' + (y = e.raid_level <= 2 ? "normal" : e.raid_level <= 4 ? "rare" : "legendary") + '.png">' } } var v = "", k = '<center class="team-' + e.team_id + '-text"><div><b class="team-' + e.team_id + '-text">' + (e.name || "") + '</b></div><div><img height="100px" style="padding: 5px;" src="static/forts/' + gymTypes[e.team_id] + '_large.png">' + m + "</div>" + c + r + '<div style="font-size: .7em">Last Modified: ' + o + "</div>" + n + "<div><a href='javascript:void(0)' onclick='javascript:openMapDirections(" + e.latitude + "," + e.longitude + ")' title='View in Maps'>Get directions</a></div></center>"; i.length ? ($.each(i, function(t, a) { var o = getIv(a.iv_attack, a.iv_defense, a.iv_stamina), n = Math.round(100 / a.move_2_energy); v += '<tr onclick=toggleGymPokemonDetails(this)><td width="30px"><i class="pokemon-sprite n' + a.pokemon_id + '"></i></td><td class="team-' + e.team_id + '-text"><div style="line-height:1em">' + a.pokemon_name + '</div><div class="cp">CP ' + a.pokemon_cp + '</div></td><td width="190" class="team-' + e.team_id + '-text" align="center"><div class="trainer-level">' + a.trainer_level + '</div><div style="line-height: 1em">' + a.trainer_name + '</div></td><td width="10">\x3c!--<a href="#" onclick="toggleGymPokemonDetails(this)">--\x3e<i class="team-' + e.team_id + '-text fa fa-angle-double-down"></i>\x3c!--</a>--\x3e</td></tr><tr class="details"><td colspan="2"><div class="ivs"><div class="iv"><div class="type">ATK</div><div class="value">' + a.iv_attack + '</div></div><div class="iv"><div class="type">DEF</div><div class="value">' + a.iv_defense + '</div></div><div class="iv"><div class="type">STA</div><div class="value">' + a.iv_stamina + '</div></div><div class="iv" style="width: 36px"><div class="type">PERFECT</div><div class="value">' + o.toFixed(0) + '<span style="font-size: .6em">%</span></div></div></div></td><td colspan="2"><div class="moves"><div class="move"><div class="name">' + a.move_1_name + ' <div class="type ' + a.move_1_type.type_en.toLowerCase() + '">' + a.move_1_type.type + '</div></div><div class="damage">' + a.move_1_damage + '</div></div><br><div class="move"><div class="name">' + a.move_2_name + ' <div class="type ' + a.move_2_type.type_en.toLowerCase() + '">' + a.move_2_type.type + '</div><div><i class="move-bar-sprite move-bar-sprite-' + n + '"></i></div></div><div class="damage">' + a.move_2_damage + "</div></div></div></td></tr>" }), v = "<table><tbody>" + v + "</tbody></table>") : v = 0 === e.team_id ? "" : '<center class="team-' + e.team_id + '-text">Gym Leader:<br><i class="pokemon-large-sprite n' + e.guard_pokemon_id + '"></i><br><b class="team-' + e.team_id + '-text">' + e.guard_pokemon_name + '</b><p style="font-size: .75em margin: 5px">No additional gym information is available for this gym. Make sure you are collecting detailed gym info. If you have detailed gym info collection running, this gym\'s Pokemon information may be out of date.</p></center>', t.innerHTML = k + v, (a = document.createElement("a")).href = "#", a.className = "close", a.tabIndex = 0, t.appendChild(a), a.addEventListener("click", function(e) { e.preventDefault(), e.stopPropagation(), t.classList.remove("visible") }) }) } function toggleGymPokemonDetails(e) { e.lastElementChild.firstElementChild.classList.toggle("fa-angle-double-up"), e.lastElementChild.firstElementChild.classList.toggle("fa-angle-double-down"), e.nextElementSibling.classList.toggle("visible") } function download(e, t) { var a = document.createElement("a"); a.setAttribute("href", "data:text/plain;charset=utf-8," + encodeURIComponent(t)), a.setAttribute("download", e + "_" + moment().format("DD-MM-YYYY HH:mm")), a.style.display = "none", document.body.appendChild(a), a.click(), document.body.removeChild(a) } function upload(e) { var t = JSON.parse(JSON.parse(e)); Object.keys(t).forEach(function(e) { localStorage.setItem(e, t[e]) }), window.location.reload() } function openFile(e) { var t = e.target, a = new FileReader; a.onload = function() { console.log(a.result), upload(a.result) }, a.readAsText(t.files[0]) } var $selectExclude, $selectPokemonNotify, $selectRarityNotify, $textPerfectionNotify, $raidNotify, $selectStyle, $selectIconResolution, $selectIconSize, $switchOpenGymsOnly, $selectTeamGymsOnly, $selectLastUpdateGymsOnly, $selectMinGymLevel, $selectMaxGymLevel, $selectMinRaidLevel, $selectMaxRaidLevel, $selectLuredPokestopsOnly, $selectGymMarkerStyle, $selectLocationIconMarker, $switchGymSidebar, language = "" === document.documentElement.lang ? "en" : document.documentElement.lang, idToPokemon = {}, i8lnDictionary = {}, languageLookups = 0, languageLookupThreshold = 3, searchMarkerStyles, timestamp, excludedPokemon = [], notifiedPokemon = [], notifiedRarity = [], notifiedMinPerfection = null, onlyPokemon = 0, buffer = [], reincludedPokemon = [], reids = [], map, rawDataIsLoading = !1, locationMarker, rangeMarkers = ["pokemon", "pokestop", "gym"], storeZoom = !0, scanPath, moves, oSwLat, oSwLng, oNeLat, oNeLng, lastpokestops, lastgyms, lastpokemon, lastslocs, lastspawns, selectedStyle = "light", updateWorker, lastUpdateTime, gymTypes = ["Uncontested", "Mystic", "Valor", "Instinct"], audio = new Audio("static/sounds/ding.mp3"), genderType = ["♂", "♀", "âš²"], unownForm = ["unset", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "!", "?"], notifyIvTitle = "<pkm> <prc>% (<atk>/<def>/<sta>)", notifyNoIvTitle = "<pkm>", notifyText = "disappears at <dist> (<udist>)", updateLabelDiffTime = function e() { $(".label-countdown").each(function(e, t) { var a = getTimeUntil(parseInt(t.getAttribute("disappears-at"))), o = a.hour, n = a.min, i = a.sec, s = ""; a.ttime < a.now ? s = "(expired)" : (s = "(", o > 0 && (s = o + "h"), s += lpad(n, 2, 0) + "m", s += lpad(i, 2, 0) + "s", s += ")"), $(t).text(s) }) }; $(function() { try { if (!Notification) return void console.log("could not load notifications") } catch (e) {} try { "granted" !== Notification.permission && Notification.requestPermission() } catch (e) {} }), $(function() { $.ajax({ url: "motd_data", type: "GET", dataType: "json", cache: !1, success: function e(t) { $("#motd").attr("title", t.title).html(t.content).dialog() }, fail: function e() { return !1 } }) }), $(function() { $selectStyle = $("#map-style"), $.getJSON("static/dist/data/mapstyle.min.json").done(function(e) { var t = []; $.each(e, function(e, a) { t.push({ id: e, text: i8ln(a) }) }), $selectStyle.select2({ placeholder: "Select Style", data: t, minimumResultsForSearch: 1 / 0 }), $selectStyle.on("change", function(e) { selectedStyle = $selectStyle.val(), map.setMapTypeId(selectedStyle), Store.set("map_style", selectedStyle) }), $selectStyle.val(Store.get("map_style")).trigger("change") }), ($selectIconResolution = $("#pokemon-icons")).select2({ placeholder: "Select Icon Resolution", minimumResultsForSearch: 1 / 0 }), $selectIconResolution.on("change", function() { Store.set("pokemonIcons", this.value), redrawPokemon(mapData.pokemons), redrawPokemon(mapData.lurePokemons) }), ($selectIconSize = $("#pokemon-icon-size")).select2({ placeholder: "Select Icon Size", minimumResultsForSearch: 1 / 0 }), $selectIconSize.on("change", function() { Store.set("iconSizeModifier", this.value), redrawPokemon(mapData.pokemons), redrawPokemon(mapData.lurePokemons) }), ($switchOpenGymsOnly = $("#open-gyms-only-switch")).on("change", function() { Store.set("showOpenGymsOnly", this.checked), lastgyms = !1, updateMap() }), ($selectTeamGymsOnly = $("#team-gyms-only-switch")).select2({ placeholder: "Only Show Gyms For Team", minimumResultsForSearch: 1 / 0 }), $selectTeamGymsOnly.on("change", function() { Store.set("showTeamGymsOnly", this.value), lastgyms = !1, updateMap() }), ($selectLastUpdateGymsOnly = $("#last-update-gyms-switch")).select2({ placeholder: "Only Show Gyms Last Updated", minimumResultsForSearch: 1 / 0 }), $selectLastUpdateGymsOnly.on("change", function() { Store.set("showLastUpdatedGymsOnly", this.value), lastgyms = !1, updateMap() }), ($selectMinGymLevel = $("#min-level-gyms-filter-switch")).select2({ placeholder: "Minimum Gym Level", minimumResultsForSearch: 1 / 0 }), $selectMinGymLevel.on("change", function() { Store.set("minGymLevel", this.value), lastgyms = !1, updateMap() }), ($selectMaxGymLevel = $("#max-level-gyms-filter-switch")).select2({ placeholder: "Maximum Gym Level", minimumResultsForSearch: 1 / 0 }), $selectMaxGymLevel.on("change", function() { Store.set("maxGymLevel", this.value), lastgyms = !1, updateMap() }), ($selectMinRaidLevel = $("#min-level-raids-filter-switch")).select2({ placeholder: "Minimum Raid Level", minimumResultsForSearch: 1 / 0 }), $selectMinRaidLevel.on("change", function() { Store.set("minRaidLevel", this.value), lastgyms = !1, updateMap() }), ($selectMaxRaidLevel = $("#max-level-raids-filter-switch")).select2({ placeholder: "Maximum Raid Level", minimumResultsForSearch: 1 / 0 }), $selectMaxRaidLevel.on("change", function() { Store.set("maxRaidLevel", this.value), lastgyms = !1, updateMap() }), ($selectLuredPokestopsOnly = $("#lured-pokestops-only-switch")).select2({ placeholder: "Only Show Lured Pokestops", minimumResultsForSearch: 1 / 0 }), $selectLuredPokestopsOnly.on("change", function() { Store.set("showLuredPokestopsOnly", this.value), lastpokestops = !1, updateMap() }), ($switchGymSidebar = $("#gym-sidebar-switch")).on("change", function() { Store.set("useGymSidebar", this.checked), lastgyms = !1, $.each(["gyms"], function(e, t) { $.each(mapData[t], function(e, a) { mapData[t][e].marker.rangeCircle && (mapData[t][e].marker.rangeCircle.setMap(null), delete mapData[t][e].marker.rangeCircle), mapData[t][e].marker.setMap(null) }), mapData[t] = {} }), updateMap() }), $selectLocationIconMarker = $("#locationmarker-style"), $.getJSON("static/dist/data/searchmarkerstyle.min.json").done(function(e) { searchMarkerStyles = e; var t = []; if ($.each(e, function(e, a) { t.push({ id: e, text: a.name }) }), locationMarker = createLocationMarker(), Store.get("startAtUserLocation") && centerMapOnLocation(), Store.get("startAtLastLocation")) { var a = Store.get("startAtLastLocationPosition"), o = "lat" in a ? a.lat : centerLat, n = "lng" in a ? a.lng : centerLng, i = new google.maps.LatLng(o, n); locationMarker.setPosition(i), map.setCenter(i) } $selectLocationIconMarker.select2({ placeholder: "Select Location Marker", data: t, minimumResultsForSearch: 1 / 0 }), $selectLocationIconMarker.on("change", function(e) { Store.set("locationMarkerStyle", this.value), updateLocationMarker(this.value) }), $selectLocationIconMarker.val(Store.get("locationMarkerStyle")).trigger("change") }), ($selectGymMarkerStyle = $("#gym-marker-style")).select2({ placeholder: "Select Style", minimumResultsForSearch: 1 / 0 }), $selectGymMarkerStyle.on("change", function(e) { Store.set("gymMarkerStyle", this.value), updateGymIcons() }), $selectGymMarkerStyle.val(Store.get("gymMarkerStyle")).trigger("change") }), $(function() { function e(e) { return e.id ? $('<span><i class="pokemon-sprite n' + e.element.value.toString() + '"></i> ' + e.text + "</span>") : e.text } function t(e, t, a) { return function() { Store.set(a, this.checked), this.checked ? ("showPokemon" === a ? lastpokemon = !1 : "showRaids" === a ? lastgyms = !1 : "showGyms" === a ? lastgyms = !1 : "showPokestops" === a ? lastpokestops = !1 : "showScanned" === a ? lastslocs = !1 : "showSpawnpoints" === a && (lastspawns = !1), updateMap()) : ($.each(t, function(t, o) { $.each(e[o], function(t, n) { e[o][t].marker.rangeCircle && (e[o][t].marker.rangeCircle.setMap(null), delete e[o][t].marker.rangeCircle), "showRanges" !== a && e[o][t].marker.setMap(null) }), "showRanges" !== a && (e[o] = {}) }), "showRanges" === a && updateMap()) } } $.getJSON("static/dist/data/moves.min.json").done(function(e) { moves = e }), $selectExclude = $("#exclude-pokemon"), $selectPokemonNotify = $("#notify-pokemon"), $selectRarityNotify = $("#notify-rarity"), $textPerfectionNotify = $("#notify-perfection"); var a = 493; ($raidNotify = $("#notify-raid")).select2({ placeholder: "Minimum raid level", minimumResultsForSearch: 1 / 0 }), $raidNotify.on("change", function() { Store.set("remember_raid_notify", this.value) }), $.getJSON("static/dist/data/pokemon.min.json").done(function(t) { var a = []; $.each(t, function(e, t) { if (e > 493) return !1; var o = []; a.push({ id: e, text: i8ln(t.name) + " - #" + e }), t.name = i8ln(t.name), t.rarity = i8ln(t.rarity), $.each(t.types, function(e, t) { o.push({ type: i8ln(t.type), color: t.color }) }), t.types = o, idToPokemon[e] = t }), $selectExclude.select2({ placeholder: i8ln("Select Pokémon"), data: a, templateResult: e }), $selectPokemonNotify.select2({ placeholder: i8ln("Select Pokémon"), data: a, templateResult: e }), $selectRarityNotify.select2({ placeholder: i8ln("Select Rarity"), data: [i8ln("Common"), i8ln("Uncommon"), i8ln("Rare"), i8ln("Very Rare"), i8ln("Ultra Rare")], templateResult: e }), $selectExclude.on("change", function(e) { buffer = excludedPokemon, excludedPokemon = $selectExclude.val().map(Number), buffer = buffer.filter(function(e) { return this.indexOf(e) < 0 }, excludedPokemon), reincludedPokemon = reincludedPokemon.concat(buffer), clearStaleMarkers(), Store.set("remember_select_exclude", excludedPokemon) }), $selectPokemonNotify.on("change", function(e) { notifiedPokemon = $selectPokemonNotify.val().map(Number), Store.set("remember_select_notify", notifiedPokemon) }), $selectRarityNotify.on("change", function(e) { notifiedRarity = $selectRarityNotify.val().map(String), Store.set("remember_select_rarity_notify", notifiedRarity) }), $textPerfectionNotify.on("change", function(e) { notifiedMinPerfection = parseInt($textPerfectionNotify.val(), 10), (isNaN(notifiedMinPerfection) || notifiedMinPerfection <= 0) && (notifiedMinPerfection = ""), notifiedMinPerfection > 100 && (notifiedMinPerfection = 100), $textPerfectionNotify.val(notifiedMinPerfection), Store.set("remember_text_perfection_notify", notifiedMinPerfection) }), $selectExclude.val(Store.get("remember_select_exclude")).trigger("change"), $selectPokemonNotify.val(Store.get("remember_select_notify")).trigger("change"), $selectRarityNotify.val(Store.get("remember_select_rarity_notify")).trigger("change"), $textPerfectionNotify.val(Store.get("remember_text_perfection_notify")).trigger("change"), $raidNotify.val(Store.get("remember_raid_notify")).trigger("change"), isTouchDevice() && isMobileDevice() && $(".select2-search input").prop("readonly", !0) }), window.setInterval(updateLabelDiffTime, 1e3), window.setInterval(updateMap, 1e4), window.setInterval(updateGeoLocation, 1e3), createUpdateWorker(), $("#raids-switch").change(function() { var e = { duration: 500 }, a = $("#raids-filter-wrapper"); this.checked ? (lastgyms = !1, a.show(e)) : (lastgyms = !1, a.hide(e)), t(mapData, ["gyms"], "showRaids").bind(this)() }), $("#gyms-switch").change(function() { var e = { duration: 500 }, a = $("#gyms-filter-wrapper"); this.checked ? (lastgyms = !1, a.show(e)) : (lastgyms = !1, a.hide(e)), t(mapData, ["gyms"], "showGyms").bind(this)() }), $("#pokemon-switch").change(function() { t(mapData, ["pokemons"], "showPokemon").bind(this)() }), $("#scanned-switch").change(function() { t(mapData, ["scanned"], "showScanned").bind(this)() }), $("#spawnpoints-switch").change(function() { t(mapData, ["spawnpoints"], "showSpawnpoints").bind(this)() }), $("#ranges-switch").change(t(mapData, ["gyms", "pokemons", "pokestops"], "showRanges")), $("#pokestops-switch").change(function() { var e = { duration: 500 }, a = $("#lured-pokestops-only-wrapper"); return this.checked ? (lastpokestops = !1, a.show(e)) : (lastpokestops = !1, a.hide(e)), t(mapData, ["pokestops"], "showPokestops").bind(this)() }), $("#sound-switch").change(function() { Store.set("playSound", this.checked) }), $("#start-at-user-location-switch").change(function() { Store.set("startAtUserLocation", this.checked), !0 === this.checked && !0 === Store.get("startAtLastLocation") && (Store.set("startAtLastLocation", !1), $("#start-at-last-location-switch").prop("checked", !1)) }), $("#start-at-last-location-switch").change(function() { Store.set("startAtLastLocation", this.checked), !0 === this.checked && !0 === Store.get("startAtUserLocation") && (Store.set("startAtUserLocation", !1), $("#start-at-user-location-switch").prop("checked", !1)) }), $("#follow-my-location-switch").change(function() { navigator.geolocation ? Store.set("followMyLocation", this.checked) : this.checked = !1, locationMarker.setDraggable(!this.checked) }), $("#spawn-area-switch").change(function() { Store.set("spawnArea", this.checked), locationMarker.rangeCircle && (locationMarker.rangeCircle.setMap(null), delete locationMarker.rangeCircle) }), $("#nav-accordion").length && $("#nav-accordion").accordion({ active: !1, collapsible: !0, heightStyle: "content" }), $("#pokemonList_table").DataTable({ paging: !1, searching: !1, info: !1, errMode: "throw", language: { emptyTable: "" }, columns: [{ orderable: !1 }, null, null, null] }).order([1, "asc"]) });