{"id":1116,"date":"2025-10-24T01:49:45","date_gmt":"2025-10-24T01:49:45","guid":{"rendered":"https:\/\/abatablaster.xyz\/?page_id=1116"},"modified":"2026-10-09T02:20:34","modified_gmt":"2026-10-09T02:20:34","slug":"auto-join-group","status":"publish","type":"page","link":"https:\/\/abatablaster.xyz\/index.php\/auto-join-group\/","title":{"rendered":"Auto Join\/Leave Group"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"ms\">\n\n<head>\n    <meta charset=\"UTF-8\" \/>\n    <title>Auto Join Group \u2013 AbataBlaster<\/title>\n    <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" \/>\n    <script src=\"https:\/\/cdn.jsdelivr.net\/npm\/sweetalert2@11\"><\/script>\n    <script src=\"https:\/\/cdn.jsdelivr.net\/npm\/xlsx@0.18.5\/dist\/xlsx.full.min.js\"><\/script>\n\n    <style>\n        \/* ============ Base ============ *\/\n        :root {\n            --green: #2e7d32;\n            --green-2: #226624;\n            --green-3: #215e2e;\n            --bg: #eef9f0;\n            --muted: #668d6b;\n            --card: #fcfffb;\n            --border: #cbe8d6;\n            --border-2: #e0e0e0;\n            --shadow: 0 4px 24px rgba(54, 196, 124, .07), 0 2px 10px rgba(0, 0, 0, .05);\n        }\n\n        * {\n            box-sizing: border-box\n        }\n\n        body {\n            background: var(--bg);\n            font-family: system-ui, 'Segoe UI Emoji', 'Noto Color Emoji', sans-serif;\n            margin: 0;\n            padding: 0;\n        }\n\n        h3 {\n            color: var(--green);\n            text-align: center;\n            margin: 8px 0 14px;\n        }\n\n        \/* ============ Forms & Layout ============ *\/\n        .form-label {\n            font-weight: 600;\n            margin-top: 14px;\n            display: block;\n            color: var(--green-2);\n        }\n\n        .form-input,\n        select,\n        textarea {\n            width: 100%;\n            padding: 9px 12px;\n            margin: 6px 0 8px 0;\n            border: 1.2px solid var(--border);\n            border-radius: 7px;\n            background: #f9fff5;\n            font-size: 16px;\n            font-family: inherit;\n        }\n\n        textarea {\n            min-height: 110px;\n            min-width: 220px;\n            \/* elak terlalu kecil *\/\n            resize: both;\n            \/* boleh kiri-kanan & atas-bawah *\/\n            overflow: auto;\n            max-width: 100%;\n        }\n\n        .row {\n            display: flex;\n            gap: 10px;\n            flex-wrap: wrap;\n            align-items: center;\n        }\n\n        .row>* {\n            flex: 1 1 220px;\n        }\n\n        \/* auto pecah baris bila sempit *\/\n\n        .muted {\n            color: var(--muted);\n            font-size: 13px;\n        }\n\n        .card {\n            border: 1px solid var(--border-2);\n            border-radius: 10px;\n            padding: 12px;\n            background: var(--card);\n        }\n\n        .stack>* {\n            margin-top: 10px;\n        }\n\n        \/* ============ Buttons ============ *\/\n        .btn {\n            background: var(--green);\n            color: #fff;\n            padding: 10px 16px;\n            border: none;\n            border-radius: 7px;\n            cursor: pointer;\n            font-size: 15px;\n            font-weight: 600;\n            margin-top: 6px;\n            transition: .15s;\n            box-shadow: 0 1.5px 4px rgba(54, 196, 124, .11);\n            display: inline-block;\n        }\n\n        .btn:hover,\n        .btn:focus {\n            background: #185734;\n        }\n\n        .btn.blue {\n            background: #1565c0;\n        }\n\n        .btn.gray {\n            background: #bdbdbd;\n            color: #333;\n        }\n\n        .btn.danger {\n            background: #c62828;\n            color: #fff;\n        }\n\n        .btn.danger:hover,\n        .btn.danger:focus {\n            background: #9f1f1f;\n        }\n\n        .phone-result-card.paused {\n            border-color: #f59e0b;\n            animation: none;\n            box-shadow:\n                0 0 0 3px rgba(245, 158, 11, .10),\n                0 8px 24px rgba(245, 158, 11, .10);\n        }\n\n        .phone-result-card.stopped {\n            border-color: #b8bfc0;\n            animation: none;\n            opacity: .88;\n        }\n\n        .group-result-row.stopped {\n            background: #f5f6f5;\n            border-color: #dfe3df;\n        }\n\n        .group-result-row.stopped .group-result-status {\n            color: #68706a;\n        }\n\n        .btn.outline {\n            background: #fff;\n            color: var(--green);\n            border: 1px solid var(--green);\n        }\n\n        \/* ============ Logs ============ *\/\n        pre.log {\n            background: #0d232c;\n            color: #d7ffe5;\n            border-radius: 8px;\n            padding: 12px;\n            overflow: auto;\n            max-height: 360px;\n            font-size: 13px;\n            line-height: 1.45;\n        }\n\n        \/* Badge *\/\n        code.badge {\n            background: #e8f5e9;\n            color: var(--green-2);\n            border: 1px solid var(--border);\n            border-radius: 999px;\n            padding: 2px 7px;\n            font-size: 12px;\n        }\n\n        \/* ============ Numbers Grid ============ *\/\n        .gridNumbers {\n            display: grid;\n            gap: 12px;\n            grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));\n            \/* muat banyak pada telefon *\/\n        }\n\n        .numCard {\n            border: 1.5px dashed #cfe9da;\n            background: #f6fff8;\n            border-radius: 12px;\n            padding: 10px 12px;\n            display: flex;\n            align-items: center;\n            gap: 10px;\n            cursor: pointer;\n            transition: box-shadow .15s, background .15s, border-color .15s;\n            font-size: 14px;\n            line-height: 1.25;\n        }\n\n        .numCard:hover {\n            box-shadow: 0 2px 8px rgba(0, 0, 0, .06);\n            background: #f3fff7;\n        }\n\n        .numCard input[type=\"checkbox\"] {\n            transform: scale(1.05);\n        }\n\n        .numTitle {\n            display: flex;\n            flex-direction: column;\n        }\n\n        .numName {\n            font-weight: 600;\n            color: var(--green-3);\n        }\n\n        .numMeta {\n            color: #5b8a66;\n            font-size: 12px;\n        }\n\n        \/* status dot *\/\n        .dot {\n            width: 9px;\n            height: 9px;\n            border-radius: 50%;\n            display: inline-block;\n            margin-right: 6px;\n        }\n\n        .dot.green {\n            background: #15b34a;\n            box-shadow: 0 0 0 2px #e7f7ee inset;\n        }\n\n        .dot.red {\n            background: #e53935;\n            box-shadow: 0 0 0 2px #fde9e8 inset;\n        }\n\n        \/* Leave table hover *\/\n        #leaveGroupTable label:hover {\n            background: #f6fff8;\n        }\n\n        \/* ============ Responsive ============ *\/\n        @media (max-width:480px) {\n            .row>* {\n                flex-basis: 100%;\n            }\n\n            \/* telefon: satu lajur penuh *\/\n        }\n\n        @media (max-width:600px) {\n            #wrap {\n                padding: 10px 8px 18px;\n            }\n\n            h3 {\n                font-size: 18px;\n            }\n\n            .form-input,\n            select,\n            textarea {\n                font-size: 15px;\n            }\n\n            .btn {\n                width: 100%;\n            }\n\n            \/* butang penuh lebar *\/\n            pre.log {\n                max-height: 46vh;\n            }\n\n            \/* log tidak dominan di skrin kecil *\/\n            .numCard {\n                padding: 8px 10px;\n                font-size: 13px;\n            }\n\n            .numMeta {\n                font-size: 11px;\n            }\n        }\n\n        @media (min-width:640px) {\n\n            \/* tablet kecil \/ phone besar *\/\n            .gridNumbers {\n                grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));\n            }\n        }\n\n        @media (min-width:900px) {\n\n            \/* 3 select lebih seimbang bila lebar *\/\n            .row>div[style*=\"min-width:180px\"] {\n                flex: 1 1 0;\n            }\n        }\n\n        @media (min-width:1024px) {\n\n            \/* desktop *\/\n            .gridNumbers {\n                grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n            }\n        }\n\n        @media (min-width:1200px) {\n\n            \/* desktop besar *\/\n            pre.log {\n                max-height: 520px;\n            }\n        }\n\n        \/* elak gegaran bila scrollbar muncul\/hilang *\/\n        html {\n            scrollbar-gutter: stable both-edges;\n        }\n\n        html,\n        body {\n            overflow-x: hidden;\n        }\n\n        \/* Kontena utama \u2014 sentiasa center & melebar ikut skrin *\/\n        #wrap {\n            max-width: 1600px;\n            \/* ubah ikut selera *\/\n            width: min(96vw, 1600px);\n            \/* hampir penuh di desktop *\/\n            margin: clamp(12px, 4vw, 32px) auto;\n            padding: clamp(14px, 2.5vw, 28px);\n            background: #fff;\n            border-radius: 14px;\n            box-shadow: var(--shadow);\n        }\n\n        \/* optional \u2013 hanya jika CMS menghadkan lebar *\/\n        .container,\n        .site-content,\n        .entry-content,\n        .wp-block-group__inner-container {\n            max-width: 100% !important;\n        }\n\n        \/* Buang padding\/gutter parent di telefon *\/\n        @media (max-width: 640px) {\n            :where(.container, .site-content, .entry-content, .wp-block-group__inner-container) {\n                padding-left: 0 !important;\n                padding-right: 0 !important;\n            }\n\n            \/* Paksa kotak putih center & selebar viewport *\/\n            #wrap {\n                width: 100svw;\n                \/* elak kira scrollbar *\/\n                margin-left: calc(50% - 50svw);\n                margin-right: calc(50% - 50svw);\n                \/* optional: kalau nak ada ruang sisi sikit, guna padding-inline *\/\n                padding-inline: 12px;\n            }\n        }\n\n        \/* Fallback untuk browser lama yang tak sokong svw *\/\n        @supports not (width: 100svw) {\n            @media (max-width: 640px) {\n                #wrap {\n                    width: 100vw;\n                    margin-left: calc(50% - 50vw);\n                    margin-right: calc(50% - 50vw);\n                    padding-inline: 12px;\n                }\n            }\n        }\n\n        .actions-center {\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            gap: 10px;\n            flex-wrap: wrap;\n        }\n\n        .actions-center .muted {\n            width: 100%;\n            text-align: center;\n        }\n\n        \/* Seksyen Leave Group *\/\n        .leave {\n            margin-top: 18px;\n        }\n\n        .leave-controls {\n            display: flex;\n            gap: 12px;\n            justify-content: center;\n            align-items: flex-end;\n            flex-wrap: wrap;\n        }\n\n        .leave-controls .field {\n            min-width: 220px;\n            flex: 0 1 320px;\n        }\n\n        .leave-groups {\n            max-width: 820px;\n            margin: 12px auto;\n        }\n\n        .leave-actions {\n            margin-top: 10px;\n        }\n\n        \/* Butang besar dan center *\/\n        .btn.large {\n            padding: 12px 22px;\n            font-size: 16px;\n        }\n\n        .leave-actions .btn {\n            width: min(100%, 640px);\n        }\n\n        .leave-actions,\n        .leave-tip {\n            display: flex;\n            justify-content: center;\n        }\n\n        .leave-tip {\n            margin-top: 6px;\n        }\n\n        \/* ============ App Tabs ============ *\/\n        .app-tabs {\n            display: flex;\n            gap: 5px;\n            padding: 5px;\n            margin: 14px 0 18px;\n            background: #edf7ef;\n            border: 1px solid var(--border);\n            border-radius: 14px;\n        }\n\n        .app-tab {\n            flex: 1;\n            border: 0;\n            background: transparent;\n            color: #58755e;\n            padding: 11px 14px;\n            border-radius: 10px;\n            font-size: 14px;\n            font-weight: 700;\n            cursor: pointer;\n            font-family: inherit;\n            transition: .15s ease;\n        }\n\n        .app-tab.active {\n            background: #fff;\n            color: var(--green);\n            box-shadow: 0 2px 10px rgba(0, 0, 0, .08);\n        }\n\n        .tab-panel {\n            display: none;\n        }\n\n        .tab-panel.active {\n            display: block;\n        }\n\n        \/* ============ Invite Link Editor ============ *\/\n\n        .link-editor-head {\n            display: flex;\n            align-items: center;\n            justify-content: space-between;\n            gap: 10px;\n            margin-top: 14px;\n            margin-bottom: 6px;\n            flex-wrap: wrap;\n        }\n\n        .link-editor-title {\n            display: flex;\n            align-items: center;\n            gap: 7px;\n            color: var(--green-2);\n            font-size: 15px;\n            font-weight: 800;\n        }\n\n        .link-count-pill {\n            min-width: 28px;\n            padding: 3px 7px;\n            background: #e8f5e9;\n            border: 1px solid #cce6d1;\n            border-radius: 999px;\n            color: var(--green);\n            font-size: 10px;\n            font-weight: 800;\n            text-align: center;\n        }\n\n        .link-range-bar {\n            display: flex;\n            align-items: center;\n            gap: 5px;\n            padding: 4px 6px;\n            background: #f5faf6;\n            border: 1px solid #dcebe0;\n            border-radius: 10px;\n        }\n\n        .link-range-icon {\n            width: 24px;\n            text-align: center;\n            font-size: 14px;\n        }\n\n        .link-range-input {\n            width: 58px !important;\n            height: 30px;\n            margin: 0 !important;\n            padding: 4px 6px !important;\n            border-radius: 7px !important;\n            text-align: center;\n            font-size: 12px !important;\n            font-weight: 700;\n        }\n\n        .link-range-arrow {\n            color: #799080;\n            font-size: 11px;\n            font-weight: 800;\n        }\n\n        .link-filter-info {\n            padding: 4px 7px;\n            color: #55705d;\n            background: #fff;\n            border: 1px solid #e1ebe3;\n            border-radius: 7px;\n            font-size: 10px;\n            font-weight: 800;\n            white-space: nowrap;\n        }\n\n        .link-selection-notice {\n            display: flex;\n            align-items: center;\n            gap: 6px;\n            min-height: 28px;\n            margin-bottom: 6px;\n            padding: 5px 9px;\n            color: #5f7464;\n            background: #f7faf7;\n            border: 1px solid #e2ebe4;\n            border-radius: 8px;\n            font-size: 11px;\n            font-weight: 700;\n        }\n\n        .link-selection-notice.filtered {\n            color: #166534;\n            background: #effaf2;\n            border-color: #bfe4c8;\n        }\n\n        .link-selection-notice.invalid {\n            color: #b45309;\n            background: #fffbeb;\n            border-color: #fde68a;\n        }\n\n        .link-selection-icon {\n            flex: 0 0 auto;\n            font-size: 12px;\n            font-weight: 900;\n        }\n\n        .link-selection-text {\n            min-width: 0;\n        }\n\n        .link-editor-shell {\n            display: grid;\n            grid-template-columns: 58px minmax(0, 1fr);\n            height: 280px;\n            min-height: 180px;\n            max-height: 70vh;\n            overflow: hidden;\n            resize: vertical;\n            background: #fafff8;\n            border: 1px solid var(--border);\n            border-radius: 10px;\n        }\n\n        .link-number-gutter {\n            position: relative;\n            overflow: hidden;\n            background: #f3faf4;\n            border-right: 1px solid #dceadf;\n            user-select: none;\n        }\n\n        .link-line-numbers {\n            padding-top: 10px;\n            padding-bottom: 10px;\n            will-change: transform;\n        }\n\n        .link-line-no {\n            position: relative;\n            height: 24px;\n            padding-right: 10px;\n            color: #9aac9e;\n            font-size: 11px;\n            font-weight: 700;\n            line-height: 24px;\n            text-align: right;\n        }\n\n        .link-line-no.active {\n            color: #147b34;\n            background: #e4f6e8;\n            font-weight: 900;\n        }\n\n        .link-line-no.verifier-new {\n            color: #0f6f31;\n            background: #dcfce7;\n            box-shadow:\n                inset 3px 0 0 #22c55e;\n            font-weight: 900;\n        }\n\n        .link-line-no.verifier-new::before {\n            content: \"NEW\";\n            position: absolute;\n            left: 3px;\n            top: 50%;\n            transform: translateY(-50%);\n            padding: 1px 3px;\n            border-radius: 4px;\n            background: #16a34a;\n            color: #fff;\n            font-size: 6px;\n            font-weight: 900;\n            line-height: 1.35;\n        }\n\n        .link-line-no.verifier-new.active {\n            background: #c9f5d4;\n        }\n\n        #links.link-editor-textarea {\n            width: 100%;\n            height: 100%;\n            min-height: 0;\n            margin: 0;\n            padding: 10px 12px;\n            border: 0;\n            border-radius: 0;\n            outline: none;\n            resize: none;\n            background: transparent;\n            font-family: ui-monospace, SFMono-Regular, Consolas, monospace;\n            font-size: 12px;\n            line-height: 24px;\n            white-space: pre;\n            overflow: auto;\n        }\n\n        #links.link-editor-textarea:focus {\n            box-shadow: inset 0 0 0 1px rgba(46, 125, 50, .18);\n        }\n\n        .result-header-actions {\n            display: flex;\n            gap: 7px;\n            align-items: center;\n            flex-wrap: wrap;\n            justify-content: flex-end;\n        }\n\n        .final-link-filter {\n            margin-bottom: 12px;\n            padding: 11px;\n            background: #fff;\n            border: 1px solid #dfeae1;\n            border-radius: 12px;\n        }\n\n        .final-link-filter-head {\n            display: flex;\n            align-items: center;\n            justify-content: space-between;\n            gap: 10px;\n            flex-wrap: wrap;\n        }\n\n        .final-link-filter-title {\n            color: var(--green-3);\n            font-size: 12px;\n            font-weight: 800;\n        }\n\n        .final-link-filter-count {\n            padding: 4px 8px;\n            background: #e8f5e9;\n            border: 1px solid #cce6d1;\n            border-radius: 999px;\n            color: var(--green);\n            font-size: 10px;\n            font-weight: 800;\n        }\n\n        .final-link-filter-options {\n            display: flex;\n            gap: 6px;\n            margin-top: 9px;\n            flex-wrap: wrap;\n        }\n\n        .final-link-filter-option {\n            display: inline-flex;\n            align-items: center;\n            gap: 5px;\n            padding: 5px 8px;\n            background: #f8faf8;\n            border: 1px solid #e4ece5;\n            border-radius: 8px;\n            color: #526357;\n            cursor: pointer;\n            font-size: 10px;\n            font-weight: 700;\n            user-select: none;\n        }\n\n        .final-link-filter-option input {\n            width: auto;\n            margin: 0;\n        }\n\n        .final-link-filter-presets {\n            display: flex;\n            gap: 6px;\n            margin-top: 9px;\n            flex-wrap: wrap;\n        }\n\n        .final-link-filter-actions {\n            display: flex;\n            gap: 6px;\n            margin-top: 9px;\n            flex-wrap: wrap;\n        }\n\n        .final-link-filter-presets .btn,\n        .final-link-filter-actions .btn {\n            width: auto;\n            margin: 0;\n            padding: 7px 10px;\n            font-size: 10px;\n        }\n\n        @media (max-width:600px) {\n            .final-link-filter-presets,\n            .final-link-filter-actions {\n                display: grid;\n                grid-template-columns:\n                    repeat(2, minmax(0, 1fr));\n            }\n\n            .final-link-filter-presets .btn,\n            .final-link-filter-actions .btn {\n                width: 100%;\n            }\n        }\n\n        @media (max-width:600px) {\n            .link-editor-head {\n                align-items: stretch;\n                flex-direction: column;\n                gap: 6px;\n            }\n\n            .link-range-bar {\n                width: 100%;\n            }\n\n            .link-range-input {\n                flex: 0 0 58px;\n            }\n\n            .link-filter-info {\n                margin-left: auto;\n            }\n\n            .link-editor-shell {\n                grid-template-columns: 50px minmax(0, 1fr);\n                height: 240px;\n            }\n\n            .link-line-no {\n                padding-right: 7px;\n                font-size: 10px;\n            }\n\n            #links.link-editor-textarea {\n                font-size: 11px;\n            }\n\n            .result-header-actions {\n                width: 100%;\n                justify-content: stretch;\n            }\n\n            .result-header-actions .btn {\n                flex: 1;\n            }\n        }\n\n        \/* ============ Result Dashboard ============ *\/\n        .result-shell {\n            margin-top: 18px;\n            padding: 14px;\n            background: #f8fbf8;\n            border: 1px solid var(--border);\n            border-radius: 16px;\n        }\n\n        .result-header {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            gap: 12px;\n            margin-bottom: 12px;\n        }\n\n        .result-title {\n            color: var(--green-3);\n            font-size: 16px;\n            font-weight: 800;\n        }\n\n        .result-summary {\n            display: grid;\n            grid-template-columns: repeat(7, minmax(0, 1fr));\n            gap: 8px;\n            margin-bottom: 12px;\n        }\n\n        .summary-card {\n            background: #fff;\n            border: 1px solid #e4eee6;\n            border-radius: 12px;\n            padding: 10px;\n            text-align: center;\n        }\n\n        .summary-value {\n            display: block;\n            font-size: 21px;\n            line-height: 1;\n            font-weight: 800;\n            margin-bottom: 5px;\n        }\n\n        .summary-label {\n            color: #708075;\n            font-size: 11px;\n            font-weight: 700;\n        }\n\n        .summary-card.success .summary-value {\n            color: #15803d;\n        }\n\n        .summary-card.already .summary-value {\n            color: #b7791f;\n        }\n\n        .summary-card.approval .summary-value {\n            color: #c2410c;\n        }\n\n        .summary-card.failed .summary-value {\n            color: #c62828;\n        }\n\n        .summary-card.disconnected .summary-value {\n            color: #7c3aed;\n        }\n\n        .result-list {\n            display: flex;\n            flex-direction: column;\n            gap: 8px;\n        }\n\n        .result-empty {\n            padding: 24px 12px;\n            text-align: center;\n            color: #7a8b7e;\n            background: #fff;\n            border: 1px dashed #d8e6da;\n            border-radius: 12px;\n            font-size: 13px;\n        }\n\n        .result-card {\n            background: #fff;\n            border: 1px solid #e1e9e2;\n            border-left: 5px solid #c4cec6;\n            border-radius: 12px;\n            padding: 11px 12px;\n            box-shadow: 0 2px 8px rgba(0, 0, 0, .035);\n        }\n\n        .result-card.success {\n            border-left-color: #16a34a;\n        }\n\n        .result-card.already {\n            border-left-color: #f59e0b;\n        }\n\n        .summary-card.announcement .summary-value {\n            color: #c2410c;\n        }\n\n        .summary-card.unconfirmed .summary-value {\n            color: #d97706;\n        }\n\n        .group-result-row.announcement {\n            background: #fff7ed;\n            border-color: #fed7aa;\n        }\n\n        .group-result-row.announcement .group-result-status {\n            color: #c2410c;\n        }\n\n        .group-result-row.unconfirmed {\n            background: #fffbeb;\n            border-color: #fde68a;\n        }\n\n        .group-result-row.unconfirmed .group-result-status {\n            color: #b45309;\n        }\n\n        .result-card.failed {\n            border-left-color: #dc2626;\n        }\n\n        .result-card-top {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            gap: 8px;\n        }\n\n        .result-phone {\n            color: #243729;\n            font-size: 13px;\n            font-weight: 800;\n            word-break: break-word;\n        }\n\n        .result-status {\n            flex: 0 0 auto;\n            padding: 4px 8px;\n            border-radius: 999px;\n            font-size: 10px;\n            font-weight: 800;\n            white-space: nowrap;\n        }\n\n        .result-card.success .result-status {\n            color: #166534;\n            background: #dcfce7;\n        }\n\n        .result-card.already .result-status {\n            color: #92400e;\n            background: #fef3c7;\n        }\n\n        .result-card.failed .result-status {\n            color: #991b1b;\n            background: #fee2e2;\n        }\n\n        .result-group {\n            margin-top: 7px;\n            color: #263f2c;\n            font-size: 14px;\n            font-weight: 700;\n            word-break: break-word;\n        }\n\n        .result-message {\n            margin-top: 4px;\n            color: #718077;\n            font-size: 12px;\n            line-height: 1.4;\n        }\n\n        .result-meta {\n            margin-top: 5px;\n            color: #9aa59c;\n            font-size: 10px;\n            word-break: break-all;\n        }\n\n        \/* Debug bukan lagi paparan utama *\/\n        .debug-details {\n            margin-top: 12px;\n            border-top: 1px solid #e2ebe4;\n            padding-top: 10px;\n        }\n\n        .debug-details summary {\n            color: #758078;\n            font-size: 12px;\n            font-weight: 700;\n            cursor: pointer;\n            user-select: none;\n        }\n\n        .debug-details pre.log {\n            margin-bottom: 8px;\n        }\n\n        @media (max-width:600px) {\n            .app-tabs {\n                position: sticky;\n                top: 0;\n                z-index: 30;\n                margin-top: 8px;\n            }\n\n            .app-tab {\n                padding: 10px 6px;\n                font-size: 13px;\n            }\n\n            .result-shell {\n                padding: 10px;\n                border-radius: 13px;\n            }\n\n            .result-header {\n                align-items: flex-start;\n            }\n\n            .result-header .btn {\n                width: auto;\n                margin: 0;\n                padding: 7px 10px;\n                font-size: 11px;\n            }\n\n            .result-summary {\n                grid-template-columns: repeat(2, minmax(0, 1fr));\n                gap: 5px;\n            }\n\n            .phone-card-stats {\n                grid-template-columns: repeat(3, 1fr);\n            }\n\n            .summary-card {\n                padding: 8px 4px;\n            }\n\n            .summary-value {\n                font-size: 19px;\n            }\n\n            .summary-label {\n                font-size: 10px;\n            }\n\n            .result-card {\n                padding: 10px;\n            }\n\n            .result-phone {\n                font-size: 12px;\n            }\n\n            .result-group {\n                font-size: 13px;\n            }\n        }\n\n        \/* =====================================================\n           AUTO JOIN \u2014 1 PHONE = 1 RESULT CARD\n           ===================================================== *\/\n\n        #joinResults.result-list {\n            display: grid;\n            grid-template-columns: repeat(auto-fit, minmax(330px, 1fr));\n            gap: 12px;\n            align-items: start;\n        }\n\n        .phone-result-card {\n            position: relative;\n            overflow: hidden;\n            background: #fff;\n            border: 1px solid #dde9df;\n            border-radius: 16px;\n            padding: 13px;\n            transition:\n                border-color .2s ease,\n                box-shadow .2s ease,\n                transform .2s ease;\n        }\n\n        .phone-result-card.waiting {\n            border-color: #dde9df;\n        }\n\n        .phone-result-card.running {\n            border-color: #22a447;\n            box-shadow:\n                0 0 0 3px rgba(34, 164, 71, .12),\n                0 8px 26px rgba(34, 164, 71, .15);\n            animation: phoneRunningGlow 1.7s ease-in-out infinite;\n        }\n\n        .phone-result-card.done {\n            border-color: #b9dfc3;\n        }\n\n        .phone-result-card.error {\n            border-color: #efb5b5;\n        }\n\n        .phone-result-card.running.paused {\n            border-color: #f59e0b;\n            animation: none;\n            box-shadow:\n                0 0 0 3px rgba(245, 158, 11, .10),\n                0 8px 24px rgba(245, 158, 11, .10);\n        }\n\n        .phone-result-card.paused .phone-card-status {\n            background: #fef3c7;\n            color: #92400e;\n        }\n\n        @keyframes phoneRunningGlow {\n\n            0%,\n            100% {\n                box-shadow:\n                    0 0 0 3px rgba(34, 164, 71, .10),\n                    0 7px 20px rgba(34, 164, 71, .10);\n            }\n\n            50% {\n                box-shadow:\n                    0 0 0 5px rgba(34, 164, 71, .16),\n                    0 10px 30px rgba(34, 164, 71, .20);\n            }\n        }\n\n        .phone-card-head {\n            display: flex;\n            justify-content: space-between;\n            align-items: flex-start;\n            gap: 10px;\n        }\n\n        .phone-card-number {\n            color: #203b27;\n            font-size: 15px;\n            font-weight: 800;\n            word-break: break-word;\n        }\n\n        .phone-card-progress-text {\n            margin-top: 3px;\n            color: #78907d;\n            font-size: 11px;\n        }\n\n        .phone-card-status {\n            flex: 0 0 auto;\n            border-radius: 999px;\n            padding: 5px 9px;\n            background: #eef3ef;\n            color: #69776c;\n            font-size: 10px;\n            font-weight: 800;\n            white-space: nowrap;\n        }\n\n        .phone-result-card.running .phone-card-status {\n            background: #dcfce7;\n            color: #166534;\n        }\n\n        .phone-result-card.done .phone-card-status {\n            background: #e8f5e9;\n            color: #21743a;\n        }\n\n        .phone-result-card.error .phone-card-status {\n            background: #fee2e2;\n            color: #991b1b;\n        }\n\n        .phone-progress-track {\n            width: 100%;\n            height: 7px;\n            margin-top: 11px;\n            overflow: hidden;\n            background: #edf2ee;\n            border-radius: 999px;\n        }\n\n        .phone-progress-fill {\n            width: 0%;\n            height: 100%;\n            background: #2e9e49;\n            border-radius: inherit;\n            transition: width .3s ease;\n        }\n\n        .phone-card-stats {\n            display: grid;\n            grid-template-columns: repeat(7, 1fr);\n            gap: 6px;\n            margin-top: 10px;\n        }\n\n        .phone-mini-stat {\n            padding: 7px 5px;\n            background: #f8faf8;\n            border: 1px solid #edf1ed;\n            border-radius: 9px;\n            text-align: center;\n        }\n\n        .phone-mini-stat strong {\n            display: block;\n            color: #324337;\n            font-size: 14px;\n        }\n\n        .phone-mini-stat span {\n            display: block;\n            margin-top: 1px;\n            color: #859087;\n            font-size: 9px;\n            font-weight: 700;\n        }\n\n        .phone-group-details {\n            margin-top: 11px;\n            border-top: 1px solid #edf2ed;\n            padding-top: 9px;\n        }\n\n        .phone-group-details>summary {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            cursor: pointer;\n            color: #526357;\n            font-size: 12px;\n            font-weight: 700;\n            user-select: none;\n        }\n\n        .phone-group-details>summary::marker {\n            color: #5d8065;\n        }\n\n        .phone-group-list {\n            display: flex;\n            flex-direction: column;\n            gap: 6px;\n            margin-top: 9px;\n            max-height: 340px;\n            overflow-y: auto;\n            padding-right: 2px;\n        }\n\n        .group-result-row {\n            padding: 8px 9px;\n            border: 1px solid #edf0ed;\n            border-radius: 10px;\n            background: #fafcfa;\n            transition: .15s ease;\n        }\n\n        .group-result-row.joining {\n            background: #effaf2;\n            border-color: #a8ddb5;\n            box-shadow: 0 0 0 2px rgba(46, 125, 50, .06);\n        }\n\n        .group-result-row.waiting-reconnect {\n            background: #fff7ed;\n            border-color: #fdba74;\n            box-shadow: 0 0 0 2px rgba(234, 88, 12, .05);\n        }\n\n        .group-result-row.waiting-reconnect .group-result-status {\n            color: #c2410c;\n        }\n\n        .group-result-row.success {\n            background: #f2fbf4;\n            border-color: #c8e9cf;\n        }\n\n        .group-result-row.already {\n            background: #fffaf0;\n            border-color: #f5dcaa;\n        }\n\n        .group-result-row.failed {\n            background: #fff5f5;\n            border-color: #efc4c4;\n        }\n\n        .group-result-row.approval-required {\n            background: #fff7ed;\n            border-color: #fdba74;\n        }\n\n        .group-result-row.approval-required .group-result-status {\n            color: #c2410c;\n        }\n\n        .group-result-row.expired {\n            background: #fef2f2;\n            border-color: #fecaca;\n        }\n\n        .group-result-row.expired .group-result-status {\n            color: #b91c1c;\n        }\n\n        .group-result-row.not-allowed {\n            background: #fff1f2;\n            border-color: #fecdd3;\n        }\n\n        .group-result-row.not-allowed .group-result-status {\n            color: #be123c;\n        }\n\n        .group-result-row.bad-link {\n            background: #f8fafc;\n            border-color: #cbd5e1;\n        }\n\n        .group-result-row.bad-link .group-result-status {\n            color: #475569;\n        }\n\n        .group-result-row.disconnected {\n            background: #faf5ff;\n            border-color: #d8b4fe;\n        }\n\n        .group-result-row.disconnected .group-result-status {\n            color: #7e22ce;\n        }\n\n        .group-result-main {\n            display: flex;\n            justify-content: space-between;\n            align-items: flex-start;\n            gap: 8px;\n        }\n\n        .group-result-name {\n            min-width: 0;\n            color: #324038;\n            font-size: 12px;\n            font-weight: 700;\n            word-break: break-word;\n        }\n\n        .group-result-status {\n            flex: 0 0 auto;\n            font-size: 10px;\n            font-weight: 800;\n            white-space: nowrap;\n        }\n\n        .group-result-row.waiting .group-result-status {\n            color: #8c978e;\n        }\n\n        .group-result-row.joining .group-result-status {\n            color: #24743b;\n        }\n\n        .group-result-row.success .group-result-status {\n            color: #15803d;\n        }\n\n        .group-result-row.already .group-result-status {\n            color: #a16207;\n        }\n\n        .group-result-row.failed:not(.approval-required):not(.expired):not(.not-allowed):not(.bad-link) .group-result-status {\n            color: #b91c1c;\n        }\n\n        .group-result-meta {\n            margin-top: 3px;\n            overflow: hidden;\n            color: #9aa59c;\n            font-size: 9px;\n            text-overflow: ellipsis;\n            white-space: nowrap;\n        }\n\n        @media (max-width:700px) {\n            #joinResults.result-list {\n                grid-template-columns: 1fr;\n            }\n\n            .phone-result-card {\n                padding: 11px;\n                border-radius: 13px;\n            }\n\n            .phone-card-number {\n                font-size: 14px;\n            }\n\n            .phone-group-list {\n                max-height: 46vh;\n            }\n        }\n\n        \/* =====================================================\n           AUTO JOIN \u2014 CRASH \/ RESTART RECOVERY\n           ===================================================== *\/\n\n        .autojoin-recovery-card {\n            margin-top: 14px;\n            padding: 14px;\n            background: #fffaf0;\n            border: 1px solid #f6c96b;\n            border-left: 5px solid #f59e0b;\n            border-radius: 14px;\n            box-shadow: 0 4px 14px rgba(180, 120, 20, .08);\n        }\n\n        .autojoin-recovery-head {\n            display: flex;\n            justify-content: space-between;\n            align-items: flex-start;\n            gap: 12px;\n        }\n\n        .autojoin-recovery-title {\n            color: #92400e;\n            font-size: 15px;\n            font-weight: 800;\n        }\n\n        .autojoin-recovery-text {\n            max-width: 760px;\n            margin-top: 4px;\n            color: #785b2a;\n            font-size: 12px;\n            line-height: 1.5;\n        }\n\n        .autojoin-recovery-badge {\n            flex: 0 0 auto;\n            padding: 5px 9px;\n            color: #92400e;\n            background: #fef3c7;\n            border: 1px solid #fde68a;\n            border-radius: 999px;\n            font-size: 9px;\n            font-weight: 900;\n        }\n\n        .autojoin-recovery-stats {\n            display: grid;\n            grid-template-columns: repeat(5, minmax(0, 1fr));\n            gap: 7px;\n            margin-top: 12px;\n        }\n\n        .autojoin-recovery-stat {\n            padding: 9px 6px;\n            background: #fff;\n            border: 1px solid #f5e2b8;\n            border-radius: 10px;\n            text-align: center;\n        }\n\n        .autojoin-recovery-stat strong {\n            display: block;\n            color: #4f3b18;\n            font-size: 16px;\n        }\n\n        .autojoin-recovery-stat span {\n            display: block;\n            margin-top: 2px;\n            color: #967240;\n            font-size: 8px;\n            font-weight: 800;\n        }\n\n        .autojoin-recovery-meta {\n            margin-top: 10px;\n            color: #85652f;\n            font-size: 10px;\n            line-height: 1.5;\n        }\n\n        .autojoin-recovery-actions {\n            display: flex;\n            gap: 8px;\n            margin-top: 11px;\n            flex-wrap: wrap;\n        }\n\n        .autojoin-recovery-actions .btn {\n            margin: 0;\n        }\n\n        @media (max-width:600px) {\n            .autojoin-recovery-head {\n                flex-direction: column;\n            }\n\n            .autojoin-recovery-stats {\n                grid-template-columns: repeat(2, minmax(0, 1fr));\n            }\n\n            .autojoin-recovery-actions {\n                flex-direction: column;\n            }\n\n            .autojoin-recovery-actions .btn {\n                width: 100%;\n            }\n        }\n\n        \/* =====================================================\n           LEAVE GROUP \u2014 COMPACT APP UI\n           ===================================================== *\/\n\n        .leave-app-shell {\n            max-width: 900px;\n            margin: 0 auto;\n        }\n\n        .leave-app-head {\n            display: flex;\n            align-items: center;\n            justify-content: space-between;\n            gap: 12px;\n            margin-bottom: 12px;\n        }\n\n        .leave-app-title {\n            color: #263c2b;\n            font-size: 17px;\n            font-weight: 800;\n        }\n\n        .leave-status-pill {\n            flex: 0 0 auto;\n            padding: 5px 10px;\n            border-radius: 999px;\n            background: #edf1ee;\n            color: #657068;\n            font-size: 10px;\n            font-weight: 800;\n        }\n\n        .leave-status-pill[data-status=\"EXTRACTING\"],\n        .leave-status-pill[data-status=\"LEAVING\"] {\n            background: #dbeafe;\n            color: #1d4ed8;\n        }\n\n        .leave-status-pill[data-status=\"READY\"] {\n            background: #ecfdf5;\n            color: #047857;\n        }\n\n        .leave-status-pill[data-status=\"DONE\"] {\n            background: #dcfce7;\n            color: #166534;\n        }\n\n        .leave-status-pill[data-status=\"PARTIAL\"] {\n            background: #fff7ed;\n            color: #c2410c;\n        }\n\n        .leave-status-pill[data-status=\"ERROR\"] {\n            background: #fee2e2;\n            color: #b91c1c;\n        }\n\n        .leave-picker-card {\n            display: grid;\n            grid-template-columns: minmax(0, 1fr) auto;\n            align-items: end;\n            gap: 10px;\n            padding: 12px;\n            background: #fff;\n            border: 1px solid #e1ebe3;\n            border-radius: 14px;\n        }\n\n        .leave-picker-field .form-label {\n            margin-top: 0;\n        }\n\n        .leave-extract-btn {\n            margin-bottom: 8px;\n            white-space: nowrap;\n        }\n\n        .leave-group-panel {\n            margin-top: 12px;\n            padding: 10px;\n            background: #f8faf8;\n            border: 1px solid #e1ebe3;\n            border-radius: 14px;\n        }\n\n        .leave-list-head {\n            display: flex;\n            align-items: center;\n            justify-content: space-between;\n            gap: 10px;\n            margin-bottom: 9px;\n        }\n\n        .leave-selected-count {\n            margin-left: 7px;\n            padding: 3px 7px;\n            border-radius: 999px;\n            background: #edf4ef;\n            color: #607066;\n            font-size: 10px;\n            font-weight: 700;\n        }\n\n        .leave-select-all {\n            width: auto !important;\n            margin: 0;\n            padding: 7px 10px;\n            font-size: 11px;\n        }\n\n        .leave-group-table {\n            display: flex;\n            flex-direction: column;\n            gap: 6px;\n            max-height: 420px;\n            overflow-y: auto;\n        }\n\n        .leave-group-row {\n            display: grid;\n            grid-template-columns: auto minmax(0, 1fr) auto;\n            align-items: center;\n            gap: 9px;\n            padding: 8px 9px;\n            background: #fff;\n            border: 1px solid #e8eee9;\n            border-radius: 10px;\n            cursor: pointer;\n        }\n\n        .leave-group-row:hover {\n            border-color: #bfd7c5;\n            background: #fbfefb;\n        }\n\n        .leave-group-row input {\n            margin: 0;\n        }\n\n        .leave-group-info {\n            min-width: 0;\n        }\n\n        .leave-group-name {\n            overflow: hidden;\n            color: #304137;\n            font-size: 12px;\n            font-weight: 700;\n            text-overflow: ellipsis;\n            white-space: nowrap;\n        }\n\n        .leave-group-meta {\n            margin-top: 2px;\n            overflow: hidden;\n            color: #97a29a;\n            font-size: 9px;\n            text-overflow: ellipsis;\n            white-space: nowrap;\n        }\n\n        .leave-row-status {\n            flex: 0 0 auto;\n            color: #8a958d;\n            font-size: 9px;\n            font-weight: 800;\n            white-space: nowrap;\n        }\n\n        .leave-group-row.leaving {\n            background: #eff6ff;\n            border-color: #bfdbfe;\n        }\n\n        .leave-group-row.leaving .leave-row-status {\n            color: #1d4ed8;\n        }\n\n        .leave-group-row.left {\n            background: #f0fdf4;\n            border-color: #bbf7d0;\n        }\n\n        .leave-group-row.left .leave-row-status {\n            color: #15803d;\n        }\n\n        .leave-group-row.already-left {\n            background: #fffbeb;\n            border-color: #fde68a;\n        }\n\n        .leave-group-row.already-left .leave-row-status {\n            color: #a16207;\n        }\n\n        .leave-group-row.failed {\n            background: #fef2f2;\n            border-color: #fecaca;\n        }\n\n        .leave-group-row.failed .leave-row-status {\n            color: #b91c1c;\n        }\n\n        .leave-group-row input:disabled {\n            opacity: .45;\n        }\n\n        .leave-action-bar {\n            display: flex;\n            align-items: center;\n            justify-content: space-between;\n            gap: 12px;\n            margin-top: 12px;\n            padding: 10px 12px;\n            background: #fff;\n            border: 1px solid #e1ebe3;\n            border-radius: 14px;\n        }\n\n        .leave-action-text {\n            color: #728078;\n            font-size: 11px;\n        }\n\n        .leave-main-btn {\n            width: auto !important;\n            margin: 0;\n            white-space: nowrap;\n        }\n\n        .leave-result-box {\n            margin-top: 12px;\n            padding: 12px;\n            background: #fff;\n            border: 1px solid #e1ebe3;\n            border-radius: 14px;\n        }\n\n        .leave-result-title {\n            margin-bottom: 9px;\n            color: #2d4033;\n            font-size: 13px;\n            font-weight: 800;\n        }\n\n        .leave-result-summary {\n            display: grid;\n            grid-template-columns: repeat(3, 1fr);\n            gap: 6px;\n            margin-bottom: 9px;\n        }\n\n        .leave-summary-item {\n            padding: 7px 5px;\n            text-align: center;\n            background: #f8faf8;\n            border-radius: 9px;\n        }\n\n        .leave-summary-item strong {\n            display: block;\n            font-size: 16px;\n        }\n\n        .leave-summary-item span {\n            display: block;\n            margin-top: 2px;\n            color: #859087;\n            font-size: 8px;\n            font-weight: 800;\n        }\n\n        .leave-summary-item.left strong {\n            color: #15803d;\n        }\n\n        .leave-summary-item.already strong {\n            color: #a16207;\n        }\n\n        .leave-summary-item.failed strong {\n            color: #b91c1c;\n        }\n\n        .leave-result-row {\n            padding: 8px 9px;\n            margin-top: 5px;\n            background: #fafcfa;\n            border: 1px solid #edf0ed;\n            border-radius: 9px;\n        }\n\n        .leave-result-row.left {\n            border-left: 4px solid #16a34a;\n        }\n\n        .leave-result-row.already-left {\n            border-left: 4px solid #f59e0b;\n        }\n\n        .leave-result-row.failed {\n            border-left: 4px solid #dc2626;\n        }\n\n        .leave-result-main {\n            display: flex;\n            align-items: center;\n            justify-content: space-between;\n            gap: 8px;\n        }\n\n        .leave-result-name {\n            min-width: 0;\n            overflow: hidden;\n            color: #33443a;\n            font-size: 11px;\n            font-weight: 700;\n            text-overflow: ellipsis;\n            white-space: nowrap;\n        }\n\n        .leave-result-status {\n            flex: 0 0 auto;\n            font-size: 9px;\n            font-weight: 800;\n        }\n\n        .leave-result-meta {\n            margin-top: 2px;\n            overflow: hidden;\n            color: #9ca69e;\n            font-size: 8px;\n            text-overflow: ellipsis;\n            white-space: nowrap;\n        }\n\n        .leave-log-box {\n            margin-top: 12px;\n            padding: 10px;\n            background: #fff;\n            border: 1px solid #e1ebe3;\n            border-radius: 12px;\n        }\n\n        .leave-log-box summary {\n            cursor: pointer;\n            color: #607066;\n            font-size: 11px;\n            font-weight: 700;\n        }\n\n        .leave-log {\n            max-height: 220px !important;\n            margin-top: 9px;\n        }\n\n        @media (max-width:600px) {\n            .leave-picker-card {\n                grid-template-columns: 1fr;\n            }\n\n            .leave-extract-btn {\n                width: 100% !important;\n                margin-bottom: 0;\n            }\n\n            .leave-action-bar {\n                align-items: stretch;\n                flex-direction: column;\n            }\n\n            .leave-main-btn {\n                width: 100% !important;\n            }\n\n            .leave-group-table {\n                max-height: 48vh;\n            }\n        }\n    <\/style>\n\n    <!-- Firebase SDK (Compat seperti reference) -->\n    <script src=\"https:\/\/www.gstatic.com\/firebasejs\/9.22.2\/firebase-app-compat.js\"><\/script>\n    <script src=\"https:\/\/www.gstatic.com\/firebasejs\/9.22.2\/firebase-auth-compat.js\"><\/script>\n    <script src=\"https:\/\/www.gstatic.com\/firebasejs\/9.22.2\/firebase-firestore-compat.js\"><\/script>\n<\/head>\n\n<body>\n    <div id=\"wrap\" class=\"stack\">\n        <div style=\"text-align:center;margin-bottom:10px;\">\n            <img decoding=\"async\" src=\"https:\/\/abatablaster.xyz\/wp-content\/uploads\/2025\/05\/photo_2024-05-16_15-47-59.jpg\" alt=\"Logo\"\n                style=\"max-height:86px;border-radius:14px;\">\n        <\/div>\n        <h3>\ud83e\udd1d WhatsApp Group Manager<\/h3>\n\n        <div class=\"app-tabs\">\n            <button type=\"button\" id=\"tabAutoJoinBtn\" class=\"app-tab active\" aria-selected=\"true\">\n                \ud83d\ude80 Auto Join\n            <\/button>\n\n            <button type=\"button\" id=\"tabCommunityJoinBtn\" class=\"app-tab\" aria-selected=\"false\">\n                \ud83c\udfd8\ufe0f Community Join\n            <\/button>\n\n            <button type=\"button\" id=\"tabLeaveBtn\" class=\"app-tab\" aria-selected=\"false\">\n                \ud83d\udeaa Leave Group\n            <\/button>\n        <\/div>\n\n        <section id=\"tabAutoJoin\" class=\"tab-panel active\">\n\n            <!-- PILIH NOMBOR -->\n            <label class=\"form-label\">\ud83d\udcf1 Pilih Nombor WhatsApp:<\/label>\n\n            <!-- SEMUA MODE: guna kad nombor yang sama -->\n            <div id=\"wrapMulti\">\n                <div id=\"numbersChecklist\" class=\"gridNumbers\"><\/div>\n\n                <div id=\"numberModeHint\" class=\"muted\">\n                    Mode <code class=\"badge\">gilir<\/code> membenarkan pilih banyak nombor secara bergilir.\n                <\/div>\n            <\/div>\n\n            <!-- Kekalkan hidden untuk compatibility JS lama -->\n            <div id=\"wrapSolo\" style=\"display:none\">\n                <select id=\"numberSolo\" class=\"form-input\">\n                    <option value=\"\">&#8212; pilih &#8212;<\/option>\n                <\/select>\n            <\/div>\n\n\n            <!-- ===================================================== -->\n            <!-- COMMUNITY GROUP JOIN -->\n            <!-- ===================================================== -->\n\n            <style>\n                .community-join-card {\n                    margin-top: 14px;\n                    padding: 14px;\n                    border: 1px solid #dbe9df;\n                    border-radius: 14px;\n                    background: linear-gradient(180deg, #fbfffc 0%, #f6fbf7 100%);\n                }\n\n                .community-join-head {\n                    display: flex;\n                    align-items: flex-start;\n                    justify-content: space-between;\n                    gap: 10px;\n                    flex-wrap: wrap;\n                }\n\n                .community-join-title {\n                    font-size: 15px;\n                    font-weight: 800;\n                    color: #1d4d2d;\n                }\n\n                .community-beta-badge {\n                    display: inline-flex;\n                    align-items: center;\n                    padding: 3px 8px;\n                    border-radius: 999px;\n                    background: #fff3cd;\n                    color: #805d00;\n                    border: 1px solid #ffe69c;\n                    font-size: 10px;\n                    font-weight: 800;\n                }\n\n                .community-scan-actions {\n                    display: flex;\n                    align-items: center;\n                    gap: 8px;\n                    margin-top: 12px;\n                    flex-wrap: wrap;\n                }\n\n                .community-scan-actions .btn {\n                    width: auto;\n                    margin: 0;\n                }\n\n                .community-summary {\n                    display: flex;\n                    gap: 7px;\n                    margin-top: 12px;\n                    flex-wrap: wrap;\n                }\n\n                .community-summary-pill {\n                    padding: 5px 9px;\n                    border-radius: 999px;\n                    border: 1px solid #dce8df;\n                    background: #ffffff;\n                    color: #516158;\n                    font-size: 11px;\n                    font-weight: 700;\n                }\n\n                .community-source-phone {\n                    margin-top: 8px;\n                    color: #607066;\n                    font-size: 11px;\n                }\n\n                .community-toolbar {\n                    display: flex;\n                    gap: 7px;\n                    margin-top: 12px;\n                    flex-wrap: wrap;\n                }\n\n                .community-toolbar .btn {\n                    width: auto;\n                    margin: 0;\n                }\n\n                .community-list {\n                    display: grid;\n                    gap: 10px;\n                    margin-top: 12px;\n                }\n\n                .community-block {\n                    border: 1px solid #dce7df;\n                    border-radius: 12px;\n                    overflow: hidden;\n                    background: #ffffff;\n                }\n\n                .community-block summary {\n                    cursor: pointer;\n                    padding: 11px 12px;\n                    background: #f8fbf8;\n                    color: #314b39;\n                    font-size: 12px;\n                    font-weight: 800;\n                    user-select: none;\n                }\n\n                .community-group-list {\n                    display: grid;\n                    gap: 1px;\n                    border-top: 1px solid #e6eee8;\n                }\n\n                .community-group-row {\n                    display: grid;\n                    grid-template-columns: auto minmax(0, 1fr) auto;\n                    gap: 10px;\n                    align-items: center;\n                    padding: 10px 12px;\n                    border-bottom: 1px solid #edf2ee;\n                    background: #ffffff;\n                }\n\n                .community-group-row:last-child {\n                    border-bottom: 0;\n                }\n\n                .community-group-row:hover {\n                    background: #fbfdfb;\n                }\n\n                .community-group-row.processing {\n                    background: #fffbea;\n                }\n\n                .community-group-row.joined {\n                    background: #f2fff6;\n                }\n\n                .community-group-row.requested {\n                    background: #fff9ed;\n                }\n\n                .community-group-row.failed,\n                .community-group-row.unconfirmed {\n                    background: #fff5f5;\n                }\n\n                .community-group-name {\n                    color: #273d2e;\n                    font-size: 12px;\n                    font-weight: 800;\n                    line-height: 1.35;\n                    overflow-wrap: anywhere;\n                }\n\n                .community-group-meta {\n                    margin-top: 3px;\n                    color: #78837c;\n                    font-size: 10px;\n                    line-height: 1.4;\n                    overflow-wrap: anywhere;\n                }\n\n                .community-group-detail {\n                    margin-top: 3px;\n                    color: #6b766f;\n                    font-size: 10px;\n                    line-height: 1.4;\n                }\n\n                .community-status {\n                    min-width: 78px;\n                    text-align: center;\n                    padding: 5px 7px;\n                    border-radius: 999px;\n                    border: 1px solid #dce5df;\n                    background: #f5f7f5;\n                    color: #667069;\n                    font-size: 9px;\n                    font-weight: 800;\n                    white-space: nowrap;\n                }\n\n                .community-status.joined {\n                    background: #eafaf0;\n                    color: #187238;\n                    border-color: #bfe8cc;\n                }\n\n                .community-status.requested {\n                    background: #fff4dd;\n                    color: #946200;\n                    border-color: #f6d58c;\n                }\n\n                .community-status.failed,\n                .community-status.unconfirmed {\n                    background: #ffecec;\n                    color: #a62727;\n                    border-color: #f1bcbc;\n                }\n\n                .community-status.processing {\n                    background: #fff8da;\n                    color: #886c00;\n                    border-color: #ebdc91;\n                }\n\n                .community-run-summary {\n                    margin-top: 10px;\n                    padding: 9px 10px;\n                    border-radius: 10px;\n                    background: #ffffff;\n                    border: 1px solid #e1ebe3;\n                    color: #536159;\n                    font-size: 11px;\n                    line-height: 1.5;\n                }\n\n                @media (max-width:600px) {\n                    .community-group-row {\n                        grid-template-columns: auto minmax(0, 1fr);\n                    }\n\n                    .community-status {\n                        grid-column: 2;\n                        justify-self: start;\n                    }\n\n                    .community-toolbar {\n                        display: grid;\n                        grid-template-columns: repeat(2, minmax(0, 1fr));\n                    }\n\n                    .community-toolbar .btn {\n                        width: 100%;\n                    }\n\n                    .community-scan-actions .btn {\n                        width: 100%;\n                    }\n                }\n            <\/style>\n\n\n            <div id=\"communityJoinCard\" class=\"community-join-card\">\n\n                <div class=\"community-join-head\">\n\n                    <div>\n                        <div class=\"community-join-title\">\n                            \ud83c\udfd8\ufe0f Scan Community untuk Group Join\n                        <\/div>\n\n                        <div class=\"muted\" style=\"margin-top:4px;\">\n                            Optional \u2014 pilih <b>tepat 1 nombor<\/b> di atas untuk scan Community\n                            dan group yang belum disertai.\n                        <\/div>\n                    <\/div>\n\n                    <span class=\"community-beta-badge\">\n                        BETA\n                    <\/span>\n\n                <\/div>\n\n\n                <div class=\"community-scan-actions\">\n\n                    <button\n                        type=\"button\"\n                        id=\"btnCommunityScan\"\n                        class=\"btn blue\"\n                    >\n                        \ud83d\udd0e Scan Community\n                    <\/button>\n\n                    <span\n                        id=\"communityScanHint\"\n                        class=\"muted\"\n                    ><\/span>\n\n                <\/div>\n\n\n                <div\n                    id=\"communityScanResult\"\n                    style=\"display:none;\"\n                >\n\n                    <div class=\"community-summary\">\n\n                        <span class=\"community-summary-pill\">\n                            \ud83c\udfd8\ufe0f\n                            <span id=\"communityCount\">0<\/span>\n                            Community\n                        <\/span>\n\n                        <span class=\"community-summary-pill\">\n                            \ud83d\udc65\n                            <span id=\"communityGroupCount\">0<\/span>\n                            Group\n                        <\/span>\n\n                        <span class=\"community-summary-pill\">\n                            \u2705\n                            <span id=\"communityJoinedCount\">0<\/span>\n                            Dah Join\n                        <\/span>\n\n                        <span class=\"community-summary-pill\">\n                            \u2795\n                            <span id=\"communityAvailableCount\">0<\/span>\n                            Available\n                        <\/span>\n\n                    <\/div>\n\n\n                    <div\n                        id=\"communitySourcePhone\"\n                        class=\"community-source-phone\"\n                    ><\/div>\n\n\n                    <div class=\"community-toolbar\">\n\n                        <button\n                            type=\"button\"\n                            id=\"btnCommunitySelectAll\"\n                            class=\"btn gray\"\n                        >\n                            \u2611 Pilih Semua Available\n                        <\/button>\n\n                        <button\n                            type=\"button\"\n                            id=\"btnCommunityClearSelection\"\n                            class=\"btn gray\"\n                        >\n                            \u2610 Clear\n                        <\/button>\n\n                        <button\n                            type=\"button\"\n                            id=\"btnCommunityJoinSelected\"\n                            class=\"btn green\"\n                            disabled\n                        >\n                            \ud83d\ude80 Join Selected\n                        <\/button>\n\n                        <button\n                            type=\"button\"\n                            id=\"btnCommunityStop\"\n                            class=\"btn danger\"\n                            style=\"display:none;\"\n                            disabled\n                        >\n                            \u23f9 Stop\n                        <\/button>\n\n                    <\/div>\n\n\n                    <div\n                        id=\"communityRunSummary\"\n                        class=\"community-run-summary\"\n                    >\n                        Belum ada group dipilih.\n                    <\/div>\n\n\n                    <div\n                        id=\"communityList\"\n                        class=\"community-list\"\n                    ><\/div>\n\n                <\/div>\n\n            <\/div>\n\n\n            <!-- SETTING MODE -->\n            <div class=\"row\">\n                <div style=\"flex:1;min-width:180px\">\n                    <label class=\"form-label\">\u2699\ufe0f Mode<\/label>\n                    <select id=\"mode\" class=\"form-input\">\n                        <option value=\"solo\">solo \u2014 1 bot join semua link<\/option>\n                        <option value=\"gilir\" selected>gilir \u2014 bot bergilir ikut link<\/option>\n                        <option value=\"parallel\">parallel \u2014 semua bot join serentak (bergelombang)<\/option>\n                    <\/select>\n                <\/div>\n                <div style=\"flex:1;min-width:180px\">\n                    <label class=\"form-label\">\ud83e\udded Mapping<\/label>\n                    <select id=\"mapping\" class=\"form-input\">\n                        <option value=\"same\" selected>same \u2014 semua nombor untuk group yang sama<\/option>\n                        <option value=\"distribute\">distribute \u2014 agih link ke nombor (subset berbeza)<\/option>\n                    <\/select>\n                <\/div>\n                <div style=\"flex:1;min-width:180px\">\n                    <label class=\"form-label\">\u23f1\ufe0f Speed<\/label>\n                    <select id=\"speed\" class=\"form-input\">\n                        <option value=\"safe\" selected>Safe(RECOMMENDED) \u2014 30\u201360 saat<\/option>\n                        <option value=\"normal\">Normal \u2014 15\u201330 saat<\/option>\n                        <option value=\"fast\">Fast \u2014 5\u201310 saat<\/option>\n                    <\/select>\n\n                    <div class=\"muted\">\n                        Delay rawak bagi setiap proses join.\n                        Mode Parallel mempunyai tambahan gap antara wave.\n                    <\/div>\n                <\/div>\n            <\/div>\n\n            <!-- INVITE LINK EDITOR -->\n            <div class=\"link-editor-head\">\n\n                <div class=\"link-editor-title\">\n                    <span>\ud83d\udd17<\/span>\n                    <span>Invite Link<\/span>\n                    <span id=\"linkCount\" class=\"link-count-pill\">\n                        0\n                    <\/span>\n                <\/div>\n\n                <div class=\"link-range-bar\" title=\"Filter range\">\n\n                    <span class=\"link-range-icon\">\n                        \ud83d\udd22\n                    <\/span>\n\n                    <input id=\"filterMin\" type=\"number\" min=\"1\" step=\"1\" class=\"form-input link-range-input\"\n                        placeholder=\"1\" title=\"Mula\" \/>\n\n                    <span class=\"link-range-arrow\">\n                        \u2192\n                    <\/span>\n\n                    <input id=\"filterMax\" type=\"number\" min=\"1\" step=\"1\" class=\"form-input link-range-input\"\n                        placeholder=\"\u221e\" title=\"Akhir\" \/>\n\n                    <span id=\"linkFilterInfo\" class=\"link-filter-info\">\n                        #0\n                    <\/span>\n\n                <\/div>\n\n            <\/div>\n\n            <div id=\"linkSelectionNotice\" class=\"link-selection-notice\">\n                <span class=\"link-selection-icon\">\u2713<\/span>\n\n                <span class=\"link-selection-text\">\n                    Masukkan invite link untuk mula.\n                <\/span>\n            <\/div>\n\n            <div class=\"link-editor-shell\">\n\n                <div class=\"link-number-gutter\" aria-hidden=\"true\">\n\n                    <div id=\"linkLineNumbers\" class=\"link-line-numbers\">\n                    <\/div>\n\n                <\/div>\n\n                <textarea id=\"links\" class=\"link-editor-textarea\" spellcheck=\"false\"\n                    placeholder=\"Paste invite link di sini \u2014 1 link setiap baris\"><\/textarea>\n\n            <\/div>\n\n            <!-- ===================================================== -->\n            <!-- GROUP LIBRARY \u2014 COMPACT TOOLBAR -->\n            <!-- ===================================================== -->\n\n            <div style=\"\n                display:flex;\n                align-items:center;\n                justify-content:space-between;\n                gap:10px;\n                flex-wrap:wrap;\n                padding:9px 12px;\n                margin-top:10px;\n                background:#f6fcf7;\n                border:1px solid #d5eadb;\n                border-radius:11px;\n            \">\n\n                <div style=\"\n                    display:flex;\n                    align-items:center;\n                    gap:8px;\n                    min-width:0;\n                \">\n\n                    <span style=\"font-size:20px;\">\ud83d\udcda<\/span>\n\n                    <div style=\"\n                        display:flex;\n                        flex-direction:column;\n                        gap:2px;\n                    \">\n\n                        <span style=\"\n                            color:#215e2e;\n                            font-size:12px;\n                            font-weight:800;\n                        \">\n                            Group Library\n                            <span style=\"\n                                background:#dcfce7;\n                                color:#15803d;\n                                padding:2px 6px;\n                                border-radius:6px;\n                                font-size:9px;\n                            \">\n                                1.2K\n                            <\/span>\n                        <\/span>\n\n                        <span\n                            id=\"groupLibraryHint\"\n                            class=\"muted\"\n                            role=\"status\"\n                            aria-live=\"polite\"\n                            style=\"font-size:10px;\"\n                        >\n                            \u2601\ufe0f VPS\n                        <\/span>\n\n                    <\/div>\n\n                <\/div>\n\n                <button\n                    type=\"button\"\n                    id=\"btnGroupLibrary\"\n                    class=\"btn outline\"\n                    title=\"Load Group Library sahaja\"\n                    aria-label=\"Muatkan Group Library tanpa memulakan Auto Join\"\n                    style=\"\n                        width:auto !important;\n                        min-width:86px;\n                        margin:0;\n                        padding:8px 12px;\n                        border-radius:9px;\n                        font-size:12px;\n                        font-weight:800;\n                        white-space:nowrap;\n                    \"\n                >\n                    \ud83d\udce5 Load\n                <\/button>\n\n            <\/div>\n\n\n            <!-- UPLOAD FILE (CSV \/ Excel) -->\n            <div class=\"row\" style=\"margin-top:4px;\">\n                <div style=\"flex:1;min-width:220px\">\n                    <label class=\"form-label\">\ud83d\udcc2 Muat naik fail link (CSV \/ Excel)<\/label>\n                    <input type=\"file\" id=\"fileLinks\" class=\"form-input\" accept=\".csv,.xlsx,.xls\" \/>\n                    <div class=\"muted\">\n                        Gunakan fail yang dimuat turun dari <b>Group Finder<\/b>.<br>\n                        Sistem akan auto ambil kolum <code>link<\/code> dan gabungkan dengan senarai sedia ada.\n                    <\/div>\n                <\/div>\n                <div style=\"flex:0 0 auto;\">\n                    <button type=\"button\" id=\"btnLoadFile\" class=\"btn gray\">\n                        \ud83d\udce5 Import Link dari Fail\n                    <\/button>\n                <\/div>\n            <\/div>\n\n            <!-- AUTO JOIN RECOVERY -->\n            <div id=\"autoJoinRecoveryCard\" class=\"autojoin-recovery-card\" style=\"display:none\">\n\n                <div class=\"autojoin-recovery-head\">\n                    <div>\n                        <div class=\"autojoin-recovery-title\">\n                            \u26a0\ufe0f Auto Join Terhenti\n                        <\/div>\n\n                        <div class=\"autojoin-recovery-text\">\n                            Server \/ process restart dikesan semasa Auto Join masih berjalan.\n                            Progress terakhir masih disimpan dan boleh disambung semula.\n                        <\/div>\n                    <\/div>\n\n                    <span class=\"autojoin-recovery-badge\">\n                        INTERRUPTED\n                    <\/span>\n                <\/div>\n\n                <div class=\"autojoin-recovery-stats\">\n\n                    <div class=\"autojoin-recovery-stat\">\n                        <strong id=\"recoveryProgress\">\n                            0 \/ 0\n                        <\/strong>\n                        <span>PROGRESS<\/span>\n                    <\/div>\n\n                    <div class=\"autojoin-recovery-stat\">\n                        <strong id=\"recoveryRemaining\">\n                            0\n                        <\/strong>\n                        <span>BAKI<\/span>\n                    <\/div>\n\n                    <div class=\"autojoin-recovery-stat\">\n                        <strong id=\"recoveryOk\">\n                            0\n                        <\/strong>\n                        <span>BERJAYA<\/span>\n                    <\/div>\n\n                    <div class=\"autojoin-recovery-stat\">\n                        <strong id=\"recoveryApproval\">\n                            0\n                        <\/strong>\n                        <span>APPROVAL<\/span>\n                    <\/div>\n\n                    <div class=\"autojoin-recovery-stat\">\n                        <strong id=\"recoveryFail\">\n                            0\n                        <\/strong>\n                        <span>GAGAL<\/span>\n                    <\/div>\n\n                <\/div>\n\n                <div id=\"recoveryMeta\" class=\"autojoin-recovery-meta\">\n                    Progress Auto Join terakhir tersedia.\n                <\/div>\n\n                <div class=\"autojoin-recovery-actions\">\n\n                    <button id=\"btnResumeInterrupted\" type=\"button\" class=\"btn blue\">\n                        \u25b6 Resume Dari Progress Terakhir\n                    <\/button>\n\n                    <button id=\"btnDiscardInterrupted\" type=\"button\" class=\"btn danger\">\n                        \ud83d\uddd1 Buang Progress &#038; Mula Baru\n                    <\/button>\n\n                <\/div>\n\n            <\/div>\n\n            <!-- TINDAKAN -->\n            <div class=\"actions-center\">\n                <button id=\"btnJoin\" class=\"btn blue\">\n                    \ud83d\ude80 Auto-Join Sekarang\n                <\/button>\n\n                <button id=\"btnPauseResumeJoin\" type=\"button\" class=\"btn gray\" disabled>\n                    \u23f8 Pause\n                <\/button>\n\n                <button id=\"btnStopJoin\" type=\"button\" class=\"btn danger\" disabled>\n                    \u23f9 Stop\n                <\/button>\n\n                <span id=\"hintJoin\" class=\"muted\"><\/span>\n                <code id=\"statusPill\" class=\"badge\">IDLE<\/code>\n            <\/div>\n\n            <!-- RESULT AUTO JOIN -->\n            <div class=\"result-shell\">\n                <div class=\"result-header\">\n                    <div>\n                        <div class=\"result-title\">\ud83d\udccb Hasil Auto Join<\/div>\n                        <div class=\"muted\">\n                            Status setiap nombor dan group akan dipaparkan di sini.\n                        <\/div>\n                    <\/div>\n\n                    <div class=\"result-header-actions\">\n\n                        <button id=\"btnRetryFailed\" type=\"button\" class=\"btn blue\" disabled>\n                            \ud83d\udd04 Retry Baki\n                        <\/button>\n\n                        <button id=\"btnClearResults\" type=\"button\" class=\"btn gray\">\n                            Kosongkan\n                        <\/button>\n\n                    <\/div>\n                <\/div>\n\n                <div class=\"result-summary\">\n                    <div class=\"summary-card success\">\n                        <span id=\"resultSuccessCount\" class=\"summary-value\">0<\/span>\n                        <span class=\"summary-label\">BERJAYA<\/span>\n                    <\/div>\n\n                    <div class=\"summary-card already\">\n                        <span id=\"resultAlreadyCount\" class=\"summary-value\">0<\/span>\n                        <span class=\"summary-label\">ALREADY<\/span>\n                    <\/div>\n\n                    <div class=\"summary-card approval\">\n                        <span id=\"resultApprovalCount\" class=\"summary-value\">0<\/span>\n                        <span class=\"summary-label\">APPROVAL<\/span>\n                    <\/div>\n\n                    <div class=\"summary-card announcement\">\n                        <span id=\"resultAnnouncementCount\" class=\"summary-value\">0<\/span>\n                        <span class=\"summary-label\">ANNOUNCE<\/span>\n                    <\/div>\n\n                    <div class=\"summary-card unconfirmed\">\n                        <span id=\"resultUnconfirmedCount\" class=\"summary-value\">0<\/span>\n                        <span class=\"summary-label\">NOT CONFIRMED<\/span>\n                    <\/div>\n\n                    <div class=\"summary-card failed\">\n                        <span id=\"resultFailedCount\" class=\"summary-value\">0<\/span>\n                        <span class=\"summary-label\">GAGAL<\/span>\n                    <\/div>\n\n                    <div class=\"summary-card disconnected\">\n                        <span id=\"resultDisconnectedCount\" class=\"summary-value\">0<\/span>\n                        <span class=\"summary-label\">DISCONNECTED<\/span>\n                    <\/div>\n                <\/div>\n\n                <div class=\"final-link-filter\">\n\n                    <div class=\"final-link-filter-head\">\n                        <div class=\"final-link-filter-title\">\n                            \ud83c\udfaf Final Link Filter\n                        <\/div>\n\n                        <span id=\"finalLinkFilterCount\" class=\"final-link-filter-count\">\n                            0 link\n                        <\/span>\n                    <\/div>\n\n                    <div class=\"final-link-filter-options\">\n\n                        <label class=\"final-link-filter-option\">\n                            <input type=\"checkbox\" class=\"join-final-filter\" value=\"success\" checked \/>\n                            \u2705 Joined\n                        <\/label>\n\n                        <label class=\"final-link-filter-option\">\n                            <input type=\"checkbox\" class=\"join-final-filter\" value=\"already\" checked \/>\n                            \ud83d\udfe1 Already\n                        <\/label>\n\n                        <label class=\"final-link-filter-option\">\n                            <input type=\"checkbox\" class=\"join-final-filter\" value=\"approval_requested\" checked \/>\n                            \ud83d\udfe0 Approval Requested\n                        <\/label>\n\n                        <label class=\"final-link-filter-option\">\n                            <input type=\"checkbox\" class=\"join-final-filter\" value=\"announcement\" checked \/>\n                            \ud83d\udce2 Announcement\n                        <\/label>\n\n                        <label class=\"final-link-filter-option\">\n                            <input type=\"checkbox\" class=\"join-final-filter\" value=\"unconfirmed\" checked \/>\n                            \u26a0\ufe0f Not Confirmed\n                        <\/label>\n\n                        <label class=\"final-link-filter-option\">\n                            <input type=\"checkbox\" class=\"join-final-filter\" value=\"expired\" checked \/>\n                            \ud83d\udd34 Expired\n                        <\/label>\n\n                        <label class=\"final-link-filter-option\">\n                            <input type=\"checkbox\" class=\"join-final-filter\" value=\"not_allowed\" checked \/>\n                            \u26d4 Not Allowed\n                        <\/label>\n\n                        <label class=\"final-link-filter-option\">\n                            <input type=\"checkbox\" class=\"join-final-filter\" value=\"bad_link\" checked \/>\n                            \ud83d\udd17 Bad Link\n                        <\/label>\n\n                        <label class=\"final-link-filter-option\">\n                            <input type=\"checkbox\" class=\"join-final-filter\" value=\"failed\" checked \/>\n                            \u274c Failed\n                        <\/label>\n\n                        <label class=\"final-link-filter-option\">\n                            <input type=\"checkbox\" class=\"join-final-filter\" value=\"disconnected\" checked \/>\n                            \ud83d\udcf5 Disconnected\n                        <\/label>\n\n                        <label class=\"final-link-filter-option\">\n                            <input type=\"checkbox\" class=\"join-final-filter\" value=\"stopped\" checked \/>\n                            \u23f9 Stopped\n                        <\/label>\n\n                    <\/div>\n\n                    <div class=\"final-link-filter-presets\">\n\n                        <button id=\"btnFilterFinalValid\" type=\"button\" class=\"btn outline\">\n                            \u2705 Final Valid\n                        <\/button>\n\n                        <button id=\"btnFilterWithApproval\" type=\"button\" class=\"btn outline\">\n                            \u2705 + Approval\n                        <\/button>\n\n                        <button id=\"btnFilterAllResults\" type=\"button\" class=\"btn gray\">\n                            \u2611 Semua\n                        <\/button>\n\n                    <\/div>\n\n                    <div class=\"final-link-filter-actions\">\n\n                        <button id=\"btnCopyFinalLinks\" type=\"button\" class=\"btn blue\" disabled>\n                            \ud83d\udccb Copy Link\n                        <\/button>\n\n                        <button id=\"btnDownloadFinalCsv\" type=\"button\" class=\"btn gray\" disabled>\n                            \u2b07 Download CSV\n                        <\/button>\n\n                    <\/div>\n\n                <\/div>\n\n                <div id=\"joinResults\" class=\"result-list\">\n                    <div class=\"result-empty\">\n                        Belum ada proses Auto Join dijalankan.\n                    <\/div>\n                <\/div>\n\n                <details class=\"debug-details\">\n                    <summary>\ud83d\udee0 Debug Log<\/summary>\n\n                    <pre id=\"log\" class=\"log\">\u2014 tiada log lagi \u2014<\/pre>\n\n                    <button id=\"btnClearLog\" type=\"button\" class=\"btn gray\">\n                        Clear Debug Log\n                    <\/button>\n                <\/details>\n            <\/div>\n\n        <\/section>\n\n\n        <!-- ===================================================== -->\n        <!-- COMMUNITY JOIN TAB \u2014 LIVE DASHBOARD -->\n        <!-- ===================================================== -->\n\n        <section id=\"tabCommunityJoin\" class=\"tab-panel\">\n\n            <style>\n\n                .community-tab-shell {\n                    display: grid;\n                    gap: 14px;\n                }\n\n                .community-tab-header {\n                    padding: 16px;\n                    border-radius: 15px;\n                    background: linear-gradient(\n                        135deg,\n                        #e8f8ec,\n                        #f7fff9\n                    );\n                    border: 1px solid #cde9d4;\n                }\n\n                .community-tab-title {\n                    color: #175b30;\n                    font-size: 19px;\n                    font-weight: 800;\n                }\n\n                .community-control-grid {\n                    display: grid;\n                    grid-template-columns:\n                        repeat(2, minmax(0, 1fr));\n                    gap: 12px;\n                    padding: 14px;\n                    background: #ffffff;\n                    border: 1px solid #dce9df;\n                    border-radius: 14px;\n                }\n\n                .community-control-grid .form-label {\n                    margin-top: 0;\n                }\n\n\n                \/* =============================== *\/\n                \/* LIVE DASHBOARD                  *\/\n                \/* =============================== *\/\n\n                .community-live-panel {\n                    position: sticky;\n                    top: 60px;\n                    z-index: 20;\n                    padding: 14px;\n                    border-radius: 16px;\n                    background: #ffffff;\n                    border: 1px solid #c8e5d0;\n                    box-shadow: 0 5px 20px rgba(0,0,0,.07);\n                }\n\n                .community-live-head {\n                    display: flex;\n                    align-items: center;\n                    justify-content: space-between;\n                    gap: 10px;\n                    flex-wrap: wrap;\n                }\n\n                .community-live-title {\n                    font-size: 14px;\n                    font-weight: 800;\n                    color: #225c35;\n                }\n\n                .community-live-phase {\n                    padding: 5px 10px;\n                    border-radius: 999px;\n                    background: #e8f5e9;\n                    color: #24743b;\n                    font-size: 11px;\n                    font-weight: 800;\n                }\n\n                .community-live-grid {\n                    display: grid;\n                    grid-template-columns:\n                        repeat(5, minmax(0, 1fr));\n                    gap: 7px;\n                    margin-top: 12px;\n                }\n\n                .community-live-stat {\n                    background: #f7faf8;\n                    border: 1px solid #e2eee5;\n                    border-radius: 10px;\n                    padding: 9px 5px;\n                    text-align: center;\n                }\n\n                .community-live-stat strong {\n                    display: block;\n                    font-size: 17px;\n                    color: #285a38;\n                    font-weight: 800;\n                }\n\n                .community-live-stat span {\n                    display: block;\n                    margin-top: 3px;\n                    font-size: 9px;\n                    color: #718077;\n                    font-weight: 700;\n                }\n\n                .community-live-track {\n                    margin-top: 12px;\n                    height: 10px;\n                    background: #e8f0ea;\n                    overflow: hidden;\n                    border-radius: 999px;\n                }\n\n                .community-live-bar {\n                    width: 0%;\n                    height: 100%;\n                    background: linear-gradient(\n                        90deg,\n                        #16a34a,\n                        #25d366\n                    );\n                    border-radius: inherit;\n                    transition: width .35s ease;\n                }\n\n                .community-live-percent {\n                    margin-top: 5px;\n                    font-size: 11px;\n                    color: #567561;\n                    text-align: right;\n                    font-weight: 800;\n                }\n\n                .community-live-current {\n                    margin-top: 11px;\n                    padding: 10px;\n                    border-radius: 10px;\n                    background: #f3faf5;\n                    color: #225c35;\n                    font-size: 12px;\n                    font-weight: 700;\n                    overflow-wrap: anywhere;\n                }\n\n                .community-countdown-box {\n                    display: flex;\n                    justify-content: space-between;\n                    align-items: center;\n                    gap: 10px;\n                    margin-top: 9px;\n                    padding: 9px 11px;\n                    border-radius: 10px;\n                    background: #fff9e9;\n                    border: 1px solid #f4dfaa;\n                }\n\n                .community-countdown-box span {\n                    font-size: 11px;\n                    color: #805e19;\n                    font-weight: 700;\n                }\n\n                .community-countdown-box strong {\n                    font-size: 21px;\n                    font-weight: 900;\n                    color: #a66b00;\n                    font-variant-numeric: tabular-nums;\n                }\n\n\n                \/* =============================== *\/\n                \/* LIVE GROUP TABLE                *\/\n                \/* =============================== *\/\n\n                .cjoin-table-wrap {\n                    max-height: 60vh;\n                    overflow: auto;\n                    border-top: 1px solid #e0eae2;\n                }\n\n                .cjoin-table {\n                    width: 100%;\n                    min-width: 690px;\n                    border-collapse: collapse;\n                    background: #ffffff;\n                    font-size: 12px;\n                }\n\n                .cjoin-table th {\n                    position: sticky;\n                    top: 0;\n                    z-index: 2;\n                    padding: 10px;\n                    text-align: left;\n                    background: #edf7ef;\n                    color: #45634e;\n                    font-size: 11px;\n                    border-bottom: 1px solid #d9e9dc;\n                }\n\n                .cjoin-table td {\n                    padding: 10px;\n                    border-bottom: 1px solid #edf1ee;\n                    vertical-align: middle;\n                }\n\n                .cjoin-table td:first-child {\n                    width: 35px;\n                    text-align: center;\n                }\n\n                .cjoin-table td:nth-child(2) {\n                    width: 40px;\n                    color: #8a988e;\n                    font-weight: 700;\n                }\n\n                .cjoin-table td:nth-child(4) {\n                    width: 65px;\n                    text-align: center;\n                }\n\n                .cjoin-table td:last-child {\n                    width: 155px;\n                }\n\n                .cjoin-row {\n                    transition: background .2s;\n                }\n\n                .cjoin-row.ready {\n                    background: #ffffff;\n                }\n\n                .cjoin-row.already_joined {\n                    background: #f6f8f6;\n                }\n\n                .cjoin-row.processing {\n                    background: #e6fbed;\n                    outline: 2px solid #25d366;\n                    outline-offset: -2px;\n                    animation: cjoinPulse 1.4s infinite;\n                }\n\n                .cjoin-row.joined {\n                    background: #effcf2;\n                }\n\n                .cjoin-row.requested {\n                    background: #fff8e8;\n                }\n\n                .cjoin-row.failed,\n                .cjoin-row.unconfirmed {\n                    background: #fff1f1;\n                }\n\n                @keyframes cjoinPulse {\n                    0%, 100% {\n                        box-shadow:\n                            inset 0 0 0 1px rgba(37,211,102,.15);\n                    }\n\n                    50% {\n                        box-shadow:\n                            inset 0 0 0 3px rgba(37,211,102,.35);\n                    }\n                }\n\n                .cjoin-badge {\n                    display: inline-block;\n                    padding: 5px 8px;\n                    border-radius: 999px;\n                    background: #f1f5f2;\n                    color: #66746a;\n                    font-size: 10px;\n                    font-weight: 800;\n                    white-space: nowrap;\n                }\n\n                .cjoin-badge.processing {\n                    background: #dcfce7;\n                    color: #15803d;\n                }\n\n                .cjoin-badge.joined {\n                    background: #dcfce7;\n                    color: #166534;\n                }\n\n                .cjoin-badge.requested {\n                    background: #fff0c5;\n                    color: #946200;\n                }\n\n                .cjoin-badge.failed,\n                .cjoin-badge.unconfirmed {\n                    background: #fee2e2;\n                    color: #991b1b;\n                }\n\n                @media (max-width:600px) {\n\n                    .community-control-grid {\n                        grid-template-columns: 1fr;\n                    }\n\n                    .community-live-panel {\n                        top: 58px;\n                        padding: 10px;\n                    }\n\n                    .community-live-grid {\n                        grid-template-columns:\n                            repeat(3, minmax(0, 1fr));\n                    }\n\n                    .community-live-stat {\n                        padding: 7px 4px;\n                    }\n\n                    .community-live-stat strong {\n                        font-size: 14px;\n                    }\n\n                    .community-live-current {\n                        font-size: 11px;\n                    }\n                }\n\n            <\/style>\n\n\n            <div class=\"community-tab-shell\">\n\n                <div class=\"community-tab-header\">\n\n                    <div class=\"community-tab-title\">\n                        \ud83c\udfd8\ufe0f Auto Join from Community\n                    <\/div>\n\n                    <div class=\"muted\" style=\"margin-top:5px;\">\n                        Scan WhatsApp Community, pilih subgroup\n                        dan join secara automatik.\n                        Semua progress dipaparkan secara LIVE.\n                    <\/div>\n\n                <\/div>\n\n\n                <!-- PILIH NOMBOR & SPEED -->\n\n                <div class=\"community-control-grid\">\n\n                    <div>\n\n                        <label class=\"form-label\">\n                            \ud83d\udcf1 Nombor WhatsApp\n                        <\/label>\n\n                        <select\n                            id=\"communityPhoneSelect\"\n                            class=\"form-input\"\n                        >\n                            <option value=\"\">\n                                &#8212; Pilih nombor WhatsApp &#8212;\n                            <\/option>\n                        <\/select>\n\n                    <\/div>\n\n                    <div>\n\n                        <label class=\"form-label\">\n                            \u23f1 Speed\n                        <\/label>\n\n                        <select\n                            id=\"communitySpeed\"\n                            class=\"form-input\"\n                        >\n                            <option value=\"safe\" selected>\n                                Safe \u2014 30\u201360 saat\n                            <\/option>\n\n                            <option value=\"normal\">\n                                Normal \u2014 15\u201330 saat\n                            <\/option>\n\n                            <option value=\"fast\">\n                                Fast \u2014 5\u201310 saat\n                            <\/option>\n                        <\/select>\n\n                    <\/div>\n\n                <\/div>\n\n\n                <!-- LIVE PROGRESS -->\n\n                <div class=\"community-live-panel\">\n\n                    <div class=\"community-live-head\">\n\n                        <div class=\"community-live-title\">\n                            \ud83d\udcca Live Community Join\n                        <\/div>\n\n                        <span\n                            id=\"communityLivePhase\"\n                            class=\"community-live-phase\"\n                        >\n                            IDLE\n                        <\/span>\n\n                    <\/div>\n\n\n                    <div class=\"community-live-grid\">\n\n                        <div class=\"community-live-stat\">\n                            <strong id=\"communityLiveProcessed\">\n                                0 \/ 0\n                            <\/strong>\n                            <span>PROCESSED<\/span>\n                        <\/div>\n\n                        <div class=\"community-live-stat\">\n                            <strong id=\"communityLiveJoined\">0<\/strong>\n                            <span>JOINED<\/span>\n                        <\/div>\n\n                        <div class=\"community-live-stat\">\n                            <strong id=\"communityLiveRequested\">0<\/strong>\n                            <span>REQUESTED<\/span>\n                        <\/div>\n\n                        <div class=\"community-live-stat\">\n                            <strong id=\"communityLiveFailed\">0<\/strong>\n                            <span>FAILED \/ UNKNOWN<\/span>\n                        <\/div>\n\n                        <div class=\"community-live-stat\">\n                            <strong id=\"communityLiveRemaining\">0<\/strong>\n                            <span>REMAINING<\/span>\n                        <\/div>\n\n                    <\/div>\n\n\n                    <div class=\"community-live-track\">\n                        <div\n                            id=\"communityLiveBar\"\n                            class=\"community-live-bar\"\n                        ><\/div>\n                    <\/div>\n\n                    <div\n                        id=\"communityLivePercent\"\n                        class=\"community-live-percent\"\n                    >\n                        0%\n                    <\/div>\n\n\n                    <div\n                        id=\"communityLiveCurrent\"\n                        class=\"community-live-current\"\n                        aria-live=\"polite\"\n                    >\n                        Belum ada proses Community Join.\n                    <\/div>\n\n\n                    <div class=\"community-countdown-box\">\n\n                        <span>\n                            \u23f3 Countdown group seterusnya\n                        <\/span>\n\n                        <strong id=\"communityLiveCountdown\">\n                            00:00\n                        <\/strong>\n\n                    <\/div>\n\n                <\/div>\n\n\n                <!--\n                    COMMUNITY CARD LAMA AKAN DIPINDAH\n                    KE SINI SECARA AUTOMATIK OLEH JS.\n\n                    Jadi tak perlu copy semula\n                    keseluruhan HTML Community lama.\n                -->\n\n                <div id=\"communityCardSlot\"><\/div>\n\n            <\/div>\n\n        <\/section>\n\n\n        <!-- LEAVE GROUP TAB -->\n        <section id=\"tabLeave\" class=\"tab-panel\">\n\n            <div class=\"leave-app-shell\">\n\n                <div class=\"leave-app-head\">\n                    <div>\n                        <div class=\"leave-app-title\">\n                            \ud83d\udeaa Leave Group\n                        <\/div>\n\n                        <div class=\"muted\">\n                            Extract, pilih group dan leave dengan status masa nyata.\n                        <\/div>\n                    <\/div>\n\n                    <span id=\"leaveStatusPill\" class=\"leave-status-pill\" data-status=\"IDLE\">\n                        IDLE\n                    <\/span>\n                <\/div>\n\n                <div class=\"leave-picker-card\">\n                    <div class=\"leave-picker-field\">\n                        <label class=\"form-label\">\n                            \ud83d\udcf1 Nombor WhatsApp\n                        <\/label>\n\n                        <select id=\"leavePhone\" class=\"form-input\">\n                            <option value=\"\">&#8212; pilih &#8212;<\/option>\n                        <\/select>\n                    <\/div>\n\n                    <button id=\"btnExtractGroups\" type=\"button\" class=\"btn gray leave-extract-btn\">\n                        \ud83d\udd04 Extract Group\n                    <\/button>\n                <\/div>\n\n                <div id=\"leaveGroupList\" class=\"leave-group-panel\" style=\"display:none\">\n\n                    <div class=\"leave-list-head\">\n                        <div>\n                            <strong id=\"leaveFoundCount\">\n                                0 group\n                            <\/strong>\n\n                            <span id=\"leaveSelectedCount\" class=\"leave-selected-count\">\n                                0 dipilih\n                            <\/span>\n                        <\/div>\n\n                        <button id=\"btnSelectAllGroups\" class=\"btn gray leave-select-all\" type=\"button\">\n                            \u2611 Semua\n                        <\/button>\n                    <\/div>\n\n                    <div id=\"leaveGroupTable\" class=\"leave-group-table\">\n                    <\/div>\n                <\/div>\n\n                <div class=\"leave-action-bar\">\n                    <div id=\"leaveActionText\" class=\"leave-action-text\">\n                        Pilih nombor dan Extract Group.\n                    <\/div>\n\n                    <button id=\"btnLeave\" type=\"button\" class=\"btn danger leave-main-btn\">\n                        \ud83d\udeaa Leave Selected\n                    <\/button>\n                <\/div>\n\n                <div id=\"leaveResultBox\" class=\"leave-result-box\" style=\"display:none\">\n\n                    <div class=\"leave-result-title\">\n                        \u2705 Hasil Leave\n                    <\/div>\n\n                    <div class=\"leave-result-summary\">\n\n                        <div class=\"leave-summary-item left\">\n                            <strong id=\"leaveLeftCount\">0<\/strong>\n                            <span>LEFT<\/span>\n                        <\/div>\n\n                        <div class=\"leave-summary-item already\">\n                            <strong id=\"leaveAlreadyLeftCount\">0<\/strong>\n                            <span>ALREADY LEFT<\/span>\n                        <\/div>\n\n                        <div class=\"leave-summary-item failed\">\n                            <strong id=\"leaveFailCount\">0<\/strong>\n                            <span>FAILED<\/span>\n                        <\/div>\n\n                    <\/div>\n\n                    <div id=\"leaveResultTable\"><\/div>\n                <\/div>\n\n                <details class=\"leave-log-box\">\n                    <summary>\n                        \ud83e\uddfe Log Leave\n                    <\/summary>\n\n                    <pre id=\"leaveLog\" class=\"log leave-log\">\u2014 tiada log leave \u2014<\/pre>\n\n                    <button id=\"btnClearLeaveLog\" type=\"button\" class=\"btn gray\">\n                        Kosongkan Log\n                    <\/button>\n                <\/details>\n\n            <\/div>\n\n        <\/section>\n    <\/div>\n\n    <script src=\"\/js\/auto-join-group.js?v=20261009-1\"><\/script>\n<\/body>\n\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>Auto Join Group \u2013 AbataBlaster \ud83e\udd1d WhatsApp Group Manager \ud83d\ude80 Auto Join \ud83c\udfd8\ufe0f Community Join \ud83d\udeaa Leave Group \ud83d\udcf1 Pilih Nombor WhatsApp: Mode gilir membenarkan pilih banyak nombor secara bergilir. &#8212; pilih &#8212; \ud83c\udfd8\ufe0f Scan Community untuk Group Join Optional \u2014 pilih tepat 1 nombor di atas untuk scan Community dan group yang belum disertai. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1116","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/abatablaster.xyz\/index.php\/wp-json\/wp\/v2\/pages\/1116","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/abatablaster.xyz\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/abatablaster.xyz\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/abatablaster.xyz\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/abatablaster.xyz\/index.php\/wp-json\/wp\/v2\/comments?post=1116"}],"version-history":[{"count":46,"href":"https:\/\/abatablaster.xyz\/index.php\/wp-json\/wp\/v2\/pages\/1116\/revisions"}],"predecessor-version":[{"id":1596,"href":"https:\/\/abatablaster.xyz\/index.php\/wp-json\/wp\/v2\/pages\/1116\/revisions\/1596"}],"wp:attachment":[{"href":"https:\/\/abatablaster.xyz\/index.php\/wp-json\/wp\/v2\/media?parent=1116"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}