Email Separator
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ultimate Email Domain Separator - The Most Comprehensive Tool</title>
<meta name="description" content="The ultimate email domain separator, organizing each domain extension in its own boxed-in area, supporting all ccTLDs, regional SLDs, gTLDs, webmails, and temporary domains with DMARC compatibility checks and mobile-first design.">
<meta name="keywords" content="email separator, email organizer, email domain separator, ccTLD, regional SLD, temporary email, DMARC, email security, mobile responsive">
<link href="https://fonts.googleapis.com/css2?family=Baloo+Bhaijaan+2:wght@400;500;600;700&display=swap" rel="stylesheet">
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>✅</text></svg>">
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/css/toastr.min.css" />
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
:root {
--primary: #3b82f6;
--success: #28a745;
--warning: #ffc107;
--danger: #dc3545;
--info: #17a2b8;
--purple: #6f42c1;
--gray: #6c757d;
--dark: #343a40;
--light: #f8f9fa;
}
body {
background-color: var(--light);
font-family: 'Baloo Bhaijaan 2', sans-serif;
color: #333;
display: flex;
flex-direction: column;
min-height: 100vh;
overscroll-behavior: none;
}
.content { flex: 1; margin-bottom: 40px; }
.domain-card {
background: #fff;
border-radius: 12px;
border: 1px solid #e5e7eb;
transition: transform 0.3s, box-shadow 0.3s;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.domain-card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
}
.domain-card-header {
background-color: var(--primary);
color: #fff;
padding: 12px;
border-top-left-radius: 12px;
border-top-right-radius: 12px;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 1rem;
white-space: normal;
word-break: break-word;
}
.domain-card-header-actions {
display: flex;
align-items: center;
gap: 8px;
}
.domain-card-header-actions .btn {
padding: 0;
width: 40px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
background: none;
border: none;
color: #fff;
transition: background-color 0.3s;
}
.domain-card-header-actions .btn:hover {
background-color: rgba(255, 255, 255, 0.2);
}
.domain-card-header-actions .btn-danger { color: #ff4d4d; }
.domain-card-header-actions .badge {
background-color: rgba(255, 255, 255, 0.3);
color: #fff;
font-size: 0.9rem;
padding: 0.3rem 0.6rem;
border-radius: 12px;
}
.input-group {
background-color: rgba(59, 130, 246, 0.1);
border-radius: 10px;
border: 1px solid var(--primary);
}
.btn:hover:not(:disabled) {
background-color: #2563eb;
transform: scale(1.05);
}
footer {
border-top-left-radius: 30px;
border-top-right-radius: 30px;
background-color: #e9ecef;
padding: 3rem 0;
margin-top: auto;
color: #333;
}
.paste-area {
width: 100%;
min-height: 120px;
padding: 1rem;
background: rgba(255, 255, 255, 0.9);
border: 1px solid #e5e7eb;
border-radius: 10px;
color: #333;
font-size: 1rem;
resize: vertical;
}
.paste-area:focus {
outline: none;
border-color: var(--primary);
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);
}
.email-count {
color: #4b5563;
font-size: 1rem;
margin-top: 0.5rem;
}
.results-grid {
display: grid;
gap: 1.5rem;
margin-top: 2rem;
}
.stats-panel {
background: #fff;
border-radius: 10px;
padding: 1.5rem;
margin-bottom: 1.5rem;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.filter-controls, .sort-controls {
margin: 1.5rem 0;
display: flex;
gap: 1rem;
flex-wrap: wrap;
justify-content: center;
}
.filter-list {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.search-bar {
max-width: 400px;
margin: 1.5rem auto;
}
.badge-ccTLD { background-color: var(--success); }
.badge-regional-sld { background-color: var(--warning); }
.badge-gTLD { background-color: var(--info); }
.badge-webmail { background-color: var(--purple); }
.badge-temporary { background-color: var(--danger); }
.badge-custom { background-color: var(--gray); }
.badge-invalid { background-color: var(--dark); }
.tooltip-content {
display: none;
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.9);
padding: 0.75rem;
border-radius: 8px;
width: max-content;
max-width: 300px;
z-index: 1000;
margin-bottom: 0.5rem;
font-size: 0.9rem;
color: #fff;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2);
}
.badge.tapped .tooltip-content { display: block; }
.validation-tools {
margin-top: 1.5rem;
padding: 1.5rem;
background: #f1f5f9;
border-radius: 12px;
}
.validation-input {
width: 100%;
padding: 12px 15px;
border: 2px solid #e2e8f0;
border-radius: 8px;
margin-bottom: 10px;
font-family: monospace;
font-size: 1rem;
}
.validation-result-simple {
padding: 10px;
border-radius: 6px;
margin-top: 10px;
font-weight: 500;
font-size: 0.95rem;
}
.valid-bg { background-color: #d1fae5; color: #065f46; }
.warning-bg { background-color: #fef3c7; color: #92400e; }
.invalid-bg { background-color: #fee2e2; color: #991b1b; }
.chart-container {
max-width: 100%;
margin: 1.5rem auto;
padding: 1rem;
background: #fff;
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.high-contrast body { background: #000; color: #fff; }
.high-contrast .domain-card { background: #222; color: #fff; }
.high-contrast .domain-card-header { background: #005bb5; }
.high-contrast .badge-ccTLD { background: #00cc00; }
.high-contrast .badge-regional-sld { background: #ffeb3b; color: #000; }
.high-contrast .badge-gTLD { background: #00bcd4; }
.high-contrast .badge-webmail { background: #ab47bc; }
.high-contrast .badge-temporary { background: #d32f2f; }
.high-contrast .badge-custom { background: #757575; }
.high-contrast .badge-invalid { background: #212121; }
.high-contrast .stats-panel, .high-contrast .validation-tools { background: #333; color: #fff; }
@keyframes slideIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
@media (max-width: 768px) {
.paste-area { min-height: 100px; }
.filter-controls, .sort-controls { flex-direction: column; align-items: center; }
.domain-card-container { width: 100%; }
.search-bar { max-width: 100%; }
.stats-panel .row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.d-flex.gap-2 { gap: 0.5rem; flex-wrap: wrap; justify-content: center; }
.domain-card-header { font-size: 0.95rem; }
.domain-card-header-actions .badge { font-size: 0.85rem; }
.filter-list { display: none; }
.filter-list.show { display: flex; }
.btn { font-size: 0.9rem; padding: 10px; }
}
@media (max-width: 480px) {
.stats-panel .row { grid-template-columns: 1fr; }
.domain-card-header { font-size: 0.9rem; }
}
</style>
</head>
<body>
<div class="content">
<div class="container" style="margin-top: 50px;">
<div class="mb-4 d-flex justify-content-between align-items-center flex-wrap gap-2">
<a href="https://www.eml.ist/" class="btn" style="background-color: #ffffff; color: #333; border: 2px solid var(--primary);">
<i class="fas fa-arrow-left me-2"></i>Back to Tools
</a>
<button class="btn toggle-contrast" style="background-color: #ffffff; color: #333; border: 2px solid var(--primary);">
<i class="fas fa-adjust me-2"></i>Toggle High Contrast
</button>
</div>
<div class="container mx-auto px-4 py-8">
<div class="max-w-4xl mx-auto">
<h1 class="text-5xl font-bold text-center mb-4" style="color: var(--primary);">Ultimate Email Domain Separator</h1>
<p class="text-center mb-8 text-gray-600">Each domain extension in its own boxed-in area, supporting all ccTLDs, regional SLDs, gTLDs, webmails, and temporary domains with DMARC compatibility checks.</p>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
<div class="feature-card p-6 rounded-lg shadow-lg">
<div class="text-3xl mb-3">🌍</div>
<h2 class="font-bold mb-2" style="color: var(--primary);">Universal Domain Support</h2>
<p class="text-sm text-gray-600">Each extension in its own boxed-in area, covering all ccTLDs, SLDs, and more.</p>
</div>
<div class="feature-card p-6 rounded-lg shadow-lg">
<div class="text-3xl mb-3">⚙️</div>
<h2 class="font-bold mb-2" style="color: var(--primary);">Advanced Filtering & Sorting</h2>
<p class="text-sm text-gray-600">Filter by category, SLD, search, and sort with DMARC insights.</p>
</div>
<div class="feature-card p-6 rounded-lg shadow-lg">
<div class="text-3xl mb-3">📤</div>
<h2 class="font-bold mb-2" style="color: var(--primary);">Flexible Export & Security</h2>
<p class="text-sm text-gray-600">Export as TXT, CSV, JSON with DMARC compatibility checks.</p>
</div>
</div>
</div>
</div>
<div class="card" style="background-color: var(--primary); border: none; border-radius: 12px; box-shadow: 0px 8px 15px rgba(0, 0, 0, 0.1); margin-bottom: 30px; max-width: 800px; width: 100%; margin-left: auto; margin-right: auto;">
<div class="card-body">
<form id="emailSeparatorForm">
<div class="mb-3">
<input type="file" id="importFile" accept=".txt,.csv" class="form-control mb-3" aria-label="Upload email list">
<textarea id="emailInput" class="form-control paste-area" rows="8" placeholder="Paste your emails here (one per line, comma-separated, or custom delimiter)..." aria-label="Email input"></textarea>
</div>
<div class="row mb-3">
<div class="col-md-6">
<small style="color: rgba(255, 255, 255, 0.75);">Email Count: <span id="emailCount">0</span> | Duplicates Removed: <span id="duplicateCount">0</span></small>
</div>
<div class="col-md-6">
<select id="emailDelimiter" class="form-select" aria-label="Delimiter selection">
<option value="\n">New Line ( \n )</option>
<option value=", ">Comma ( , )</option>
<option value="|">Pipe ( | )</option>
<option value=" : ">Colon ( : )</option>
<option value="other">Custom</option>
</select>
</div>
</div>
<div id="customDelimiterWrapper" style="display: none;" class="mb-3">
<input type="text" id="customDelimiter" class="form-control" placeholder="Enter your custom delimiter" aria-label="Custom delimiter" />
</div>
<div class="d-flex justify-content-between flex-wrap gap-2">
<button type="button" class="btn" id="btnSeparate" style="background-color: #fff; color: var(--primary);"><i class="fas fa-filter"></i> Separate Domains</button>
<button type="button" class="btn" id="btnCopyAll" style="background-color: #fff; color: var(--primary);"><i class="fas fa-copy"></i> Copy All</button>
<button type="button" class="btn" id="btnDownloadTxt" style="background-color: #fff; color: var(--primary);"><i class="fas fa-download"></i> TXT</button>
<button type="button" class="btn" id="btnDownloadCsv" style="background-color: #fff; color: var(--primary);"><i class="fas fa-file-csv"></i> CSV</button>
<button type="button" class="btn" id="btnDownloadJson" style="background-color: #fff; color: var(--primary);"><i class="fas fa-file-code"></i> JSON</button>
<button type="reset" class="btn" style="border: 1px solid #fff; color: #fff;" id="btnReset"><i class="fas fa-refresh"></i> Reset</button>
</div>
</form>
</div>
</div>
<div class="stats-panel">
<h3 class="text-center mb-3">Statistics</h3>
<div class="row text-center">
<div class="col-md-3"><strong>ccTLDs</strong>: <span id="statsCcTLD">0</span></div>
<div class="col-md-3"><strong>Regional SLDs</strong>: <span id="statsRegionalSld">0</span></div>
<div class="col-md-3"><strong>Webmails</strong>: <span id="statsWebmail">0</span></div>
<div class="col-md-3"><strong>Temporary</strong>: <span id="statsTemporary">0</span></div>
</div>
<div class="chart-container">
<canvas id="statsChart"></canvas>
</div>
</div>
<div class="validation-tools">
<h3>🔍 DMARC Compatibility Check</h3>
<p>Check SPF/DKIM syntax for selected domains (client-side, no DNS lookup):</p>
<div class="form-group">
<label for="spf-input">SPF Record</label>
<input type="text" id="spf-input" class="validation-input" placeholder="v=spf1 include:_spf.example.com ~all" aria-label="SPF record input">
<button class="btn btn-primary" onclick="validateSPF()" style="width: 100%; margin-bottom: 15px;">Validate SPF</button>
<div id="spf-result" class="validation-result-simple"></div>
</div>
<div class="form-group">
<label for="dkim-input">DKIM Record</label>
<input type="text" id="dkim-input" class="validation-input" placeholder="v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3..." aria-label="DKIM record input">
<button class="btn btn-primary" onclick="validateDKIM()" style="width: 100%;">Validate DKIM</button>
<div id="dkim-result" class="validation-result-simple"></div>
</div>
</div>
<div class="filter-controls">
<button class="btn toggle-filters" style="background-color: #fff; color: var(--primary);"><i class="fas fa-filter"></i> Toggle Filters</button>
<div class="filter-list">
<label><input type="checkbox" class="filter-category" value="ccTLD" checked> ccTLD</label>
<label><input type="checkbox" class="filter-category" value="regional-sld" checked> Regional SLD</label>
<label><input type="checkbox" class="filter-category" value="gTLD" checked> gTLD</label>
<label><input type="checkbox" class="filter-category" value="webmail" checked> Webmail</label>
<label><input type="checkbox" class="filter-category" value="temporary" checked> Temporary</label>
<label><input type="checkbox" class="filter-category" value="custom" checked> Custom</label>
<label><input type="checkbox" class="filter-category" value="invalid" checked> Invalid</label>
</div>
<input type="text" id="filterSld" class="form-control search-bar" placeholder="Filter by SLD (e.g., yahoo)..." aria-label="SLD filter">
</div>
<input type="text" id="searchDomains" class="form-control search-bar" placeholder="Search domains (e.g., .co.uk, gmail)..." aria-label="Domain search">
<div class="sort-controls">
<select id="sortBy" class="form-select" style="max-width: 200px;" aria-label="Sort selection">
<option value="name">Sort by Name</option>
<option value="count">Sort by Count</option>
<option value="category">Sort by Category</option>
</select>
<button id="sortAsc" class="btn btn-sm active" style="background-color: #fff; color: var(--primary);"><i class="fas fa-sort-alpha-down"></i> Asc</button>
<button id="sortDesc" class="btn btn-sm" style="background-color: #fff; color: var(--primary);"><i class="fas fa-sort-alpha-up"></i> Desc</button>
</div>
<div id="domainResults" class="row g-4"></div>
</div>
</div>
<footer>
<div class="container">
<div class="row d-flex align-items-center justify-content-between">
<div class="col-md-4 d-inline-flex align-items-center">
<h5 class="mb-0"><a href="https://eml.ist" style="color: var(--primary); text-decoration: none;">Email Tools</a></h5>
</div>
<div class="col-md-4 d-inline-flex align-items-center justify-content-center"></div>
<div class="col-md-4 d-inline-flex align-items-center justify-content-end">
<a href="https://eml.ist/privacy.html" class="me-3" style="color: #4b5563; text-decoration: none;">Privacy Policy</a>
</div>
</div>
<div class="align-items-center d-inline-flex justify-content-center w-100 mt-3 flex-wrap gap-3">
<a href="https://eml.ist/about.html" style="color: #4b5563;">About Us</a>
<a href="https://eml.ist/contact.html" style="color: #4b5563;">Contact Us</a>
<a href="https://eml.ist/faq.html" style="color: #4b5563;">FAQs</a>
<a href="https://eml.ist/copyright.html" style="color: #4b5563;">Copyright</a>
<a href="https://eml.ist/terms.html" style="color: #4b5563;">Terms of Use</a>
<a href="https://eml.ist/index.html?our-tools#our-tools" style="color: #4b5563;">All Tools</a>
</div>
<div class="text-center mt-3" style="color: #4b5563;">
<p>Copyright 2025. All Rights Reserved</p>
<p style="font-size: 14px; margin-top: 8px;">
Website created by <a href="https://webopsx.com" target="_blank" style="color: var(--primary); text-decoration: none;">WebOpsX</a>
</p>
</div>
</div>
</footer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/js/toastr.min.js"></script>
<script>
$(document).ready(function () {
// Embedded TLD data (expanded sample)
const tldInfo = {
'.us': { type: 'ccTLD', manager: 'United States', display: '.US (United States)', tooltip: 'Country code for the United States' },
'.uk': { type: 'ccTLD', manager: 'United Kingdom', display: '.UK (United Kingdom)', tooltip: 'Country code for the United Kingdom' },
'.co.uk': { type: 'ccTLD', manager: 'United Kingdom', display: '.CO.UK (United Kingdom)', tooltip: 'Commercial domain for the United Kingdom' },
'.ru': { type: 'ccTLD', manager: 'Russia', display: '.RU (Russia)', tooltip: 'Country code for Russia' },
'.jp': { type: 'ccTLD', manager: 'Japan', display: '.JP (Japan)', tooltip: 'Country code for Japan' },
'.co.jp': { type: 'ccTLD', manager: 'Japan', display: '.CO.JP (Japan)', tooltip: 'Commercial domain for Japan' },
'.br': { type: 'ccTLD', manager: 'Brazil', display: '.BR (Brazil)', tooltip: 'Country code for Brazil' },
'.com.br': { type: 'ccTLD', manager: 'Brazil', display: '.COM.BR (Brazil)', tooltip: 'Commercial domain for Brazil' },
'.fr': { type: 'ccTLD', manager: 'France', display: '.FR (France)', tooltip: 'Country code for France' },
'.de': { type: 'ccTLD', manager: 'Germany', display: '.DE (Germany)', tooltip: 'Country code for Germany' },
'.it': { type: 'ccTLD', manager: 'Italy', display: '.IT (Italy)', tooltip: 'Country code for Italy' },
'.au': { type: 'ccTLD', manager: 'Australia', display: '.AU (Australia)', tooltip: 'Country code for Australia' },
'.com.au': { type: 'ccTLD', manager: 'Australia', display: '.COM.AU (Australia)', tooltip: 'Commercial domain for Australia' },
'.ca': { type: 'ccTLD', manager: 'Canada', display: '.CA (Canada)', tooltip: 'Country code for Canada' },
'.nl': { type: 'ccTLD', manager: 'Netherlands', display: '.NL (Netherlands)', tooltip: 'Country code for Netherlands' },
'.pl': { type: 'ccTLD', manager: 'Poland', display: '.PL (Poland)', tooltip: 'Country code for Poland' },
'.es': { type: 'ccTLD', manager: 'Spain', display: '.ES (Spain)', tooltip: 'Country code for Spain' },
'.cn': { type: 'ccTLD', manager: 'China', display: '.CN (China)', tooltip: 'Country code for China' },
'.in': { type: 'ccTLD', manager: 'India', display: '.IN (India)', tooltip: 'Country code for India' },
'.рф': { type: 'ccTLD-idn', manager: 'Russia', display: '.РФ (Russia)', tooltip: 'Cyrillic domain for Russia' },
'.za': { type: 'ccTLD', manager: 'South Africa', display: '.ZA (South Africa)', tooltip: 'Country code for South Africa' },
'.kr': { type: 'ccTLD', manager: 'South Korea', display: '.KR (South Korea)', tooltip: 'Country code for South Korea' },
'.mx': { type: 'ccTLD', manager: 'Mexico', display: '.MX (Mexico)', tooltip: 'Country code for Mexico' },
'.us.com': { type: 'regional-sld', manager: 'United States (Commercial)', display: '.US.COM (US Commercial)', tooltip: 'Commercial domain mimicking US ccTLD' },
'.uk.com': { type: 'regional-sld', manager: 'United Kingdom (Commercial)', display: '.UK.COM (UK Commercial)', tooltip: 'Commercial domain mimicking UK ccTLD' },
'.de.com': { type: 'regional-sld', manager: 'Germany (Commercial)', display: '.DE.COM (Germany Commercial)', tooltip: 'Commercial domain mimicking Germany ccTLD' },
'.eu.com': { type: 'regional-sld', manager: 'Europe (Commercial)', display: '.EU.COM (Europe Commercial)', tooltip: 'Commercial domain mimicking Europe ccTLD' },
'.cn.com': { type: 'regional-sld', manager: 'China (Commercial)', display: '.CN.COM (China Commercial)', tooltip: 'Commercial domain mimicking China ccTLD' },
'.br.com': { type: 'regional-sld', manager: 'Brazil (Commercial)', display: '.BR.COM (Brazil Commercial)', tooltip: 'Commercial domain mimicking Brazil ccTLD' },
'.ru.com': { type: 'regional-sld', manager: 'Russia (Commercial)', display: '.RU.COM (Russia Commercial)', tooltip: 'Commercial domain mimicking Russia ccTLD' },
'.jp.net': { type: 'regional-sld', manager: 'Japan (Commercial)', display: '.JP.NET (Japan Commercial)', tooltip: 'Commercial domain mimicking Japan ccTLD' },
'.sa.com': { type: 'regional-sld', manager: 'Saudi Arabia (Commercial)', display: '.SA.COM (Saudi Arabia Commercial)', tooltip: 'Commercial domain mimicking Saudi Arabia ccTLD' },
'.za.com': { type: 'regional-sld', manager: 'South Africa (Commercial)', display: '.ZA.COM (South Africa Commercial)', tooltip: 'Commercial domain mimicking South Africa ccTLD' },
'.com': { type: 'gTLD', manager: 'Generic', display: '.COM (Generic)', tooltip: 'Generic top-level domain' },
'.net': { type: 'gTLD', manager: 'Generic', display: '.NET (Generic)', tooltip: 'Generic top-level domain' },
'.org': { type: 'gTLD', manager: 'Generic', display: '.ORG (Generic)', tooltip: 'Generic top-level domain' },
};
const majorWebmails = {
'gmail.com': { displayName: 'Gmail.com (Webmail)', type: 'webmail', tooltip: 'Google’s email service', spf: 'v=spf1 include:_spf.google.com ~all' },
'yahoo.com': { displayName: 'Yahoo.com (Webmail)', type: 'webmail', tooltip: 'Yahoo’s email service', spf: 'v=spf1 include:_spf.yahoo.com ~all' },
'outlook.com': { displayName: 'Outlook.com (Webmail)', type: 'webmail', tooltip: 'Microsoft’s email service', spf: 'v=spf1 include:_spf.outlook.com ~all' },
'hotmail.com': { displayName: 'Hotmail.com (Webmail)', type: 'webmail', tooltip: 'Microsoft’s legacy email service', spf: 'v=spf1 include:_spf.hotmail.com ~all' },
};
const temporaryDomains = [
'mailinator.com', '10minutemail.com', 'trashmail.com', 'guerrillamail.com', 'temp-mail.com',
'disposableinbox.com', 'yopmail.com', 'sharklasers.com', '20minutemail.com', '30minutemail.com',
'60minutemail.com', 'discardmail.com', 'tempemail.net', 'throwawayemailaddress.com', 'fakemailz.com',
'pookmail.com', 'spamgourmet.com', 'tempmail.com', 'maildrop.cc', 'getnada.com',
'tempinbox.com', 'mailcatch.com', 'fakeinbox.com'
];
let chartInstance = null;
$("#emailDelimiter").on("change", function () {
$("#customDelimiterWrapper").toggle($(this).val() === "other");
});
$('.toggle-filters').on('click', function() {
$('.filter-list').toggleClass('show').slideToggle(200);
});
$('.toggle-contrast').on('click', function() {
$('body').toggleClass('high-contrast');
toastr.info($('body').hasClass('high-contrast') ? 'High contrast mode enabled' : 'High contrast mode disabled');
updateChart();
});
$(document).on('click', '.badge', function(e) {
e.stopPropagation();
$('.badge').not(this).removeClass('tapped');
$(this).toggleClass('tapped');
});
$(document).on('click', function(e) {
if (!$(e.target).closest('.badge').length) {
$('.badge').removeClass('tapped');
}
});
$("#importFile").on("change", function(e) {
const file = e.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = function(e) {
$("#emailInput").val(e.target.result);
$("#btnSeparate").trigger('click');
};
reader.readAsText(file);
this.value = '';
});
$("#btnSeparate").on("click", function() {
const inputText = $("#emailInput").val().trim();
let inputDelimiter = $("#emailDelimiter").val();
if (inputDelimiter === "other") {
inputDelimiter = $("#customDelimiter").val() || "\n";
}
const normalizedDelimiter = inputDelimiter === "\\n" ? "\n" : inputDelimiter;
const emailPattern = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/gm;
const extractedEmails = [];
let match;
while ((match = emailPattern.exec(inputText)) !== null) {
extractedEmails.push(match[0]);
}
const emailSet = new Set(extractedEmails.map(email => email.toLowerCase()));
const uniqueEmails = [...emailSet];
const duplicateCount = extractedEmails.length - uniqueEmails.length;
$("#emailCount").text(uniqueEmails.length);
$("#duplicateCount").text(duplicateCount);
const domainGroups = new Map();
const temporaryGroup = {
emails: [],
displayName: 'Temporary Emails',
tldInfo: { type: 'temporary', manager: 'Disposable Email Services', tooltip: 'Temporary or disposable email domains' }
};
const customWebmails = {
emails: [],
displayName: 'Custom Web Mails',
tldInfo: { type: 'custom', manager: 'Unknown Domains', tooltip: 'Domains not recognized as ccTLD, SLD, gTLD, or webmail' }
};
const invalidEmails = {
emails: [],
displayName: 'Invalid Emails',
tldInfo: { type: 'invalid', manager: 'Malformed Emails', tooltip: 'Emails with invalid or missing domains' }
};
uniqueEmails.forEach(email => {
const emailLower = email.toLowerCase();
const [, domain] = emailLower.split('@');
if (!domain || !domain.includes('.')) {
invalidEmails.emails.push(email);
return;
}
const domainParts = domain.split('.');
const sld = domainParts.length > 1 ? domainParts[0] : '';
const tld1 = '.' + domainParts.slice(-1)[0];
const tld2 = domainParts.length > 1 ? '.' + domainParts.slice(-2).join('.') : null;
const tld3 = domainParts.length > 2 ? '.' + domainParts.slice(-3).join('.') : null;
let groupKey, displayName, tldInfoEntry;
if (majorWebmails[domain]) {
groupKey = domain;
displayName = majorWebmails[domain].displayName;
tldInfoEntry = { ...majorWebmails[domain], manager: domain };
$("#spf-input").val(majorWebmails[domain].spf || '');
} else if (temporaryDomains.includes(domain)) {
temporaryGroup.emails.push(email);
return;
} else if (tld3 && tldInfo[tld3]) {
groupKey = tld3;
displayName = tldInfo[tld3].display;
tldInfoEntry = tldInfo[tld3];
} else if (tld2 && tldInfo[tld2]) {
groupKey = tld2;
displayName = tldInfo[tld2].display;
tldInfoEntry = tldInfo[tld2];
} else if (tld1 && tldInfo[tld1]) {
groupKey = tld1;
displayName = tldInfo[tld1].display;
tldInfoEntry = tldInfo[tld1];
} else {
if (tld3 && tld3.endsWith('.com') && tld3.split('.')[0].length === 2) {
groupKey = tld3;
displayName = `${tld3.toUpperCase()} (Potential Regional SLD)`;
tldInfoEntry = { type: 'regional-sld', manager: 'Unknown (Commercial)', tooltip: 'Possible commercial domain mimicking a ccTLD' };
} else {
customWebmails.emails.push(email);
return;
}
}
const sldFilter = $("#filterSld").val().toLowerCase();
if (sldFilter && !sld.includes(sldFilter)) {
return;
}
if (!domainGroups.has(groupKey)) {
domainGroups.set(groupKey, {
emails: [],
displayName: displayName,
tldInfo: tldInfoEntry
});
}
domainGroups.get(groupKey).emails.push(email);
});
updateStatistics(domainGroups, temporaryGroup, customWebmails, invalidEmails);
$("#domainResults").empty();
lazyRenderCards(domainGroups, temporaryGroup, customWebmails, invalidEmails, normalizedDelimiter);
toastr.success(`Emails separated successfully! ${uniqueEmails.length} unique emails, ${duplicateCount} duplicates removed.`);
});
function updateStatistics(domainGroups, temporaryGroup, customWebmails, invalidEmails) {
let ccTldCount = 0, regionalSldCount = 0, gTldCount = 0, webmailCount = 0;
for (const [, info] of domainGroups) {
if (info.tldInfo.type === 'ccTLD' || info.tldInfo.type === 'ccTLD-idn') {
ccTldCount += info.emails.length;
} else if (info.tldInfo.type === 'regional-sld') {
regionalSldCount += info.emails.length;
} else if (info.tldInfo.type === 'gTLD') {
gTldCount += info.emails.length;
} else if (info.tldInfo.type === 'webmail') {
webmailCount += info.emails.length;
}
}
$("#statsCcTLD").text(ccTldCount);
$("#statsRegionalSld").text(regionalSldCount);
$("#statsWebmail").text(webmailCount);
$("#statsTemporary").text(temporaryGroup.emails.length);
updateChart(ccTldCount, regionalSldCount, gTldCount, webmailCount, temporaryGroup.emails.length, customWebmails.emails.length, invalidEmails.emails.length);
}
function updateChart(ccTldCount, regionalSldCount, gTldCount, webmailCount, tempCount, customCount, invalidCount) {
if (chartInstance) {
chartInstance.destroy();
}
const ctx = document.getElementById('statsChart').getContext('2d');
const isHighContrast = $('body').hasClass('high-contrast');
chartInstance = new Chart(ctx, {
type: 'pie',
data: {
labels: ['ccTLDs', 'Regional SLDs', 'gTLDs', 'Webmails', 'Temporary', 'Custom', 'Invalid'],
datasets: [{
data: [ccTldCount, regionalSldCount, gTldCount, webmailCount, tempCount, customCount, invalidCount],
backgroundColor: isHighContrast ? [
'#00cc00', '#ffeb3b', '#00bcd4', '#ab47bc', '#d32f2f', '#757575', '#212121'
] : [
'#28a745', '#ffc107', '#17a2b8', '#6f42c1', '#dc3545', '#6c757d', '#343a40'
],
borderColor: isHighContrast ? '#fff' : '#000',
borderWidth: 1
}]
},
options: {
responsive: true,
plugins: {
legend: { position: 'bottom', labels: { font: { size: 12 } } },
title: { display: true, text: 'Email Domain Distribution', font: { size: 16 } }
},
animation: { duration: 500 }
}
});
}
function lazyRenderCards(domainGroups, temporaryGroup, customWebmails, invalidEmails, delimiter) {
const groups = [];
if (temporaryGroup.emails.length > 0) groups.push(temporaryGroup);
if (customWebmails.emails.length > 0) groups.push(customWebmails);
if (invalidEmails.emails.length > 0) groups.push(invalidEmails);
for (const [, info] of domainGroups) {
groups.push(info);
}
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const info = JSON.parse(entry.target.dataset.info);
appendDomainCard(info, delimiter);
observer.unobserve(entry.target);
}
});
}, { rootMargin: '100px' });
const filterCategories = new Set($(".filter-category:checked").map(function() { return $(this).val(); }).get());
const searchTerm = $("#searchDomains").val().toLowerCase();
groups.sort((a, b) => {
const sortBy = $("#sortBy").val();
const sortDesc = $("#sortDesc").hasClass('active');
if (sortBy === 'name') {
return sortDesc ? b.displayName.localeCompare(a.displayName) : a.displayName.localeCompare(b.displayName);
} else if (sortBy === 'count') {
return sortDesc ? b.emails.length - a.emails.length : a.emails.length - b.emails.length;
} else {
const categoryOrder = ['webmail', 'ccTLD', 'regional-sld', 'gTLD', 'temporary', 'custom', 'invalid'];
const aIndex = categoryOrder.indexOf(a.tldInfo.type);
const bIndex = categoryOrder.indexOf(b.tldInfo.type);
return sortDesc ? bIndex - aIndex : aIndex - bIndex;
}
}).forEach(info => {
if (filterCategories.has(info.tldInfo.type) && info.displayName.toLowerCase().includes(searchTerm)) {
const placeholder = document.createElement('div');
placeholder.className = 'col-md-4 domain-card-container mb-4';
placeholder.dataset.info = JSON.stringify(info);
$("#domainResults").append(placeholder);
observer.observe(placeholder);
}
});
}
function appendDomainCard(info, delimiter) {
const badgeClass = info.tldInfo.type === 'ccTLD' || info.tldInfo.type === 'ccTLD-idn' ? 'badge-ccTLD' :
info.tldInfo.type === 'regional-sld' ? 'badge-regional-sld' :
info.tldInfo.type === 'gTLD' ? 'badge-gTLD' :
info.tldInfo.type === 'webmail' ? 'badge-webmail' :
info.tldInfo.type === 'temporary' ? 'badge-temporary' :
info.tldInfo.type === 'custom' ? 'badge-custom' :
'badge-invalid';
const cardHtml = `
<div class="col-md-4 domain-card-container mb-4" data-category="${info.tldInfo.type}" data-name="${info.displayName.toLowerCase()}">
<div class="domain-card">
<div class="domain-card-header">
<span>
<i class="fas fa-globe"></i> ${info.displayName}
<span class="badge ${badgeClass} ms-2">
${info.tldInfo.type.toUpperCase()}
<span class="tooltip-content">${info.tldInfo.tooltip}</span>
</span>
</span>
<div class="domain-card-header-actions">
<span class="badge">${info.emails.length}</span>
<button class="btn btn-sm copy-domain-emails" title="Copy Emails">
<i class="fas fa-copy"></i>
</button>
<button class="btn btn-sm download-domain-emails" title="Download Emails">
<i class="fas fa-download"></i>
</button>
<button class="btn btn-sm reset-domain-card" title="Close">
<i class="fas fa-times text-danger"></i>
</button>
</div>
</div>
<div class="p-3">
<textarea class="form-control domain-emails" rows="5" readonly aria-label="Emails for ${info.displayName}">${info.emails.join(delimiter)}</textarea>
<button class="btn btn-sm copy-textarea mt-2" style="background-color: #fff; color: var(--primary);" title="Copy Emails"><i class="fas fa-copy"></i> Copy</button>
</div>
</div>
</div>
`;
$("#domainResults").append(cardHtml);
}
let searchTimeout;
$(".filter-category, #searchDomains, #filterSld").on("input change", function() {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => $("#btnSeparate").trigger('click'), 300);
});
$("#sortBy").on("change", function() {
$("#btnSeparate").trigger('click');
});
$("#sortAsc, #sortDesc").on("click", function() {
$("#sortAsc, #sortDesc").removeClass('active');
$(this).addClass('active');
$("#btnSeparate").trigger('click');
});
$("#btnCopyAll").on("click", function () {
const delimiter = $("#emailDelimiter").val() === "other" ? $("#customDelimiter").val() || "\n" : ($("#emailDelimiter").val() === "\\n" ? "\n" : $("#emailDelimiter").val());
const emails = $(".domain-emails").map(function() { return $(this).val().trim(); }).get().join(delimiter);
navigator.clipboard.writeText(emails);
toastr.info("All emails copied to clipboard!");
});
$("#btnDownloadTxt").on("click", function () {
const delimiter = $("#emailDelimiter").val() === "other" ? $("#customDelimiter").val() || "\n" : ($("#emailDelimiter").val() === "\\n" ? "\n" : $("#emailDelimiter").val());
const emails = $(".domain-emails").map(function() { return $(this).val().trim(); }).get().join(delimiter);
const blob = new Blob([emails], { type: "text/plain" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "all-domain-emails.txt";
a.click();
URL.revokeObjectURL(url);
toastr.success("All emails downloaded as TXT!");
});
$("#btnDownloadCsv").on("click", function () {
const delimiter = $("#emailDelimiter").val() === "other" ? $("#customDelimiter").val() || "," : ($("#emailDelimiter").val() === "\\n" ? "," : $("#emailDelimiter").val());
let csvContent = "Category,Domain,Emails\n";
$(".domain-emails").each(function() {
const displayName = $(this).closest('.domain-card').find('.domain-card-header span').text();
const type = $(this).closest('.domain-card').find('.badge').text().split(' ')[0];
const emails = $(this).val().trim().split('\n').map(e => `"${e.replace(/"/g, '""')}"`).join(delimiter);
csvContent += `"${type}","${displayName.replace(/"/g, '""')}","${emails}"\n`;
});
const blob = new Blob([csvContent], { type: "text/csv" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "all-domain-emails.csv";
a.click();
URL.revokeObjectURL(url);
toastr.success("All emails downloaded as CSV!");
});
$("#btnDownloadJson").on("click", function() {
const data = {};
$(".domain-emails").each(function() {
const displayName = $(this).closest('.domain-card').find('.domain-card-header span').text();
const type = $(this).closest('.domain-card').find('.badge').text().split(' ')[0];
data[displayName] = {
category: type,
emails: $(this).val().trim().split('\n').filter(e => e)
};
});
const blob = new Blob([JSON.stringify(data, null, 2)], { type: "application/json" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "all-domain-emails.json";
a.click();
URL.revokeObjectURL(url);
toastr.success("All emails downloaded as JSON!");
});
$(document).on('click', '.copy-domain-emails, .copy-textarea', function() {
const $textarea = $(this).closest('.domain-card').find('.domain-emails');
navigator.clipboard.writeText($textarea.val().trim());
toastr.info("Domain emails copied to clipboard!");
});
$(document).on('click', '.download-domain-emails', function() {
const $card = $(this).closest('.domain-card');
const $textarea = $card.find('.domain-emails');
const domain = $card.find('.domain-card-header span').text().replace(/[^a-zA-Z0-9.-]/g, '');
const emails = $textarea.val().trim();
const blob = new Blob([emails], { type: "text/plain" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = `${domain}-emails.txt`;
a.click();
URL.revokeObjectURL(url);
toastr.success(`${domain} emails downloaded!`);
});
$(document).on('click', '.reset-domain-card', function() {
const $container = $(this).closest('.domain-card-container');
$container.remove();
updateTotalEmailCount();
$("#btnSeparate").trigger('click');
});
$("#btnReset").on("click", function() {
$("#domainResults").empty();
$("#emailCount").text(0);
$("#duplicateCount").text(0);
$("#emailInput").val('');
$("#filterSld").val('');
$("#searchDomains").val('');
$("#spf-input").val('');
$("#dkim-input").val('');
$("#statsCcTLD, #statsRegionalSld, #statsWebmail, #statsTemporary").text(0);
if (chartInstance) {
chartInstance.destroy();
chartInstance = null;
}
});
function updateTotalEmailCount() {
const totalEmails = $(".domain-emails").toArray().reduce((sum, textarea) =>
sum + $(textarea).val().trim().split('\n').filter(e => e).length, 0);
$("#emailCount").text(totalEmails);
}
function validateSPF() {
const spfRecord = $("#spf-input").val().trim();
const resultDiv = $("#spf-result");
if (!spfRecord) {
resultDiv.text("❌ Please enter an SPF record").addClass("invalid-bg").removeClass("valid-bg warning-bg");
return;
}
if (!spfRecord.startsWith("v=spf1")) {
resultDiv.text("❌ Missing 'v=spf1' in SPF record").addClass("invalid-bg").removeClass("valid-bg warning-bg");
return;
}
if (spfRecord.includes("+all")) {
resultDiv.text("⚠️ Warning: '+all' allows all senders (risky!)").addClass("warning-bg").removeClass("valid-bg invalid-bg");
return;
}
if (!spfRecord.match(/[~+-]all$/)) {
resultDiv.text("⚠️ Warning: SPF record should end with ~all, -all, or +all").addClass("warning-bg").removeClass("valid-bg invalid-bg");
return;
}
resultDiv.text("✅ SPF syntax looks valid").addClass("valid-bg").removeClass("warning-bg invalid-bg");
}
function validateDKIM() {
const dkimRecord = $("#dkim-input").val().trim();
const resultDiv = $("#dkim-result");
if (!dkimRecord) {
resultDiv.text("❌ Please enter a DKIM record").addClass("invalid-bg").removeClass("valid-bg warning-bg");
return;
}
if (!dkimRecord.startsWith("v=DKIM1")) {
resultDiv.text("❌ Missing 'v=DKIM1' in DKIM record").addClass("invalid-bg").removeClass("valid-bg warning-bg");
return;
}
if (!dkimRecord.includes("p=")) {
resultDiv.text("❌ Missing public key (p=) in DKIM record").addClass("invalid-bg").removeClass("valid-bg warning-bg");
return;
}
resultDiv.text("✅ DKIM syntax looks valid").addClass("valid-bg").removeClass("warning-bg invalid-bg");
}
});
</script>
</body>
</html>
Comments
Post a Comment