var charIndex = 0; var isRunning = 0; // ----------------------------------------------------------- function stripslashes(str) { return (str + '') .replace(/\\'/g, "'") .replace(/\\"/g, '"') .replace(/\\\\/g, '\\'); } // ----------------------------------------------------------- function ucwords(str) { const words = str.split(' '); const capitalizedWords = words.map(word => { if (word.length === 0) return ''; return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); }); return capitalizedWords.join(' '); } // ----------------------------------------------------------- async function getDBRecord(slug) { if (document.getElementById('searchresultssubmit') !== null) document.getElementById('searchresultssubmit').disable = true; var form = document.forms['searchform']; var formData = new FormData(); formData.append('slug', slug); formData.append('action', 'getRecord'); formData.append('recordID', form['recordID'].value); var parentVal = ''; if (form['parentID'] !== undefined && form['parentID'] !== null) { parentVal = form['parentID'].value; formData.append('parentID', parentVal); } var searchresults = await ajaxGetDBInfo(formData); if (document.getElementById('searchresultssubmit') !== null) document.getElementById('searchresultssubmit').disable = false; var output = ""; var hiddenFields = ''; if ((searchresults !== false) && (searchresults !== null) && (typeof searchresults === 'object')) { output += "
"; Object.entries(searchresults).forEach(([index, val]) => { if (hiddenFields.length < 1) hiddenFields = index; else hiddenFields += ',' + index; var display = ucwords(index); switch (index) { case "fname": display = "First Name"; break; case "lname": display = "Last Name"; break; case "ip": display = "IP Address"; break; case "optin": display = "Opt-in Date"; break; case "sourceUrl": display = "Source Url"; break; } output += ""; }); output += "

" + display + ":







"; if (document.getElementById('statusdiv') !== null) document.getElementById('statusdiv').innerHTML = "

Record ID: " + form['recordID'].value + "

"; if (document.getElementById('searchresults') !== null) document.getElementById('searchresults').innerHTML = output; } else { if (document.getElementById('statusdiv') !== null) document.getElementById('statusdiv').innerHTML = "

" + searchresults + "

"; if (document.getElementById('searchresults') !== null) document.getElementById('searchresults').innerHTML = ""; } } // ----------------------------------------------------------- async function updateDBRecord(slug) { var form = document.forms['updateDBRecordForm']; var formData = new FormData(); formData.append('slug', slug); formData.append('action', 'updateRecord'); formData.append('recordID', form['recordID'].value); formData.append('hiddenFields', form['hiddenFields'].value); if (form['parentID'] !== undefined && form['parentID'] !== null) formData.append('parentID', form['parentID'].value); var fields = form['hiddenFields'].value.split(','); if ((fields !== false) && (fields !== null) && (typeof fields === 'object')) { Object.entries(fields).forEach(([index, val]) => { formData.append(val, form[val].value); }); } var statusStr = await ajaxGetDBInfo(formData); if (statusStr.length < 1) statusStr = "

No response from the server.

"; if (document.getElementById('statusdiv') !== null) document.getElementById('statusdiv').innerHTML = "

" + statusStr + "

