// ==UserScript==
// @name WME Permalink to several Maps DACH
// @description WME PTSM für Deutschland Österreich Schweiz - Dropdown Design
// @namespace https://greasyforks.org/de/users/863740-horst-wittlich
// @version 2025.06.02
// @match https://*.waze.com/editor*
// @match https://*.waze.com/*/editor*
// @match https://beta.waze.com/editor*
// @match https://beta.waze.com/*/editor*
// @icon https://i.ibb.co/ckSvk59/waze-icon.png
// @grant none
// @license MIT
// ==/UserScript==
/* global OpenLayers */
/* global W */
/* global proj4 */
var ptsmVersion = '2025.06.02'
const ScriptName = GM_info.script.name;
const ScriptVersion = GM_info.script.version;
let ChangeLog = "WME Permalink to several Maps wurde Aktualisiert " + ScriptVersion + "<br />";
ChangeLog = ChangeLog + "<br /><b>Updated: Dropdown Menu Design & CSP Compliance</b>";
function getCenterZoom() {
var map = W.map.getOLMap()
var zoom = map.getZoom()
var center = map.getCenter().transform(new OpenLayers.Projection('EPSG:900913'), new OpenLayers.Projection('EPSG:4326'))
center.zoom = zoom
return center
}
function addButtons() {
if (document.getElementById('user-info') == null) {
setTimeout(addButtons, 500)
console.log('user-info element not yet available, page still loading')
return
}
if (!W.loginManager.user) {
W.loginManager.events.register('login', null, addButtons)
W.loginManager.events.register('loginStatus', null, addButtons)
if (!W.loginManager.user) {
return
}
}
if ("undefined" == typeof proj4) {
var script = document.createElement('script')
script.type = 'text/javascript'
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.4.4/proj4.js'
document.getElementsByTagName('head')[0].appendChild(script)
}
// Modern Dropdown CSS styling - CSP compliant
var style = document.createElement('style')
style.type = 'text/css'
style.textContent = `
/* Container Styling */
#sidepanel-ptsm {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
padding: 16px;
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
border-radius: 8px;
margin: 8px;
}
/* Dropdown Category Styling */
.ptsm-category {
margin-bottom: 12px;
border-radius: 8px;
overflow: hidden;
background: #ffffff;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
border: 1px solid #e3e6ea;
}
/* Category Header (Dropdown Toggle) */
.ptsm-category-header {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
padding: 12px 16px;
background: linear-gradient(135deg, #6c757d 0%, #495057 100%);
color: white;
border: none;
cursor: pointer;
font-weight: 600;
font-size: 13px;
text-transform: uppercase;
letter-spacing: 0.5px;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.ptsm-category-header:hover {
background: linear-gradient(135deg, #5a6268 0%, #343a40 100%);
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}
/* Dropdown Arrow */
.ptsm-dropdown-arrow {
width: 0;
height: 0;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 8px solid white;
transition: transform 0.3s ease;
margin-left: 8px;
}
.ptsm-category.open .ptsm-dropdown-arrow {
transform: rotate(180deg);
}
/* Category Content (Dropdown Body) */
.ptsm-category-content {
max-height: 0;
overflow: hidden;
padding: 0 12px;
background: #ffffff;
transition: max-height 0.4s cubic-bezier(0.4, 0, 0.2, 1), padding 0.3s ease;
}
.ptsm-category.open .ptsm-category-content {
max-height: 800px;
padding: 16px 12px;
}
/* Map Service Buttons */
.ptsm-map-btn {
position: relative;
display: inline-flex;
align-items: center;
justify-content: flex-start;
width: 48%;
height: 36px;
margin: 1%;
padding: 6px 10px 6px 32px;
background: linear-gradient(145deg, #ffffff 0%, #f8f9fa 100%);
border: 1px solid #dee2e6;
border-radius: 8px;
font-size: 12px;
font-weight: 500;
color: #495057;
text-align: left;
text-decoration: none;
cursor: pointer;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
}
/* Icon positioning for map buttons */
.ptsm-map-btn::before {
content: '';
position: absolute;
left: 8px;
top: 50%;
transform: translateY(-50%);
width: 16px;
height: 16px;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
}
/* Map Button Hover Effects */
.ptsm-map-btn:hover {
transform: translateY(-1px);
background: linear-gradient(145deg, #ffffff 0%, #f1f3f4 100%);
border-color: #007bff;
color: #0056b3;
box-shadow: 0 4px 12px rgba(0, 123, 255, 0.15);
}
.ptsm-map-btn:active {
transform: translateY(0);
box-shadow: 0 1px 3px rgba(0, 123, 255, 0.2);
}
/* Category Color Coding */
.ptsm-category-allgem .ptsm-category-header {
background: linear-gradient(135deg, #007bff 0%, #0056b3 100%);
}
.ptsm-category-allgem .ptsm-category-header:hover {
background: linear-gradient(135deg, #0056b3 0%, #004085 100%);
}
.ptsm-category-baustell .ptsm-category-header {
background: linear-gradient(135deg, #28a745 0%, #1e7e34 100%);
}
.ptsm-category-baustell .ptsm-category-header:hover {
background: linear-gradient(135deg, #1e7e34 0%, #155724 100%);
}
.ptsm-category-blitzer .ptsm-category-header {
background: linear-gradient(135deg, #dc3545 0%, #c82333 100%);
}
.ptsm-category-blitzer .ptsm-category-header:hover {
background: linear-gradient(135deg, #c82333 0%, #a02834 100%);
}
.ptsm-category-bilder .ptsm-category-header {
background: linear-gradient(135deg, #17a2b8 0%, #138496 100%);
}
.ptsm-category-bilder .ptsm-category-header:hover {
background: linear-gradient(135deg, #138496 0%, #0f6674 100%);
}
.ptsm-category-geoportal .ptsm-category-header {
background: linear-gradient(135deg, #6f42c1 0%, #59359a 100%);
}
.ptsm-category-geoportal .ptsm-category-header:hover {
background: linear-gradient(135deg, #59359a 0%, #4c2c85 100%);
}
.ptsm-category-misc .ptsm-category-header {
background: linear-gradient(135deg, #fd7e14 0%, #e65100 100%);
}
.ptsm-category-misc .ptsm-category-header:hover {
background: linear-gradient(135deg, #e65100 0%, #bf360c 100%);
}
/* Individual button icon styles */
.ptsm-google::before { background-image: url(https://i.ibb.co/d0zx6Pdt/google-maps.png); }
.ptsm-f4map::before { background-image: url(https://i.ibb.co/5WxjKkLp/F-Logo.png); }
.ptsm-apple::before { background-image: url(https://i.ibb.co/WsH15zC/Apple-Jetzt.png); }
.ptsm-bing::before { background-image: url(https://i.ibb.co/0LF74p6/bing.png); }
.ptsm-nrw::before { background-image: url(https://i.ibb.co/37q7H37/nrw.png); }
.ptsm-osm::before { background-image: url(https://i.ibb.co/20wtGrsL/osm.png); }
.ptsm-autobahn::before { background-image: url(https://i.ibb.co/2Y3pT8v2/Autobahn-Logo.png); }
.ptsm-poi-karte::before { background-image: url(https://i.ibb.co/nMRSSKKp/POI-Karte.jpg); }
.ptsm-poi-base::before { background-image: url(https://i.ibb.co/xS7vJQr8/POI-Base.jpg); }
.ptsm-viamichelin::before { background-image: url(https://i.ibb.co/RTzJP87C/viamichelin.png); }
.ptsm-here::before { background-image: url(https://i.ibb.co/MC9JF7T/h-logo.png); }
.ptsm-mapillary::before { background-image: url(https://i.ibb.co/JWkZnh0X/mapillary.png); }
.ptsm-osbrowser::before { background-image: url(https://i.ibb.co/RdQSgsY/osb.png); }
.ptsm-mappy::before { background-image: url(https://i.ibb.co/wrhH7H95/mappy.png); }
.ptsm-blitzer::before { background-image: url(https://i.ibb.co/gVKMwKS/blitzer.png); }
.ptsm-bayernatlas::before { background-image: url(https://i.ibb.co/KxnBpv7J/bayernatlas.png); }
.ptsm-tomtom::before { background-image: url(https://i.ibb.co/hDq5bys/tomtom-icon2.png); }
.ptsm-basemap-de::before { background-image: url(https://i.ibb.co/V3jJJrb/de-map.png); }
.ptsm-reporting::before { background-image: url(https://i.ibb.co/rZb76j2/pin.png); }
.ptsm-kartaview::before { background-image: url(https://i.ibb.co/xgnTMFf/kartaview.png); }
.ptsm-bayerninfo::before { background-image: url(https://i.ibb.co/R0K3SSs/bayerninfo.png); }
.ptsm-timonline::before { background-image: url(https://i.ibb.co/bPJ4qRy/das-da2.png); }
.ptsm-geoadmin::before { background-image: url(https://i.ibb.co/Np5chv4/CH-Icon-20.png); }
.ptsm-basemap-at::before { background-image: url(https://i.ibb.co/MCKhDSH/AT-Icon.png); }
.ptsm-adac::before { background-image: url(https://i.ibb.co/6YsGCFy/adac.png); }
.ptsm-here-edit::before { background-image: url(https://i.ibb.co/VghMgy8/here.png); }
.ptsm-umsehen::before { background-image: url(https://i.ibb.co/XYqjkYX/umsehen-icon.png); }
.ptsm-hackintosh::before { background-image: url(https://i.ibb.co/8xP5RyC/Hackintosh.png); }
.ptsm-archive::before { background-image: url(https://i.ibb.co/QHpvd85/Das-Logo.png); }
/* Warning section styling */
.ptsm-warning {
background: linear-gradient(135deg, #fff3cd 0%, #ffeaa7 100%);
border: 2px solid #ffc107;
border-radius: 8px;
padding: 12px;
margin-top: 20px;
display: flex;
align-items: flex-start;
}
.ptsm-warning .w-icon {
font-size: 20px;
color: #856404;
margin-right: 10px;
flex-shrink: 0;
}
.ptsm-warning-text {
font-size: 12px;
color: #856404;
line-height: 1.4;
}
/* Update link styling */
.ptsm-update-link {
display: inline-block;
color: #007bff;
text-decoration: none;
font-weight: 600;
font-size: 13px;
padding: 12px 0;
border-bottom: 2px solid transparent;
transition: all 0.2s ease;
}
.ptsm-update-link:hover {
color: #0056b3;
border-bottom-color: #007bff;
text-decoration: none;
}
/* Animation for smooth dropdown */
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.ptsm-category.open .ptsm-category-content {
animation: slideDown 0.3s ease-out;
}
/* State persistence info */
.ptsm-state-info {
font-size: 11px;
color: #6c757d;
font-style: italic;
text-align: center;
margin-top: 8px;
padding: 4px;
}
/* Responsive design */
@media (max-width: 768px) {
.ptsm-map-btn {
width: 98%;
margin: 1%;
}
}
`;
document.getElementsByTagName('head')[0].appendChild(style)
// Button creation functions with proper event handlers
function createMapButton(text, className, clickHandler) {
var btn = document.createElement('button');
btn.textContent = text;
btn.className = 'ptsm-map-btn ' + className;
btn.addEventListener('click', clickHandler);
return btn;
}
// LocalStorage functions for saving dropdown states
function saveDropdownStates() {
const states = {};
document.querySelectorAll('.ptsm-category').forEach(category => {
const className = category.className.match(/ptsm-category-(\w+)/);
if (className) {
states[className[1]] = category.classList.contains('open');
}
});
try {
localStorage.setItem('wme-ptsm-dropdown-states', JSON.stringify(states));
} catch (e) {
console.log('PTSM: localStorage not available, states will not be saved');
}
}
function loadDropdownStates() {
try {
const saved = localStorage.getItem('wme-ptsm-dropdown-states');
return saved ? JSON.parse(saved) : {};
} catch (e) {
console.log('PTSM: Error loading saved states, using defaults');
return {};
}
}
function createCategory(title, className, defaultOpen = false) {
const savedStates = loadDropdownStates();
const categoryKey = className.replace('ptsm-category-', '');
// Use saved state if available, otherwise use default
const isOpen = savedStates.hasOwnProperty(categoryKey) ?
savedStates[categoryKey] : defaultOpen;
var category = document.createElement('div');
category.className = 'ptsm-category ' + className + (isOpen ? ' open' : '');
var header = document.createElement('button');
header.className = 'ptsm-category-header';
header.innerHTML = title + '<div class="ptsm-dropdown-arrow"></div>';
var content = document.createElement('div');
content.className = 'ptsm-category-content';
// Toggle functionality with state saving
header.addEventListener('click', function() {
category.classList.toggle('open');
// Save state after toggle
setTimeout(saveDropdownStates, 100);
});
category.appendChild(header);
category.appendChild(content);
return { category, content };
}
// Create all map service buttons
var btn1 = createMapButton('Google', 'ptsm-google', () => {
var cz = getCenterZoom()
var mapsUrl = 'https://www.google.com/maps/@' + cz.lat + ',' + cz.lon + ',' + cz.zoom + 'z/data=!5m1!1e1'
window.open(mapsUrl, '_blank');
});
var btn4 = createMapButton('F4 3D Map', 'ptsm-f4map', () => {
var cz = getCenterZoom()
var mapsUrl = 'https://demo.f4map.com/#lat=' + cz.lat + '&lon=' + cz.lon + '&zoom=' + cz.zoom
window.open(mapsUrl, '_blank');
});
var btn5 = createMapButton('Apple', 'ptsm-apple', () => {
var cz = getCenterZoom()
var mapsUrl = 'https://maps.apple.com/look-around?coordinate=' + cz.lat + '%2C' + cz.lon
window.open(mapsUrl, '_blank');
});
var btn2 = createMapButton('Bing', 'ptsm-bing', () => {
var cz = getCenterZoom()
cz.zoom -= 1
var mapsUrl = 'https://www.bing.com/maps/traffic?cp=' + cz.lat + '~' + cz.lon + '&lvl=' + cz.zoom
window.open(mapsUrl, '_blank');
});
var btn3 = createMapButton('Ver. NRW', 'ptsm-nrw', () => {
var cz = getCenterZoom()
var mapsUrl = 'https://www.verkehr.nrw/?center=' + cz.lat + ',' + cz.lon + '&zoom=' + cz.zoom + '&layer=Verkehrslage,Baustellen,Haltestellen,Parken,Webcams,Verkehrsmeldungen,ELadesaeulen,Tankstellen&highlightRoute=false'
window.open(mapsUrl, '_blank');
});
var btn3a = createMapButton('OSM', 'ptsm-osm', () => {
var cz = getCenterZoom()
var mapsUrl = 'https://www.openstreetmap.org/#map=' + cz.zoom + '/' + cz.lat + '/' + cz.lon
window.open(mapsUrl, '_blank');
});
var btn6 = createMapButton('Autobahn', 'ptsm-autobahn', () => {
var cz = getCenterZoom()
var mapsUrl = 'https://verkehr.vz-deutschland.de/?layer=raststellen,baustellen,stau,verkehrsmeldungen&zoom=' + cz.zoom + '&lat=' + cz.lat + '&lon=' + cz.lon
window.open(mapsUrl, '_blank');
});
var btn7 = createMapButton('POI Karte', 'ptsm-poi-karte', () => {
var cz = getCenterZoom();
var newZoom = cz.zoom + 600;
var mapsUrl = 'https://www.flosm.org/de/POI-Karte.html?lat=' + cz.lat + '&lon=' + cz.lon + '&r=' + newZoom + '&st=0&sw=speedcamera';
window.open(mapsUrl, '_blank');
});
var btn8 = createMapButton('POI Base', 'ptsm-poi-base', () => {
var cz = getCenterZoom()
var mapsUrl = 'https://www.poibase.com/de/karte/#/map/coords-' + cz.lon + ',' + cz.lat + '/zoom-' + cz.zoom
window.open(mapsUrl, '_blank');
});
var btn9 = createMapButton('ViaM', 'ptsm-viamichelin', () => {
var cz = getCenterZoom()
cz.zoom -= 1
var mapsUrl = 'https://www.viamichelin.de/karten-stadtplan/verkehr?bounds=' + cz.lon*1.0001 + '~' + cz.lat*1.0001 + '~' + cz.lon *0.9999 + '~' + cz.lat*0.9999 + '¢er=' + cz.lon + '~' +cz.lat+ '&detailedView=true&itinerary=&page=1&poiCategories=0'
window.open(mapsUrl, '_blank');
});
var btn10 = createMapButton('Here', 'ptsm-here', () => {
var cz = getCenterZoom()
var mapsUrl = 'https://wego.here.com/traffic/explore?map=' + cz.lat + ',' + cz.lon + ',' + cz.zoom + ',traffic'
window.open(mapsUrl, '_blank');
});
var btn11 = createMapButton('Mapillary', 'ptsm-mapillary', () => {
var cz = getCenterZoom()
cz.zoom -= 1
var mapsUrl = 'https://www.mapillary.com/app/?lat=' + cz.lat + '&lng=' + cz.lon + '&z=' + cz.zoom
window.open(mapsUrl, '_blank');
});
var btn12 = createMapButton('OSBrowser', 'ptsm-osbrowser', () => {
var cz = getCenterZoom()
var mapsUrl = 'https://www.openstreetbrowser.org/#map=' + cz.zoom + '/' + cz.lat + '/' + cz.lon + '&categories=car_maxspeed'
window.open(mapsUrl, '_blank');
});
var btn13 = createMapButton('Mappy', 'ptsm-mappy', () => {
var cz = getCenterZoom()
var mapsUrl = 'https://en.mappy.com/plan#/' + cz.lat + ',' + cz.lon
window.open(mapsUrl, '_blank');
});
var btn14 = createMapButton('Blitzer.de', 'ptsm-blitzer', () => {
var cz = getCenterZoom()
var mapsUrl = 'https://map.atudo.com/v5/?lat=' + cz.lat + '&lng=' + cz.lon + '&zoom=' + cz.zoom
window.open(mapsUrl, '_blank');
});
var btn16 = createMapButton('BY Atlas', 'ptsm-bayernatlas', () => {
var cz = getCenterZoom()
cz.zoom -= 5
if (!proj4) {
console.log('proj4 not loaded :-(')
return
}
var firstProj = '+proj=utm +zone=32 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs'
var utm = proj4(firstProj, [cz.lon, cz.lat])
var mapsUrl = 'https://geoportal.bayern.de/bayernatlas/index.html?zoom=' + cz.zoom + '&E=' + utm[0] + '&N=' + utm[1]
window.open(mapsUrl, '_blank');
});
var btn18 = createMapButton('TomTom', 'ptsm-tomtom', () => {
var cz = getCenterZoom()
cz.zoom -= 1
var mapsUrl = 'https://plan.tomtom.com/de?p=' + cz.lat + ',' + cz.lon + ',' + cz.zoom + 'z'
window.open(mapsUrl, '_blank');
});
var btn19 = createMapButton('Basemap.de', 'ptsm-basemap-de', () => {
var cz = getCenterZoom()
cz.zoom = 0.985 * cz.zoom - 1.05
var mapsUrl = 'https://basemap.de/viewer?config=' + btoa('{"lat":' + cz.lat + ',"lon":' + cz.lon + ',"zoom":' + cz.zoom + ',"styleID":0,"pitch":0,"bearing":0,"saturation":0,"brightness":0,"hiddenControls":[],"hiddenLayers":[],"changedLayers":[],"hiddenSubGroups":[],"changedSubGroups":[],"externalStyleURL":""}')
window.open(mapsUrl, '_blank');
});
var btn20 = createMapButton('Reporting', 'ptsm-reporting', () => {
var cz = getCenterZoom()
cz.zoom -= 1
var mapsUrl = 'https://www.waze.com/partnerhub/map-tool?lat=' + cz.lat + '&lon=' + cz.lon + '&zoom=' + cz.zoom
window.open(mapsUrl, '_blank');
});
var btn21 = createMapButton('KartaView', 'ptsm-kartaview', () => {
var cz = getCenterZoom()
cz.zoom -= 1
var mapsUrl = 'https://kartaview.org/map/@' + cz.lat + ',' + cz.lon + ',' + cz.zoom + 'z'
window.open(mapsUrl, '_blank');
});
var btn22 = createMapButton('Bayerninfo', 'ptsm-bayerninfo', () => {
var cz = getCenterZoom()
cz.zoom -= 2
var now = new Date()
var then = new Date()
then.setDate(then.getDate() + 60)
let mapsUrl = 'https://www.bayerninfo.de/de/baustellenkalender?geo=' + cz.lat + ',' + cz.lon + '&zoom=' + cz.zoom
mapsUrl = mapsUrl + '&datetimeFrom=' + now.toISOString() + '&datetimeTo=' + then.toISOString()
window.open(mapsUrl, '_blank');
});
var btn30 = createMapButton('TimOnline', 'ptsm-timonline', () => {
var cz = getCenterZoom()
cz.zoom = 454959671.96858*Math.exp(-0.693*cz.zoom)
var mapsUrl = 'https://www.tim-online.nrw.de/tim-online2/?center=' + cz.lat + ',' + cz.lon + '&scale=' + cz.zoom
window.open(mapsUrl, '_blank');
});
var btn31 = createMapButton('GeoAdmin', 'ptsm-geoadmin', () => {
var cz = getCenterZoom()
cz.zoom -= 7.2
var phi1 = ((cz.lat * 3600) - 169028.66) / 10000
var lmd1 = ((cz.lon * 3600) - 26782.5) / 10000
var x = 200147.07 + 308807.95 * phi1 + 3745.25 * lmd1 * lmd1 + 76.63 * phi1 * phi1 + 119.79 * phi1 * phi1 * phi1 - 194.56 * lmd1 * lmd1 * phi1
var y = 600072.37 + 211455.93 * lmd1 - 10938.51 * lmd1 * phi1 - 0.36 * lmd1 * phi1 * phi1 - 44.54 * lmd1 * lmd1 * lmd1
var mapsUrl = 'https://map.geo.admin.ch/?Y=' + y.toFixed(0) + '&X=' + x.toFixed(0) + '&zoom=' + cz.zoom + '&topic=ech&lang=de&bgLayer=ch.swisstopo.pixelkarte-farbe&layers=ch.bfs.gebaeude_wohnungs_register,ch.kantone.cadastralwebmap-farbe,ch.swisstopo.swissimage-product,ch.bfe.ladestellen-elektromobilitaet&catalogNodes=457,532,687,458,477,485,491,510,527,1743&layers_visibility=false,false,true,true&layers_timestamp=,,current';
window.open(mapsUrl,'_blank');
});
var btn32 = createMapButton('Basemap', 'ptsm-basemap-at', () => {
var cz = getCenterZoom()
var x = cz.lon / 180 * 20037508.34
let y = Math.log(Math.tan((90 + cz.lat * 1) * Math.PI / 360)) / Math.PI
y *= 20037508.34
var mapsUrl = 'https://basemap.at/bmapp/index.html#{"center":[' + x.toFixed(10) + ',' + y.toFixed(10) + '],"zoom":' + cz.zoom + ',"rotation":0,"layers":"1000000000"}'
window.open(mapsUrl, '_blank');
});
var btn34 = createMapButton('ADAC', 'ptsm-adac', () => {
var cz = getCenterZoom()
var mapsUrl = 'https://maps.adac.de/show?place=' + cz.lat + '_' + cz.lon + '_2&traffic=announcements%2Cconstruction%2Cflow'
window.open(mapsUrl, '_blank');
});
var btn36 = createMapButton('Here Edit', 'ptsm-here-edit', () => {
var cz = getCenterZoom()
var mapsUrl = 'https://mapcreator.here.com/?l=' + cz.lat + ',' + cz.lon + ',' + cz.zoom + ',autoselect'
window.open(mapsUrl, '_blank');
});
var btn37 = createMapButton('Umsehen', 'ptsm-umsehen', () => {
var cz = getCenterZoom()
cz.zoom += 1.0
var mapsUrl = 'https://maps.apple.com/?ll=' + cz.lat + ',' + cz.lon + '&z=' + cz.zoom + '&t=m'
window.open(mapsUrl, '_blank');
});
var btn39 = createMapButton('Hackintosh', 'ptsm-hackintosh', () => {
var cz = getCenterZoom()
var mapsUrl = 'https://lookmap.eu.pythonanywhere.com/#c=' + cz.zoom + '/' + cz.lat + '/' + cz.lon + '/'
window.open(mapsUrl, '_blank');
});
var btn40 = createMapButton('Archive', 'ptsm-archive', () => {
var mapsUrl = 'https://archive.is/';
window.open(mapsUrl,'_blank');
});
// Create tab structure
let userTabs = document.getElementById('user-info')
let navTabs = document.getElementsByClassName('nav-tabs', userTabs)[0]
let tabContent = document.getElementsByClassName('tab-content', userTabs)[0]
let newtab = document.createElement('li')
newtab.innerHTML = '<a href="#sidepanel-ptsm" data-toggle="tab">PTSM</a>'
navTabs.appendChild(newtab)
let addon = document.createElement('section')
addon.id = 'sidepanel-ptsm'
addon.className = 'tab-pane'
tabContent.appendChild(addon)
// Create update link section
let divInfo = document.createElement('div');
divInfo.id = 'ptsm-Info';
let updateLink = document.createElement('a');
updateLink.href = 'https://greasyforks.org/de/scripts/448378-wme-permalink-to-several-maps-dach';
updateLink.target = '_blank';
updateLink.className = 'ptsm-update-link';
updateLink.textContent = 'Auf Updates überprüfen / V' + ptsmVersion;
divInfo.appendChild(updateLink);
// Add state persistence info
let stateInfo = document.createElement('div');
stateInfo.className = 'ptsm-state-info';
stateInfo.textContent = 'Menü-Zustände werden automatisch gespeichert';
divInfo.appendChild(stateInfo);
addon.appendChild(divInfo);
// Create dropdown categories
var allgemCategory = createCategory('ALLGEMEINE KARTEN', 'ptsm-category-allgem', true);
allgemCategory.content.appendChild(btn1); // Google
allgemCategory.content.appendChild(btn3a); // OSM
allgemCategory.content.appendChild(btn9); // ViaM
allgemCategory.content.appendChild(btn10); // HERE
allgemCategory.content.appendChild(btn13); // MAPPY
allgemCategory.content.appendChild(btn18); // TOMTOM
allgemCategory.content.appendChild(btn5); // Apple
allgemCategory.content.appendChild(btn4); // F4Maps
allgemCategory.content.appendChild(btn34); // ADAC
addon.appendChild(allgemCategory.category);
var baustellCategory = createCategory('BAUSTELLEN', 'ptsm-category-baustell');
baustellCategory.content.appendChild(btn6); // Autobahn GMBH
baustellCategory.content.appendChild(btn2); // BING
baustellCategory.content.appendChild(btn3); // Verkehr NRW
baustellCategory.content.appendChild(btn22); // BAYERNINFO
addon.appendChild(baustellCategory.category);
var blitzerCategory = createCategory('BLITZER', 'ptsm-category-blitzer');
blitzerCategory.content.appendChild(btn14); // Blitzer.de
blitzerCategory.content.appendChild(btn7); // POI Karte
blitzerCategory.content.appendChild(btn8); // POI Base
addon.appendChild(blitzerCategory.category);
var bilderCategory = createCategory('GESCHWINDIGKEITEN / BILDER', 'ptsm-category-bilder');
bilderCategory.content.appendChild(btn11); // MAPILLARY
bilderCategory.content.appendChild(btn21); // KARTAVIEW
bilderCategory.content.appendChild(btn12); // OSBROWSER
addon.appendChild(bilderCategory.category);
var geoportalCategory = createCategory('GEOPORTALE', 'ptsm-category-geoportal');
geoportalCategory.content.appendChild(btn19); // Basemap.de
geoportalCategory.content.appendChild(btn32); // Basemap.at
geoportalCategory.content.appendChild(btn31); // GEOADMIN
geoportalCategory.content.appendChild(btn30); // TIM
geoportalCategory.content.appendChild(btn16); // BAYERNATLAS
addon.appendChild(geoportalCategory.category);
var miscCategory = createCategory('MISC', 'ptsm-category-misc');
miscCategory.content.appendChild(btn20); // Waze Report
miscCategory.content.appendChild(btn36); // Here Editor
miscCategory.content.appendChild(btn37); // Apple Umsehen
miscCategory.content.appendChild(btn39); // Appetize Emulator
miscCategory.content.appendChild(btn40); // Archive.is
addon.appendChild(miscCategory.category);
// Create warning section
let warningDiv = document.createElement('div');
warningDiv.className = 'ptsm-warning';
warningDiv.innerHTML = `
<i class="w-icon w-icon-warning"></i>
<div class="ptsm-warning-text">
Hinweis: Einige der externen Karten sind als Informationsquelle zur Kartenbearbeitung nicht zulässig!
</div>
`;
addon.appendChild(warningDiv);
// Show update notification for new version
showUpdateNotification();
}
addButtons()