{"id":59,"date":"2026-03-26T13:17:41","date_gmt":"2026-03-26T07:47:41","guid":{"rendered":"https:\/\/www.oneclickai.in\/?page_id=59"},"modified":"2026-03-27T15:10:25","modified_gmt":"2026-03-27T09:40:25","slug":"bulk-resume-parser","status":"publish","type":"page","link":"https:\/\/www.oneclickai.in\/index.php\/bulk-resume-parser\/","title":{"rendered":"Bulk Resume Parser"},"content":{"rendered":"\n\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Resume Parser &#8211; Extract Contacts<\/title>\n    \n    <!-- Tailwind CSS -->\n    <script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\n    \n    <!-- Google Fonts -->\n    <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@300;400;500;600;700;800&#038;display=swap\" rel=\"stylesheet\">\n    \n    <!-- Parsing Libraries -->\n    <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/2.16.105\/pdf.min.js\"><\/script>\n    <script>pdfjsLib.GlobalWorkerOptions.workerSrc = 'https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/2.16.105\/pdf.worker.min.js';<\/script>\n    <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/mammoth\/1.4.21\/mammoth.browser.min.js\"><\/script>\n\n    <script>\n        tailwind.config = {\n            theme: {\n                extend: {\n                    fontFamily: { 'sans': ['Inter', 'sans-serif'] },\n                    colors: {\n                        'primary': '#F59E0B',\n                        'primary-dark': '#D97706',\n                        'dark': '#111827',\n                    }\n                }\n            }\n        }\n    <\/script>\n\n    <style>\n        body { font-family: 'Inter', sans-serif; }\n        .gradient-text {\n            background: linear-gradient(135deg, #F59E0B 0%, #D97706 100%);\n            -webkit-background-clip: text;\n            -webkit-text-fill-color: transparent;\n            background-clip: text;\n        }\n        .btn-primary {\n            background: linear-gradient(135deg, #F59E0B 0%, #D97706 100%);\n            transition: all 0.3s ease;\n        }\n        .btn-primary:hover {\n            transform: translateY(-1px);\n            box-shadow: 0 10px 25px rgba(245, 158, 11, 0.3);\n        }\n        .btn-outline {\n            border: 2px solid #F59E0B;\n            color: #F59E0B;\n            transition: all 0.3s ease;\n        }\n        .btn-outline:hover {\n            background: #F59E0B;\n            color: white;\n        }\n        .progress-bar {\n            background: linear-gradient(90deg, #F59E0B, #D97706);\n        }\n        .card {\n            transition: all 0.3s ease;\n            border: 1px solid #E5E7EB;\n        }\n        .card:hover {\n            transform: translateY(-2px);\n            box-shadow: 0 20px 40px rgba(0, 0, 0, 0.08);\n            border-color: #F59E0B;\n        }\n        ::-webkit-scrollbar { width: 8px; height: 8px; }\n        ::-webkit-scrollbar-track { background: #f1f1f1; }\n        ::-webkit-scrollbar-thumb { background: #F59E0B; border-radius: 4px; }\n    <\/style>\n<\/head>\n<body class=\"bg-white min-h-screen\">\n\n    <!-- Main Content -->\n    <main class=\"max-w-7xl mx-auto px-6 py-12\">\n        \n        <!-- Hero Section -->\n        <div class=\"text-center mb-16\">\n            <div class=\"inline-flex items-center gap-2 px-4 py-2 bg-primary\/10 rounded-full mb-6\">\n                <span class=\"w-2 h-2 bg-primary rounded-full animate-pulse\"><\/span>\n                <span class=\"text-sm font-medium text-primary\">100% Client-Side Processing<\/span>\n            <\/div>\n            <h1 class=\"text-4xl lg:text-6xl font-bold text-dark mb-6\">\n                Extract contacts from <span class=\"gradient-text\">resumes<\/span> instantly\n            <\/h1>\n            <p class=\"text-xl text-gray-600 max-w-2xl mx-auto mb-8\">\n                Upload PDF or DOCX files to parse emails and phone numbers. Smart filtering removes invalid data automatically.\n            <\/p>\n        <\/div>\n\n        <!-- Stats Cards -->\n        <div id=\"statsContainer\" class=\"hidden grid grid-cols-1 md:grid-cols-3 gap-6 mb-12\">\n            <div class=\"card bg-gray-50 rounded-2xl p-6 text-center\">\n                <div id=\"statFiles\" class=\"text-4xl font-bold text-dark mb-2\">0<\/div>\n                <div class=\"text-sm text-gray-600 font-medium\">Files Processed<\/div>\n            <\/div>\n            <div class=\"card bg-primary\/10 rounded-2xl p-6 text-center\">\n                <div id=\"statEmails\" class=\"text-4xl font-bold text-primary mb-2\">0<\/div>\n                <div class=\"text-sm text-gray-600 font-medium\">Emails Detected<\/div>\n            <\/div>\n            <div class=\"card bg-blue-50 rounded-2xl p-6 text-center\">\n                <div id=\"statPhones\" class=\"text-4xl font-bold text-blue-600 mb-2\">0<\/div>\n                <div class=\"text-sm text-gray-600 font-medium\">Phones Detected<\/div>\n            <\/div>\n        <\/div>\n\n        <!-- Upload Section -->\n        <div class=\"card bg-gray-50 rounded-2xl p-8 mb-12\">\n            <div id=\"dropZone\" class=\"border-2 border-dashed border-gray-300 rounded-xl p-12 text-center cursor-pointer hover:border-primary hover:bg-primary\/5 transition-all\">\n                <input type=\"file\" id=\"fileInput\" multiple accept=\".pdf,.docx\" class=\"absolute inset-0 w-full h-full opacity-0 cursor-pointer\">\n                \n                <div class=\"pointer-events-none\">\n                    <div class=\"w-16 h-16 bg-primary\/10 rounded-full flex items-center justify-center mx-auto mb-4\">\n                        <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"h-8 w-8 text-primary\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n                            <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12\" \/>\n                        <\/svg>\n                    <\/div>\n                    <h3 class=\"text-lg font-semibold text-dark mb-2\">Drop resumes here<\/h3>\n                    <p class=\"text-gray-500 mb-4\">or click to browse files<\/p>\n                    <div class=\"flex items-center justify-center gap-2\">\n                        <span class=\"px-3 py-1 bg-white border border-gray-300 rounded-full text-sm\">PDF<\/span>\n                        <span class=\"px-3 py-1 bg-white border border-gray-300 rounded-full text-sm\">DOCX<\/span>\n                    <\/div>\n                <\/div>\n            <\/div>\n\n            <!-- Progress -->\n            <div id=\"progressContainer\" class=\"hidden mt-6\">\n                <div class=\"flex justify-between text-sm font-medium text-gray-600 mb-2\">\n                    <span>Processing&#8230;<\/span>\n                    <span id=\"progressText\" class=\"text-primary\">0%<\/span>\n                <\/div>\n                <div class=\"w-full bg-gray-200 rounded-full h-2\">\n                    <div id=\"progressBar\" class=\"progress-bar h-full rounded-full transition-all duration-500\" style=\"width: 0%\"><\/div>\n                <\/div>\n            <\/div>\n            \n            <div id=\"errorArea\" class=\"hidden mt-4 p-4 bg-red-50 text-red-600 text-sm rounded-lg border border-red-200\"><\/div>\n        <\/div>\n\n        <!-- Action Buttons -->\n        <div id=\"actionButtons\" class=\"hidden flex flex-wrap justify-center gap-4 mb-8\">\n            <button id=\"copyEmailsBtn\" class=\"btn-outline px-6 py-3 rounded-xl font-semibold flex items-center gap-2\">\n                <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n                    <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3\" \/>\n                <\/svg>\n                Copy Emails\n            <\/button>\n            <button id=\"exportBtn\" class=\"btn-primary text-white px-6 py-3 rounded-xl font-semibold flex items-center gap-2\">\n                <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n                    <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4\" \/>\n                <\/svg>\n                Export CSV\n            <\/button>\n        <\/div>\n\n        <!-- Results Section -->\n        <div class=\"card rounded-2xl overflow-hidden\">\n            <div class=\"p-6 border-b border-gray-200 flex flex-col lg:flex-row justify-between items-center gap-4\">\n                <h2 class=\"text-xl font-bold text-dark flex items-center gap-2\">\n                    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"h-6 w-6 text-primary\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n                        <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\" \/>\n                    <\/svg>\n                    Extracted Contacts\n                <\/h2>\n                \n                <div class=\"flex flex-wrap items-center gap-3\">\n                    <label class=\"flex items-center gap-2 cursor-pointer px-4 py-2 bg-gray-50 rounded-lg border border-gray-200 hover:border-primary transition-colors\">\n                        <input type=\"checkbox\" id=\"filterEmail\" class=\"w-4 h-4 text-primary rounded focus:ring-primary border-gray-300\">\n                        <span class=\"text-sm font-medium text-gray-700\">Hide Missing Emails<\/span>\n                    <\/label>\n                    <label class=\"flex items-center gap-2 cursor-pointer px-4 py-2 bg-gray-50 rounded-lg border border-gray-200 hover:border-primary transition-colors\">\n                        <input type=\"checkbox\" id=\"filterPhone\" class=\"w-4 h-4 text-primary rounded focus:ring-primary border-gray-300\">\n                        <span class=\"text-sm font-medium text-gray-700\">Hide Missing Phones<\/span>\n                    <\/label>\n                    <span id=\"resultCount\" class=\"px-4 py-2 bg-primary text-white rounded-lg text-sm font-semibold\">0 records<\/span>\n                <\/div>\n            <\/div>\n            \n            <div class=\"overflow-x-auto\">\n                <table class=\"w-full\">\n                    <thead class=\"bg-gray-50\">\n                        <tr>\n                            <th class=\"px-6 py-4 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider\">File Name<\/th>\n                            <th class=\"px-6 py-4 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider\">Email Address<\/th>\n                            <th class=\"px-6 py-4 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider\">Phone Number<\/th>\n                        <\/tr>\n                    <\/thead>\n                    <tbody id=\"resultsBody\" class=\"divide-y divide-gray-200\">\n                        <tr>\n                            <td colspan=\"3\" class=\"px-6 py-12 text-center text-gray-400\">\n                                <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"h-12 w-12 mx-auto mb-3 text-gray-300\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n                                    <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\" \/>\n                                <\/svg>\n                                <p>Upload resumes to see results<\/p>\n                            <\/td>\n                        <\/tr>\n                    <\/tbody>\n                <\/table>\n            <\/div>\n        <\/div>\n\n        <!-- Trust Badges -->\n        <div class=\"flex flex-wrap justify-center items-center gap-8 mt-12 text-sm text-gray-500\">\n            <div class=\"flex items-center gap-2\">\n                <svg class=\"w-5 h-5 text-primary\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n                    <path d=\"M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z\"\/>\n                <\/svg>\n                <span>No credit card required<\/span>\n            <\/div>\n            <div class=\"flex items-center gap-2\">\n                <svg class=\"w-5 h-5 text-green-500\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                    <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z\"\/>\n                <\/svg>\n                <span>GDPR Compliant<\/span>\n            <\/div>\n            <div class=\"flex items-center gap-2\">\n                <svg class=\"w-5 h-5 text-blue-500\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                    <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\"\/>\n                <\/svg>\n                <span>Data stays in your browser<\/span>\n            <\/div>\n        <\/div>\n    <\/main>\n\n    <!-- Toast Notification -->\n    <div id=\"copyToast\" class=\"hidden fixed bottom-6 left-1\/2 transform -translate-x-1\/2 bg-dark text-white px-6 py-3 rounded-lg shadow-2xl z-50 flex items-center gap-2\">\n        <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"h-5 w-5 text-primary\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n            <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13l4 4L19 7\" \/>\n        <\/svg>\n        <span id=\"toastMessage\">Emails copied!<\/span>\n    <\/div>\n\n    <script>\n        \/\/ --- State & Elements ---\n        let parsedData = [];\n        let filters = { hideNoEmail: false, hideNoPhone: false };\n\n        const fileInput = document.getElementById('fileInput');\n        const dropZone = document.getElementById('dropZone');\n        const progressBar = document.getElementById('progressBar');\n        const progressText = document.getElementById('progressText');\n        const progressContainer = document.getElementById('progressContainer');\n        const resultsBody = document.getElementById('resultsBody');\n        const exportBtn = document.getElementById('exportBtn');\n        const copyEmailsBtn = document.getElementById('copyEmailsBtn');\n        const actionButtons = document.getElementById('actionButtons');\n        const errorArea = document.getElementById('errorArea');\n        const resultCount = document.getElementById('resultCount');\n        const copyToast = document.getElementById('copyToast');\n        const toastMessage = document.getElementById('toastMessage');\n        const statsContainer = document.getElementById('statsContainer');\n        const statFiles = document.getElementById('statFiles');\n        const statEmails = document.getElementById('statEmails');\n        const statPhones = document.getElementById('statPhones');\n        const filterEmailInput = document.getElementById('filterEmail');\n        const filterPhoneInput = document.getElementById('filterPhone');\n\n        \/\/ --- Event Listeners ---\n        ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {\n            dropZone.addEventListener(eventName, (e) => { \n                e.preventDefault(); e.stopPropagation();\n                if(eventName === 'dragover') dropZone.classList.add('border-primary', 'bg-primary\/5');\n                if(eventName === 'dragleave') dropZone.classList.remove('border-primary', 'bg-primary\/5');\n            }, false);\n        });\n        \n        dropZone.addEventListener('drop', (e) => {\n            dropZone.classList.remove('border-primary', 'bg-primary\/5');\n            processFiles(e.dataTransfer.files);\n        }, false);\n        \n        fileInput.addEventListener('change', (e) => { processFiles(e.target.files); fileInput.value = ''; }, false);\n        exportBtn.addEventListener('click', exportToCSV);\n        copyEmailsBtn.addEventListener('click', copyEmails);\n        filterEmailInput.addEventListener('change', (e) => { filters.hideNoEmail = e.target.checked; renderTable(); });\n        filterPhoneInput.addEventListener('change', (e) => { filters.hideNoPhone = e.target.checked; renderTable(); });\n\n        \/\/ --- Core Processing ---\n        async function processFiles(files) {\n            if (parsedData.length === 0) {\n                resultsBody.innerHTML = '';\n                errorArea.classList.add('hidden');\n            }\n            \n            const validFiles = Array.from(files).filter(file => {\n                const ext = file.name.split('.').pop().toLowerCase();\n                if (ext !== 'pdf' && ext !== 'docx') {\n                    showError(`Skipped: ${file.name} (Unsupported format)`);\n                    return false;\n                }\n                return true;\n            });\n\n            if (validFiles.length === 0) return;\n\n            progressContainer.classList.remove('hidden');\n            let processedCount = 0;\n\n            for (const file of validFiles) {\n                try {\n                    const text = await extractTextFromFile(file);\n                    const data = parseContactInfo(text, file.name);\n                    parsedData.push(data);\n                    renderTable();\n                    updateStats();\n                } catch (err) {\n                    showError(`Failed: ${file.name}`);\n                }\n                processedCount++;\n                updateProgress(processedCount, validFiles.length);\n            }\n\n            setTimeout(() => progressContainer.classList.add('hidden'), 1000);\n            if (parsedData.length > 0) {\n                actionButtons.classList.remove('hidden');\n                statsContainer.classList.remove('hidden');\n            }\n        }\n\n        function updateProgress(current, total) {\n            const percent = Math.round((current \/ total) * 100);\n            progressBar.style.width = `${percent}%`;\n            progressText.textContent = `${percent}%`;\n        }\n\n        async function extractTextFromFile(file) {\n            const ext = file.name.split('.').pop().toLowerCase();\n            const arrayBuffer = await file.arrayBuffer();\n            \n            if (ext === 'pdf') {\n                const pdf = await pdfjsLib.getDocument(arrayBuffer).promise;\n                let fullText = '';\n                for (let i = 1; i <= Math.min(pdf.numPages, 5); i++) {\n                    const page = await pdf.getPage(i);\n                    const textContent = await page.getTextContent();\n                    fullText += textContent.items.map(item => item.str).join(' ') + '\\n';\n                }\n                return fullText;\n            } else {\n                const result = await mammoth.extractRawText({ arrayBuffer });\n                return result.value;\n            }\n        }\n\n        function parseContactInfo(text, fileName) {\n            const emailRegex = \/[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,6}\/;\n            const email = text.match(emailRegex)?.[0] || '';\n            const phone = extractValidPhone(text);\n            return { fileName, email: email || 'Not Found', phone: phone || 'Not Found' };\n        }\n\n        function extractValidPhone(text) {\n            const isYear = (str) => { const n = parseInt(str.replace(\/\\D\/g,'')); return n>=2000 && n<=2099; };\n            const hasYearRange = (str) => \/20\\d{2}[\\s\\-]?20\\d{2}\/.test(str);\n            const countDigits = (str) => (str.match(\/\\d\/g)||[]).length;\n\n            const patterns = [\n                \/(?:\\+91|91|0091)[\\s\\-]?\\d{5}[\\s\\-]?\\d{5}\/g,\n                \/(?:\\+91|91|0091)[\\s\\-]?\\d{10}\/g,\n                \/(?:\\+?\\d{1,3}[\\s\\-])?([6-9]\\d{9})\/g,\n                \/\\+\\d{1,3}[\\s\\-]?\\d{3}[\\s\\-]?\\d{3}[\\s\\-]?\\d{4}\/g,\n                \/\\d{3}[\\s\\-\\.]\\d{3}[\\s\\-\\.]\\d{4}\/g\n            ];\n\n            for (const pattern of patterns) {\n                const matches = text.match(pattern);\n                if (matches) {\n                    const valid = matches.find(m => {\n                        const digits = countDigits(m);\n                        return digits >= 10 && digits <= 13 &#038;&#038; !hasYearRange(m) &#038;&#038; !isYear(m);\n                    });\n                    if (valid) return valid.replace(\/\\s+\/g,' ').trim();\n                }\n            }\n            return '';\n        }\n\n        function updateStats() {\n            statFiles.textContent = parsedData.length;\n            statEmails.textContent = parsedData.filter(i => i.email !== 'Not Found').length;\n            statPhones.textContent = parsedData.filter(i => i.phone !== 'Not Found').length;\n        }\n\n        function copyEmails() {\n            const emails = parsedData.filter(i => i.email !== 'Not Found').map(i => i.email);\n            if (!emails.length) { showToast('No emails to copy!', 'error'); return; }\n            navigator.clipboard.writeText(emails.join(', '))\n                .then(() => showToast(`${emails.length} email${emails.length>1?'s':''} copied!`))\n                .catch(() => showToast('Copy failed', 'error'));\n        }\n\n        function showToast(msg, type='success') {\n            toastMessage.textContent = msg;\n            copyToast.className = `fixed bottom-6 left-1\/2 -translate-x-1\/2 px-6 py-3 rounded-lg shadow-2xl z-50 flex items-center gap-2 ${type==='error'?'bg-red-600':'bg-dark'} text-white`;\n            copyToast.classList.remove('hidden');\n            setTimeout(() => copyToast.classList.add('hidden'), 3000);\n        }\n\n        function renderTable() {\n            resultsBody.innerHTML = '';\n            const visible = parsedData.filter(item => {\n                if (filters.hideNoEmail && item.email==='Not Found') return false;\n                if (filters.hideNoPhone && item.phone==='Not Found') return false;\n                return true;\n            });\n\n            resultCount.textContent = `${visible.length} record${visible.length!==1?'s':''}`;\n\n            if (!visible.length) {\n                resultsBody.innerHTML = `<tr><td colspan=\"3\" class=\"px-6 py-12 text-center text-gray-400\">${parsedData.length===0?'Upload resumes to see results':'No records match filters'}<\/td><\/tr>`;\n                return;\n            }\n\n            visible.forEach(data => {\n                const row = document.createElement('tr');\n                row.className = \"hover:bg-gray-50 transition-colors\";\n                row.innerHTML = `\n                    <td class=\"px-6 py-4 text-sm text-gray-600 font-mono\">${data.fileName}<\/td>\n                    <td class=\"px-6 py-4 text-sm ${data.email==='Not Found'?'text-gray-400 italic':'text-primary font-semibold'}\">${data.email}<\/td>\n                    <td class=\"px-6 py-4 text-sm ${data.phone==='Not Found'?'text-gray-400 italic':'text-blue-600 font-semibold'}\">${data.phone}<\/td>\n                `;\n                resultsBody.appendChild(row);\n            });\n        }\n\n        function showError(msg) {\n            errorArea.textContent = msg;\n            errorArea.classList.remove('hidden');\n            setTimeout(() => errorArea.classList.add('hidden'), 5000);\n        }\n\n        function exportToCSV() {\n            if (!parsedData.length) return;\n            const headers = ['File Name','Email Address','Phone Number'];\n            const rows = parsedData.map(r => [`\"${r.fileName}\"`, `\"${r.email}\"`, `\"${r.phone}\"`].join(','));\n            const csv = [headers.join(','), ...rows].join('\\n');\n            const blob = new Blob([csv], {type:'text\/csv'});\n            const link = document.createElement('a');\n            link.href = URL.createObjectURL(blob);\n            link.download = `contacts_${new Date().toISOString().split('T')[0]}.csv`;\n            link.click();\n        }\n    <\/script>\n<\/body>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>Resume Parser &#8211; Extract Contacts 100% Client-Side Processing Extract contacts from resumes instantly Upload PDF or DOCX files to parse [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"full-width-container","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"disabled","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"disabled","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-59","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.oneclickai.in\/index.php\/wp-json\/wp\/v2\/pages\/59","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.oneclickai.in\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.oneclickai.in\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.oneclickai.in\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.oneclickai.in\/index.php\/wp-json\/wp\/v2\/comments?post=59"}],"version-history":[{"count":0,"href":"https:\/\/www.oneclickai.in\/index.php\/wp-json\/wp\/v2\/pages\/59\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.oneclickai.in\/index.php\/wp-json\/wp\/v2\/media?parent=59"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}