"; } // ----------------------------------------------------------- function ajaxGetDBInfo(formData) { return fetch('ajaxGetDBInfo.php', { method: 'POST', body: formData}).then(async response => { const text = await response.text(); console.log('HTTP status:', response.status); console.log('raw response (first 300 chars):', text.slice(0,300)); if (!response.ok) { console.error('Non-OK HTTP response:', response.status, response.statusText); throw new Error('Network response was not OK: ' + response.status); } const stripped = text.replace(/^\uFEFF/, '').trim(); if (stripped.startsWith('<')) { console.error('Server returned HTML instead of JSON:', stripped.slice(0,300)); throw new Error('Expected JSON but received HTML. Check server logs/output.'); } try { return JSON.parse(stripped); } catch (e) { console.error('Failed to parse JSON. Full response below:\n', stripped); throw new Error('Invalid JSON from server: ' + e.message); } }) .then(data => { if (data && data.message) return data.message; else if (data && data.fields) return data.fields; else return data; //else return "Invalid Response"; }).catch(error => console.error('Error:', error)); } // ----------------------------------------------------------- async function ajaxGetDBField(slug, field, curval, fieldsToUpdate) { var formData = new FormData(); formData.append('slug', slug); formData.append('action', 'getdbfield'); formData.append('field', field); formData.append('recordID', curval); formData.append('hiddenFields', fieldsToUpdate); fields = await ajaxGetDBInfo(formData); if (fields && typeof fields === 'object') { for (var index in fields) { if (fields.hasOwnProperty(index) && document.getElementById(index) !== null) { document.getElementById(index).value = fields[index]; } } } //else if (document.getElementById('errorstatus') !== null) document.getElementById('errorstatus').innerHTML = ""; } // ----------------------------------------------------------- async function filterListMessages(slug, field, curval, fieldsToUpdate, messageSelectId) { await ajaxGetDBField(slug, field, curval, fieldsToUpdate); var filterFields = fieldsToUpdate.split(','); var filterFieldId = filterFields[filterFields.length - 1]; var filterEl = document.getElementById(filterFieldId); if (!filterEl) return; var filterVal = filterEl.value; var select = document.getElementById(messageSelectId); if (!select) return; for (var i = 0; i < select.options.length; i++) { var opt = select.options[i]; if (opt.value === '') continue; opt.style.display = (opt.getAttribute('data-filter') === filterVal) ? '' : 'none'; } select.value = ''; } // ----------------------------------------------------------- async function restartAppSupport() { var formData = new FormData(); formData.append('action', 'appsupport'); formData.append('restartchat', '1'); fields = await aiAppsAjax(formData); if (fields && typeof fields === 'object') { if (fields.hasOwnProperty('error') && document.getElementById('appsupporterrorstatus') !== null) document.getElementById('appsupporterrorstatus').innerHTML = fields['error']; else if (fields['message'].length < 1) fields['message'] = fields['error']; if (fields.hasOwnProperty('message') && document.getElementById('appsupportsuggest') !== null) document.getElementById('appsupportsuggest').value = fields['message']; } //else if (document.getElementById('errorstatus') !== null) document.getElementById('errorstatus').innerHTML = fields; } // ----------------------------------------------------------- async function getAppSupport(formname = 'appsupportform') { var form = document.forms[formname]; var formData = new FormData(); formData.append('action', 'appsupport'); formData.append('prompt', form['prompt'].value); fields = await aiAppsAjax(formData); if (fields && typeof fields === 'object') { if (fields.hasOwnProperty('error') && document.getElementById('appsupporterrorstatus') !== null) document.getElementById('appsupporterrorstatus').innerHTML = fields['error']; else if (fields['message'].length < 1) fields['message'] = fields['error']; if (fields.hasOwnProperty('message') && document.getElementById('appsupportsuggest') !== null) document.getElementById('appsupportsuggest').value = fields['message']; } //else if (document.getElementById('errorstatus') !== null) document.getElementById('errorstatus').innerHTML = fields; } //var count = 0; //while ((count < 60) && (fields == null)) { await jssleep(1000); count++; } //form['prompt'].value = fields['message']; // ----------------------------------------------------------- async function getAISuggestion(returnField = 'aisuggest', formname = 'broadcastform') { var index = 0; var form = document.forms[formname]; while ((form == null) && (index < 20)) { form = document.forms[formname + index]; index++; } var formData = new FormData(); formData.append('action', 'suggestions'); formData.append('prompt', form['prompt'].value); formData.append('rulesGPT', form['rulesGPT'].value); // this means we gave them a choice of a returnField if (returnField == "radio") returnField = form['aiReturnRadio'].value; var original = form['original'].value; if (original.length > 0) { formData.append('original', original); formData.append(original, form[original].value); if (returnField != "prompt") returnField = original; } fields = await aiAppsAjax(formData); if (fields && typeof fields === 'object') { if (fields['message'].length < 1) fields['message'] = fields['error']; if (returnField.length < 1) { if (fields.hasOwnProperty('message') && form['prompt'].value !== null) form['prompt'].value = fields['message']; } else { if (fields.hasOwnProperty('message') && form[returnField].value !== null) form[returnField].value = fields['message']; } } } // ----------------------------------------------------------- function aiAppsAjax(formData) { return fetch('aiAppsAjaxAdmin.php', { method: 'POST', body: formData}).then(async response => { const text = await response.text(); console.log('HTTP status:', response.status); console.log('raw response (first 300 chars):', text.slice(0, 300)); if (!response.ok) { console.error('Non-OK HTTP response:', response.status, response.statusText); throw new Error('Network response was not OK: ' + response.status); } const stripped = text.replace(/^\uFEFF/, '').trim(); if (stripped.startsWith('<')) { console.error('Server returned HTML instead of JSON:', stripped.slice(0, 300)); throw new Error('Expected JSON but received HTML. Check server logs/output.'); } return JSON.parse(stripped); }).then(data => { if (data && data.message) return data; else if (data && data.fields) return data; else return { message: "Invalid Response" }; }) .catch(error => { console.error('Error:', error); return { error: error.message, message: error.message }; }); } // ----------------------------------------------------------- function AnimateText(elementName, newText, duration) { gsap.to(elementName, { duration: duration, text: { value: newText, newClass: "class2", delimiter: " ", type: "diff" } }); } // ----------------------------------------------------------- function paywithpaypal() { var form = document.forms["paymentform"]; var amount = form["amount"].value; window.location.replace('/paypal.php?amount=' + amount); } // ----------------------------------------------------------- function paywithstripe() { var form = document.forms["paymentform"]; var amount = form["amount"].value; var rebill = form["rebill"].value; window.location.replace('/stripe.php?amount=' + amount + '&rebill=' + rebill); } // ----------------------------------------------------------- function OpenHelpDiv(thisText) { var el = document.getElementById("helpDiv"); if (el == null) return; el.innerText = thisText; if (el.style.display === 'none' || el.style.display === '') el.style.display = 'block'; else el.style.display = 'none'; } // ----------------------------------------------------------- function SwitchTabDiv(newTab, numTabs = 3) { var el = null; for (var i = 1; i <= numTabs; i++) { el = document.getElementById("pagetab" + i); if (i == newTab) el.style.display = 'block'; else el.style.display = 'none'; } } // ----------------------------------------------------------- function flipVisibility(id) { var el = document.getElementById(id); if (el.style.display === 'none' || el.style.display === '') el.style.display = 'block'; else el.style.display = 'none'; } // ----------------------------------------------------------- function toggleDiv(page, id) { var el = document.getElementById('div' + id); var onOff = 'on'; if (el.style.display === 'none' || el.style.display === '') { el.style.display = 'block'; onOff = 'on'; } else { el.style.display = 'none'; onOff = 'off'; } var formData = new FormData(); formData.append('id', id); formData.append('page', page); formData.append('onOff', onOff); //fetch('savedivstatus.php', { method: 'POST', body: formData}).then(response => response.json()).then(data => { }).catch(error => console.error('Error:', error)); } // ----------------------------------------------------------- function countChars() { var index = 0; var form = document.forms["broadcastform"]; while ((form == null) && (index < 20)) { form = document.forms["broadcastform" + index]; index++; } if (!form) return; var message = form["message"].value.trim(); var totalchars = message.length; form["charcount"].value = totalchars; } // ----------------------------------------------------------- function countMessageChars(formname, variable) { var form = document.forms[formname]; var message = form[variable].value.trim(); var totalchars = message.length; form["charcount"].value = totalchars; return totalchars; } // ----------------------------------------------------------- function expandMultipleDropdown(formname, field) { var form = document.forms[formname]; if (form[field + "[]"].size == 1) form[field + "[]"].size = 12; else form[field + "[]"].size = 1; } // ----------------------------------------------------------- async function jssleep (ms) { return new Promise(resolve => setTimeout(resolve, ms)); }; // ----------------------------------------------------------- // Mobile navigation functionality document.addEventListener('DOMContentLoaded', function() { const mobileToggle = document.querySelector('.mobile-nav-toggle'); const navMenu = document.querySelector('.navmenu'); if (mobileToggle && navMenu) { // Toggle main navigation mobileToggle.addEventListener('click', function() { navMenu.classList.toggle('active'); }); // Toggle dropdowns on mobile const topLevelLinks = document.querySelectorAll('.navmenu > ul > li > a'); topLevelLinks.forEach(link => { link.addEventListener('click', function(e) { if (window.innerWidth <= 768) { e.preventDefault(); const parentLi = this.parentElement; parentLi.classList.toggle('active'); // Close other open dropdowns topLevelLinks.forEach(otherLink => { if (otherLink !== this) { otherLink.parentElement.classList.remove('active'); } }); } }); }); // Close menu when clicking outside on mobile document.addEventListener('click', function(e) { if (window.innerWidth <= 768 && navMenu.classList.contains('active')) { if (!navMenu.contains(e.target) && !mobileToggle.contains(e.target)) { navMenu.classList.remove('active'); // Also close all dropdowns document.querySelectorAll('.navmenu > ul > li').forEach(li => { li.classList.remove('active'); }); } } }); // Close menu when window is resized to desktop window.addEventListener('resize', function() { if (window.innerWidth > 768) { navMenu.classList.remove('active'); document.querySelectorAll('.navmenu > ul > li').forEach(li => { li.classList.remove('active'); }); } }); } }); // ----------------------------------------------------------- function runSplitAnimation() { var el = document.querySelector("#dynamictext"); if (!el) el = document.querySelector("#supportreply"); if (!el) { console.warn("element not found."); return; } if (window._mySplit) window._mySplit.revert(); if (window._myAnim) { try { window._myAnim.revert(); } catch (e) { /* ignore */ } } window._mySplit = new SplitText(el, { type: "lines" }); window._myAnim = gsap.from(window._mySplit.lines, { x: 150, opacity: 0, duration: 3, ease: "power4.out", stagger: 0.09 }); } // ----------------------------------------------------------- function waitForOverlayToHide() { const overlay = document.getElementById("cookie-overlay"); if (!overlay) return Promise.resolve(); const style = getComputedStyle(overlay); if (style.display === "none" || style.visibility === "hidden" || overlay.classList.contains("hidden")) return Promise.resolve(); return new Promise((resolve) => { const observer = new MutationObserver(() => { const s = getComputedStyle(overlay); if (s.display === "none" || s.visibility === "hidden" || overlay.classList.contains("hidden")) { observer.disconnect(); resolve(); } }); observer.observe(overlay, { attributes: true, attributeFilter: ["style", "class"] }); const parentObserver = new MutationObserver(() => { if (!document.getElementById("cookie-overlay")) { parentObserver.disconnect(); observer.disconnect(); resolve(); } }); parentObserver.observe(document.body, { childList: true, subtree: true }); setTimeout(() => { observer.disconnect(); parentObserver.disconnect(); resolve(); }, 3000); }); }