Author SHA1 Message Date
chriz 01ea3bd07a First appointment fixes. 2026-10-21 08:31:00 +02:00
chriz eef49d7bb3 Erstkontakt. 2026-10-20 18:19:06 +02:00
chriz 93d4d3bba3 Ansprechpartner Medizintechnik: 2026-10-20 17:50:04 +02:00
chriz bc1c5a62fb Flyer Optimierungen. 2026-10-20 12:42:38 +02:00
chriz ac8468ca76 Enable HTTP/2 & HTTP/3 2026-10-20 12:02:30 +02:00
chriz 014422e0b6 Accessibility fixes. 2026-10-20 11:11:04 +02:00
chriz 02c92db1e5 add email sat 2026-10-20 10:48:59 +02:00
chriz 92f2703788 Copy Text Optimierung. 2026-10-20 10:28:25 +02:00
chriz 6648523b04 Fix Haemo Master and cleanup files. 2026-10-20 09:26:35 +02:00
chriz de178b0ceb Container fixup. 2026-10-19 22:10:32 +02:00
chriz 086db21318 Legal and content review. 2026-10-19 20:49:57 +02:00
chriz 167dc1dfb1 QM run. 2026-10-19 20:04:00 +02:00
chriz ab516628af Alphe version. 2026-10-19 19:20:55 +02:00
chriz 33dd2fb757 Alpha Version. 2026-10-19 19:05:51 +02:00
chriz 8660ea6173 Rework using Gemini 2026-10-19 18:43:01 +02:00
chriz 911b8864ca Website Update Gemini - 1st run. 2026-10-19 15:54:08 +02:00
208 changed files with 4721 additions and 39509 deletions

No files matched your search

