window.FacebookSignal = window.FacebookSignal || { _held: false, _releasing: false, _pixelInitialized: false, _pixelId: null, _pixelUserInfo: {}, _pixelOptions: {}, _pendingPixelEvents: [], _queue: [], _config: {}, _seenEventIds: {}, _fbclid: (function () { try { var match = window.location.search.match(/[?&]fbclid=([^&]*)/); return match ? decodeURIComponent(match[1]) : null; } catch (e) { return null; } })(), _readCookie: function (name) { try { var pairs = (document.cookie || '').split(';'); for (var i = 0; i < pairs.length; i++) { var pair = pairs[i].replace(/^\s+/, ''); if (pair.indexOf(name + '=') === 0) { return decodeURIComponent(pair.substring(name.length + 1)); } } } catch (e) {} return null; }, init: function (config) { this._config = config || {}; this._attribution = this._config.attribution || {}; // Read cookie directly so cached pages resolve the correct held/active // state even when PHP rendered held: false. var cookieState = this._readCookie('wc_facebook_signals_state'); this._held = cookieState ? cookieState === 'held' : !!this._config.held; // Sync consent immediately so fbevents.js obeys the current state. if (typeof fbq === 'function') { fbq('consent', this._held ? 'revoke' : 'grant'); } try { var raw = window.sessionStorage.getItem('fbpix_seen_event_ids'); this._seenEventIds = raw ? JSON.parse(raw) : {}; } catch (e) { this._seenEventIds = this._seenEventIds || {}; } }, initPixel: function (pixelId, userInfo, options) { this._pixelId = pixelId; this._pixelUserInfo = userInfo && typeof userInfo === 'object' && !Array.isArray(userInfo) ? userInfo : {}; this._pixelOptions = options || {}; if (!this._held) { this._runPixelInit(); } }, _runPixelInit: function () { if (this._pixelInitialized || !this._pixelId || typeof fbq !== 'function') { return; } if (this._pixelOptions && this._pixelOptions.includeCapiIntegration) { var url = window.location.origin + '?ob=open-bridge'; fbq('set', 'openbridge', this._pixelId, url); } if (this._config.capig === '1') { fbq('optinMetaEnabledCapi', this._pixelId); } fbq('init', this._pixelId, this._pixelUserInfo, this._pixelOptions); this._pixelInitialized = true; this._flushPendingPixelEvents(); }, _flushPendingPixelEvents: function () { var pending = this._pendingPixelEvents; this._pendingPixelEvents = []; for (var i = 0; i < pending.length; i++) { var ev = pending[i]; this._firePixelEvent(ev.name, ev.params, ev.method, ev.eventId); } }, _fireOrQueuePixelEvent: function (name, params, method, eventId) { if (!this._pixelInitialized) { this._pendingPixelEvents.push({ name: name, params: params || {}, method: method || 'track', eventId: eventId || null, }); return; } this._firePixelEvent(name, params || {}, method || 'track', eventId || null); }, _firePixelEvent: function (name, params, method, eventId) { method = method || 'track'; if (eventId) { fbq(method, name, params || {}, { eventID: eventId }); } else { fbq(method, name, params || {}); } }, _syncCookie: function (name, serverValue, domain) { if (!serverValue) { return; } var encoded = encodeURIComponent(serverValue); var match = document.cookie.match( new RegExp('(?:^|;\\s*)' + name + '=([^;]*)'), ); var current = match ? match[1] : null; if (current && current !== encoded) { var cookie = name + '=' + encoded + ';path=/;max-age=7776000;SameSite=Lax'; if (domain) { cookie += ';domain=' + domain; } document.cookie = cookie; } }, queueEvent: function (eventData) { if (!eventData || !eventData.event_name) { return; } if (eventData.event_id && this._seenEventIds[eventData.event_id]) { return; } eventData.event_time = eventData.event_time || Math.floor(Date.now() / 1000); eventData.event_source_url = eventData.event_source_url || window.location.href; this._queue.push(eventData); if (eventData.event_id) { this._seenEventIds[eventData.event_id] = 1; try { window.sessionStorage.setItem( 'fbpix_seen_event_ids', JSON.stringify(this._seenEventIds), ); } catch (e) {} } }, trackEvent: function (name, params, userData, method, eventId) { method = method || 'track'; eventId = eventId || (params && params.eventID) || null; if (this._held) { this.queueEvent({ event_name: name, custom_data: params || {}, event_id: eventId, event_time: Math.floor(Date.now() / 1000), method: method, }); } else { this._fireOrQueuePixelEvent(name, params || {}, method, eventId); } }, hold: function () { this._held = true; fbq('consent', 'revoke'); }, release: function () { var self = this; if (!self._held || self._releasing || !self._config.ajaxUrl) { return Promise.resolve({ success: true, data: { sent_count: 0 } }); } self._releasing = true; return new Promise(function (resolve, reject) { var xhr = new XMLHttpRequest(); var url = self._config.ajaxUrl + (self._config.ajaxUrl.indexOf('?') === -1 ? '?' : '&') + 'action=' + encodeURIComponent(self._config.releaseAction); xhr.open('POST', url, true); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.onload = function () { if (xhr.status < 200 || xhr.status >= 300) { self._releasing = false; reject(new Error('Release AJAX failed: ' + xhr.status)); return; } try { var response = JSON.parse(xhr.responseText); self._handleReleaseResponse(response.data || {}); self._releasing = false; resolve(response); } catch (error) { self._releasing = false; reject(error); } }; xhr.onerror = function () { self._releasing = false; reject(new Error('Network error')); }; var attribution = self._config.attribution || {}; xhr.send( JSON.stringify({ events: self._queue, fbclid: self._fbclid, fbp: self._readCookie('_fbp') || attribution.fbp || null, fbc: self._readCookie('_fbc') || attribution.fbc || null, }), ); }); }, _handleReleaseResponse: function (data) { var attr = this._config.attribution || {}; var fbpValue = data.fbp || attr.fbp; var fbcValue = data.fbc || attr.fbc; if (fbpValue) { var fbpCookie = '_fbp=' + encodeURIComponent(fbpValue) + ';path=/;max-age=7776000;SameSite=Lax'; if (attr.fbpDomain) { fbpCookie += ';domain=' + attr.fbpDomain; } document.cookie = fbpCookie; } if (fbcValue) { var fbcCookie = '_fbc=' + encodeURIComponent(fbcValue) + ';path=/;max-age=7776000;SameSite=Lax'; if (attr.fbcDomain) { fbcCookie += ';domain=' + attr.fbcDomain; } document.cookie = fbcCookie; } // Update user_info with fresh AAM data from the release response, then // run (or re-run) fbq('init') so the pixel has correct user_info. if ( data.user_info && typeof data.user_info === 'object' && !Array.isArray(data.user_info) ) { this._pixelUserInfo = data.user_info; } this._pixelInitialized = false; this._runPixelInit(); fbq('consent', 'grant'); for (var i = 0; i < this._queue.length; i++) { var queuedEvent = this._queue[i]; var customData = queuedEvent.custom_data || {}; var trackMethod = queuedEvent.method || (queuedEvent.is_custom ? 'trackCustom' : 'track'); if (queuedEvent.event_id) { fbq(trackMethod, queuedEvent.event_name, customData, { eventID: queuedEvent.event_id, }); } else { fbq(trackMethod, queuedEvent.event_name, customData); } } this._queue = []; this._held = false; this._releasing = false; }, }; window.fbwcsignal = window.fbwcsignal || {}; (function (api) { var signalConfig = window.facebookSignalConfig || {}; var cookieName = signalConfig.cookieName || ''; var ajaxUrl = signalConfig.ajaxUrl || ''; var signalsAction = signalConfig.signalsAction || ''; var signalsNonce = signalConfig.signalsNonce || ''; function setCookie(value) { var expires = new Date(); expires.setTime(expires.getTime() + 365 * 24 * 60 * 60 * 1000); document.cookie = cookieName + '=' + encodeURIComponent(value) + ';expires=' + expires.toUTCString() + ';path=/;SameSite=Lax'; } function getCookie() { var match = document.cookie.match( new RegExp('(?:^|;\\s*)' + cookieName + '=([^;]*)'), ); return match ? decodeURIComponent(match[1]) : null; } function updateState(state) { var normalizedState = state === 'active' ? 'active' : 'held'; setCookie(normalizedState); return new Promise(function (resolve, reject) { var xhr = new XMLHttpRequest(); xhr.open('POST', ajaxUrl, true); xhr.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8', ); xhr.onload = function () { if (xhr.status < 200 || xhr.status >= 300) { reject(new Error('Signals AJAX failed: ' + xhr.status)); return; } try { var response = JSON.parse(xhr.responseText); if (normalizedState === 'held') { window.FacebookSignal.hold(); resolve(response); return; } if (window.FacebookSignal && window.FacebookSignal._held) { window.FacebookSignal.release().then( function () { resolve(response); }, function (error) { reject(error); }, ); return; } resolve(response); } catch (error) { reject(error); } }; xhr.onerror = function () { reject(new Error('Network error')); }; xhr.send( 'action=' + encodeURIComponent(signalsAction) + '&security=' + encodeURIComponent(signalsNonce) + '&state=' + encodeURIComponent(normalizedState), ); }); } api.hold = function () { return updateState('held'); }; api.release = function () { return updateState('active'); }; api.getState = function () { var value = getCookie(); if (value === 'active' || value === 'held') { return value; } return null; }; })(window.fbwcsignal);