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 += "
";
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);
}); }