
{"id":19916,"date":"2025-08-01T17:08:11","date_gmt":"2025-08-01T17:08:11","guid":{"rendered":"https:\/\/seoteampro.com\/?page_id=19916"},"modified":"2025-08-05T06:17:16","modified_gmt":"2025-08-05T06:17:16","slug":"bulk-url-opener","status":"publish","type":"page","link":"https:\/\/seoteampro.com\/?page_id=19916","title":{"rendered":"Bulk URL Opener"},"content":{"rendered":"    \r\n    <div id=\"bulk-url-opener-container\" class=\"bulk-url-opener-wrapper\">\r\n        <div class=\"bulk-url-opener-container\">\r\n            <h1 class=\"bulk-url-opener-title\">\ud83d\ude80 Bulk URL Opener<\/h1>\r\n            <p class=\"bulk-url-opener-subtitle\">Open multiple URLs automatically with smart popup handling<\/p>\r\n            \r\n            <div class=\"bulk-url-opener-input-section\">\r\n                <label class=\"bulk-url-opener-label\" for=\"bulk-url-opener-input\">Paste URLs Here: *<\/label>\r\n                <textarea id=\"bulk-url-opener-input\" class=\"bulk-url-opener-textarea\" placeholder=\"Enter URLs here, one per line:\r\n\r\nhttps:\/\/www.google.com\r\nhttps:\/\/www.youtube.com\r\nhttps:\/\/www.github.com\r\nhttps:\/\/www.stackoverflow.com\r\nhttps:\/\/www.wikipedia.org\"><\/textarea>\r\n                <div class=\"bulk-url-opener-counter\"><span id=\"bulk-url-opener-count\">0<\/span> URLs<\/div>\r\n            <\/div>\r\n            \r\n            <div class=\"bulk-url-opener-modifier-section\">\r\n                <label class=\"bulk-url-opener-label\" for=\"bulk-url-opener-prefix\">Add Before URLs: <span class=\"bulk-url-opener-optional\">(Optional)<\/span><\/label>\r\n                <input type=\"text\" id=\"bulk-url-opener-prefix\" class=\"bulk-url-opener-modifier-input\" placeholder=\"e.g., https:\/\/www.google.com\/search?q=site:\" \/>\r\n            <\/div>\r\n            \r\n            <div class=\"bulk-url-opener-modifier-section\">\r\n                <label class=\"bulk-url-opener-label\" for=\"bulk-url-opener-suffix\">Add After URLs: <span class=\"bulk-url-opener-optional\">(Optional)<\/span><\/label>\r\n                <input type=\"text\" id=\"bulk-url-opener-suffix\" class=\"bulk-url-opener-modifier-input\" placeholder=\"e.g., ?preview=true\" \/>\r\n            <\/div>\r\n            \r\n            <div class=\"bulk-url-opener-settings-row\">\r\n                <div class=\"bulk-url-opener-delay-section\">\r\n                    <label class=\"bulk-url-opener-delay-label\" for=\"bulk-url-opener-delay\">DELAY BETWEEN OPENING LINKS<\/label>\r\n                    <div class=\"bulk-url-opener-delay-wrapper\">\r\n                        <input type=\"number\" id=\"bulk-url-opener-delay\" class=\"bulk-url-opener-delay-input\" min=\"0\" max=\"20\" placeholder=\"In Seconds\" value=\"0\" \/>\r\n                    <\/div>\r\n                <\/div>\r\n                \r\n                <div class=\"bulk-url-opener-tab-section\">\r\n                    <label class=\"bulk-url-opener-tab-label\" for=\"bulk-url-opener-tab-options\">TAB VS WINDOW<\/label>\r\n                    <select id=\"bulk-url-opener-tab-options\" class=\"bulk-url-opener-select\">\r\n                        <option value=\"unique-tabs\" selected>All URL + Unique Tabs<\/option>\r\n                        <option value=\"same-tab\">All URL + Same Tab<\/option>\r\n                        <option value=\"unique-windows\">All URL + Unique Windows<\/option>\r\n                        <option value=\"same-window\">All URL + Same Window<\/option>\r\n                    <\/select>\r\n                <\/div>\r\n            <\/div>\r\n            \r\n            <div class=\"bulk-url-opener-action-buttons\">\r\n                <button id=\"bulk-url-opener-open-btn\" class=\"bulk-url-opener-action-btn bulk-url-opener-primary\">\ud83d\ude80 Bulk Open URLs<\/button>\r\n                <button id=\"bulk-url-opener-reset-btn\" class=\"bulk-url-opener-action-btn bulk-url-opener-secondary\">\ud83d\udd04 Reset<\/button>\r\n            <\/div>\r\n            \r\n            <div class=\"bulk-url-opener-util-buttons\">\r\n                <button id=\"bulk-url-opener-paste-btn\" class=\"bulk-url-opener-util-btn\">\ud83d\udccb Paste<\/button>\r\n                <button id=\"bulk-url-opener-copy-btn\" class=\"bulk-url-opener-util-btn\">\ud83d\udcc4 Copy<\/button>\r\n                <button id=\"bulk-url-opener-extract-btn\" class=\"bulk-url-opener-util-btn\">\ud83d\udd0d Extract URLs<\/button>\r\n                <button id=\"bulk-url-opener-clear-btn\" class=\"bulk-url-opener-util-btn\">\ud83d\uddd1\ufe0f Clear<\/button>\r\n            <\/div>\r\n            \r\n            <div id=\"bulk-url-opener-progress-container\" class=\"bulk-url-opener-progress-section\">\r\n                <div class=\"bulk-url-opener-progress-bar\">\r\n                    <div id=\"bulk-url-opener-progress-fill\" class=\"bulk-url-opener-progress-fill\"><\/div>\r\n                <\/div>\r\n                <div class=\"bulk-url-opener-progress-text\">\r\n                    Opening <span id=\"bulk-url-opener-progress-current\">0<\/span> of <span id=\"bulk-url-opener-progress-total\">0<\/span>\r\n                <\/div>\r\n            <\/div>\r\n            \r\n            <div id=\"bulk-url-opener-status\" class=\"bulk-url-opener-status\"><\/div>\r\n        <\/div>\r\n    <\/div>\r\n    \r\n    <style>\r\n    \/* WordPress-compatible styles with brand colors - Override any theme styles *\/\r\n    #bulk-url-opener-container {\r\n        max-width: 100% !important;\r\n        margin: 20px auto !important;\r\n        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-container {\r\n        max-width: 800px !important;\r\n        margin: 0 auto !important;\r\n        background: white !important;\r\n        padding: 30px !important;\r\n        border-radius: 10px !important;\r\n        box-shadow: 0 2px 10px rgba(0,0,0,0.1) !important;\r\n        position: relative !important;\r\n        z-index: 1 !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-title {\r\n        text-align: center !important;\r\n        color: #333 !important;\r\n        margin-top: 0 !important;\r\n        font-size: 28px !important;\r\n        font-weight: 700 !important;\r\n        margin-bottom: 10px !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-subtitle {\r\n        text-align: center !important;\r\n        color: #7f8c8d !important;\r\n        margin-bottom: 30px !important;\r\n        font-size: 16px !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-input-section {\r\n        margin-bottom: 25px !important;\r\n        position: relative !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-label {\r\n        display: block !important;\r\n        margin-bottom: 8px !important;\r\n        font-weight: 600 !important;\r\n        color: #2c3e50 !important;\r\n        font-size: 14px !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-textarea {\r\n        width: 100% !important;\r\n        height: 200px !important;\r\n        padding: 15px !important;\r\n        padding-bottom: 35px !important;\r\n        border: 2px solid #e1e8ed !important;\r\n        border-radius: 8px !important;\r\n        font-family: 'Consolas', 'Monaco', 'Courier New', monospace !important;\r\n        font-size: 14px !important;\r\n        line-height: 1.6 !important;\r\n        resize: vertical !important;\r\n        box-sizing: border-box !important;\r\n        background: #f8f9fa !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-textarea:focus {\r\n        outline: none !important;\r\n        border-color: #5D39B7 !important;\r\n        background: #ffffff !important;\r\n        box-shadow: 0 0 0 3px rgba(93, 57, 183, 0.1) !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-counter {\r\n        position: absolute !important;\r\n        bottom: 10px !important;\r\n        right: 15px !important;\r\n        background: #e1e8ed !important;\r\n        padding: 6px 14px !important;\r\n        border-radius: 20px !important;\r\n        font-size: 13px !important;\r\n        color: #5a6c7d !important;\r\n        font-weight: 500 !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-modifier-section {\r\n        margin-bottom: 20px !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-modifier-input {\r\n        width: 100% !important;\r\n        padding: 12px 15px !important;\r\n        border: 2px solid #e1e8ed !important;\r\n        border-radius: 8px !important;\r\n        font-size: 14px !important;\r\n        background: #f8f9fa !important;\r\n        box-sizing: border-box !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-modifier-input:focus {\r\n        outline: none !important;\r\n        border-color: #5D39B7 !important;\r\n        background: #ffffff !important;\r\n        box-shadow: 0 0 0 3px rgba(93, 57, 183, 0.1) !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-optional {\r\n        color: #95a5a6 !important;\r\n        font-weight: normal !important;\r\n        font-size: 13px !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-settings-row {\r\n        display: grid !important;\r\n        grid-template-columns: 1fr 1fr !important;\r\n        gap: 30px !important;\r\n        margin-bottom: 25px !important;\r\n    }\r\n    \r\n    \/* NEW STYLES - Matching the HTML file UI *\/\r\n    #bulk-url-opener-container .bulk-url-opener-delay-section label,\r\n    #bulk-url-opener-container .bulk-url-opener-tab-section label {\r\n        font-size: 12px !important;\r\n        text-transform: uppercase !important;\r\n        color: #7f8c8d !important;\r\n        letter-spacing: 0.5px !important;\r\n        margin-bottom: 10px !important;\r\n        font-weight: 700 !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-delay-label,\r\n    #bulk-url-opener-container .bulk-url-opener-tab-label {\r\n        font-size: 12px !important;\r\n        text-transform: uppercase !important;\r\n        color: #7f8c8d !important;\r\n        letter-spacing: 0.5px !important;\r\n        margin-bottom: 10px !important;\r\n        font-weight: 700 !important;\r\n        display: block !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-delay-wrapper {\r\n        position: relative !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-delay-input {\r\n        width: 100% !important;\r\n        padding: 12px 15px !important;\r\n        border: 2px solid #e1e8ed !important;\r\n        border-radius: 8px !important;\r\n        font-size: 14px !important;\r\n        background: #f8f9fa !important;\r\n        box-sizing: border-box !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-delay-input:focus {\r\n        outline: none !important;\r\n        border-color: #5D39B7 !important;\r\n        background: #ffffff !important;\r\n        box-shadow: 0 0 0 3px rgba(93, 57, 183, 0.1) !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-select {\r\n        width: 100% !important;\r\n        padding: 12px 15px !important;\r\n        border: 2px solid #5D39B7 !important;\r\n        border-radius: 8px !important;\r\n        font-size: 14px !important;\r\n        background: #ffffff !important;\r\n        cursor: pointer !important;\r\n        appearance: none !important;\r\n        -webkit-appearance: none !important;\r\n        -moz-appearance: none !important;\r\n        color: #2c3e50 !important;\r\n        font-weight: 500 !important;\r\n        box-sizing: border-box !important;\r\n        background-image: url(\"data:image\/svg+xml;charset=UTF-8,%3csvg xmlns='http:\/\/www.w3.org\/2000\/svg' viewBox='0 0 24 24' fill='none' stroke='%235D39B7' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c\/polyline%3e%3c\/svg%3e\") !important;\r\n        background-repeat: no-repeat !important;\r\n        background-position: right 12px center !important;\r\n        background-size: 20px !important;\r\n        padding-right: 40px !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-select:focus {\r\n        outline: none !important;\r\n        border-color: #4a2d94 !important;\r\n        box-shadow: 0 0 0 3px rgba(93, 57, 183, 0.1) !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-action-buttons {\r\n        display: grid !important;\r\n        grid-template-columns: 1fr 1fr !important;\r\n        gap: 20px !important;\r\n        margin-bottom: 20px !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-action-btn {\r\n        padding: 15px 30px !important;\r\n        border: none !important;\r\n        border-radius: 8px !important;\r\n        font-size: 16px !important;\r\n        font-weight: 600 !important;\r\n        cursor: pointer !important;\r\n        transition: all 0.3s ease !important;\r\n        display: flex !important;\r\n        align-items: center !important;\r\n        justify-content: center !important;\r\n        gap: 8px !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-primary {\r\n        background: #4285f4 !important;\r\n        color: white !important;\r\n        box-shadow: 0 2px 4px rgba(66, 133, 244, 0.2) !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-primary:hover {\r\n        background: #3367d6 !important;\r\n        transform: translateY(-1px) !important;\r\n        box-shadow: 0 4px 8px rgba(66, 133, 244, 0.3) !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-secondary {\r\n        background: #fbbc04 !important;\r\n        color: #1f2937 !important;\r\n        box-shadow: 0 2px 4px rgba(251, 188, 4, 0.2) !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-secondary:hover {\r\n        background: #f9ab00 !important;\r\n        transform: translateY(-1px) !important;\r\n        box-shadow: 0 4px 8px rgba(251, 188, 4, 0.3) !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-util-buttons {\r\n        display: flex !important;\r\n        flex-wrap: wrap !important;\r\n        justify-content: center !important;\r\n        gap: 10px !important;\r\n        margin-top: 10px !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-util-btn {\r\n        padding: 8px 15px !important;\r\n        border: 1px solid #e1e8ed !important;\r\n        border-radius: 6px !important;\r\n        font-size: 14px !important;\r\n        background: #f1f1f1 !important;\r\n        color: #333 !important;\r\n        cursor: pointer !important;\r\n        transition: all 0.2s ease !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-util-btn:hover {\r\n        background: #e5e5e5 !important;\r\n        transform: translateY(-1px) !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-progress-section {\r\n        margin: 20px 0 !important;\r\n        display: none !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-progress-bar {\r\n        width: 100% !important;\r\n        height: 20px !important;\r\n        background: #e1e8ed !important;\r\n        border-radius: 10px !important;\r\n        overflow: hidden !important;\r\n        position: relative !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-progress-fill {\r\n        height: 100% !important;\r\n        background: linear-gradient(90deg, #5D39B7 0%, #FF8D6A 100%) !important;\r\n        border-radius: 10px !important;\r\n        transition: width 0.3s ease !important;\r\n        width: 0% !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-progress-text {\r\n        text-align: center !important;\r\n        margin-top: 10px !important;\r\n        font-size: 14px !important;\r\n        color: #7f8c8d !important;\r\n        font-weight: 500 !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-status {\r\n        margin-top: 20px !important;\r\n        padding: 15px !important;\r\n        border-radius: 8px !important;\r\n        text-align: center !important;\r\n        display: none !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-status.success {\r\n        background: #d4edda !important;\r\n        color: #155724 !important;\r\n        border: 1px solid #c3e6cb !important;\r\n        display: block !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-status.error {\r\n        background: #f8d7da !important;\r\n        color: #721c24 !important;\r\n        border: 1px solid #f5c6cb !important;\r\n        display: block !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-status.warning {\r\n        background: #fff3cd !important;\r\n        color: #856404 !important;\r\n        border: 1px solid #ffeeba !important;\r\n        display: block !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-status.info {\r\n        background: #d1ecf1 !important;\r\n        color: #0c5460 !important;\r\n        border: 1px solid #bee5eb !important;\r\n        display: block !important;\r\n    }\r\n    \r\n    \/* Mobile responsive *\/\r\n    @media (max-width: 768px) {\r\n        #bulk-url-opener-container .bulk-url-opener-container {\r\n            padding: 20px !important;\r\n            margin: 10px !important;\r\n        }\r\n        \r\n        #bulk-url-opener-container .bulk-url-opener-title {\r\n            font-size: 24px !important;\r\n        }\r\n        \r\n        #bulk-url-opener-container .bulk-url-opener-settings-row {\r\n            grid-template-columns: 1fr !important;\r\n            gap: 20px !important;\r\n        }\r\n        \r\n        #bulk-url-opener-container .bulk-url-opener-action-buttons {\r\n            grid-template-columns: 1fr !important;\r\n        }\r\n    }\r\n    \r\n    \/* Remove spinner arrows *\/\r\n    #bulk-url-opener-container .bulk-url-opener-delay-input::-webkit-outer-spin-button,\r\n    #bulk-url-opener-container .bulk-url-opener-delay-input::-webkit-inner-spin-button {\r\n        -webkit-appearance: none !important;\r\n        margin: 0 !important;\r\n    }\r\n    \r\n    #bulk-url-opener-container .bulk-url-opener-delay-input[type=number] {\r\n        -moz-appearance: textfield !important;\r\n    }\r\n    <\/style>\r\n    \r\n    <script>\r\n    document.addEventListener('DOMContentLoaded', function() {\r\n        \/\/ Bulk URL Opener Tool\r\n        const BulkOpener = {\r\n            isProcessing: false,\r\n            shouldCancel: false,\r\n            windowRefs: [],\r\n            currentWindow: null,\r\n            elements: {},\r\n            openedCount: 0,\r\n            blockedCount: 0,\r\n            popupBlocked: false,\r\n            \r\n            init: function() {\r\n                this.setup();\r\n            },\r\n            \r\n            setup: function() {\r\n                \/\/ Get elements\r\n                this.elements = {\r\n                    urlsTextarea: document.getElementById('bulk-url-opener-input'),\r\n                    urlCount: document.getElementById('bulk-url-opener-count'),\r\n                    prefixInput: document.getElementById('bulk-url-opener-prefix'),\r\n                    suffixInput: document.getElementById('bulk-url-opener-suffix'),\r\n                    delayInput: document.getElementById('bulk-url-opener-delay'),\r\n                    tabOptions: document.getElementById('bulk-url-opener-tab-options'),\r\n                    openBtn: document.getElementById('bulk-url-opener-open-btn'),\r\n                    resetBtn: document.getElementById('bulk-url-opener-reset-btn'),\r\n                    pasteBtn: document.getElementById('bulk-url-opener-paste-btn'),\r\n                    copyBtn: document.getElementById('bulk-url-opener-copy-btn'),\r\n                    extractBtn: document.getElementById('bulk-url-opener-extract-btn'),\r\n                    clearBtn: document.getElementById('bulk-url-opener-clear-btn'),\r\n                    statusDiv: document.getElementById('bulk-url-opener-status'),\r\n                    progressContainer: document.getElementById('bulk-url-opener-progress-container'),\r\n                    progressFill: document.getElementById('bulk-url-opener-progress-fill'),\r\n                    progressCurrent: document.getElementById('bulk-url-opener-progress-current'),\r\n                    progressTotal: document.getElementById('bulk-url-opener-progress-total')\r\n                };\r\n                \r\n                \/\/ Setup events\r\n                this.setupEvents();\r\n                this.updateUrlCounter();\r\n                \r\n                \/\/ Load sample URLs\r\n                this.loadSampleUrls();\r\n            },\r\n            \r\n            setupEvents: function() {\r\n                const self = this;\r\n                \r\n                \/\/ Main buttons\r\n                this.elements.openBtn.addEventListener('click', function(e) {\r\n                    e.preventDefault();\r\n                    self.handleOpenUrls();\r\n                });\r\n                \r\n                this.elements.resetBtn.addEventListener('click', function(e) {\r\n                    e.preventDefault();\r\n                    self.resetAll();\r\n                });\r\n                \r\n                \/\/ Utility buttons\r\n                this.elements.pasteBtn.addEventListener('click', function(e) {\r\n                    e.preventDefault();\r\n                    self.pasteFromClipboard();\r\n                });\r\n                \r\n                this.elements.copyBtn.addEventListener('click', function(e) {\r\n                    e.preventDefault();\r\n                    self.copyToClipboard();\r\n                });\r\n                \r\n                this.elements.extractBtn.addEventListener('click', function(e) {\r\n                    e.preventDefault();\r\n                    self.extractUrls();\r\n                });\r\n                \r\n                this.elements.clearBtn.addEventListener('click', function(e) {\r\n                    e.preventDefault();\r\n                    self.clearUrls();\r\n                });\r\n                \r\n                \/\/ Input events\r\n                this.elements.urlsTextarea.addEventListener('input', function() {\r\n                    self.updateUrlCounter();\r\n                });\r\n                \r\n                this.elements.urlsTextarea.addEventListener('paste', function() {\r\n                    setTimeout(function() { self.updateUrlCounter(); }, 10);\r\n                });\r\n                \r\n                \/\/ Make delay input clear on focus\r\n                this.elements.delayInput.addEventListener('focus', function() {\r\n                    if (this.value === '0') {\r\n                        this.value = '';\r\n                    }\r\n                });\r\n                \r\n                this.elements.delayInput.addEventListener('blur', function() {\r\n                    if (this.value === '') {\r\n                        this.value = '0';\r\n                    }\r\n                });\r\n                \r\n                \/\/ Add keyboard shortcut for opening URLs (Ctrl+Enter)\r\n                this.elements.urlsTextarea.addEventListener('keydown', function(e) {\r\n                    if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {\r\n                        e.preventDefault();\r\n                        self.handleOpenUrls();\r\n                    }\r\n                });\r\n            },\r\n            \r\n            detectPopupBlocking: function() {\r\n                try {\r\n                    const testWindow = window.open('', '_blank');\r\n                    if (testWindow) {\r\n                        testWindow.close();\r\n                        this.popupBlocked = false;\r\n                    } else {\r\n                        this.popupBlocked = true;\r\n                    }\r\n                } catch (e) {\r\n                    this.popupBlocked = true;\r\n                }\r\n            },\r\n            \r\n            loadSampleUrls: function() {\r\n                const sampleUrls = [\r\n                    'https:\/\/www.google.com',\r\n                    'https:\/\/www.facebook.com',\r\n                    'https:\/\/www.youtube.com',\r\n                    'https:\/\/www.instagram.com',\r\n                    'https:\/\/www.twitter.com'\r\n                ];\r\n                this.elements.urlsTextarea.value = sampleUrls.join('\\n');\r\n                this.updateUrlCounter();\r\n            },\r\n            \r\n            getUrls: function() {\r\n                const text = this.elements.urlsTextarea.value.trim();\r\n                if (!text) return [];\r\n                \r\n                return text.split('\\n')\r\n                    .map(function(url) { return url.trim(); })\r\n                    .filter(function(url) { return url.length > 0; });\r\n            },\r\n            \r\n            updateUrlCounter: function() {\r\n                const count = this.getUrls().length;\r\n                this.elements.urlCount.textContent = count;\r\n            },\r\n            \r\n            processUrl: function(url, prefix, suffix) {\r\n                let processed = url.trim();\r\n                \r\n                \/\/ Add protocol if missing\r\n                if (!processed.match(\/^[a-zA-Z][a-zA-Z0-9+.-]*:\\\/\\\/\/)) {\r\n                    processed = 'https:\/\/' + processed;\r\n                }\r\n                \r\n                \/\/ Add prefix\/suffix\r\n                if (prefix) processed = prefix + processed;\r\n                if (suffix) processed = processed + suffix;\r\n                \r\n                return processed;\r\n            },\r\n            \r\n            showStatus: function(message, type) {\r\n                this.elements.statusDiv.innerHTML = message;\r\n                this.elements.statusDiv.className = 'bulk-url-opener-status ' + type;\r\n                this.elements.statusDiv.style.display = 'block';\r\n            },\r\n            \r\n            showProgress: function(total) {\r\n                this.elements.progressContainer.style.display = 'block';\r\n                this.elements.progressTotal.textContent = total;\r\n                this.elements.progressCurrent.textContent = '0';\r\n                this.elements.progressFill.style.width = '0%';\r\n            },\r\n            \r\n            updateProgress: function(current, total) {\r\n                this.elements.progressCurrent.textContent = current;\r\n                const percentage = Math.min((current \/ total) * 100, 100);\r\n                this.elements.progressFill.style.width = percentage + '%';\r\n            },\r\n            \r\n            hideProgress: function() {\r\n                this.elements.progressContainer.style.display = 'none';\r\n            },\r\n            \r\n            openUrl: function(url, mode, index) {\r\n                const self = this;\r\n                return new Promise(function(resolve) {\r\n                    try {\r\n                        let newWindow = null;\r\n                        \r\n                        switch(mode) {\r\n                            case 'unique-tabs':\r\n                                newWindow = window.open(url, '_blank', 'noopener,noreferrer');\r\n                                break;\r\n                                \r\n                            case 'unique-windows':\r\n                                newWindow = window.open(url, 'window_' + index, 'width=1200,height=800');\r\n                                break;\r\n                                \r\n                            case 'same-window':\r\n                                if (!self.currentWindow || self.currentWindow.closed) {\r\n                                    self.currentWindow = window.open(url, 'bulkWindow', 'width=1200,height=800');\r\n                                    newWindow = self.currentWindow;\r\n                                } else {\r\n                                    self.currentWindow.location.href = url;\r\n                                    newWindow = self.currentWindow;\r\n                                }\r\n                                break;\r\n                                \r\n                            case 'same-tab':\r\n                                window.location.href = url;\r\n                                resolve(true);\r\n                                return;\r\n                        }\r\n                        \r\n                        if (newWindow) {\r\n                            self.openedCount++;\r\n                            resolve(true);\r\n                        } else {\r\n                            self.blockedCount++;\r\n                            resolve(false);\r\n                        }\r\n                    } catch (error) {\r\n                        self.blockedCount++;\r\n                        resolve(false);\r\n                    }\r\n                });\r\n            },\r\n            \r\n            handleOpenUrls: async function() {\r\n                if (this.isProcessing) {\r\n                    this.shouldCancel = true;\r\n                    return;\r\n                }\r\n                \r\n                const urls = this.getUrls();\r\n                if (urls.length === 0) {\r\n                    this.showStatus('\u274c Please enter at least one URL', 'error');\r\n                    this.elements.urlsTextarea.focus();\r\n                    return;\r\n                }\r\n                \r\n                const prefix = this.elements.prefixInput.value.trim();\r\n                const suffix = this.elements.suffixInput.value.trim();\r\n                const mode = this.elements.tabOptions.value;\r\n                const delay = parseInt(this.elements.delayInput.value) || 0;\r\n                \r\n                const self = this;\r\n                const processedUrls = urls.map(function(url) {\r\n                    return self.processUrl(url, prefix, suffix);\r\n                });\r\n                \r\n                \/\/ Reset counters\r\n                this.openedCount = 0;\r\n                this.blockedCount = 0;\r\n                \r\n                \/\/ Start processing\r\n                this.isProcessing = true;\r\n                this.shouldCancel = false;\r\n                this.elements.openBtn.textContent = '\ud83d\uded1 Cancel';\r\n                \r\n                this.showProgress(processedUrls.length);\r\n                this.showStatus('\ud83d\ude80 Opening URLs...', 'info');\r\n                \r\n                \/\/ Detect popup blocking status\r\n                this.detectPopupBlocking();\r\n                \r\n                \/\/ Open URLs with delay\r\n                for (let i = 0; i < processedUrls.length && !this.shouldCancel; i++) {\r\n                    this.updateProgress(i + 1, processedUrls.length);\r\n                    \r\n                    const success = await this.openUrl(processedUrls[i], mode, i);\r\n                    \r\n                    \/\/ Add delay if specified\r\n                    if (delay > 0 && i < processedUrls.length - 1) {\r\n                        await new Promise(function(resolve) {\r\n                            setTimeout(resolve, delay * 1000);\r\n                        });\r\n                    }\r\n                }\r\n                \r\n                \/\/ Finish\r\n                this.isProcessing = false;\r\n                this.elements.openBtn.textContent = '\ud83d\ude80 Bulk Open URLs';\r\n                this.hideProgress();\r\n                \r\n                \/\/ Show result\r\n                if (this.shouldCancel) {\r\n                    this.showStatus('\ud83d\uded1 Operation cancelled', 'warning');\r\n                } else if (this.blockedCount > 0) {\r\n                    \/\/ Show detailed instructions for enabling popups\r\n                    const message = `\r\n                        <div class=\"permission-instructions\">\r\n                            <p>\u26a0\ufe0f Opened ${this.openedCount} URLs. ${this.blockedCount} ${this.blockedCount === 1 ? 'was' : 'were'} blocked.<\/p>\r\n                            <p>If this bulk URL opener tool does not run in your browser, go to your browser settings and allow site pop-ups. Then the tool should work perfectly.<\/p>\r\n                    \r\n                        <\/div>\r\n                    `;\r\n                    this.elements.statusDiv.innerHTML = message;\r\n                    this.elements.statusDiv.className = 'bulk-url-opener-status warning';\r\n                    this.elements.statusDiv.style.display = 'block';\r\n                } else {\r\n                    this.showStatus('\u2705 Successfully opened ' + this.openedCount + ' URLs!', 'success');\r\n                }\r\n            },\r\n            \r\n            resetAll: function() {\r\n                this.elements.urlsTextarea.value = '';\r\n                this.elements.prefixInput.value = '';\r\n                this.elements.suffixInput.value = '';\r\n                this.elements.delayInput.value = '0';\r\n                this.elements.tabOptions.value = 'unique-tabs';\r\n                this.updateUrlCounter();\r\n                this.hideProgress();\r\n                this.elements.statusDiv.style.display = 'none';\r\n                this.showStatus('\u2705 All fields have been reset', 'success');\r\n            },\r\n            \r\n            clearUrls: function() {\r\n                this.elements.urlsTextarea.value = '';\r\n                this.updateUrlCounter();\r\n                this.showStatus('\u2705 URLs cleared', 'success');\r\n            },\r\n            \r\n            pasteFromClipboard: async function() {\r\n                try {\r\n                    const text = await navigator.clipboard.readText();\r\n                    this.elements.urlsTextarea.value = text;\r\n                    this.updateUrlCounter();\r\n                    this.showStatus('\u2705 Content pasted from clipboard', 'success');\r\n                } catch (err) {\r\n                    this.showStatus('\u274c Unable to paste. Please use Ctrl+V', 'error');\r\n                }\r\n            },\r\n            \r\n            copyToClipboard: async function() {\r\n                const text = this.elements.urlsTextarea.value;\r\n                if (!text) {\r\n                    this.showStatus('\u274c No content to copy', 'error');\r\n                    return;\r\n                }\r\n                \r\n                try {\r\n                    await navigator.clipboard.writeText(text);\r\n                    this.showStatus('\u2705 Content copied to clipboard', 'success');\r\n                } catch (err) {\r\n                    this.showStatus('\u274c Unable to copy. Please use Ctrl+C', 'error');\r\n                }\r\n            },\r\n            \r\n            extractUrls: function() {\r\n                const text = this.elements.urlsTextarea.value;\r\n                const urlRegex = \/https?:\\\/\\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&\/\/=]*)\/gi;\r\n                const matches = text.match(urlRegex);\r\n                \r\n                if (matches && matches.length > 0) {\r\n                    \/\/ Remove duplicates using Set\r\n                    const uniqueUrls = Array.from(new Set(matches));\r\n                    this.elements.urlsTextarea.value = uniqueUrls.join('\\n');\r\n                    this.updateUrlCounter();\r\n                    this.showStatus('\u2705 Extracted ' + uniqueUrls.length + ' URLs', 'success');\r\n                } else {\r\n                    this.showStatus('\u274c No URLs found in the text', 'error');\r\n                }\r\n            }\r\n        };\r\n        \r\n        \/\/ Initialize the tool\r\n        BulkOpener.init();\r\n    });\r\n    <\/script>\r\n    \r\n    \n<h3>\ud83d\ude80 What You Can Do:<\/h3>\n<ul>\n<li><strong>Toggle Case:<\/strong> Switch between upper and lower case<\/li>\n<li><strong>Sentence Case:<\/strong> Capitalize the first letter of sentences<\/li>\n<li><strong>Upper\/Lower Case:<\/strong> Convert entire text to capitals or lowercase<\/li>\n<li><strong>Capitalize Words:<\/strong> Make each word start with a capital letter<\/li>\n<li><strong>Alternate Case:<\/strong> Create alternating upper\/lower pattern<\/li>\n<li><strong>Copy &amp; Download:<\/strong> Easy sharing and file saving<\/li>\n<li><strong>Real-time Stats:<\/strong> Character, word, and line counting<\/li>\n<\/ul>\n<h3>\ud83d\udcf1 Features:<\/h3>\n<ul>\n<li>\u2705 <strong>Mobile Responsive<\/strong> &#8211; Works on all devices<\/li>\n<li>\u2705 <strong>Instant Results<\/strong> &#8211; No waiting, immediate conversion<\/li>\n<li>\u2705 <strong>Privacy Focused<\/strong> &#8211; Your text stays on your device<\/li>\n<li>\u2705 <strong>No Registration<\/strong> &#8211; Use immediately, no signup required<\/li>\n<li>\u2705 <strong>Professional Design<\/strong> &#8211; Clean, modern interface<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Free online text case converter. Transform text to uppercase, lowercase, sentence case and more.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":20008,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"categories":[35],"class_list":["post-19916","page","type-page","status-publish","hentry","category-tool"],"_links":{"self":[{"href":"https:\/\/seoteampro.com\/index.php?rest_route=\/wp\/v2\/pages\/19916","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/seoteampro.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/seoteampro.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/seoteampro.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/seoteampro.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=19916"}],"version-history":[{"count":0,"href":"https:\/\/seoteampro.com\/index.php?rest_route=\/wp\/v2\/pages\/19916\/revisions"}],"up":[{"embeddable":true,"href":"https:\/\/seoteampro.com\/index.php?rest_route=\/wp\/v2\/pages\/20008"}],"wp:attachment":[{"href":"https:\/\/seoteampro.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=19916"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/seoteampro.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=19916"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}