From f1a86215ce65bbddd7893cf4d0cb9e7c9932b6e3 Mon Sep 17 00:00:00 2001 From: David Huser <4357648+davidhuser@users.noreply.github.com> Date: Wed, 15 Apr 2026 20:19:13 +0200 Subject: [PATCH 1/4] update timestamp in map --- js/map-providers.js | 4 +++- js/map-security.js | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/js/map-providers.js b/js/map-providers.js index 688c5f3..b4da095 100644 --- a/js/map-providers.js +++ b/js/map-providers.js @@ -464,6 +464,7 @@ function loadUnifiedProviderMap(mapConfig, countries) { }; var latestGenerated = null; + var latestCommit = null; for (var ci = 0; ci < results.length; ci++) { var data = results[ci].data; @@ -473,6 +474,7 @@ function loadUnifiedProviderMap(mapConfig, countries) { if (data.generated && (!latestGenerated || data.generated > latestGenerated)) { latestGenerated = data.generated; + latestCommit = data.commit; } var keys = Object.keys(muni); @@ -490,7 +492,7 @@ function loadUnifiedProviderMap(mapConfig, countries) { } if (latestGenerated) { - showGenerated({ generated: latestGenerated, commit: results[0].data.commit }); + showGenerated({ generated: latestGenerated, commit: latestCommit }); } var hatchSvg = 'data:image/svg+xml,' + diff --git a/js/map-security.js b/js/map-security.js index 75c553e..fad78c1 100644 --- a/js/map-security.js +++ b/js/map-security.js @@ -101,6 +101,7 @@ function loadSecurityMap(mapConfig, countries) { var catCounts = { 'both': 0, 'spf-only': 0, 'dmarc-only': 0, 'none': 0, 'no-data': 0 }; var latestGenerated = null; + var latestCommit = null; for (var ci = 0; ci < results.length; ci++) { var data = results[ci].data; @@ -109,6 +110,7 @@ function loadSecurityMap(mapConfig, countries) { if (data.generated && (!latestGenerated || data.generated > latestGenerated)) { latestGenerated = data.generated; + latestCommit = data.commit; } var keys = Object.keys(muni); @@ -123,7 +125,7 @@ function loadSecurityMap(mapConfig, countries) { } if (latestGenerated) { - showGenerated({ generated: latestGenerated, commit: results[0].data.commit }); + showGenerated({ generated: latestGenerated, commit: latestCommit }); } var hatchSvg = 'data:image/svg+xml,' + From 132f32a84b1c0fa5d519265aa1438bab08726c18 Mon Sep 17 00:00:00 2001 From: David Huser <4357648+davidhuser@users.noreply.github.com> Date: Wed, 15 Apr 2026 20:40:27 +0200 Subject: [PATCH 2/4] ui --- index.html | 6 +++--- js/map-shared.js | 6 +++--- js/nav.js | 8 ++++++++ providers.html | 2 +- security.html | 2 +- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/index.html b/index.html index 71cdfb5..3e6b428 100644 --- a/index.html +++ b/index.html @@ -39,16 +39,16 @@

Municipality Email Maps

Interactive maps showing email infrastructure of ~15,300 municipalities in Germany, Austria, and Switzerland, based on public DNS records and network signals.

-

Email Providers

+

📨 Email Providers

Which provider handles each municipality's official email? Classified by jurisdiction: US cloud (Microsoft, Google, AWS), domestic, or foreign.

-

Email Security

+

🛡️ Email Security

How well are municipality email domains protected against spoofing? Based on SPF and DMARC configuration.

diff --git a/js/map-shared.js b/js/map-shared.js index 367be28..151b45b 100644 --- a/js/map-shared.js +++ b/js/map-shared.js @@ -387,8 +387,8 @@ function addDownloadButton(map, filename) { var btn = document.createElement('button'); btn.className = 'toggle-info'; btn.id = 'download-btn'; - btn.innerHTML = '\u2913 Download'; - btn.setAttribute('aria-label', 'Download map as PNG'); + btn.innerHTML = '\u2913 Download HQ image'; + btn.setAttribute('aria-label', 'Download map as high-quality PNG (~50 MB)'); var headerRight = document.querySelector('.header-right'); var aboutBtn = document.getElementById('toggle-info'); @@ -400,7 +400,7 @@ function addDownloadButton(map, filename) { setTimeout(function () { exportMapImage(map, filename, function () { btn.disabled = false; - btn.innerHTML = '\u2913 Download'; + btn.innerHTML = '\u2913 Download HQ image'; }); }, 50); }); diff --git a/js/nav.js b/js/nav.js index b7ecb4c..30e3ede 100644 --- a/js/nav.js +++ b/js/nav.js @@ -37,11 +37,19 @@ toggle.textContent = '\u22EF'; nav.appendChild(toggle); + var extras = [ + { href: 'impressum.html', label: 'Impressum', match: ['impressum.html'] }, + { href: 'datenschutz.html', label: 'Datenschutz', match: ['datenschutz.html'] }, + ]; + var menu = document.createElement('div'); menu.className = 'nav-menu'; primary.forEach(function (link) { menu.appendChild(makeLink(link, 'nav-menu-mobile')); }); + extras.forEach(function (link) { + menu.appendChild(makeLink(link)); + }); nav.appendChild(menu); toggle.addEventListener('click', function (e) { diff --git a/providers.html b/providers.html index d49913c..d8977c3 100644 --- a/providers.html +++ b/providers.html @@ -58,7 +58,7 @@

How does it work?

Open source & open data

-

The code and data are on GitHub.

+

Part of an ongoing research project currently in peer review. The code and data are on GitHub.

diff --git a/security.html b/security.html index f0dcb77..c890417 100644 --- a/security.html +++ b/security.html @@ -58,7 +58,7 @@

DMARC

Open source & open data

-

The code and data are on GitHub.

+

Part of an ongoing research project currently in peer review. The code and data are on GitHub.

From eb5b2bbd967645c6ef83f33b915b7092ca2b9cea Mon Sep 17 00:00:00 2001 From: David Huser <4357648+davidhuser@users.noreply.github.com> Date: Wed, 15 Apr 2026 20:51:49 +0200 Subject: [PATCH 3/4] slightly enhance medium foreign provider color --- js/map-providers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/map-providers.js b/js/map-providers.js index b4da095..fbb6e1c 100644 --- a/js/map-providers.js +++ b/js/map-providers.js @@ -4,7 +4,7 @@ var COLOR_SCHEMES = { default: { 'us-cloud': { high: '#ffa199', medium: '#ffccb6', low: '#cccccc' }, 'domestic': { high: '#88faaa', medium: '#daffc2', low: '#cccccc' }, - 'foreign': { high: '#f5c842', medium: '#fde7c4', low: '#cccccc' }, + 'foreign': { high: '#f8c936', medium: '#fde89a', low: '#cccccc' }, lake: '#89B3D6', }, colorblind: { From 861be9fb7103b3991090ec08bad015046d1cec77 Mon Sep 17 00:00:00 2001 From: David Huser <4357648+davidhuser@users.noreply.github.com> Date: Wed, 15 Apr 2026 20:52:08 +0200 Subject: [PATCH 4/4] datenschutz und impressum --- css/content.css | 45 +++++++++++++++++++++++++++++++++++++++ datenschutz.html | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ impressum.html | 45 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 145 insertions(+) create mode 100644 css/content.css create mode 100644 datenschutz.html create mode 100644 impressum.html diff --git a/css/content.css b/css/content.css new file mode 100644 index 0000000..7e0377d --- /dev/null +++ b/css/content.css @@ -0,0 +1,45 @@ +/* content.css — styles for text-heavy pages (impressum, datenschutz) */ +main { + max-width: 640px; + margin: 0 auto; + padding: 40px 20px 60px; +} +main h1 { + font-size: 22px; + font-weight: 700; + color: #1a1a2e; + margin-bottom: 24px; +} +main h2 { + font-size: 16px; + font-weight: 600; + color: #1a1a2e; + margin-top: 28px; + margin-bottom: 8px; +} +main p, main ul { + font-size: 14px; + color: #444; + line-height: 1.7; + margin-bottom: 12px; +} +main ul { padding-left: 20px; } +main li { margin-bottom: 4px; } +main a { color: #2563eb; text-decoration: none; } +main a:hover { text-decoration: underline; } +main code { + font-size: 13px; + background: #f0f1f5; + padding: 1px 5px; + border-radius: 3px; +} +footer { + max-width: 640px; + margin: 0 auto; + padding: 16px 20px 32px; + font-size: 12px; + color: #999; + border-top: 1px solid #e5e7eb; +} +footer a { color: #2563eb; text-decoration: none; } +footer a:hover { text-decoration: underline; } diff --git a/datenschutz.html b/datenschutz.html new file mode 100644 index 0000000..f0e42f1 --- /dev/null +++ b/datenschutz.html @@ -0,0 +1,55 @@ + + + + + + +Datenschutzerklärung — Municipality Emails + + + + + + + + + + +
+

Datenschutzerklärung

+ +

1. Allgemeines

+

Diese Datenschutzerklärung erläutert, wie auf dieser Website mit Personendaten umgegangen wird. Die verantwortliche Person ist im Impressum aufgeführt.

+ +

2. Hosting

+

Diese Website wird über GitHub Pages (GitHub Inc., USA) bereitgestellt. Beim Aufruf der Website wird Ihre IP-Adresse an die Server von GitHub übermittelt. Dies ist technisch notwendig, um die Website auszuliefern. Weitere Informationen finden Sie in der Datenschutzerklärung von GitHub.

+ +

3. Externe Ressourcen

+

Zur Darstellung der Karten werden externe Ressourcen von Drittanbietern geladen. Dabei wird Ihre IP-Adresse an die jeweiligen Server ĂĽbermittelt:

+ + +

4. Cookies

+

Diese Website verwendet keine Cookies.

+ +

5. Keine Erhebung personenbezogener Daten

+

Diese Website enthält keine Formulare, kein Tracking, keine Analysedienste und keine Werbung. Es werden keine personenbezogenen Daten über die in den Abschnitten 2 und 3 beschriebenen technisch notwendigen Übermittlungen hinaus erhoben.

+ +

6. Ihre Rechte

+

Sie haben gemäss dem Bundesgesetz über den Datenschutz (nDSG) sowie der EU-Datenschutz-Grundverordnung (DSGVO) das Recht auf Auskunft, Berichtigung, Löschung und Herausgabe Ihrer Personendaten. Für entsprechende Anfragen wenden Sie sich bitte an die im Impressum genannte Kontaktadresse.

+ +

7. Änderungen

+

Diese Datenschutzerklärung kann jederzeit angepasst werden. Die jeweils aktuelle Fassung ist auf dieser Seite abrufbar.

+
+ + + diff --git a/impressum.html b/impressum.html new file mode 100644 index 0000000..aa03c3b --- /dev/null +++ b/impressum.html @@ -0,0 +1,45 @@ + + + + + + +Impressum — Municipality Emails + + + + + + + + + + +
+

Impressum

+ +

Angaben gemäss Art. 3 UWG / § 5 DDG / § 5 ECG

+

+ David Huser
+ E-Mail: davidhus@pm.me +

+ +

Verantwortlich fĂĽr den Inhalt

+

David Huser, Mario Bischof, Ronald Petrlic, Alexej Ochsner

+ +

Haftungsausschluss

+

Die Daten auf dieser Website basieren auf DNS-Einträgen und anderen öffentlichen Ressourcen. DNS-Einträge zeigen das Mail-Routing und autorisierte Absender an, nicht zwingend den tatsächlichen Speicherort der Daten. Es wird keine Gewähr für die Richtigkeit, Vollständigkeit oder Aktualität der bereitgestellten Informationen übernommen.

+ +

Urheberrecht

+

Der Quellcode dieses Projekts steht unter der MIT-Lizenz und ist auf GitHub verfĂĽgbar.

+
+ + +