+7
View File
@@ -0,0 +1,7 @@
.git
.gitignore
.dockerignore
Dockerfile
files/flyer_template.html
files/flyer_map.png
+35 -12
View File
@@ -1,22 +1,45 @@
Options +FollowSymLinks Options +FollowSymLinks
RewriteEngine on RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\.dialyse-berlin\.net [NC] # Redirect duplicate homepage URLs (/main.html and /index.php) to canonical root /
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L] RewriteRule ^main\.html$ / [R=301,L]
RewriteCond %{THE_REQUEST} \s/+index\.php[\s?] [NC]
RewriteCond %{HTTP_HOST} ^www\.dialyse-berlin\.net [NC] RewriteCond %{QUERY_STRING} ^$
RewriteCond %{HTTPS} !=on RewriteRule ^index\.php$ / [R=301,L]
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
# Clean URL routing for .html pages
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{QUERY_STRING} ([a-zA-Z0-9-_.=&+%]*) RewriteCond %{QUERY_STRING} ([a-zA-Z0-9-_.=&+%]*)
RewriteRule ^([0-9a-zA-Z\-]+).html$ index.php?action=$1&%1 [L] RewriteRule ^([0-9a-zA-Z\-]+).html$ index.php?action=$1&%1 [L]
RewriteRule ^captcha.png$ captcha.php [L]
# Custom 404 handler
ErrorDocument 404 /index.php?action=404
# Advertise HTTP/3 (h3) support via Alt-Svc header
<IfModule mod_headers.c>
Header setIfEmpty Alt-Svc "h3=\":443\"; ma=86400"
</IfModule>
# Gzip / Deflate Compression for Core Web Vitals & PageSpeed
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/xml application/xhtml+xml application/rss+xml application/javascript application/x-javascript application/ld+json image/svg+xml
</IfModule>
# Browser Caching for Static Assets
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/x-icon "access plus 1 month"
ExpiresByType image/svg+xml "access plus 1 month"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType application/pdf "access plus 7 days"
ExpiresByType font/ttf "access plus 1 year"
</IfModule>
<Files .htaccess> <Files .htaccess>
order allow,deny Require all denied
deny from all
</Files> </Files>
# Allow Robots.txt to pass through muss noch eingebunden werden
+15
View File
@@ -0,0 +1,15 @@
FROM php:8.5-apache-trixie
# Use official production php.ini and configure timezone & security settings
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" \
&& printf "date.timezone = Europe/Berlin\nexpose_php = Off\nsession.cookie_httponly = 1\nsession.use_strict_mode = 1\n" > "$PHP_INI_DIR/conf.d/99-custom.ini"
# Enable Apache modules (including HTTP/2) and harden server signature
RUN a2enmod rewrite headers expires deflate http2 \
&& printf "ServerTokens Prod\nServerSignature Off\nProtocols h2 h2c http/1.1\n" > /etc/apache2/conf-available/security-hardening.conf \
&& a2enconf security-hardening
# Copy application code
COPY --chown=www-data:www-data . /var/www/html/
EXPOSE 80
-34
View File
@@ -1,34 +0,0 @@
<?php
$captchaText = sha1(microtime());
$captchaText = base64_encode($captchaText);
$captchaText = substr($captchaText, 1, 5);
$_SESSION['key'] = strtolower($captchaText);
$fonts = ["cheapink.ttf"];
$fontsizes = array(25);
$yCorr = array(25);
$img = ImageCreateFromPNG('img/captcha.png');
$color = ImageColorAllocate($img, 40, 40, 40);
$index = rand(0, count($fonts)-1);
$ttf = 'fonts/' . $fonts[$index];
$ttfsize = $fontsizes[$index];
$angle = rand(2, 6);
$t_x = rand(10, 50);
$t_y = 24 + $yCorr[$index];
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Accept-Ranges: bytes");
header("Content-type: image/png");
ImageTtfText($img, $ttfsize, $angle, $t_x, $t_y, $color, $ttf, $captchaText);
ImagePNG($img);
ImageDestroy($img);
+3 -3
View File
@@ -11,8 +11,8 @@ return [
'before' => '2W', 'before' => '2W',
'from' => '2022-12-27', 'from' => '2022-12-27',
'until' => '2025-05-02', 'until' => '2025-05-02',
'text' => 'Wir suchen aktuell eine(n) Gesundheits- oder Krankenpfleger-(in)/MFA (m/w/d) für den Dialysebereich, sowie eine Küchenkraft/ Dialyseassistenz in Voll- oder Teilzeit. <br> 'text' => 'Wir suchen aktuell eine(n) Gesundheits- oder Krankenpfleger(in) / MFA (m/w/d) für den Dialysebereich sowie eine Küchenkraft / Dialyseassistenz in Voll- oder Teilzeit. <br>
Gründliche Einarbeitung gewährleistet! Melden Sie sich gern unter <a href="mailto:kontakt@dialyse-berlin.de">kontakt@dialyse-berlin.de</a>. <br> Gründliche Einarbeitung gewährleistet! Melden Sie sich gern unter <a href="mailto:kontakt@dialyse-berlin.net">kontakt@dialyse-berlin.net</a>. <br>
Wir freuen uns schon Sie kennen zu lernen!' Wir freuen uns schon, Sie kennenzulernen!'
] ]
]; ];
+8 -5
View File
@@ -6,11 +6,12 @@ require_once __DIR__ . '/lib/Session.php';
$session = new Session(); $session = new Session();
function validate($data) { function validate($data) {
return !empty($data['name']) && !empty($data['email']) && !empty($data['phone']) && !empty($data['message']); $hasContact = !empty(trim($data['email'] ?? '')) || !empty(trim($data['phone'] ?? ''));
return !empty(trim($data['name'] ?? '')) && $hasContact && !empty(trim($data['message'] ?? ''));
} }
function isBot($data) { function isBot($data) {
return !empty($data['company']) || ($data['check'] != 'send') && (time() - $data['timestamp']) <= 5; return !empty($data['company']) || (($data['check'] ?? '') != 'send' && (time() - (int)($data['timestamp'] ?? 0)) <= 5);
} }
if($_POST && count($_POST) > 0) { if($_POST && count($_POST) > 0) {
@@ -21,16 +22,18 @@ if($_POST && count($_POST) > 0) {
if(!validate($_POST)) { if(!validate($_POST)) {
$session->set('form', $_POST); $session->set('form', $_POST);
$session->set('alert-class', 'alert-danger'); $session->set('alert-class', 'alert-danger');
$session->set('alert', 'Nicht alle Pflichtfelder ausgefüllt.'); $session->set('alert', 'Bitte füllen Sie alle Pflichtfelder aus und geben Sie mindestens eine E-Mail-Adresse oder Telefonnummer an.');
} else { } else {
$ip = $_SERVER['REMOTE_ADDR']; $ip = $_SERVER['REMOTE_ADDR'];
$mail = new SendMail(); $mail = new SendMail();
$mail->setReplyTo($_POST['email'], $_POST['name']); if(!empty(trim($_POST['email'] ?? ''))) {
$mail->setReplyTo(trim($_POST['email']), trim($_POST['name']));
}
$mail->setTo('kontakt@dialyse-berlin.net', 'Kontaktformular'); $mail->setTo('kontakt@dialyse-berlin.net', 'Kontaktformular');
// $mail->setTo('dominic.zirpel@web.de', 'Kontaktformular'); // $mail->setTo('dominic.zirpel@web.de', 'Kontaktformular');
$mail->setSubject('Kontaktformular - Dialyse Homepage'); $mail->setSubject('Kontaktformular - Dialyse Homepage');
$mail->setBody(sprintf("Name: %s %s\nTelefon: %s\nIP: %s\nE-Mail: %s\n-----------------------------\n%s", $_POST['surname'], $_POST['name'], $_POST['phone'], $ip, $_POST['email'], $_POST['message'])); $mail->setBody(sprintf("Name: %s %s\nTelefon: %s\nIP: %s\nE-Mail: %s\n-----------------------------\n%s", $_POST['surname'] ?? '', $_POST['name'] ?? '', $_POST['phone'] ?? '', $ip, $_POST['email'] ?? '', $_POST['message'] ?? ''));
if($mail->send()) { if($mail->send()) {
$session->remove('form'); $session->remove('form');
$session->set('alert-class', 'alert-success'); $session->set('alert-class', 'alert-success');
+1784 -236
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -1 +1 @@
.lb-loader,.lightbox{text-align:center;line-height:0;position:absolute;left:0}body.lb-disable-scrolling{overflow:hidden}.lightboxOverlay{position:absolute;top:0;left:0;z-index:9999;background-color:#000;filter:alpha(Opacity=80);opacity:.8;display:none}.lightbox{width:100%;z-index:10000;font-weight:400;outline:0}.lightbox .lb-image{display:block;height:auto;max-width:inherit;max-height:none;border-radius:3px;border:4px solid #fff}.lightbox a img{border:none}.lb-outerContainer{position:relative;width:250px;height:250px;margin:0 auto;border-radius:4px;background-color:#fff}.lb-outerContainer:after{content:"";display:table;clear:both}.lb-loader{top:43%;height:25%;width:100%}.lb-cancel{display:block;width:32px;height:32px;margin:0 auto;background:url(../img/lightbox/loading.gif) no-repeat}.lb-nav{position:absolute;top:0;left:0;height:100%;width:100%;z-index:10}.lb-container>.nav{left:0}.lb-nav a{outline:0;background-image:url(data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==)}.lb-next,.lb-prev{height:100%;cursor:pointer;display:block}.lb-nav a.lb-prev{width:34%;left:0;float:left;background:url(../img/lightbox/prev.png) left 48% no-repeat;filter:alpha(Opacity=0);opacity:0;-webkit-transition:opacity .6s;-moz-transition:opacity .6s;-o-transition:opacity .6s;transition:opacity .6s}.lb-nav a.lb-prev:hover{filter:alpha(Opacity=100);opacity:1}.lb-nav a.lb-next{width:64%;right:0;float:right;background:url(../img/lightbox/next.png) right 48% no-repeat;filter:alpha(Opacity=0);opacity:0;-webkit-transition:opacity .6s;-moz-transition:opacity .6s;-o-transition:opacity .6s;transition:opacity .6s}.lb-nav a.lb-next:hover{filter:alpha(Opacity=100);opacity:1}.lb-dataContainer{margin:0 auto;padding-top:5px;width:100%;border-bottom-left-radius:4px;border-bottom-right-radius:4px}.lb-dataContainer:after{content:"";display:table;clear:both}.lb-data{padding:0 4px;color:#ccc}.lb-data .lb-details{width:85%;float:left;text-align:left;line-height:1.1em}.lb-data .lb-caption{font-size:13px;font-weight:700;line-height:1em}.lb-data .lb-caption a{color:#4ae}.lb-data .lb-number{display:block;clear:left;padding-bottom:1em;font-size:12px;color:#999}.lb-data .lb-close{display:block;float:right;width:30px;height:30px;background:url(../img/lightbox/close.png) top right no-repeat;text-align:right;outline:0;filter:alpha(Opacity=70);opacity:.7;-webkit-transition:opacity .2s;-moz-transition:opacity .2s;-o-transition:opacity .2s;transition:opacity .2s}.lb-data .lb-close:hover{cursor:pointer;filter:alpha(Opacity=100);opacity:1} .lb-loader,.lightbox{text-align:center;line-height:0}body.lb-disable-scrolling{overflow:hidden}.lightboxOverlay{position:absolute;top:0;left:0;z-index:9999;background-color:#000;opacity:.8;display:none}.lightbox{position:absolute;left:0;width:100%;z-index:10000;font-weight:400;outline:0}.lightbox .lb-image{display:block;height:auto;max-width:inherit;max-height:none;border-radius:3px;border:4px solid #fff}.lightbox a img{border:none}.lb-outerContainer{position:relative;width:250px;height:250px;margin:0 auto;border-radius:4px;background-color:#fff}.lb-loader,.lb-nav{position:absolute;left:0}.lb-outerContainer:after{content:"";display:table;clear:both}.lb-loader{top:43%;height:25%;width:100%}.lb-cancel{display:block;width:32px;height:32px;margin:0 auto;background:url(../img/lightbox/loading.gif) no-repeat}.lb-nav{top:0;height:100%;width:100%;z-index:10}.lb-container>.nav{left:0}.lb-nav a{outline:0;background-image:url(data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==)}.lb-next,.lb-prev{height:100%;cursor:pointer;display:block}.lb-nav a.lb-prev{width:34%;left:0;float:left;background:url(../img/lightbox/prev.png) left 48% no-repeat;opacity:0;-webkit-transition:opacity .6s;-moz-transition:opacity .6s;-o-transition:opacity .6s;transition:opacity .6s}.lb-nav a.lb-prev:hover{opacity:1}.lb-nav a.lb-next{width:64%;right:0;float:right;background:url(../img/lightbox/next.png) right 48% no-repeat;opacity:0;-webkit-transition:opacity .6s;-moz-transition:opacity .6s;-o-transition:opacity .6s;transition:opacity .6s}.lb-nav a.lb-next:hover{opacity:1}.lb-dataContainer{margin:0 auto;padding-top:5px;width:100%;border-bottom-left-radius:4px;border-bottom-right-radius:4px}.lb-dataContainer:after{content:"";display:table;clear:both}.lb-data{padding:0 4px;color:#ccc}.lb-data .lb-details{width:85%;float:left;text-align:left;line-height:1.1em}.lb-data .lb-caption{font-size:13px;font-weight:700;line-height:1em}.lb-data .lb-caption a{color:#4ae}.lb-data .lb-number{display:block;clear:left;padding-bottom:1em;font-size:12px;color:#999}.lb-data .lb-close{display:block;float:right;width:30px;height:30px;background:url(../img/lightbox/close.png) top right no-repeat;text-align:right;outline:0;opacity:.7;-webkit-transition:opacity .2s;-moz-transition:opacity .2s;-o-transition:opacity .2s;transition:opacity .2s}.lb-data .lb-close:hover{cursor:pointer;opacity:1}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

+650
View File
@@ -0,0 +1,650 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<title>Praxis-Flyer | Dialysezentrum Berlin-Mahlsdorf</title>
<style>
@page {
size: A4 portrait;
margin: 0;
}
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Open Sans', Arial, Helvetica, sans-serif;
color: #1e293b;
background: #ffffff;
line-height: 1.45;
font-size: 9pt;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
.page {
width: 210mm;
height: 297mm;
position: relative;
padding: 9.5mm 11.5mm 8.5mm;
overflow: hidden;
display: flex;
flex-direction: column;
}
/* Header */
.flyer-header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 3mm;
border-bottom: 2px solid #0284c7;
margin-bottom: 3.5mm;
}
.brand {
display: flex;
align-items: center;
}
.header-right {
display: flex;
align-items: center;
gap: 3.2mm;
}
.header-contact {
text-align: right;
font-size: 8.8pt;
color: #07384d;
line-height: 1.42;
}
.header-contact strong {
color: #07384d;
}
.header-contact .web-link {
color: #0284c7;
font-weight: 700;
}
.header-qr-box {
width: 15.5mm;
height: 15.5mm;
padding: 1.1mm;
background: #ffffff;
border: 1px solid #cbd5e1;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.header-qr {
width: 100%;
height: 100%;
display: block;
}
/* Motto Banner */
.motto-banner {
background: linear-gradient(135deg, #07384d 0%, #0b4f6c 100%);
color: #ffffff;
border-radius: 6px;
padding: 3.2mm 4.5mm;
margin-bottom: 3.5mm;
display: flex;
justify-content: space-between;
align-items: center;
gap: 3mm;
}
.motto-text {
font-size: 10.2pt;
font-weight: 700;
font-style: italic;
color: #f0f9ff;
white-space: nowrap;
}
.motto-sub {
font-size: 8pt;
color: #bae6fd;
white-space: nowrap;
font-weight: 600;
}
/* Physicians Row */
.physicians-row {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 3.4mm;
margin-bottom: 3.6mm;
}
.physician-card {
background: #f8fafc;
border: 1px solid #e2e8f0;
border-left: 3.5px solid #0284c7;
border-radius: 6px;
padding: 3mm 3.4mm;
}
.physician-name {
font-size: 9.4pt;
font-weight: 700;
color: #07384d;
line-height: 1.25;
}
.physician-role {
font-size: 7.2pt;
font-weight: 600;
color: #0284c7;
margin-top: 0.8mm;
line-height: 1.3;
white-space: nowrap;
}
/* Main 2-Column Content Grid */
.content-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 3.8mm;
flex: 1;
margin-bottom: 3.5mm;
}
.col-stack {
display: flex;
flex-direction: column;
gap: 3.5mm;
height: 100%;
}
.section-card {
background: #f8fafc;
border: 1px solid #e2e8f0;
border-radius: 6px;
padding: 3.8mm 4.2mm;
}
.section-card.card-grow {
flex: 1;
display: flex;
flex-direction: column;
}
.card-header {
display: flex;
align-items: center;
gap: 6px;
font-size: 9.6pt;
font-weight: 700;
color: #07384d;
margin-bottom: 2.5mm;
padding-bottom: 1.5mm;
border-bottom: 1px solid #e2e8f0;
}
.card-header svg {
width: 14px;
height: 14px;
fill: #0284c7;
flex-shrink: 0;
}
/* Lists & Details */
.check-list {
list-style: none;
font-size: 8.8pt;
color: #334155;
display: flex;
flex-direction: column;
justify-content: space-around;
flex: 1;
gap: 2.2mm;
}
.check-list li {
position: relative;
padding-left: 14px;
line-height: 1.42;
}
.check-list li::before {
content: "✓";
position: absolute;
left: 0;
top: 0;
color: #0284c7;
font-weight: bold;
font-size: 8.8pt;
}
/* Schedule rows */
.sched-list {
display: flex;
flex-direction: column;
justify-content: space-around;
flex: 1;
}
.sched-item {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 8.5pt;
padding: 1.8mm 0;
border-bottom: 1px dashed #e2e8f0;
line-height: 1.42;
}
.sched-item:last-child {
border-bottom: none;
padding-bottom: 0;
}
.sched-title {
font-weight: 700;
color: #07384d;
white-space: nowrap;
}
.sched-hours {
text-align: right;
color: #1e293b;
}
.badge-tag {
background: #e0f2fe;
color: #0369a1;
font-size: 7pt;
font-weight: 700;
padding: 0.5px 4px;
border-radius: 3px;
margin-right: 3px;
}
/* Locations */
.loc-block {
margin-bottom: 2.8mm;
font-size: 8.6pt;
line-height: 1.45;
}
.loc-block:last-child {
margin-bottom: 0;
}
.loc-head-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.7mm;
}
.loc-head {
font-weight: 700;
color: #07384d;
font-size: 9pt;
}
.loc-badge {
background: #e0f2fe;
color: #0369a1;
font-size: 7.2pt;
font-weight: 700;
padding: 0.5mm 2.2mm;
border-radius: 99px;
}
.loc-body {
color: #475569;
}
.loc-body strong {
color: #07384d;
}
/* Anfahrt & Map */
.anfahrt-flex {
display: flex;
gap: 3.5mm;
align-items: center;
}
.anfahrt-text {
flex: 1;
font-size: 8.5pt;
color: #475569;
line-height: 1.42;
}
.anfahrt-text p {
margin-bottom: 2mm;
}
.anfahrt-text p:last-child {
margin-bottom: 0;
}
.map-thumb {
width: 39mm;
height: 44mm;
object-fit: contain;
border: 1px solid #cbd5e1;
border-radius: 5px;
background: #ffffff;
padding: 1mm;
flex-shrink: 0;
}
/* Photo Showcase Card */
.photo-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2.8mm;
flex: 1;
}
.photo-item {
position: relative;
border-radius: 5px;
overflow: hidden;
border: 1px solid #cbd5e1;
height: 100%;
min-height: 62mm;
}
.photo-caption {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: linear-gradient(to top, rgba(7, 56, 77, 0.9), rgba(7, 56, 77, 0));
color: #ffffff;
font-size: 6.5pt;
font-weight: 600;
padding: 4mm 1.5mm 1.5mm;
text-align: center;
white-space: nowrap;
}
/* Bottom Callout & Footer */
.footer-callout {
background: linear-gradient(135deg, #07384d 0%, #0284c7 100%);
color: #ffffff;
border-radius: 6px;
padding: 3mm 4.5mm;
display: flex;
justify-content: space-between;
align-items: center;
gap: 4mm;
}
.callout-left {
flex: 1;
min-width: 0;
}
.callout-title {
font-size: 9pt;
font-weight: 700;
margin-bottom: 0.4mm;
white-space: nowrap;
}
.callout-sub {
font-size: 7.4pt;
color: #e0f2fe;
white-space: nowrap;
}
.callout-channels {
display: flex;
gap: 5mm;
align-items: center;
flex-shrink: 0;
}
.callout-item {
text-align: right;
}
.callout-item small {
display: block;
font-size: 6pt;
font-weight: 600;
color: #bae6fd;
text-transform: uppercase;
letter-spacing: 0.04em;
}
.callout-item .channel-val {
font-size: 8.8pt;
font-weight: 800;
color: #ffffff;
white-space: nowrap;
}
.flyer-bottom-info {
border-top: 1px solid #e2e8f0;
padding-top: 1.4mm;
margin-top: 1.6mm;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
gap: 0.4mm;
font-size: 6.6pt;
color: #64748b;
line-height: 1.3;
}
</style>
</head>
<body>
<div class="page">
<!-- Top Brand Header -->
<div class="flyer-header">
<div class="brand">
<img src="file:///d:/web-repo2/img/logo_dialysezentrum.png" style="height: 15.5mm; width: auto; object-fit: contain;" alt="Dialysezentrum Berlin-Mahlsdorf">
</div>
<div class="header-right">
<div class="header-contact">
<div><strong>Praxis für Nephrologie &amp; Dialyse</strong></div>
<div>Web: <span class="web-link">www.dialyse-berlin.net</span></div>
</div>
<div class="header-qr-box">
<svg class="header-qr" viewBox="0 0 29 29" shape-rendering="crispEdges" aria-label="QR-Code www.dialyse-berlin.net"><path fill="#07384d" d="M0,0h1v1h-1zM1,0h1v1h-1zM2,0h1v1h-1zM3,0h1v1h-1zM4,0h1v1h-1zM5,0h1v1h-1zM6,0h1v1h-1zM8,0h1v1h-1zM9,0h1v1h-1zM10,0h1v1h-1zM22,0h1v1h-1zM23,0h1v1h-1zM24,0h1v1h-1zM25,0h1v1h-1zM26,0h1v1h-1zM27,0h1v1h-1zM28,0h1v1h-1zM0,1h1v1h-1zM6,1h1v1h-1zM11,1h1v1h-1zM12,1h1v1h-1zM16,1h1v1h-1zM17,1h1v1h-1zM18,1h1v1h-1zM19,1h1v1h-1zM22,1h1v1h-1zM28,1h1v1h-1zM0,2h1v1h-1zM2,2h1v1h-1zM3,2h1v1h-1zM4,2h1v1h-1zM6,2h1v1h-1zM9,2h1v1h-1zM10,2h1v1h-1zM12,2h1v1h-1zM13,2h1v1h-1zM15,2h1v1h-1zM16,2h1v1h-1zM17,2h1v1h-1zM20,2h1v1h-1zM22,2h1v1h-1zM24,2h1v1h-1zM25,2h1v1h-1zM26,2h1v1h-1zM28,2h1v1h-1zM0,3h1v1h-1zM2,3h1v1h-1zM3,3h1v1h-1zM4,3h1v1h-1zM6,3h1v1h-1zM8,3h1v1h-1zM10,3h1v1h-1zM11,3h1v1h-1zM12,3h1v1h-1zM14,3h1v1h-1zM15,3h1v1h-1zM16,3h1v1h-1zM18,3h1v1h-1zM22,3h1v1h-1zM24,3h1v1h-1zM25,3h1v1h-1zM26,3h1v1h-1zM28,3h1v1h-1zM0,4h1v1h-1zM2,4h1v1h-1zM3,4h1v1h-1zM4,4h1v1h-1zM6,4h1v1h-1zM8,4h1v1h-1zM9,4h1v1h-1zM10,4h1v1h-1zM11,4h1v1h-1zM12,4h1v1h-1zM13,4h1v1h-1zM14,4h1v1h-1zM16,4h1v1h-1zM17,4h1v1h-1zM18,4h1v1h-1zM22,4h1v1h-1zM24,4h1v1h-1zM25,4h1v1h-1zM26,4h1v1h-1zM28,4h1v1h-1zM0,5h1v1h-1zM6,5h1v1h-1zM8,5h1v1h-1zM11,5h1v1h-1zM13,5h1v1h-1zM14,5h1v1h-1zM15,5h1v1h-1zM19,5h1v1h-1zM20,5h1v1h-1zM22,5h1v1h-1zM28,5h1v1h-1zM0,6h1v1h-1zM1,6h1v1h-1zM2,6h1v1h-1zM3,6h1v1h-1zM4,6h1v1h-1zM5,6h1v1h-1zM6,6h1v1h-1zM8,6h1v1h-1zM10,6h1v1h-1zM12,6h1v1h-1zM14,6h1v1h-1zM16,6h1v1h-1zM18,6h1v1h-1zM20,6h1v1h-1zM22,6h1v1h-1zM23,6h1v1h-1zM24,6h1v1h-1zM25,6h1v1h-1zM26,6h1v1h-1zM27,6h1v1h-1zM28,6h1v1h-1zM8,7h1v1h-1zM10,7h1v1h-1zM11,7h1v1h-1zM14,7h1v1h-1zM17,7h1v1h-1zM19,7h1v1h-1zM0,8h1v1h-1zM4,8h1v1h-1zM6,8h1v1h-1zM7,8h1v1h-1zM8,8h1v1h-1zM9,8h1v1h-1zM10,8h1v1h-1zM12,8h1v1h-1zM13,8h1v1h-1zM14,8h1v1h-1zM15,8h1v1h-1zM16,8h1v1h-1zM17,8h1v1h-1zM19,8h1v1h-1zM20,8h1v1h-1zM21,8h1v1h-1zM22,8h1v1h-1zM23,8h1v1h-1zM24,8h1v1h-1zM25,8h1v1h-1zM28,8h1v1h-1zM2,9h1v1h-1zM5,9h1v1h-1zM8,9h1v1h-1zM10,9h1v1h-1zM11,9h1v1h-1zM17,9h1v1h-1zM18,9h1v1h-1zM22,9h1v1h-1zM23,9h1v1h-1zM24,9h1v1h-1zM25,9h1v1h-1zM26,9h1v1h-1zM27,9h1v1h-1zM28,9h1v1h-1zM0,10h1v1h-1zM1,10h1v1h-1zM3,10h1v1h-1zM6,10h1v1h-1zM9,10h1v1h-1zM13,10h1v1h-1zM14,10h1v1h-1zM15,10h1v1h-1zM17,10h1v1h-1zM20,10h1v1h-1zM22,10h1v1h-1zM23,10h1v1h-1zM24,10h1v1h-1zM28,10h1v1h-1zM3,11h1v1h-1zM7,11h1v1h-1zM8,11h1v1h-1zM10,11h1v1h-1zM11,11h1v1h-1zM12,11h1v1h-1zM13,11h1v1h-1zM15,11h1v1h-1zM16,11h1v1h-1zM17,11h1v1h-1zM18,11h1v1h-1zM20,11h1v1h-1zM21,11h1v1h-1zM22,11h1v1h-1zM24,11h1v1h-1zM25,11h1v1h-1zM27,11h1v1h-1zM28,11h1v1h-1zM1,12h1v1h-1zM4,12h1v1h-1zM6,12h1v1h-1zM9,12h1v1h-1zM10,12h1v1h-1zM11,12h1v1h-1zM12,12h1v1h-1zM13,12h1v1h-1zM17,12h1v1h-1zM20,12h1v1h-1zM21,12h1v1h-1zM27,12h1v1h-1zM0,13h1v1h-1zM1,13h1v1h-1zM3,13h1v1h-1zM4,13h1v1h-1zM5,13h1v1h-1zM10,13h1v1h-1zM11,13h1v1h-1zM12,13h1v1h-1zM13,13h1v1h-1zM14,13h1v1h-1zM16,13h1v1h-1zM17,13h1v1h-1zM18,13h1v1h-1zM20,13h1v1h-1zM22,13h1v1h-1zM24,13h1v1h-1zM25,13h1v1h-1zM26,13h1v1h-1zM27,13h1v1h-1zM28,13h1v1h-1zM1,14h1v1h-1zM2,14h1v1h-1zM6,14h1v1h-1zM7,14h1v1h-1zM10,14h1v1h-1zM11,14h1v1h-1zM12,14h1v1h-1zM16,14h1v1h-1zM18,14h1v1h-1zM20,14h1v1h-1zM21,14h1v1h-1zM24,14h1v1h-1zM25,14h1v1h-1zM26,14h1v1h-1zM28,14h1v1h-1zM3,15h1v1h-1zM4,15h1v1h-1zM5,15h1v1h-1zM9,15h1v1h-1zM10,15h1v1h-1zM12,15h1v1h-1zM14,15h1v1h-1zM17,15h1v1h-1zM20,15h1v1h-1zM22,15h1v1h-1zM27,15h1v1h-1zM28,15h1v1h-1zM3,16h1v1h-1zM5,16h1v1h-1zM6,16h1v1h-1zM7,16h1v1h-1zM10,16h1v1h-1zM13,16h1v1h-1zM14,16h1v1h-1zM15,16h1v1h-1zM16,16h1v1h-1zM17,16h1v1h-1zM18,16h1v1h-1zM19,16h1v1h-1zM20,16h1v1h-1zM21,16h1v1h-1zM23,16h1v1h-1zM27,16h1v1h-1zM0,17h1v1h-1zM2,17h1v1h-1zM3,17h1v1h-1zM5,17h1v1h-1zM7,17h1v1h-1zM12,17h1v1h-1zM17,17h1v1h-1zM18,17h1v1h-1zM22,17h1v1h-1zM23,17h1v1h-1zM24,17h1v1h-1zM25,17h1v1h-1zM27,17h1v1h-1zM28,17h1v1h-1zM2,18h1v1h-1zM6,18h1v1h-1zM8,18h1v1h-1zM13,18h1v1h-1zM14,18h1v1h-1zM15,18h1v1h-1zM18,18h1v1h-1zM20,18h1v1h-1zM21,18h1v1h-1zM22,18h1v1h-1zM24,18h1v1h-1zM26,18h1v1h-1zM28,18h1v1h-1zM4,19h1v1h-1zM9,19h1v1h-1zM10,19h1v1h-1zM13,19h1v1h-1zM15,19h1v1h-1zM16,19h1v1h-1zM17,19h1v1h-1zM19,19h1v1h-1zM22,19h1v1h-1zM27,19h1v1h-1zM28,19h1v1h-1zM0,20h1v1h-1zM1,20h1v1h-1zM4,20h1v1h-1zM6,20h1v1h-1zM7,20h1v1h-1zM8,20h1v1h-1zM9,20h1v1h-1zM13,20h1v1h-1zM17,20h1v1h-1zM19,20h1v1h-1zM20,20h1v1h-1zM21,20h1v1h-1zM22,20h1v1h-1zM23,20h1v1h-1zM24,20h1v1h-1zM25,20h1v1h-1zM28,20h1v1h-1zM8,21h1v1h-1zM13,21h1v1h-1zM14,21h1v1h-1zM16,21h1v1h-1zM17,21h1v1h-1zM18,21h1v1h-1zM20,21h1v1h-1zM24,21h1v1h-1zM28,21h1v1h-1zM0,22h1v1h-1zM1,22h1v1h-1zM2,22h1v1h-1zM3,22h1v1h-1zM4,22h1v1h-1zM5,22h1v1h-1zM6,22h1v1h-1zM8,22h1v1h-1zM9,22h1v1h-1zM10,22h1v1h-1zM11,22h1v1h-1zM16,22h1v1h-1zM18,22h1v1h-1zM19,22h1v1h-1zM20,22h1v1h-1zM22,22h1v1h-1zM24,22h1v1h-1zM25,22h1v1h-1zM26,22h1v1h-1zM28,22h1v1h-1zM0,23h1v1h-1zM6,23h1v1h-1zM10,23h1v1h-1zM11,23h1v1h-1zM12,23h1v1h-1zM14,23h1v1h-1zM17,23h1v1h-1zM19,23h1v1h-1zM20,23h1v1h-1zM24,23h1v1h-1zM27,23h1v1h-1zM0,24h1v1h-1zM2,24h1v1h-1zM3,24h1v1h-1zM4,24h1v1h-1zM6,24h1v1h-1zM8,24h1v1h-1zM9,24h1v1h-1zM10,24h1v1h-1Line truncated
</div>
</div>
</div>
<!-- Motto Banner -->
<div class="motto-banner">
<div class="motto-text">&bdquo;Die individuelle Dialyse im grünen Gürtel von Berlin&ldquo;</div>
<div class="motto-sub">2 Standorte &bull; Feriendialyse &bull; Barrierefrei</div>
</div>
<!-- Physicians Row -->
<div class="physicians-row">
<div class="physician-card">
<div class="physician-name">Dr. med. Bianca Bischoff</div>
<div class="physician-role">Fachärztin für Innere Medizin &amp; Nephrologie</div>
</div>
<div class="physician-card">
<div class="physician-name">Dr. med. Juliane Hoffzimmer</div>
<div class="physician-role">Fachärztin für Innere Medizin &amp; Nephrologie</div>
</div>
<div class="physician-card">
<div class="physician-name">Dr. med. Claudia Körner</div>
<div class="physician-role">Fachärztin für Innere Medizin</div>
</div>
</div>
<!-- Main 2-Column Content -->
<div class="content-grid">
<!-- LEFT COLUMN: Leistungen, Komfort & Behandlungszeiten -->
<div class="col-stack">
<!-- Leistungen -->
<div class="section-card card-grow">
<div class="card-header">
<svg viewBox="0 0 24 24"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-2 10h-4v4h-2v-4H7v-2h4V7h2v4h4v2z"/></svg>
Leistungsspektrum &amp; Medizintechnik
</div>
<ul class="check-list">
<li><strong>Nephrologische Ambulanz:</strong> Diagnostik &amp; Therapie von Nierenerkrankungen, Blutdruck- und Diabeteseinstellung</li>
<li><strong>Funktionsdiagnostik:</strong> Sonographie (Nieren/Abdomen), EKG &amp; 24-Std.-Blutdruckmessung</li>
<li><strong>Dialyseverfahren (HD &amp; Online-HDF):</strong> Kreislaufschonend mit Nikkiso <strong>Haemo-Master</strong> &amp; <strong>Fresenius BCM</strong></li>
<li><strong>Begleitende Betreuung:</strong> Transplantationsvorbereitung, Nachsorge &amp; individuelle Ernährungsberatung</li>
</ul>
</div>
<!-- Feriendialyse & Komfort -->
<div class="section-card">
<div class="card-header">
<svg viewBox="0 0 24 24"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg>
Feriendialyse &amp; Patientenkomfort
</div>
<ul class="check-list">
<li><strong>Ganzjährige Feriendialysen</strong> für Berlin-Besucher in barrierefreien Praxisräumen</li>
<li><strong>Persönliche Betreuung</strong> durch 3 Fachärztinnen sowie 23 Pflege- und Servicekräfte</li>
<li><strong>Wohlfühlatmosphäre</strong> mit kostenlosem WLAN, Patienten-TV, Imbiss &amp; Getränken</li>
</ul>
</div>
<!-- Öffnungszeiten -->
<div class="section-card card-grow">
<div class="card-header">
<svg viewBox="0 0 24 24"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z"/></svg>
Behandlungs- &amp; Sprechzeiten
</div>
<div class="sched-list">
<div class="sched-item">
<div class="sched-title">Dialyse (Mo, Mi, Fr):</div>
<div class="sched-hours">
<div><span class="badge-tag">1. Schicht</span> 07:00 &ndash; 13:00 Uhr</div>
<div><span class="badge-tag">2. Schicht</span> 13:00 &ndash; 18:00 Uhr</div>
<div><span class="badge-tag">3. Schicht</span> 14:30 &ndash; 20:00 Uhr</div>
</div>
</div>
<div class="sched-item">
<div class="sched-title">Dialyse (Di, Do, Sa):</div>
<div class="sched-hours"><span class="badge-tag">1. Schicht</span> 07:00 &ndash; 13:00 Uhr</div>
</div>
<div class="sched-item">
<div class="sched-title">Ambulanz (Mo, Mi, Fr):</div>
<div class="sched-hours">
<div>08:30 &ndash; 11:30 Uhr</div>
<div>14:00 &ndash; 17:00 Uhr (n. Vereinb.)</div>
</div>
</div>
<div class="sched-item">
<div class="sched-title">Ambulanz (Di, Do):</div>
<div class="sched-hours">08:30 &ndash; 12:00 Uhr</div>
</div>
</div>
</div>
</div>
<!-- RIGHT COLUMN: Standorte, Anfahrt & Praxis-Einblicke -->
<div class="col-stack">
<!-- Standorte -->
<div class="section-card">
<div class="card-header">
<svg viewBox="0 0 24 24"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5a2.5 2.5 0 0 1 0-5 2.5 2.5 0 0 1 0 5z"/></svg>
Unsere Standorte in Berlin
</div>
<div class="loc-block">
<div class="loc-head-row">
<div class="loc-head">Zentrumsdialyse (Hauptpraxis &amp; Ambulanz)</div>
<span class="loc-badge">16 Plätze</span>
</div>
<div class="loc-body">
<strong>Thorner Straße 1 &bull; 12623 Berlin-Mahlsdorf</strong>
</div>
</div>
<div class="loc-block" style="border-top: 1px dashed #e2e8f0; padding-top: 2.4mm;">
<div class="loc-head-row">
<div class="loc-head">Satellitendialyse Berlin-Marzahn</div>
<span class="loc-badge">18 Plätze</span>
</div>
<div class="loc-body">
<strong>Blumberger Damm 130 &bull; 12685 Berlin</strong><br>
Eingang: Pritzhagener Weg 21
</div>
</div>
</div>
<!-- Anfahrt & Skizze -->
<div class="section-card">
<div class="card-header">
<svg viewBox="0 0 24 24"><path d="M20.5 3l-.16.03L15 5.1 9 3 3.36 4.9c-.21.07-.36.25-.36.48V20.5c0 .28.22.5.5.5l.16-.03L9 18.9l6 2.1 5.64-1.9c.21-.07-.36-.25-.36-.48V3.5c0-.28-.22-.5-.5-.5zM15 19l-6-2.11V5l6 2.11V19z"/></svg>
Anfahrt &amp; Parken (Hauptpraxis)
</div>
<div class="anfahrt-flex">
<div class="anfahrt-text">
<p><strong>ÖPNV:</strong> S-Bahn <strong>S5</strong> oder Regionalbahn bis <strong>S-Bhf. Mahlsdorf</strong> (wenige Gehminuten).</p>
<p><strong>Pkw:</strong> Über <strong>B1/B5 (Alt-Mahlsdorf)</strong> &rarr; Hönower Str. &rarr; Waldowstr. &rarr; Thorner Str. 1.</p>
<p style="color: #0284c7; font-weight: 600;">&#x2713; Parkplätze direkt vor der Praxis.</p>
</div>
<img src="file:///d:/web-repo2/files/flyer_map.png" class="map-thumb" alt="Lageplan">
</div>
</div>
<!-- Praxis-Einblicke (2 Bilder) -->
<div class="section-card card-grow">
<div class="card-header">
<svg viewBox="0 0 24 24"><path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"/></svg>
Einblicke in unsere Praxis
</div>
<div class="photo-grid">
<div class="photo-item" style="background: url('file:///d:/web-repo2/img/gallery/praxis1.jpg') 92% 65% / cover no-repeat;">
<div class="photo-caption">Praxisgebäude &bull; Thorner Str. 1</div>
</div>
<div class="photo-item" style="background: url('file:///d:/web-repo2/img/gallery/behandlung2.jpg') center center / cover no-repeat;">
<div class="photo-caption">Dialyseplatz mit Nikkiso-Technik</div>
</div>
</div>
</div>
</div>
</div>
<!-- Bottom Action Callout -->
<div class="footer-callout">
<div class="callout-left">
<div class="callout-title">Kontakt &amp; Terminvereinbarung</div>
<div class="callout-sub">Wir beraten Sie gern persönlich</div>
</div>
<div class="callout-channels">
<div class="callout-item">
<small>Tel. Dialyse</small>
<div class="channel-val">030 / 566 24 84</div>
</div>
<div class="callout-item">
<small>Tel. Ambulanz</small>
<div class="channel-val">030 / 566 25 39</div>
</div>
<div class="callout-item">
<small>E-Mail</small>
<div class="channel-val">kontakt@dialyse-berlin.net</div>
</div>
</div>
</div>
<!-- Bottom Info Line -->
<div class="flyer-bottom-info">
<div>Dialysezentrum Berlin-Mahlsdorf &bull; Zentrum für Nephrologie und Dialyse &bull; Dr. med. Bianca Bischoff &amp; Dr. med. Juliane Hoffzimmer</div>
<div>Thorner Str. 1, 12623 Berlin &bull; Blumberger Damm 130, 12685 Berlin</div>
</div>
</div>
</body>
</html>
BIN
View File
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 547 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 703 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 894 B

After

Width:  |  Height:  |  Size: 6.5 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 368 KiB

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 KiB

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 KiB

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 329 KiB

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 259 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 363 KiB

After

Width:  |  Height:  |  Size: 345 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 501 KiB

After

Width:  |  Height:  |  Size: 436 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 259 KiB

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 KiB

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 903 B

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 237 B

+4
View File
@@ -34,6 +34,9 @@ switch ($action) {
case 'team': case 'team':
$content = $loadFile('view/team.php'); $content = $loadFile('view/team.php');
break; break;
case 'ersttermin':
$content = $loadFile('view/first-appointment.php');
break;
case 'kontakt': case 'kontakt':
$content = $loadFile('view/contact.php'); $content = $loadFile('view/contact.php');
break; break;
@@ -48,6 +51,7 @@ switch ($action) {
break; break;
default: default:
http_response_code(404); http_response_code(404);
$action = '404';
$content = $loadFile('view/error.php'); $content = $loadFile('view/error.php');
} }
+69 -25
View File
@@ -1,35 +1,79 @@
function initialize() { /**
var geocoder = new google.maps.Geocoder(); * Contact and Map Helpers
* Dialysezentrum Berlin-Mahlsdorf
*/
geocoder.geocode( { 'address': 'Thorner Straße 1,12623 Berlin'}, function(results, status) { function sending(user, domain, tld) {
if(status == google.maps.GeocoderStatus.OK) { user = user || 'kontakt';
var myOptions = { domain = domain || 'dialyse-berlin';
zoom: 15, tld = tld || 'net';
center: results[0].geometry.location, window.location.href = 'mailto:' + user + '@' + domain + '.' + tld;
mapTypeId: google.maps.MapTypeId.ROADMAP, return true;
mapTypeControl: false, }
navigationControl: true,
navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL}
};
var map = new google.maps.Map(document.getElementById("googlemap"), myOptions); function initObfuscatedEmails() {
// Dynamically reconstruct obfuscated email links and text for real visitors
$('.mail-obf').each(function() {
var $el = $(this);
var u = $el.attr('data-usr') || $el.data('usr');
var d = $el.attr('data-dom') || $el.data('dom');
var t = $el.attr('data-tld') || $el.data('tld');
if (u && d && t) {
var email = u + '@' + d + '.' + t;
$el.attr('href', 'mailto:' + email);
var $val = $el.find('.mail-val');
if ($val.length) {
$val.removeClass('c-rev').text(email);
}
}
});
var marker = new google.maps.Marker({ $('.mail-obf-text').each(function() {
position: results[0].geometry.location, var $el = $(this);
map: map var u = $el.attr('data-usr') || $el.data('usr');
}); var d = $el.attr('data-dom') || $el.data('dom');
} else { var t = $el.attr('data-tld') || $el.data('tld');
alert("Geocode was not successful for the following reason: " + status); if (u && d && t) {
var email = u + '@' + d + '.' + t;
var $val = $el.find('.mail-val');
if ($val.length) {
$val.removeClass('c-rev').text(email);
} else {
$el.text(email);
}
} }
}); });
} }
initialize(); $(function() {
initObfuscatedEmails();
});
function sending() { function showMapLocation(loc) {
var text = "%6D%61%69%6C%74%6F:%6B%6F%6E%74%61%6B%74@%64%69%61%6C%79%73%65%2D%62%65%72%6C%69%6E%2E%6E%65%74"; var $frame = $('#mapFrame');
var $headerTitle = $('#mapHeaderTitle');
var $addrText = $('#mapAddressText');
var $extLink = $('#mapExternalLink');
var $btnMahlsdorf = $('#btnMapMahlsdorf');
var $btnSatellit = $('#btnMapSatellit');
location.href = decodeURI(text); if (loc === 'satellit') {
$frame.attr('src', 'https://maps.google.com/maps?q=Blumberger+Damm+130,+12685+Berlin&t=&z=15&ie=UTF8&iwloc=&output=embed');
return true; $frame.attr('title', 'Karte Satellitendialyse Berlin-Marzahn');
$headerTitle.html('Standortkarte &bull; Berlin-Marzahn');
$addrText.text('Blumberger Damm 130 (Eingang Pritzhagener Weg 21), 12685 Berlin');
$extLink.attr('href', 'https://www.google.com/maps/place/Dialysezentrum+Berlin-Mahlsdorf+LC/@52.5428128,13.5716785,17z/data=!3m1!4b1!4m6!3m5!1s0x47a84991f9d5111b:0xda0b4785760166c5!8m2!3d52.5428128!4d13.5716785!16s%2Fg%2F1ts_5mmj');
$btnMahlsdorf.removeClass('btn-primary').addClass('btn-outline-primary').attr('aria-pressed', 'false');
$btnSatellit.removeClass('btn-outline-primary').addClass('btn-primary').attr('aria-pressed', 'true');
} else {
$frame.attr('src', 'https://maps.google.com/maps?q=Thorner+Stra%C3%9Fe+1,+12623+Berlin&t=&z=15&ie=UTF8&iwloc=&output=embed');
$frame.attr('title', 'Karte Zentrumsdialyse Berlin-Mahlsdorf');
$headerTitle.html('Standortkarte &bull; Berlin-Mahlsdorf');
$addrText.text('Thorner Straße 1, 12623 Berlin');
$extLink.attr('href', 'https://www.google.com/maps/place/Dialysezentrum+Berlin-Mahlsdorf/@52.5078291,13.6092903,17z/data=!3m1!4b1!4m6!3m5!1s0x47a84991f9c57f7f:0xad4486f559442067!8m2!3d52.5078291!4d13.6092903!16s%2Fg%2F1tdqghgn');
$btnMahlsdorf.removeClass('btn-outline-primary').addClass('btn-primary').attr('aria-pressed', 'true');
$btnSatellit.removeClass('btn-primary').addClass('btn-outline-primary').attr('aria-pressed', 'false');
}
} }
-2
View File
@@ -1,2 +0,0 @@
/*! jQuery v3.6.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */
!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,y=n.hasOwnProperty,a=y.toString,l=a.call(Object),v={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}S.fn=S.prototype={jquery:f,constructor:S,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=S.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return S.each(this,e)},map:function(n){return this.pushStack(S.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(S.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(S.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},S.extend=S.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(S.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||S.isPlainObject(n)?n:{},i=!1,a[t]=S.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},S.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=y.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){b(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(p(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},makeArray:function(e,t){var n=t||[];return null!=e&&(p(Object(e))?S.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(p(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:v}),"function"==typeof Symbol&&(S.fn[Symbol.iterator]=t[Symbol.iterator]),S.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var d=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,y,s,c,v,S="sizzle"+1*new Date,p=n.document,k=0,r=0,m=ue(),x=ue(),A=ue(),N=ue(),j=function(e,t){return e===t&&(l=!0),0},D={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",I="(?:\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",W="\\["+M+"*("+I+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+I+"))|)"+M+"*\\]",F=":("+I+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+W+")*)|.*)\\)|)",$=new RegExp(M+"+","g"),B=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=new RegExp("^"+M+"*,"+M+"*"),z=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^Line truncated
+2
View File
@@ -0,0 +1,2 @@
/*! jQuery v3.7.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */
!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}function fe(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}ce.fn=ce.prototype={jquery:t,constructor:ce,length:0,toArray:function(){return ae.call(this)},get:function(e){return null==e?ae.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=ce.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return ce.each(this,e)},map:function(n){return this.pushStack(ce.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(ae.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(ce.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(ce.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:s,sort:oe.sort,splice:oe.splice},ce.extend=ce.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||v(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(ce.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||ce.isPlainObject(n)?n:{},i=!1,a[t]=ce.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},ce.extend({expando:"jQuery"+(t+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==i.call(e))&&(!(t=r(e))||"function"==typeof(n=ue.call(t,"constructor")&&t.constructor)&&o.call(n)===a)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){m(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(c(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},text:function(e){var t,n="",r=0,i=e.nodeType;if(!i)while(t=e[r++])n+=ce.text(t);return 1===i||11===i?e.textContent:9===i?e.documentElement.textContent:3===i||4===i?e.nodeValue:n},makeArray:function(e,t){var n=t||[];return null!=e&&(c(Object(e))?ce.merge(n,"string"==typeof e?[e]:e):s.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:se.call(t,e,n)},isXMLDoc:function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!l.test(t||n&&n.nodeName||"HTML")},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(c(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:le}),"function"==typeof Symbol&&(ce.fn[Symbol.iterator]=oe[Symbol.iterator]),ce.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var pe=oe.pop,de=oe.sort,he=oe.splice,ge="[\\x20\\t\\r\\n\\f]",ve=new RegExp("^"+ge+"+|((?:^|[^\\\\])(?:\\\\.)*)"+ge+"+$","g");ce.contains=function(e,t){var n=t&&t.parentNode;return e===n||!(!n||1!==n.nodeType||!(e.contains?e.contains(n):e.compareDocumentPosition&&16&e.compareDocumentPosition(n)))};var f=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;function p(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e}ce.escapeSelector=function(e){return(e+"").replace(f,p)};var ye=C,me=s;!function(){var e,b,w,o,a,T,r,C,d,i,k=me,S=ce.expando,E=0,n=0,s=W(),c=W(),u=W(),h=W(),l=function(e,t){return e===t&&(a=!0),0},f="checked|selected|async|autofocus|autoplay|conLine truncated
-38
View File
@@ -1,38 +0,0 @@
/*!
* jQuery JavaScript Library v3.4.1
* https://jquery.com/
*
* Includes Sizzle.js
* https://sizzlejs.com/
*
* Copyright JS Foundation and other contributors
* Released under the MIT license
* https://jquery.org/license
*
* Date: 2019-05-01T21:04Z
*/
!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";function c(a,b,c){c=c||ia;var d,e,f=c.createElement("script");if(f.text=a,b)for(d in wa)(e=b[d]||b.getAttribute&&b.getAttribute(d))&&f.setAttribute(d,e);c.head.appendChild(f).parentNode.removeChild(f)}function d(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?oa[pa.call(a)]||"object":typeof a}function e(a){var b=!!a&&"length"in a&&a.length,c=d(a);return!ua(a)&&!va(a)&&("array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a)}function f(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}function g(a,b,c){return ua(b)?ya.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?ya.grep(a,function(a){return a===b!==c}):"string"!=typeof b?ya.grep(a,function(a){return na.call(b,a)>-1!==c}):ya.filter(b,a,c)}function h(a,b){for(;(a=a[b])&&1!==a.nodeType;);return a}function i(a){var b={};return ya.each(a.match(Ja)||[],function(a,c){b[c]=!0}),b}function j(a){return a}function k(a){throw a}function l(a,b,c,d){var e;try{a&&ua(e=a.promise)?e.call(a).done(b).fail(c):a&&ua(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}function m(){ia.removeEventListener("DOMContentLoaded",m),a.removeEventListener("load",m),ya.ready()}function n(a,b){return b.toUpperCase()}function o(a){return a.replace(Na,"ms-").replace(Oa,n)}function p(){this.expando=ya.expando+p.uid++}function q(a){return"true"===a||"false"!==a&&("null"===a?null:a===+a+""?+a:Sa.test(a)?JSON.parse(a):a)}function r(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Ta,"-$&").toLowerCase(),"string"==typeof(c=a.getAttribute(d))){try{c=q(c)}catch(a){}Ra.set(a,b,c)}else c=void 0;return c}function s(a,b,c,d){var e,f,g=20,h=d?function(){return d.cur()}:function(){return ya.css(a,b,"")},i=h(),j=c&&c[3]||(ya.cssNumber[b]?"":"px"),k=a.nodeType&&(ya.cssNumber[b]||"px"!==j&&+i)&&Va.exec(ya.css(a,b));if(k&&k[3]!==j){for(i/=2,j=j||k[3],k=+i||1;g--;)ya.style(a,b,k+j),(1-f)*(1-(f=h()/i||.5))<=0&&(g=0),k/=f;k*=2,ya.style(a,b,k+j),c=c||[]}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}function t(a){var b,c=a.ownerDocument,d=a.nodeName,e=ab[d];return e||(b=c.body.appendChild(c.createElement(d)),e=ya.css(b,"display"),b.parentNode.removeChild(b),"none"===e&&(e="block"),ab[d]=e,e)}function u(a,b){for(var c,d,e=[],f=0,g=a.length;f<g;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=Qa.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&$a(d)&&(e[f]=t(d))):"none"!==c&&(e[f]="none",Qa.set(d,"display",c)));for(f=0;f<g;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}function v(a,b){var c;return c=void 0!==a.getElementsByTagName?a.getElementsByTagName(b||"*"):void 0!==a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&f(a,b)?ya.merge([a],c):c}function w(a,b){for(var c=0,d=a.length;c<d;c++)Qa.set(a[c],"globalEval",!b||Qa.get(b[c],"globalEval"))}function x(a,b,c,e,f){for(var g,h,i,j,k,l,m=b.createDocumentFragment(),n=[],o=0,p=a.length;o<p;o++)if((g=a[o])||0===g)if("object"===d(g))ya.merge(n,g.nodeType?[g]:g);else if(fb.test(g)){for(h=h||m.appendChild(b.createElement("div")),i=(cb.exec(g)||["",""])[1].toLowerCase(),j=eb[i]||eb._default,h.innerHTML=j[1]+ya.htmlPrefilter(g)+j[2],l=j[0];l--;)h=h.lastChild;ya.merge(n,h.childNodes),h=m.firstChild,h.textContent=""}else n.push(b.createTextNode(g));for(m.textContent="",o=0;g=n[o++];)if(e&&ya.inArray(g,e)>-1)f&&f.push(g);else if(k=Ya(g),h=v(m.appendChild(g),"script"),k&&w(h),c)for(l=0;g=h[l++];)db.test(g.type||"")&&c.push(g);return m}function y(){return!0}function z(){return!1}function A(a,b){return a===B()==("focus"===b)}function B(){try{return ia.activeElement}catch(a){}}function C(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)C(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),!1===e)e=z;else if(!e)return a;return 1===f&&(g=e,e=function(a){return ya().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=ya.guid++)),a.each(function(){ya.event.add(this,b,e,d,c)})}function D(a,b,c){if(!c)return void(void 0===Qa.get(a,b)&&ya.event.add(a,b,y));Qa.set(a,b,!1),ya.event.add(a,b,{namespace:!1,handler:function(a){var d,e,f=Qa.get(this,b);if(1&a.isTrigger&&this[b]){if(f.length)(ya.event.special[b]||{}).delegateType&&a.stopPropagation();else if(f=ka.call(arguments),Qa.set(this,b,f),d=c(this,b),this[b](),e=Qa.get(this,b),f!==e||d?Qa.set(this,b,!1):e={},f!==e)return a.stopImmediatePropagation(),a.preventDefault(),e.value}else f.length&&(Qa.set(this,b,{value:ya.event.trigger(ya.extend(f[0],ya.Event.prototype),f.slice(1),this)}),a.stopImmediatePropagation())}})}function E(a,b){return f(a,"table"Line truncated
* Sizzle CSS Selector Engine v2.3.4
* https://sizzlejs.com/
*
* Copyright JS Foundation and other contributors
* Released under the MIT license
* https://js.foundation/
*
* Date: 2019-04-08
*/
function(a){function b(a,b,c,d){var e,f,g,h,i,j,k,m=b&&b.ownerDocument,o=b?b.nodeType:9;if(c=c||[],"string"!=typeof a||!a||1!==o&&9!==o&&11!==o)return c;if(!d&&((b?b.ownerDocument||b:P)!==H&&G(b),b=b||H,J)){if(11!==o&&(i=ta.exec(a)))if(e=i[1]){if(9===o){if(!(g=b.getElementById(e)))return c;if(g.id===e)return c.push(g),c}else if(m&&(g=m.getElementById(e))&&N(b,g)&&g.id===e)return c.push(g),c}else{if(i[2])return _.apply(c,b.getElementsByTagName(a)),c;if((e=i[3])&&w.getElementsByClassName&&b.getElementsByClassName)return _.apply(c,b.getElementsByClassName(e)),c}if(w.qsa&&!V[a+" "]&&(!K||!K.test(a))&&(1!==o||"object"!==b.nodeName.toLowerCase())){if(k=a,m=b,1===o&&la.test(a)){for((h=b.getAttribute("id"))?h=h.replace(xa,ya):b.setAttribute("id",h=O),j=A(a),f=j.length;f--;)j[f]="#"+h+" "+n(j[f]);k=j.join(","),m=ua.test(a)&&l(b.parentNode)||b}try{return _.apply(c,m.querySelectorAll(k)),c}catch(b){V(a,!0)}finally{h===O&&b.removeAttribute("id")}}}return C(a.replace(ia,"$1"),b,c,d)}function c(){function a(c,d){return b.push(c+" ")>x.cacheLength&&delete a[b.shift()],a[c+" "]=d}var b=[];return a}function d(a){return a[O]=!0,a}function e(a){var b=H.createElement("fieldset");try{return!!a(b)}catch(a){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function f(a,b){for(var c=a.split("|"),d=c.length;d--;)x.attrHandle[c[d]]=b}function g(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)for(;c=c.nextSibling;)if(c===b)return-1;return a?1:-1}function h(a){return function(b){return"input"===b.nodeName.toLowerCase()&&b.type===a}}function i(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function j(a){return function(b){return"form"in b?b.parentNode&&!1===b.disabled?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&Aa(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function k(a){return d(function(b){return b=+b,d(function(c,d){for(var e,f=a([],c.length,b),g=f.length;g--;)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function l(a){return a&&void 0!==a.getElementsByTagName&&a}function m(){}function n(a){for(var b=0,c=a.length,d="";b<c;b++)d+=a[b].value;return d}function o(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=R++;return b.first?function(b,c,e){for(;b=b[d];)if(1===b.nodeType||g)return a(b,c,e);return!1}:function(b,c,i){var j,k,l,m=[Q,h];if(i){for(;b=b[d];)if((1===b.nodeType||g)&&a(b,c,i))return!0}else for(;b=b[d];)if(1===b.nodeType||g)if(l=b[O]||(b[O]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===Q&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}return!1}}function p(a){return a.length>1?function(b,c,d){for(var e=a.length;e--;)if(!a[e](b,c,d))return!1;return!0}:a[0]}function q(a,c,d){for(var e=0,f=c.length;e<f;e++)b(a,c[e],d);return d}function r(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;h<i;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function s(a,b,c,e,f,g){return e&&!e[O]&&(e=s(e)),f&&!f[O]&&(f=s(f,g)),d(function(d,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=d||q(b||"*",h.nodeType?[h]:h,[]),s=!a||!d&&b?p:r(p,m,a,h,i),t=c?f||(d?a:o||e)?[]:g:s;if(c&&c(s,t,h,i),e)for(j=r(t,n),e(j,[],h,i),k=j.length;k--;)(l=j[k])&&(t[n[k]]=!(s[n[k]]=l));if(d){if(f||a){if(f){for(j=[],k=t.length;k--;)(l=t[k])&&j.push(s[k]=l);f(null,t=[],j,i)}for(k=t.length;k--;)(l=t[k])&&(j=f?ba(d,l):m[k])>-1&&(d[j]=!(g[j]=l))}}else t=r(t===g?t.splice(o,t.length):t),f?f(null,g,t,i):_.apply(g,t)})}function t(a){for(var b,c,d,e=a.length,f=x.relative[a[0].type],g=f||x.relative[" "],h=f?1:0,i=o(function(a){return a===b},g,!0),j=o(function(a){return ba(b,a)>-1},g,!0),k=[function(a,c,d){var e=!f&&(d||c!==D)||((b=c).nodeType?i(a,c,d):j(a,c,d));return b=null,e}];h<e;h++)if(c=x.relative[a[h].type])k=[o(p(k),c)];else{if(c=x.filter[a[h].type].apply(null,a[h].matches),c[O]){for(d=++h;d<e&&!x.relative[a[d].type];d++);return s(h>1&&p(k),h>1&&n(a.slice(0,h-1).concat({value:" "===a[h-2].type?"*":""})).replace(ia,"$1"),c,h<d&&t(a.slice(h,d)),d<e&&t(a=a.slice(d)),d<e&&n(a))}k.push(c)}return p(k)}function u(a,c){var e=c.length>0,f=a.length>0,g=function(d,g,h,i,j){var k,l,m,n=0,o="0",p=d&&[],q=[],s=D,t=d||f&&x.find.TAG("*",j),u=Q+=null==s?1:Math.random()||.1,v=t.length;for(j&&(D=g===H||g||j);o!==v&&null!=(k=t[o]);o++){if(f&&k){for(l=0,g||k.ownerDocument===H||(G(k),h=!J);m=a[l++];)if(m(k,g||H,h)){i.push(k);break}j&&(Q=u)}e&&((k=!m&&k)&&n--,d&&p.push(k))}if(n+=o,e&&o!==n){for(l=0;m=c[l++];)m(p,q,g,h);if(d){if(n>0)for(;o--;)p[o]||q[o]||(q[o]=Z.call(i));q=r(q)}_.apply(i,q),j&&!d&&q.length>0&&n+c.length>1&&b.uniqueSort(i)}return j&&(Q=u,D=s),p};return e?d(g):g}var v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O="sizzle"+1*new Date,P=a.document,Q=0,R=0,S=c(),T=c(),U=c(),V=c(),W=function(a,b){return a===b&&(F=!0),0},X={}.hasOwnProperty,Y=[],Z=Y.pop,$=Y.push,_=Y.push,aa=Y.slice,ba=function(a,b){for(var c=0,d=a.length;c<Line truncated
* Lightbox v2.11.3
* by Lokesh Dhakar
*
* More info:
* http://lokeshdhakar.com/projects/lightbox2/
*
* Copyright Lokesh Dhakar
* Released under the MIT license
* https://github.com/lokesh/lightbox2/blob/master/LICENSE
*
* @preserve
*/
function(a,b){"function"==typeof define&&define.amd?define(["jquery"],b):"object"==typeof exports?module.exports=b(require("jquery")):a.lightbox=b(a.jQuery)}(this,function(a){function b(b){this.album=[],this.currentImageIndex=void 0,this.init(),this.options=a.extend({},this.constructor.defaults),this.option(b)}return b.defaults={albumLabel:"Image %1 of %2",alwaysShowNavOnTouchDevices:!1,fadeDuration:600,fitImagesInViewport:!0,imageFadeDuration:600,positionFromTop:50,resizeDuration:700,showImageNumberLabel:!0,wrapAround:!1,disableScrolling:!1,sanitizeTitle:!1},b.prototype.option=function(b){a.extend(this.options,b)},b.prototype.imageCountLabel=function(a,b){return this.options.albumLabel.replace(/%1/g,a).replace(/%2/g,b)},b.prototype.init=function(){var b=this;a(document).ready(function(){b.enable(),b.build()})},b.prototype.enable=function(){var b=this;a("body").on("click","a[rel^=lightbox], area[rel^=lightbox], a[data-lightbox], area[data-lightbox]",function(c){return b.start(a(c.currentTarget)),!1})},b.prototype.build=function(){if(!(a("#lightbox").length>0)){var b=this;a('<div id="lightboxOverlay" tabindex="-1" class="lightboxOverlay"></div><div id="lightbox" tabindex="-1" class="lightbox"><div class="lb-outerContainer"><div class="lb-container"><img class="lb-image" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" alt=""/><div class="lb-nav"><a class="lb-prev" aria-label="Previous image" href="" ></a><a class="lb-next" aria-label="Next image" href="" ></a></div><div class="lb-loader"><a class="lb-cancel"></a></div></div></div><div class="lb-dataContainer"><div class="lb-data"><div class="lb-details"><span class="lb-caption"></span><span class="lb-number"></span></div><div class="lb-closeContainer"><a class="lb-close"></a></div></div></div></div>').appendTo(a("body")),this.$lightbox=a("#lightbox"),this.$overlay=a("#lightboxOverlay"),this.$outerContainer=this.$lightbox.find(".lb-outerContainer"),this.$container=this.$lightbox.find(".lb-container"),this.$image=this.$lightbox.find(".lb-image"),this.$nav=this.$lightbox.find(".lb-nav"),this.containerPadding={top:parseInt(this.$container.css("padding-top"),10),right:parseInt(this.$container.css("padding-right"),10),bottom:parseInt(this.$container.css("padding-bottom"),10),left:parseInt(this.$container.css("padding-left"),10)},this.imageBorderWidth={top:parseInt(this.$image.css("border-top-width"),10),right:parseInt(this.$image.css("border-right-width"),10),bottom:parseInt(this.$image.css("border-bottom-width"),10),left:parseInt(this.$image.css("border-left-width"),10)},this.$overlay.hide().on("click",function(){return b.end(),!1}),this.$lightbox.hide().on("click",function(c){"lightbox"===a(c.target).attr("id")&&b.end()}),this.$outerContainer.on("click",function(c){return"lightbox"===a(c.target).attr("id")&&b.end(),!1}),this.$lightbox.find(".lb-prev").on("click",function(){return 0===b.currentImageIndex?b.changeImage(b.album.length-1):b.changeImage(b.currentImageIndex-1),!1}),this.$lightbox.find(".lb-next").on("click",function(){return b.currentImageIndex===b.album.length-1?b.changeImage(0):b.changeImage(b.currentImageIndex+1),!1}),this.$nav.on("mousedown",function(a){3===a.which&&(b.$nav.css("pointer-events","none"),b.$lightbox.one("contextmenu",function(){setTimeout(function(){this.$nav.css("pointer-events","auto")}.bind(b),0)}))}),this.$lightbox.find(".lb-loader, .lb-close").on("click",function(){return b.end(),!1})}},b.prototype.start=function(b){function c(a){d.album.push({alt:a.attr("data-alt"),link:a.attr("href"),title:a.attr("data-title")||a.attr("title")})}var d=this,e=a(window);e.on("resize",a.proxy(this.sizeOverlay,this)),this.sizeOverlay(),this.album=[];var f,g=0,h=b.attr("data-lightbox");if(h){f=a(b.prop("tagName")+'[data-lightbox="'+h+'"]');for(var i=0;i<f.length;i=++i)c(a(f[i])),f[i]===b[0]&&(g=i)}else if("lightbox"===b.attr("rel"))c(b);else{f=a(b.prop("tagName")+'[rel="'+b.attr("rel")+'"]');for(var j=0;j<f.length;j=++j)c(a(f[j])),f[j]===b[0]&&(g=j)}var k=e.scrollTop()+this.options.positionFromTop,l=e.scrollLeft();this.$lightbox.css({top:k+"px",left:l+"px"}).fadeIn(this.options.fadeDuration),this.options.disableScrolling&&a("body").addClass("lb-disable-scrolling"),this.changeImage(g)},b.prototype.changeImage=function(b){var c=this,d=this.album[b].link,e=d.split(".").slice(-1)[0],f=this.$lightbox.find(".lb-image");this.disableKeyboardNav(),this.$overlay.fadeIn(this.options.fadeDuration),a(".lb-loader").fadeIn("slow"),this.$lightbox.find(".lb-image, .lb-nav, .lb-prev, .lb-next, .lb-dataContainer, .lb-numbers, .lb-caption").hide(),this.$outerContainer.addClass("animating");var g=new Image;g.onload=function(){var h,i,j,k,l,m;f.attr({alt:c.album[b].alt,src:d}),a(g),f.width(g.width),f.height(g.height),m=a(window).width(),l=a(window).height(),k=m-c.containerPadding.left-c.containerPadding.right-c.imageBorderWidth.left-c.imageBorderWidth.right-20,j=l-c.containerPadding.top-c.containerPadding.bottom-c.imageBorderWidLine truncated
//# sourceMappingURL=lightbox-plus-jquery.min.map
-1
View File
@@ -1 +0,0 @@
{"version":3,"sources":["lightbox-plus-jquery.js"],"names":["global","factory","module","exports","document","w","Error","window","this","noGlobal","DOMEval","code","node","doc","i","val","script","createElement","text","preservedScriptAttributes","getAttribute","setAttribute","head","appendChild","parentNode","removeChild","toType","obj","class2type","toString","call","isArrayLike","length","type","isFunction","isWindow","nodeName","elem","name","toLowerCase","winnow","elements","qualifier","not","jQuery","grep","nodeType","indexOf","filter","sibling","cur","dir","createOptions","options","object","each","match","rnothtmlwhite","_","flag","Identity","v","Thrower","ex","adoptValue","value","resolve","reject","noValue","method","promise","done","fail","then","apply","undefined","slice","completed","removeEventListener","ready","fcamelCase","all","letter","toUpperCase","camelCase","string","replace","rmsPrefix","rdashAlpha","Data","expando","uid","getData","data","rbrace","test","JSON","parse","dataAttr","key","rmultiDash","e","dataUser","set","adjustCSS","prop","valueParts","tween","adjusted","scale","maxIterations","currentValue","css","initial","unit","cssNumber","initialInUnit","rcssNum","exec","style","start","end","getDefaultDisplay","temp","ownerDocument","display","defaultDisplayMap","body","showHide","show","values","index","dataPriv","get","isHiddenWithinTree","getAll","context","tag","ret","getElementsByTagName","querySelectorAll","merge","setGlobalEval","elems","refElements","l","buildFragment","scripts","selection","ignored","tmp","wrap","attached","j","fragment","createDocumentFragment","nodes","rhtml","rtagName","wrapMap","_default","innerHTML","htmlPrefilter","lastChild","childNodes","firstChild","textContent","push","createTextNode","inArray","isAttached","rscriptType","returnTrue","returnFalse","expectSync","safeActiveElement","activeElement","err","on","types","selector","fn","one","origFn","event","off","arguments","guid","add","leverageNative","el","namespace","handler","notAsync","result","saved","isTrigger","special","delegateType","stopPropagation","stopImmediatePropagation","preventDefault","trigger","extend","Event","prototype","manipulationTarget","content","children","disableScript","restoreScript","removeAttribute","cloneCopyEvent","src","dest","pdataOld","pdataCur","udataOld","udataCur","events","hasData","access","handle","fixInput","rcheckableType","checked","defaultValue","domManip","collection","args","callback","concat","first","hasScripts","iNoClone","valueIsFunction","support","checkClone","rchecked","self","eq","html","map","clone","contains","_evalUrl","noModule","nonce","rcleanScript","remove","keepData","cleanData","curCSS","computed","width","minWidth","maxWidth","getStyles","getPropertyValue","pixelBoxStyles","rnumnonpx","rboxStyle","addGetHookIf","conditionFn","hookFn","vendorPropName","capName","cssPrefixes","emptyStyle","finalPropName","final","cssProps","vendorProps","setPositiveNumber","subtract","matches","Math","max","boxModelAdjustment","dimension","box","isBorderBox","styles","computedVal","extra","delta","cssExpand","ceil","getWidthOrHeight","boxSizingNeeded","boxSizingReliable","valueIsBorderBox","offsetProp","parseFloat","getClientRects","Tween","easing","init","schedule","inProgress","hidden","requestAnimationFrame","setTimeout","fx","interval","tick","createFxNow","fxNow","Date","now","genFx","includeWidth","which","attrs","height","opacity","createTween","animation","Animation","tweeners","defaultPrefilter","props","opts","toggle","hooks","oldfire","propTween","restoreDisplay","isBox","anim","orig","dataShow","queue","_queueHooks","unqueued","empty","fire","always","rfxtypes","isEmptyObject","overflow","overflowX","overflowY","propFilter","specialEasing","Array","isArray","cssHooks","expand","properties","stopped","prefilters","deferred","Deferred","currentTime","remaining","startTime","duration","percent","tweens","run","notifyWith","resolveWith","originalProperties","originalOptions","stop","gotoEnd","rejectWith","bind","progress","complete","timer","stripAndCollapse","join","getClass","classesToArray","buildParams","prefix","traditional","rbracket","addToPrefiltersOrTransports","structure","dataTypeExpression","func","dataType","dataTypes","unshift","inspectPrefiltersOrTransports","jqXHR","inspect","selected","inspected","prefilterOrFactory","dataTypeOrTransport","seekingTransport","transports","ajaxExtend","target","deep","flatOptions","ajaxSettings","ajaxHandleResponses","s","responses","ct","finalDataType","firstDataType","contents","shift","mimeType","getResponseHeader","converters","ajaxConvert","response","isSuccess","conv2","current","conv","prev","responseFields","dataFilter","split","throws","state","error","arr","getProto","Object","getPrototypeOf","hasOwn","hasOwnProperty","fnToString","ObjectFunctionString","version","rtrim","jquery","constructor","toArray","num","pushStack","prevObject","last","len","sort","splice","copy","copyIsArray"Line truncated
+15
View File
@@ -0,0 +1,15 @@
/*!
* Lightbox v2.11.5
* by Lokesh Dhakar
*
* More info:
* http://lokeshdhakar.com/projects/lightbox2/
*
* Copyright Lokesh Dhakar
* Released under the MIT license
* https://github.com/lokesh/lightbox2/blob/master/LICENSE
*
* @preserve
*/
!function(a,b){"function"==typeof define&&define.amd?define(["jquery"],b):"object"==typeof exports?module.exports=b(require("jquery")):a.lightbox=b(a.jQuery)}(this,function(a){function b(b){this.album=[],this.currentImageIndex=void 0,this.init(),this.options=a.extend({},this.constructor.defaults),this.option(b)}return b.defaults={albumLabel:"Image %1 of %2",alwaysShowNavOnTouchDevices:!1,fadeDuration:600,fitImagesInViewport:!0,imageFadeDuration:600,positionFromTop:50,resizeDuration:700,showImageNumberLabel:!0,wrapAround:!1,disableScrolling:!1,sanitizeTitle:!1},b.prototype.option=function(b){a.extend(this.options,b)},b.prototype.imageCountLabel=function(a,b){return this.options.albumLabel.replace(/%1/g,a).replace(/%2/g,b)},b.prototype.init=function(){var b=this;a(document).ready(function(){b.enable(),b.build()})},b.prototype.enable=function(){var b=this;a("body").on("click","a[rel^=lightbox], area[rel^=lightbox], a[data-lightbox], area[data-lightbox]",function(c){return b.start(a(c.currentTarget)),!1})},b.prototype.build=function(){if(!(a("#lightbox").length>0)){var b=this;a('<div id="lightboxOverlay" tabindex="-1" class="lightboxOverlay"></div><div id="lightbox" tabindex="-1" class="lightbox"><div class="lb-outerContainer"><div class="lb-container"><img class="lb-image" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" alt=""/><div class="lb-nav"><a class="lb-prev" role="button" tabindex="0" aria-label="Previous image" href="" ></a><a class="lb-next" role="button" tabindex="0" aria-label="Next image" href="" ></a></div><div class="lb-loader"><a class="lb-cancel" role="button" tabindex="0"></a></div></div></div><div class="lb-dataContainer"><div class="lb-data"><div class="lb-details"><span class="lb-caption"></span><span class="lb-number"></span></div><div class="lb-closeContainer"><a class="lb-close" role="button" tabindex="0"></a></div></div></div></div>').appendTo(a("body")),this.$lightbox=a("#lightbox"),this.$overlay=a("#lightboxOverlay"),this.$outerContainer=this.$lightbox.find(".lb-outerContainer"),this.$container=this.$lightbox.find(".lb-container"),this.$image=this.$lightbox.find(".lb-image"),this.$nav=this.$lightbox.find(".lb-nav"),this.containerPadding={top:parseInt(this.$container.css("padding-top"),10),right:parseInt(this.$container.css("padding-right"),10),bottom:parseInt(this.$container.css("padding-bottom"),10),left:parseInt(this.$container.css("padding-left"),10)},this.imageBorderWidth={top:parseInt(this.$image.css("border-top-width"),10),right:parseInt(this.$image.css("border-right-width"),10),bottom:parseInt(this.$image.css("border-bottom-width"),10),left:parseInt(this.$image.css("border-left-width"),10)},this.$overlay.hide().on("click",function(){return b.end(),!1}),this.$lightbox.hide().on("click",function(c){"lightbox"===a(c.target).attr("id")&&b.end()}),this.$outerContainer.on("click",function(c){return"lightbox"===a(c.target).attr("id")&&b.end(),!1}),this.$lightbox.find(".lb-prev").on("click",function(){return 0===b.currentImageIndex?b.changeImage(b.album.length-1):b.changeImage(b.currentImageIndex-1),!1}),this.$lightbox.find(".lb-next").on("click",function(){return b.currentImageIndex===b.album.length-1?b.changeImage(0):b.changeImage(b.currentImageIndex+1),!1}),this.$nav.on("mousedown",function(a){3===a.which&&(b.$nav.css("pointer-events","none"),b.$lightbox.one("contextmenu",function(){setTimeout(function(){this.$nav.css("pointer-events","auto")}.bind(b),0)}))}),this.$lightbox.find(".lb-loader, .lb-close").on("click keyup",function(a){if("click"===a.type||"keyup"===a.type&&(13===a.which||32===a.which))return b.end(),!1})}},b.prototype.start=function(b){function c(a){d.album.push({alt:a.attr("data-alt"),link:a.attr("href"),title:a.attr("data-title")||a.attr("title")})}var d=this,e=a(window);e.on("resize",a.proxy(this.sizeOverlay,this)),this.sizeOverlay(),this.album=[];var f,g=0,h=b.attr("data-lightbox");if(h){f=a(b.prop("tagName")+'[data-lightbox="'+h+'"]');for(var i=0;i<f.length;i=++i)c(a(f[i])),f[i]===b[0]&&(g=i)}else if("lightbox"===b.attr("rel"))c(b);else{f=a(b.prop("tagName")+'[rel="'+b.attr("rel")+'"]');for(var j=0;j<f.length;j=++j)c(a(f[j])),f[j]===b[0]&&(g=j)}var k=e.scrollTop()+this.options.positionFromTop,l=e.scrollLeft();this.$lightbox.css({top:k+"px",left:l+"px"}).fadeIn(this.options.fadeDuration),this.options.disableScrolling&&a("body").addClass("lb-disable-scrolling"),this.changeImage(g)},b.prototype.changeImage=function(b){var c=this,d=this.album[b].link,e=d.split(".").slice(-1)[0],f=this.$lightbox.find(".lb-image");this.disableKeyboardNav(),this.$overlay.fadeIn(this.options.fadeDuration),a(".lb-loader").fadeIn("slow"),this.$lightbox.find(".lb-image, .lb-nav, .lb-prev, .lb-next, .lb-dataContainer, .lb-numbers, .lb-caption").hide(),this.$outerContainer.addClass("animating");var g=new Image;g.onload=function(){var h,i,j,k,l,m;f.attr({alt:c.album[b].alt,src:d}),a(g),f.width(g.width),f.height(g.height);var n=g.width/g.height;m=a(windLine truncated
//# sourceMappingURL=lightbox.min.map
+87
View File
@@ -36,4 +36,91 @@ class Helper {
return ($dialogShowFrom <= $today && $until > $today); return ($dialogShowFrom <= $today && $until > $today);
} }
/**
* Generate an obfuscated email link to protect against automated spambot harvesting.
* Raw HTML contains no plain email address or mailto: link.
* Splitting into data attributes with CSS bidi-override fallback renders correctly visually,
* while JavaScript dynamically activates the live mailto link for real human visitors.
*
* @param string $email
* @param string|null $label Optional text/label before or wrapping the email
* @param array $attrs Optional HTML attributes (class, style, title, icon, etc.)
* @return string
*/
public static function obfuscateEmail($email, $label = null, $attrs = []) {
if (strpos($email, '@') === false) {
return htmlspecialchars($email);
}
list($user, $domainPart) = explode('@', $email, 2);
$lastDot = strrpos($domainPart, '.');
if ($lastDot !== false) {
$domain = substr($domainPart, 0, $lastDot);
$tld = substr($domainPart, $lastDot + 1);
} else {
$domain = $domainPart;
$tld = '';
}
$reversed = strrev($email);
$baseClass = isset($attrs['class']) ? $attrs['class'] . ' mail-obf' : 'mail-obf';
$title = isset($attrs['title']) ? ' title="' . htmlspecialchars($attrs['title']) . '"' : '';
$style = isset($attrs['style']) ? ' style="' . htmlspecialchars($attrs['style']) . '"' : '';
$id = isset($attrs['id']) ? ' id="' . htmlspecialchars($attrs['id']) . '"' : '';
$content = '';
if (isset($attrs['icon']) && !empty($attrs['icon'])) {
$content .= $attrs['icon'] . ' ';
}
if ($label !== null && $label !== '') {
$content .= htmlspecialchars($label) . ' ';
}
$content .= '<span class="mail-val c-rev">' . htmlspecialchars($reversed) . '</span>';
return sprintf(
'<a href="javascript:void(0);" class="%s" data-usr="%s" data-dom="%s" data-tld="%s"%s%s%s>%s</a>',
htmlspecialchars($baseClass),
htmlspecialchars($user),
htmlspecialchars($domain),
htmlspecialchars($tld),
$title,
$style,
$id,
$content
);
}
/**
* Obfuscate plain text email (non-link).
*/
public static function obfuscateEmailText($email, $attrs = []) {
if (strpos($email, '@') === false) {
return htmlspecialchars($email);
}
list($user, $domainPart) = explode('@', $email, 2);
$lastDot = strrpos($domainPart, '.');
if ($lastDot !== false) {
$domain = substr($domainPart, 0, $lastDot);
$tld = substr($domainPart, $lastDot + 1);
} else {
$domain = $domainPart;
$tld = '';
}
$reversed = strrev($email);
$baseClass = isset($attrs['class']) ? $attrs['class'] . ' mail-obf-text' : 'mail-obf-text';
$style = isset($attrs['style']) ? ' style="' . htmlspecialchars($attrs['style']) . '"' : '';
return sprintf(
'<span class="%s" data-usr="%s" data-dom="%s" data-tld="%s"%s><span class="mail-val c-rev">%s</span></span>',
htmlspecialchars($baseClass),
htmlspecialchars($user),
htmlspecialchars($domain),
htmlspecialchars($tld),
$style,
htmlspecialchars($reversed)
);
}
} }
+1 -1
View File
@@ -13,7 +13,7 @@
* @copyright 2012 - 2020 Marcus Bointon * @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski * @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost * @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License * @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT * @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. * FITNESS FOR A PARTICULAR PURPOSE.
-139
View File
@@ -1,139 +0,0 @@
<?php
/**
* PHPMailer - PHP email creation and transport class.
* PHP Version 5.5.
*
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
*
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
* @author Brent R. Matzelle (original founder)
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*/
namespace PHPMailer\PHPMailer;
use League\OAuth2\Client\Grant\RefreshToken;
use League\OAuth2\Client\Provider\AbstractProvider;
use League\OAuth2\Client\Token\AccessToken;
/**
* OAuth - OAuth2 authentication wrapper class.
* Uses the oauth2-client package from the League of Extraordinary Packages.
*
* @see http://oauth2-client.thephpleague.com
*
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
*/
class OAuth implements OAuthTokenProvider
{
/**
* An instance of the League OAuth Client Provider.
*
* @var AbstractProvider
*/
protected $provider;
/**
* The current OAuth access token.
*
* @var AccessToken
*/
protected $oauthToken;
/**
* The user's email address, usually used as the login ID
* and also the from address when sending email.
*
* @var string
*/
protected $oauthUserEmail = '';
/**
* The client secret, generated in the app definition of the service you're connecting to.
*
* @var string
*/
protected $oauthClientSecret = '';
/**
* The client ID, generated in the app definition of the service you're connecting to.
*
* @var string
*/
protected $oauthClientId = '';
/**
* The refresh token, used to obtain new AccessTokens.
*
* @var string
*/
protected $oauthRefreshToken = '';
/**
* OAuth constructor.
*
* @param array $options Associative array containing
* `provider`, `userName`, `clientSecret`, `clientId` and `refreshToken` elements
*/
public function __construct($options)
{
$this->provider = $options['provider'];
$this->oauthUserEmail = $options['userName'];
$this->oauthClientSecret = $options['clientSecret'];
$this->oauthClientId = $options['clientId'];
$this->oauthRefreshToken = $options['refreshToken'];
}
/**
* Get a new RefreshToken.
*
* @return RefreshToken
*/
protected function getGrant()
{
return new RefreshToken();
}
/**
* Get a new AccessToken.
*
* @return AccessToken
*/
protected function getToken()
{
return $this->provider->getAccessToken(
$this->getGrant(),
['refresh_token' => $this->oauthRefreshToken]
);
}
/**
* Generate a base64-encoded OAuth token.
*
* @return string
*/
public function getOauth64()
{
//Get a new token if it's not available or has expired
if (null === $this->oauthToken || $this->oauthToken->hasExpired()) {
$this->oauthToken = $this->getToken();
}
return base64_encode(
'user=' .
$this->oauthUserEmail .
"\001auth=Bearer " .
$this->oauthToken .
"\001\001"
);
}
}
-44
View File
@@ -1,44 +0,0 @@
<?php
/**
* PHPMailer - PHP email creation and transport class.
* PHP Version 5.5.
*
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
*
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
* @author Brent R. Matzelle (original founder)
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*/
namespace PHPMailer\PHPMailer;
/**
* OAuthTokenProvider - OAuth2 token provider interface.
* Provides base64 encoded OAuth2 auth strings for SMTP authentication.
*
* @see OAuth
* @see SMTP::authenticate()
*
* @author Peter Scopes (pdscopes)
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
*/
interface OAuthTokenProvider
{
/**
* Generate a base64-encoded OAuth token ensuring that the access token has not expired.
* The string to be base 64 encoded should be in the form:
* "user=<user_email_address>\001auth=Bearer <access_token>\001\001"
*
* @return string
*/
public function getOauth64();
}
+285 -49
View File
@@ -13,7 +13,7 @@
* @copyright 2012 - 2020 Marcus Bointon * @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski * @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost * @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License * @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT * @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. * FITNESS FOR A PARTICULAR PURPOSE.
@@ -152,8 +152,7 @@ class PHPMailer
* Only supported in simple alt or alt_inline message types * Only supported in simple alt or alt_inline message types
* To generate iCal event structures, use classes like EasyPeasyICS or iCalcreator. * To generate iCal event structures, use classes like EasyPeasyICS or iCalcreator.
* *
* @see http://sprain.ch/blog/downloads/php-class-easypeasyics-create-ical-files-with-php/ * @see https://kigkonsult.se/iCalcreator/
* @see http://kigkonsult.se/iCalcreator/
* *
* @var string * @var string
*/ */
@@ -254,7 +253,7 @@ class PHPMailer
* You can set your own, but it must be in the format "<id@domain>", * You can set your own, but it must be in the format "<id@domain>",
* as defined in RFC5322 section 3.6.4 or it will be ignored. * as defined in RFC5322 section 3.6.4 or it will be ignored.
* *
* @see https://tools.ietf.org/html/rfc5322#section-3.6.4 * @see https://www.rfc-editor.org/rfc/rfc5322#section-3.6.4
* *
* @var string * @var string
*/ */
@@ -357,6 +356,13 @@ class PHPMailer
*/ */
public $AuthType = ''; public $AuthType = '';
/**
* SMTP SMTPXClient command attributes
*
* @var array
*/
protected $SMTPXClient = [];
/** /**
* An implementation of the PHPMailer OAuthTokenProvider interface. * An implementation of the PHPMailer OAuthTokenProvider interface.
* *
@@ -381,7 +387,7 @@ class PHPMailer
* 'DELAY' will notify you if there is an unusual delay in delivery, but the actual * 'DELAY' will notify you if there is an unusual delay in delivery, but the actual
* delivery's outcome (success or failure) is not yet decided. * delivery's outcome (success or failure) is not yet decided.
* *
* @see https://tools.ietf.org/html/rfc3461 See section 4.1 for more information about NOTIFY * @see https://www.rfc-editor.org/rfc/rfc3461.html#section-4.1 for more information about NOTIFY
*/ */
public $dsn = ''; public $dsn = '';
@@ -461,7 +467,7 @@ class PHPMailer
* Only applicable when sending via SMTP. * Only applicable when sending via SMTP.
* *
* @see https://en.wikipedia.org/wiki/Variable_envelope_return_path * @see https://en.wikipedia.org/wiki/Variable_envelope_return_path
* @see http://www.postfix.org/VERP_README.html Postfix VERP info * @see https://www.postfix.org/VERP_README.html Postfix VERP info
* *
* @var bool * @var bool
*/ */
@@ -544,10 +550,10 @@ class PHPMailer
* The function that handles the result of the send email action. * The function that handles the result of the send email action.
* It is called out by send() for each email sent. * It is called out by send() for each email sent.
* *
* Value can be any php callable: http://www.php.net/is_callable * Value can be any php callable: https://www.php.net/is_callable
* *
* Parameters: * Parameters:
* bool $result result of the send action * bool $result result of the send action
* array $to email addresses of the recipients * array $to email addresses of the recipients
* array $cc cc email addresses * array $cc cc email addresses
* array $bcc bcc email addresses * array $bcc bcc email addresses
@@ -574,6 +580,10 @@ class PHPMailer
* May be a callable to inject your own validator, but there are several built-in validators. * May be a callable to inject your own validator, but there are several built-in validators.
* The default validator uses PHP's FILTER_VALIDATE_EMAIL filter_var option. * The default validator uses PHP's FILTER_VALIDATE_EMAIL filter_var option.
* *
* If CharSet is UTF8, the validator is left at the default value,
* and you send to addresses that use non-ASCII local parts, then
* PHPMailer automatically changes to the 'eai' validator.
*
* @see PHPMailer::validateAddress() * @see PHPMailer::validateAddress()
* *
* @var string|callable * @var string|callable
@@ -653,6 +663,14 @@ class PHPMailer
*/ */
protected $ReplyToQueue = []; protected $ReplyToQueue = [];
/**
* Whether the need for SMTPUTF8 has been detected. Set by
* preSend() if necessary.
*
* @var bool
*/
public $UseSMTPUTF8 = false;
/** /**
* The array of attachments. * The array of attachments.
* *
@@ -750,7 +768,7 @@ class PHPMailer
* *
* @var string * @var string
*/ */
const VERSION = '6.7.1'; const VERSION = '6.12.0';
/** /**
* Error severity: message only, continue processing. * Error severity: message only, continue processing.
@@ -795,7 +813,7 @@ class PHPMailer
* The maximum line length supported by mail(). * The maximum line length supported by mail().
* *
* Background: mail() will sometimes corrupt messages * Background: mail() will sometimes corrupt messages
* with headers headers longer than 65 chars, see #818. * with headers longer than 65 chars, see #818.
* *
* @var int * @var int
*/ */
@@ -896,7 +914,7 @@ class PHPMailer
} }
//Is this a PSR-3 logger? //Is this a PSR-3 logger?
if ($this->Debugoutput instanceof \Psr\Log\LoggerInterface) { if ($this->Debugoutput instanceof \Psr\Log\LoggerInterface) {
$this->Debugoutput->debug($str); $this->Debugoutput->debug(rtrim($str, "\r\n"));
return; return;
} }
@@ -1065,7 +1083,7 @@ class PHPMailer
* be modified after calling this function), addition of such addresses is delayed until send(). * be modified after calling this function), addition of such addresses is delayed until send().
* Addresses that have been added already return false, but do not throw exceptions. * Addresses that have been added already return false, but do not throw exceptions.
* *
* @param string $kind One of 'to', 'cc', 'bcc', or 'ReplyTo' * @param string $kind One of 'to', 'cc', 'bcc', or 'Reply-To'
* @param string $address The email address * @param string $address The email address
* @param string $name An optional username associated with the address * @param string $name An optional username associated with the address
* *
@@ -1104,19 +1122,22 @@ class PHPMailer
$params = [$kind, $address, $name]; $params = [$kind, $address, $name];
//Enqueue addresses with IDN until we know the PHPMailer::$CharSet. //Enqueue addresses with IDN until we know the PHPMailer::$CharSet.
//Domain is assumed to be whatever is after the last @ symbol in the address //Domain is assumed to be whatever is after the last @ symbol in the address
if (static::idnSupported() && $this->has8bitChars(substr($address, ++$pos))) { if ($this->has8bitChars(substr($address, ++$pos))) {
if ('Reply-To' !== $kind) { if (static::idnSupported()) {
if (!array_key_exists($address, $this->RecipientsQueue)) { if ('Reply-To' !== $kind) {
$this->RecipientsQueue[$address] = $params; if (!array_key_exists($address, $this->RecipientsQueue)) {
$this->RecipientsQueue[$address] = $params;
return true;
}
} elseif (!array_key_exists($address, $this->ReplyToQueue)) {
$this->ReplyToQueue[$address] = $params;
return true; return true;
} }
} elseif (!array_key_exists($address, $this->ReplyToQueue)) {
$this->ReplyToQueue[$address] = $params;
return true;
} }
//We have an 8-bit domain, but we are missing the necessary extensions to support it
//Or we are already sending to this address
return false; return false;
} }
@@ -1154,6 +1175,15 @@ class PHPMailer
*/ */
protected function addAnAddress($kind, $address, $name = '') protected function addAnAddress($kind, $address, $name = '')
{ {
if (
self::$validator === 'php' &&
((bool) preg_match('/[\x80-\xFF]/', $address))
) {
//The caller has not altered the validator and is sending to an address
//with UTF-8, so assume that they want UTF-8 support instead of failing
$this->CharSet = self::CHARSET_UTF8;
self::$validator = 'eai';
}
if (!in_array($kind, ['to', 'cc', 'bcc', 'Reply-To'])) { if (!in_array($kind, ['to', 'cc', 'bcc', 'Reply-To'])) {
$error_message = sprintf( $error_message = sprintf(
'%s: %s', '%s: %s',
@@ -1205,7 +1235,7 @@ class PHPMailer
* Uses the imap_rfc822_parse_adrlist function if the IMAP extension is available. * Uses the imap_rfc822_parse_adrlist function if the IMAP extension is available.
* Note that quotes in the name part are removed. * Note that quotes in the name part are removed.
* *
* @see http://www.andrew.cmu.edu/user/agreen1/testing/mrbs/web/Mail/RFC822.php A more careful implementation * @see https://www.andrew.cmu.edu/user/agreen1/testing/mrbs/web/Mail/RFC822.php A more careful implementation
* *
* @param string $addrstr The address list string * @param string $addrstr The address list string
* @param bool $useimap Whether to use the IMAP extension to parse the list * @param bool $useimap Whether to use the IMAP extension to parse the list
@@ -1356,6 +1386,7 @@ class PHPMailer
* * `pcre` Use old PCRE implementation; * * `pcre` Use old PCRE implementation;
* * `php` Use PHP built-in FILTER_VALIDATE_EMAIL; * * `php` Use PHP built-in FILTER_VALIDATE_EMAIL;
* * `html5` Use the pattern given by the HTML5 spec for 'email' type form input elements. * * `html5` Use the pattern given by the HTML5 spec for 'email' type form input elements.
* * `eai` Use a pattern similar to the HTML5 spec for 'email' and to firefox, extended to support EAI (RFC6530).
* * `noregex` Don't use a regex: super fast, really dumb. * * `noregex` Don't use a regex: super fast, really dumb.
* Alternatively you may pass in a callable to inject your own validator, for example: * Alternatively you may pass in a callable to inject your own validator, for example:
* *
@@ -1400,7 +1431,6 @@ class PHPMailer
* * IPv6 literals: 'first.last@[IPv6:a1::]' * * IPv6 literals: 'first.last@[IPv6:a1::]'
* Not all of these will necessarily work for sending! * Not all of these will necessarily work for sending!
* *
* @see http://squiloople.com/2009/12/20/email-address-validation/
* @copyright 2009-2010 Michael Rushton * @copyright 2009-2010 Michael Rushton
* Feel free to use and redistribute this code. But please keep this copyright notice. * Feel free to use and redistribute this code. But please keep this copyright notice.
*/ */
@@ -1427,6 +1457,24 @@ class PHPMailer
'[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD', '[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD',
$address $address
); );
case 'eai':
/*
* This is the pattern used in the HTML5 spec for validation of 'email' type
* form input elements (as above), modified to accept Unicode email addresses.
* This is also more lenient than Firefox' html5 spec, in order to make the regex faster.
* 'eai' is an acronym for Email Address Internationalization.
* This validator is selected automatically if you attempt to use recipient addresses
* that contain Unicode characters in the local part.
*
* @see https://html.spec.whatwg.org/#e-mail-state-(type=email)
* @see https://en.wikipedia.org/wiki/International_email
*/
return (bool) preg_match(
'/^[-\p{L}\p{N}\p{M}.!#$%&\'*+\/=?^_`{|}~]+@[\p{L}\p{N}\p{M}](?:[\p{L}\p{N}\p{M}-]{0,61}' .
'[\p{L}\p{N}\p{M}])?(?:\.[\p{L}\p{N}\p{M}]' .
'(?:[-\p{L}\p{N}\p{M}]{0,61}[\p{L}\p{N}\p{M}])?)*$/usD',
$address
);
case 'php': case 'php':
default: default:
return filter_var($address, FILTER_VALIDATE_EMAIL) !== false; return filter_var($address, FILTER_VALIDATE_EMAIL) !== false;
@@ -1560,9 +1608,26 @@ class PHPMailer
$this->error_count = 0; //Reset errors $this->error_count = 0; //Reset errors
$this->mailHeader = ''; $this->mailHeader = '';
//The code below tries to support full use of Unicode,
//while remaining compatible with legacy SMTP servers to
//the greatest degree possible: If the message uses
//Unicode in the local parts of any addresses, it is sent
//using SMTPUTF8. If not, it it sent using
//punycode-encoded domains and plain SMTP.
if (
static::CHARSET_UTF8 === strtolower($this->CharSet) &&
($this->anyAddressHasUnicodeLocalPart($this->RecipientsQueue) ||
$this->anyAddressHasUnicodeLocalPart(array_keys($this->all_recipients)) ||
$this->anyAddressHasUnicodeLocalPart($this->ReplyToQueue) ||
$this->addressHasUnicodeLocalPart($this->From))
) {
$this->UseSMTPUTF8 = true;
}
//Dequeue recipient and Reply-To addresses with IDN //Dequeue recipient and Reply-To addresses with IDN
foreach (array_merge($this->RecipientsQueue, $this->ReplyToQueue) as $params) { foreach (array_merge($this->RecipientsQueue, $this->ReplyToQueue) as $params) {
$params[1] = $this->punyencodeAddress($params[1]); if (!$this->UseSMTPUTF8) {
$params[1] = $this->punyencodeAddress($params[1]);
}
call_user_func_array([$this, 'addAnAddress'], $params); call_user_func_array([$this, 'addAnAddress'], $params);
} }
if (count($this->to) + count($this->cc) + count($this->bcc) < 1) { if (count($this->to) + count($this->cc) + count($this->bcc) < 1) {
@@ -1571,6 +1636,10 @@ class PHPMailer
//Validate From, Sender, and ConfirmReadingTo addresses //Validate From, Sender, and ConfirmReadingTo addresses
foreach (['From', 'Sender', 'ConfirmReadingTo'] as $address_kind) { foreach (['From', 'Sender', 'ConfirmReadingTo'] as $address_kind) {
if ($this->{$address_kind} === null) {
$this->{$address_kind} = '';
continue;
}
$this->{$address_kind} = trim($this->{$address_kind}); $this->{$address_kind} = trim($this->{$address_kind});
if (empty($this->{$address_kind})) { if (empty($this->{$address_kind})) {
continue; continue;
@@ -1723,9 +1792,8 @@ class PHPMailer
//This sets the SMTP envelope sender which gets turned into a return-path header by the receiver //This sets the SMTP envelope sender which gets turned into a return-path header by the receiver
//A space after `-f` is optional, but there is a long history of its presence //A space after `-f` is optional, but there is a long history of its presence
//causing problems, so we don't use one //causing problems, so we don't use one
//Exim docs: http://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html //Exim docs: https://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html
//Sendmail docs: http://www.sendmail.org/~ca/email/man/sendmail.html //Sendmail docs: https://www.sendmail.org/~ca/email/man/sendmail.html
//Qmail docs: http://www.qmail.org/man/man8/qmail-inject.html
//Example problem: https://www.drupal.org/node/1057954 //Example problem: https://www.drupal.org/node/1057954
//PHP 5.6 workaround //PHP 5.6 workaround
@@ -1863,7 +1931,7 @@ class PHPMailer
*/ */
protected static function isPermittedPath($path) protected static function isPermittedPath($path)
{ {
//Matches scheme definition from https://tools.ietf.org/html/rfc3986#section-3.1 //Matches scheme definition from https://www.rfc-editor.org/rfc/rfc3986#section-3.1
return !preg_match('#^[a-z][a-z\d+.-]*://#i', $path); return !preg_match('#^[a-z][a-z\d+.-]*://#i', $path);
} }
@@ -1890,7 +1958,7 @@ class PHPMailer
/** /**
* Send mail using the PHP mail() function. * Send mail using the PHP mail() function.
* *
* @see http://www.php.net/manual/en/book.mail.php * @see https://www.php.net/manual/en/book.mail.php
* *
* @param string $header The message headers * @param string $header The message headers
* @param string $body The message body * @param string $body The message body
@@ -1920,9 +1988,8 @@ class PHPMailer
//This sets the SMTP envelope sender which gets turned into a return-path header by the receiver //This sets the SMTP envelope sender which gets turned into a return-path header by the receiver
//A space after `-f` is optional, but there is a long history of its presence //A space after `-f` is optional, but there is a long history of its presence
//causing problems, so we don't use one //causing problems, so we don't use one
//Exim docs: http://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html //Exim docs: https://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html
//Sendmail docs: http://www.sendmail.org/~ca/email/man/sendmail.html //Sendmail docs: https://www.sendmail.org/~ca/email/man/sendmail.html
//Qmail docs: http://www.qmail.org/man/man8/qmail-inject.html
//Example problem: https://www.drupal.org/node/1057954 //Example problem: https://www.drupal.org/node/1057954
//CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped. //CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped.
@@ -1997,6 +2064,38 @@ class PHPMailer
return $this->smtp; return $this->smtp;
} }
/**
* Provide SMTP XCLIENT attributes
*
* @param string $name Attribute name
* @param ?string $value Attribute value
*
* @return bool
*/
public function setSMTPXclientAttribute($name, $value)
{
if (!in_array($name, SMTP::$xclient_allowed_attributes)) {
return false;
}
if (isset($this->SMTPXClient[$name]) && $value === null) {
unset($this->SMTPXClient[$name]);
} elseif ($value !== null) {
$this->SMTPXClient[$name] = $value;
}
return true;
}
/**
* Get SMTP XCLIENT attributes
*
* @return array
*/
public function getSMTPXclientAttributes()
{
return $this->SMTPXClient;
}
/** /**
* Send mail via SMTP. * Send mail via SMTP.
* Returns false if there is a bad MAIL FROM, RCPT, or DATA input. * Returns false if there is a bad MAIL FROM, RCPT, or DATA input.
@@ -2019,12 +2118,20 @@ class PHPMailer
if (!$this->smtpConnect($this->SMTPOptions)) { if (!$this->smtpConnect($this->SMTPOptions)) {
throw new Exception($this->lang('smtp_connect_failed'), self::STOP_CRITICAL); throw new Exception($this->lang('smtp_connect_failed'), self::STOP_CRITICAL);
} }
//If we have recipient addresses that need Unicode support,
//but the server doesn't support it, stop here
if ($this->UseSMTPUTF8 && !$this->smtp->getServerExt('SMTPUTF8')) {
throw new Exception($this->lang('no_smtputf8'), self::STOP_CRITICAL);
}
//Sender already validated in preSend() //Sender already validated in preSend()
if ('' === $this->Sender) { if ('' === $this->Sender) {
$smtp_from = $this->From; $smtp_from = $this->From;
} else { } else {
$smtp_from = $this->Sender; $smtp_from = $this->Sender;
} }
if (count($this->SMTPXClient)) {
$this->smtp->xclient($this->SMTPXClient);
}
if (!$this->smtp->mail($smtp_from)) { if (!$this->smtp->mail($smtp_from)) {
$this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError())); $this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError()));
throw new Exception($this->ErrorInfo, self::STOP_CRITICAL); throw new Exception($this->ErrorInfo, self::STOP_CRITICAL);
@@ -2117,6 +2224,7 @@ class PHPMailer
$this->smtp->setDebugLevel($this->SMTPDebug); $this->smtp->setDebugLevel($this->SMTPDebug);
$this->smtp->setDebugOutput($this->Debugoutput); $this->smtp->setDebugOutput($this->Debugoutput);
$this->smtp->setVerp($this->do_verp); $this->smtp->setVerp($this->do_verp);
$this->smtp->setSMTPUTF8($this->UseSMTPUTF8);
if ($this->Host === null) { if ($this->Host === null) {
$this->Host = 'localhost'; $this->Host = 'localhost';
} }
@@ -2187,10 +2295,17 @@ class PHPMailer
$this->smtp->hello($hello); $this->smtp->hello($hello);
//Automatically enable TLS encryption if: //Automatically enable TLS encryption if:
//* it's not disabled //* it's not disabled
//* we are not connecting to localhost
//* we have openssl extension //* we have openssl extension
//* we are not already using SSL //* we are not already using SSL
//* the server offers STARTTLS //* the server offers STARTTLS
if ($this->SMTPAutoTLS && $sslext && 'ssl' !== $secure && $this->smtp->getServerExt('STARTTLS')) { if (
$this->SMTPAutoTLS &&
$this->Host !== 'localhost' &&
$sslext &&
$secure !== 'ssl' &&
$this->smtp->getServerExt('STARTTLS')
) {
$tls = true; $tls = true;
} }
if ($tls) { if ($tls) {
@@ -2307,6 +2422,7 @@ class PHPMailer
'smtp_detail' => 'Detail: ', 'smtp_detail' => 'Detail: ',
'smtp_error' => 'SMTP server error: ', 'smtp_error' => 'SMTP server error: ',
'variable_set' => 'Cannot set or reset variable: ', 'variable_set' => 'Cannot set or reset variable: ',
'no_smtputf8' => 'Server does not support SMTPUTF8 needed to send to Unicode addresses',
]; ];
if (empty($lang_path)) { if (empty($lang_path)) {
//Calculate an absolute path so it can work if CWD is not here //Calculate an absolute path so it can work if CWD is not here
@@ -2656,7 +2772,7 @@ class PHPMailer
} }
//Only allow a custom message ID if it conforms to RFC 5322 section 3.6.4 //Only allow a custom message ID if it conforms to RFC 5322 section 3.6.4
//https://tools.ietf.org/html/rfc5322#section-3.6.4 //https://www.rfc-editor.org/rfc/rfc5322#section-3.6.4
if ( if (
'' !== $this->MessageID && '' !== $this->MessageID &&
preg_match( preg_match(
@@ -2821,7 +2937,9 @@ class PHPMailer
$bodyEncoding = $this->Encoding; $bodyEncoding = $this->Encoding;
$bodyCharSet = $this->CharSet; $bodyCharSet = $this->CharSet;
//Can we do a 7-bit downgrade? //Can we do a 7-bit downgrade?
if (static::ENCODING_8BIT === $bodyEncoding && !$this->has8bitChars($this->Body)) { if ($this->UseSMTPUTF8) {
$bodyEncoding = static::ENCODING_8BIT;
} elseif (static::ENCODING_8BIT === $bodyEncoding && !$this->has8bitChars($this->Body)) {
$bodyEncoding = static::ENCODING_7BIT; $bodyEncoding = static::ENCODING_7BIT;
//All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit //All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit
$bodyCharSet = static::CHARSET_ASCII; $bodyCharSet = static::CHARSET_ASCII;
@@ -3458,7 +3576,8 @@ class PHPMailer
/** /**
* Encode a header value (not including its label) optimally. * Encode a header value (not including its label) optimally.
* Picks shortest of Q, B, or none. Result includes folding if needed. * Picks shortest of Q, B, or none. Result includes folding if needed.
* See RFC822 definitions for phrase, comment and text positions. * See RFC822 definitions for phrase, comment and text positions,
* and RFC2047 for inline encodings.
* *
* @param string $str The header value to encode * @param string $str The header value to encode
* @param string $position What context the string will be used in * @param string $position What context the string will be used in
@@ -3467,6 +3586,11 @@ class PHPMailer
*/ */
public function encodeHeader($str, $position = 'text') public function encodeHeader($str, $position = 'text')
{ {
$position = strtolower($position);
if ($this->UseSMTPUTF8 && !("comment" === $position)) {
return trim(static::normalizeBreaks($str));
}
$matchcount = 0; $matchcount = 0;
switch (strtolower($position)) { switch (strtolower($position)) {
case 'phrase': case 'phrase':
@@ -3581,7 +3705,7 @@ class PHPMailer
* without breaking lines within a character. * without breaking lines within a character.
* Adapted from a function by paravoid. * Adapted from a function by paravoid.
* *
* @see http://www.php.net/manual/en/function.mb-encode-mimeheader.php#60283 * @see https://www.php.net/manual/en/function.mb-encode-mimeheader.php#60283
* *
* @param string $str multi-byte text to wrap encode * @param string $str multi-byte text to wrap encode
* @param string $linebreak string to use as linefeed/end-of-line * @param string $linebreak string to use as linefeed/end-of-line
@@ -3637,7 +3761,7 @@ class PHPMailer
/** /**
* Encode a string using Q encoding. * Encode a string using Q encoding.
* *
* @see http://tools.ietf.org/html/rfc2047#section-4.2 * @see https://www.rfc-editor.org/rfc/rfc2047#section-4.2
* *
* @param string $str the text to encode * @param string $str the text to encode
* @param string $position Where the text is going to be used, see the RFC for what that means * @param string $position Where the text is going to be used, see the RFC for what that means
@@ -4047,6 +4171,79 @@ class PHPMailer
$this->CustomHeader = []; $this->CustomHeader = [];
} }
/**
* Clear a specific custom header by name or name and value.
* $name value can be overloaded to contain
* both header name and value (name:value).
*
* @param string $name Custom header name
* @param string|null $value Header value
*
* @return bool True if a header was replaced successfully
*/
public function clearCustomHeader($name, $value = null)
{
if (null === $value && strpos($name, ':') !== false) {
//Value passed in as name:value
list($name, $value) = explode(':', $name, 2);
}
$name = trim($name);
$value = (null === $value) ? null : trim($value);
foreach ($this->CustomHeader as $k => $pair) {
if ($pair[0] == $name) {
// We remove the header if the value is not provided or it matches.
if (null === $value || $pair[1] == $value) {
unset($this->CustomHeader[$k]);
}
}
}
return true;
}
/**
* Replace a custom header.
* $name value can be overloaded to contain
* both header name and value (name:value).
*
* @param string $name Custom header name
* @param string|null $value Header value
*
* @return bool True if a header was replaced successfully
* @throws Exception
*/
public function replaceCustomHeader($name, $value = null)
{
if (null === $value && strpos($name, ':') !== false) {
//Value passed in as name:value
list($name, $value) = explode(':', $name, 2);
}
$name = trim($name);
$value = (null === $value) ? '' : trim($value);
$replaced = false;
foreach ($this->CustomHeader as $k => $pair) {
if ($pair[0] == $name) {
if ($replaced) {
unset($this->CustomHeader[$k]);
continue;
}
if (strpbrk($name . $value, "\r\n") !== false) {
if ($this->exceptions) {
throw new Exception($this->lang('invalid_header'));
}
return false;
}
$this->CustomHeader[$k] = [$name, $value];
$replaced = true;
}
}
return true;
}
/** /**
* Add an error message to the error container. * Add an error message to the error container.
* *
@@ -4058,7 +4255,7 @@ class PHPMailer
if ('smtp' === $this->Mailer && null !== $this->smtp) { if ('smtp' === $this->Mailer && null !== $this->smtp) {
$lasterror = $this->smtp->getError(); $lasterror = $this->smtp->getError();
if (!empty($lasterror['error'])) { if (!empty($lasterror['error'])) {
$msg .= $this->lang('smtp_error') . $lasterror['error']; $msg .= ' ' . $this->lang('smtp_error') . $lasterror['error'];
if (!empty($lasterror['detail'])) { if (!empty($lasterror['detail'])) {
$msg .= ' ' . $this->lang('smtp_detail') . $lasterror['detail']; $msg .= ' ' . $this->lang('smtp_detail') . $lasterror['detail'];
} }
@@ -4102,7 +4299,7 @@ class PHPMailer
$result = $_SERVER['SERVER_NAME']; $result = $_SERVER['SERVER_NAME'];
} elseif (function_exists('gethostname') && gethostname() !== false) { } elseif (function_exists('gethostname') && gethostname() !== false) {
$result = gethostname(); $result = gethostname();
} elseif (php_uname('n') !== false) { } elseif (php_uname('n') !== '') {
$result = php_uname('n'); $result = php_uname('n');
} }
if (!static::isValidHost($result)) { if (!static::isValidHost($result)) {
@@ -4127,7 +4324,7 @@ class PHPMailer
empty($host) empty($host)
|| !is_string($host) || !is_string($host)
|| strlen($host) > 256 || strlen($host) > 256
|| !preg_match('/^([a-zA-Z\d.-]*|\[[a-fA-F\d:]+\])$/', $host) || !preg_match('/^([a-z\d.-]*|\[[a-f\d:]+\])$/i', $host)
) { ) {
return false; return false;
} }
@@ -4141,10 +4338,49 @@ class PHPMailer
//Is it a valid IPv4 address? //Is it a valid IPv4 address?
return filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false; return filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false;
} }
//Is it a syntactically valid hostname (when embeded in a URL)? //Is it a syntactically valid hostname (when embedded in a URL)?
return filter_var('http://' . $host, FILTER_VALIDATE_URL) !== false; return filter_var('https://' . $host, FILTER_VALIDATE_URL) !== false;
} }
/**
* Check whether the supplied address uses Unicode in the local part.
*
* @return bool
*/
protected function addressHasUnicodeLocalPart($address)
{
return (bool) preg_match('/[\x80-\xFF].*@/', $address);
}
/**
* Check whether any of the supplied addresses use Unicode in the local part.
*
* @return bool
*/
protected function anyAddressHasUnicodeLocalPart($addresses)
{
foreach ($addresses as $address) {
if (is_array($address)) {
$address = $address[0];
}
if ($this->addressHasUnicodeLocalPart($address)) {
return true;
}
}
return false;
}
/**
* Check whether the message requires SMTPUTF8 based on what's known so far.
*
* @return bool
*/
public function needsSMTPUTF8()
{
return $this->UseSMTPUTF8;
}
/** /**
* Get an error message in the current language. * Get an error message in the current language.
* *
@@ -4553,7 +4789,7 @@ class PHPMailer
* Multi-byte-safe pathinfo replacement. * Multi-byte-safe pathinfo replacement.
* Drop-in replacement for pathinfo(), but multibyte- and cross-platform-safe. * Drop-in replacement for pathinfo(), but multibyte- and cross-platform-safe.
* *
* @see http://www.php.net/manual/en/function.pathinfo.php#107461 * @see https://www.php.net/manual/en/function.pathinfo.php#107461
* *
* @param string $path A filename or path, does not need to exist as a file * @param string $path A filename or path, does not need to exist as a file
* @param int|string $options Either a PATHINFO_* constant, * @param int|string $options Either a PATHINFO_* constant,
@@ -4788,7 +5024,7 @@ class PHPMailer
* Uses the 'relaxed' algorithm from RFC6376 section 3.4.2. * Uses the 'relaxed' algorithm from RFC6376 section 3.4.2.
* Canonicalized headers should *always* use CRLF, regardless of mailer setting. * Canonicalized headers should *always* use CRLF, regardless of mailer setting.
* *
* @see https://tools.ietf.org/html/rfc6376#section-3.4.2 * @see https://www.rfc-editor.org/rfc/rfc6376#section-3.4.2
* *
* @param string $signHeader Header * @param string $signHeader Header
* *
@@ -4800,7 +5036,7 @@ class PHPMailer
$signHeader = static::normalizeBreaks($signHeader, self::CRLF); $signHeader = static::normalizeBreaks($signHeader, self::CRLF);
//Unfold header lines //Unfold header lines
//Note PCRE \s is too broad a definition of whitespace; RFC5322 defines it as `[ \t]` //Note PCRE \s is too broad a definition of whitespace; RFC5322 defines it as `[ \t]`
//@see https://tools.ietf.org/html/rfc5322#section-2.2 //@see https://www.rfc-editor.org/rfc/rfc5322#section-2.2
//That means this may break if you do something daft like put vertical tabs in your headers. //That means this may break if you do something daft like put vertical tabs in your headers.
$signHeader = preg_replace('/\r\n[ \t]+/', ' ', $signHeader); $signHeader = preg_replace('/\r\n[ \t]+/', ' ', $signHeader);
//Break headers out into an array //Break headers out into an array
@@ -4832,7 +5068,7 @@ class PHPMailer
* Uses the 'simple' algorithm from RFC6376 section 3.4.3. * Uses the 'simple' algorithm from RFC6376 section 3.4.3.
* Canonicalized bodies should *always* use CRLF, regardless of mailer setting. * Canonicalized bodies should *always* use CRLF, regardless of mailer setting.
* *
* @see https://tools.ietf.org/html/rfc6376#section-3.4.3 * @see https://www.rfc-editor.org/rfc/rfc6376#section-3.4.3
* *
* @param string $body Message Body * @param string $body Message Body
* *
@@ -4868,7 +5104,7 @@ class PHPMailer
$DKIMquery = 'dns/txt'; //Query method $DKIMquery = 'dns/txt'; //Query method
$DKIMtime = time(); $DKIMtime = time();
//Always sign these headers without being asked //Always sign these headers without being asked
//Recommended list from https://tools.ietf.org/html/rfc6376#section-5.4.1 //Recommended list from https://www.rfc-editor.org/rfc/rfc6376#section-5.4.1
$autoSignHeaders = [ $autoSignHeaders = [
'from', 'from',
'to', 'to',
@@ -4974,7 +5210,7 @@ class PHPMailer
} }
//The DKIM-Signature header is included in the signature *except for* the value of the `b` tag //The DKIM-Signature header is included in the signature *except for* the value of the `b` tag
//which is appended after calculating the signature //which is appended after calculating the signature
//https://tools.ietf.org/html/rfc6376#section-3.5 //https://www.rfc-editor.org/rfc/rfc6376#section-3.5
$dkimSignatureHeader = 'DKIM-Signature: v=1;' . $dkimSignatureHeader = 'DKIM-Signature: v=1;' .
' d=' . $this->DKIM_domain . ';' . ' d=' . $this->DKIM_domain . ';' .
' s=' . $this->DKIM_selector . ';' . static::$LE . ' s=' . $this->DKIM_selector . ';' . static::$LE .
-467
View File
@@ -1,467 +0,0 @@
<?php
/**
* PHPMailer POP-Before-SMTP Authentication Class.
* PHP Version 5.5.
*
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
*
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
* @author Brent R. Matzelle (original founder)
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*/
namespace PHPMailer\PHPMailer;
/**
* PHPMailer POP-Before-SMTP Authentication Class.
* Specifically for PHPMailer to use for RFC1939 POP-before-SMTP authentication.
* 1) This class does not support APOP authentication.
* 2) Opening and closing lots of POP3 connections can be quite slow. If you need
* to send a batch of emails then just perform the authentication once at the start,
* and then loop through your mail sending script. Providing this process doesn't
* take longer than the verification period lasts on your POP3 server, you should be fine.
* 3) This is really ancient technology; you should only need to use it to talk to very old systems.
* 4) This POP3 class is deliberately lightweight and incomplete, implementing just
* enough to do authentication.
* If you want a more complete class there are other POP3 classes for PHP available.
*
* @author Richard Davey (original author) <rich@corephp.co.uk>
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
*/
class POP3
{
/**
* The POP3 PHPMailer Version number.
*
* @var string
*/
const VERSION = '6.7.1';
/**
* Default POP3 port number.
*
* @var int
*/
const DEFAULT_PORT = 110;
/**
* Default timeout in seconds.
*
* @var int
*/
const DEFAULT_TIMEOUT = 30;
/**
* POP3 class debug output mode.
* Debug output level.
* Options:
* @see POP3::DEBUG_OFF: No output
* @see POP3::DEBUG_SERVER: Server messages, connection/server errors
* @see POP3::DEBUG_CLIENT: Client and Server messages, connection/server errors
*
* @var int
*/
public $do_debug = self::DEBUG_OFF;
/**
* POP3 mail server hostname.
*
* @var string
*/
public $host;
/**
* POP3 port number.
*
* @var int
*/
public $port;
/**
* POP3 Timeout Value in seconds.
*
* @var int
*/
public $tval;
/**
* POP3 username.
*
* @var string
*/
public $username;
/**
* POP3 password.
*
* @var string
*/
public $password;
/**
* Resource handle for the POP3 connection socket.
*
* @var resource
*/
protected $pop_conn;
/**
* Are we connected?
*
* @var bool
*/
protected $connected = false;
/**
* Error container.
*
* @var array
*/
protected $errors = [];
/**
* Line break constant.
*/
const LE = "\r\n";
/**
* Debug level for no output.
*
* @var int
*/
const DEBUG_OFF = 0;
/**
* Debug level to show server -> client messages
* also shows clients connection errors or errors from server
*
* @var int
*/
const DEBUG_SERVER = 1;
/**
* Debug level to show client -> server and server -> client messages.
*
* @var int
*/
const DEBUG_CLIENT = 2;
/**
* Simple static wrapper for all-in-one POP before SMTP.
*
* @param string $host The hostname to connect to
* @param int|bool $port The port number to connect to
* @param int|bool $timeout The timeout value
* @param string $username
* @param string $password
* @param int $debug_level
*
* @return bool
*/
public static function popBeforeSmtp(
$host,
$port = false,
$timeout = false,
$username = '',
$password = '',
$debug_level = 0
) {
$pop = new self();
return $pop->authorise($host, $port, $timeout, $username, $password, $debug_level);
}
/**
* Authenticate with a POP3 server.
* A connect, login, disconnect sequence
* appropriate for POP-before SMTP authorisation.
*
* @param string $host The hostname to connect to
* @param int|bool $port The port number to connect to
* @param int|bool $timeout The timeout value
* @param string $username
* @param string $password
* @param int $debug_level
*
* @return bool
*/
public function authorise($host, $port = false, $timeout = false, $username = '', $password = '', $debug_level = 0)
{
$this->host = $host;
//If no port value provided, use default
if (false === $port) {
$this->port = static::DEFAULT_PORT;
} else {
$this->port = (int) $port;
}
//If no timeout value provided, use default
if (false === $timeout) {
$this->tval = static::DEFAULT_TIMEOUT;
} else {
$this->tval = (int) $timeout;
}
$this->do_debug = $debug_level;
$this->username = $username;
$this->password = $password;
//Reset the error log
$this->errors = [];
//Connect
$result = $this->connect($this->host, $this->port, $this->tval);
if ($result) {
$login_result = $this->login($this->username, $this->password);
if ($login_result) {
$this->disconnect();
return true;
}
}
//We need to disconnect regardless of whether the login succeeded
$this->disconnect();
return false;
}
/**
* Connect to a POP3 server.
*
* @param string $host
* @param int|bool $port
* @param int $tval
*
* @return bool
*/
public function connect($host, $port = false, $tval = 30)
{
//Are we already connected?
if ($this->connected) {
return true;
}
//On Windows this will raise a PHP Warning error if the hostname doesn't exist.
//Rather than suppress it with @fsockopen, capture it cleanly instead
set_error_handler([$this, 'catchWarning']);
if (false === $port) {
$port = static::DEFAULT_PORT;
}
//Connect to the POP3 server
$errno = 0;
$errstr = '';
$this->pop_conn = fsockopen(
$host, //POP3 Host
$port, //Port #
$errno, //Error Number
$errstr, //Error Message
$tval
); //Timeout (seconds)
//Restore the error handler
restore_error_handler();
//Did we connect?
if (false === $this->pop_conn) {
//It would appear not...
$this->setError(
"Failed to connect to server $host on port $port. errno: $errno; errstr: $errstr"
);
return false;
}
//Increase the stream time-out
stream_set_timeout($this->pop_conn, $tval, 0);
//Get the POP3 server response
$pop3_response = $this->getResponse();
//Check for the +OK
if ($this->checkResponse($pop3_response)) {
//The connection is established and the POP3 server is talking
$this->connected = true;
return true;
}
return false;
}
/**
* Log in to the POP3 server.
* Does not support APOP (RFC 2828, 4949).
*
* @param string $username
* @param string $password
*
* @return bool
*/
public function login($username = '', $password = '')
{
if (!$this->connected) {
$this->setError('Not connected to POP3 server');
return false;
}
if (empty($username)) {
$username = $this->username;
}
if (empty($password)) {
$password = $this->password;
}
//Send the Username
$this->sendString("USER $username" . static::LE);
$pop3_response = $this->getResponse();
if ($this->checkResponse($pop3_response)) {
//Send the Password
$this->sendString("PASS $password" . static::LE);
$pop3_response = $this->getResponse();
if ($this->checkResponse($pop3_response)) {
return true;
}
}
return false;
}
/**
* Disconnect from the POP3 server.
*/
public function disconnect()
{
// If could not connect at all, no need to disconnect
if ($this->pop_conn === false) {
return;
}
$this->sendString('QUIT' . static::LE);
// RFC 1939 shows POP3 server sending a +OK response to the QUIT command.
// Try to get it. Ignore any failures here.
try {
$this->getResponse();
} catch (Exception $e) {
//Do nothing
}
//The QUIT command may cause the daemon to exit, which will kill our connection
//So ignore errors here
try {
@fclose($this->pop_conn);
} catch (Exception $e) {
//Do nothing
}
// Clean up attributes.
$this->connected = false;
$this->pop_conn = false;
}
/**
* Get a response from the POP3 server.
*
* @param int $size The maximum number of bytes to retrieve
*
* @return string
*/
protected function getResponse($size = 128)
{
$response = fgets($this->pop_conn, $size);
if ($this->do_debug >= self::DEBUG_SERVER) {
echo 'Server -> Client: ', $response;
}
return $response;
}
/**
* Send raw data to the POP3 server.
*
* @param string $string
*
* @return int
*/
protected function sendString($string)
{
if ($this->pop_conn) {
if ($this->do_debug >= self::DEBUG_CLIENT) { //Show client messages when debug >= 2
echo 'Client -> Server: ', $string;
}
return fwrite($this->pop_conn, $string, strlen($string));
}
return 0;
}
/**
* Checks the POP3 server response.
* Looks for for +OK or -ERR.
*
* @param string $string
*
* @return bool
*/
protected function checkResponse($string)
{
if (strpos($string, '+OK') !== 0) {
$this->setError("Server reported an error: $string");
return false;
}
return true;
}
/**
* Add an error to the internal error store.
* Also display debug output if it's enabled.
*
* @param string $error
*/
protected function setError($error)
{
$this->errors[] = $error;
if ($this->do_debug >= self::DEBUG_SERVER) {
echo '<pre>';
foreach ($this->errors as $e) {
print_r($e);
}
echo '</pre>';
}
}
/**
* Get an array of error messages, if any.
*
* @return array
*/
public function getErrors()
{
return $this->errors;
}
/**
* POP3 connection error handler.
*
* @param int $errno
* @param string $errstr
* @param string $errfile
* @param int $errline
*/
protected function catchWarning($errno, $errstr, $errfile, $errline)
{
$this->setError(
'Connecting to the POP3 server raised a PHP warning:' .
"errno: $errno errstr: $errstr; errfile: $errfile; errline: $errline"
);
}
}
Loaded 100 of 208 files, more files were not shown because too many files have changed in this diff. Show more