(function () {
// 1) Basic bot filter (extend if you like)
function isBot() {
return /(bot|crawl|spider|google|bing|slurp|yandex|facebook|linkedin|pinterest|preview|whatsapp|discord|telegram|headless|puppeteer)/i
.test(navigator.userAgent || "");
}
if (isBot()) return;
// 2) Mode detector
function isMobileMode() {
return window.matchMedia("(max-width: 767px)").matches ||
/Mobi|Android|iPhone|iPad|iPod/i.test(navigator.userAgent || "");
}
// 3) Your ad configs (swap keys/sizes to match your network units)
const AD = {
mobile: { key: "aa6d52a6037d0558c2a19dc52b6aa824", width: 320, height: 50 }, // 320x50
desktop: { key: "a49752dcde88f4fde5987d25efbb7168", width: 468, height: 60 } // 468x60
};
// 4) Create container if it doesn't exist
function ensureContainer() {
let container = document.getElementById("ad-container");
if (!container) {
container = document.createElement("div");
container.id = "ad-container";
container.style.display = "none";
document.body.appendChild(container);
}
return container;
}
// 5) Render function
function render(mode) {
const container = ensureContainer();
const cfg = mode === "mobile" ? AD.mobile : AD.desktop;
// Set global atOptions for ad network
window.atOptions = {
key: cfg.key,
format: "iframe",
height: cfg.height,
width: cfg.width,
params: {}
};
// Clear previous ad/script then inject
container.innerHTML = "";
container.style.display = "block";
const s = document.createElement("script");
s.src = `//selfportraitproved.com/${cfg.key}/invoke.js`;
s.async = true;
container.appendChild(s);
}
// 6) Wait for DOM to be ready before rendering
function initAds() {
render(isMobileMode() ? "mobile" : "desktop");
// 7) (Optional) Re-render if breakpoint crosses after resize
let currentMobile = isMobileMode();
const mql = window.matchMedia("(max-width: 767px)");
if (mql.addEventListener) {
mql.addEventListener("change", (e) => {
const nowMobile = e.matches;
if (nowMobile !== currentMobile) {
currentMobile = nowMobile;
render(currentMobile ? "mobile" : "desktop");
}
});
} else if (mql.addListener) { // older browsers
mql.addListener((e) => {
const nowMobile = e.matches;
if (nowMobile !== currentMobile) {
currentMobile = nowMobile;
render(currentMobile ? "mobile" : "desktop");
}
});
}
}
// 8) Execute when DOM is ready
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", initAds);
} else {
initAds();
}
})();
DES MOINES, Iowa — Cajun Fest returns to Des Moines this weekend for its fourth year.
Cajun Fest will offer a taste of Louisiana with crawfish boils, gumbo, beignets, and more. A special Cajun-influenced beer will also be brewed by Confluence Brewing.
“It started as a backyard thing, moved here from Louisiana, wanted to get together with some friends. Flew in 100 pounds of crawfish everyone enjoyed the boil everyone threw in a couple bucks so we could give to charity, and honestly in four years it’s grown beyond our wildest dreams, so we’re lucky and fortunate to be here,” said Cajun Fest founder Stephen Smith.
The event will raise money for two local charities this year, iJAG and Saint Vincent of DePaul.
👉 For more insights, check out this resource.
The festival is expecting a huge turnout this year which is why organizers moved venues from the Birdland Marina to JR’s South Pork Ranch at the Iowa State Fairgrounds.
“This space is perfect to do events like Cajun Fest. I mean we have a pretty robust kitchen in the back, and we’ve got our culinary team in the back, they’re gonna be making gumbo, and jambalaya and beignets, and obviously we will be doing the crawfish boil. So, we have a great team that’s gonna be cooking up some wonderful Cajun recipes from our friends down in Louisiana, we kinda use their recipes,” said Brooks Reynolds, owner of JR’s South Pork Ranch.
👉 Discover more in this in-depth guide.
The event runs Saturday from 11:00 a.m. through 7:00 p.m. Tickets start at $40 and you can find more information about the event here.