PageSourceSearch

https://www.cybersmile.org/wp-content/themes/cybersmile-wp-main-3.…/assets/js/blocktype.consent.js?ver=1.1.0

js cybersmile.org collected 2026-10-02 04:02:42 UTC 9,656 bytes, 249 lines download raw bytes

1(function () {
2    'use strict';
3
4    // ============================================
5    // 1) CONFIG & STATE
6    // ============================================
7    const CONFIG = {
8        debug: false,
9        cookieExpiry: 365,
10        botKeywords: [
11            'bot', 'googlebot', 'applebot', 'bingbot', 'crawler', 'spider', 
12            'mediapartners', 'adsbot', 'baiduspider', 'yandex', 'duckduckbot', 
13            'facebot', 'facebookexternalhit', 'ia_archiver', 'headless', 'puppeteer', 
14            'selenium', 'webdriver'
15        ]
16    };
17
18    const isUserLoggedIn = /wordpress_logged_in_/.test(document.cookie);
19    const isLocalHost = (window.location.hostname === 'localhost');
20
21    // ============================================
22    // 2) SIMPLE LOGGER
23    // ============================================
24    function debugLog(message, type = 'info') {
25        if (!CONFIG.debug) return;
26        const colors = {
27            info: 'color: #007bff;',
28            success: 'color: #08c753;',
29            warn: 'color: #FF5100;',
30            error: 'color: #EC2361;'
31        };
32        console.log(`%c[DEBUG] ${message}`, colors[type] || colors.info);
33    }
34
35    // ============================================
36    // 3) UTILITIES
37    // ============================================
38    function getCookie(name) {
39        const value = `; ${document.cookie}`;
40        const parts = value.split(`; ${name}=`);
41        if (parts.length === 2) return decodeURIComponent(parts.pop().split(';').shift());
42        return null;
43    }
44
45    function setCookie(name, value, days) {
46        debugLog(`Setting cookie: ${name}=${value}`, 'info');
47        const date = new Date();
48        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
49        let cookieStr = `${name}=${encodeURIComponent(value)};expires=${date.toUTCString()};path=/;SameSite=Lax`;
50        if (location.protocol === 'https:') cookieStr += ";Secure";
51        document.cookie = cookieStr;
52    }
53
54    function isBot() {
55        const ua = navigator.userAgent.toLowerCase();
56        return CONFIG.botKeywords.some(keyword => ua.indexOf(keyword) !== -1);
57    }
58
59    function isMobile() {
60        return /android|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent);
61    }
62
63    // ============================================
64    // 4) SCRIPT LOADERS
65    // ============================================
66
67    function loadGoogleAnalytics(context = 'general_load') {
68        if (document.getElementById('google-gtag-script')) return;
69        
70        debugLog(`Initializing GA4 via context: ${context}`, 'info');
71
72        // 1. DataLayer Setup
73        window.dataLayer = window.dataLayer || [];
74        window.gtag = function(){ dataLayer.push(arguments); };
75        
76        gtag('js', new Date());
77        gtag('config', 'G-042W6VTM7G');
78
79        // 2. Log Privacy Event
80        gtag('event', 'privacy_consent_load', {
81            'event_category': 'privacy',
82            'event_label': context
83        });
84
85        // 3. Inject Library
86        const ga = document.createElement('script');
87        ga.id = 'google-gtag-script';
88        ga.async = true;
89        ga.src = 'https://www.googletagmanager.com/gtag/js?id=G-042W6VTM7G';
90        document.head.appendChild(ga);
91    }
92
93    function loadBeacon() {
94        if (!document.querySelector('.blocktype-form') || document.getElementById('beacon-js-sdk')) return;
95        debugLog('Loading Beacon CRM...');
96        const js = document.createElement('script');
97        js.id = 'beacon-js-sdk';
98        js.src = 'https://static.beaconproducts.co.uk/js-sdk/production/beaconcrm.min.js';
99        document.head.appendChild(js);
100    }
101
102    function loadAssistant() {
103        if (document.querySelector('.assistant-trigger')) return;
104        debugLog('Injecting Assistant markup...');
105        const div = document.createElement('div');
106        div.className = 'assistant-trigger';
107        div.innerHTML = `
108            <button aria-label="Open Cybersmile Assistant">
109               <svg class="icon" fill="currentColor" aria-hidden="true" focusable="false">
110                   <use xlink:href="#icon-logo-square"></use>
111               </svg>
112               <span class="sr-only">Open Assistant</span>
113            </button>
114            <span class="arrow-right"></span>`;
115        document.body.appendChild(div);
116    }
117
118    function removeMailerLiteDiv() {
119        const mailerLiteDiv = document.getElementById('mailerlite');
120        if (mailerLiteDiv) {
121            debugLog('Removing MailerLite div.');
122            mailerLiteDiv.parentNode.removeChild(mailerLiteDiv);
123        }
124    }
125
126    function loadMailerLite() {
127        const mailerLiteDiv = document.getElementById('mailerlite');
128        if (!mailerLiteDiv || document.getElementById('mailerlite-script')) return;
129        debugLog('Loading MailerLite scripts...');
130        const nonce = document.querySelector('script[nonce]')?.nonce || '';
131        const sdk = document.createElement('script');
132        sdk.id = 'mailerlite-script';
133        sdk.src = 'https://groot.mailerlite.com/js/w/webforms.min.js?v176e10baa5e7ed80d35ae235be3d5024';
134        if (nonce) sdk.setAttribute('nonce', nonce);
135        document.head.appendChild(sdk);
136    }
137
138    function runAllScripts(context) {
139        debugLog(`Executing runAllScripts from: ${context}`, 'success');
140
141        if (!isMobile()) loadAssistant();
142
143        if (!isUserLoggedIn && !isLocalHost) {
144            loadGoogleAnalytics(context);
145        } else {
146            debugLog('Skipping GA (Logged in or Localhost).');
147        }
148
149        loadBeacon();
150        loadMailerLite();
151    }
152
153    // ============================================
154    // 5) CONSENT UI (BANNER)
155    // ============================================
156    function showCookieBanner() {
157        if (document.getElementById('siteCookiesWrapper')) return;
158        debugLog('Attempting to show cookie banner...', 'info');
159
160        const html = `
161            <div id="siteCookiesWrapper" class="site-cookies--wrapper" role="alertdialog" aria-modal="true" aria-labelledby="siteCookiesTitle">
162                <div class="site-cookies--overlay"></div>
163                <div class="site-cookies">
164                    <div class="site-cookies--body">
165                        <button class="site-cookies--close" data-action="deny-cookies">✕</button>
166                        <div id="siteCookiesTitle" class="site-cookies--headline">We value your privacy.</div>
167                        <div class="site-cookies--description">
168                            <p>Our website uses cookies to provide you with a better online experience. By acknowledging this notice, you accept the use of cookies on this site.</p>
169                            <p>If you wish to view and adjust your privacy settings, you can click <span style="font-weight:500;">Manage My Consent</span> at any time in the website footer. You can <a href="https://www.cybersmile.org/cookie-policy/">read our privacy policy here</a>.</p>
170                        </div>
171                    </div>
172                    <div class="site-cookies--actions">
173                        <button class="site-cookies--action" data-action="accept-cookies">Accept All</button>
174                        <button class="site-cookies--action" data-action="deny-cookies">Reject All</button>
175                    </div>
176                </div>
177            </div>`;
178
179        document.body.insertAdjacentHTML('beforeend', html);
180        
181        document.getElementById('siteCookiesWrapper').addEventListener('click', (e) => {
182            const action = e.target.closest('[data-action]')?.dataset.action;
183            if (!action) return;
184
185            if (action === 'accept-cookies') {
186                debugLog('User accepted cookies. Reloading...', 'success');
187                setCookie('cy-consent', 'true', CONFIG.cookieExpiry);
188                location.reload();
189            } else {
190                debugLog('User denied cookies. Hiding banner.', 'warn');
191                setCookie('cy-consent', 'false', CONFIG.cookieExpiry);
192                removeMailerLiteDiv();
193                document.getElementById('siteCookiesWrapper').remove();
194            }
195        });
196    }
197
198    // ============================================
199    // 6) CORE LOGIC
200    // ============================================
201    function init() {
202        debugLog(`Script started. isUserLoggedIn=${isUserLoggedIn}`, 'info');
203
204        const userConsent = getCookie('cy-consent');
205        const edgeFlag = getCookie('cy-requires-consent');
206
207        if (userConsent === 'true') {
208            runAllScripts('returning_user');
209            return;
210        }
211
212        if (userConsent === 'false') {
213            debugLog('Consent previously denied. Skipping scripts.', 'warn');
214            removeMailerLiteDiv();
215            return;
216        }
217
218        if (isBot()) {
219            setCookie('cy-consent', 'true', CONFIG.cookieExpiry);
220            runAllScripts('bot_bypass');
221            return;
222        }
223
224        if (isUserLoggedIn) {
225            runAllScripts('auth_bypass');
226            return;
227        }
228
229        if (edgeFlag === 'false') {
230            setCookie('cy-consent', 'true', CONFIG.cookieExpiry);
231            runAllScripts('geo_bypass');
232        } else {
233            showCookieBanner();
234        }
235    }
236
237    init();
238
239    document.addEventListener('DOMContentLoaded', () => {
240        const manageLink = document.getElementById('manage-consent-link');
241        if (manageLink) {
242            manageLink.addEventListener('click', (e) => {
243                e.preventDefault();
244                showCookieBanner();
245            });
246        }
247    });
248
249})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.