1(function () { 2 const rawPath = window.location.pathname.replace(/\/$/, "") || "/"; 3 const pathAliases = new Map([ 4 ["/meet-the-team", "/team-4"], 5 ["/board-of-directors", "/copy-of-meet-the-team"], 6 ["/advisory-board", "/copy-of-meet-the-team-1"], 7 ["/financial-strategic-plan", "/publications"], 8 ["/know-the-signs", "/about-4"], 9 ["/spot-it-stop-it", "/projects-7"], 10 ["/volunteer", "/about-4-1"], 11 ["/donor-dock", "/copy-of-lifeboat-lifesavers"], 12 ["/international-partnership-form", "/partner-form"], 13 ["/international-partner-form", "/partner-form"], 14 ["/team/jill-bolander-cohen", "/about-5"], 15 ["/team/jonny", "/copy-of-jill-cohen"], 16 ["/team/eme", "/copy-of-bella"], 17 ["/team/maryanne", "/copy-of-kathy"], 18 ["/team/kathy-pierson", "/copy-of-jamie"], 19 ["/team/ed-gilbert", "/copy-of-bella-1"], 20 ["/team/kristen-jensen", "/copy-of-piros"], 21 ["/team/kristen", "/copy-of-piros"], 22 ["/team/nancy", "/copy-of-eme"], 23 ["/team/jamie-holmes", "/copy-of-nancy"], 24 ["/team/piros-pazaurek", "/copy-of-ed"], 25 ["/team/bella", "/copy-of-jonny"], 26 ["/team/shannon-fraser", "/copy-of-bella-2"], 27 ["/team/gary-cohen", "/copy-of-shannon"], 28 ["/team/mark", "/copy-of-gary"], 29 ["/team/jeremy-smith", "/copy-of-gary-1"], 30 ["/team/linda-kennedy-martin", "/copy-of-jeremy"], 31 ]); 32 const path = pathAliases.get(rawPath) || rawPath; 33 const storiesPath = "/stories/"; 34 const storiesVideosHash = "#comp-mm6udoup"; 35 const yachtRockFlyerImage = "/assets/updates/yacht-rock/invitation-2026.jpg"; 36 const yachtRockEventPath = "/yacht-rock-benefit-bash"; 37 const whatWeDoHeaderImage = "/assets/updates/what-we-do-header.webp"; 38 const getInvolvedHeaderImage = "/assets/updates/get-involved-header.webp"; 39 const volunteerHeaderImage = "/assets/updates/volunteer-header.webp"; 40 const knowTheSignsHeaderImage = "/assets/updates/know-the-signs-header.webp"; 41 const homeSafetyImage = "/assets/updates/home-safety-support.jpg"; 42 const homeHeroVideoSrc = "/assets/videos/our-impact.mp4"; 43 const mobileLogoImage = "/assets/captured/c5f8d598b3dde3c0.png"; 44 const lindaKennedyMartinPortrait = "/assets/updates/team/linda-kennedy-martin.jpg"; 45 const candidProfileUrl = "https://app.candid.org/profile/9263741/the-lifeboat-project-inc-45-5412556"; 46 const donateUrl = "https://thelifeboatproject.networkforgood.com/projects/120280-donate-to-the-lifeboat-project"; 47 const requestHelpUrl = "https://docs.google.com/forms/d/e/1FAIpQLSe1SqfRxeTjXKlknS-daZLEfl0H0Hpma7CRr6MmxRCyQPjm8A/viewform"; 48 const contactEmail = "[email protected]"; 49 const volunteerApplyEmail = "mailto:[email protected]?subject=Volunteer%20Application"; 50 const volunteerApplyFormUrl = "https://docs.google.com/forms/d/e/1FAIpQLSf57dc8asiUQhlG9PR_uOjf0wi5819l3iRBLxqQJp2ahfgJbw/viewform"; 51 let homeGetInvolvedChatBound = false; 52 let homeGetInvolvedChatFrame = 0; 53 const blogPosts = [ 54 { 55 title: "Congratulations Gary Cohen!", 56 path: "/post/congratulations-gary-cohen/", 57 date: "Feb 28", 58 views: "29 views", 59 category: "Leadership", 60 image: "/assets/updates/blog-gary-cohen.webp", 61 summary: 62 "A community congratulations for Co-Founder and Treasurer Gary Cohen after more than a decade of service with the Greater Orlando Sports Commission.", 63 excerpt: 64 "Gary Cohen pictured with former Olympic runner Keith Brantly ahead of the 2024 U.S. Olympic Team Trials - Marathon in downtown Orlando. All of us at The Lifeboat Project want to extend our heartfelt congratulations to our Co-Founder and Treasurer, Gary Cohen, on his well-deserved retirement after more than 10 years of service with the Greater Orlando Sports Commission. Gary's visionary leadership has played a pivotal role in elevating Orlando's presence on the global sport", 65 }, 66 { 67 title: "Congratulations, Commissioner Lee Constantine!", 68 path: "/post/congratulations-commissioner-lee-constantine/", 69 date: "Feb 26", 70 views: "21 views", 71 category: "Community", 72 image: "/assets/updates/blog-lee-constantine.png", 73 summary: 74 "Celebrating Commissioner Lee Constantine's lifetime achievement recognition and his continued leadership across Central Florida.", 75 excerpt: 76 "We are incredibly proud of our outstanding Board of Directors member, Commissioner Lee Constantine, for receiving the Marlene Young Lifetime Achievement Award from the Florida Association of Counties! This prestigious honor recognizes a lifetime of dedicated public service, advocacy, and leadership, and no one is more deserving than Lee. His unwavering commitment to our community and to strengthening local government continues to inspire us all. Congratulations, Lee, on this", 77 }, 78 { 79 title: "Mental Health Association: Legacy of Champions Luncheon", 80 path: "/post/mental-health-association-legacy-of-champions-luncheon/", 81 date: "Feb 23", 82 views: "17 views", 83 category: "Partnerships", 84 image: "/assets/updates/blog-mental-health-luncheon.jpg", 85 summary: 86 "A look back at the Mental Health Association's Legacy of Champions Luncheon and Lifeboat's expanded sponsorship support.", 87 excerpt: 88 "Our team at The Lifeboat Project was incredibly honored to attend the Mental Health Association's Legacy of Champions Luncheon. We are proud to of had two full tables of staff and Board of Director members join us for this occasion. The Legacy of Champions Luncheon was an inspiring event dedicated to recognizing community leaders making great impacts in the realm of mental health advocacy. We increased our sponsorship level from last year's luncheon to be Premier sponsors, as", 89 }, 90 { 91 title: "Making Waves to End Human Trafficking", 92 path: "/post/making-waves-to-end-human-trafficking/", 93 date: "Mar 19, 2025", 94 views: "27 views", 95 category: "Events", 96 image: "/assets/updates/blog-making-waves.webp", 97 summary: 98 "Community leaders gathered at Venue on Lake Lily to raise awareness, support survivors, and move the mission forward.", 99 excerpt: 100 "On Wednesday, April 30, 2025, we hosted a great luncheon at the Venue on Lake Lily, featuring many professionals and leaders in the Central Florida community. Thank y
100ou so much to everyone who came out in support of fighting the horrific crime that is human trafficking. To everyone who contributed monetarily, your donation will greatly affect the lives of those who are suffering from this crime. Donations directly support survivors with trauma counseling, family counseling,", 101 }, 102 { 103 title: "An Evening Supporting Survivors of Human Trafficking", 104 path: "/post/an-evening-supporting-survivors-of-human-trafficking/", 105 date: "Nov 28, 2024", 106 views: "18 views", 107 category: "Fundraiser", 108 image: "/assets/updates/blog-yacht-rock-gala.jpg", 109 summary: 110 "A recap from the annual Yacht Rock Gala, where supporters came together for survivor services and trafficking awareness.", 111 excerpt: 112 "Jill Cohen, The Lifeboat Project, and Chad Pitt, Magic 107.7, on stage speaking at the Gala. The Lifeboat Project held its annual Yacht Rock Gala at the Wyndham, Lake Buena Vista, Disney Springs on Saturday, November 2nd, 2024. It was an incredible fundraising event where many from the Central Florida community came together to raise awareness on human trafficking. The Lifeboat Project is a safe space for all adult victims of human trafficking, regardless of gender, faith de", 113 }, 114 ]; 115 const storyThumbnailImages = new Map([ 116 ["Our Impact", "/assets/captured/6250f9d2681f491e.jpeg"], 117 ["Raychelle's Story", "/assets/captured/b8752ecd9c945a05.jpeg"], 118 ["Every Person Matters", "/assets/captured/d9c3fdaaf78d4037.jpeg"], 119 ["Our Mission", "/assets/captured/19e9dbc92f892326.jpeg"], 120 ["Our Proudest Moments", "/assets/captured/4dfa1b1b0c08622f.jpeg"], 121 ["Unconditional Love", "/assets/captured/ea7994bea5a7ee9a.jpeg"], 122 ["Signs Someone is Being Trafficked", "/assets/captured/3935c070afae7ab7.jpeg"], 123 ]); 124 const whatWeDoVideo = { 125 rootId: "comp-mm6u6r7x", 126 title: "Unconditional Love", 127 src: "/assets/videos/unconditional-love.mp4", 128 poster: "/assets/captured/ea7994bea5a7ee9a.jpeg", 129 }; 130 const storyVideoSources = new Map([ 131 ["Our Impact", "/assets/videos/our-impact.mp4"], 132 ["Raychelle's Story", "/assets/videos/raychelle-story.m4v"], 133 ["Every Person Matters", "/assets/videos/every-person-matters.m4v"], 134 ["Our Mission", "/assets/videos/our-mission.mp4"], 135 ["Our Proudest Moments", "/assets/videos/proudest-moments.mp4"], 136 ["Unconditional Love", "/assets/videos/unconditional-love.mp4"], 137 ["Signs Someone is Being Trafficked", "/assets/videos/signs-someone-trafficked.mp4"], 138 ]); 139 const storyVideoLibrary = [...storyVideoSources].map(([title, src]) => ({ 140 title, 141 src, 142 image: storyThumbnailImages.get(title) || "/assets/updates/home-hero-first-frame.jpg", 143 })); 144 let homeVideoIndex = Math.max( 145 0, 146 storyVideoLibrary.findIndex((video) => video.title === "Our Impact"), 147 ); 148 let activeVideoModal = null; 149 150 function clean(text) { 151 return String(text || "") 152 .replace(/[\u200B-\u200D\uFEFF]/g, "") 153 .replace(/\s+/g, " ") 154 .trim(); 155 } 156 157 function bindCleanHomeVideoLoop(video) { 158 if (!video || video.dataset.edCleanHomeVideoLoop === "true") return; 159 video.dataset.edCleanHomeVideoLoop = "true"; 160 let resumeAttempts = 0; 161 162 const requestPlayback = () => { 163 try { 164 if (resumeAttempts > 18 && video.paused) return; 165 resumeAttempts += 1; 166 video.autoplay = true; 167 video.loop = false; 168 video.muted = true; 169 video.defaultMuted = true; 170 video.playsInline = true; 171 video.playbackRate = 1; 172 const currentSource = video.currentSrc || video.getAttribute("src") || ""; 173 const source = video.querySelector("source"); 174 if (!currentSource.includes(homeHeroVideoSrc)) { 175 video.setAttribute("src", homeHeroVideoSrc); 176 if (source) source.setAttribute("src", homeHeroVideoSrc); 177 video.load(); 178 } else if (source && !source.getAttribute("src")?.includes(homeHeroVideoSrc)) { 179 source.setAttribute("src", homeHeroVideoSrc); 180 } 181 video.setAttribute("autoplay", ""); 182 video.removeAttribute("loop"); 183 video.setAttribute("muted", ""); 184 video.setAttribute("playsinline", ""); 185 video.setAttribute("webkit-playsinline", ""); 186 video.setAttribute("preload", "auto");
187 const playPromise = video.play(); 188 if (playPromise && typeof playPromise.catch === "function") playPromise.catch(() => {}); 189 } catch {} 190 }; 191 192 const requestPlaybackSoon = () => { 193 requestPlayback(); 194 window.setTimeout(requestPlayback, 80); 195 window.setTimeout(requestPlayback, 360); 196 }; 197 198 video.addEventListener("loadedmetadata", () => { 199 video.loop = false; 200 video.playbackRate = 1; 201 video.removeAttribute("loop"); 202 requestPlayback(); 203 }); 204 video.addEventListener("loadeddata", requestPlaybackSoon); 205 video.addEventListener("canplay", requestPlaybackSoon); 206 video.addEventListener("play", () => { 207 resumeAttempts = 0; 208 video.loop = false; 209 video.playbackRate = 1; 210 video.removeAttribute("loop"); 211 }); 212 video.addEventListener("pause", () => { 213 if (!video.ended) requestPlaybackSoon(); 214 }); 215 216 requestPlaybackSoon(); 217 window.setTimeout(requestPlaybackSoon, 1200); 218 document.addEventListener("visibilitychange", () => { 219 if (!document.hidden) requestPlaybackSoon(); 220 }); 221 window.addEventListener("focus", requestPlaybackSoon); 222 window.addEventListener("pageshow", requestPlaybackSoon); 223 window.addEventListener("touchstart", requestPlaybackSoon, { passive: true, once: true }); 224 window.addEventListener("pointerdown", requestPlaybackSoon, { passive: true, once: true }); 225 } 226 227 function escapeMarkup(value) { 228 return String(value || "").replace(/[&<>"']/g, (character) => { 229 switch (character) { 230 case "&": 231 return "&"; 232 case "<": 233 return "<"; 234 case ">": 235 return ">"; 236 case '"': 237 return """; 238 default: 239 return "'"; 240 } 241 }); 242 } 243 244 function insertBeforeFooter(section) { 245 const pageContent = document.querySelector("#PAGES_CONTAINER"); 246 if (pageContent) { 247 const sitePages = pageContent.querySelector(":scope > #SITE_PAGES"); 248 pageContent.insertBefore(section, sitePages || pageContent.firstChild); 249 return; 250 } 251 252 const footer = document.querySelector("#SITE_FOOTER, footer"); 253 if (footer && footer.parentNode) { 254 footer.parentNode.insertBefore(section, footer); 255 return; 256 } 257 258 const master = document.querySelector("main") || document.querySelector("#masterPage") || document.body; 259 master.appendChild(section); 260 } 261 262 function positionBeforeFooterInside(parent, section) { 263 const sectionRect = section.getBoundingClientRect(); 264 const sectionBottom = sectionRect.bottom; 265 let element = parent; 266 let guard = 0; 267 268 while (element && element !== document.body && guard < 7) { 269 const rect = element.getBoundingClientRect(); 270 const neededHeight = sectionBottom - rect.top + 40; 271 if (rect.height < neededHeight) { 272 element.style.minHeight = `${neededHeight}px`; 273 } 274 element = element.parentElement; 275 guard += 1; 276 } 277 } 278 279 function fitPanelToVisualViewport(section, options = {}) { 280 const visualWidth = Math.min( 281 document.documentElement.clientWidth || window.innerWidth, 282 window.visualViewport?.width || window.innerWidth, 283 ); 284 285 if (visualWidth > 700) { 286 section.classList.remove("ed-mobile-fit"); 287 section.style.removeProperty("max-width"); 288 if (!options.absolute) { 289 section.style.removeProperty("margin-left"); 290 section.style.removeProperty("margin-right"); 291 section.style.removeProperty("width"); 292 } 293 return; 294 } 295 296 const panelWidth = Math.max(visualWidth - 24, 280); 297 section.classList.add("ed-mobile-fit"); 298 section.style.maxWidth = `${panelWidth}px`; 299 section.style.width = `${panelWidth}px`; 300 301 if (options.absolute) { 302 section.style.left = "12px"; 303 section.style.transform = "none"; 304 } else { 305 section.style.marginLeft = "12px"; 306 section.style.marginRight = "0"; 307 } 308 } 309 310 function placeTeamUpdate(section) { 311 const teamSection = [...document.querySelectorAll("section.wixui-section")].find((candidate) => 312 /Meet The Team/i.test(clean(candidate.innerText || candidate.textContent)), 313 ); 314 315 if (!teamSection) { 316 insertBeforeFooter(section); 317 return; 318 } 319 320 teamSection.style.removeProperty("min-height"); 321 teamSection.appendChild(section); 322 323 const teamTop = teamSection.getBoundingClientRect().top; 324 const teamRepeater = teamSection.querySelector("#comp-mm5u1hh1") || teamSection; 325 const repeaterItems = [...teamRepeater.querySelectorAll(".wixui-repeater__item")].filter( 326 (item) => !item.classList.contains("ed-hidden"), 327 ); 328 const lastTeamItemBottom = repeaterItems.length 329 ? Math.max(...repeaterItems.map((item) => item.getBoundingClientRect().bottom)) 330 : teamTop + teamSection.getBoundingClientRect().height; 331 const top = Math.max(0, lastTeamItemBottom - teamTop + 72); 332 333 section.classList.add("ed-wix-inline-section");
334 Object.assign(section.style, { 335 left: "50%", 336 margin: "0", 337 position: "absolute", 338 top: `${top}px`, 339 transform: "translateX(-50%)", 340 width: "min(1120px, calc(100% - 48px))", 341 zIndex: "4", 342 }); 343 344 fitPanelToVisualViewport(section, { absolute: true }); 345 positionBeforeFooterInside(teamSection, section); 346 } 347 348 function hideElement(element) { 349 if (!element) return; 350 element.classList.add("ed-hidden"); 351 element.setAttribute("aria-hidden", "true"); 352 } 353 354 function elementTextEquals(element, expected) { 355 return clean(element.innerText || element.textContent) === expected; 356 } 357 358 function elementsByExactText(expected) { 359 return [...document.querySelectorAll("body *")].filter((element) => 360 element.children.length === 0 && elementTextEquals(element, expected), 361 ); 362 } 363 364 function setExactText(oldText, newText) { 365 elementsByExactText(oldText).forEach((element) => { 366 element.textContent = newText; 367 }); 368 } 369 370 function setLinkText(oldText, newText) { 371 document.querySelectorAll("a").forEach((link) => { 372 if (clean(link.textContent) === oldText) { 373 link.textContent = newText; 374 link.setAttribute("aria-label", newText); 375 } 376 }); 377 } 378 379 function isMobileShellViewport() { 380 const visualWidth = Math.min( 381 document.documentElement.clientWidth || window.innerWidth, 382 window.visualViewport?.width || window.innerWidth, 383 window.screen?.width || window.innerWidth, 384 ); 385 const key = rawPath.replace(/\/$/, "") || "/"; 386 const mobileBreakpoint = key === "/" ? 1100 : 980; 387 return visualWidth <= mobileBreakpoint; 388 } 389 390 function shouldUseNativeSponsorsPage() { 391 return path === "/sponsors" && Boolean(document.querySelector(".sponsors-shell")); 392 } 393 394 function shouldUseNativeDonorDockPage() { 395 return path === "/copy-of-lifeboat-lifesavers" && Boolean(document.querySelector(".donor-dock")); 396 } 397 398 function shouldUseSharedDesktopDonorFooter() { 399 return ["/privacy-policy", "/accessibility-statement", "/get-involved"].includes(path); 400 } 401 402 const renderedNavigation = new WeakMap(); 403 404 function mobileLinkItems() { 405 const items = [{ label: "Home", href: "/", mobileLevel: "primary" }]; 406
407 desktopNavItems().forEach((item) => { 408 items.push({ ...item, mobileLevel: "primary" }); 409 (item.submenu || []).forEach((subItem) => { 410 items.push({ 411 ...subItem, 412 mobileLevel: "subitem", 413 parent: item.label, 414 }); 415 }); 416 }); 417 418 return items; 419 } 420 421 function mobileAnchor({ label, href, external = false, mobileLevel = "primary", parent = "" }, className = "") { 422 const externalAttrs = external ? ' target="_blank" rel="noopener noreferrer"' : ""; 423 const classes = [ 424 className, 425 mobileLevel === "subitem" ? "ed-mobile-menu-subitem" : "ed-mobile-menu-primary", 426 ].filter(Boolean); 427 const classAttr = classes.length ? ` class="${classes.map(escapeMarkup).join(" ")}"` : ""; 428 const parentAttr = parent ? ` data-ed-mobile-menu-parent="${escapeMarkup(parent)}"` : ""; 429 const ariaLabel = parent ? ` aria-label="${escapeMarkup(`${parent}: ${label}`)}"` : ""; 430 return `<a${classAttr}${parentAttr}${ariaLabel} href="${href}"${externalAttrs}>${escapeMarkup(label)}</a>`; 431 } 432 433 function desktopNavItems() { 434 return [ 435 { 436 label: "Who We Are", 437 href: "/who-we-are/", 438 activePaths: ["/who-we-are", "/meet-the-team", "/board-of-directors", "/advisory-board", "/financial-strategic-plan"], 439 submenu: [ 440 { label: "Meet the Team", href: "/meet-the-team/" }, 441 { label: "Board of Directors", href: "/board-of-directors/" }, 442 { label: "Advisory Board", href: "/advisory-board/" }, 443 { label: "Financial & Strategic Plan", href: "/financial-strategic-plan/" }, 444 ], 445 }, 446 { label: "What We Do", href: "/what-we-do/" }, 447 { 448 label: "Know the Signs", 449 href: "/know-the-signs/", 450 activePaths: ["/know-the-signs", "/spot-it-stop-it", "/projects-7"], 451 submenu: [{ label: "Spot It. Stop It", href: "/spot-it-stop-it/" }], 452 }, 453 { label: "Request Help", href: requestHelpUrl, external: true }, 454 { 455 label: "Get Involved", 456 href: "/get-involved/", 457 activePaths: ["/get-involved", "/volunteer", "/request-a-speaker", "/international-partnerships"], 458 submenu: [ 459 { label: "International Partnerships", href: "/international-partnerships/" }, 460 { label: "Volunteer", href: "/volunteer/" }, 461 { label: "Request a Speaker", href: "/request-a-speaker/" }, 462 ], 463 }, 464 { 465 label: "Sponsors", 466 href: "/sponsors/", 467 activePaths: ["/sponsors", "/lifeboat-lifesavers", "/donor-dock", "/copy-of-lifeboat-lifesavers"], 468 submenu: [ 469 { label: "Lifeboat Lifesavers", href: "/lifeboat-lifesavers/" }, 470 { label: "The Donor Dock", href: "/donor-dock/" }, 471 ], 472 }, 473 { 474 label: "Events", 475 href: "/events/", 476 activePaths: ["/events", "/yacht-rock-benefit-bash"], 477 submenu: [{ label: "Yacht Rock Benefit Bash", href: "/yacht-rock-benefit-bash" }], 478 }, 479 { 480 label: "Stories", 481 href: "/stories/", 482 activePaths: ["/stories", "/blog"], 483 submenu: [{ label: "Blog", href: "/blog/" }], 484 }, 485 { label: "Contact", href: "/contact/" }, 486 ]; 487 } 488 489 function normalizeNavPath(value) { 490 if (!value) return "/"; 491 try { 492 const url = new URL(value, window.location.origin); 493 value = url.pathname; 494 } catch { 495 value = String(value || "/").split(/[?#]/)[0]; 496 } 497 498 return `/${value.replace(/^\/+/, "").replace(/\/+$/, "")}`.replace(/^\/$/, "/"); 499 } 500 501 function isDesktopNavActive(item) { 502 const current = normalizeNavPath(rawPath); 503 const canonicalCurrent = normalizeNavPath(path); 504 const candidates = [item.href, ...(item.activePaths || [])].map(normalizeNavPath); 505 return candidates.some((candidate) => current === candidate || canonicalCurrent === candidate); 506 } 507 508 function desktopNavAnchor(item, className = "") { 509 const attrs = [ 510 `href="${escapeMarkup(item.href)}"`, 511 className ? `class="${escapeMarkup(className)}"` : "", 512 item.external ? 'target="_blank" rel="noopener noreferrer"' : "", 513 item.submenu ? 'aria-haspopup="true" aria-expanded="false"' : "", 514 isDesktopNavActive(item) ? 'aria-current="page"' : "",
515 ].filter(Boolean).join(" "); 516 517 return `<a ${attrs}>${escapeMarkup(item.label)}</a>`; 518 } 519 520 function desktopNavMarkup() { 521 return desktopNavItems() 522 .map((item) => { 523 const submenu = item.submenu?.length 524 ? `<div class="ed-desktop-subnav" aria-label="${escapeMarkup(item.label)} pages">${ 525 item.submenu.map((subItem) => desktopNavAnchor(subItem)).join("") 526 }</div>` 527 : ""; 528 const className = item.submenu?.length ? "ed-desktop-nav-item has-subnav" : "ed-desktop-nav-item"; 529 530 return `<div class="${className}">${desktopNavAnchor(item, "ed-desktop-nav-link")}${submenu}</div>`; 531 }) 532 .join(""); 533 } 534 535 function bindUnifiedDesktopDropdowns(header) { 536 header.querySelectorAll(".ed-desktop-nav-item.has-subnav").forEach((item) => { 537 const link = item.querySelector(".ed-desktop-nav-link"); 538 if (!link || item.dataset.edDesktopDropdownBound === "true") return; 539 item.dataset.edDesktopDropdownBound = "true"; 540 541 let closeTimer; 542 const show = () => { 543 window.clearTimeout(closeTimer); 544 item.classList.add("is-open"); 545 link.setAttribute("aria-expanded", "true"); 546 }; 547 const hide = () => { 548 window.clearTimeout(closeTimer); 549 item.classList.remove("is-open"); 550 link.setAttribute("aria-expanded", "false"); 551 }; 552 const scheduleHide = () => { 553 window.clearTimeout(closeTimer); 554 closeTimer = window.setTimeout(hide, 140); 555 }; 556 557 item.addEventListener("pointerenter", show); 558 item.addEventListener("pointerleave", scheduleHide); 559 item.addEventListener("focusin", show); 560 item.addEventListener("focusout", () => { 561 window.requestAnimationFrame(() => { 562 if (!item.contains(document.activeElement)) hide(); 563 }); 564 }); 565 }); 566 } 567 568 function installUnifiedDesktopHeader() { 569 document.body.classList.add("ed-unified-desktop-nav"); 570 const markup = desktopNavMarkup(); 571 572 let header = document.querySelector(".ed-desktop-header"); 573 if (!header) { 574 header = document.createElement("header"); 575 header.className = "ed-desktop-header"; 576 header.setAttribute("aria-label", "Site header"); 577 header.innerHTML = ` 578 <div class="ed-desktop-header-inner"> 579 <a class="ed-desktop-brand" href="/" aria-label="The Lifeboat Project home"> 580 <img src="${mobileLogoImage}" alt="The Lifeboat Project"> 581 </a> 582 <nav class="ed-desktop-nav" aria-label="Site navigation"> 583 ${markup} 584 </nav> 585 <a class="ed-desktop-donate" href="${donateUrl}" target="_blank" rel="noopener noreferrer">Donate</a> 586 </div> 587 `; 588 document.body.insertBefore(header, document.body.firstChild); 589 } 590 591 const nav = header.querySelector(".ed-desktop-nav"); 592 // Scheduled page repairs must not replace a focused or open navigation menu. 593 if (nav && renderedNavigation.get(nav) !== markup) { 594 nav.innerHTML = markup; 595 renderedNavigation.set(nav, markup); 596 } 597 598 bindUnifiedDesktopDropdowns(header); 599 } 600 601 function mobileCard(title, body, href, cta = "Learn More") { 602 return ` 603 <article class="ed-mobile-card"> 604 <h2>${escapeMarkup(title)}</h2> 605 <p>${escapeMarkup(body)}</p> 606 <a href="${href}">${escapeMarkup(cta)}</a> 607 </article> 608 `; 609 } 610 611 function blogSummary(post) { 612 return clean(post.summary || post.excerpt).replace(/,\s*$/, "."); 613 } 614 615 function blogCategory(post) {
616 return clean(post.category) || "Update"; 617 } 618 619 function renderMobileBlogTile(post, options = {}) { 620 const featuredClass = options.featured ? " ed-mobile-blog-tile-featured" : ""; 621 622 return ` 623 <a class="ed-mobile-blog-tile${featuredClass}" href="${post.path}"> 624 <img src="${post.image}" alt="${escapeMarkup(post.title)}" loading="eager" decoding="async"> 625 <span class="ed-mobile-blog-copy"> 626 <span class="ed-mobile-blog-meta">${escapeMarkup(blogCategory(post))} - ${escapeMarkup(post.date)}</span> 627 <strong>${escapeMarkup(post.title)}</strong> 628 <span>${escapeMarkup(blogSummary(post))}</span> 629 </span> 630 </a> 631 `; 632 } 633 634 function storyVideoDescription(title) { 635 const descriptions = new Map([ 636 ["Our Impact", "A closer look at how survivor care, housing, counseling, and advocacy move the mission forward."], 637 ["Raychelle's Story", "A survivor-centered story of safety, rebuilding, and the long-term care that makes healing possible."], 638 ["Every Person Matters", "A reminder that every survivor deserves dignity, protection, and a path toward freedom."], 639 ["Our Mission", "The heart of The Lifeboat Project's work: awareness, aftercare, and practical support for survivors."], 640 ["Our Proudest Moments", "Community moments, partnerships, and milestones from the work behind the mission."], 641 ["Unconditional Love", "A glimpse into the care philosophy that guides Lifeboat's survivor-centered programs."], 642 ["Signs Someone is Being Trafficked", "A quick awareness video to help people recognize warning signs and respond wisely."], 643 ]); 644 645 return descriptions.get(title) || "Watch this Lifeboat Project story."; 646 } 647 648 function renderMobileStoryVideoCard(video, index) { 649 return ` 650 <article class="ed-mobile-story-video-card">
651 <button type="button" data-ed-home-mission-play data-video-title="${escapeMarkup(video.title)}" aria-label="Play video: ${escapeMarkup(video.title)}"> 652 <img src="${escapeMarkup(video.image)}" alt="${escapeMarkup(video.title)} video preview" width="1280" height="720" loading="${index < 2 ? "eager" : "lazy"}" decoding="async"> 653 <span class="ed-mobile-story-play" aria-hidden="true"><span></span></span> 654 </button> 655 <div> 656 <p class="ed-mobile-kicker">Mission Video</p> 657 <h2>${escapeMarkup(video.title)}</h2> 658 <p>${escapeMarkup(storyVideoDescription(video.title))}</p> 659 </div> 660 </article> 661 `; 662 } 663 664 function shouldUseMobileFallback(key) { 665 const fallbackRoutes = new Set([ 666 "/about-4-1", 667 "/about-4", 668 "/about-5", 669 "/accessibility-statement", 670 "/advisory-board", 671 "/blog", 672 "/contact", 673 "/copy-of-bella", 674 "/copy-of-bella-1", 675 "/copy-of-bella-2", 676 "/copy-of-ed", 677 "/copy-of-eme", 678 "/copy-of-gary", 679 "/copy-of-gary-1", 680 "/copy-of-jamie", 681 "/copy-of-jeremy", 682 "/copy-of-jill-cohen", 683 "/copy-of-jonny", 684 "/copy-of-kathy", 685 "/copy-of-lifeboat-lifesavers", 686 "/copy-of-meet-the-team-1", 687 "/copy-of-nancy", 688 "/copy-of-piros", 689 "/copy-of-shannon", 690 "/donor-dock", 691 "/events", 692 "/financial-strategic-plan", 693 "/get-involved", 694 "/international-partnerships", 695 "/know-the-signs", 696 "/lifeboat-lifesavers", 697 "/making-waves", 698 "/meet-the-team", 699 "/partner-form", 700 "/privacy-policy", 701 "/projects-7", 702 "/publications", 703 "/request-a-speaker", 704 "/spot-it-stop-it", 705 "/sponsors", 706 "/stories", 707 "/team-4", 708 "/volunteer", 709 "/what-we-do", 710 "/who-we-are", 711 "/", 712 ]); 713 return fallbackRoutes.has(key) || key.startsWith("/team/") || key.startsWith("/post/"); 714 } 715 716 function mobileFallbackRoot(key) { 717 return document.querySelector("#PAGES_CONTAINER") || document.querySelector("#SITE_PAGES"); 718 } 719 720 function mobileFallbackTitle(key, root) { 721 const routeTitles = new Map([ 722 ["/about-4", "Know the Signs"], 723 ["/accessibility-statement", "Accessibility Statement"], 724 ["/advisory-board", "Advisory Board"], 725 ["/board-of-directors", "Board of Directors"], 726 ["/copy-of-meet-the-team", "Board of Directors"], 727 ["/donor-dock", "The Donor Dock"], 728 ["/financial-strategic-plan", "Financial & Strategic Plan"], 729 ["/international-partnerships", "International Partnerships"], 730 ["/know-the-signs", "Know the Signs"], 731 ["/making-waves", "Making Waves"], 732 ["/privacy-policy", "Privacy Policy"], 733 ["/projects-7", "Spot It. Stop It"], 734 ["/publications", "Financial & Strategic Plan"], 735 ["/spot-it-stop-it", "Spot It. Stop It"], 736 ]); 737 if (routeTitles.has(key)) return routeTitles.get(key); 738 const domHeading = clean(root?.querySelector("h1, h2, h3")?.textContent); 739 if (domHeading) return domHeading; 740 return clean(document.title.replace(/\s*\|\s*The Lifeboat Project\s*$/i, "")) || "The Lifeboat Project"; 741 } 742 743 function mobileFallbackBlocks(root, title) { 744 const skipExact = new Set([ 745 "", 746 "Home", 747 "Who We Are", 748 "Meet the Team", 749 "Board of Directors", 750 "What We Do", 751 "Know the Signs", 752 "Request Help", 753 "Get Involved", 754 "Sponsors", 755 "Events", 756 "Stories", 757 "Blog", 758 "Contact", 759 "Play Video", 760 "Read more", 761 "Read More", 762 "All Posts", 763 "Search", 764 "top of page", 765 ]); 766 const seen = new Set(); 767 const seenTexts = new Set(); 768 const blocks = []; 769 const isVisibleContent = (element) => { 770 if ( 771 element.closest( 772 ".ed-mobile-header, .ed-mobile-menu, .ed-mobile-footer, .ed-mobile-donor-footer, .ed-mobile-page, .ed-desktop-header, #SITE_HEADER, #SITE_FOOTER, nav, script, style", 773 ) 774 ) { 775 return false; 776 } 777 778 for (let current = element; current && current !== document; current = current.parentElement) { 779 if (!(current instanceof Element)) continue; 780 const style = getComputedStyle(current); 781 if ( 782 style.display === "none" || 783 style.visibility === "hidden" || 784 Number(style.opacity || "1") <= 0.01 785 ) { 786 return false;
787 } 788 } 789 790 return true; 791 }; 792 793 root 794 ?.querySelectorAll("h1, h2, h3, h4, h5, h6, p, li, dt, dd, figcaption, label, a, button, img[alt]") 795 .forEach((element) => { 796 if (!isVisibleContent(element)) return; 797 const tagName = element.tagName.toLowerCase(); 798 const isImage = tagName === "img"; 799 // Preserve editorial and profile-gallery photos in their original reading order. 800 if (isImage && ( 801 (rawPath.startsWith("/post/") && element.hasAttribute("data-pin-media")) || 802 (path === "/copy-of-jill-cohen" && element.hasAttribute("data-ed-jonny-image")) 803 )) { 804 const src = element.getAttribute("data-pin-media") || element.getAttribute("src"); 805 if (src && !seen.has(`image:${src}`)) { 806 seen.add(`image:${src}`); 807 blocks.push({ kind: "image", src, text: element.getAttribute("alt") || "" }); 808 } 809 return; 810 } 811 const text = clean(isImage ? element.getAttribute("alt") : element.innerText || element.textContent); 812 if (!text || skipExact.has(text)) return; 813 if (isImage && /\bportrait$/i.test(text)) return; 814 if (isImage && /\.(?:avif|gif|jpe?g|png|svg|webp)$/i.test(text)) return; 815 if (/bodyCacheable|ssrInfo|wixEmbedsAPI|^[{}[\],:\"0-9a-f-]{40,}$/i.test(text)) return; 816 if (text.length < 2) return; 817 const textKey = text.toLowerCase(); 818 if (tagName !== "a" && seenTexts.has(textKey)) return; 819 const key = `${tagName}:${text.toLowerCase()}:${tagName === "a" ? element.getAttribute("href") || "" : ""}`; 820 if (seen.has(key)) return; 821 if (tagName !== "a" && [...seen].some((seenKey) => { 822 const seenText = seenKey.split(":").slice(1).join(":"); 823 return text.length < 80 && seenText.includes(text.toLowerCase()); 824 })) { 825 return; 826 } 827 seen.add(key); 828 seenTexts.add(textKey); 829 const heading = /^h[1-6]$/.test(tagName); 830 const link = tagName === "a" ? element.getAttribute("href") || "" : ""; 831 const kind = heading ? "heading" : link ? "link" : "paragraph"; 832 blocks.push({ kind, text, href: link }); 833 }); 834 835 if (!blocks.some((block) => clean(block.text).toLowerCase() === clean(title).toLowerCase())) { 836 blocks.unshift({ kind: "heading", text: title, href: "" }); 837 } 838 839 return blocks.slice(0, 220); 840 } 841 842 function mobileVolunteerHeaderHtml() { 843 return ` 844 <section class="ed-mobile-get-involved-header ed-mobile-volunteer-header" aria-labelledby="ed-mobile-volunteer-title"> 845 <img src="${volunteerHeaderImage}" alt="Volunteer. Your time. Their hope. Together, we can make a difference." width="1774" height="887" loading="eager" fetchpriority="high"> 846 <div class="ed-screen-reader-only"> 847 <h1 id="ed-mobile-volunteer-title">Volunteer</h1> 848 <p>Your time. Their hope. Together, we can make a difference.</p> 849 </div> 850 </section> 851 `; 852 } 853 854 function volunteerProudestPoster() { 855 return storyThumbnailImages.get("Our Proudest Moments") || "/assets/updates/home-hero-first-frame.jpg"; 856 } 857 858 function volunteerBenefitCards() { 859 return [ 860 { 861 title: "Make a Tangible Impact", 862 body: 863 "Every hour you give helps move survivor support, prevention education, and community awareness forward in a practical way.", 864 }, 865 { 866 title: "Raise Awareness", 867 body: 868 "Help more neighbors recognize the realities of human trafficking and learn how to respond with care, accuracy, and courage.", 869 }, 870 { 871 title: "Be Part of Something Bigger", 872 body: 873 "Join a mission-driven team working for freedom, justice, and a future where exploitation does not get the final word.", 874 }, 875 { 876 title: "Personal Growth", 877 body: 878 "Build meaningful skills, deepen your understanding of trauma-informed support, and serve alongside people who care deeply.", 879 }, 880 ]; 881 } 882 883 function volunteerPageContentHtml() { 884 const poster = volunteerProudestPoster(); 885 const benefitCards = volunteerBenefitCards(); 886 const steps = [ 887 { 888 title: "Tell us you're interested", 889 body: 890 "Use the Volunteer Today form to share your contact information, availability, and how you would like to help.", 891 }, 892 { 893 title: "Complete onboarding", 894 body: 895 "Volunteers attend a one-day training session, submit personal references, and agree to a background check.", 896 }, 897 { 898 title: "Serve with support", 899 body: 900 "Our team helps match your time and strengths to survivor-centered support, awareness work, and community needs.", 901 }, 902 ]; 903 904 return ` 905 <div class="ed-volunteer-shell"> 906 <div class="ed-volunteer-intro" aria-labelledby="ed-volunteer-mission-title"> 907 <div class="ed-volunteer-intro-copy"> 908 <p class="ed-volunteer-kicker">Join Our Mission</p> 909 <h2 id="ed-volunteer-mission-title">Your time can become someone else's next step toward freedom.</h2> 910 <p>At The Lifeboat Project, our mission to end human trafficking and support survivors is only made possible through the incredible support of passionate individuals like you.</p> 911 <p>Volunteers are the heart of our work. Whether you're helping raise awareness, educating others, or standing beside survivor-centered programs, your involvement helps turn hope into action.</p> 912 <div class="ed-volunteer-actions"> 913 <a href="#ed-volunteer-start">How to Volunteer</a> 914 <a href="${volunteerApplyFormUrl}" target="_blank" rel="noopener noreferrer">Volunteer Today</a> 915 </div> 916 </div> 917 <aside class="ed-volunteer-mission-card" aria-labelledby="ed-volunteer-change-title"> 918 <p class="ed-volunteer-kicker">Change the World</p> 919 <h3 id="ed-volunteer-change-title">Show up where hope is needed most.</h3> 920 <p>
920By joining our team, you are becoming part of a movement that fights for freedom, justice, and a future free from exploitation.</p> 921 <ul> 922 <li>Support survivor-centered healing</li> 923 <li>Help educate and equip the community</li> 924 <li>Bring steady compassion to difficult work</li> 925 </ul> 926 </aside> 927 </div> 928 929 <div class="ed-volunteer-impact" aria-labelledby="ed-volunteer-impact-title"> 930 <div class="ed-volunteer-section-heading"> 931 <p class="ed-volunteer-kicker">Why Volunteer With Us?</p> 932 <h2 id="ed-volunteer-impact-title">Every role helps move someone closer to safety.</h2> 933 </div> 934 <div class="ed-volunteer-impact-grid"> 935 ${benefitCards 936 .map( 937 (card, index) => ` 938 <article> 939 <span>${String(index + 1).padStart(2, "0")}</span> 940 <h3>${escapeMarkup(card.title)}</h3> 941 <p>${escapeMarkup(card.body)}</p> 942 </article> 943 `, 944 ) 945 .join("")} 946 </div> 947 </div> 948 949 <div class="ed-volunteer-video-band" aria-labelledby="ed-volunteer-video-title"> 950 <div class="ed-volunteer-video-copy"> 951 <p class="ed-volunteer-kicker">Our Proudest Moments</p> 952 <h2 id="ed-volunteer-video-title">See the mission in motion.</h2> 953 <p>Watch a glimpse of the community, care, and persistence behind the work. This is what volunteer energy helps make possible.</p> 954 <button type="button" data-ed-home-mission-play data-vi
954deo-title="Our Proudest Moments"> 955 <span class="ed-volunteer-play-dot" aria-hidden="true"></span> 956 <span>Play Video</span> 957 </button> 958 </div> 959 <button class="ed-volunteer-video-preview" type="button" data-ed-home-mission-play data-video-title="Our Proudest Moments" aria-label="Play video: Our Proudest Moments"> 960 <img src="${escapeMarkup(poster)}" alt="Our Proudest Moments video preview" width="1280" height="720" loading="lazy" decoding="async"> 961 <span aria-hidden="true"><span></span></span> 962 </button> 963 </div> 964 965 <div class="ed-volunteer-start" id="ed-volunteer-start" aria-labelledby="ed-volunteer-start-title"> 966 <div class="ed-volunteer-section-heading"> 967 <p class="ed-volunteer-kicker">How to Volunteer</p> 968 <h2 id="ed-volunteer-start-title">A simple path into meaningful action.</h2> 969 </div> 970 <ol class="ed-volunteer-steps"> 971 ${steps 972 .map( 973 (step, index) => ` 974 <li> 975 <span>${index + 1}</span> 976 <h3>${escapeMarkup(step.title)}</h3> 977 <p>${escapeMarkup(step.body)}</p> 978 </li> 979 `, 980 ) 981 .join("")} 982 </ol> 983 <div class="ed-volunteer-requirements"> 984 <h3>What You’ll Need to Get Started:</h3> 985 <p>All volunteers must attend a one-day training session, submit personal references, and agree to a background check. Our training ensures you have the knowledge and tools to help survivors effectively and sensitively, and to understand the complexities of human trafficking.</p> 986 </div> 987 </div> 988 989 <div class="ed-volunteer-final-cta" aria-labelledby="ed-volunteer-final-title"> 990 <p class="ed-volunteer-kicker">Ready to Make a Difference?</p> 991 <h2 id="ed-volunteer-final-title">Becoming a volunteer means becoming part of a movement that will change lives.</h2> 992 <p>We're looking for dedicated, compassionate individuals who want to take meaningful action. Are you ready to take the first step?</p> 993 <a href="${volunteerApplyFormUrl}" target="_blank" rel="noopener noreferrer">Volunteer Today</a> 994 </div> 995 </div> 996 `; 997 } 998 999 function volunteerMobileExperienceHtml() { 1000 const benefitCards = volunteerBenefitCards(); 1001 1002 return ` 1003 <section class="ed-mobile-hero compact ed-mobile-volunteer-intro"> 1004 <p class="ed-mobile-kicker">Join Our Mission</p> 1005 <h1>Your time can become someone else's next step toward freedom.</h1> 1006 <p>At The Lifeboat Project, our mission to end human trafficking and support survivors is only made possible through the incredible support of passionate individuals like you.</p> 1007 <p>Volunteers are the heart of our work. Whether you're helping raise awareness, educating others, or standing beside survivor-centered programs, your involvement helps turn hope into action.</p> 1008 <div class="ed-mobile-actions"> 1009 <a href="#ed-mobile-volunteer-start">How to Volunteer</a> 1010 <a href="${volunteerApplyFormUrl}" target="_blank" rel="noopener noreferrer">Volunteer Today</a> 1011 </div> 1012 </section> 1013 1014 <section class="ed-mobile-article ed-mobile-volunteer-highlight" aria-label="Change the World"> 1015 <p class="ed-mobile-kicker">Change the World</p> 1016 <h2>Show up where hope is needed most.</h2> 1017 <p>By joining our team, you are becoming part of a movement that fights for freedom, justice, and a future free from exploitation.</p> 1018 <p>We're looking for dedicated, compassionate individuals who want to take meaningful action and bring hope where it is desperately needed.</p> 1019 <ul class="ed-mobile-volunteer-mini-list"> 1020 <li>Support survivor-centered healing</li> 1021 <li>Help educate and equip the community</li> 1022 <li>Bring steady compassion to difficult work</li> 1023 </ul> 1024 </section> 1025 1026 <section class="ed-mobile-volunteer-points" aria-label="Why volunteer with The Lifeboat Project"> 1027 <p class="ed-mobile-kicker">Why Volunteer With Us?</p> 1028 <h2>Every role helps move someone closer to safety.</h2>
1029 ${benefitCards 1030 .map( 1031 (card, index) => ` 1032 <article> 1033 <span>${String(index + 1).padStart(2, "0")}</span> 1034 <h3>${escapeMarkup(card.title)}</h3> 1035 <p>${escapeMarkup(card.body)}</p> 1036 </article> 1037 `, 1038 ) 1039 .join("")} 1040 </section> 1041 1042 ${mobileVideoFeatureHtml("Our Proudest Moments", { 1043 kicker: "Our Proudest Moments", 1044 eager: true, 1045 description: 1046 "Watch a glimpse of the community, care, and persistence behind the work volunteer energy helps make possible.", 1047 })} 1048 <section class="ed-mobile-article ed-mobile-volunteer-motion"> 1049 <h2>See the mission in motion.</h2> 1050 <p>Watch a glimpse of the community, care, and persistence behind the work. This is what volunteer energy helps make possible.</p> 1051 </section> 1052 1053 <section class="ed-mobile-article ed-mobile-volunteer-start" id="ed-mobile-volunteer-start" aria-label="How to Volunteer"> 1054 <p class="ed-mobile-kicker">How to Volunteer</p> 1055 <h2>A simple path into meaningful action.</h2> 1056 <ol class="ed-mobile-volunteer-steps"> 1057 <li><strong>1 Tell us you're interested</strong><span>Use the Volunteer Today form to share your contact information, availability, and how you would like to help.</span></li> 1058 <li><strong>2 Complete onboarding</strong><span>Volunteers attend a one-day training session, submit personal references, and agree to a background check.</span></li> 1059 <li><strong>3 Serve with support</strong><span>Our team helps match your time and strengths to survivor-centered support, awareness work, and community needs.</span></li> 1060 </ol> 1061 <h2>What You’ll Need to Get Started:</h2> 1062 <p>All volunteers must attend a one-day training session, submit personal references, and agree to a background check.</p> 1063 <p>Our training ensures you have the knowledge and tools to help survivors effectively and sensitively, and to understand the complexities of human trafficking.</p> 1064 </section> 1065 1066 <section class="ed-mobile-card ed-mobile-volunteer-cta" aria-label="Ready to Make a Difference"> 1067 <p class="ed-mobile-kicker">Ready to Make a Difference?</p> 1068 <h2>Becoming a volunteer means becoming part of a movement that will change lives.</h2> 1069 <p>Are you ready to take the first step?</p> 1070 <a href="${volunteerApplyFormUrl}" target="_blank" rel="noopener noreferrer">Volunteer Today</a> 1071 </section> 1072 `; 1073 } 1074 1075 function withMobileDesktopExtraction(callback) { 1076 const htmlHadMobile = document.documentElement.classList.contains("ed-mobile-shell-root"); 1077 const bodyHadMobile = document.body.classList.contains("ed-mobile-shell"); 1078 const mobilePage = document.querySelector(".ed-mobile-page"); 1079 const mobilePageDisplay = mobilePage?.style.display || ""; 1080 const hiddenByMobile = [...document.querySelectorAll(".ed-mobile-native-hidden")].map((element) => ({ 1081 element, 1082 ariaHidden: element.getAttribute("aria-hidden"), 1083 })); 1084 const forcedVisible = [ 1085 ...document.querySelectorAll( 1086 [ 1087 ".ed-blog-index", 1088 ".ed-team-update-section", 1089 ".ed-board-directors-page", 1090 ".ed-financial-page", 1091 ".ed-events-page", 1092 ".ed-sponsors-page", 1093 ".ed-lifesavers-page", 1094 ".ed-donor-page", 1095 ".ed-international-page", 1096 ".ed-know-page", 1097 ".ed-what-hero-section", 1098 ".ed-lifelong-care-section", 1099 ".ed-board-hero .ed-board-shell", 1100 ".ed-board-card", 1101 ".ed-board-card-bio", 1102 "[data-ed-email-update='what-we-do-believe-intro']", 1103 "[data-ed-email-update='shield-program']", 1104 ].join(", "), 1105 ), 1106 ].map((element) => ({ 1107 element, 1108 ariaHidden: element.getAttribute("aria-hidden"), 1109 style: element.getAttribute("style"), 1110 })); 1111 1112 document.documentElement.classList.remove("ed-mobile-shell-root"); 1113 document.body.classList.remove("ed-mobile-shell"); 1114 hiddenByMobile.forEach(({ element }) => { 1115 element.classList.remove("ed-mobile-native-hidden"); 1116 element.removeAttribute("aria-hidden"); 1117 }); 1118 forcedVisible.forEach(({ element }) => { 1119 element.removeAttribute("aria-hidden"); 1120 element.style.setProperty("display", "block", "important"); 1121 element.style.setProperty("height", "auto", "important"); 1122 element.style.setProperty("min-height", "0", "important"); 1123 element.style.setProperty("opacity", "1", "important"); 1124 element.style.setProperty("visibility", "visible", "important"); 1125 }); 1126 if (mobilePage) mobilePage.style.display = "none"; 1127 1128 try { 1129 return callback(); 1130 } finally { 1131 if (mobilePage) mobilePage.style.display = mobilePageDisplay; 1132 forcedVisible.forEach(({ element, ariaHidden, style }) => { 1133 if (style === null) element.removeAttribute("style"); 1134 else element.setAttribute("style", style); 1135 if (ariaHidden === null) element.removeAttribute("aria-hidden"); 1136 else element.setAttribute("aria-hidden", ariaHidden); 1137 }); 1138 hiddenByMobile.forEach(({ element, ariaHidden }) => { 1139 element.classList.add("ed-mobile-native-hidden"); 1140 if (ariaHidden === null) element.removeAttribute("aria-hidden"); 1141 else element.setAttribute("aria-hidden", ariaHidden); 1142 }); 1143 document.documentElement.classList.toggle("ed-mobile-shell-root", htmlHadMobile); 1144 document.body.classList.toggle("ed-mobile-shell", bodyHadMobile); 1145 } 1146 } 1147 1148 function mobileParityHtmlFromBlocks(blocks, title) { 1149 return ` 1150 <section class="ed-mobile-article ed-mobile-parity-content" aria-label="${escapeMarkup(title)}"> 1151 ${blocks 1152 .map((block) => { 1153 if (block.kind === "image") return `<figure class="ed-mobile-post-photo"><img src="${escapeMarkup(block.src)}" alt="${escapeMarkup(block.text)}" loading="lazy" decoding="async"></figure>`; 1154 if (block.kind === "heading") return `<h2>${escapeMarkup(block.text)}</h2>`; 1155 if (block.kind === "link" && block.href) { 1156 return `<p><a class="ed-mobile-inline-link" href="${escapeMarkup(block.href)}">${escapeMarkup(block.text)}</a></p>`; 1157 } 1158 return `<p>${escapeMarkup(block.text)}</p>`; 1159 }) 1160 .join("")} 1161 </section> 1162 `; 1163 } 1164 1165 const mobileTeamProfiles = [ 1166 { 1167 name: "Jill Bolander Cohen", 1168 role: "Founder & CEO", 1169 href: "/team/jill-bolander-cohen/", 1170 image: "/assets/captured/c5f78ac048be0217.jpg", 1171 routes: ["/team/jill-bolander-cohen", "/about-5"], 1172 }, 1173 { 1174 name: "Tina Sopp", 1175 role: "Chief Operating Officer", 1176 href: "/team/tina-sopp/", 1177 image: "/assets/updates/tina-sopp.jpg", 1178 routes: ["/team/tina-sopp"], 1179 objectPosition: "50% 18%", 1180 }, 1181 { 1182 name: "Jonny", 1183 role: "Director of Maintenance", 1184 href: "/team/jonny/", 1185 image: "/assets/captured/13491f9c8c8da178.jpeg", 1186 routes: ["/team/jonny", "/copy-of-jill-cohen"], 1187 }, 1188 { 1189 name: "Eme", 1190 role: "Grant Compliance Manager", 1191 href: "/team/eme/", 1192 image: "/assets/updates/team/eme.jpg", 1193 routes: ["/team/eme", "/copy-of-bella"], 1194 }, 1195 { 1196 name: "MaryAnne", 1197 role: "Office Administrator", 1198 href: "/team/maryanne/",
1199 image: "/assets/captured/d87cb8764556bb2e.jpg", 1200 routes: ["/team/maryanne", "/copy-of-kathy"], 1201 }, 1202 { 1203 name: "Kathy Pierson", 1204 role: "Public Relations", 1205 href: "/team/kathy-pierson/", 1206 image: "/assets/captured/5ce3b9adf7603a29.jpg", 1207 routes: ["/team/kathy-pierson", "/copy-of-jamie"], 1208 }, 1209 { 1210 name: "Ed Gilbert", 1211 role: "Chief Strategy Officer", 1212 href: "/team/ed-gilbert/", 1213 image: "/assets/captured/80409f65c3f6ecdc.jpeg", 1214 routes: ["/team/ed-gilbert", "/copy-of-bella-1"], 1215 }, 1216 { 1217 name: "Kristen Jensen", 1218 role: "Program Director", 1219 href: "/team/kristen-jensen/", 1220 image: "/assets/captured/926d3ddd00beedf5.jpg", 1221 routes: ["/team/kristen-jensen", "/team/kristen", "/copy-of-piros"], 1222 }, 1223 { 1224 name: "Nancy", 1225 role: "Senior Case Manager", 1226 href: "/team/nancy/", 1227 image: "/assets/captured/0c3cc7932809d7cd.jpg", 1228 routes: ["/team/nancy", "/copy-of-eme"], 1229 }, 1230 { 1231 name: "Jamie Holmes", 1232 role: "Social Media & Video Content Creator", 1233 href: "/team/jamie-holmes/", 1234 image: "/assets/captured/f6c2fb93aaa14226.jpeg", 1235 routes: ["/team/jamie-holmes", "/copy-of-nancy"], 1236 }, 1237 { 1238 name: "Piros Pazaurek", 1239 role: "Community Outreach & International Affairs", 1240 href: "/team/piros-pazaurek/", 1241 image: "/assets/captured/cb1f2549c4b8fc68.jpeg", 1242 routes: ["/team/piros-pazaurek", "/copy-of-ed"], 1243 }, 1244 { 1245 name: "Bella", 1246 role: "The Lifeboat Project Team", 1247 href: "/team/bella/", 1248 image: "https://static.wixstatic.com/media/20fea4_0fc7c0c6bd8d40bcbb1f6f4bbf915790~mv2.jpg/v1/fill/w_422,h_414,al_c,q_80,usm_0.66_1.00_0.01,enc_avif,quality_auto/20fea4_0fc7c0c6bd8d40bcbb1f6f4bbf915790~mv2.jpg", 1249 routes: ["/team/bella", "/copy-of-jonny"], 1250 showOnTeamIndex: false, 1251 }, 1252 { 1253 name: "Shannon Fraser", 1254 role: "The Lifeboat Project Team", 1255 href: "/team/shannon-fraser/", 1256 image: "https://static.wixstatic.com/media/20fea4_59902c4ddb21424da626c94ea3c4b822~mv2.jpg/v1/fill/w_422,h_637,al_c,q_80,usm_0.66_1.00_0.01,enc_avif,quality_auto/20fea4_59902c4ddb21424da626c94ea3c4b822~mv2.jpg", 1257 routes: ["/team/shannon-fraser", "/copy-of-bella-2"], 1258 showOnTeamIndex: false, 1259 }, 1260 { 1261 name: "Gary Cohen", 1262 role: "Co-Founder & Treasurer", 1263 href: "/team/gary-cohen/", 1264 image: "https://static.wixstatic.com/media/20fea4_f94ff1efa6b44f40895696577bb1c0e5~mv2.jpg/v1/fill/w_422,h_538,al_c,q_80,usm_0.66_1.00_0.01,enc_avif,quality_auto/20fea4_f94ff1efa6b44f40895696577bb1c0e5~mv2.jpg", 1265 routes: ["/team/gary-cohen", "/copy-of-shannon"], 1266 showOnTeamIndex: false, 1267 }, 1268 { 1269 name: "Mark", 1270 role: "The Lifeboat Project Team", 1271 href: "/team/mark/", 1272 image: "https://static.wixstatic.com/media/20fea4_ee905b8be3e84688a3ca75889ef2f3eb~mv2.jpg/v1/fill/w_422,h_486,al_c,q_80,usm_0.66_1.00_0.01,enc_avif,quality_auto/20fea4_ee905b8be3e84688a3ca75889ef2f3eb~mv2.jpg", 1273 routes: ["/team/mark", "/copy-of-gary"], 1274 showOnTeamIndex: false, 1275 }, 1276 { 1277 name: "Jeremy Smith", 1278 role: "The Lifeboat Project Team", 1279 href: "/team/jeremy-smith/", 1280 image: "https://static.wixstatic.com/media/20fea4_0b033563b628488f8c36d72ab17162ba~mv2.jpg/v1/fill/w_422,h_649,al_c,q_80,usm_0.66_1.00_0.01,enc_avif,quality_auto/20fea4_0b033563b628488f8c36d72ab17162ba~mv2.jpg", 1281 routes: ["/team/jeremy-smith", "/copy-of-gary-1"], 1282 showOnTeamIndex: false, 1283 }, 1284 { 1285 name: "Linda Kennedy Martin", 1286 role: "The Lifeboat Project Team", 1287 href: "/team/linda-kennedy-martin/", 1288 image: lindaKennedyMartinPortrait, 1289 routes: ["/team/linda-kennedy-martin", "/copy-of-jeremy"], 1290 showOnTeamIndex: false, 1291 }, 1292 ]; 1293 1294 function mobileTeamProfileForRoute(key) { 1295 return mobileTeamProfiles.find((profile) => profile.routes.includes(key) || profile.routes.includes(path)); 1296 } 1297 1298 function mobileTeamImageStyle(profile) { 1299 return profile.objectPosition ? ` style="object-position: ${escapeMarkup(profile.objectPosition)}"` : ""; 1300 } 1301 1302 function renderMobileTeamCard(profile) { 1303 return ` 1304 <a class="ed-mobile-team-card" href="${escapeMarkup(profile.href)}" data-ed-team-name="${escapeMarkup(profile.name)}" data-ed-team-role="${escapeMarkup(profile.role)}"> 1305 <img src="${escapeMarkup(profile.image)}" alt="${escapeMarkup(`${profile.name} portrait`)}" width="422" height="320" loading="lazy" decoding="async"${mobileTeamImageStyle(profile)}
1305> 1306 <span class="ed-mobile-team-copy"> 1307 <span class="ed-mobile-team-role">${escapeMarkup(profile.role)}</span> 1308 <strong>${escapeMarkup(profile.name)}</strong> 1309 <em>Read more</em> 1310 </span> 1311 </a> 1312 `; 1313 } 1314 1315 function renderMobileTeamIndexHtml() { 1316 const team = mobileTeamProfiles.filter((profile) => profile.showOnTeamIndex !== false); 1317 return ` 1318 <section class="ed-mobile-hero compact"> 1319 <p class="ed-mobile-kicker">Meet the Team</p> 1320 <h1>The people behind The Lifeboat Project.</h1> 1321 <p>Tap a profile to read more about the team members supporting survivors and advancing the mission.</p> 1322 </section> 1323 <section class="ed-mobile-list ed-mobile-team-list" aria-label="Team profiles"> 1324 ${team.map((profile) => renderMobileTeamCard(profile)).join("")} 1325 </section> 1326 `; 1327 } 1328 1329 function escapeRegExp(value) { 1330 return String(value || "").replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); 1331 } 1332 1333 function mobileProfileAliases(profile) { 1334 const aliases = [profile.name]; 1335 if (profile.name === "Kristen Jensen") aliases.push("Kristen"); 1336 if (profile.name === "MaryAnne") aliases.push("Mary Anne"); 1337 if (profile.name === "Jamie Holmes") aliases.push("Jamie"); 1338 if (profile.name === "Piros Pazaurek") aliases.push("Piros"); 1339 return aliases; 1340 } 1341 1342 function profileMatchFromText(text) { 1343 const candidates = mobileTeamProfiles 1344 .filter((profile) => profile.showOnTeamIndex !== false) 1345 .flatMap((profile) => 1346 mobileProfileAliases(profile).map((alias) => ({ 1347 profile, 1348 alias, 1349 match: text.match(new RegExp(`\\b${escapeRegExp(alias)}\\b`, "i")), 1350 })), 1351 ) 1352 .filter((candidate) => candidate.match); 1353 1354 candidates.sort((a, b) => a.match.index - b.match.index || b.alias.length - a.alias.length); 1355 return candidates[0] || null; 1356 } 1357 1358 function mobileDesktopPeopleCards(selector) { 1359 return withMobileDesktopExtraction(() => { 1360 const cards = [...document.querySelectorAll(`${selector} .wixui-repeater__item`)]; 1361 const seen = new Set(); 1362 return cards 1363 .map((card) => { 1364 const text = clean(card.innerText || card.textContent).replace(/\bRead more\b/gi, "").trim(); 1365 const image = card.querySelector("img"); 1366 if (!text || !image) return null; 1367 1368 const match = profileMatchFromText(text); 1369 if (!match) return null; 1370 1371 const { profile, alias } = match; 1372 if (seen.has(profile.name)) return null; 1373 seen.add(profile.name); 1374 1375 const nameIndex = match.match.index; 1376 const role = clean(text.slice(0, nameIndex)) || profile.role; 1377 const bio = clean(text.slice(nameIndex + alias.length)) || ""; 1378 const imageSrc = image.currentSrc || image.getAttribute("src") || profile.image; 1379 1380 return { 1381 name: profile.name, 1382 role, 1383 href: profile.href, 1384 image: imageSrc || profile.image, 1385 bio, 1386 objectPosition: profile.objectPosition, 1387 }; 1388 }) 1389 .filter(Boolean); 1390 }); 1391 } 1392 1393 function renderMobilePersonCard(profile) { 1394 const bio = clean(profile.bio); 1395 const preview = bio.length > 230 ? `${bio.slice(0, 230).replace(/\s+\S*$/, "")}...` : bio; 1396 const details = bio.length > 230 1397 ? ` 1398 <details> 1399 <summary>Read full bio</summary> 1400 <p>${escapeMarkup(bio)}</p> 1401 </details> 1402 ` 1403 : ""; 1404 1405 return ` 1406 <article class="ed-mobile-person-card"> 1407 <img src="${escapeMarkup(profile.image)}" alt="${escapeMarkup(`${profile.name} portrait`)}" width="422" height="320" loading="lazy" decoding="async"${mobileTeamImageStyle(profile)}> 1408 <div> 1409 <p class="ed-mobile-person-role">${escapeMarkup(profile.role)}</p> 1410 <h2>${escapeMarkup(profile.name)}</h2> 1411 ${preview ? `<p>${escapeMarkup(preview)}</p>` : ""} 1412 ${details} 1413 <a href="${escapeMarkup(profile.href)}">View profile</a> 1414 </div> 1415 </article> 1416 `; 1417 } 1418 1419 function renderMobileAdvisoryBoardHtml() { 1420 return ` 1421 <section class="ed-mobile-lifesavers-page ed-mobile-advisory-board-page" aria-label="Advisory Board"> 1422 <section class="ed-mobile-lifesavers-board" aria-labelledby="ed-mobile-advisory-members-title"> 1423 <p class="ed-mobile-kicker">Members</p> 1424 <h1 id="ed-mobile-advisory-members-title">Advisory Board Members</h1> 1425 <p class="ed-mobile-advisory-board-note">Meet the people lending their experience, relationships, and stewardship to the organization.</p>
1426 <span class="ed-mobile-lifesavers-divider" aria-hidden="true"></span> 1427 <div class="ed-mobile-lifesavers-grid" aria-label="Advisory Board profiles"> 1428 ${advisoryBoardProfiles.map((profile, index) => advisoryBoardCardHtml(profile, index, { mobile: true })).join("")} 1429 </div> 1430 </section> 1431 </section> 1432 `; 1433 } 1434 1435 function mobileVideoFeatureHtml(title, options = {}) { 1436 const video = storyVideoLibrary.find((entry) => entry.title === title); 1437 const poster = video?.image || storyThumbnailImages.get(title) || "/assets/updates/home-hero-first-frame.jpg"; 1438 const loading = options.eager ? "eager" : "lazy"; 1439 const priority = options.eager ? ' fetchpriority="high"' : ""; 1440 const description = options.description 1441 ? `<p>${escapeMarkup(options.description)}</p>` 1442 : ""; 1443 1444 return ` 1445 <section class="ed-mobile-feature ed-mobile-video-feature ed-mobile-who-video"> 1446 <p class="ed-mobile-kicker">${escapeMarkup(options.kicker || "Video")}</p> 1447 <h2>${escapeMarkup(title)}</h2>
1448 <button type="button" data-ed-home-mission-play data-video-title="${escapeMarkup(title)}" aria-label="Play video: ${escapeMarkup(title)}"> 1449 <img src="${escapeMarkup(poster)}" alt="${escapeMarkup(title)} video preview" loading="${loading}" decoding="async"${priority}> 1450 <span class="ed-mobile-video-play" aria-hidden="true"><span></span></span> 1451 <em class="ed-mobile-video-play-label">Play Video</em> 1452 </button> 1453 ${description} 1454 </section> 1455 `; 1456 } 1457 1458 function renderMobileWhoWeAreHtml() { 1459 return ` 1460 ${mobileVideoFeatureHtml("Our Mission", { kicker: "Our Mission", eager: true })} 1461 <section class="ed-mobile-hero compact ed-mobile-who-intro"> 1462 <p class="ed-mobile-kicker">Who We Are</p> 1463 <h1>Who We Are</h1> 1464 <div class="ed-mobile-actions ed-mobile-who-read-more"> 1465 <a href="#ed-mobile-who-why">Read More</a> 1466 </div> 1467 </section> 1468 <section class="ed-mobile-article ed-mobile-who-mission" aria-label="The Lifeboat Project mission and vision"> 1469 <h2>The Mission</h2> 1470 <p>The mission of The Lifeboat Project is to raise awareness of the issue of human trafficking and to empower the lives of survivors through long-term aftercare, residential programs, trauma counseling, housing, personal development, and educational resources.</p> 1471 <h2>The Vision</h2> 1472 <p>The Lifeboat Project’s vision is to inspire and engage communities in a collaborative effort to battle human trafficking.</p> 1473 </section> 1474 <section class="ed-mobile-article ed-mobile-who-why-heading" id="ed-mobile-who-why" aria-label="Why it Matters"> 1475 <h2>Why it Matters</h2> 1476 </section> 1477 ${mobileVideoFeatureHtml("Raychelle's Story", { 1478 kicker: "Raychelle's Story", 1479 description: 1480 "The Lifeboat Project is more than an organization; it’s a lifeline for those like Raychelle and her daughter. By supporting The Lifeboat Project, you help provide survivors with the tools to heal, the strength to rebuild, and the courage to speak out. Every survivor deserves a chance at freedom, dignity, and a future filled with hope. Together, we can make sure that no one has to fight their battle alone.", 1481 })} 1482 <nav class="ed-mobile-actions ed-mobile-who-actions" aria-label="Related Who We Are links"> 1483 <a href="/what-we-do/">What We Do</a> 1484 <a href="${requestHelpUrl}" target="_blank" rel="noopener noreferrer">Request Help</a> 1485 <a href="/know-the-signs/">Know the Signs</a> 1486 </nav> 1487 `; 1488 } 1489 1490 function renderMobileProfilePhoto(profile) { 1491 if (!profile) return ""; 1492 return ` 1493 <figure class="ed-mobile-profile-photo"> 1494 <img src="${escapeMarkup(profile.image)}" alt="${escapeMarkup(`${profile.name} portrait`)}" loading="eager" decoding="async"${mobileTeamImageStyle(profile)}> 1495 <figcaption> 1496 <strong>${escapeMarkup(profile.name)}</strong> 1497 <span>${escapeMarkup(profile.role)}</span> 1498 </figcaption> 1499 </figure> 1500 `; 1501 } 1502 1503 function mobileKnowSignsPageHtml() { 1504 return ` 1505 <section class="ed-mobile-know-signs-header" aria-labelledby="ed-mobile-know-signs-title"> 1506 <img src="${knowTheSignsHeaderImage}" alt="Know the Signs. Awareness can save lives. Learn the signs. Make a difference." width="1717" height="916" loading="eager" fetchpriority="high"> 1507 <div class="ed-screen-reader-only"> 1508 <h1 id="ed-mobile-know-signs-title">Know the Signs</h1> 1509 <p>Awareness can save lives. Learn the signs. Make a difference.</p> 1510 </div> 1511 </section> 1512 <section class="ed-mobile-article ed-mobile-parity-content" aria-label="Understanding Human Trafficking"> 1513 <h2>Understanding Human Trafficking</h2> 1514 <p>Human trafficking is a form of exploitation that affects individuals across every community. Learning the facts and recognizing the signs is the first step toward meaningful action and support.</p> 1515 <h2>Key Facts That Matter</h2> 1516 <p>Clear facts help communities recognize risk and respond with care.</p> 1517 <p><strong>#3*</strong> Florida ranks #3 in the nation for human trafficking cases.</p> 1518 <p><strong>700K*</strong> cases of human trafficking in Florida in 2024.</p> 1519 <p><strong>77%*</strong> of Florida's human trafficking cases involved children.</p> 1520 <p><strong>12*</strong> average age a child enters human trafficking.</p> 1521 <p>* Sources: National Human Trafficking Hotline; USF/TIP Lab 2024 State Report; Florida DCF reporting.</p> 1522 <h2>What Human Trafficking Is</h2> 1523 <p>Human trafficking occurs when a person is forced, coerced, or manipulated into labor, services, or commercial sex. It can affect anyone regardless of age, gender, or background and often involves subtle control and exploitation rather than obvious restraints.</p> 1524 <p>Trafficking commonly involves <strong>force, fraud,</strong> or <strong>coercion.</strong></p> 1525 <h2>Need to report a concern?</h2> 1526 <p>If someone may be in danger, use trusted resources. If it is an emergency, call <strong>911</strong>.</p> 1527 <p><strong>Call:</strong> <a class="ed-mobile-inline-link" href="tel:18883737888">1-888-373-7888</a></p> 1528 <p><strong>Text:</strong> Text HELP or INFO to 233733</p> 1529 <p>National Human Trafficking Hotline resources: <a class="ed-mobile-inline-link" href="https://humantraffickinghotline.org/" target="_blank" rel="noopener noreferrer">humantraffickinghotline.org</a></p> 1530 <h2>How Trafficking Happens</h2> 1531 <p>Exploitation can take many forms. Click each to learn what it can look like.</p> 1532 <p><strong>Force:</strong> Physical violence, threats, intimidation, confinement, or threats against family members.</p> 1533 <p><strong>Fraud:</strong> False promises of jobs, housing, relationships, travel, stability, or opportunity.</p> 1534 <p><strong>Coercion:</strong> Emotional manipulation, debt, financial control, blackmail, immigration pressure, or fear of consequences.</p> 1535 <p><strong>Isolation:</strong> Separation from family, friends, documents, or support systems; being moved often, monitored online, or prevented from asking for help.</p> 1536 <p>Isolation Separation from family, friends, documents, or support systems.</p> 1537 <h2>Myths and Facts</h2> 1538 <p>Click a card to reveal the fact. Tap to reveal the fact; on mobile, each myth and fact is shown together for easier reading.</p> 1539 <p><strong>Myth:</strong> Trafficking only happens in other countries. <strong>Fact:</strong> Human trafficking happens in every state, including communities across Florida.</p> 1540 <p><strong>Myth:</strong> Victims can simply leave if they want to. <strong>Fact:</strong> Fear, threats, debt, manipulation, trauma, and lack of safe options can make leaving dangerous.</p> 1541 <p><strong>Myth:</strong> Trafficking always involves kidnapping. <strong>Fact:</strong> Many cases begin through relationships, job offers, housing promises, or online grooming.</p> 1542 <p><strong>Myth:</strong> Trafficking is easy to spot. <strong>Fact:</strong> It is often hidden in ordinary settings and may look like subtle control, fear, or isolation.</p> 1543 <h2>What You Can Do</h2> 1544 <p>Small actions taken wisely can protect someone and support long-term recovery.</p> 1545 <p><strong>Recognize:</strong> Learn common indicators of exploitation and take concerns seriously.</p> 1546 <p><strong>Respond:</strong> Prioritize safety and use trusted reporting resources.</p> 1547 <p><strong>Support:</strong> Donate, volunteer, or share vetted resources that help survivors access long-term care.</p> 1548 <h2>Resources</h2> 1549 <p>Explore trusted information and ways to learn more.</p> 1550 <p><a class="ed-mobile-inline-link" href="https://humantraffickinghotline.org/" target="_blank" rel="noopener noreferrer">National Hotline</a></p> 1551 <p><a class="ed-mobile-inline-link" href="https://www.justice.gov/humantrafficking" target="_blank" rel="noopener noreferrer">U.S. DOJ Resources</a></p> 1552 <p><a class="ed-mobile-inline-link" href="https://report.cybertip.org/" target="_blank" rel="noopener noreferrer">NCMEC CyberTipline (Report Exploitation)</a></p> 1553 </section> 1554 ${mobileKnowSignsContinuationHtml()} 1555 `; 1556 } 1557 1558 function mobileNativeFallbackHtml() {
1559 const key = rawPath.replace(/\/$/, "") || "/"; 1560 if (!shouldUseMobileFallback(key)) return ""; 1561 if (key === "/know-the-signs" || key === "/about-4") return mobileKnowSignsPageHtml(); 1562 1563 return withMobileDesktopExtraction(() => { 1564 const root = mobileFallbackRoot(key); 1565 if (!root) return ""; 1566 1567 const title = mobileFallbackTitle(key, root); 1568 const blocks = mobileFallbackBlocks(root, title); 1569 const profile = mobileTeamProfileForRoute(key); 1570 if (!blocks.length) return ""; 1571 1572 return ` 1573 ${key === "/know-the-signs" || key === "/about-4" ? ` 1574 <section class="ed-mobile-know-signs-header" aria-labelledby="ed-mobile-know-signs-title"> 1575 <img src="${knowTheSignsHeaderImage}" alt="Know the Signs. Awareness can save lives. Learn the signs. Make a difference." width="1717" height="916" loading="eager" fetchpriority="high"> 1576 <div class="ed-screen-reader-only"> 1577 <h1 id="ed-mobile-know-signs-title">Know the Signs</h1> 1578 <p>Awareness can save lives. Learn the signs. Make a difference.</p> 1579 </div> 1580 </section> 1581 ` : ""} 1582 ${key === "/volunteer" || key === "/about-4-1" ? mobileVolunteerHeaderHtml() : ""} 1583 ${renderMobileProfilePhoto(profile)}
1583 1584 ${key === "/request-a-speaker" ? `<section class="ed-mobile-article"><figure class="ed-mobile-post-photo"><img src="/assets/captured/a64c350ca655a41e.jpg" alt="Jill Bolander Cohen speaking at the Alfond Inn" loading="lazy"></figure></section>` : ""} 1585 ${key === "/making-waves" ? `<section class="ed-mobile-article"><figure class="ed-mobile-post-photo"><img src="/assets/captured/9a8758065191d318.png" alt="Making Waves Breakfast Benefit event announcement" loading="lazy"></figure></section>` : ""} 1586 ${mobileParityHtmlFromBlocks(blocks, title)} 1587 ${key === "/copy-of-meet-the-team" ? ` 1588 <section class="ed-mobile-article ed-mobile-parity-content" aria-label="Board legacy information"> 1589 <p>Our Board of Directors brings together a diverse group of leaders dedicated to ending human trafficking. With expertise spanning various fields, they provide strategic direction, governance, and oversight to ensure our mission’s success. Meet the committed individuals guiding our efforts to create a world free from exploitation. Email <a class="ed-mobile-inline-link" href="mailto:[email protected]">[email protected]</a> if you are interested in joining our team.</p> 1590 <h1>Executive Committee</h1> 1591 <p>Linda has over 42 years of experience in the financial sector, including 30 years in Retail Branch Management and 8 years in Branch Administration. She is VP and Banking Center Manager for the Medical District Banking Center in Central Florida and joined First Horizon Bank in 2008 through the acquisition of Old Florida National Bank. Linda serves on several community boards and is an alumna of Florida State University. She has two adult children and five grandchildren.</p> 1592 <p>Our team members are committed to empowering survivors and driving meaningful change in the fight against human trafficking.</p> 1593 <p>Join our Advisory Board and help develop The Lifeboat Project with your knowledge, passion, and enthusiasm for making a difference.</p> 1594 <p>Lifeboat Lifesavers</p> 1595 <p>A Lifeboat Lifesaver is a company or organization that donates time, services, or products to support our mission in aiding survivors.</p> 1596 <p>We're seeking dedicated individuals to join our mission to support human trafficking survivors and raise awareness.</p> 1597 </section> 1598 ` : ""} 1599 ${key === "/meet-the-team" || key === "/team-4" ? ` 1600 <section class="ed-mobile-article ed-mobile-parity-content" aria-label="Tina Sopp"> 1601 <h2>Tina Sopp</h2> 1602 <p>Chief Operating Officer</p> 1603 <p>Tina Sopp serves as Chief Operating Officer for The Lifeboat Project, supporting daily operations, team coordination, and the systems that help survivor-centered programs run with consistency and care.</p> 1604 </section> 1605 ` : ""} 1606 ${key === "/know-the-signs" || key === "/about-4" ? mobileKnowSignsContinuationHtml() : ""} 1607 `; 1608 }); 1609 } 1610 1611 function mobileKnowSignsContinuationHtml() { 1612 const videoTitle = "Signs Someone is Being Trafficked"; 1613 const poster = storyThumbnailImages.get(videoTitle) || "/assets/updates/home-hero-first-frame.jpg"; 1614 1615 return ` 1616 <section class="ed-mobile-feature ed-mobile-video-feature ed-mobile-know-video"> 1617 <p class="ed-mobile-kicker">Video</p> 1618 <h2>${escapeMarkup(videoTitle)}</h2>
1619 <button type="button" data-ed-home-mission-play data-video-title="${escapeMarkup(videoTitle)}" aria-label="Play video: ${escapeMarkup(videoTitle)}"> 1620 <img src="${escapeMarkup(poster)}" alt="${escapeMarkup(videoTitle)} video preview" loading="lazy"> 1621 <span><span></span></span> 1622 </button> 1623 <p>Watch this quick awareness video to learn warning signs that may indicate someone is being trafficked.</p> 1624 </section> 1625 <section class="ed-mobile-article ed-mobile-spot-campaign" aria-labelledby="ed-mobile-spot-campaign-title"> 1626 <h2 id="ed-mobile-spot-campaign-title">Spot it Stop it Campaign</h2> 1627 <p>The Spot It, Stop It campaign raises awareness about the signs of human trafficking through quick, impactful shorts. These videos are designed to help you recognize the red flags that may indicate someone is at risk.</p> 1628 <p>By learning what to look for, you can make a difference and take action. Every shared video, every informed individual, brings us one step closer to stopping trafficking in our communities.</p> 1629 <p>Together, we can spot the signs and stop the cycle.</p> 1630 <div class="ed-mobile-actions"> 1631 <a href="/spot-it-stop-it/">Watch Now</a> 1632 </div> 1633 </section> 1634 `; 1635 } 1636 1637 function mobileSpotItStopItPageHtml() { 1638 return ` 1639 <section class="ed-mobile-hero compact ed-mobile-spot-intro" aria-labelledby="ed-mobile-spot-title"> 1640 <p class="ed-mobile-kicker">Awareness Campaign</p> 1641 <h1 id="ed-mobile-spot-title">Spot It. Stop It</h1> 1642 <p>The Spot It, Stop It campaign is dedicated to educating the public on how to identify the signs of human trafficking. Through concise, informative shorts, we equip you with the knowledge to recognize subtle but critical red flags that could save a life.</p> 1643 <p>Together, we can create a safer world by raising awareness and taking action when it matters most. Stay alert, stay informed, and be the change in your community.</p> 1644 </section> 1645 <section class="ed-mobile-feature ed-mobile-spot-videos" aria-labelledby="ed-mobile-spot-videos-title"> 1646 <p class="ed-mobile-kicker">Campaign Shorts</p> 1647 <h2 id="ed-mobile-spot-videos-title">Spot It. Stop It videos</h2> 1648 <div class="ed-mobile-spot-video-grid" data-ed-mobile-spot-video-grid></div> 1649 </section> 1650 `; 1651 } 1652 1653 function mobileSpotVideoEntries() { 1654 const seen = new Set(); 1655 const entries = []; 1656 1657 document.querySelectorAll(".lifeboat-spot-video-root").forEach((root) => { 1658 const src = root.dataset.lifeboatSpotVideoSrc || ""; 1659 const image = root.querySelector(".lifeboat-spot-video-tile img"); 1660 const poster = image?.getAttribute("src") || image?.currentSrc || ""; 1661 if (!src || !poster || seen.has(src)) return; 1662 seen.add(src); 1663 entries.push({ 1664 src, 1665 poster, 1666 title: `Spot It. Stop It video ${entries.length + 1}`, 1667 }); 1668 }); 1669 1670 return entries; 1671 } 1672 1673 function renderMobileSpotVideoTile(video, index) { 1674 return ` 1675 <button class="ed-mobile-spot-video-card" type="button" data-ed-spot-video-src="${escapeMarkup(video.src)}" data-ed-spot-video-title="${escapeMarkup(video.title)}" aria-label="Play ${escapeMarkup(video.title)}"> 1676 <img src="${escapeMarkup(video.poster)}" alt="" width="394" height="693" loading="${index < 4 ? "eager" : "lazy"}" decoding="async"> 1677 <span class="ed-mobile-spot-video-play" aria-hidden="true"> 1678 <svg viewBox="0 0 58 58" focusable="false"> 1679 <circle cx="29" cy="29" r="26"></circle> 1680 <path d="M24 18v22l17-11z"></path> 1681 </svg> 1682 </span> 1683 </button> 1684 `; 1685 } 1686 1687 function mobileEventsPageHtml() { 1688 return ` 1689 <section class="ed-mobile-hero compact ed-mobile-events-hero"> 1690 <p class="ed-mobile-kicker">Events</p> 1691 <h1>Upcoming Events</h1> 1692 <p>Find the next Lifeboat fundraiser, volunteer day, or awareness event in one clear place.</p> 1693 </section> 1694 1695 <section class="ed-mobile-feature ed-mobile-event-feature ed-mobile-events-featured" id="featured-yacht-rock" aria-labelledby="ed-mobile-events-feature-title">
1696 <a class="ed-mobile-events-flyer" href="${yachtRockEventPath}" aria-label="View Yacht Rock Benefit Bash event details"> 1697 <img src="${yachtRockFlyerImage}" alt="6th Annual Yacht Rock Benefit Bash flyer" width="1536" height="864" loading="eager" decoding="async" fetchpriority="high"> 1698 </a> 1699 <div class="ed-mobile-events-feature-copy"> 1700 <p class="ed-mobile-kicker">Featured Event</p> 1701 <h2 id="ed-mobile-events-feature-title">6th Annual Yacht Rock Benefit Bash</h2> 1702 <p>Join us for dinner, music, and an evening supporting survivors of human trafficking.</p> 1703 <div class="ed-mobile-event-details" aria-label="Yacht Rock Benefit Bash details"> 1704 <p><span>Date</span><strong>October 17, 2026</strong></p> 1705 <p><span>Location</span><strong>Hilton Orlando Lake Buena Vista</strong></p> 1706 <p><span>Time</span><strong>5:30–9:30 PM Eastern</strong></p> 1707 </div> 1708 <div class="ed-mobile-event-actions"> 1709 <a href="${yachtRockEventPath}">View Event Details</a> 1710 <a href="https://calendar.google.com/calendar/render?action=TEMPLATE&text=6th%20Annual%20Yacht%20Rock%20Benefit%20Bash&dates=20261017T213000Z/20261018T013000Z&ctz=America%2FNew_York&details=Benefit%20bash%20supporting%20survivors%20of%20human%20trafficking%20%E2%80%94%20https%3A%2F%2Flifeboatproject.org%2Fyacht-rock-benefit-bash&location=Hilton%20Orlando%20Lake%20Buena%20Vista%2C%201751%20Hotel%20Plaza%20Blvd%2C%20Lake%20Buena%20Vista%2C%20FL%2032830" target="_blank" rel="noopener noreferrer">Add to Calendar</a> 1711 </div> 1712 </div> 1713 </section> 1714 1715 <section class="ed-mobile-events-list" aria-labelledby="ed-mobile-events-upcoming-title"> 1716 <div class="ed-mobile-article ed-mobile-events-heading"> 1717 <p class="ed-mobile-kicker">More Ways to Get Involved</p> 1718 <h2 id="ed-mobile-events-upcoming-title">A quick look at what is next.</h2> 1719 </div> 1720 <article class="ed-mobile-card ed-mobile-event-card"> 1721 <p class="ed-mobile-event-date-pill">Fall 2026</p> 1722 <span class="ed-mobile-event-status">Coming Soon</span> 1723 <h2>Fall Poker Tournament</h2> 1724 <p>Details are coming soon for a lively fundraising night with sponsorship, volunteer, and guest opportunities.</p> 1725 <a href="/contact/">Notify Me</a> 1726 </article> 1727 <article class="ed-mobile-card ed-mobile-event-card"> 1728 <p class="ed-mobile-event-date-pill">Winter 2026</p> 1729 <span class="ed-mobile-event-status">Volunteers Needed</span> 1730 <h2>Community Volunteer Day</h2> 1731 <p>Help with outreach, event preparation, guest support, and awareness efforts across Central Florida.</p> 1732 <a href="/volunteer">Volunteer</a> 1733 </article> 1734 <article class="ed-mobile-card ed-mobile-event-card"> 1735 <p class="ed-mobile-event-date-pill">TBD</p> 1736 <span class="ed-mobile-event-status">Educational</span> 1737 <h2>Lunch & Learn Sessions</h2> 1738 <p>Bring Lifeboat's prevention education to a workplace, civic group, school, or community organization.</p> 1739 <a href="/request-a-speaker/">Request a Speaker</a> 1740 </article> 1741 <article class="ed-mobile-card ed-mobile-event-card"> 1742 <p class="ed-mobile-event-date-pill">TBD</p> 1743 <span class="ed-mobile-event-status">Community</span> 1744 <h2>Community Partner Pop-Up</h2> 1745 <p>Invite Lifeboat into your venue or workplace for a focused awareness moment, resource table, or partner gathering.</p> 1746 <a href="/contact/">Start a Conversation</a> 1747 </article> 1748 </section> 1749 1750 <section class="ed-mobile-feature ed-mobile-events-contact"> 1751 <p class="ed-mobile-kicker">Questions?</p> 1752 <h2>Looking for sponsorship, volunteer, or event details?</h2> 1753 <p>Reach out and the Lifeboat team can point you to the right next step.</p> 1754 <a href="/contact/">Start a Conversation</a> 1755 </section> 1756 `; 1757 } 1758 1759 const currentSponsorLogos = [ 1760 { 1761 name: "Sutherlin Nissan Orlando", 1762 href: "https://orlandonissan.com", 1763 src: "/assets/sponsor-logos/orlando-nissan.png", 1764 width: 225, 1765 height: 225, 1766 }, 1767 { 1768 name: "iHeartMedia", 1769 href: "https://www.iheartmedia.com/", 1770 src: "/assets/sponsor-logos/iheartmedia.png", 1771 width: 300, 1772 height: 100, 1773 }, 1774 { 1775 name: "Delta Air Lines", 1776 href: "https://www.delta.com/", 1777 src: "/assets/sponsor-logos/delta-air-lines.png", 1778 width: 500, 1779 height: 77, 1780 }, 1781 { 1782 name: "AdventHealth", 1783 href: "https://www.adventhealth.com/", 1784 src: "/assets/sponsor-logos/adventhealth.png", 1785 width: 300, 1786 height: 167, 1787 }, 1788 {
1789 name: "Clear Channel Outdoor", 1790 href: "https://clearchanneloutdoor.com/", 1791 src: "/assets/sponsor-logos/clear-channel-outdoor.png", 1792 width: 150, 1793 height: 100, 1794 }, 1795 { 1796 name: "Audi North Orlando", 1797 href: "https://www.audinorthorlando.com/", 1798 src: "/assets/sponsor-logos/audi-north-orlando.jpeg", 1799 width: 300, 1800 height: 185, 1801 }, 1802 { 1803 name: "Park Jewelers", 1804 href: "https://www.parkjewelers.com/", 1805 src: "/assets/sponsor-logos/park-jewelers.png", 1806 width: 300, 1807 height: 136, 1808 }, 1809 { 1810 name: "Team Snow Domino's", 1811 href: "https://www.dominos.com/", 1812 src: "/assets/sponsor-logos/team-snow-domino-s.jpeg", 1813 width: 300, 1814 height: 145, 1815 footerAlt: "Team SNOW, Cindy and Rick Traenkner", 1816 }, 1817 { 1818 name: "Park Square Homes", 1819 href: "https://www.parksquarehomes.com/", 1820 src: "/assets/sponsor-logos/park-square-homes.png", 1821 width: 100, 1822 height: 100, 1823 }, 1824 { 1825 name: "Seminole County", 1826 href: "https://www.seminolecountyfl.gov/", 1827 src: "/assets/sponsor-logos/seminole-county-florida-s-natural-choice.png", 1828 width: 300, 1829 height: 118, 1830 }, 1831 { 1832 name: "HomeAid Orlando", 1833 href: "https://www.homeaidorlando.org/", 1834 src: "/assets/sponsor-logos/homeaid-orlando.png", 1835 width: 164, 1836 height: 160, 1837 }, 1838 { 1839 name: "Fifth Third Bank", 1840 href: "https://www.53.com/", 1841 src: "/assets/sponsor-logos/fifth-third-bank.jpg", 1842 width: 300, 1843 height: 123, 1844 }, 1845 { 1846 name: "City of Orlando", 1847 href: "https://www.orlando.gov/Home", 1848 src: "/assets/sponsor-logos/city-of-orlando.png", 1849 width: 300, 1850 height: 90, 1851 }, 1852 { 1853 name: "Seminole County Sheriff's Office Foundation", 1854 href: "https://www.seminolesheriff.org/foundation/", 1855 src: "/assets/sponsor-logos/seminole-county-sheriff-s-office-foundation.jpg", 1856 width: 720, 1857 height: 325, 1858 }, 1859 { 1860 name: "Fabulous Buses", 1861 href: "https://www.fabulousbuses.com/", 1862 src: "/assets/sponsor-logos/fabulous-buses.png", 1863 width: 300, 1864 height: 168, 1865 }, 1866 { 1867 name: "Greater Orlando Sports Commission", 1868 href: "https://greaterorlandosports.com/", 1869 src: "/assets/sponsor-logos/greater-orlando-sports-commission.png", 1870 width: 7328, 1871 height: 1684, 1872 }, 1873 { 1874 name: "Key Performance Hospitality Management",
1875 href: "https://www.keyperformancehospitality.com/", 1876 src: "/assets/sponsor-logos/key-performance-hospitality-management.png", 1877 width: 726, 1878 height: 80, 1879 }, 1880 { 1881 name: "JDA", 1882 href: "https://www.jdatransport.com/", 1883 src: "/assets/sponsor-logos/jda.png", 1884 width: 400, 1885 height: 400, 1886 }, 1887 { 1888 name: "Disney Springs Resort Area Hotels", 1889 href: "https://disneyspringshotels.com/", 1890 src: "/assets/sponsor-logos/disney-springs-resort-area-hotels.png", 1891 width: 280, 1892 height: 300, 1893 }, 1894 { 1895 name: "First Horizon", 1896 href: "https://www.firsthorizon.com/", 1897 src: "/assets/sponsor-logos/first-horizon.jpg", 1898 width: 2560, 1899 height: 597, 1900 }, 1901 { 1902 name: "Griffis Wealth Strategies", 1903 href: "https://www.raymondjames.com/", 1904 src: "/assets/sponsor-logos/griffis-wealth-strategies.png", 1905 width: 372, 1906 height: 136, 1907 }, 1908 { 1909 name: "Dr. Phillips Charities", 1910 href: "https://drphillips.org/", 1911 src: "/assets/sponsor-logos/dr-phillips-charities.jpeg", 1912 width: 720, 1913 height: 528, 1914 }, 1915 { 1916 name: "Central Florida Hotel and Lodging Association", 1917 href: "https://www.cfhla.org/", 1918 src: "/assets/sponsor-logos/central-florida-hotel-and-lodging-association.jpg", 1919 width: 1200, 1920 height: 1200, 1921 }, 1922 { 1923 name: "Visit Orlando", 1924 href: "https://www.visitorlando.com/", 1925 src: "/assets/sponsor-logos/visit-orlando.svg", 1926 width: 301, 1927 height: 53, 1928 }, 1929 { 1930 name: "St. Margaret Mary Catholic Church", 1931 href: "https://stmargaretmary.org/", 1932 src: "/assets/sponsor-logos/st-margaret-mary-catholic-church.png", 1933 width: 771, 1934 height: 382, 1935 }, 1936 { 1937 name: "Gatorland", 1938 href: "https://www.gatorland.com/", 1939 src: "/assets/sponsor-logos/gatorland.png", 1940 width: 525, 1941 height: 175, 1942 }, 1943 ]; 1944 1945 const donorDockFooterSponsorOverrides = new Map([ 1946 ["Delta Air Lines", { className: "is-wide" }], 1947 [ 1948 "Seminole County Sheriff's Office Foundation", 1949 { alt: "Seminole County Sheriff's Office Community Foundation" }, 1950 ], 1951 ["Greater Orlando Sports Commission", { className: "is-wide" }], 1952 ["Key Performance Hospitality Management", { className: "is-wide" }], 1953 ["JDA", { className: "is-small" }], 1954 ]); 1955 1956 const donorDockFooterSponsors = currentSponsorLogos.map((sponsor) => { 1957 const override = donorDockFooterSponsorOverrides.get(sponsor.name) || {}; 1958 return { 1959 ...sponsor, 1960 ...override, 1961 alt: override.alt || sponsor.alt || sponsor.footerAlt || sponsor.name, 1962 }; 1963 }); 1964 1965 function renderDonorDockFooterSponsorLinks({ duplicate = false } = {}) { 1966 return donorDockFooterSponsors 1967 .map((sponsor) => { 1968 const classAttribute = sponsor.className ? ` class="${escapeMarkup(sponsor.className)}"` : ""; 1969 const tabindexAttribute = duplicate ? ' tabindex="-1"' : ""; 1970 const alt = duplicate ? "" : sponsor.alt; 1971 return ` 1972 <a${tabindexAttribute}${classAttribute} href="${escapeMarkup(sponsor.href)}" target="_blank" rel="noopener noreferrer"> 1973 <img src="${escapeMarkup(sponsor.src)}" alt="${escapeMarkup(alt)}" width="${sponsor.width}" height="${sponsor.height}" loading="eager" decoding="async"> 1974 </a> 1975 `; 1976 }) 1977 .join(""); 1978 } 1979 1980 function mobileDonorDockFooterHtml() { 1981 return ` 1982 <section class="sponsors-thanks" aria-labelledby="ed-mobile-donor-footer-sponsors-title"> 1983 <h2 id="ed-mobile-donor-footer-sponsors-title">Thank you to our wonderful <span>sponsors.</span></h2> 1984 <div class="logo-strip" aria-label="Featured sponsor logos"> 1985 <div class="logo-track"> 1986 <div class="logo-set"> 1987 ${renderDonorDockFooterSponsorLinks()} 1988 </div> 1989 <div class="logo-set" aria-hidden="true"> 1990 ${renderDonorDockFooterSponsorLinks({ duplicate: true })} 1991 </div> 1992 </div> 1993 </div> 1994 </section> 1995 1996 <section class="newsletter" aria-labelledby="ed-mobile-donor-footer-newsletter-title"> 1997 <h2 id="ed-mobile-donor-footer-newsletter-title">
1997Subscribe to receive our newsletter.</h2> 1998 <form data-subscribe-form> 1999 <div class="newsletter-row"> 2000 <div class="field"> 2001 <label for="ed-mobile-donor-footer-email">Email *</label> 2002 <input id="ed-mobile-donor-footer-email" name="email" type="email" autocomplete="email" placeholder="e.g., [email protected]" required> 2003 </div> 2004 <button type="submit">Join Our Mailing List</button> 2005 </div> 2006 <label class="checkbox-row"> 2007 <input type="checkbox" name="subscribeConsent" required> 2008 <span>I want to subscribe to your mailing list.</span> 2009 </label> 2010 <p class="subscribe-status ed-subscribe-status" role="status" aria-live="polite"></p> 2011 </form> 2012 </section> 2013 2014 <footer class="footer"> 2015 <div class="footer-main"> 2016 <div> 2017 <h3>Need Help?</h3> 2018 <p>Call 911</p> 2019 <p>or</p> 2020 <ul> 2021 <li><a href="https://humantraffickinghotline.org/" target="_blank" rel="noopener noreferrer">National Human<br>Trafficking Hotline</a></li> 2022 <li><a href="tel:18883737888">1-888-373-7888 (U.S.)</a></li> 2023 <li>Text HELP or INFO to<br>233733</li> 2024 </ul> 2025 </div> 2026 2027 <div class="footer-center"> 2028 <p>P.O. Box 1083</p> 2029 <p>Apopka, FL 32704</p> 2030 <div class="footer-links footer-legal-link"> 2031 <a href="/privacy-policy/">Privacy Policy</a> 2032 </div> 2033 </div> 2034 2035 <div class="footer-contact"> 2036 <p><a href="tel:14073108905">407-310-8905</a></p> 2037 <p><a href="mailto:[email protected]">[email protected]</a></p> 2038 <div class="social-links" aria-label="Social links"> 2039 <a href="https://www.facebook.com/TheLifeboatProject/" target="_blank" rel="noopener noreferrer" aria-label="Facebook"><img src="/assets/captured/8b38b8aae4fce7df.png" alt="" width="20" height="20" decoding="async"></a> 2040 <a href="https://www.linkedin.com/company/the-lifeboat-project-inc" target="_blank" rel="noopener noreferrer" aria-label="LinkedIn"><img src="/assets/captured/088027c1ca6e599a.png" alt="" width="20" height="20" decoding="async"></a> 2041 <a href="https://www.youtube.com/@TheLifeboatProj/shorts" target="_blank" rel="noopener noreferrer" aria-label="YouTube"><img src="/assets/updates/social/youtube.svg" alt="" width="20" height="20" decoding="async"></a> 2042 <a href="https://www.instagram.com/thelifeboatproject/?hl=en" target="_blank" rel="noopener noreferrer" aria-label="Instagram"><img src="/assets/updates/social/instagram.svg" alt="" width="20" height="20" decoding="async"></a> 2043 </div> 2044 <div class="footer-links footer-legal-link"> 2045 <a href="/accessibility-statement/">Accessibility Statement</a> 2046 </div> 2047 </div> 2048 2049 <div class="candid-badge"> 2050 <a href="${candidProfileUrl}" target="_blank" rel="noopener noreferrer"> 2051 <img src="/assets/updates/candid-platinum-2026.svg" alt="Candid Platinum Seal of Transparency 2026" width="119" height="117" decoding="async"> 2052 </a> 2053 </div> 2054 </div> 2055 </footer> 2056 2057 <div class="copyright">© 2026 by <a href="http://topstorystudios.com" target="_blank" rel="noopener noreferrer">Top Story Studios</a>.</div> 2058 `; 2059 } 2060 2061 function ensureMobileDonorFooter({ native = false, hideSponsors = false } = {}) { 2062 document.querySelector(".ed-mobile-footer")?.remove(); 2063 2064 let donorFooter = document.querySelector(".ed-mobile-donor-footer"); 2065 if (!donorFooter) { 2066 donorFooter = document.createElement("div"); 2067 donorFooter.className = "ed-mobile-donor-footer"; 2068 donorFooter.dataset.edMobileDonorFooter = "true"; 2069 donorFooter.innerHTML = mobileDonorDockFooterHtml(); 2070 document.body.appendChild(donorFooter); 2071 } 2072 2073 document.body.classList.add("ed-shared-donor-footer-active"); 2074 donorFooter.classList.toggle("ed-mobile-donor-footer-native", native); 2075 donorFooter.classList.toggle("ed-mobile-donor-footer-hide-sponsors", hideSponsors); 2076 donorFooter.dataset.edMobileNativeFooter = native ? "true" : "false"; 2077 donorFooter.dataset.edMobileFooterSponsorsHidden = hideSponsors ? "true" : "false"; 2078 updateSubscribeMessage(); 2079 return donorFooter; 2080 } 2081 2082 function removeMobileDonorFooter() { 2083 document.querySelector(".ed-mobile-footer")?.remove(); 2084 document.querySelector(".ed-mobile-donor-footer")?.remove(); 2085 document.body.classList.remove("ed-shared-donor-footer-active"); 2086 } 2087 2088 const lifeboatLifesaversProfiles = [ 2089 { 2090 role: "Attorney and Counselor at Law, Baker Donelson", 2091 name: "Donald Christopher", 2092 image: "/assets/captured/f7fffe877893ddc5.jpg", 2093 alt: "Donald Christopher portrait", 2094 }, 2095 { 2096 role: "Member of the Advisory Board, Host of The Ted Show", 2097 name: "Ted Bogert", 2098 image: "/assets/captured/95ee98610d2a3492.jpeg", 2099 alt: "Ted Bogert portrait", 2100 }, 2101 { 2102 role: "Executive Director, City Serve Florida, Global Outreach Paula White Ministries", 2103 name: "Todd Lamphere", 2104 image: "/assets/captured/cb7f3a763c555865.jpg", 2105 alt: "Todd Lamphere portrait", 2106 }, 2107 { 2108 role: "Security Systems and Monitoring", 2109 name: "Consortyo Network & Security",
2110 image: "/assets/captured/74d9b0edbd54ae21.png", 2111 alt: "Consortyo Network & Security logo", 2112 }, 2113 ]; 2114 2115 const advisoryBoardMergedRosterProfiles = [ 2116 { 2117 role: "Member of the Advisory Board, CEO/Co-Founder at Cornerstone Strategic Alliance", 2118 name: "Deb Adkins", 2119 image: "/assets/captured/756454b74899dde3.jpg", 2120 alt: "Deb Adkins portrait", 2121 group: "2024 and 2025 Classes", 2122 bio: "Deb is a senior financial expert with experience across companies of all sizes, from startups to those with $1.5 billion in revenue. She has served as interim CFO, partner in a national firm, and owner of a forensic accounting firm, with deep expertise in financial strategy, ERP implementation, and fraud consulting.", 2123 }, 2124 { 2125 role: "Member of the Advisory Board, Business Development Manager, Austin Commercial", 2126 name: "Rob Allen", 2127 group: "2026 Class", 2128 bio: "Rob Allen supports Austin Commercial's Central Florida growth and client relationships. He brings more than two decades of construction and development experience with major regional clients across entertainment, healthcare, and commercial development.", 2129 }, 2130 { 2131 role: "Member of the Advisory Board, Government Affairs Advisor at Gray Robinson", 2132 name: "Kylee Anzueto", 2133 image: "/assets/captured/113cfbf738cf3686.jpg", 2134 alt: "Kylee Anzueto portrait", 2135 group: "2026 Class", 2136 bio: "Kylee Anzueto is a government affairs advisor specializing in policy and appropriations at the Florida Capitol and local levels. Based in Orlando, she offers strategic insights, summaries of state and local hearings, and tailored government affairs updates while strengthening relationships with elected officials across the state.", 2137 }, 2138 { 2139 role: "Member of the Advisory Board, Senior Vice President and Commercial Relationship Manager at One Florida Bank in Orlando", 2140 name: "Karim Arja", 2141 image: "/assets/captured/11e69580193ee206.jpg", 2142 alt: "Karim Arja portrait", 2143 group: "2026 Class", 2144 bio: "Karim Arja serves as Senior Vice President and Commercial Relationship Manager at One Florida Bank in Orlando. He brings financial leadership, community relationships, and business development experience to support mission-driven growth.", 2145 }, 2146 { 2147 role: "Member of the Advisory Board, President at Kenney Communications", 2148 name: "Barbara Kenney", 2149 group: "2026 Class", 2150 bio: "Barbara Kenney is President of Kenney Communications and has more than four decades of experience in tourism marketing, communications, and community engagement. Her leadership connects public, private, and nonprofit partners around causes that strengthen Central Florida.", 2151 }, 2152 { 2153 role: "Member of the Advisory Board, Licensed Marriage and Family Therapist", 2154 name: "Cherlette McCullough", 2155 group: "2024 and 2025 Classes", 2156 bio: "Cherlette McCullough is a licensed marriage and family therapist with extensive experience supporting individuals, couples, and families. She has shared mental health expertise through local and national media and brings a compassionate, trauma-informed perspective to survivor-centered work.", 2157 }, 2158 { 2159 role: "Member of the Advisory Board, Co-owner and President of The Darlings Productions", 2160 name: "Chelsea McLean", 2161 group: "Community Advisors", 2162 bio: "Chelsea McLean is co-owner and President of The Darlings Productions, an Orlando-based entertainment and production company. She brings creative leadership, event experience, and community connection to The Lifeboat Project's mission.", 2163 }, 2164 { 2165 role: "Member of the Advisory Board, Chief Sales Officer for Visit Orlando", 2166 name: "Lisa Messina", 2167 group: "2026 Class", 2168 bio: "Lisa Messina is Chief Sales Officer for Visit Orlando and has spent more than three decades leading sales, hospitality, and destination strategy. Her experience helps connect The Lifeboat Project with business, travel, and civic partners.", 2169 }, 2170 { 2171 role: "Member of the Advisory Board, CEO of Consortyo Networks and Security", 2172 name: "Atu Naseem", 2173 group: "2024 and 2025 Classes", 2174 bio: "Atu Naseem is a seasoned business owner and security leader. Through Consortyo Networks and Security, he brings practical expertise in systems, monitoring, and organizational resilience.", 2175 }, 2176 { 2177 role: "Member of the Advisory Board, Co-Founder at RYN File", 2178 name: "Ron Nation", 2179 group: "2024 and 2025 Classes", 2180 bio: "Ron Nation is co-founder of RYN File and has built a career solving complex client problems with practical technology. His work includes secure platforms, biometrics, and process improvements that help organizations move faster with confidence.", 2181 }, 2182 { 2183 role: "Member of the Advisory Board, Co-owner of The Darlings Productions", 2184 name: "Kari Ringer", 2185 image: "/assets/captured/70dbe4233f37c01e.jpg",
2186 alt: "Kari Ringer portrait", 2187 group: "2026 Class", 2188 bio: "Kari Ringer is co-owner of The Darlings Productions and brings performance, production, and booking experience to the Advisory Board. Her career spans live entertainment, event coordination, and creative community partnerships.", 2189 }, 2190 { 2191 role: "Member of the Advisory Board, Vice President of Sales and Marketing at Masterpiece Design Group", 2192 name: "Jannett Roberts", 2193 group: "2026 Class", 2194 bio: "Jannett Roberts serves as Vice President of Sales and Marketing at Masterpiece Design Group. She brings strategic sales, marketing, and relationship-building expertise that helps expand awareness and support for the mission.", 2195 }, 2196 { 2197 role: "Member of the Advisory Board, CEO of the Greater Orlando Sports Commission", 2198 name: "Jason Siegel", 2199 group: "2024 and 2025 Classes", 2200 bio: "Jason Siegel is CEO of the Greater Orlando Sports Commission. He brings regional leadership, partnership development, and major-event experience to help strengthen visibility, strategy, and community engagement.", 2201 }, 2202 { 2203 role: "Member of the Advisory Board, CPA at Schafer, Tschopp, Whitcomb, Mitchell, and Sheridan, LLP", 2204 name: "Thomas Tschopp", 2205 image: "/assets/captured/b7891a1f64980b8d.jpg", 2206 alt: "Thomas Tschopp portrait", 2207 group: "2024 and 2025 Classes", 2208 bio: "Thomas Tschopp is a CPA with Schafer, Tschopp, Whitcomb, Mitchell, and Sheridan, LLP. He brings financial oversight, accounting experience, and governance perspective to the Advisory Board.", 2209 }, 2210 { 2211 role: "Member of the Advisory Board, Director of Sales and Marketing at the International Drive District", 2212 name: "Norah White", 2213 group: "Community Advisors", 2214 bio: "Norah White serves as Director of Sales and Marketing at the International Drive District. She brings hospitality, tourism, and regional marketing expertise to support community education and outreach.", 2215 }, 2216 { 2217 role: "Member of the Advisory Board", 2218 name: "Beth Spinda", 2219 group: "2024 and 2025 Classes", 2220 }, 2221 { 2222 role: "Member of the Advisory Board", 2223 name: "Dave Green", 2224 group: "2024 and 2025 Classes", 2225 }, 2226 { 2227 role: "Member of the Advisory Board, Account Manager at Landreth Lighting", 2228 name: "Glyn Griffis", 2229 image: "/assets/captured/dc4e72c6303c7f29.jpg", 2230 alt: "Glyn Griffis portrait", 2231 group: "2024 and 2025 Classes", 2232 }, 2233 { 2234 role: "Member of the Advisory Board, Senior Director at Vaco", 2235 name: "Laura Arrowsmith", 2236 group: "2024 and 2025 Classes", 2237 bio: "Laura Arrowsmith is a Senior Director at Vaco by Highspring, a global professional services firm. Since 2016, she has specialized in business development and talent solutions for Central Florida companies, with a focus on accounting, finance, HR, operations, legal, hospitality, tech, and healthcare.", 2238 }, 2239 { 2240 role: "Member of the Advisory Board", 2241 name: "Lisa Feder", 2242 group: "2024 and 2025 Classes", 2243 }, 2244 { 2245 role: "Member of the Advisory Board", 2246 name: "Piros Pazaurek", 2247 group: "2024 and 2025 Classes", 2248 }, 2249 { 2250 role: "Member of the Advisory Board, Host of The Ted Show", 2251 name: "Ted Bogert", 2252 image: "/assets/captured/95ee98610d2a3492.jpeg", 2253 alt: "Ted Bogert portrait", 2254 group: "2024 and 2025 Classes", 2255 }, 2256 { 2257 role: "Member of the Advisory Board, Executive Director, City Serve Florida, Global Outreach Paula White Ministries", 2258 name: "Todd Lamphere", 2259 image: "/assets/captured/cb7f3a763c555865.jpg", 2260 alt: "Todd Lamphere portrait", 2261 group: "2024 and 2025 Classes", 2262 }, 2263 { 2264 role: "Member of the Advisory Board", 2265 name: "Wendy Gray", 2266 group: "2024 and 2025 Classes", 2267 }, 2268 { 2269 role: "Member of the Advisory Board", 2270 name: "Adam Dovi", 2271 group: "2026 Class", 2272 }, 2273 { 2274 role: "Member of the Advisory Board", 2275 name: "Mike Fisher", 2276 group: "2026 Class", 2277 }, 2278 { 2279 role: "Member of the Advisory Board, EmpowerHER Executive Coach", 2280 name: "Shaelyn Ingram", 2281 group: "2026 Class", 2282 }, 2283 { 2284 role: "Member of the Advisory Board, Lived Experience Advisor", 2285 name: "Raychelle Green", 2286 group: "Lived Experience", 2287 }, 2288 ]; 2289 2290 const advisoryBoardProfiles = [ 2291 { 2292 role: "Member of the Advisory Board, CEO/Co-Founder at Cornerstone Strategic Alliance", 2293 name: "Deb Adkins", 2294 image: "/assets/updates/advisory-board/deb-adkins.jpg", 2295 alt: "Deb Adkins portrait", 2296 bio: "Deb is a senior financial expert with experience across companies of all sizes, from startups to those with $1.5 billion in revenue. She has served as interim CFO, partner in a
2296national firm, and owner of a forensic accounting firm. Specializing in financial strategy, ERP implementation, and fraud consulting, she has helped numerous organizations navigate complex challenges.", 2297 }, 2298 { 2299 role: "Member of the Advisory Board, Business Development Manager, Austin Commercial", 2300 name: "Rob Allen", 2301 image: "/assets/updates/advisory-board/rob-allen.jpg", 2302 alt: "Rob Allen portrait", 2303 bio: "As the Business Development Manager for Austin Commercial, Rob Allen is responsible for growing the Central Florida market & maintaining existing clients. Allen has 21 years of hands-on construction and development experience in all facets in the industry, and a verifiable record of accomplishment for the successful completion of multimillion-dollar projects in Central Florida. The Central Florida office does between $150M-$200M revenue annually. Key clients he is responsible for are Disney, SeaWorld, Universal Studios, Tavistock, Lincoln Property Company, and Advent Health. Austin Industries is one of the nation’s largest, most diversified U.S.-based construction companies. With more than 6,000 employee-owners, Austin Industries provides nearly every type of civil, commercial and industrial
2303construction services through the expertise of our operating companies: Austin Bridge & Road, Austin Commercial and Austin Industrial. Allen has also had the pleasure of serving on the Board of Directors for the Downtown Orlando Partnership, ABC of Central Florida and is a past President of the Professional Construction Estimators Association.", 2304 }, 2305 { 2306 role: "Member of the Advisory Board, Government Affairs Advisor at Gray Robinson", 2307 name: "Kylee Anzueto", 2308 image: "/assets/updates/advisory-board/kylee-anzueto.jpg", 2309 alt: "Kylee Anzueto portrait", 2310 bio: "Kylee Anzueto is a skilled Government Affairs Advisor specializing in policy and appropriations at both the Florida Capitol and local levels. Based in Orlando, she offers clients strategic insights, detailed summaries of state and local hearings, and tailored government affairs updates and reports. Kylee works diligently to strengthen relationships with elected officials across the state and represents GrayRobinson at key board meetings. She also delivers educational briefings to select groups, including college students pursuing careers in the legislative field. Before joining GrayRobinson, Kylee contributed to the University of Central Florida’s Government and Community Relations team, where she aided in the oversight of student interns placed in the Florida Senate, House, and statewide lobbying firms during legislative sessions. She honed her expertise in Florida’s legislative processes through hands-on internships at various government levels. During her time with the Government Relations Department at Publix Super Market, Inc., Kylee focused on alcohol legislation and presented to the corporation’s CEO, president, and executive members on pharmacy benefit manager regulations. Her experience also includes advocating for infrastru
2310cture and transportation issues in Tallahassee as part of the City of Orlando’s Intergovernmental Relations Office. Additionally, she gained valuable insights into public policies and campaign data while providing clerical support and voter education at a nonprofit. Kylee’s early career included serving in constituent services for U.S. Senator Marco Rubio, where she developed her understanding of federal issues such as social security, immigration, and veterans’ affairs.", 2311 }, 2312 { 2313 role: "Member of the Advisory Board, Senior Vice President and Commercial Relationship Manager at One Florida Bank in Orlando", 2314 name: "Karim Arja", 2315 image: "/assets/updates/advisory-board/karim-arja.jpg", 2316 alt: "Karim Arja portrait", 2317 bio: "Karim Arja is Senior Vice President and Commercial Relationship Manager at One Florida Bank in Orlando. Karim is a trusted leader in the banking and corporate finance sectors with over 30 years of expertise in management accounting, treasury operations, and long term and working capital financing. Having served with industry-leading organizations such as Truist, Honeywell and Lockheed Martin where he held a top-secret security clearance, Karim has developed a reputation for strategic leadership, innovation, and commitment to community advancement. He holds an MBA and dual BS degrees in Accounting and Finance from the University of South Florida as well as previous Certified Financial Planner and Certified Treasury Professional designations. In his current role at One Florida Bank in Orlando, Karim is focused on business development and client consultation working closely with family offices, real estate developers, and commercial clients to provide comprehensive financial solutions using his broad experience and long-term success in providing over $1Billion in lending solutions. Previously, Karim has been instrumental in shaping company strategy and product offerings at two start up financial institutions, while also contributing project management skills for software implementations, marketing campaigns, and staff development. Karim is deeply committed to community involvement and volunteerism. A resident of Winter Park with his wife and two children, Karim’s current and previous roles include Downtown Orlando Partnership Board, Orlando Tech Community Executive Committee, Community Evaluator the Victory Cup Initiative, the City of Winter Park Utility Advisory Board, Florida Citrus Sports member, Outback/Reliaquest Bowl Committee, University of South Florida Alumni Association fundraising/event committee, Leadership Orlando, Winter Park High School fundraising, and youth sports coach for football, soccer, and baseball. He is thrilled to be a member of The Lifeboat Project’s Advisory Board of Directors.", 2318 }, 2319 { 2320 role: "Member of the Advisory Board, Senior Director at Vaco", 2321 name: "Laura Arrowsmith", 2322 image: "/assets/updates/advisory-board/laura-arrowsmith.png", 2323 alt: "Laura Arrowsmith portrait", 2324 bio: "Laura Arrowsmith is a Senior Director at Vaco by Highspring, a global professional services firm. Since 2016, she has specialized in business development and talent solutions for Central Florida companies, focusing on contract staffing and direct hire in accounting, finance, HR, and operations—particularly within the legal, hospitality, tech, and healthcare sectors. A proud UCF graduate, Laura is passionate about community involvement. Outside of work, she enjoys the beach, cooking, and spending time with her family and yorkie, Lina.", 2325 }, 2326 { 2327 role: "Member of the Advisory Board, Host of The Ted Show", 2328 name: "Ted Bogert", 2329 image: "/assets/updates/advisory-board/ted-bogert.jpeg", 2330 alt: "Ted Bogert portrait", 2331 bio: "For over 30 years, Ted has been assisting professionals, business owners and families find efficient ways to utilize their resources and protect their assets in the insurance, mortgage and real estate industries. Ted’s current role is Business Development Manager at LeaderOne. In 2017, Ted launched the eponymous podcast, The Ted Show! Community leaders, innovators, influencers, motivators, philanthropists and creators have all told their stories on Ted’s Show.", 2332 }, 2333 { 2334 role: "Member of the Advisory Board, President of Dovi Window Designs, Inc.", 2335 name: "Adam Dovi", 2336 image: "/assets/updates/advisory-board/adam-dovi.jpg", 2337 alt: "Adam Dovi portrait", 2338 bio: "Adam Dovi, President of Dovi Window Designs, Inc., was born in the Port Orange area and has grown up in the window and door industry. His father, Pete, started down the fenestration path over 33 years ago and made a point of teaching his son the industry as he grew. When Adam opened Dovi Windows in the spring of 2003, he was able to draw on the real-world experience and know-how that both he and his father had accumulated over the years. The main focus of the business is simple: quality, quality, quality. Every buyer knows that there are dozens of companies in the Daytona Beach area to choose from, but what separates Dovi Window Designs, Inc. from the rest is that they only use qual
2338ity products and always treat every house as if it were their own. Time and time again, this shows through on the final product. Adam serves Daytona Beach Rotary as President-Nominee and Special Projects Chair and is active in Tiger Bay of Volusia County. He is thrilled to serve on the Lifeboat Project’s Advisory Board of Directors.", 2339 }, 2340 { 2341 role: "Member of the Advisory Board, Account Manager Commercial Construction Division Waste Connections", 2342 name: "Lisa Feder", 2343 image: "/assets/updates/advisory-board/lisa-feder.jpeg", 2344 alt: "Lisa Feder portrait", 2345 bio: "Lisa Feder is an Account Manager with Waste Connections, an international leader in the garbage and recycling industry. Lisa has over a dozen years of experience in garbage, recycling, clean buildings and LEED compliance for commercial construction projects. She believes strongly in reducing our carbon footprint for the next generation and, using her seasoned expertise, advocates for her clients to achieve their goals. Lisa is a long-time Central Florida resident and has lead and supported multiple charitable organizations within the community for over 30 years. She has 3 grown children all of which were born and raised in Central Florida.", 2346 }, 2347 { 2348 role: "Member of the Advisory Board, Director of Security Investigations at Universal Orlando", 2349 name: "Mike Fisher", 2350 image: "/assets/updates/advisory-board/mike-fisher.jpg", 2351 alt: "Mike Fisher portrait", 2352 bio: "Mike has almost 4 decades of comprehensive experience in the Law Enforcement, Public Safety and Corporate Security fields. Mike currently holds the position of Director of Security Investigations for Universal Orlando, leading a team of Investigators and Analysts that work daily to protect guests, Team Members, company assets and the Universal brand. Prior to making Universal his home for the last 9 years, Mike spent a distinguished 30-year career at the Osceola County Sheriff’s Office where he retired in 2017 at the rank of Captain. During his time with the Osceola County Sheriff’s Office Mike spent time significant supervising and managing the agency’s Intelligence Unit and Criminal Investigations Teams where he directed major case investigations involving gangs, narcotics and violent crimes. Mike also established the agency’s current Tourism Policing Unit which focused on tourist related crimes. During that time the Tourism Policing Unit investigated and coordinated a successful prosecution of the agency’s first Human trafficking case in 2004, shortly after the state of Florida criminalized Human Trafficking. Mike has been a resident of Osceola County since 1980 and has established long term relationships in the community and currently serves as the Chairman of the Central Florida Boys and Girls Club, Osceola Branch Board. During his off time off, Mike loves spending time with his family and his 8 grandchildren keep him and his wife Rachel very busy.", 2353 }, 2354 { 2355 role: "Member of the Advisory Board, Director of Event and Catering at Rio Pinar Golf", 2356 name: "Wendy Gray", 2357 image: "/assets/updates/advisory-board/wendy-gray.jpg", 2358 alt: "Wendy Gray portrait", 2359 bio: "Wendy is the Director of Event and Catering at Rio Pinar Golf, overseeing all aspects of event delivery to ensure memorable experiences. With over 15 years of event management experience, she previously managed operations and events at Eola View. Wendy is skilled in event management, banquet operations, and guest satisfaction, having worked with clients like Bacardi, the Tiger Woods Gala, and UCF. Her focus on detail and quality ensures every event’s success. Wendy holds an Associate of Science degree from Berkley/Bay Path College.", 2360 }, 2361 { 2362 role: "Member of the Advisory Board, Survivor Advocate", 2363 name: "Raychelle Green", 2364 image: "/assets/updates/advisory-board/raychelle-green.png", 2365 alt: "Raychelle Green portrait", 2366 bio: "Raychelle Green is a proud member of the Lifeboat Project Advisory Board and survivor advocate.", 2367 }, 2368 { 2369 role: "Member of the Advisory Board, Branch Manager at Griffis Wealth Strategies", 2370 name: "Glyn Griffis", 2371 image: "/assets/updates/advisory-board/glyn-griffis.jpg", 2372 alt: "Glyn Griffis portrait", 2373 bio: "Glyn, a CERTIFIED FINANCIAL PLANNER™, helps clients with investment management, risk management, retirement planning, and financial goal-setting. He holds a Finance degree from the University of Florida and began his wealth management practice in 2000. Active in Central Florida, he’s involved in the Orlando CEO Leadership Forum, contributes to the Orlando Sentinel, and has held leadership roles with the Rotary Club of Windermere and United Way.", 2374 }, 2375 { 2376 role: "Member of the Advisory Board, Mortgage Loan Originator at The Mortgage Firm", 2377 name: "Shaelyn Ingram", 2378 image: "/assets/updates/advisory-board/shaelyn-ingram.jpg", 2379 alt: "Shaelyn Ingram portrait", 2380 bio: "Shaelyn Ingram is a native of Central Florida, mother of 2 beautiful children, Mia and Jaxon, and is married to Paul Ingram. Shaelyn has spent her life in the service of her family first, community, and career. She has had a 25-year career in Finance, has led the Accounting and Finance Women’s alliance for the last 5 years as President and is dedicated to helping her clients achieve home ownership and wealth growth through real estate investment. She is dedicated to lifting her community up, seeing her clients through this major milestone and raising a thriving family. Shaelyn is a graduate of the Athena NextGen Leadership community of Central Florida, a proud Rotarian in Winter Springs, FL, will serve on Council 101 for the Orlando Museum of Art starting July of this year, and has the honor of joining the advisory board of The Lifeboat Project in January 2026. She is committed to protecting children and families in her philanthropic work and moving the arts forward in Central Florida. Shaelyn has a special interest in advocating for and lifting women up in financial literacy, professional growth and real estate investing, this has been a key area of focus through her
2380career, and her passion has grown out of her own experiences of support from women leaders in the community.", 2381 }, 2382 { 2383 role: "Member of the Advisory Board, President at Kenney Communications", 2384 name: "Barbara Kenney", 2385 image: "/assets/updates/advisory-board/barbara-kenney.jpg", 2386 alt: "Barbara Kenney portrait", 2387 bio: "Barbara Kenney is the President and driving force behind Kenney Communications, a leading tourism marketing and media company based in Orlando. With a career spanning more than four decades, she has played a key role in connecting millions of visitors to Central Florida’s attractions, hospitality venues, and experiences through innovative print, digital, and distribution channels. As publisher of Enjoy Florida Magazine and leader of one of the region’s largest brochure distribution networks, Kenney has helped shape how tourism information is delivered across the area—including exclusive advertising and distribution services at Florida Turnpike service plazas. Her company’s work reaches visitors through hotels, visitor centers, and high-traffic travel locations throughout Central Florida. Kenney is also deeply involved in the tourism and hospitality community, serving in leadership roles with organizations such as the International Drive Chamber, Central Florida Hotel & Lodging Association, and Florida Attractions Association. She has received multiple industry honors, including the 2025 Rosie Award recognizing her contributions to the region’s tourism industry. In addition to her professional accomplishments, Barbara Kenney is known for her community involvement and philanthropic efforts, supporting local nonprofit organizations and initiatives throughout the Orlando area.", 2388 }, 2389 { 2390 role: "Member of the Advisory Board, Licensed Marriage & Family Therapist", 2391 name: "Cherlette McCullough", 2392 image: "/assets/updates/advisory-board/cherlette-mccullough.jpeg", 2393 alt: "Cherlette McCullough portrait", 2394 bio: "Cherlette McCullough is a highly respected marriage and family therapist with over 12 years of experience in the field. Known for her innovative approaches to addressing relationship challenges, she has shared her expertise at numerous professional conferences and media platforms, including WESH-2, ABC Action News 6, NPR radio, and TV One’s Fatal Attraction. Her work has helped illuminate the complexities of mental health and relationships, particularly in the context of today’s digital age. In addition to her therapy practice, Cherlette serves as the Vice President of the Mental Health Association of Central Florida, an organization that provides free, comprehensive care and support for individuals and families. She is also the author of W.I.N.K: What I Need to Know After the Breakup, a self-help book for those navigating relationship endings. Cherlette’s contributions to the mental health field have earned her several awards, including the Cheryl Laird Outstanding Mental Health Therapist Award (2019), the Women’s Achievement Award for Health and Wellness (2022), and the Business Women’s Leadership Award (2022). With her unique blend of empathy, humor, and real-world knowledge, Cherlette connects deeply with her clients and audiences, empowering individuals to strengthen their relationships with themselves and others. Through her leadership roles and ongoing commitment to mental health awareness, she continues to expand her impact and push the boundaries of traditional therapy in an increasingly digital world.", 2395 }, 2396 { 2397 role: "Member of the Advisory Board, Co-owner and President of The Darlings Productions", 2398 name: "Chelsea McLean", 2399 image: "/assets/updates/advisory-board/chelsea-mclean.jpg", 2400 alt: "Chelsea McLean portrait", 2401 bio: "Chelsea is a co-owner and president of The Darlings Productions, an entertainment booking company out of Orlando FL since 2015. Chelsea is thrilled to be a member of the Lifeboat Project’s Advisory Board. She hails from the Midwest, and has traveled the world working with various entertainment venues, cruise ships, touring companies and more. Much like her wardrobe, Chelsea likes to bring a little sparkle to the table and is honored to help the Lifeboat Project shine.", 2402 }, 2403 { 2404 role: "Member of the Advisory Board, Chief Sales Officer for Visit Orlando", 2405 name: "Lisa Messina", 2406 image: "/assets/updates/advisory-board/lisa-messina.jpeg", 2407 alt: "Lisa Messina portrait", 2408 bio: "Lisa Messina is the Chief Sales Officer for Visit Orlando. In her role Messina oversees several departments, including the meeting and convention sales and experience team, travel industry sales, membership, and supporting services. Messina’s impressive career spans three decades in leadership roles at several of the meetings and events industry’s leading organizations. Prior to joining Visit Orlando, Messina served as the chief sales officer for the Las Vegas Convention & Visitors Authority, which also owns and operates the Las Vegas Convention Center. Before her tenure at the Las Vegas Convention & Visitors Authority, Messina served as senior vice president of sales for Caesars Entertainment, leading revenue strategy for the meetings and conventions segment. Prior to Caesars, Messina held numerous sales leadership roles during her 16 years with Hilton Worldwide and served as the chief marketing officer for ConferenceDirect, a full-service global meetings solution company. Throughout her career, she has received a host of prestigious awards and served on key industry boards. In 2023, she was named one of MPI’s 50 Most Influential Meeting Professionals and was inducted into Smart Meetings Hall of Fame. Messina has also served on CVENT’s Advisory Board, HSMAI’s Advisory Board and the Executive Board of the American Heart Association Southern Nevada. Messina currently serves on the Meeting Professionals International (MPI), International Board of Directors. Messina holds a Bachelor of Science in Hotel Administration from Cornell University.", 2409 }, 2410 { 2411 role: "Member of the Advisory Board, CEO of Consortyo Networks & Security", 2412 name: "Atu Naseem", 2413 image: "/assets/updates/advisory-board/atu-naseem.jpg", 2414 alt: "Atu Naseem portrait", 2415 bio: "Seasoned business owner with a strong technical background and a passion for logical problem-solving. Demonstrated expertise in leading teams, managing operations, and driving business growth. Proven ability to understand and implement detailed processes to achieve organizational objectives.", 2416 }, 2417 { 2418 role: "Member of the Advisory Board, Co-Founder at RYN File", 2419 name: "Ron Nation", 2420 image: "/assets/updates/advisory-board/ron-nation.jpg", 2421 alt: "Ron Nation portrait", 2422 bio: "Ron has had a rewarding career solving his client’s problems using technology, and one of the problems solved was used to launch the RYN Platform, a Cloud-Based encryption service. In 2010 they developed and started using biometrics (fingerprints) to encrypt appraisal reports for our clients (financial institutions) to stop the identity theft of real estate appraisers used for loans.", 2423 }, 2424 { 2425 role: "Member of the Advisory Board, Co-owner of the Darlings Productions", 2426 name: "Kari Ringer", 2427 image: "/assets/updates/advisory-board/kari-ringer.jpg",
2428 alt: "Kari Ringer portrait", 2429 bio: "Kari Ringer is co-owner of The Darlings Productions booking agency and production house. She hails from Ohio and is pumped to be a member of the Lifeboat Project Advisory Board! Her musical theatre background has afforded her the opportunity to perform on Broadway, regional theatres, cruise ships, theme parks, and corporate functions across the globe. As a co-owner of The Darlings Productions booking agency and production house, life is about uplifting incredible talent to spread sunshine and smiles! She is looking forward to collaborating with the incredible Lifeboat colleagues, supporters, and survivors to bring awareness to this wonderful cause.", 2430 }, 2431 { 2432 role: "Member of the Advisory Board, Vice President of Sales and Marketing at Masterpiece Design Group", 2433 name: "Jannett Roberts", 2434 image: "/assets/updates/advisory-board/jannett-roberts.jpg", 2435 alt: "Jannett Roberts portrait", 2436 bio: "Jannett Roberts is the Vice President of Sales and Marketing for Masterpiece Design Group, where she leads strategic growth initiatives and oversees both the residential and commercial divisions. With more than 30 years of experience in sales and marketing in the Orlando and Winter Park markets, she is known for developing results-driven strategies that support revenue growth, strengthen partnerships, and elevate brand presence. Jannett works closely with builders, architects, and clients to ensure projects are executed seamlessly while maintaining the high standards that define the Masterpiece brand. After studying at Stetson University, Jannett began her career in finance, advising clients on investment portfolios and retirement planning. She later transitioned into publishing, serving as publisher of an international business art magazine that helped artists build successful entrepreneurial careers. Drawing on her combined experience in finance, publishing, and business development, she joined Masterpiece Design Group in 2018 and quickly became a key driver of the company’s continued growth. Outside of work, Jannett enjoys traveling, reading, and planning adventures with close friends. She values time with her children, Brooke and Landon, and her dogs, Finnegan and Cooper. She is also passionate about giving back and is committed to supporting initiatives that combat human trafficking in her community.", 2437 }, 2438 { 2439 role: "Member of the Advisory Board, CEO of The Greater Orlando Sports Commission", 2440 name: "Jason Siegel", 2441 image: "/assets/updates/advisory-board/jason-siegel.jpg", 2442 alt: "Jason Siegel portrait", 2443 bio: "Jason Siegel has enjoyed more than 30 years of success and accomplishments in sports tourism, major and minor league professional sports, as well as intercollegiate athletics. He is currently in his ninth year as President & Chief Executive Officer of the Greater Orlando Sports Commission (GO Sports!). Siegel currently serves on several local community Boards including the Board of Advisors at the UCF Rosen College of Hospitality Management, American Diabetes Association (past Community Chairman 2018 & 2019), Central Florida Hotel and Lodging Association, Scouting America – Central Florida Council, the Central Florida Commission on Homelessness, and has now joined The Lifeboat Project Advisory Board. In addition, he and his wife Sarah Grafton founded and host the annual Winter Park Fashion Week. Jason and Sarah, both passionate about service to their community, and supporters of the arts, reside in Maitland, FL, raising their four children, Stephanie (24), Ryder (16), Bobby (14), and Joseph (7).", 2444 }, 2445 { 2446 role: "Member of the Advisory Board, CPA at Schafer, Tschopp, Whitcomb, Mitchell, & Sheridan, LLP", 2447 name: "Thomas Tschopp", 2448 image: "/assets/updates/advisory-board/thomas-tschopp.jpg", 2449 alt: "Thomas Tschopp portrait", 2450 bio: "Tom, a University of Florida Accounting graduate, has 12 years of experience with an international accounting firm before founding his own in 1995. He specializes in audits, due diligence, and benchmarking, with expertise in nonprofit, construction, manufacturing, and agribusiness sectors. Tom is active in the Central Florida business community and involved in the American and Florida Institutes of Certified Public Accountants.", 2451 }, 2452 { 2453 role: "Member of the Advisory Board, Director of Sales and Marketing at the International Drive District", 2454 name: "Norah White", 2455 image: "/assets/updates/advisory-board/norah-white.jpg", 2456 alt: "Norah White portrait", 2457 bio: "Norah has been a dedicated leader in Central Florida’s hospital
2457ity industry since 1996. She currently serves as Director of Sales and Marketing for the International Drive District, where she has worked for 23 years, helping promote one of the region’s most visited tourism corridors while supporting initiatives focused on public safety and transportation for millions of guests. She serves on the Global Marketing Committee for Visit Orlando and the Government Affairs Board for the Central Florida Hotel & Lodging Association (CFHLA), and is the current President of SKAL International Orlando. Passionate about community impact, Norah is proud to serve on the board of The Lifeboat Project. She believes that if even one victim can be rescued from the horrors of human trafficking, the time and effort are worth it. In her time off, she is working toward a personal goal of visiting 50 countries by her 75th birthday…and is well on track.", 2458 }, 2459 ]; 2460 2461 function advisoryInitials(name) { 2462 return clean(name) 2463 .split(/\s+/) 2464 .filter(Boolean) 2465 .map((part) => part.charAt(0)) 2466 .join("") 2467 .slice(0, 2) 2468 .toUpperCase(); 2469 } 2470 2471 function advisoryPreview(text, maxLength) { 2472 const bio = clean(text); 2473 if (!bio || bio.length <= maxLength) return bio; 2474 return `${bio.slice(0, maxLength).replace(/\s+\S*$/, "")}...`; 2475 } 2476 2477 function advisoryBoardCardHtml(profile, index, options = {}) { 2478 const mobile = options.mobile === true; 2479 const bio = clean(profile.bio || ""); 2480 const maxLength = mobile ? 168 : 228; 2481 const preview = advisoryPreview(bio, maxLength); 2482 const readMore = bio.length > maxLength 2483 ? `<button class="ed-advisory-read-more" type="button" data-ed-advisory-index="${index}" aria-label="Read more about ${escapeMarkup(profile.name)}">Read more</button>` 2484 : ""; 2485 const role = clean(profile.role || "Member of the Advisory Board"); 2486 const group = clean(profile.group || ""); 2487 const photoClass = profile.image ? "" : " ed-advisory-initials-photo"; 2488 const loading = "eager"; 2489 const photo = profile.image 2490 ? `<img src="${escapeMarkup(profile.image)}" alt="${escapeMarkup(profile.alt || `${profile.name} portrait`)}" loading="${loading}" decoding="async">` 2491 : `<span class="ed-advisory-initials" aria-hidden="true">${escapeMarkup(advisoryInitials(profile.name))}</span>`; 2492 2493 if (mobile) { 2494 return ` 2495 <article class="ed-mobile-lifesavers-card ed-advisory-member-card${profile.image ? "" : " ed-advisory-no-photo"}"> 2496 <div class="ed-mobile-lifesavers-photo${photoClass}"> 2497 ${photo} 2498 </div> 2499 <p class="ed-advisory-card-role">${escapeMarkup(role)}</p> 2500 <h3>${escapeMarkup(profile.name)}</h3> 2501 ${preview ? `<p class="ed-advisory-card-bio">${escapeMarkup(preview)}</p>` : ""} 2502 ${readMore} 2503 </article> 2504 `; 2505 } 2506 2507 return ` 2508 <article class="ed-lifesavers-card ed-advisory-member-card${profile.image ? "" : " ed-advisory-no-photo"}"> 2509 <div class="ed-lifesavers-card-photo${photoClass}"> 2510 ${photo} 2511 </div> 2512 <div class="ed-lifesavers-card-copy"> 2513 <p class="ed-advisory-card-role">${escapeMarkup(role)}</p> 2514 <h3>${escapeMarkup(profile.name)}</h3> 2515 ${preview ? `<p class="ed-advisory-card-bio">${escapeMarkup(preview)}</p>` : ""} 2516 ${readMore} 2517 </div> 2518 </article> 2519 `; 2520 } 2521 2522 let advisoryBioHandlersInstalled = false; 2523 let advisoryBioModal = null; 2524 let advisoryBioLastTrigger = null; 2525 2526 function ensureAdvisoryBioModal() { 2527 if (advisoryBioModal?.isConnected) return advisoryBioModal; 2528 2529 advisoryBioModal = document.createElement("div"); 2530 advisoryBioModal.className = "ed-advisory-modal"; 2531 advisoryBioModal.hidden = true; 2532 advisoryBioModal.setAttribute("role", "dialog"); 2533 advisoryBioModal.setAttribute("aria-modal", "true"); 2534 advisoryBioModal.setAttribute("aria-labelledby", "ed-advisory-modal-title"); 2535 advisoryBioModal.innerHTML = ` 2536 <button class="ed-advisory-modal-backdrop" type="button" data-ed-advisory-modal-close aria-label="Close advisory profile"></button> 2537 <div class="ed-advisory-modal-panel" role="document"> 2538 <button class="ed-advisory-modal-close" type="button" data-ed-advisory-modal-close>Close</button> 2539 <div class="ed-advisory-modal-content" data-ed-advisory-modal-content></div> 2540 </div> 2541 `; 2542 document.body.appendChild(advisoryBioModal); 2543 return advisoryBioModal;
2544 } 2545 2546 function closeAdvisoryBioModal() { 2547 if (!advisoryBioModal) return; 2548 advisoryBioModal.hidden = true; 2549 document.body.classList.remove("ed-advisory-modal-open"); 2550 advisoryBioLastTrigger?.focus?.(); 2551 advisoryBioLastTrigger = null; 2552 } 2553 2554 function openAdvisoryBioModal(index, trigger) { 2555 const profile = advisoryBoardProfiles[Number(index)]; 2556 if (!profile) return; 2557 2558 const modal = ensureAdvisoryBioModal(); 2559 const content = modal.querySelector("[data-ed-advisory-modal-content]"); 2560 const role = clean(profile.role || "Member of the Advisory Board"); 2561 const bio = clean(profile.bio || ""); 2562 const photo = profile.image 2563 ? `<img src="${escapeMarkup(profile.image)}" alt="${escapeMarkup(profile.alt || `${profile.name} portrait`)}" loading="eager" decoding="async">` 2564 : `<span class="ed-advisory-initials" aria-hidden="true">${escapeMarkup(advisoryInitials(profile.name))}</span>`; 2565 2566 content.innerHTML = ` 2567 <div class="ed-advisory-modal-profile${profile.image ? "" : " ed-advisory-no-photo"}"> 2568 <div class="ed-advisory-modal-photo${profile.image ? "" : " ed-advisory-initials-photo"}"> 2569 ${photo} 2570 </div> 2571 <div class="ed-advisory-modal-copy"> 2572 <p>${escapeMarkup(role)}</p> 2573 <h2 id="ed-advisory-modal-title">${escapeMarkup(profile.name)}</h2> 2574 ${bio ? `<p class="ed-advisory-modal-bio">${escapeMarkup(bio)}</p>` : ""} 2575 </div> 2576 </div> 2577 `; 2578 2579 advisoryBioLastTrigger = trigger || null; 2580 modal.hidden = false; 2581 document.body.classList.add("ed-advisory-modal-open"); 2582 modal.querySelector(".ed-advisory-modal-close")?.focus?.(); 2583 } 2584 2585 function installAdvisoryBioHandlers() { 2586 if (advisoryBioHandlersInstalled) return; 2587 advisoryBioHandlersInstalled = true; 2588 2589 document.addEventListener("click", (event) => { 2590 const closeTrigger = event.target.closest?.("[data-ed-advisory-modal-close]"); 2591 if (closeTrigger) { 2592 closeAdvisoryBioModal(); 2593 return; 2594 } 2595 2596 const trigger = event.target.closest?.(".ed-advisory-member-card [data-ed-advisory-index]"); 2597 if (!trigger) return; 2598 event.preventDefault(); 2599 openAdvisoryBioModal(trigger.dataset.edAdvisoryIndex, trigger); 2600 }); 2601 2602 document.addEventListener("keydown", (event) => { 2603 if (event.key === "Escape" && advisoryBioModal && !advisoryBioModal.hidden) { 2604 closeAdvisoryBioModal(); 2605 } 2606 }); 2607 } 2608 2609 let advisoryChatObserver = null; 2610 2611 const advisoryChatSelectors = [ 2612 ".lifeboat-local-chat", 2613 "#pinnedBottomRight", 2614 ".pinnedBottomRight", 2615 'iframe[title*="Chat"]', 2616 'iframe[title*="chat"]', 2617 'iframe[src*="chat"]', 2618 '[data-testid*="Chat"]', 2619 '[data-testid*="chat"]', 2620 '[aria-label*="Chat"]', 2621 '[aria-label*="chat"]', 2622 '[id*="chatbot"]', 2623 '[class*="chatbot"]', 2624 '[id*="wix-chat"]', 2625 '[class*="wix-chat"]', 2626 ]; 2627 2628 function suppressAdvisoryChatElements() { 2629 if (path !== "/copy-of-meet-the-team-1") return; 2630 2631 document 2632 .querySelectorAll(advisoryChatSelectors.join(",")) 2633 .forEach((element) => { 2634 element.classList?.add("ed-advisory-chat-suppressed"); 2635 element.setAttribute?.("aria-hidden", "true"); 2636 element.style?.setProperty("display", "none", "important"); 2637 element.style?.setProperty("height", "0", "important"); 2638 element.style?.setProperty("min-height", "0", "important"); 2639 element.style?.setProperty("opacity", "0", "important"); 2640 element.style?.setProperty("overflow", "hidden", "important"); 2641 element.style?.setProperty("pointer-events", "none", "important"); 2642 element.style?.setProperty("visibility", "hidden", "important"); 2643 element.style?.setProperty("width", "0", "important"); 2644 }); 2645 } 2646 2647 function installAdvisoryChatSuppression() { 2648 if (path !== "/copy-of-meet-the-team-1") return; 2649 2650 suppressAdvisoryChatElements(); 2651 window.setTimeout(suppressAdvisoryChatElements, 500); 2652 window.setTimeout(suppressAdvisoryChatElements, 1500); 2653 2654 if (advisoryChatObserver || !window.MutationObserver) return; 2655 advisoryChatObserver = new MutationObserver(suppressAdvisoryChatElements); 2656 advisoryChatObserver.observe(document.documentElement, { 2657 childList: true, 2658 subtree: true, 2659 }); 2660 } 2661 2662 function mobileSponsorLogoCardsHtml() { 2663 return currentSponsorLogos 2664 .map( 2665 (sponsor) => ` 2666 <a href="${sponsor.href}" target="_blank" rel="noopener noreferrer"> 2667 <img src="${sponsor.src}" alt="${escapeMarkup(sponsor.name)}" width="${sponsor.width}" height="${sponsor.height}" loading="lazy" decoding="async">
2668 <span>${escapeMarkup(sponsor.name)}</span> 2669 </a> 2670 `, 2671 ) 2672 .join(""); 2673 } 2674 2675 function mobileSponsorsPageHtml() { 2676 return ` 2677 <section class="ed-mobile-hero compact"> 2678 <p class="ed-mobile-kicker">Partners in Freedom</p> 2679 <h1>Our Sponsors</h1> 2680 <p>We are deeply grateful for the partners and sponsors who stand with The Lifeboat Project. Their generosity helps provide safe housing, long-term care, survivor support, education, advocacy, and outreach for people impacted by human trafficking.</p> 2681 <h2>Sponsors helping carry the mission.</h2> 2682 <p>Every logo below represents real support behind survivor care, prevention education, advocacy, and the daily work of bringing hope back within reach.</p> 2683 </section> 2684 <section class="ed-mobile-sponsor-grid" aria-label="Sponsor logos"> 2685 ${mobileSponsorLogoCardsHtml()} 2686 </section> 2687 `; 2688 } 2689 2690 function mobileLifesaversPageHtml() { 2691 return ` 2692 <section class="ed-mobile-lifesavers-page" aria-label="Lifeboat Lifesavers"> 2693 <section class="ed-mobile-lifesavers-hero" aria-labelledby="ed-mobile-lifesavers-title"> 2694 <div class="ed-mobile-lifesavers-title-block"> 2695 <h1 id="ed-mobile-lifesavers-title">Lifeboat<br>Lifesavers</h1> 2696 <p>Courage in Action</p> 2697 </div> 2698 <div class="ed-mobile-lifesavers-copy"> 2699 <p>Human trafficking thrives in silence, but freedom spreads with compassion and commitment.</p> 2700 <p>Lifeboat Lifesavers aren’t just donors; <strong>they are lifelines</strong>. They are the people who choose action over apathy, hope over helplessness, and community over isolation. By joining this group of faithful supporters, Lifesavers fuel the mission that changes the course of lives.</p> 2701 <span aria-hidden="true"></span> 2702 </div> 2703 </section> 2704 <section class="ed-mobile-lifesavers-board" aria-labelledby="ed-mobile-lifesavers-board-title"> 2705 <h2 id="ed-mobile-lifesavers-board-title">Advisory Board</h2> 2706 <span class="ed-mobile-lifesavers-divider" aria-hidden="true"></span> 2707 <div class="ed-mobile-lifesavers-grid"> 2708 ${lifeboatLifesaversProfiles 2709 .map( 2710 (profile, index) => ` 2711 <article class="ed-mobile-lifesavers-card"> 2712 <div class="ed-mobile-lifesavers-photo"> 2713 <img src="${escapeMarkup(profile.image)}" alt="${escapeMarkup(profile.alt)}" loading="${index === 0 ? "eager" : "lazy"}" decoding="async"> 2714 </div> 2715 <p>${escapeMarkup(profile.role)}</p> 2716 <h3>${escapeMarkup(profile.name)}</h3> 2717 </article> 2718 `, 2719 ) 2720 .join("")} 2721 </div> 2722 </section> 2723 </section> 2724 `; 2725 } 2726 2727 function mobileDonorDockPageHtml() { 2728 const tiers = [ 2729 { 2730 title: "Bronze", 2731 amount: "$2,500 — $4,999", 2732 benefits: [ 2733 "Featured in our newsletter", 2734 "Recognition on our website", 2735 "Spotlight on social media channels", 2736 "Recognition at events", 2737 ], 2738 }, 2739 { 2740 title: "Silver", 2741 amount: "$5,000 — $7,499", 2742 benefits: [ 2743 "All Bronze benefits", 2744 "Exclusive guest speaker feature", 2745 "Special recognition at major events", 2746 "1 annual feature article in our newsletter", 2747 ], 2748 }, 2749 { 2750 title: "Gold", 2751 amount: "$7,500 — $14,999", 2752 benefits: [ 2753 "All Silver benefits", 2754 "Special recognition at 2 events", 2755 "Enhanced marketing exposure", 2756 "2 bi-annual articles in our newsletter", 2757 ], 2758 }, 2759 { 2760 title: "Platinum", 2761 amount: "$15,000+", 2762 benefits: [ 2763 "All Gold benefits", 2764 "Guest speaker at multiple events", 2765 "Priority marketing and sponsorship opportunities", 2766 "4 quarterly newsletter features", 2767 ], 2768 }, 2769 ]; 2770 2771 return ` 2772 <section class="ed-mobile-hero compact ed-mobile-donor-hero"> 2773 <p class="ed-mobile-kicker">The Donor Dock</p> 2774 <h1>Your generosity anchors hope.</h1> 2775 <p>
2775Partner with The Lifeboat Project to support survivor care, prevention education, and community awareness. Choose a giving level, or reach out and we will help match the right fit.</p> 2776 <div class="ed-mobile-actions"> 2777 <a href="${donateUrl}" target="_blank" rel="noopener noreferrer">Become a Lifesaver Today</a> 2778 </div> 2779 </section> 2780 <section class="ed-mobile-article"> 2781 <h2>Choose a simple sponsor level.</h2> 2782 <p>Each tier includes meaningful recognition and helps sustain Lifeboat's survivor-centered mission.</p> 2783 </section> 2784 <section class="ed-mobile-donor-tiers" aria-label="Donor Dock giving tiers"> 2785 ${tiers 2786 .map( 2787 (tier) => ` 2788 <article> 2789 <h2>${escapeMarkup(tier.title)}</h2> 2790 <p class="ed-mobile-donor-amount">${tier.amount}</p> 2791 <ul> 2792 ${tier.benefits.map((benefit) => `<li>${escapeMarkup(benefit)}</li>`).join("")} 2793 </ul> 2794 </article> 2795 `, 2796 ) 2797 .join("")} 2798 </section> 2799 <section class="ed-mobile-article ed-mobile-donor-contact"> 2800 <h2>Want help choosing a level?</h2> 2801 <p>Tell us what kind of sponsor visibility you want, and we will help you choose the right fit.</p> 2802 <p><a class="ed-mobile-inline-link" href="mailto:[email protected]">[email protected]</a></p> 2803 <p><a class="ed-mobile-inline-link" href="tel:14073108905">407-310-8905</a></p> 2804 <div class="ed-mobile-actions"> 2805 <a href="mailto:[email protected]?subject=Donor%20Dock%20Sponsorship">Start a Conversation</a> 2806 </div> 2807 </section> 2808 `; 2809 } 2810 2811 function mobileInternationalPartnerFormHtml() { 2812 return ` 2813 <section class="ed-mobile-hero compact ed-mobile-partner-form-hero"> 2814 <p class="ed-mobile-kicker">Partner Interest</p> 2815 <h1>Become an International Partner</h1> 2816 <p>Tell The Lifeboat Project who you are, where you work, and what type of collaboration you would like to explore.</p> 2817 </section> 2818 ${partnerFormHtml({ 2819 className: "ed-mobile-form-card", 2820 prefix: "ed-mobile-partner", 2821 statusClassName: "ed-mobile-contact-status ed-partner-form-status", 2822 })} 2823 `; 2824 } 2825 2826 function mobileGetInvolvedPageHtml() { 2827 return ` 2828 <section class="ed-mobile-get-involved-header" aria-labelledby="ed-mobile-get-involved-title"> 2829 <img src="${getInvolvedHeaderImage}" alt="Get Involved. Together, we can end human trafficking and bring hope to survivors." width="1717" height="916" loading="eager" fetchpriority="high"> 2830 <div class="ed-screen-reader-only"> 2831 <h1 id="ed-mobile-get-involved-title">Get Involved</h1> 2832 <p>Choose a practical path to volunteer, request education, or support the mission.</p> 2833 </div> 2834 </section> 2835 <section class="ed-mobile-article"> 2836 <h2>Ways to stand with survivors</h2> 2837 <p>Choose a practical path to give time, invite education, and help Central Florida respond with care.</p> 2838 </section> 2839 <section class="ed-mobile-get-involved-cards" aria-label="Ways to get involved"> 2840 <article> 2841 <p class="ed-mobile-kicker">Volunteer</p> 2842 <h2>Volunteer</h2> 2843 <p>Join outreach, events, and awareness efforts that help survivors feel seen, supported, and connected to care.</p> 2844 <p>Join a compassionate team of volunteers committed to healing, prevention, and community education. Whether you serve at events, assist in outreach efforts, or help with awareness campaigns, your time and heart make a meaningful impact in restoring lives.</p> 2845 <a href="${volunteerApplyEmail}">Apply Today</a> 2846 </article> 2847 <article> 2848 <p class="ed-mobile-kicker">Housing</p> 2849 <h2>Haven Homes</h2> 2850 <p>The Haven Home Program provides survivors with a supportive, family-based environment to heal and regain independence. Unlike traditional foster homes, each Haven Home family hosts one survivor over 18, working alongside Lifeboat Project professionals.</p> 2851 <a href="mailto:[email protected]?subject=I%20would%20like%20to%20become%20a%20Haven%20Home">
2851Become a Haven Home</a> 2852 </article> 2853 <article> 2854 <p class="ed-mobile-kicker">Education</p> 2855 <h2>Request a Speaker</h2> 2856 <p>Bring Lifeboat's prevention education and survivor-centered awareness to schools, churches, workplaces, and community events.</p> 2857 <p>Our passionate speakers are on a mission to raise awareness and inspire action against human trafficking. Available for local and national events such as schools, churches, and community gatherings, we help audiences understand the magnitude of this critical issue.</p> 2858 <a href="/request-a-speaker/">Request a Speaker</a> 2859 </article> 2860 <article> 2861 <p class="ed-mobile-kicker">Request a Training</p> 2862 <h2>REQUEST A TRAINING</h2> 2863 <p>We offer exceptional interactive training sessions that provide practical tools for identifying, responding to, and preventing human trafficking. Participants gain actionable skills, trauma-informed strategies, and resources tailored to their professional or community role.</p> 2864 <a href="mailto:[email protected]?subject=Speaker%20Request">Request a Training</a> 2865 </article> 2866 </section> 2867 <section class="ed-mobile-grid ed-mobile-support-grid"> 2868 ${mobileCard("Donate", "Give directly to survivor support and prevention work.", donateUrl, "Donate")} 2869 ${mobileCard("International Partnerships", "Start a conversation about mission-aligned collaboration.", "/international-partnerships/")} 2870 </section> 2871 `; 2872 } 2873 2874 function mobileInternationalPhoto(src, alt, className = "") { 2875 return ` 2876 <figure class="ed-mobile-intl-photo${className ? ` ${className}` : ""}"> 2877 <img src="${escapeMarkup(src)}" alt="${escapeMarkup(alt)}" loading="${className.includes("hero") ? "eager" : "lazy"}" decoding="async"${className.includes("hero") ? " fetchpriority=\"high\"" : ""}> 2878 </figure> 2879 `; 2880 } 2881 2882 function mobileInternationalPartnershipsPageHtml() { 2883 const tags = [ 2884 "Benchmarking", 2885 "Prevention Campaigns", 2886 "Education & Training", 2887 "Research & Data Sharing", 2888 "Victim-Centered Models", 2889 "Cross-Border Referral Pathways", 2890 "Policy Dialogue & Advocacy", 2891 "Joint Grant Projects", 2892 "Corporate Awareness", 2893 "Tourism Sector Training", 2894 "Youth & School Engagement", 2895 "Speaking & Conferences", 2896 ]; 2897 2898 return ` 2899 <section class="ed-mobile-intl-hero" aria-labelledby="ed-mobile-international-title"> 2900 <p class="ed-mobile-kicker">International Partnerships</p> 2901 <h1 id="ed-mobile-international-title">Building Global Partnerships Against Human Trafficking</h1> 2902 <p>The Lifeboat Project is committed to building meaningful international partnerships that strengthen prevention, expand education, support survivor-centered solutions, and advance practical collaboration across borders.</p> 2903 <p>We are seeking mission-aligned organizations, institutions, and partners from around the world who are ready to share knowledge, exchange best practices, and explore future joint initiatives.</p> 2904 <div class="ed-mobile-actions"> 2905 <a href="/international-partnership-form/">Become a Partner</a> 2906 </div> 2907 </section> 2908 2909 ${mobileInternationalPhoto( 2910 "/assets/updates/international-partnerships/hero-un-partnership.webp", 2911 "Lifeboat Project representatives at the United Nations General Assembly", 2912 "ed-mobile-intl-hero-photo", 2913 )} 2914 2915 <section class="ed-mobile-intl-section"> 2916 <p class="ed-mobile-kicker">The Global Reality</p> 2917 <h2>A crisis that demands international cooperation</h2> 2918 <p>Human trafficking is a global issue that affects vulnerable individuals across regions, industries, and communities. No one organization and no one country can solve it alone.</p> 2919 <p>Lasting progress requires cross-border communication, practical learning, and stronger partnerships between nonprofits, educators, public institutions, researchers, and mission-driven organizations.</p> 2920 </section> 2921 2922 <section class="ed-mobile-intl-mini-grid" aria-label="International cooperation priorities"> 2923 <article><span>01</span><h2>Global Scale</h2><p>Trafficking impacts people around the world and requires responses that are informed, connected, and adaptable.</p></article> 2924 <article><span>02</span><h2>Shared Learning</h2><p>
2924Organizations grow stronger when they exchange ideas, compare models, and learn from different regions and sectors.</p></article> 2925 </section> 2926 2927 <section class="ed-mobile-intl-photo-grid" aria-label="International partnership meeting photos"> 2928 ${mobileInternationalPhoto("/assets/updates/international-partnerships/meeting-left.png", "International meeting room with delegates seated around a conference table")} 2929 ${mobileInternationalPhoto("/assets/updates/international-partnerships/meeting-wide.png", "Wide view of an international roundtable discussion")} 2930 ${mobileInternationalPhoto("/assets/updates/international-partnerships/speaker-room.png", "Lifeboat Project representative participating in an international meeting")} 2931 </section> 2932 2933 <section class="ed-mobile-intl-section ed-mobile-intl-soft"> 2934 <p class="ed-mobile-kicker">Why International Collaboration Matters</p> 2935 <h2>Local experience. Global relevance.</h2> 2936 <p>The Lifeboat Project is based in Central Florida, one of the most internationally connected regions in the United States. With high tourism volume, constant mobility, and global movement through the region, trafficking-related risks are especially relevant.</p> 2937 <p>That reality gives our organization both a strong reason to engage internationally and meaningful experience to contribute. At the same time, we believe the strongest solutions come from collaboration, humility, and a willingness to learn from others doing this work around the world.</p> 2938 <p>This initiative is designed to build relationships that strengthen prevention, education, survivor-centered practice, and future joint efforts.</p> 2939 </section> 2940 2941 <section class="ed-mobile-intl-dark"> 2942 <p class="ed-mobile-kicker">Our Approach</p> 2943 <h2>We want to contribute, learn, benchmark, and build.</h2> 2944 <p>Through international partnerships, The Lifeboat Project aims to exchange best practices, improve systems, deepen shared understanding, and explore future mission-aligned projects with organizations across the world.</p> 2945 </section> 2946 2947 <section class="ed-mobile-intl-section"> 2948 <p class="ed-mobile-kicker">Partnership Pillars</p> 2949 <h2>Where collaboration can begin</h2> 2950 <div class="ed-mobile-intl-card-grid"> 2951 <article><span>A</span><h3>Benchmarking</h3><p>Exchange best practices, compare models, and learn from each other's methods, referral structures, and program approaches.</p></article> 2952 <article><span>B</span><h3>Prevention</h3><p>Strengthen prevention efforts through awareness campaigns, public education, and practical risk-reduction strategies.</p></article> 2953 <article><span>C</span><h3>Education</h3><p>Collaborate on training, resource development, webinars, workshops, and educational partnerships.</p></article> 2954 <article><span>D</span><h3>Joint International Projects</h3><p>Explore research collaboration, pilot programs, grants, and other future cross-border initiatives.</p></article> 2955 </div> 2956 </section> 2957 2958 <section class="ed-mobile-intl-section ed-mobile-intl-soft"> 2959 <p class="ed-mobile-kicker">What Collaboration Can Look Like</p> 2960 <h2>Practical ways to work together</h2> 2961 <ul class="ed-mobile-intl-checks"> 2962 <li>Knowledge exchange calls and strategic introductions</li> 2963 <li>Joint webinars, panels, and awareness campaigns</li> 2964 <li>Training partnerships and survivor-centered service model exchange</li> 2965 <li>School, university, and youth engagement collaborations</li> 2966 <li>Research collaboration, data sharing, and benchmarking</li> 2967 <li>Conference participation, speaking opportunities, and international networking</li> 2968 <li>Corporate awareness partnerships and tourism and hospitality training</li> 2969 <li>Joint grant exploration and future cross-border initiatives</li> 2970 </ul> 2971 </section> 2972 2973 <section class="ed-mobile-intl-section"> 2974 <p class="ed-mobile-kicker">Who We Hope To Connect With</p> 2975 <h2>Mission-aligned partners worldwide</h2> 2976 <div class="ed-mobile-intl-card-grid"> 2977 <article><h3>Nonprofits</h3><p>Organizations working in anti-trafficking, survivor support, prevention, child protection, community education, or victim services.</p></article> 2978 <article><h3>Universities & Schools</h3><p>Institutions interested in educational partnerships, research, applied learning, and training collaboration.</p></article> 2979 <article><h3>Public Institutions</h3><p>Municipalities, agencies, policy groups, and international bodies exploring dialogue, prevention, or pilot initiatives.</p></article> 2980 <article><h3>Private Sector Partners</h3><p>
2980Mission-driven companies, tourism leaders, hospitality organizations, and responsible corporate partners seeking to raise awareness and strengthen training.</p></article> 2981 </div> 2982 </section> 2983 2984 <section class="ed-mobile-intl-photo-grid ed-mobile-intl-photo-grid-small" aria-label="International partnership detail photos"> 2985 ${mobileInternationalPhoto("/assets/updates/international-partnerships/speaker-room.png", "International meeting presentation on human trafficking prevention")} 2986 ${mobileInternationalPhoto("/assets/updates/international-partnerships/flags-pin.png", "United Nations pin with United States and Hungary flag pins")} 2987 ${mobileInternationalPhoto("/assets/updates/international-partnerships/hero-un-partnership.webp", "Lifeboat Project representatives with international partners")} 2988 </section> 2989 2990 <section class="ed-mobile-intl-section"> 2991 <p class="ed-mobile-kicker">Partner Interest</p> 2992 <h2>Start the conversation</h2> 2993 <p>We welcome opportunities to connect with organizations, institutions, and mission-aligned partners who are interested in meaningful collaboration to strengthen the global response to human trafficking.</p> 2994 <p>Whether your interest is in prevention, education, benchmarking, research, awareness, or future international initiatives, we would be honored to explore what partnership could look like together.</p> 2995 <div class="ed-mobile-intl-tags" aria-label="Partnership interest areas"> 2996 ${tags.map((tag) => `<span>${escapeMarkup(tag)}</span>`).join("")} 2997 </div> 2998 </section> 2999 3000 <section class="ed-mobile-intl-dark" id="form"> 3001 <p class="ed-mobile-kicker">Become A Partner</p> 3002 <h2>Ready to connect with The Lifeboat Project?</h2> 3003 <p>Use the partnership form to share more about your organization, your focus, and the areas where you would like to explore collaboration.</p> 3004 <div class="ed-mobile-actions"> 3005 <a href="/international-partnership-form/">Complete the Form</a> 3006 </div> 3007 </section> 3008 3009 <section class="ed-mobile-intl-final"> 3010 <p class="ed-mobile-kicker">Become A Partner</p> 3011 <h2>Let's build a stronger international response together.</h2> 3012 <p>We believe meaningful change is built through partnership, shared knowledge, and practical action. If your organization is ready to explore collaboration, we would love to hear from you.</p> 3013 <div class="ed-mobile-actions"> 3014 <a href="/international-partnership-form/">Become a Partner</a> 3015 </div> 3016 </section> 3017 `; 3018 } 3019 3020 function mobilePageHtml() { 3021 const key = rawPath.replace(/\/$/, "") || "/"; 3022 if (key === "/volunteer" || key === "/about-4-1") { 3023 return ` 3024 ${mobileVolunteerHeaderHtml()} 3025 ${volunteerMobileExperienceHtml()} 3026 `; 3027 } 3028 if (key === "/who-we-are") return renderMobileWhoWeAreHtml(); 3029 if (key === "/advisory-board" || key === "/copy-of-meet-the-team-1") return renderMobileAdvisoryBoardHtml(); 3030 if (key === "/get-involved") return mobileGetInvolvedPageHtml(); 3031 if (key === "/international-partnerships") return mobileInternationalPartnershipsPageHtml(); 3032 if (key === "/sponsors") return mobileSponsorsPageHtml(); 3033 if (key === "/lifeboat-lifesavers") return mobileLifesaversPageHtml(); 3034 if (key === "/donor-dock" || key === "/copy-of-lifeboat-lifesavers") return mobileDonorDockPageHtml(); 3035 if (key === "/events") return mobileEventsPageHtml(); 3036 if (key === "/spot-it-stop-it" || key === "/projects-7") return mobileSpotItStopItPageHtml(); 3037 if (key === "/international-partnership-form" || key === "/international-partner-form" || key === "/partner-form") { 3038 return mobileInternationalPartnerFormHtml(); 3039 } 3040 if (key === "/financial-strategic-plan" || key === "/publications") { 3041 return ` 3042 <section class="ed-mobile-hero compact"> 3043 <p class="ed-mobile-kicker">TRANSPARENCY & PLANNING</p> 3044 <h1>Financial & Strategic Plan</h1> 3045 <p>The Lifeboat Project makes key planning, financial, and compliance documents available so donors, partners, and community members can see how the organization stewards resources and plans for survivor-centered care.</p> 3046 </section> 3047 <section class="ed-mobile-article" aria-label="What these resources show"> 3048 <h2>Strategic Direction</h2> 3049 <p>The 2025-2027 Strategic Plan outlines mission priorities, goals, and strategies for the current planning period.</p> 3050 <h2>Financial Accountability</h2> 3051 <p>The Form 990 and audited financial statements provide a clearer view of nonprofit reporting and financial stewardship.</p> 3052 <h2>Compliance Standing</h2> 3053 <p>The annual corporate filing confirms current registration information and public compliance documentation.</p> 3054 </section> 3055 <section class="ed-mobile-list" aria-label="Financial and strategic resources"> 3056 <p class="ed-mobile-kicker">Available Documents</p> 3057 <a href="/assets/captured/4ad4052bcbeef908.pdf" target="_blank" rel="noopener noreferrer"> 3058 <strong>Strategic Plan 2025-2027</strong>
3059 <span>Outlines The Lifeboat Project's mission, values, goals, and strategies for the three-year planning period.</span> 3060 <em>Open Strategic Plan</em> 3061 </a> 3062 <a href="/assets/captured/cebdb18255f5d56d.pdf" target="_blank" rel="noopener noreferrer"> 3063 <strong>Form 990</strong> 3064 <span>Federal tax-exempt filing for calendar year 2024, maintained as part of the organization's public nonprofit reporting.</span> 3065 <em>Open Form 990</em> 3066 </a> 3067 <a href="/assets/captured/818cda4f36e20898.pdf" target="_blank" rel="noopener noreferrer"> 3068 <strong>Audited Financial Statements</strong> 3069 <span>Independent financial statements for fiscal years ended December 31, 2024 and 2023.</span> 3070 <em>Open Financial Statements</em> 3071 </a> 3072 <a href="/assets/captured/c20950269423e2bb.pdf" target="_blank" rel="noopener noreferrer"> 3073 <strong>Annual Corporate/Compliance Filing</strong> 3074 <span>Current Florida not-for-profit annual report filed April 7, 2026.</span> 3075 <em>Open Annual Filing</em> 3076 </a> 3077 </section> 3078 <section class="ed-mobile-article" aria-label="About these documents"> 3079 <h2>Planning and accountability resources</h2> 3080 <p>Each document opens as a PDF in a new tab.</p> 3081 <h2>What these resources cover</h2> 3082 <p>Together, these documents outline the organization's strategic direction, financial accountability, and compliance standing. They are provided for donors, partners, and community members who want a clearer view of the work behind the mission.</p> 3083 </section> 3084 <section class="ed-mobile-article" aria-label="Questions about financial and strategic resources"> 3085 <h2>Questions about these documents?</h2> 3086 <p>For questions about The Lifeboat Project's planning materials, financial reporting, or compliance documentation, please contact the team directly.</p> 3087 <div class="ed-mobile-actions"> 3088 <a href="/contact/">Contact The Lifeboat Project</a> 3089 </div> 3090 </section> 3091 `; 3092 } 3093 3094 if (key === "/meet-the-team" || key === "/team-4") return renderMobileTeamIndexHtml(); 3095 3096 if (key === "/blog") { 3097 const [featuredPost, ...morePosts] = blogPosts; 3098 3099 return ` 3100 <section class="ed-mobile-hero compact ed-mobile-blog-hero"> 3101 <p class="ed-mobile-kicker">Stories & Updates</p> 3102 <h1>Stories from The Lifeboat Project.</h1> 3103 <h2>Community wins, event recaps, and mission moments.</h2> 3104 <p>Recent moments, partnerships, and community updates from the work happening around the mission.</p> 3105 <ul class="ed-mobile-plain-list"> 3106 <li>Leadership updates</li> 3107 <li>Partnership highlights</li> 3108 </ul> 3109 </section> 3110 <section class="ed-mobile-blog-feed" aria-label="Recent Lifeboat Project blog posts"> 3111 ${renderMobileBlogTile(featuredPost, { featured: true })} 3112 ${morePosts.map((post) => renderMobileBlogTile(post)).join("")} 3113 </section> 3114 `; 3115 } 3116 3117 if (key === "/stories") { 3118 return ` 3119 <section class="ed-mobile-hero compact ed-mobile-stories-hero"> 3120 <p class="ed-mobile-kicker">Stories</p> 3121 <h1>Stories, videos, and impact updates.</h1> 3122 <p>Read recent posts and watch stories that show the mission in action.</p> 3123 </section> 3124 <section class="ed-mobile-article ed-mobile-story-intro"> 3125 <h3>EVERY STORY MATTERS.</h3> 3126 <p>Survivor-centered stories, mission videos, and awareness resources help the community understand why this work matters.</p> 3127 </section> 3128 <section class="ed-mobile-story-video-grid" aria-label="Mission videos"> 3129 ${storyVideoLibrary.map((video, index) => renderMobileStoryVideoCard(video, index)).join("")} 3130 </section> 3131 <section class="ed-mobile-article ed-mobile-spot-campaign"> 3132 <h1>Spot it Stop it Campaign</h1> 3133 <p>The Spot It, Stop It campaign raises awareness about the signs of human trafficking through quick, impactful shorts. These videos are designed to help you recognize the red flags that may indicate someone is at risk. By learning what to look for, you can make a difference and take action. Every shared video, every informed individual, brings us one step closer to stopping trafficking in our
3133communities. Together, we can spot the signs and stop the cycle.</p> 3134 <div class="ed-mobile-actions"> 3135 <a href="/spot-it-stop-it/">Watch the Campaign</a> 3136 </div> 3137 </section> 3138 <section class="ed-mobile-article ed-mobile-story-updates-heading"> 3139 <p class="ed-mobile-kicker">Latest Updates</p> 3140 <h2>Community wins, partnerships, and event recaps.</h2> 3141 </section> 3142 <section class="ed-mobile-blog-feed ed-mobile-story-updates" aria-label="Recent Lifeboat Project updates"> 3143 ${blogPosts.map((post, index) => renderMobileBlogTile(post, { featured: index === 0 })).join("")} 3144 </section> 3145 `; 3146 } 3147 3148 if (key !== "/" && key !== "/what-we-do") return ""; 3149 3150 if (key === "/") { 3151 return ` 3152 <section class="ed-mobile-video-hero" aria-label="The Lifeboat Project homepage video"> 3153 <video autoplay muted playsinline webkit-playsinline preload="auto" poster="/assets/updates/home-hero-first-frame.jpg" src="${homeHeroVideoSrc}" aria-hidden="true"> 3154 <source src="${homeHeroVideoSrc}" type="video/mp4"> 3155 </video> 3156 </section> 3157 <section class="ed-mobile-stats" aria-label="Human trafficking statistics"> 3158 <article><strong>#3</strong><span>Florida ranks #3 in the nation for human trafficking cases.</span></article> 3159 <article><strong>700,000</strong><span>Estimated annual human trafficking cases in Florida.</span></article> 3160 <article><strong>75%</strong><span>Of human trafficking cases involve children under 18.</span></article> 3161 <article><strong>13</strong><span>Average age of a child entering human trafficking.</span></article> 3162 </section> 3163 <p class="ed-mobile-stat-source">* Source: USF/TIPSTER Research Program. ** Source: National Human Trafficking Hotline.</p> 3164 <section class="ed-mobile-home-safety" aria-labelledby="ed-mobile-home-safety-title"> 3165 <img src="${homeSafetyImage}" alt="People standing together with arms around each other" width="1528" height="1600" loading="lazy" decoding="async"> 3166 <div class="ed-mobile-home-safety-copy"> 3167 <h2 id="ed-mobile-home-safety-title">Helping Survivors Reclaim Safety, Stability, and Hope</h2> 3168 <p>The Lifeboat Project provides long-term, trauma-informed care and housing-first support for survivors of human trafficking.</p> 3169 <div class="ed-mobile-actions"> 3170 <a href="/who-we-are/">Our Mission</a> 3171 <a href="${requestHelpUrl}" target="_blank" rel="noopener noreferrer">Request Help</a> 3172 </div> 3173 </div> 3174 </section> 3175 <section class="ed-mobile-feature ed-mobile-video-feature"> 3176 <p class="ed-mobile-kicker">Our Impact</p> 3177 <h2>See the work behind safety, stability, and hope.</h2> 3178 <button type="button" data-ed-home-mission-play data-vi
3178deo-title="Our Impact" aria-label="Play video: Our Impact"> 3179 <img src="/assets/captured/6250f9d2681f491e.jpeg" alt="Our Impact video preview" loading="lazy"> 3180 <span><span></span></span> 3181 <em class="ed-mobile-video-play-label">Our Impact Watch the mission story</em> 3182 </button> 3183 <p><strong>Our Impact:</strong> Watch the mission story.</p> 3184 <p>Hear how The Lifeboat Project pairs immediate support with long-term, trauma-informed care for survivors rebuilding in Central Florida.</p> 3185 </section> 3186 <section class="ed-mobile-grid" aria-label="Featured site sections"> 3187 ${mobileCard("Know the Signs", "Learn warning signs, common myths, reporting options, and safety-focused next steps.", "/know-the-signs/")} 3188 ${mobileCard("What We Do", "Explore survivor-centered programs, including The S.H.I.E.L.D. Program.", "/what-we-do/")} 3189 ${mobileCard("Events", "See upcoming fundraisers, volunteer opportunities, and community events.", "/events/")} 3190 ${mobileCard("Get Involved", "Find practical ways to volunteer, partner, sponsor, or support the mission.", "/get-involved/")} 3191 </section> 3192 <section class="ed-mobile-feature ed-mobile-event-feature"> 3193 <div> 3194 <p class="ed-mobile-kicker">Featured Event</p> 3195 <h2>Yacht Rock Benefit Bash</h2> 3196 <p>Join The Lifeboat Project for its 6th annual benefit bash: an evening of dinner, cocktails, auctions, entertainment, and yacht rock supporting human trafficking awareness and survivor care.</p> 3197 <div class="ed-mobile-event-details" aria-label="Yacht Rock Benefit Bash details"> 3198 <p><span>Date</span><strong>Oct. 17, 2026</strong></p> 3199 <p><span>Time</span><strong>5:30–9:30 PM Eastern</strong></p> 3200 <p><span>Location</span><strong>Hilton Lake Buena Vista</strong></p> 3201 </div> 3202 <p class="ed-mobile-event-experience">Open bar, three-course meal, cocktail party, live and silent auction, entertainment, and yacht rock all night.</p> 3203 <p class="ed-mobile-event-price">Tickets are $300. Tables of eight are $3,500.</p> 3204 <p class="ed-mobile-event-price">Sponsor opportunities are available at $5,000, $10,000, and $15,000 levels.</p> 3205 <div class="ed-mobile-event-actions">
3206 <a href="${yachtRockEventPath}">View Event Details</a> 3207 <a href="mailto:[email protected]?subject=Yacht%20Rock%20Benefit%20Bash%20Sponsorship">Sponsor the Event</a> 3208 </div> 3209 </div> 3210 <a class="ed-mobile-event-flyer" href="${yachtRockEventPath}" aria-label="View Yacht Rock Benefit Bash event details"> 3211 <img src="${yachtRockFlyerImage}" alt="6th Annual Yacht Rock Benefit Bash flyer" loading="lazy"> 3212 </a> 3213 </section> 3214 `; 3215 } 3216 3217 if (key === "/who-we-are") { 3218 return ` 3219 <section class="ed-mobile-hero compact"> 3220 <p class="ed-mobile-kicker">Who We Are</p> 3221 <h1>Survivor-centered care, advocacy, and prevention.</h1> 3222 <p>The Lifeboat Project supports survivors of human trafficking through long-term care, education, partnerships, and community action.</p> 3223 </section> 3224 <section class="ed-mobile-grid"> 3225 ${mobileCard("Meet the Team", "Learn about the staff and leadership carrying this work forward.", "/meet-the-team/")} 3226 ${mobileCard("Board of Directors", "Review the board members guiding the organization.", "/board-of-directors/")} 3227 ${mobileCard("Financial & Strategic Plan", "Open the organization's financial and strategic information.", "/financial-strategic-plan/")} 3228 ${mobileCard("Contact", "Reach the team with questions, support offers, or partnership ideas.", "/contact/")} 3229 </section> 3230 `; 3231 } 3232 3233 if (key === "/financial-strategic-plan" || key === "/publications") { 3234 return ` 3235 <section class="ed-mobile-hero compact"> 3236 <p class="ed-mobile-kicker">Transparency & Planning</p> 3237 <h1>Financial & Strategic Plan</h1> 3238 <p>Review the key planning, financial, and compliance documents that show how The Lifeboat Project stewards resources and plans for survivor-centered care.</p> 3239 </section> 3240 <section class="ed-mobile-article" aria-label="What these resources show"> 3241 <h2>Strategic Direction</h2> 3242 <p>The 2025-2027 Strategic Plan outlines mission priorities, goals, and strategies for the current planning period.</p> 3243 <h2>Financial Accountability</h2> 3244 <p>The Form 990 and audited financial statements provide a clearer view of nonprofit reporting and financial stewardship.</p> 3245 <h2>Compliance Standing</h2> 3246 <p>The annual corporate filing confirms current registration information and public compliance documentation.</p> 3247 </section> 3248 <section class="ed-mobile-list" aria-label="Financial and strategic resources"> 3249 <p class="ed-mobile-kicker">Available Documents</p> 3250 <a href="/assets/captured/4ad4052bcbeef908.pdf" target="_blank" rel="noopener noreferrer"> 3251 <strong>Strategic Plan 2025-2027</strong> 3252 <span>Mission, values, goals, and strategies for the current three-year planning period.</span> 3253 <em>Open Strategic Plan</em> 3254 </a> 3255 <a href="/assets/captured/cebdb18255f5d56d.pdf" target="_blank" rel="noopener noreferrer"> 3256 <strong>Form 990</strong> 3257 <span>Federal tax-exempt filing for calendar year 2024.</span> 3258 <em>Open Form 990</em> 3259 </a> 3260 <a href="/assets/captured/818cda4f36e20898.pdf" target="_blank" rel="noopener noreferrer"> 3261 <strong>Audited Financial Statements</strong> 3262 <span>Independent financial statements for fiscal years ended December 31, 2024 and 2023.</span> 3263 <em>Open Financial Statements</em> 3264 </a> 3265 <a href="/assets/captured/c20950269423e2bb.pdf" target="_blank" rel="noopener noreferrer"> 3266 <strong>Annual Corporate/Compliance Filing</strong> 3267 <span>Current Florida not-for-profit annual report filed April 7, 2026.</span> 3268 <em>Open Annual Filing</em> 3269 </a> 3270 </section> 3271 <section class="ed-mobile-article" aria-label="About these documents"> 3272 <h2>What these resources cover</h2> 3273 <p>Together, these documents outline the organization's strategic direction, financial accountability, and compliance standing. They are provided for donors, partners, and community members who want a clearer view of the work behind the mission.</p> 3274 </section> 3275 <section class="ed-mobile-article" aria-label="Questions about financial and strategic resources"> 3276 <h2>Questions about these documents?</h2> 3277 <p>For questions about The Lifeboat Project's planning materials, financial reporting, or compliance documentation, please contact the team directly.</p> 3278 <div class="ed-mobile-actions"> 3279 <a href="/contact/">Contact The Lifeboat Project</a> 3280 </div> 3281 </section> 3282 `; 3283 } 3284 3285 if (key === "/meet-the-team" || key === "/team-4") { 3286 const team = [ 3287 ["Jill Bolander Cohen", "Founder & CEO", "/team/jill-bolander-cohen/"], 3288 ["Tina Sopp", "Chief Operating Officer", "/team/tina-sopp/"], 3289 ["Jonny", "Director of Maintenance", "/team/jonny/"], 3290 ["Eme", "Grant Compliance Manager", "/team/eme/"], 3291 ["Kristen Jensen", "Program Director", "/team/kristen-jensen/"], 3292 ["Nancy", "Team Member", "/team/nancy/"], 3293 ["Jamie Holmes", "Team Member", "/team/jamie-holmes/"], 3294 ["Piros Pazaurek", "Team Member", "/team/piros-pazaurek/"], 3295 ]; 3296 return ` 3297 <section class="ed-mobile-hero compact"> 3298 <p class="ed-mobile-kicker">Meet the Team</p> 3299 <h1>The people behind The Lifeboat Project.</h1> 3300 <p>Tap a profile to read more about the team members supporting survivors and advancing the mission.</p> 3301 </section> 3302 <section class="ed-mobile-list"> 3303 ${team.map(([name, role, href]) => `<a href="${href}"><strong>${escapeMarkup(name)}</strong><span>${escapeMarkup(role)}</span></a>`).join("")} 3304 </section> 3305 `; 3306 } 3307 3308 if (key === "/what-we-do") { 3309 return ` 3310 <section class="ed-mobile-what-header" aria-label="What We Do page header"> 3311 <img src="${whatWeDoHeaderImage}" alt="What We Do. We exist to end human trafficking and restore hope to survivors." width="1717" height="916" loading="eager" fetchpriority="high"> 3312 </section> 3313 <section class="ed-mobile-hero compact ed-mobile-believe-intro"> 3314 <p class="ed-mobile-kicker">Our Approach</p> 3315 <h1>We believe in showing people love without conditions.</h1> 3316 <p>Every program begins with dignity, safety, and steady support for survivors as they move from crisis toward lasting freedom.</p> 3317 </section> 3318 <section class="ed-mobile-what-video" aria-label="${escapeMarkup(whatWeDoVideo.title)} video"> 3319 <video controls playsinline preload="metadata" poster="${whatWeDoVideo.poster}" src="${whatWeDoVideo.src}" title="${escapeMarkup(whatWeDoVideo.title)}" aria-label="${escapeMarkup(whatWeDoVideo.title)}"> 3320 <source src="${whatWeDoVideo.src}" type="video/mp4"> 3321 </video> 3322 </section> 3323 <section class="ed-mobile-hero compact ed-mobile-shield-hero"> 3324 <p class="ed-mobile-kicker">The S.H.I.E.L.D. Program</p> 3325 <h1>From Crisis to Autonomy: The S.H.I.E.L.D. Program</h1> 3326 <p>The Lifeboat Project's S.H.I.E.L.D. Program is a comprehensive, trauma-informed framework designed to transition survivors of human trafficking from immediate crisis to long-term self-sufficiency and lifelong empowerment.</p> 3327 <div class="ed-mobile-actions"> 3328 <a href="${donateUrl}" target="_blank" rel="noopener noreferrer">Support Our Mission</a> 3329 <a href="mailto:[email protected]?subject=S.H.I.E.L.D.%20Program%20Information">Request Program Information</a> 3330 </div> 3331 </section> 3332 <section class="ed-mobile-article ed-mobile-shield-continuum"> 3333 <h2>The S.H.I.E.L.D. Continuum of Care</h2> 3334 <p>Recovery is not a single event; it is a lifelong journey. The S.H.I.E.L.D. model represents a holistic approach to restoration by addressing immediate p
3334hysical safety first, then systematically strengthening a survivor's health, legal standing, financial independence, and community support network.</p> 3335 </section> 3336 <section class="ed-mobile-shield-list" aria-label="S.H.I.E.L.D. program elements"> 3337 <article><span>S</span><div><h2>Stabilization & Safety</h2><p>Immediate crisis intervention, secure emergency housing, and critical safety planning help remove survivors from harm's way and provide a peaceful space to begin decompressing from trauma.</p></div></article> 3338 <article><span>H</span><div><h2>Holistic Healthcare</h2><p>Coordinated medical treatment, psychiatric support, long-term counseling, and restorative wellness therapies address both physical and psychological wounds.</p></div></article> 3339 <article><span>I</span><div><h2>Institutional Advocacy</h2><p>Advocates walk alongside survivors through criminal justice proceedings, child welfare systems, victim compensation, housing, and government agencies.</p></div></article> 3340 <article><span>E</span><div><h2>Economic Empowerment</h2><p>Job readiness training, financial literacy education, resume building, and business partnerships help create safe, dignified employment and education pathways.</p></div></article> 3341 <article><span>L</span><div><h2>Lifelong Mentoring & Social Integrity</h2><p>Peer mentoring, community reintegration, healthy social networks, and ongoing mentorship help rebuild trust in community and long-term resilience.</p></div></article> 3342 <article><span>D</span><div><h2>Desired Development</h2><p>Individualized planning helps each survivor identify personal, creative, educational, or professional dreams and access resources to pursue them.</p></div></article> 3343 </section> 3344 <section class="ed-mobile-article ed-mobile-shield-impact"> 3345 <h2>Why the S.H.I.E.L.D. Approach Works</h2> 3346 <p>Many programs offer crisis shelter, but survivors often struggle when that initial safety net is removed. S.H.I.E.L.D. bridges the gap between immediate stabilization and long-term, self-directed development so survivors can build lives of deep purpose, financial stability, and lasting freedom.</p> 3347 <p>We do not define survivors by what they have been through, but by where they are going. S.H.I.E.L.D. provides the support they need to heal and the tools they need to soar.</p> 3348 </section> 3349 <section class="ed-mobile-hero compact ed-mobile-lifelong-care"> 3350 <p class="ed-mobile-kicker">Lifelong Care</p> 3351 <h1>Care does not end when a survivor is safe.</h1> 3352 <p>The Lifeboat Project helps survivors move through the practical next steps: crisis response, counseling, housing, benefits, legal advocacy, and steady relationships that make recovery possible.</p> 3353 <div class="ed-mobile-actions"> 3354 <a href="${donateUrl}" target="_blank" rel="noopener noreferrer">Support Survivor Care</a> 3355 <a href="${requestHelpUrl}" target="_blank" rel="noopener noreferrer">Request Help</a> 3356 </div> 3357 </section> 3358 <figure class="ed-mobile-lifelong-visual"> 3359 <img src="/assets/captured/b8752ecd9c945a05.jpeg" alt="Interview still from a Lifeboat Project story video" width="825" height="420" loading="lazy" decoding="async"> 3360 <figcaption>Support continues through the appointments, paperwork, housing steps, and relationships that follow stabilization.</figcaption> 3361 </figure> 3362 <section class="ed-mobile-shield-list ed-mobile-care-list" aria-label="Lifelong care priorities"> 3363 <article><span>01</span><div><h2>Immediate Safety</h2><p>Crisis response, safety planning, and secure support help survivors take the first steps out of danger.</p></div></article> 3364 <article><span>02</span><div><h2>Whole-Person Healing</h2><p>Trauma-informed counseling, healthcare connections, and daily stability support recovery over time.</p></div></article> 3365 <article><span>03</span><div><h2>Advocacy & Access</h2><p>Guidance through legal, housing, benefits, education, and employment systems keeps progress moving.</p></div></article> 3366 <article><span>04</span><div><h2>Community for Life</h2><p>Mentoring, healthy relationships, and continued check-ins help survivors build trust, purpose, and independence.</p></div></article> 3367 </section> 3368 <section class="ed-mobile-article ed-mobile-lifelong-note"> 3369 <h2>Patient, practical, close to home.</h2> 3370 <p>
3370Long-term care means staying present for the paperwork, appointments, housing transitions, setbacks, milestones, and new dreams that come after immediate crisis support.</p> 3371 </section> 3372 `; 3373 } 3374 3375 if (key === "/get-involved" || key === "/volunteer" || key === "/about-4-1") { 3376 const isVolunteerPage = key === "/volunteer" || key === "/about-4-1"; 3377 const headerImage = isVolunteerPage ? volunteerHeaderImage : getInvolvedHeaderImage; 3378 const headerAlt = isVolunteerPage 3379 ? "Volunteer. Your time. Their hope. Together, we can make a difference." 3380 : "Get Involved. Together, we can end human trafficking and bring hope to survivors."; 3381 const headerTitle = isVolunteerPage ? "Volunteer" : "Get Involved"; 3382 const headerDescription = isVolunteerPage 3383 ? "Your time. Their hope. Together, we can make a difference." 3384 : "Choose a practical path to volunteer, request education, or support the mission."; 3385 const headerWidth = isVolunteerPage ? 1774 : 1717; 3386 const headerHeight = isVolunteerPage ? 887 : 916; 3387 const mobileActionCards = [ 3388 { 3389 title: "Volunteer", 3390 body: "", 3391 href: volunteerApplyEmail, 3392 target: "", 3393 rel: "", 3394 cta: "Apply Today", 3395 imageAlt: "Back of a group of volunteers", 3396 imageSrc: "/assets/captured/6f40a75b55b16457.jpeg", 3397 kind: "volunteer", 3398 }, 3399 { 3400 title: "Request a Speaker", 3401 body: "", 3402 href: "/request-a-speaker/", 3403 target: "_self", 3404 rel: "", 3405 cta: "Request a Speaker", 3406 imageAlt: "Jill Cohen speaking at a podium", 3407 imageSrc: "/assets/captured/a64c350ca655a41e.jpg", 3408 kind: "speaker", 3409 }, 3410 ]; 3411 3412 return ` 3413 <section class="ed-mobile-get-involved-header" aria-labelledby="ed-mobile-get-involved-title"> 3414 <img src="${headerImage}" alt="${headerAlt}" width="${headerWidth}" height="${headerHeight}" loading="eager" fetchpriority="high"> 3415 <div class="ed-screen-reader-only"> 3416 <h1 id="ed-mobile-get-involved-title">${headerTitle}</h1> 3417 <p>${headerDescription}</p> 3418 </div> 3419 </section> 3420 <section class="ed-mobile-action-wrap" aria-label="Ways to get involved"> 3421 ${renderGetInvolvedActionBand(mobileActionCards, "mobile")} 3422 </section> 3423 <section class="ed-mobile-grid ed-mobile-support-grid"> 3424 ${mobileCard("Donate", "Give directly to survivor support and prevention work.", donateUrl, "Donate")} 3425 ${mobileCard("International Partnerships", "Start a conversation about mission-aligned collaboration.", "/international-partnerships/")} 3426 </section> 3427 `; 3428 } 3429 3430 if (key === "/request-a-speaker") { 3431 return ` 3432 <section class="ed-mobile-hero compact"> 3433 <p class="ed-mobile-kicker">Request a Speaker</p> 3434 <h1>Bring prevention education to your organization.</h1> 3435 <p>Use the contact form to share your event details, audience, preferred date, and topic needs.</p> 3436 <div class="ed-mobile-actions"><a href="/contact/">Request Through Contact Form</a></div> 3437 </section> 3438 `; 3439 } 3440 3441 if (key === "/international-partnership-form" || key === "/international-partner-form" || key === "/partner-form") { 3442 return ` 3443 <section class="ed-mobile-hero compact"> 3444 <p class="ed-mobile-kicker">Partner Interest</p> 3445 <h1>Start an international partnership conversation.</h1> 3446 <p>Tell The Lifeboat Project who you are, where you work, and what type of collaboration you would like to explore.</p> 3447 <div class="ed-mobile-actions"><a href="/contact/">Contact the Team</a></div> 3448 </section> 3449 `; 3450 } 3451 3452 if (key === "/contact") { 3453 return ` 3454 <section class="ed-mobile-hero compact"> 3455 <p class="ed-mobile-kicker">Contact</p> 3456 <h1>Reach The Lifeboat Project quickly.</h1> 3457 <p>Use email or phone and share as much or as little as you feel comfortable sharing.</p> 3458 </section> 3459 <section class="ed-mobile-contact-card" aria-label="Fast contact options"> 3460 <div class="ed-mobile-contact-actions"> 3461 <a href="mailto:[email protected]">Email Lifeboat<span>
3461[email protected]</span></a> 3462 <a href="tel:+14073108905">Call Lifeboat<span>407-310-8905</span></a> 3463 </div> 3464 <p class="ed-mobile-contact-note"> 3465 For agency referrals or longer intake details: 3466 <a href="${requestHelpUrl}" target="_blank" rel="noreferrer noopener">Open referral/application form</a> 3467 </p> 3468 </section> 3469 `; 3470 } 3471 3472 return ""; 3473 } 3474 3475 function installMobileContactForm(section) { 3476 const form = section.querySelector("[data-ed-mobile-contact-form]"); 3477 if (!form || form.dataset.edMobileContactBound === "true") return; 3478 form.dataset.edMobileContactBound = "true"; 3479 3480 form.addEventListener("submit", async (event) => { 3481 event.preventDefault(); 3482 const status = form.querySelector(".ed-mobile-contact-status"); 3483 const formData = new FormData(form); 3484 const payload = Object.fromEntries(formData.entries()); 3485 3486 if (status) { 3487 status.textContent = "Sending..."; 3488 status.dataset.state = "info"; 3489 } 3490 3491 try { 3492 const response = await fetch("/api/contact", { 3493 method: "POST", 3494 headers: { "content-type": "application/json" }, 3495 body: JSON.stringify(payload), 3496 }); 3497 const result = await response.json().catch(() => ({})); 3498 if (!response.ok || !result.ok) throw new Error(result.error || "Unable to send this message right now."); 3499 window.lifeboatAnalytics?.track('contact_submit_success'); 3500 form.reset(); 3501 if (status) { 3502 status.textContent = result.message || "Thanks, your message was sent."; 3503 status.dataset.state = "success"; 3504 } 3505 } catch (error) { 3506 const message = error instanceof Error ? error.message : "Unable to send this message right now."; 3507 if (status) { 3508 status.textContent = `${message} You can also email [email protected].`; 3509 status.dataset.state = "error"; 3510 } 3511 } 3512 }); 3513 } 3514 3515 function ensureKnowSignsMobilePage() { 3516 const key = rawPath.replace(/\/$/, "") || "/"; 3517 if (key !== "/know-the-signs" && key !== "/about-4") return; 3518 if (!isMobileShellViewport()) return; 3519 3520 document.documentElement.classList.add("ed-mobile-shell-root"); 3521 document.body.classList.add("ed-mobile-shell"); 3522 3523 const pageContent = document.querySelector("#PAGES_CONTAINER") || document.querySelector("#masterPage") || document.body; 3524 const sitePages = pageContent.querySelector(":scope > #SITE_PAGES") || document.querySelector("#SITE_PAGES"); 3525 3526 document 3527 .querySelectorAll( 3528 "#SITE_PAGES, [data-ed-email-update='know-signs-header'], [data-ed-email-update='know-signs-education']", 3529 ) 3530 .forEach((element) => { 3531 element.classList.add("ed-mobile-native-hidden"); 3532 element.setAttribute("aria-hidden", "true"); 3533 }); 3534 3535 let section = pageContent.querySelector(":scope > .ed-mobile-page"); 3536 if (!section) { 3537 section = document.createElement("main"); 3538 section.className = "ed-mobile-page"; 3539 section.dataset.edMobilePage = "true"; 3540 pageContent.insertBefore(section, sitePages || pageContent.firstChild); 3541 } 3542 3543 if (section.dataset.edMobileRoute !== key || section.dataset.edMobileSource !== "know-signs-explicit") { 3544 section.dataset.edMobileRoute = key; 3545 section.dataset.edMobileSource = "know-signs-explicit"; 3546 section.innerHTML = mobileKnowSignsPageHtml(); 3547 } 3548 } 3549 3550 function installMobileShell(forceFallbackRefresh = false) { 3551 const useNativeSponsorsPage = shouldUseNativeSponsorsPage(); 3552 const useNativeDonorDockPage = shouldUseNativeDonorDockPage(); 3553 const mobileViewport = isMobileShellViewport(); 3554 const enabled = mobileViewport; 3555 document.documentElement.classList.toggle("ed-mobile-shell-root", enabled); 3556 document.body.classList.toggle("ed-mobile-shell", enabled); 3557 if (!enabled) { 3558 document.querySelectorAll(".ed-mobile-native-hidden").forEach((element) => { 3559 element.classList.remove("ed-mobile-native-hidden"); 3560 element.removeAttribute("aria-hidden"); 3561 }); 3562 if (useNativeDonorDockPage) { 3563 document.querySelector(".ed-mobile-page")?.remove(); 3564 document.querySelector(".ed-mobile-header")?.remove(); 3565 document.getElementById("ed-mobile-menu")?.remove(); 3566 removeMobileDonorFooter(); 3567 } else if (shouldUseSharedDesktopDonorFooter()) { 3568 ensureMobileDonorFooter(); 3569 } else { 3570 removeMobileDonorFooter(); 3571 } 3572 return; 3573 } 3574 3575 let header = document.querySelector(".ed-mobile-header"); 3576 if (!header) { 3577 header = document.createElement("header"); 3578 header.className = "ed-mobile-header"; 3579 header.innerHTML = ` 3580 <a class="ed-mobile-brand" href="/" aria-label="The Lifeboat Project home"> 3581 <img src="${mobileLogoImage}" alt="The Lifeboat Project"> 3582 </a> 3583 <a class="ed-mobile-donate" href="${donateUrl}" target="_blank" rel="noopener noreferrer">Donate</a> 3584 <button class="ed-mobile-menu-button" type="button" aria-expanded="false" aria-controls="ed-mobile-menu">
3585 <span></span><span></span><span></span> 3586 </button> 3587 `; 3588 document.body.insertBefore(header, document.body.firstChild); 3589 } 3590 3591 let menu = document.getElementById("ed-mobile-menu"); 3592 if (!menu) { 3593 menu = document.createElement("nav"); 3594 menu.id = "ed-mobile-menu"; 3595 menu.className = "ed-mobile-menu"; 3596 menu.setAttribute("aria-label", "Mobile navigation"); 3597 header.insertAdjacentElement("afterend", menu); 3598 } 3599 const menuMarkup = mobileLinkItems().map((item) => mobileAnchor(item)).join(""); 3600 if (renderedNavigation.get(menu) !== menuMarkup) { 3601 menu.innerHTML = menuMarkup; 3602 renderedNavigation.set(menu, menuMarkup); 3603 } 3604 3605 const button = header.querySelector(".ed-mobile-menu-button"); 3606 const syncMobileMenuViewport = () => { 3607 const viewportHeight = window.visualViewport?.height || window.innerHeight || document.documentElement.clientHeight || 0; 3608 const headerHeight = Math.ceil(header.getBoundingClientRect().height || 76); 3609 const menuHeight = Math.max(260, Math.floor(viewportHeight - headerHeight)); 3610 menu.style.setProperty("--ed-mobile-header-height", `${headerHeight}px`); 3611 menu.style.setProperty("--ed-mobile-menu-height", `${menuHeight}px`); 3612 }; 3613 syncMobileMenuViewport(); 3614 if (menu.dataset.edMobileViewportBound !== "true") { 3615 menu.dataset.edMobileViewportBound = "true"; 3616 window.addEventListener("resize", syncMobileMenuViewport, { passive: true }); 3617 window.addEventListener("orientationchange", syncMobileMenuViewport, { passive: true }); 3618 window.visualViewport?.addEventListener("resize", syncMobileMenuViewport, { passive: true }); 3619 window.visualViewport?.addEventListener("scroll", syncMobileMenuViewport, { passive: true }); 3620 } 3621 if (button && menu && button.dataset.edMobileMenuBound !== "true") { 3622 button.dataset.edMobileMenuBound = "true"; 3623 button.addEventListener("click", () => { 3624 syncMobileMenuViewport(); 3625 const open = header.classList.toggle("is-open"); 3626 menu.classList.toggle("is-open", open); 3627 button.setAttribute("aria-expanded", open ? "true" : "false"); 3628 if (open) menu.scrollTop = 0; 3629 }); 3630 menu.addEventListener("click", (event) => { 3631 const target = event.target instanceof Element ? event.target.closest("a") : null; 3632 if (!target) return; 3633 header.classList.remove("is-open"); 3634 menu.classList.remove("is-open"); 3635 button.setAttribute("aria-expanded", "false"); 3636 }); 3637 } 3638 3639 if (useNativeDonorDockPage) { 3640 document.querySelector(".ed-mobile-page")?.remove(); 3641 removeMobileDonorFooter(); 3642 return; 3643 } 3644 3645 if (useNativeSponsorsPage) { 3646 document.querySelector(".ed-mobile-page")?.remove(); 3647 ensureMobileDonorFooter({ native: true, hideSponsors: true }); 3648 return; 3649 } 3650 3651 ensureMobileDonorFooter(); 3652 3653 const explicitHtml = mobilePageHtml(); 3654 const html = explicitHtml || mobileNativeFallbackHtml(); 3655 const htmlSource = explicitHtml ? "explicit" : "fallback"; 3656 const routeKey = rawPath.replace(/\/$/, "") || "/"; 3657 const pageContent = document.querySelector("#PAGES_CONTAINER") || document.querySelector("#masterPage") || document.body; 3658 const sitePages = pageContent.querySelector(":scope > #SITE_PAGES") || document.querySelector("#SITE_PAGES"); 3659 3660 if (!html) return; 3661 3662 sitePages?.classList.add("ed-mobile-native-hidden"); 3663 sitePages?.setAttribute("aria-hidden", "true"); 3664 document 3665 .querySelectorAll('img[src*="6b1d7e06f32ed327"], img[src*="a900460d79f6071b"]') 3666 .forEach((image) => { 3667 const wrapper = image.closest("li, a") || image; 3668 wrapper.classList.add("ed-mobile-native-hidden"); 3669 wrapper.setAttribute("aria-hidden", "true"); 3670 }); 3671 if (routeKey === "/what-we-do") { 3672 document 3673 .querySelectorAll( 3674 ".ed-what-hero-section, [data-ed-email-update='what-we-do-believe-intro'], [data-ed-email-update='shield-program'], .ed-lifelong-care-section", 3675 ) 3676 .forEach((element) => { 3677 element.classList.add("ed-mobile-native-hidden"); 3678 element.setAttribute("aria-hidden", "true"); 3679 }); 3680 } 3681 if (htmlSource === "fallback" || htmlSource === "explicit") { 3682 document 3683 .querySelectorAll( 3684 [ 3685 ".ed-blog-index", 3686 ".ed-board-directors-page", 3687 ".ed-donor-page", 3688 ".ed-events-page", 3689 ".ed-financial-page", 3690 ".ed-international-page", 3691 ".ed-know-page", 3692 ".ed-lifesavers-page", 3693 ".ed-sponsors-page", 3694 ".ed-what-hero-section", 3695 ".ed-lifelong-care-section", 3696 "[data-ed-email-update='what-we-do-believe-intro']", 3697 "[data-ed-email-update='shield-program']", 3698 ].join(", "), 3699 ) 3700 .forEach((element) => { 3701 element.classList.add("ed-mobile-native-hidden"); 3702 element.setAttribute("aria-hidden", "true"); 3703 }); 3704 } 3705 3706 let section = pageContent.querySelector(":scope > .ed-mobile-page"); 3707 if (!section) { 3708 section = document.createElement("main"); 3709 section.className = "ed-mobile-page"; 3710 section.dataset.edMobilePage = "true"; 3711 const bodyPageAnchor = 3712 pageContent === document.body 3713 ? document.querySelector("body > main:not(.ed-mobile-page), body > footer") 3714 : null; 3715 pageContent.insertBefore(section, bodyPageAnchor || sitePages || pageContent.firstChild); 3716 } 3717 3718 if ( 3719 section.dataset.edMobileRoute !== routeKey || 3720 (forceFallbackRefresh && section.dataset.edMobileSource === "fallback") 3721 ) { 3722 section.dataset.edMobileRoute = routeKey; 3723 section.dataset.edMobileSource = htmlSource; 3724 section.innerHTML = html; 3725 } 3726 3727 installMobileContactForm(section); 3728 installPartnerForms(section); 3729 section.querySelectorAll(".ed-mobile-video-hero video").forEach(bindCleanHomeVideoLoop); 3730 syncMobileSpotItStopItVideos(section); 3731 } 3732 3733 function closestRepeaterItem(element) {
3734 let current = element; 3735 while (current && current !== document.body) { 3736 if (String(current.className || "").includes("wixui-repeater__item")) return current; 3737 current = current.parentElement; 3738 } 3739 return null; 3740 } 3741 3742 function closestPageSection(element) { 3743 let current = element; 3744 while (current && current !== document.body) { 3745 if ( 3746 current.matches?.("section.wixui-section") || 3747 current.getAttribute?.("data-block-level-container") === "ClassicSection" 3748 ) { 3749 return current; 3750 } 3751 current = current.parentElement; 3752 } 3753 return null; 3754 } 3755 3756 function hideRepeaterItemContaining(text) { 3757 elementsByExactText(text).forEach((element) => { 3758 hideElement(closestRepeaterItem(element) || element.closest("section") || element.parentElement); 3759 }); 3760 } 3761 3762 function hideSectionContaining(text) { 3763 elementsByExactText(text).forEach((element) => { 3764 hideElement(closestPageSection(element) || element.closest("section") || element.parentElement); 3765 }); 3766 } 3767 3768 function hideSectionsMatching(pattern) { 3769 document.querySelectorAll("main section.wixui-section").forEach((section) => { 3770 if (pattern.test(clean(section.innerText || section.textContent))) hideElement(section); 3771 }); 3772 } 3773 3774 function hideCardsContaining(pattern) { 3775 document.querySelectorAll("body *").forEach((element) => { 3776 if (element.children.length > 0) return; 3777 if (!pattern.test(clean(element.innerText || element.textContent))) return; 3778 hideElement(closestRepeaterItem(element) || element.closest("[data-hook='item']") || element.closest("section") || element); 3779 }); 3780 } 3781 3782 function removeSponsorVideo(title) { 3783 document.querySelectorAll("body *").forEach((element) => { 3784 if (!elementTextEquals(element, title)) return; 3785 const card = 3786 element.closest("[data-hook='slide']") || 3787 element.closest(".WXhjVQ") || 3788 element.closest(".C9Zjgc") || 3789 closestRepeaterItem(element); 3790 hideElement(card || element); 3791 }); 3792 } 3793 3794 function blogCardTitle(card) { 3795 const title = card?.querySelector?.("[data-hook='post-title'], h2"); 3796 return clean(title?.innerText || title?.textContent || ""); 3797 } 3798 3799 function blogPostForTitle(title) { 3800 return blogPosts.find((post) => post.title === title) || null; 3801 } 3802 3803 function blogCards() { 3804 return [...document.querySelectorAll(".gallery-item-container.visible")].filter((card) => 3805 Boolean(blogPostForTitle(blogCardTitle(card))), 3806 ); 3807 } 3808 3809 function findBlogCard(title) { 3810 return blogCards().find((card) => blogCardTitle(card) === title) || null; 3811 } 3812 3813 function installBlogCardRouting(card, post = blogPostForTitle(blogCardTitle(card))) { 3814 if (!card || !post) return; 3815 3816 const wrapper = card.closest(".item-link-wrapper") || card; 3817 wrapper.dataset.lifeboatBlogPostUrl = post.path; 3818 card.dataset.lifeboatBlogPostUrl = post.path; 3819 wrapper.classList.add("lifeboat-clickable-blog-card"); 3820 card.classList.add("lifeboat-clickable-blog-card"); 3821 wrapper.setAttribute("role", "link"); 3822 wrapper.setAttribute("tabindex", "0"); 3823 wrapper.setAttribute("aria-label", post.title); 3824 wrapper.style.setProperty("cursor", "pointer", "important"); 3825 card.style.setProperty("cursor", "pointer", "important"); 3826 3827 wrapper.querySelectorAll("a[href]").forEach((anchor) => { 3828 const href = anchor.getAttribute("href") || ""; 3829 const text = clean(anchor.innerText || anchor.textContent); 3830 if (href.includes("/post/") || text === post.title) { 3831 anchor.setAttribute("href", post.path); 3832 } 3833 }); 3834 3835 if (wrapper.dataset.lifeboatBlogClickBound === "true") return; 3836 wrapper.dataset.lifeboatBlogClickBound = "true"; 3837 3838 const navigateToCardPost = (event) => { 3839 const target = event.target instanceof Element ? event.target : null; 3840 if (!target) return; 3841 3842 const control = target.closest("button, input, select, textarea, summary, [role='button']"); 3843 if (control && wrapper.contains(control)) return; 3844 3845 const anchor = target.closest("a[href]"); 3846 if (anchor && wrapper.contains(anchor) && (anchor.getAttribute("href") || "").includes("/post/")) { 3847 return; 3848 } 3849 3850 const postUrl = wrapper.dataset.lifeboatBlogPostUrl; 3851 if (!postUrl) return; 3852 3853 event.preventDefault(); 3854 event.stopPropagation(); 3855 event.stopImmediatePropagation?.(); 3856 window.location.href = postUrl; 3857 }; 3858 3859 wrapper.addEventListener("click", navigateToCardPost, true); 3860 wrapper.addEventListener("keydown", (event) => { 3861 if (event.key !== "Enter" && event.key !== " ") return; 3862 if (document.activeElement !== wrapper) return; 3863 3864 event.preventDefault(); 3865 event.stopPropagation(); 3866 window.location.href = wrapper.dataset.lifeboatBlogPostUrl || post.path; 3867 }); 3868 } 3869 3870 function renderEditorialBlogTile(post) { 3871 return ` 3872 <a class="ed-blog-tile" href="${post.path}">
3873 <span class="ed-blog-tile-image"> 3874 <img src="${post.image}" alt="${escapeMarkup(post.title)}" loading="eager" decoding="async"> 3875 </span> 3876 <span class="ed-blog-tile-copy"> 3877 <span class="ed-blog-meta"> 3878 <span>${escapeMarkup(blogCategory(post))}</span> 3879 <span>${escapeMarkup(post.date)}</span> 3880 </span> 3881 <strong>${escapeMarkup(post.title)}</strong> 3882 <span>${escapeMarkup(blogSummary(post))}</span> 3883 <em>Read story</em> 3884 </span> 3885 </a> 3886 `; 3887 } 3888 3889 function renderEditorialBlogIndex() { 3890 const [featuredPost, ...secondaryPosts] = blogPosts; 3891 3892 return ` 3893 <div class="ed-blog-shell"> 3894 <header class="ed-blog-topline"> 3895 <p class="ed-blog-kicker">Stories & Updates</p> 3896 <h1>Stories from The Lifeboat Project</h1> 3897 <p>Recent moments, partnerships, and community updates from the work happening around the mission.</p> 3898 </header> 3899 3900 <div class="ed-blog-lead-grid"> 3901 <a class="ed-blog-feature" href="${featuredPost.path}"> 3902 <span class="ed-blog-feature-image"> 3903 <img src="${featuredPost.image}" alt="${escapeMarkup(featuredPost.title)}" loading="eager" decoding="async"> 3904 </span> 3905 <span class="ed-blog-feature-copy"> 3906 <span class="ed-blog-meta"> 3907 <span>${escapeMarkup(blogCategory(featuredPost))}</span> 3908 <span>${escapeMarkup(featuredPost.date)}</span> 3909 </span> 3910 <strong>${escapeMarkup(featuredPost.title)}</strong> 3911 <span>${escapeMarkup(blogSummary(featuredPost))}</span> 3912 <em>Read the featured story</em> 3913 </span> 3914 </a> 3915 3916 <aside class="ed-blog-side-panel" aria-label="Blog editorial focus"> 3917 <p>In this section</p> 3918 <h2>Community wins, event recaps, and mission moments.</h2> 3919 <ul> 3920 <li>Leadership updates</li> 3921 <li>Partnership highlights</li> 3922 <li>Fundraiser recaps</li> 3923 </ul> 3924 </aside> 3925 </div> 3926 3927 <div class="ed-blog-grid" aria-label="More recent posts"> 3928 ${secondaryPosts.map((post) => renderEditorialBlogTile(post)).join("")} 3929 </div> 3930 </div> 3931 `; 3932 } 3933 3934 function nativeBlogIndexSection() { 3935 return ( 3936 document.getElementById("comp-lt8riasv") || 3937 document.querySelector("[data-hook='feed-page-root']")?.closest("section.wixui-section") 3938 ); 3939 } 3940 3941 function installEditorialBlogIndex() { 3942 if (path !== "/blog") return; 3943 3944 const nativeSection = nativeBlogIndexSection(); 3945 const existing = document.querySelector("[data-ed-email-update='editorial-blog-index']"); 3946 3947 if (!nativeSection) return; 3948 3949 nativeSection.classList.add("ed-blog-native-hidden"); 3950 nativeSection.setAttribute("aria-hidden", "true"); 3951 3952 let section = existing; 3953 if (!section) { 3954 section = document.createElement("section"); 3955 section.className = "ed-blog-index"; 3956 section.dataset.edEmailUpdate = "editorial-blog-index"; 3957 section.setAttribute("aria-labelledby", "ed-blog-title"); 3958 nativeSection.parentNode?.insertBefore(section, nativeSection); 3959 } 3960 3961 section.innerHTML = renderEditorialBlogIndex(); 3962 const title = section.querySelector(".ed-blog-topline h1"); 3963 if (title) title.id = "ed-blog-title"; 3964 } 3965 3966 function imageTypeFor(src) { 3967 return src.endsWith(".webp") ? "image/webp" : /\.jpe?g$/i.test(src) ? "image/jpeg" : "image/png"; 3968 } 3969 3970 function srcsetDescriptorWeight(descriptor) { 3971 if (descriptor.endsWith("x")) { 3972 return Number.parseFloat(descriptor) || 1; 3973 } 3974 if (descriptor.endsWith("w")) { 3975 return (Number.parseFloat(descriptor) || 1) / 1000; 3976 } 3977 return 1; 3978 } 3979 3980 const capturedImageFallbacks = new Map([ 3981 ["/assets/captured/45903583af6321c3.jpg", "/assets/captured/bb765029e0dec22c.jpg"], 3982 ["/assets/captured/21843b91b0d34777.jpg", "/assets/captured/8256887a1059a4a9.jpg"], 3983 ["/assets/captured/6200ad9b8cca7f14.jpg", lindaKennedyMartinPortrait], 3984 ["/assets/captured/4c67845d34762710.jpg", lindaKennedyMartinPortrait], 3985 ["/assets/captured/8a7106cba4ed5351.jpg", lindaKennedyMartinPortrait], 3986 ["/assets/captured/11e0aabaf9436976.jpg", "/assets/captured/cc497b65890bcafa.jpg"], 3987 ["/assets/captured/ed26217795ffb03c.jpg", "/assets/captured/296423e421bd6a18.jpg"], 3988 ["/assets/captured/75e814fa8db3ca2c.jpg", "/assets/captured/c64f186f3bcffcac.jpg"], 3989 ["/assets/captured/54f647786239c0ef.jpg", "/assets/captured/cef62704a5d998fe.jpg"], 3990 ["/assets/captured/7ebbdfb8ed497993.jpg", "/assets/captured/cef62704a5d998fe.jpg"], 3991 ["/assets/captured/4bf3bf300293230a.jpg", "/assets/captured/0c3cc7932809d7cd.jpg"], 3992 ["/assets/captured/cb67469f22eef7a2.jpeg", "/assets/captured/bc486e6e5729903f.jpeg"], 3993 ["/assets/captured/59ca8dffcccdda21.jpg", "/assets/captured/c5f78ac048be0217.jpg"], 3994 ["/assets/captured/41aecf40eb472101.jpeg", "/assets/captured/80409f65c3f6ecdc.jpeg"], 3995 ["/assets/captured/4125291da16c9335.jpeg", "/assets/captured/f6c2fb93aaa14226.jpeg"], 3996 ["/assets/captured/0da33e58e8cf76bb.jpeg", "/assets/captured/cb1f2549
3996c4b8fc68.jpeg"], 3997 ["/assets/captured/0e3c3b6fa5ad9a62.jpeg", "/assets/captured/c45e2f28e5bc52b0.jpeg"], 3998 ]); 3999 4000 function mediaFallbackFor(value) { 4001 const rawValue = String(value || ""); 4002 if (!rawValue) return ""; 4003 4004 for (const [source, replacement] of capturedImageFallbacks) { 4005 if (rawValue === source || rawValue.endsWith(source)) return replacement; 4006 } 4007 4008 return ""; 4009 } 4010 4011 function replaceCapturedImageFallbacks(value) { 4012 let nextValue = String(value || ""); 4013 4014 capturedImageFallbacks.forEach((replacement, source) => { 4015 nextValue = nextValue.replaceAll(source, replacement); 4016 }); 4017 4018 return nextValue; 4019 } 4020 4021 function srcsetCandidates(value) { 4022 return String(value || "") 4023 .split(/\s*,\s*/) 4024 .map((part) => { 4025 const match = part.trim().match(/^(.+?)(?:\s+(\d+(?:\.\d+)?x|\d+w))?$/); 4026 if (!match) return null; 4027 return { 4028 src: match[1], 4029 descriptor: match[2] || "1x", 4030 weight: srcsetDescriptorWeight(match[2] || "1x"), 4031 }; 4032 }) 4033 .filter((candidate) => candidate?.src); 4034 } 4035 4036 function bestSrcsetCandidate(value) { 4037 const candidates = srcsetCandidates(value); 4038 if (candidates.length < 2) return null; 4039 4040 return candidates.reduce((bestCandidate, candidate) => 4041 candidate.weight > bestCandidate.weight ? candidate : bestCandidate, 4042 ); 4043 } 4044 4045 function repairCapturedSrcsetImages() { 4046 document.querySelectorAll("img").forEach((image) => { 4047 const rawSrc = image.getAttribute("src") || ""; 4048 const rawSrcset = image.getAttribute("srcset") || ""; 4049 const fallbackSrc = mediaFallbackFor(rawSrc); 4050 4051 if (fallbackSrc) { 4052 image.setAttribute("src", fallbackSrc); 4053 image.src = fallbackSrc; 4054 } 4055 4056 if (rawSrcset.includes("/assets/captured/")) { 4057 const repairedSrcset = replaceCapturedImageFallbacks(rawSrcset); 4058 if (repairedSrcset !== rawSrcset) image.setAttribute("srcset", repairedSrcset); 4059 } 4060 4061 const candidateSource = rawSrc.includes(",") ? rawSrc : rawSrcset; 4062 if (!candidateSource.includes("/assets/captured/") || !candidateSource.includes(",")) return; 4063 4064 const best = bestSrcsetCandidate(replaceCapturedImageFallbacks(candidateSource)); 4065 if (!best) return; 4066 image.removeAttribute("srcset"); 4067 image.setAttribute("src", best.src); 4068 image.src = best.src; 4069 }); 4070 4071 document.querySelectorAll("source[srcset]").forEach((source) => { 4072 const rawSrcset = source.getAttribute("srcset") || ""; 4073 if (!rawSrcset.includes("/assets/captured/")) return; 4074 4075 const repairedSrcset = replaceCapturedImageFallbacks(rawSrcset); 4076 const best = repairedSrcset.includes(",") ? bestSrcsetCandidate(repairedSrcset) : null; 4077 source.setAttribute("srcset", best?.src || repairedSrcset); 4078 }); 4079 } 4080 4081 const socialIconFallbacks = new Map([ 4082 ["youtube", "/assets/updates/social/youtube.svg"], 4083 ["instagram", "/assets/updates/social/instagram.svg"], 4084 ]); 4085 4086 function repairFooterSocialIcons() {
4087 const socialCapturedFallbacks = [ 4088 { pattern: /6b1d7e06f32ed327|31ddba9b591e8be3/i, icon: "youtube" }, 4089 { pattern: /a900460d79f6071b|6e8ce0fb86da845c/i, icon: "instagram" }, 4090 ]; 4091 4092 document.querySelectorAll("img").forEach((image) => { 4093 const imageText = [ 4094 image.alt, 4095 image.getAttribute("src"), 4096 image.getAttribute("srcset"), 4097 image.closest("a")?.getAttribute("aria-label"), 4098 ] 4099 .map((value) => clean(value).toLowerCase()) 4100 .join(" "); 4101 const inferredIcon = socialCapturedFallbacks.find((fallback) => fallback.pattern.test(imageText))?.icon; 4102 const replacement = socialIconFallbacks.get(clean(image.alt).toLowerCase()) || socialIconFallbacks.get(inferredIcon); 4103 if (!replacement) return; 4104 4105 image.removeAttribute("srcset"); 4106 image.setAttribute("src", replacement); 4107 image.src = replacement; 4108 image.decoding = "async"; 4109 }); 4110 } 4111 4112 function promoteStoryThumbnailImages() { 4113 if (path !== "/stories") return; 4114 4115 document.querySelectorAll("img[alt]").forEach((image) => { 4116 const replacement = storyThumbnailImages.get(image.alt); 4117 if (!replacement) return; 4118 const absoluteReplacement = new URL(replacement, window.location.href).href; 4119 4120 image.removeAttribute("srcset"); 4121 if (image.getAttribute("src") !== replacement) { 4122 image.src = replacement; 4123 } 4124 if (image.currentSrc && image.currentSrc !== absoluteReplacement) { 4125 const replacementImage = document.createElement("img"); 4126 [...image.attributes].forEach((attribute) => { 4127 if (attribute.name === "src" || attribute.name === "srcset") return; 4128 replacementImage.setAttribute(attribute.name, attribute.value); 4129 }); 4130 replacementImage.src = replacement; 4131 image.replaceWith(replacementImage); 4132 } 4133 }); 4134 } 4135 4136 function installImageRepairObserver() { 4137 if (document.documentElement.dataset.edImageRepairObserver === "true") return; 4138 if (!document.body) return; 4139 4140 document.documentElement.dataset.edImageRepairObserver = "true"; 4141 let queued = false; 4142 const repair = () => { 4143 queued = false; 4144 repairCapturedSrcsetImages(); 4145 repairFooterSocialIcons(); 4146 repairTeamPortraitImages(); 4147 promoteStoryThumbnailImages(); 4148 ensureBlogInventory(); 4149 arrangeStoriesBlogCards(); 4150 }; 4151 const queueRepair = () => { 4152 if (queued) return; 4153 queued = true; 4154 window.setTimeout(repair, 80); 4155 }; 4156 4157 new MutationObserver(queueRepair).observe(document.body, { 4158 attributeFilter: ["src", "srcset"], 4159 attributes: true, 4160 childList: true, 4161 subtree: true, 4162 }); 4163 } 4164 4165 function setBlogCardContent(root, post) { 4166 root.querySelectorAll("a[href*='/post/']").forEach((anchor) => { 4167 anchor.href = post.path; 4168 }); 4169 root.querySelectorAll("[aria-label]").forEach((element) => { 4170 const label = element.getAttribute("aria-label") || ""; 4171 if (blogPosts.some((candidate) => label.includes(candidate.title))) { 4172 element.setAttribute("aria-label", post.title); 4173 } 4174 }); 4175 root.querySelectorAll("[data-hook='post-title'], h2").forEach((element) => { 4176 element.textContent = post.title; 4177 }); 4178 root.querySelectorAll("[data-hook='post-description']").forEach((element) => { 4179 element.textContent = post.excerpt; 4180 }); 4181 root.querySelectorAll("[data-hook='time-ago']").forEach((element) => { 4182 element.textContent = post.date; 4183 element.setAttribute("title", post.date); 4184 }); 4185 root.querySelectorAll("[data-hook='post-stats'] span").forEach((element) => { 4186 element.textContent = post.views; 4187 }); 4188 root.querySelectorAll("img").forEach((image) => { 4189 image.src = post.image; 4190 image.alt = post.title; 4191 }); 4192 root.querySelectorAll("source").forEach((source) => { 4193 source.srcset = post.image + " 1x"; 4194 source.type = imageTypeFor(post.image); 4195 }); 4196 4197 const card = root.matches?.(".gallery-item-container") ? root : root.querySelector(".gallery-item-container"); 4198 installBlogCardRouting(card, post); 4199 } 4200 4201 function resizeBlogList(list, options = {}) { 4202 const cards = [...list.querySelectorAll(".gallery-item-container.visible")]; 4203 const requiredHeight = cards.reduce((height, card) => { 4204 const top = parseFloat(card.style.top || "0") || 0; 4205 const cardHeight = 4206 parseFloat(card.style.height || "0") || card.getBoundingClientRect().height || 0; 4207 return Math.max(height, top + cardHeight); 4208 }, 0); 4209 4210 [ 4211 list, 4212 list.closest(".pro-gallery-margin-container"), 4213 list.closest(".pro-gallery.inline-styles"), 4214 ].forEach((element) => { 4215 if (!element || !requiredHeight) return; 4216 const currentHeight = parseFloat(element.style.height || "0") || 0; 4217 if (options.exact || currentHeight < requiredHeight) { 4218 element.style.setProperty("height", requiredHeight + "px", "important"); 4219 } 4220 }); 4221 } 4222 4223 function arrangeStoriesBlogCards() { 4224 if (path !== "/stories") return; 4225
4226 const orderedCards = blogPosts.map((post) => findBlogCard(post.title)).filter(Boolean); 4227 if (orderedCards.length < 2) return; 4228 4229 const sourceWrapper = orderedCards[0].closest(".item-link-wrapper"); 4230 const list = sourceWrapper?.parentElement; 4231 if (!list) return; 4232 4233 const listWidth = 4234 list.getBoundingClientRect().width || 4235 Math.max(document.documentElement.clientWidth - 40, 280); 4236 const viewportWidth = Math.min( 4237 document.documentElement.clientWidth || window.innerWidth, 4238 window.visualViewport?.width || window.innerWidth, 4239 ); 4240 4241 let columns = 1; 4242 if (viewportWidth >= 1180 && listWidth >= 1180) { 4243 columns = 5; 4244 } else if (viewportWidth >= 820 && listWidth >= 820) { 4245 columns = 3; 4246 } else if (viewportWidth >= 560 && listWidth >= 560) { 4247 columns = 2; 4248 } 4249 4250 const maxGap = columns === 5 ? 40 : 32; 4251 const minCardWidth = columns === 5 ? 220 : 240; 4252 const gap = 4253 columns > 1 4254 ? Math.min(maxGap, Math.max(18, (listWidth - minCardWidth * columns) / (columns - 1))) 4255 : 0; 4256 const cardWidth = Math.max( 4257 220, 4258 Math.floor((listWidth - gap * (columns - 1)) / columns), 4259 ); 4260 const cardHeight = Math.max( 4261 ...orderedCards.map((card) => { 4262 return ( 4263 parseFloat(card.style.height || "0") || 4264 card.getBoundingClientRect().height || 4265 548.75 4266 ); 4267 }), 4268 548.75, 4269 ); 4270 const rowGap = columns === 1 ? 24 : 32; 4271 4272 orderedCards.forEach((card, index) => { 4273 const row = Math.floor(index / columns); 4274 const column = index % columns; 4275 card.style.setProperty("display", "block", "important"); 4276 card.style.setProperty("opacity", "1", "important"); 4277 card.style.setProperty("top", row * (cardHeight + rowGap) + "px", "important"); 4278 card.style.setProperty("left", column * (cardWidth + gap) + "px", "important"); 4279 card.style.setProperty("width", cardWidth + "px", "important"); 4280 card.style.setProperty("height", cardHeight + "px", "important"); 4281 }); 4282 4283 resizeBlogList(list, { exact: true }); 4284 } 4285 4286 function ensureBlogInventory() { 4287 if (path !== "/blog" && path !== "/stories") return; 4288 4289 const initialCards = blogCards(); 4290 blogPosts.forEach((post, index) => { 4291 const existing = findBlogCard(post.title); 4292 if (existing) { 4293 setBlogCardContent(existing.closest(".item-link-wrapper") || existing, post); 4294 return; 4295 } 4296 4297 const template = 4298 [...blogPosts] 4299 .slice(0, index) 4300 .reverse() 4301 .map((candidate) => findBlogCard(candidate.title)) 4302 .find(Boolean) || 4303 initialCards[initialCards.length - 1] || 4304 document.querySelector(".gallery-item-container.visible"); 4305 const sourceWrapper = template?.closest(".item-link-wrapper"); 4306 const list = sourceWrapper?.parentElement; 4307 if (!template || !sourceWrapper || !list) return; 4308 4309 const cloneWrapper = sourceWrapper.cloneNode(true); 4310 const cloneCard = cloneWrapper.querySelector(".gallery-item-container"); 4311 if (!cloneCard) return; 4312 4313 const hash = "lifeboat-static-blog-" + index; 4314 const sourceHash = template.getAttribute("data-id") || template.getAttribute("data-hash") || ""; 4315 const sourceHashCompact = sourceHash.replace(/-/g, ""); 4316 cloneWrapper.setAttribute("data-id", hash); 4317 cloneWrapper.setAttribute("data-idx", String(index)); 4318 cloneCard.setAttribute("data-id", hash); 4319 cloneCard.setAttribute("data-hash", hash); 4320 cloneCard.setAttribute("data-idx", String(index)); 4321 cloneWrapper.querySelectorAll("[data-idx]").forEach((element) => { 4322 element.setAttribute("data-idx", String(index)); 4323 }); 4324 cloneWrapper.querySelectorAll("[id]").forEach((element) => { 4325 element.id = element.id 4326 .replaceAll(sourceHash, hash) 4327 .replaceAll(sourceHashCompact, hash.replace(/-/g, "")); 4328 }); 4329 4330 const cards = [...list.querySelectorAll(".gallery-item-container.visible")]; 4331 const templateHeight = parseFloat(template.style.height || "340.5") || 340.5; 4332 const maxBottom = cards.reduce((height, card) => { 4333 const top = parseFloat(card.style.top || "0") || 0; 4334 const cardHeight = parseFloat(card.style.height || String(templateHeight)) || templateHeight; 4335 return Math.max(height, top + cardHeight); 4336 }, 0); 4337 cloneCard.style.setProperty("top", maxBottom + 32 + "px", "important"); 4338 cloneCard.style.setProperty("display", "block", "important"); 4339 cloneCard.style.setProperty("opacity", "1", "important"); 4340 4341 setBlogCardContent(cloneWrapper, post); 4342 list.appendChild(cloneWrapper); 4343 resizeBlogList(list); 4344 }); 4345 4346 document.documentElement.dataset.lifeboatBlogPostCount = String(blogCards().length);
4347 blogCards().forEach((card) => installBlogCardRouting(card)); 4348 arrangeStoriesBlogCards(); 4349 } 4350 4351 const featuredFooterSponsors = currentSponsorLogos.map((sponsor) => ({ 4352 ...sponsor, 4353 alt: sponsor.footerAlt || sponsor.name, 4354 })); 4355 4356 function footerHasNativeSponsorLinks(footer) { 4357 const links = [...footer.querySelectorAll("a[href]")].map((link) => link.href); 4358 let matches = 0; 4359 4360 featuredFooterSponsors.forEach((sponsor) => { 4361 const host = new URL(sponsor.href).hostname.replace(/^www\./, ""); 4362 if (links.some((href) => href.includes(host))) matches += 1; 4363 }); 4364 4365 return matches >= 3; 4366 } 4367 4368 function renderSponsorLinks(sponsors, { duplicate = false } = {}) { 4369 const duplicateAttributes = duplicate ? ' tabindex="-1"' : ""; 4370 4371 return sponsors 4372 .map( 4373 (sponsor) => ` 4374 <a class="ed-footer-sponsor-link" href="${sponsor.href}" target="_blank" rel="noopener noreferrer"${duplicateAttributes}> 4375 <img src="${sponsor.src}" alt="${escapeMarkup(sponsor.alt || sponsor.footerAlt || sponsor.name)}" width="${sponsor.width}" height="${sponsor.height}" loading="eager" decoding="async"> 4376 </a> 4377 `, 4378 ) 4379 .join(""); 4380 } 4381 4382 function renderFooterSponsorLinks(options = {}) { 4383 return renderSponsorLinks(featuredFooterSponsors, options); 4384 } 4385 4386 function renderFooterSponsorTrack(sponsors = featuredFooterSponsors) { 4387 return ` 4388 <div class="ed-footer-sponsor-track"> 4389 <div class="ed-footer-sponsor-set"> 4390 ${renderSponsorLinks(sponsors)} 4391 </div> 4392 <div class="ed-footer-sponsor-set" aria-hidden="true"> 4393 ${renderSponsorLinks(sponsors, { duplicate: true })} 4394 </div> 4395 </div> 4396 `; 4397 } 4398 4399 function syncFooterSponsorMarquees(root = document) { 4400 root.querySelectorAll(".ed-footer-sponsor-band").forEach((band) => { 4401 const track = band.querySelector(".ed-footer-sponsor-track"); 4402 const firstSet = track?.querySelector(".ed-footer-sponsor-set"); 4403 if (!track || !firstSet) return; 4404 4405 const sync = () => { 4406 const distance = firstSet.getBoundingClientRect().width || firstSet.scrollWidth || 0; 4407 if (distance <= 0) return; 4408 4409 track.style.setProperty("--ed-footer-sponsor-shift", `${-distance}px`); 4410 track.dataset.edFooterSponsorShift = String(Math.round(distance)); 4411 4412 const mobileContext = 4413 document.body.classList.contains("ed-mobile-shell") || 4414 Boolean(band.closest(".ed-mobile-footer-sponsors")); 4415 const pixelsPerSecond = mobileContext ? 32 : 42; 4416 const duration = Math.max(32, Math.min(78, distance / pixelsPerSecond)); 4417 track.style.setProperty("--ed-footer-sponsor-speed", `${duration.toFixed(2)}s`); 4418 }; 4419 4420 sync(); 4421 window.requestAnimationFrame(sync); 4422 4423 track.querySelectorAll("img").forEach((image) => { 4424 if (image.dataset.edFooterSponsorMeasureBound === "true") return; 4425 image.dataset.edFooterSponsorMeasureBound = "true"; 4426 if (!image.complete) { 4427 image.addEventListener("load", () => syncFooterSponsorMarquees(), { once: true }); 4428 image.addEventListener("error", () => syncFooterSponsorMarquees(), { once: true }); 4429 } 4430 }); 4431 }); 4432 } 4433 4434 function restoreHtmlEmbed(hostId, src) { 4435 const host = document.getElementById(hostId); 4436 if (!host || host.querySelector(`iframe[src="${src}"]`)) return false; 4437 4438 const wixIframe = document.createElement("wix-iframe"); 4439 const wrapper = document.createElement("div"); 4440 const iframe = document.createElement("iframe"); 4441 4442 wixIframe.setAttribute("data-src", ""); 4443 wixIframe.style.display = "block"; 4444 wixIframe.style.height = "100%"; 4445 wixIframe.style.width = "100%"; 4446 4447 wrapper.className = "vWU4ML"; 4448 wrapper.style.height = "100%"; 4449 wrapper.style.width = "100%"; 4450 4451 iframe.className = "xxJnkq"; 4452 iframe.title = "Embedded Content"; 4453 iframe.name = "htmlComp-iframe"; 4454 iframe.width = "100%"; 4455 iframe.height = "100%"; 4456 iframe.allow = "fullscreen"; 4457 iframe.setAttribute("data-src", ""); 4458 iframe.style.border = "0"; 4459 iframe.src = src; 4460 4461 wrapper.appendChild(iframe); 4462 wixIframe.appendChild(wrapper); 4463 host.replaceChildren(wixIframe); 4464 return true; 4465 } 4466 4467 function restoreAboutFourEmbeds() { 4468 if (path !== "/about-4") return; 4469 4470 restoreHtmlEmbed( 4471 "comp-mm6pct5a", 4472 "https://www-thelifeboatproject-org.filesusr.com/html/20fea4_d21991076612bb9cb35e740a9dd692e1.html", 4473 ); 4474 document 4475 .querySelectorAll("[data-ed-email-update='footer-sponsor-band']") 4476 .forEach((element) => element.remove()); 4477 document.querySelector("#SITE_FOOTER, footer")?.classList.remove("ed-footer-sponsor-host"); 4478 } 4479 4480 function placeKnowSignsSection(section) { 4481 const pageContent = document.querySelector("#PAGES_CONTAINER");
4482 const sitePages = pageContent?.querySelector(":scope > #SITE_PAGES"); 4483 const header = pageContent?.querySelector( 4484 ":scope > [data-ed-email-update='know-signs-header']", 4485 ); 4486 4487 if (pageContent && sitePages) { 4488 pageContent.insertBefore(section, header?.nextSibling || sitePages); 4489 return; 4490 } 4491 4492 const campaignSection = [...document.querySelectorAll("#SITE_PAGES section.wixui-section")].find((candidate) => 4493 /Spot it Stop it Campaign/i.test(clean(candidate.innerText || candidate.textContent)), 4494 ); 4495 if (campaignSection?.parentNode) { 4496 campaignSection.parentNode.insertBefore(section, campaignSection); 4497 return; 4498 } 4499 4500 const footer = document.querySelector("#SITE_FOOTER, footer"); 4501 if (footer?.parentNode) { 4502 footer.parentNode.insertBefore(section, footer); 4503 return; 4504 } 4505 4506 insertBeforeFooter(section); 4507 } 4508 4509 function hideAboutFourEmptySections() { 4510 if (path !== "/about-4") return; 4511 ["comp-mm5zwovp", "comp-mm6pco8t"].forEach((id) => { 4512 const section = document.getElementById(id); 4513 if (section && !clean(section.innerText || section.textContent)) hideElement(section); 4514 }); 4515 } 4516 4517 function installKnowSignsHeader() { 4518 if (path !== "/about-4") return; 4519 4520 document.body.classList.add("ed-know-signs-route"); 4521 const existing = document.querySelector("[data-ed-email-update='know-signs-header']"); 4522 4523 const placeHeader = (section) => { 4524 const pageContent = document.querySelector("#PAGES_CONTAINER"); 4525 const sitePages = pageContent?.querySelector(":scope > #SITE_PAGES"); 4526 const education = pageContent?.querySelector( 4527 ":scope > [data-ed-email-update='know-signs-education']", 4528 ); 4529 if (pageContent && sitePages) { 4530 pageContent.insertBefore(section, education || sitePages); 4531 return; 4532 } 4533 4534 const campaignSection = [...document.querySelectorAll("#SITE_PAGES section.wixui-section")].find((candidate) => 4535 /Spot it Stop it Campaign/i.test(clean(candidate.innerText || candidate.textContent)), 4536 ); 4537 if (campaignSection?.parentNode) { 4538 campaignSection.parentNode.insertBefore(section, campaignSection); 4539 return; 4540 } 4541 4542 insertBeforeFooter(section); 4543 }; 4544 4545 if (existing) { 4546 placeHeader(existing); 4547 return; 4548 } 4549 4550 const section = document.createElement("section"); 4551 section.className = "ed-know-signs-header"; 4552 section.dataset.edEmailUpdate = "know-signs-header"; 4553 section.setAttribute("aria-labelledby", "ed-know-signs-header-title"); 4554 section.innerHTML = ` 4555 <div class="ed-know-signs-header-frame"> 4556 <img src="${knowTheSignsHeaderImage}" alt="Know the Signs. Awareness can save lives. Learn the signs. Make a difference." width="1717" height="916" loading="eager" decoding="async" fetchpriority="high"> 4557 </div> 4558 <div class="ed-screen-reader-only"> 4559 <h1 id="ed-know-signs-header-title">Know the Signs</h1> 4560 <p>Awareness can save lives. Learn the signs. Make a difference.</p> 4561 </div> 4562 `; 4563 4564 placeHeader(section); 4565 } 4566 4567 function copyTextToClipboard(text) { 4568 if (navigator.clipboard?.writeText) return navigator.clipboard.writeText(text); 4569 4570 const textarea = document.createElement("textarea"); 4571 textarea.value = text; 4572 textarea.setAttribute("readonly", ""); 4573 textarea.style.position = "fixed"; 4574 textarea.style.top = "-999px"; 4575 document.body.appendChild(textarea); 4576 textarea.select(); 4577 document.execCommand("copy"); 4578 textarea.remove(); 4579 return Promise.resolve(); 4580 } 4581 4582 function bindKnowSignsInteractions(section) { 4583 section.querySelectorAll("[data-ed-know-toggle]").forEach((button) => { 4584 if (button.dataset.edKnowBound === "true") return; 4585 button.dataset.edKnowBound = "true"; 4586 button.addEventListener("click", () => { 4587 const isOpen = button.classList.toggle("is-open"); 4588 button.setAttribute("aria-expanded", String(isOpen)); 4589 }); 4590 }); 4591 4592 section.querySelectorAll("[data-ed-know-copy]").forEach((button) => { 4593 if (button.dataset.edKnowCopyBound === "true") return; 4594 button.dataset.edKnowCopyBound = "true"; 4595 const defaultLabel = button.getAttribute("aria-label") || "Copy"; 4596 button.addEventListener("click", () => { 4597 copyTextToClipboard(button.dataset.edKnowCopy || "") 4598 .then(() => { 4599 button.classList.add("is-copied"); 4600 button.setAttribute("aria-label", "Copied"); 4601 window.setTimeout(() => { 4602 button.classList.remove("is-copied"); 4603 button.setAttribute("aria-label", defaultLabel); 4604 }, 1300); 4605 }) 4606 .catch(() => {}); 4607 }); 4608 }); 4609 } 4610 4611 function installKnowSignsEducation() { 4612 if (path !== "/about-4") return; 4613 4614 hideAboutFourEmptySections(); 4615 4616 const existing = document.querySelector("[data-ed-email-update='know-signs-education']"); 4617 if (existing) { 4618 placeKnowSignsSection(existing); 4619 bindKnowSignsInteractions(existing); 4620 return; 4621 } 4622 4623 const section = document.createElement("section"); 4624 section.className = "ed-know-page"; 4625 section.dataset.edEmailUpdate = "know-signs-education"; 4626 section.setAttribute("aria-labelledby", "ed-know-title"); 4627 section.innerHTML = `
4628 <div class="ed-know-shell"> 4629 <section class="ed-know-hero"> 4630 <p class="ed-know-kicker">Be Informed</p> 4631 <h1 id="ed-know-title">Understanding Human Trafficking</h1> 4632 <p>Human trafficking is a form of exploitation that affects individuals across every community. Learning the facts and recognizing the signs is the first step toward meaningful action and support.</p> 4633 </section> 4634 4635 <section class="ed-know-card" aria-labelledby="ed-know-facts-title"> 4636 <h2 id="ed-know-facts-title">Key Facts That Matter</h2> 4637 <p class="ed-know-intro">Clear facts help communities recognize risk and respond with care.</p> 4638 <div class="ed-know-fact-grid"> 4639 <article><strong>#3*</strong><span>Florida ranks #3 in the nation for human trafficking cases</span></article> 4640 <article><strong>700K*</strong><span>cases of human trafficking in Florida in 2024</span></article> 4641 <article><strong>77%*</strong><span>of Florida's human trafficking cases involved children</span></article> 4642 <article><strong>12*</strong><span>average age a child enters human trafficking</span></article> 4643 </div> 4644 <p class="ed-know-source">* Sources: National Human Trafficking Hotline; USF/TIP Lab 2024 State Report; Florida DCF reporting.</p> 4645 </section> 4646 4647 <section class="ed-know-card" aria-labelledby="ed-know-definition-title"> 4648 <h2 id="ed-know-definition-title">What Human Trafficking Is</h2> 4649 <p>Human trafficking occurs when a person is forced, coerced, or manipulated into labor, services, or commercial sex. It can affect anyone regardless of age, gender, or background and often involves subtle control and exploitation rather than obvious restraints.</p> 4650 <p>Trafficking commonly involves <strong>force, fraud,</strong> or <strong>coercion.</strong></p> 4651 4652 <div class="ed-know-report"> 4653 <h3>Need to report a concern?</h3> 4654 <p>If someone may be in danger, use trusted resources. If it is an emergency, call <strong>911</strong>.</p> 4655 <div class="ed-know-report-grid"> 4656 <article> 4657 <span>Call</span> 4658 <a href="tel:18883737888">1-888-373-7888</a> 4659 <button type="button" data-ed-know-copy="1-888-373-7888" aria-label="Copy hotline phone number"></button> 4660 </article> 4661 <article> 4662 <span>Text</span> 4663 <strong>Text HELP or INFO to 233733</strong> 4664 <button type="button" data-ed-know-copy="Text HELP or INFO to 233733" aria-label="Copy hotline text instructions"></button> 4665 </article> 4666 </div> 4667 <p class="ed-know-hotline">National Human Trafficking Hotline resources: <a href="https://humantraffickinghotline.org/" target="_blank" rel="noopener noreferrer">humantraffickinghotline.org</a></p> 4668 </div> 4669 </section> 4670 4671 <section class="ed-know-card" aria-labelledby="ed-know-methods-title"> 4672 <h2 id="ed-know-methods-title">How Trafficking Happens</h2> 4673 <p class="ed-know-intro">Exploitation can take many forms. Click each to learn what it can look like.</p> 4674 <div class="ed-know-method-grid"> 4675 <button class="ed-know-toggle" type="button" data-ed-know-toggle aria-expanded="false"> 4676 <span class="ed-know-toggle-head"><strong>Force</strong><i aria-hidden="true"></i></span> 4677 <span>Physical violence, threats, or intimidation.</span> 4678 <span class="ed-know-toggle-detail">This can include harm, threats of harm, confinement, or threats against family members.</span> 4679 </button> 4680 <button class="ed-know-toggle" type="button" data-ed-know-toggle aria-expanded="false"> 4681 <span class="ed-know-toggle-head"><strong>Fraud</strong><i aria-hidden="true"></i></span> 4682 <span>False promises of jobs, housing, relationships, or opportunity.</span> 4683 <span class="ed-know-toggle-detail">Traffickers may offer help, romance, employment, travel, or stability, then use that trust to exploit someone.</span> 4684 </button> 4685 <button class="ed-know-toggle" type="button" data-ed-know-toggle aria-expanded="false">
4686 <span class="ed-know-toggle-head"><strong>Coercion</strong><i aria-hidden="true"></i></span> 4687 <span>Emotional manipulation, debt, financial control, or fear of consequences.</span> 4688 <span class="ed-know-toggle-detail">Control can look like threats, blackmail, debt bondage, immigration pressure, or withholding money and documents.</span> 4689 </button> 4690 <button class="ed-know-toggle" type="button" data-ed-know-toggle aria-expanded="false"> 4691 <span class="ed-know-toggle-head"><strong>Isolation</strong><i aria-hidden="true"></i></span> 4692 <span>Separation from family, friends, documents, or support systems.</span> 4693 <span class="ed-know-toggle-detail">Someone may be moved often, kept away from trusted people, monitored online, or prevented from asking for help.</span> 4694 </button> 4695 </div> 4696 </section> 4697 4698 <section class="ed-know-card" aria-labelledby="ed-know-myths-title"> 4699 <h2 id="ed-know-myths-title">Myths and Facts</h2> 4700 <p class="ed-know-intro">Click a card to reveal the fact.</p> 4701 <div class="ed-know-myth-grid"> 4702 <button class="ed-know-myth" type="button" data-ed-know-toggle aria-expanded="false"> 4703 <span>Myth</span> 4704 <strong>Trafficking only happens in other countries.</strong> 4705 <em>Tap to reveal the fact</em> 4706 <b>Fact: Human trafficking happens in every state, including communities across Florida.</b> 4707 </button> 4708 <button class="ed-know-myth" type="button" data-ed-know-toggle aria-expanded="false"> 4709 <span>Myth</span> 4710 <strong>Victims can simply leave if they want to.</strong> 4711 <em>Tap to reveal the fact</em> 4712 <b>Fact: Fear, threats, debt, manipulation, trauma, and lack of safe options can make leaving dangerous.</b> 4713 </button> 4714 <button class="ed-know-myth" type="button" data-ed-know-toggle aria-expanded="false"> 4715 <span>Myth</span> 4716 <strong>Trafficking always involves kidnapping.</strong> 4717 <em>Tap to reveal the fact</em> 4718 <b>Fact: Many cases begin through relationships, job offers, housing promises, or online grooming.</b> 4719 </button> 4720 <button class="ed-know-myth" type="button" data-ed-know-toggle aria-expanded="false"> 4721 <span>Myth</span> 4722 <strong>Trafficking is easy to spot.</strong> 4723 <em>Tap to reveal the fact</em> 4724 <b>Fact: It is often hidden in ordinary settings and may look like subtle control, fear, or isolation.</b> 4725 </button> 4726 </div> 4727 </section> 4728 4729 <section class="ed-know-card" aria-labelledby="ed-know-action-title"> 4730 <h2 id="ed-know-action-title">What You Can Do</h2> 4731 <p class="ed-know-intro">Small actions taken wisely can protect someone and support long-term recovery.</p> 4732 <div class="ed-know-action-grid"> 4733 <article><span>1</span><h3>Recognize</h3><p>Learn common indicators of exploitation and take concerns seriously.</p></article> 4734 <article><span>2</span><h3>Respond</h3><p>Prioritize safety and use trusted reporting resources.</p></article> 4735 <article><span>3</span><h3>Support</h3><p>Donate, volunteer, or share vetted resources that help survivors access long-term care.</p></article> 4736 </div> 4737 </section> 4738 4739 <section class="ed-know-card" aria-labelledby="ed-know-resources-title"> 4740 <h2 id="ed-know-resources-title">Resources</h2> 4741 <p class="ed-know-intro">Explore trusted information and ways to learn more.</p> 4742 <div class="ed-know-resource-row"> 4743 <a href="https://humantraffickinghotline.org/" target="_blank" rel="noopener noreferrer">National Hotline</a> 4744 <a href="https://www.justice.gov/humantrafficking" target="_blank" rel="noopener noreferrer">U.S. DOJ Resources</a> 4745 <a href="https://report.cybertip.org/" target="_blank" rel="noopener noreferrer">NCMEC CyberTipline (Report Exploitation)</a> 4746 </div> 4747 </section> 4748 </div> 4749 `; 4750 4751 placeKnowSignsSection(section); 4752 bindKnowSignsInteractions(section); 4753 } 4754 4755 function trimKnowSignsFooterGap() { 4756 if (path !== "/about-4" || document.body.classList.contains("ed-mobile-shell")) return; 4757 4758 const sitePages = document.querySelector("#SITE_PAGES"); 4759 if (!sitePages) return; 4760 4761 const visibleNativeSections = [...sitePages.querySelectorAll("section.wixui-section")].filter((section) => { 4762 const rect = section.getBoundingClientRect(); 4763 const style = getComputedStyle(section); 4764 return ( 4765 rect.width > 1 && 4766 rect.height > 1 && 4767 style.display !== "none" && 4768 style.visibility !== "hidden" && 4769 Number(style.opacity || 1) !== 0 4770 ); 4771 }); 4772 if (!visibleNativeSections.length) return; 4773 4774 const sitePagesTop = sitePages.getBoundingClientRect().top + window.scrollY; 4775 const visibleBottom = Math.max( 4776 ...visibleNativeSections.map((section) => section.getBoundingClientRect().bottom + window.scrollY), 4777 ); 4778 const nextHeight = Math.max(0, Math.ceil(visibleBottom - sitePagesTop)); 4779
4780 [sitePages, ...sitePages.children].forEach((element) => { 4781 element.style.setProperty("height", `${nextHeight}px`, "important"); 4782 element.style.setProperty("min-height", "0", "important"); 4783 element.style.setProperty("overflow", "visible", "important"); 4784 }); 4785 } 4786 4787 function installFooterSponsorBand() { 4788 const capturedHost = document.getElementById("comp-mns22ume"); 4789 if (capturedHost && (rawPath.startsWith("/post/") || path === "/about-4")) { 4790 if (!capturedHost.querySelector(".ed-captured-sponsor-band")) { 4791 const capturedBand = document.createElement("div"); 4792 capturedBand.className = "ed-footer-sponsor-band ed-captured-sponsor-band"; 4793 capturedBand.setAttribute("aria-label", "Featured sponsors"); 4794 capturedBand.innerHTML = renderFooterSponsorTrack(); 4795 capturedHost.replaceChildren(capturedBand); 4796 } 4797 syncFooterSponsorMarquees(capturedHost); 4798 return; 4799 } 4800 4801 const footer = document.querySelector("#SITE_FOOTER, footer"); 4802 if (!footer) return; 4803 if (footer.querySelector("[data-ed-email-update='footer-sponsor-band']")) return; 4804 if (!/wonderful sponsors/i.test(clean(footer.innerText || footer.textContent))) return; 4805 if (footerHasNativeSponsorLinks(footer)) return; 4806 4807 const band = document.createElement("div"); 4808 band.className = "ed-footer-sponsor-band"; 4809 band.dataset.edEmailUpdate = "footer-sponsor-band"; 4810 band.setAttribute("aria-label", "Featured sponsors"); 4811 band.innerHTML = renderFooterSponsorTrack(); 4812 4813 footer.classList.add("ed-footer-sponsor-host"); 4814 footer.appendChild(band); 4815 syncFooterSponsorMarquees(footer); 4816 } 4817 4818 function installDonorDockFullSponsorList() { 4819 if (path !== "/copy-of-lifeboat-lifesavers") return; 4820 if (!isMobileShellViewport()) return; 4821 4822 const section = document.querySelector(".donor-dock .sponsors-thanks, .sponsors-thanks"); 4823 if (!section || section.dataset.edEmailUpdate === "donor-dock-full-sponsors") return; 4824 4825 section.dataset.edEmailUpdate = "donor-dock-full-sponsors"; 4826 section.classList.add("ed-donor-dock-full-sponsors"); 4827 section.setAttribute("aria-labelledby", "sponsors-thanks-title"); 4828 section.innerHTML = ` 4829 <h2 id="sponsors-thanks-title">Thank you to our wonderful sponsors.</h2> 4830 <div class="ed-mobile-sponsor-grid ed-donor-dock-sponsor-grid" aria-label="Sponsor logos"> 4831 ${mobileSponsorLogoCardsHtml()} 4832 </div> 4833 `; 4834 } 4835 4836 function removeHomeSponsorDuplicate() { 4837 if (path !== "/") return; 4838 4839 const sponsorSection = document.getElementById("comp-lt8riarj"); 4840 if (!sponsorSection) return; 4841 if (!/wonderful sponsors/i.test(clean(sponsorSection.innerText || sponsorSection.textContent))) return; 4842 4843 sponsorSection.classList.add("ed-home-sponsor-duplicate-hidden"); 4844 sponsorSection.setAttribute("aria-hidden", "true"); 4845 } 4846 4847 function installHomepageYachtRockPromo() { 4848 if (path !== "/") return; 4849 4850 const flyerFrame = document.getElementById("comp-mqtvh113"); 4851 const expiredDinnerFrame = document.getElementById("comp-mqtxnude"); 4852 4853 if (expiredDinnerFrame) { 4854 expiredDinnerFrame.classList.add("ed-expired-event-promo"); 4855 expiredDinnerFrame.setAttribute("aria-hidden", "true"); 4856 } 4857 4858 if (document.querySelector("[data-ed-email-update='home-yacht-rock-promo']")) return; 4859 if (!flyerFrame) return; 4860 4861 const promo = document.createElement("section"); 4862 promo.id = flyerFrame.id; 4863 promo.className = "ed-yacht-rock-home-promo"; 4864 promo.dataset.edEmailUpdate = "home-yacht-rock-promo"; 4865 promo.setAttribute("aria-labelledby", "ed-yacht-rock-home-title"); 4866 promo.innerHTML = ` 4867 <div class="ed-yacht-rock-home-copy"> 4868 <p class="ed-yacht-rock-kicker">Featured Event</p> 4869 <h2 id="ed-yacht-rock-home-title">Yacht Rock Benefit Bash</h2> 4870 <p class="ed-yacht-rock-intro">Join The Lifeboat Project for its 6th annual benefit bash: an evening of dinner, cocktails, auctions, entertainment, and yacht rock supporting human trafficking awareness and survivor care.</p> 4871 <div class="ed-yacht-rock-details" aria-label="Yacht Rock Benefit Bash details"> 4872 <div>
4873 <span>Date & Time</span> 4874 <strong>October 17, 2026, 5:30–9:30 PM Eastern</strong> 4875 </div> 4876 <div> 4877 <span>Location</span> 4878 <strong>Hilton Lake Buena Vista, Disney Springs, Orlando</strong> 4879 </div> 4880 <div> 4881 <span>Tickets</span> 4882 <strong>$300 individual | $3,500 table of eight</strong> 4883 </div> 4884 </div> 4885 <p class="ed-yacht-rock-experience">Open bar, three-course meal, cocktail party, live and silent auction, entertainment, and yacht rock all night.</p> 4886 <p class="ed-yacht-rock-pricing">Sponsor opportunities are available at $5,000, $10,000, and $15,000 levels.</p> 4887 <div class="ed-yacht-rock-actions"> 4888 <a class="ed-yacht-rock-cta primary" href="${yachtRockEventPath}">View Event Details</a> 4889 <a class="ed-yacht-rock-cta secondary" href="mailto:[email protected]?subject=Yacht%20Rock%20Benefit%20Bash%20Sponsorship">Sponsor the Event</a> 4890 </div> 4891 </div> 4892 <a class="ed-yacht-rock-flyer-preview" href="${yachtRockEventPath}" aria-label="View Yacht Rock Benefit Bash event details"> 4893 <img src="${yachtRockFlyerImage}" srcset="${yachtRockFlyerImage} 1536w" sizes="(max-width: 700px) 180px, 260px" alt="6th Annual Yacht Rock Benefit Bash flyer" width="1536" height="864" loading="eager" decoding="async"> 4894 <span>Save the Date</span> 4895 </a> 4896 `; 4897 4898 flyerFrame.replaceWith(promo); 4899 } 4900 4901 function applyGlobalLabels() { 4902 setLinkText("Publications", "Financial & Strategic Plan"); 4903 setExactText("Publications", "Financial & Strategic Plan"); 4904 4905 document.querySelectorAll("[aria-label]").forEach((element) => { 4906 const label = element.getAttribute("aria-label") || ""; 4907 if (label.includes("Publications")) { 4908 element.setAttribute("aria-label", label.replaceAll("Publications", "Financial & Strategic Plan")); 4909 } 4910 }); 4911 } 4912 4913 function removeRetiredWhoWeAreLinks() { 4914 document.querySelectorAll("#SITE_HEADER a, header a").forEach((anchor) => { 4915 const label = clean(anchor.innerText || anchor.textContent); 4916 const href = anchor.getAttribute("href") || ""; 4917 const isRetiredItem = 4918 label === "Exciting News Coming" || 4919 href.includes("/exciting-news-coming") || 4920 (label === "Advisory Board" && href.includes("/advisory-board")); 4921 4922 if (!isRetiredItem) return; 4923 4924 const listItem = anchor.closest("li"); 4925 if (listItem) { 4926 listItem.remove(); 4927 } else { 4928 anchor.remove(); 4929 } 4930 }); 4931 } 4932 4933 function normalizeLegacyActionCards() { 4934 document.querySelectorAll("a").forEach((anchor) => { 4935 const label = clean(anchor.innerText || anchor.textContent); 4936 const card = anchor.closest(".wixui-repeater__item, article, section"); 4937 const cardText = clean(card?.innerText || card?.textContent); 4938 4939 if (label === "Learn More" && /Advisory Board/i.test(cardText)) { 4940 anchor.setAttribute("href", "/advisory-board"); 4941 anchor.removeAttribute("target"); 4942 anchor.removeAttribute("rel"); 4943 return; 4944 } 4945 4946 if (label === "Learn More" && /Lifeboat Lifesavers/i.test(cardText)) { 4947 const labelNode = anchor.querySelector(".wixui-button__label") || anchor; 4948 labelNode.textContent = "More to come"; 4949 anchor.removeAttribute("href"); 4950 anchor.removeAttribute("target"); 4951 anchor.removeAttribute("rel"); 4952 anchor.setAttribute("aria-disabled", "true"); 4953 anchor.classList.add("ed-more-to-come-link"); 4954 4955 if (anchor.dataset.edMoreToComeBound === "true") return; 4956 anchor.dataset.edMoreToComeBound = "true"; 4957 anchor.addEventListener("click", (event) => { 4958 event.preventDefault(); 4959 event.stopPropagation(); 4960 }); 4961 } 4962 }); 4963 } 4964 4965 function cleanInternalHref(href) { 4966 if (!href) return href; 4967 4968 let localHref = href.replace(/^https:\/\/(?:www\.)?(?:thelifeboatproject|lifeboatproject)\.org(?=\/|$)/, ""); 4969 if (localHref === "") localHref = "/"; 4970 if (!localHref.startsWith("/")) return href; 4971 return localHref; 4972 } 4973 4974 const homeGetInvolvedImages = { 4975 volunteer: "/assets/captured/6f40a75b55b16457.jpeg", 4976 haven: "/assets/captured/b67d48eeb0672e0f.jpg", 4977 speaker: "/assets/captured/a64c350ca655a41e.jpg", 4978 }; 4979 4980 const getInvolvedActionCopy = { 4981 volunteer: { 4982 eyebrow: "Volunteer", 4983 title: "Volunteer", 4984 body: 4985 "Join outreach, events, and awareness efforts that help survivors feel seen, supported, and connected to care.", 4986 cta: "Apply Today", 4987 }, 4988 speaker: { 4989 eyebrow: "Education", 4990 title: "Request a Speaker", 4991 body: 4992 "Bring Lifeboat's prevention education and survivor-centered awareness to schools, churches, workplaces, and community events.", 4993 cta: "Request a Speaker", 4994 }, 4995 haven: { 4996 eyebrow: "Housing", 4997 title: "Haven Homes", 4998 body: 4999 "Provide a supportive, family-based environment where survivors over 18 can heal, rebuild independence, and work alongside Lifeboat Project professionals.", 5000 cta: "Become a Haven Home", 5001 }, 5002 }; 5003 5004 function getInvolvedActionIcon(kind) { 5005 if (kind === "speaker") { 5006 return ( 5007 '<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">' + 5008 '<path d="M12 14a3 3 0 0 0 3-3V6a3 3 0 1 0-6 0v5a3 3 0 0 0 3 3Z"/>' + 5009 '<path d="M18 11a6 6 0 0 1-12 0"/>' + 5010 '<path d="M12 17v4"/>' + 5011 '<path d="M8 21h8"/>' + 5012 '</svg>' 5013 ); 5014 } 5015 5016 if (kind === "haven") { 5017 return ( 5018 '<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">' + 5019 '<path d="M3 11.5 12 4l9 7.5"/>' + 5020 '<path d="M5 10.5V20h14v-9.5"/>' + 5021 '<path d="M9 20v-6h6v6"/>' + 5022 '</svg>' 5023 ); 5024 } 5025 5026 return ( 5027 '<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">' + 5028 '<path d="M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z"/>' + 5029 '</svg>' 5030 ); 5031 } 5032 5033 function renderGetInvolvedActionBand(cardData, variant = "page") { 5034 const cards = cardData 5035 .map((card) => { 5036 const actionCopy = getInvolvedActionCopy[card.kind] || {}; 5037 const title = actionCopy.title || card.title; 5038 const body = actionCopy.body || card.body; 5039 const cta = actionCopy.cta || card.cta; 5040 const eyebrow = actionCopy.eyebrow || title; 5041 const href = card.kind === "volunteer" ? volunteerApplyEmail : card.href; 5042 const isEmailAction = /^mailto:/i.test(href); 5043 const rel = !isEmailAction && card.rel ? ` rel="${escapeMarkup(card.rel)}"` : ""; 5044 const target = !isEmailAction && card.target ? ` target="${escapeMarkup(card.target)}"` : ""; 5045 const image = card.imageSrc 5046 ? `<img src="${escapeMarkup(card.imageSrc)}" alt="${escapeMarkup(card.imageAlt)}" loading="lazy" decoding="async" data-ed-stable-media="true">` 5047 : ""; 5048 5049 return ` 5050 <article class="ed-action-card ed-action-card-${escapeMarkup(card.kind)}"> 5051 ${image} 5052 <div class="ed-action-card-overlay" aria-hidden="true"></div> 5053 <div class="ed-action-card-copy">
5054 <span class="ed-action-icon">${getInvolvedActionIcon(card.kind)}</span> 5055 <span class="ed-action-card-kicker">${escapeMarkup(eyebrow)}</span> 5056 <h3>${escapeMarkup(title)}</h3> 5057 <p>${escapeMarkup(body)}</p> 5058 <a href="${escapeMarkup(href)}"${target}${rel}> 5059 <span>${escapeMarkup(cta)}</span> 5060 <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"> 5061 <path d="M5 12h14"/> 5062 <path d="m13 6 6 6-6 6"/> 5063 </svg> 5064 </a> 5065 </div> 5066 </article> 5067 `; 5068 }) 5069 .join(""); 5070 5071 return ` 5072 <div class="ed-action-band ed-action-band-${variant}"> 5073 <div class="ed-action-intro"> 5074 <p class="ed-action-kicker">Get involved</p> 5075 <h2>Ways to stand with survivors</h2> 5076 <p>Choose a practical path to give time, invite education, and help Central Florida respond with care.</p> 5077 </div> 5078 <div class="ed-action-cards"> 5079 ${cards} 5080 </div> 5081 </div> 5082 `; 5083 } 5084 5085 function applyGlobalLinks() { 5086 document.querySelectorAll("a[href]").forEach((anchor) => { 5087 const href = anchor.getAttribute("href"); 5088 const cleanHref = cleanInternalHref(href); 5089 if (cleanHref && cleanHref !== href) anchor.setAttribute("href", cleanHref); 5090 }); 5091 } 5092 5093 function installContactOverflowNavItem() { 5094 const moreItem = document.getElementById("comp-k7974fvs__more__"); 5095 if (!moreItem) return; 5096 5097 const label = moreItem.querySelector("#comp-k7974fvs__more__label, .wGxoBM"); 5098 if (label) label.textContent = "Contact"; 5099 5100 const linkElement = moreItem.querySelector('[data-testid="linkElement"]'); 5101 if (linkElement) { 5102 linkElement.removeAttribute("aria-haspopup"); 5103 linkElement.setAttribute("aria-label", "Contact"); 5104 linkElement.setAttribute("role", "link"); 5105 linkElement.setAttribute("tabindex", "0"); 5106 } 5107 5108 moreItem.classList.add("ed-more-nav-contact"); 5109 moreItem.setAttribute("data-state", "menu false link"); 5110 moreItem.setAttribute("data-dropdown", "false"); 5111 5112 if (moreItem.dataset.edContactOverflowBound === "true") return; 5113 moreItem.dataset.edContactOverflowBound = "true"; 5114 const openContact = (event) => { 5115 event.preventDefault(); 5116 event.stopPropagation(); 5117 window.location.href = "/contact"; 5118 }; 5119 5120 moreItem.addEventListener("click", openContact, true); 5121 moreItem.addEventListener("keydown", (event) => { 5122 if (event.key !== "Enter" && event.key !== " ") return; 5123 openContact(event); 5124 }); 5125 } 5126 5127 function updateHomeStats() { 5128 if (path !== "/") return; 5129 5130 const fallback = document.querySelector(".lifeboat-stats-fallback"); 5131 if (fallback) { 5132 fallback.innerHTML = 5133 '<div class="lifeboat-stats-grid">' + 5134 '<div class="lifeboat-stat"><strong>#3<sup>**</sup></strong><span>Florida ranks #3 in the nation for human trafficking cases</span></div>' + 5135 '<div class="lifeboat-stat"><strong>700,000<sup>*</sup></strong><span>estimated annual human trafficking cases in Florida</span></div>' + 5136 '<div class="lifeboat-stat"><strong>75%<sup>*</sup></strong><span>of human trafficking cases involve children under 18</span></div>' + 5137 '<div class="lifeboat-stat"><strong>13<sup>*</sup></strong><span>average age of a child entering human trafficking</span></div>' + 5138 '</div>' + 5139 '<p class="lifeboat-stats-source">* Source: USF/TIPSTER Research Program. ** Source: National Human Trafficking Hotline.</p>'; 5140 } 5141 5142 repairHomeGetInvolvedLayout(); 5143 syncHomeGetInvolvedChat(); 5144 } 5145 5146 function repairHomeGetInvolvedLayout() { 5147 if (path !== "/") return; 5148 5149 const repeater = document.querySelector("#comp-mm6nz8rc"); 5150 if (!repeater) return; 5151 5152 const cards = [...repeater.querySelectorAll(".wixui-repeater__item")]; 5153 const activeCards = cards.filter((card) => { 5154 return /VOLUNTEER|HAVEN\s+HOMES|REQUEST\s+A\s+SPEAKER/i.test(clean(card.innerText || card.textContent)); 5155 }); 5156 5157 if (activeCards.length < 3) return; 5158 5159 const section = closestPageSection(repeater); 5160 section?.classList.add("ed-home-get-involved-section"); 5161 repeater.classList.add("ed-home-get-involved-replaced"); 5162 repeater.style.setProperty("display", "none", "important"); 5163 5164 let staticGrid = section?.querySelector(".ed-home-get-involved-static-grid"); 5165 if (!staticGrid) { 5166 staticGrid = document.createElement("div"); 5167 staticGrid.className = "ed-home-get-involved-static-grid"; 5168 repeater.insertAdjacentElement("afterend", staticGrid); 5169 } 5170 if (staticGrid.dataset.edHydrated === "true") { 5171 repeater.remove(); 5172 return; 5173 } 5174 5175 const cardData = activeCards.map((card) => { 5176 const title = clean(card.querySelector('[id^="comp-mm6nz8ru5__"]')?.textContent); 5177 const body = clean(card.querySelector('[id^="comp-mm6nz8rw__"]')?.textContent); 5178 const anchor = card.querySelector('[id^="comp-mm6oukoc__"] a[href]'); 5179 const image = card.querySelector('[id^="comp-mm6otrg8__"] img'); 5180 const isSpeaker = /REQUEST\s+A\s+SPEAKER/i.test(title); 5181 const isHaven = /HAVEN\s+HOMES/i.test(title);
5182 const kind = isSpeaker ? "speaker" : isHaven ? "haven" : "volunteer"; 5183 5184 return { 5185 title, 5186 body, 5187 href: anchor?.getAttribute("href") || (isSpeaker ? "/contact" : isHaven ? "mailto:[email protected]" : "/volunteer"), 5188 target: anchor?.getAttribute("target") || "_self", 5189 rel: anchor?.getAttribute("rel") || "", 5190 cta: clean(anchor?.textContent) || (isSpeaker ? "Request a Speaker" : isHaven ? "Become a Haven Home" : "Apply Today"), 5191 imageAlt: image?.getAttribute("alt") || title, 5192 imageSrc: homeGetInvolvedImages[kind] || image?.getAttribute("src") || "", 5193 kind, 5194 }; 5195 }); 5196 5197 staticGrid.innerHTML = renderGetInvolvedActionBand(cardData, "home"); 5198 staticGrid.dataset.edHydrated = "true"; 5199 repeater.remove(); 5200 } 5201 5202 function installGetInvolvedHeader() { 5203 if (path !== "/get-involved") return; 5204 5205 document.body.classList.add("ed-get-involved-route"); 5206 5207 const existing = document.querySelector("[data-ed-email-update='get-involved-header']"); 5208 const nativeHeading = [...document.querySelectorAll("#PAGES_CONTAINER h1, #PAGES_CONTAINER h2, #PAGES_CONTAINER h3, #PAGES_CONTAINER h4, #PAGES_CONTAINER [role='heading']")].find((element) => 5209 /^Get Involved\.?$/i.test(clean(element.innerText || element.textContent)), 5210 ); 5211 const nativeHero = document.getElementById("comp-mm59rmbx") || (nativeHeading ? closestPageSection(nativeHeading) : null); 5212 5213 if (nativeHero && nativeHero.dataset.edEmailUpdate !== "get-involved-header") { 5214 hideElement(nativeHero); 5215 } 5216 5217 if (existing) return; 5218 5219 const section = document.createElement("section"); 5220 section.className = "ed-get-involved-header"; 5221 section.dataset.edEmailUpdate = "get-involved-header"; 5222 section.setAttribute("aria-labelledby", "ed-get-involved-header-title"); 5223 section.innerHTML = ` 5224 <div class="ed-get-involved-header-frame"> 5225 <img src="${getInvolvedHeaderImage}" alt="Get Involved. Together, we can end human trafficking and bring hope to survivors." width="1717" height="916" loading="eager" decoding="async" fetchpriority="high"> 5226 </div> 5227 <div class="ed-screen-reader-only"> 5228 <h1 id="ed-get-involved-header-title">Get Involved</h1> 5229 <p>Together, we can end human trafficking and bring hope to survivors through donations, volunteering, advocacy, and partnership.</p> 5230 </div> 5231 `; 5232 5233 if (nativeHero?.parentNode) { 5234 nativeHero.parentNode.insertBefore(section, nativeHero); 5235 return; 5236 } 5237 5238 const cardSection = document.getElementById("comp-mm59rmdz"); 5239 if (cardSection?.parentNode) { 5240 cardSection.parentNode.insertBefore(section, cardSection); 5241 return; 5242 } 5243 5244 insertBeforeFooter(section); 5245 } 5246 5247 function installVolunteerHeader() { 5248 if (path !== "/about-4-1") return; 5249 5250 document.body.classList.add("ed-volunteer-route"); 5251 5252 const existing = document.querySelector("[data-ed-email-update='volunteer-header']"); 5253 const nativeHeading = [...document.querySelectorAll("#PAGES_CONTAINER h1, #PAGES_CONTAINER h2, #PAGES_CONTAINER h3, #PAGES_CONTAINER h4, #PAGES_CONTAINER [role='heading']")].find((element) => 5254 /^Volunteer\.?$/i.test(clean(element.innerText || element.textContent)), 5255 ); 5256 const nativeHero = nativeHeading ? closestPageSection(nativeHeading) : null; 5257 5258 if (nativeHero && nativeHero.dataset.edEmailUpdate !== "volunteer-header") { 5259 hideElement(nativeHero); 5260 } 5261 5262 const placeHeader = (targetSection) => { 5263 if (nativeHero?.parentNode) { 5264 nativeHero.parentNode.insertBefore(targetSection, nativeHero); 5265 return; 5266 } 5267 5268 insertBeforeFooter(targetSection); 5269 }; 5270 5271 if (existing) { 5272 placeHeader(existing); 5273 return; 5274 } 5275 5276 const section = document.createElement("section"); 5277 section.className = "ed-volunteer-header"; 5278 section.dataset.edEmailUpdate = "volunteer-header"; 5279 section.setAttribute("aria-labelledby", "ed-volunteer-header-title"); 5280 section.innerHTML = ` 5281 <div class="ed-volunteer-header-frame"> 5282 <img src="${volunteerHeaderImage}" alt="Volunteer. Your time. Their hope. Together, we can make a difference." width="1774" height="887" loading="eager" decoding="async" fetchpriority="high"> 5283 </div> 5284 <div class="ed-screen-reader-only"> 5285 <h1 id="ed-volunteer-header-title">Volunteer</h1> 5286 <p>Your time. Their hope. Together, we can make a difference.</p> 5287 </div> 5288 `; 5289 5290 placeHeader(section); 5291 } 5292 5293 function installVolunteerPageExperience() { 5294 if (path !== "/about-4-1") return; 5295 5296 document.body.classList.add("ed-volunteer-refresh-route"); 5297 5298 const pageContent = document.querySelector("#PAGES_CONTAINER") || document.querySelector("main") || document.body;
5299 const sitePages = pageContent.querySelector(":scope > #SITE_PAGES") || document.querySelector("#SITE_PAGES"); 5300 const header = document.querySelector("[data-ed-email-update='volunteer-header']"); 5301 let section = document.querySelector("[data-ed-email-update='volunteer-experience']"); 5302 5303 if (!section) { 5304 section = document.createElement("section"); 5305 section.className = "ed-volunteer-experience"; 5306 section.dataset.edEmailUpdate = "volunteer-experience"; 5307 section.setAttribute("aria-label", "Volunteer information and application steps"); 5308 section.innerHTML = volunteerPageContentHtml(); 5309 } 5310 5311 if (header?.parentNode && header.nextElementSibling !== section) { 5312 header.insertAdjacentElement("afterend", section); 5313 } else if (!section.parentNode && sitePages?.parentNode) { 5314 sitePages.parentNode.insertBefore(section, sitePages); 5315 } else if (!section.parentNode) { 5316 insertBeforeFooter(section); 5317 } 5318 5319 if (sitePages) { 5320 sitePages.classList.add("ed-volunteer-native-hidden"); 5321 sitePages.setAttribute("aria-hidden", "true"); 5322 } 5323 5324 bindHomeMissionVideoTriggers(section); 5325 } 5326 5327 function repairGetInvolvedPageCards() { 5328 if (path !== "/get-involved") return; 5329 5330 const repeater = document.querySelector("#comp-mm719hsb"); 5331 if (!repeater) return; 5332 5333 const cards = [...repeater.querySelectorAll(".wixui-repeater__item")]; 5334 const activeCards = cards.filter((card) => { 5335 const text = clean(card.innerText || card.textContent); 5336 return /VOLUNTEER|REQUEST\s+A\s+SPEAKER/i.test(text) && !/HAVEN\s+HOMES/i.test(text); 5337 }); 5338 5339 if (activeCards.length < 2) return; 5340 5341 const section = closestPageSection(repeater); 5342 section?.classList.add("ed-get-involved-card-section"); 5343 repeater.classList.add("ed-get-involved-replaced"); 5344 repeater.style.setProperty("display", "none", "important"); 5345 5346 let staticGrid = section?.querySelector(".ed-get-involved-static-grid"); 5347 if (!staticGrid) { 5348 staticGrid = document.createElement("div"); 5349 staticGrid.className = "ed-get-involved-static-grid"; 5350 repeater.insertAdjacentElement("afterend", staticGrid); 5351 } 5352 if (staticGrid.dataset.edHydrated === "true") { 5353 repeater.remove(); 5354 return; 5355 } 5356 5357 const cardData = activeCards.map((card) => { 5358 const title = clean(card.querySelector('[id^="comp-mm719ht7__"]')?.textContent); 5359 const body = clean(card.querySelector('[id^="comp-mm719ht8__"]')?.textContent); 5360 const anchor = card.querySelector('[id^="comp-mm719ht85__"] a[href]'); 5361 const image = card.querySelector('[id^="comp-mm719ht51__"] img'); 5362 const isSpeaker = /REQUEST\s+A\s+SPEAKER/i.test(title); 5363 5364 return { 5365 title, 5366 body, 5367 href: cleanInternalHref(anchor?.getAttribute("href")) || (isSpeaker ? "/contact" : "/volunteer"), 5368 target: anchor?.getAttribute("target") || "_self", 5369 rel: anchor?.getAttribute("rel") || "", 5370 cta: clean(anchor?.textContent) || (isSpeaker ? "Request a Speaker" : "Learn More"), 5371 imageAlt: image?.getAttribute("alt") || title, 5372 imageSrc: homeGetInvolvedImages[isSpeaker ? "speaker" : "volunteer"] || image?.currentSrc || image?.getAttribute("src") || "", 5373 kind: isSpeaker ? "speaker" : "volunteer", 5374 }; 5375 }); 5376 5377 staticGrid.innerHTML = renderGetInvolvedActionBand(cardData, "page"); 5378 staticGrid.dataset.edHydrated = "true"; 5379 repeater.remove(); 5380 } 5381 5382 function syncHomeGetInvolvedChat() { 5383 if (path !== "/" && path !== "/get-involved") return; 5384 5385 const chat = document.querySelector(".lifeboat-local-chat"); 5386 const section = document.querySelector(".ed-home-get-involved-section, .ed-get-involved-card-section"); 5387 if (!chat || !section) return; 5388 5389 chat.style.setProperty("bottom", "max(24px, env(safe-area-inset-bottom))", "important"); 5390 chat.style.setProperty("top", "auto", "important"); 5391 chat.style.setProperty("z-index", "900000", "important"); 5392 5393 const visualWidth = Math.min( 5394 document.documentElement.clientWidth || window.innerWidth, 5395 window.visualViewport?.width || window.innerWidth, 5396 ); 5397 const rect = section.getBoundingClientRect(); 5398 const sectionVisible = rect.top < window.innerHeight && rect.bottom > 0; 5399 5400 chat.classList.toggle( 5401 "ed-chat-hidden-for-get-involved", 5402 visualWidth <= 1500 && sectionVisible, 5403 ); 5404 5405 if (homeGetInvolvedChatBound) return; 5406 homeGetInvolvedChatBound = true; 5407 5408 const scheduleSync = () => { 5409 window.cancelAnimationFrame(homeGetInvolvedChatFrame); 5410 homeGetInvolvedChatFrame = window.requestAnimationFrame(syncHomeGetInvolvedChat); 5411 }; 5412 5413 window.addEventListener("scroll", scheduleSync, { passive: true }); 5414 window.addEventListener("resize", scheduleSync); 5415 } 5416 5417 const teamProfileLinks = [ 5418 { label: "Jill Bolander Cohen", matches: ["Jill Bolander Cohen"], href: "/team/jill-bolander-cohen", image: "/assets/captured/c5f78ac048be0217.jpg" }, 5419 { label: "Tina Sopp", matches: ["Tina Sopp"], href: "/team/tina-sopp", image: "/assets/updates/tina-sopp.jpg", objectPosition: "50% 18%" }, 5420 { label: "Jonny", matches: ["Jonny"], href: "/team/jonny", image: "/assets/captured/13491f9c8c8da178.jpeg" }, 5421 { label: "Eme", matches: ["Eme"], href: "/team/eme", image: "/assets/updates/team/eme.jpg" }, 5422 { label: "MaryAnne", matches: ["MaryAnne", "Mary Anne"], href: "/team/maryanne", image: "/assets/captured/d87cb8764556bb2e.
5422jpg" }, 5423 { label: "Kathy Pierson", matches: ["Kathy Pierson"], href: "/team/kathy-pierson", image: "/assets/captured/5ce3b9adf7603a29.jpg" }, 5424 { label: "Ed Gilbert", matches: ["Ed Gilbert"], href: "/team/ed-gilbert", image: "/assets/captured/80409f65c3f6ecdc.jpeg" }, 5425 { label: "Kristen", matches: ["Kristen"], href: "/team/kristen-jensen", image: "/assets/captured/926d3ddd00beedf5.jpg" }, 5426 { label: "Nancy", matches: ["Nancy"], href: "/team/nancy", image: "/assets/captured/0c3cc7932809d7cd.jpg" }, 5427 { label: "Jamie", matches: ["Jamie"], href: "/team/jamie-holmes", image: "/assets/captured/f6c2fb93aaa14226.jpeg" }, 5428 { label: "Piros Pazaurek", matches: ["Piros Pazaurek"], href: "/team/piros-pazaurek", image: "/assets/captured/cb1f2549c4b8fc68.jpeg" }, 5429 ]; 5430 const teamProfileRoutes = new Set([ 5431 "/about-5", 5432 "/copy-of-bella", 5433 "/copy-of-bella-1", 5434 "/copy-of-bella-2", 5435 "/copy-of-ed", 5436 "/copy-of-eme", 5437 "/copy-of-gary", 5438 "/copy-of-gary-1", 5439 "/copy-of-jamie", 5440 "/copy-of-jeremy", 5441 "/copy-of-jill-cohen", 5442 "/copy-of-jonny", 5443 "/copy-of-kathy", 5444 "/copy-of-nancy", 5445 "/copy-of-piros", 5446 "/copy-of-shannon", 5447 "/team/tina-sopp", 5448 ]); 5449 const jonnyGalleryPhotos = [ 5450 { 5451 key: "outreach", 5452 className: "ed-jonny-collage-side ed-jonny-collage-left", 5453 src: "/assets/updates/jonny/outreach-table.jpeg", 5454 alt: "Jonny and Lifeboat Project partners at an outreach table", 5455 width: 506, 5456 height: 373, 5457 }, 5458 { 5459 key: "event", 5460 className: "ed-jonny-collage-main", 5461 src: "/assets/updates/jonny/event-main.jpeg", 5462 alt: "Jonny with Lifeboat Project supporters at an event", 5463 width: 460, 5464 height: 314, 5465 }, 5466 { 5467 key: "team", 5468 className: "ed-jonny-collage-side ed-jonny-collage-right", 5469 src: "/assets/updates/jonny/team-group.jpg", 5470 alt: "Jonny with The Lifeboat Project team at a community event", 5471 width: 506, 5472 height: 373, 5473 }, 5474 ]; 5475 5476 function ensureTeamReadMoreLink(textBlock, profile) { 5477 let link = textBlock.querySelector(".ed-team-read-more"); 5478 if (!link) { 5479 link = document.createElement("a"); 5480 link.className = "ed-team-read-more"; 5481 textBlock.appendChild(link); 5482 } 5483 5484 link.textContent = "Read more"; 5485 link.href = profile.href; 5486 link.target = "_self"; 5487 link.removeAttribute("rel"); 5488 link.setAttribute("aria-label", `Read more about ${profile.label}`); 5489 return link; 5490 } 5491 5492 function findTeamProfileForCard(card) { 5493 const leafText = [...card.querySelectorAll("*")] 5494 .filter((element) => element.children.length === 0) 5495 .map((element) => clean(element.innerText || element.textContent)); 5496 5497 return teamProfileLinks.find((entry) => 5498 entry.matches.some((match) => leafText.includes(match)), 5499 ); 5500 } 5501 5502 function pinPortraitImage(image, profile) { 5503 if (!image || !profile?.image) return; 5504 5505 image.removeAttribute("srcset"); 5506 image.setAttribute("src", profile.image); 5507 image.src = profile.image; 5508 image.alt = profile.label; 5509 image.loading = image.loading || "lazy"; 5510 image.decoding = "async"; 5511 5512 if (profile.objectPosition) { 5513 image.style.setProperty("object-position", profile.objectPosition, "important"); 5514 } 5515 } 5516 5517 function repairTeamPortraitImages() { 5518 if (path !== "/team-4" && path !== "/meet-the-team") return; 5519 5520 document.querySelectorAll("#comp-mm5u1hh1 .wixui-repeater__item").forEach((card) => { 5521 const profile = findTeamProfileForCard(card); 5522 if (!profile) return; 5523 5524 pinPortraitImage(card.querySelector("img"), profile); 5525 }); 5526 } 5527 5528 function installTeamReadMoreLinks() { 5529 if (path !== "/team-4" && path !== "/meet-the-team") return; 5530 5531 document.querySelectorAll("#comp-mm5u1hgs .wixui-repeater__item").forEach((card) => { 5532 const profile = findTeamProfileForCard(card); 5533 if (!profile) return; 5534 5535 const textBlock = card.querySelector('[id^="comp-mm5u7css__"]'); 5536 if (!textBlock) return; 5537 5538 ensureTeamReadMoreLink(textBlock, profile); 5539 }); 5540 } 5541 5542 function replaceTextNodes(root, value) { 5543 const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT); 5544 const textNodes = []; 5545 let node = walker.nextNode(); 5546 5547 while (node) { 5548 if (clean(node.nodeValue)) textNodes.push(node); 5549 node = walker.nextNode(); 5550 } 5551
5552 textNodes.forEach((textNode, index) => { 5553 textNode.nodeValue = index === 0 ? value : ""; 5554 }); 5555 } 5556 5557 function renameCloneAttributes(root, oldSuffix, newSuffix) { 5558 [root, ...root.querySelectorAll("*")].forEach((element) => { 5559 [...element.attributes].forEach((attribute) => { 5560 if (attribute.value.includes(oldSuffix)) { 5561 element.setAttribute(attribute.name, attribute.value.replaceAll(oldSuffix, newSuffix)); 5562 } 5563 }); 5564 }); 5565 } 5566 5567 function numericStyleValue(element, property, fallback = 0) { 5568 const value = Number.parseFloat(element.style[property]); 5569 return Number.isFinite(value) ? value : fallback; 5570 } 5571 5572 function savedTeamGridValue(card, property) { 5573 const datasetKey = property === "top" ? "edTeamGridTop" : "edTeamGridLeft"; 5574 const currentValue = numericStyleValue(card, property); 5575 if (!card.dataset[datasetKey]) card.dataset[datasetKey] = String(currentValue); 5576 const savedValue = Number.parseFloat(card.dataset[datasetKey]); 5577 return Number.isFinite(savedValue) ? savedValue : currentValue; 5578 } 5579 5580 function uniqueSorted(values, tolerance = 8) { 5581 return values 5582 .slice() 5583 .sort((a, b) => a - b) 5584 .reduce((unique, value) => { 5585 if (!unique.length || Math.abs(unique[unique.length - 1] - value) > tolerance) { 5586 unique.push(value); 5587 } 5588 return unique; 5589 }, []); 5590 } 5591 5592 function layoutTeamCardsWithTina(tinaCard) { 5593 const teamSection = document.getElementById("comp-mm5u1hgs"); 5594 const repeater = document.getElementById("comp-mm5u1hh1"); 5595 const wrapper = document.getElementById("comp-mm5u1hh1_wrapper"); 5596 const fluid = repeater?.querySelector("fluid-columns-repeater"); 5597 if (!teamSection || !repeater || !fluid) return; 5598 5599 teamSection.style.removeProperty("min-height"); 5600 document.querySelectorAll("section[data-ed-email-update='tina-sopp']").forEach((panel) => panel.remove()); 5601 5602 const nativeCards = [...repeater.querySelectorAll(".wixui-repeater__item")] 5603 .filter((card) => card !== tinaCard && !card.classList.contains("ed-hidden")) 5604 .sort((a, b) => { 5605 const topDiff = savedTeamGridValue(a, "top") - savedTeamGridValue(b, "top"); 5606 return Math.abs(topDiff) > 8 ? topDiff : savedTeamGridValue(a, "left") - savedTeamGridValue(b, "left"); 5607 }); 5608 if (!nativeCards.length) return; 5609 5610 const jillCard = nativeCards.find((card) => /Jill Bolander Cohen/i.test(clean(card.innerText || card.textContent))) || nativeCards[0]; 5611 if (tinaCard.previousElementSibling !== jillCard) jillCard.after(tinaCard); 5612 5613 const columnLefts = uniqueSorted(nativeCards.map((card) => savedTeamGridValue(card, "left"))); 5614 const rowTops = uniqueSorted(nativeCards.map((card) => savedTeamGridValue(card, "top"))); 5615 const columns = Math.max(1, columnLefts.length); 5616 const cardHeight = Math.max(...nativeCards.map((card) => card.getBoundingClientRect().height)); 5617 const rowStep = rowTops.length > 1 ? rowTops[1] - rowTops[0] : cardHeight + 60; 5618 const rowStart = rowTops[0] || 30; 5619 const orderedCards = [jillCard, tinaCard, ...nativeCards.filter((card) => card !== jillCard)]; 5620 const totalRows = Math.ceil(orderedCards.length / columns); 5621 const repeaterHeight = Math.ceil(rowStep * Math.max(0, totalRows - 1) + cardHeight); 5622 5623 orderedCards.forEach((card, index) => { 5624 const row = Math.floor(index / columns); 5625 const column = index % columns; 5626 card.style.setProperty("position", "absolute", "important"); 5627 card.style.setProperty("top", `${rowStart + row * rowStep}px`, "important"); 5628 card.style.setProperty("left", `${columnLefts[column] ?? columnLefts[0]}px`, "important"); 5629 card.style.removeProperty("transform"); 5630 }); 5631 5632 fluid.setAttribute("items", String(orderedCards.length)); 5633 [repeater, wrapper, fluid].forEach((element) => { 5634 if (!element) return; 5635 element.style.setProperty("height", `${repeaterHeight}px`, "important"); 5636 }); 5637 } 5638 5639 function installTinaSoppCard() { 5640 if (path !== "/team-4" && path !== "/meet-the-team") return; 5641 5642 const repeater = document.getElementById("comp-mm5u1hh1"); 5643 const jillCard = [...document.querySelectorAll("#comp-mm5u1hh1 .wixui-repeater__item")].find((card) => 5644 /Jill Bolander Cohen/i.test(clean(card.innerText || card.textContent)), 5645 ); 5646 if (!repeater || !jillCard) return; 5647 5648 let tinaCard = repeater.querySelector("[data-ed-email-update='tina-sopp']"); 5649 if (!tinaCard) { 5650 tinaCard = jillCard.cloneNode(true); 5651 tinaCard.dataset.edEmailUpdate = "tina-sopp"; 5652 renameCloneAttributes(tinaCard, "__item1", "__ed-tina-sopp"); 5653 tinaCard.querySelector(".ed-team-read-more")?.remove(); 5654 jillCard.after(tinaCard); 5655 } 5656 5657 const image = tinaCard.querySelector("img"); 5658 if (image) { 5659 image.src = "/assets/updates/tina-sopp.jpg"; 5660 image.srcset = "/assets/updates/tina-sopp.jpg 1x"; 5661 image.alt = "Tina Sopp"; 5662 image.loading = "eager"; 5663 image.decoding = "async"; 5664 } 5665 5666 const titleBlock = tinaCard.querySelector('[id^="comp-mm5u1hhj__"]'); 5667 const nameBlock = tinaCard.querySelector('[id^="comp-mm5u1hhk__"]'); 5668 const bioBlock = tinaCard.querySelector('[id^="comp-mm5u7css__"]'); 5669 if (titleBlock) replaceTextNodes(titleBlock, "Chief Operating Officer"); 5670 if (nameBlock) replaceTextNodes(nameBlock, "Tina Sopp"); 5671 if (bioBlock) { 5672 bioBlock.querySelector(".ed-team-read-more")?.remove(); 5673 const bioText = bioBlock.querySelector(".wixui-collapsible-text__text") || bioBlock.querySelector("p") || bioBlock; 5674 replaceTextNodes( 5675 bioText, 5676 "Tina Sopp serves as Chief Operating Officer for The Lifeboat Project, supporting daily operations, team coordination, and the systems that help survivor-centered programs run with consistency and care.", 5677 ); 5678 ensureTeamReadMoreLink(bioBlock, { 5679 label: "Tina Sopp", 5680 href: "/team/tina-sopp", 5681 }); 5682 } 5683
5684 layoutTeamCardsWithTina(tinaCard); 5685 } 5686 5687 function installTinaSoppProfile() { 5688 if (rawPath !== "/team/tina-sopp") return; 5689 5690 document.body.classList.add("ed-team-profile-route", "ed-tina-profile-route"); 5691 5692 setExactText("Meet Jonny", "Meet Tina"); 5693 document.querySelectorAll("body *").forEach((element) => { 5694 if (element.children.length > 0) return; 5695 const text = clean(element.textContent); 5696 if (/Guided by purpose and compassion, Jonny is passionate/i.test(text)) { 5697 element.textContent = 5698 "Tina Sopp serves as Chief Operating Officer for The Lifeboat Project, supporting daily operations, team coordination, and the systems that help survivor-centered programs run with consistency and care."; 5699 } 5700 }); 5701 5702 const heroImage = document.querySelector("#comp-mm5utinl img"); 5703 if (heroImage) { 5704 heroImage.src = "/assets/updates/tina-sopp.jpg"; 5705 heroImage.srcset = "/assets/updates/tina-sopp.jpg 1x"; 5706 heroImage.alt = "Tina Sopp"; 5707 heroImage.loading = "eager"; 5708 heroImage.decoding = "async"; 5709 } 5710 5711 const gallery = document.getElementById("comp-mm5utint2"); 5712 if (gallery) hideElement(gallery); 5713 } 5714 5715 function installJonnyProfileGallery() { 5716 if (path !== "/copy-of-jill-cohen") return; 5717 5718 const section = document.getElementById("comp-mm5utint2"); 5719 if (!section) return; 5720 5721 document.body.classList.add("ed-jonny-profile-route"); 5722 section.classList.add("ed-jonny-gallery-section"); 5723 section.removeAttribute("aria-hidden"); 5724 5725 let gallery = section.querySelector(".ed-jonny-collage"); 5726 if (!gallery) { 5727 gallery = document.createElement("div"); 5728 gallery.className = "ed-jonny-collage"; 5729 gallery.dataset.edEmailUpdate = "jonny-gallery"; 5730 gallery.setAttribute("aria-label", "Jonny with The Lifeboat Project at community events"); 5731 } 5732 5733 if (gallery.dataset.edJonnyGalleryInstalled !== "true") { 5734 gallery.replaceChildren( 5735 ...jonnyGalleryPhotos.map((photo) => { 5736 const image = document.createElement("img"); 5737 image.className = photo.className; 5738 image.src = photo.src; 5739 image.alt = photo.alt; 5740 image.width = photo.width; 5741 image.height = photo.height; 5742 image.loading = "eager"; 5743 image.decoding = "async"; 5744 image.dataset.edJonnyImage = photo.key; 5745 return image; 5746 }), 5747 ); 5748 gallery.dataset.edJonnyGalleryInstalled = "true"; 5749 } 5750 5751 section.replaceChildren(gallery); 5752 } 5753 5754 function sectionHasRenderedMedia(section) { 5755 return [...section.querySelectorAll("img, video, iframe, canvas, svg")].some((element) => { 5756 if (element.closest("[data-testid='colorUnderlay'], [data-hook='bgLayers']")) return false; 5757 if ( 5758 element.tagName === "IFRAME" && 5759 /\/siteAssets\/media\/Carousel\./i.test(element.getAttribute("src") || "") 5760 ) { 5761 return false; 5762 } 5763 5764 const rect = element.getBoundingClientRect(); 5765 const style = getComputedStyle(element); 5766 return ( 5767 rect.width > 8 && 5768 rect.height > 8 && 5769 style.display !== "none" && 5770 style.visibility !== "hidden" && 5771 Number(style.opacity || "1") > 0 5772 ); 5773 }); 5774 } 5775 5776 function removeTeamProfileBlankSpacers() { 5777 if (!teamProfileRoutes.has(path)) return; 5778 5779 document.body.classList.add("ed-team-profile-route"); 5780 5781 document.querySelectorAll("#PAGES_CONTAINER section.wixui-section, main section.wixui-section").forEach((section) => { 5782 if (section.classList.contains("ed-jonny-gallery-section")) return; 5783 if (section.dataset.edEmailUpdate || section.querySelector("[data-ed-email-update]")) return; 5784 5785 const rect = section.getBoundingClientRect(); 5786 if (rect.height < 220) return; 5787 if (clean(section.innerText || section.textContent)) return; 5788 if (sectionHasRenderedMedia(section)) return; 5789 5790 section.classList.add("ed-team-profile-blank-spacer"); 5791 hideElement(section); 5792 }); 5793 } 5794 5795 function updateBoardPage() { 5796 if (path !== "/copy-of-meet-the-team") return; 5797 5798 document.querySelectorAll("body *").forEach((element) => { 5799 if (element.children.length > 0) return; 5800 const text = clean(element.textContent); 5801 if (text === "Member of the Board, VP and Banking Center Manager at First Horizon Bank") { 5802 element.textContent = "Member of the Board, VP at Pinnacle Bank"; 5803 } 5804 if (text === "Member of the Board, Mayor of Apopka") { 5805 element.textContent = "Member of the Board, Former Mayor of Apopka"; 5806 } 5807 }); 5808 } 5809 5810 function bindBoardDirectorsReadMore(root = document) { 5811 root.querySelectorAll(".ed-board-bio-toggle").forEach((button) => {
5812 if (button.dataset.edBoardBound === "true") return; 5813 button.dataset.edBoardBound = "true"; 5814 button.addEventListener("click", () => { 5815 const card = button.closest(".ed-board-card"); 5816 if (!card) return; 5817 5818 const expanded = !card.classList.contains("ed-board-card-expanded"); 5819 card.classList.toggle("ed-board-card-expanded", expanded); 5820 button.textContent = expanded ? "Read less" : "Read more"; 5821 button.setAttribute("aria-expanded", String(expanded)); 5822 }); 5823 }); 5824 } 5825 5826 function revealBoardDirectorsPage(root = document) { 5827 const page = root.querySelector?.(".ed-board-directors-page") || document.querySelector(".ed-board-directors-page"); 5828 if (!page || page.dataset.edBoardRevealBound === "true") return; 5829 5830 page.dataset.edBoardRevealBound = "true"; 5831 const revealItems = [...page.querySelectorAll(".ed-board-hero .ed-board-shell, .ed-board-card")]; 5832 const reduceMotion = window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches; 5833 5834 if (reduceMotion || !("IntersectionObserver" in window)) { 5835 revealItems.forEach((item) => item.classList.add("ed-board-in-view")); 5836 return; 5837 } 5838 5839 page.classList.add("ed-board-motion-ready"); 5840 const observer = new IntersectionObserver( 5841 (entries) => { 5842 entries.forEach((entry) => { 5843 if (!entry.isIntersecting) return; 5844 entry.target.classList.add("ed-board-in-view"); 5845 observer.unobserve(entry.target); 5846 }); 5847 }, 5848 { rootMargin: "0px 0px -8% 0px", threshold: 0.16 }, 5849 ); 5850 5851 revealItems.forEach((item, index) => { 5852 item.style.setProperty("--ed-board-reveal-delay", `${Math.min(index, 9) * 55}ms`); 5853 observer.observe(item); 5854 }); 5855 } 5856 5857 function installBoardDirectorsPage() { 5858 if (path !== "/copy-of-meet-the-team") return; 5859 5860 const boardMembers = [ 5861 { 5862 role: "Founder & CEO", 5863 name: "Jill Bolander Cohen", 5864 image: "/assets/captured/bb765029e0dec22c.jpg", 5865 bio: "Founder and CEO of the Lifeboat Project, a central Florida 501(c)3 nonprofit which increases awareness and provides wraparound services to victims and survivors of Human Trafficking such as trauma counseling, housing, personal development and educational resources. Jill was Vice-President of her family’s Coffee Service which has served central Florida for over 45 years. Her passion and previous career are that of a professional Jazz singer and worship leader. Jill was educated at Francis Marion University in Florence, South Carolina and Lake Brantley High School in Altamonte Springs, Florida. She and her husband, Gary, reside in Apopka, Florida.", 5866 }, 5867 { 5868 role: "Chairman of the Board of Directors, VP of Sales, Central Florida iHeartMedia Markets Group", 5869 name: "Shannon K. Fraser", 5870 image: "/assets/captured/8256887a1059a4a9.jpg", 5871 bio: "Shannon Fraser is the Senior Vice President of Sales at iHeartMedia Orlando, where she leads strategic sales across radio, digital, and event sponsorships. With over 20 years in media sales, Shannon is known for her strong leadership, innovative approach, and commitment to team development. She plays a key role in driving market growth and solidifying iHeartMedia’s leadership in the Orlando region. Known for her balance of creativity and analytics, she fosters and encourages a collaborative team environment with her sales approach. Shannon is also an advocate for mentorship and professional development, dedicating time to coach emerging sales professionals and encouraging diversity within the industry. Her influence extends beyond iHeartMedia as she actively participates in Orlando’s business community, contributing her expertise to local initiatives and organizations. Shannon has been deeply connected to the Orlando area for over 20 years. When she’s not working, she travels, loves local dining and supports her city in both sports and community/charitable events. She has dedicated the last few years to the cause of Human Trafficking and believes education and exposure are vital to stopping this tragedy affecting so many lives.", 5872 }, 5873 { 5874 role: "Treasurer of the Board of Directors, Chief Financial Officer of the Greater Orlando Sports Commission, (Retired)", 5875 name: "Gary Cohen", 5876 image: "/assets/captured/14e72653805984a6.jpg", 5877 bio: "Gary Cohen has 40 years of experience in financial management and strategic planning, most recently serving as CFO of the Greater Orlando Sports Commission for over eleven years until his retirement in mid-2025. He has 40 years of experience in financial management and strategic planning. Previously, he founded and led GaryCohenRunning. Cohen is also Treasurer of The Lifeboat Project, overseeing all financial matters, and a co-founder of CEO Leadership Forums. He has held various leadership roles, including Treasurer of the Wekiva Wilderness Trust and serving on the Maitland Presbyterian Church Finance C
5877ommittee. A former track and field champion, Gary has run over 120,000 miles and fifty marathons. His website, GaryCohenRunning, earned the 2017 Alan Jacobs Award for excellence in online journalism. He also authored All in a Day’s Run, a collection of essays on running and fitness.", 5878 }, 5879 { 5880 role: "Member of the Board, VP at Pinnacle Bank", 5881 name: "Linda Kennedy-Martin", 5882 image: lindaKennedyMartinPortrait, 5883 bio: "Linda has over 42 years of experience in the financial sector, including 30 years in Retail Branch Management and 8 years in Branch Administration. She serves as VP at Pinnacle Bank and brings deep Central Florida banking, leadership, and community service experience to The Lifeboat Project. Linda serves on several community boards and is an alumna of Florida State University. She has two adult children and five grandchildren.", 5884 }, 5885 { 5886 role: "Secretary of the Board, Vice President & Business Banking Relationship Manager at Fifth Third Bank", 5887 name: "Jeremy Smith", 5888 image: "/assets/captured/ba5c13f4150e8bf7.png", 5889 bio: "Jeremy serves as Vice President and Business Banking Relationship Manager of Fifth Third Bank, N.A. In this role, he works with a diverse group of commercial companies in the Central Florida market to deliver financial solutions and strategies utilizing the bank’s capital market products, syndications department and treasury management capabilities. Jeremy has more than 20 years of financial services experience and enjoys partnering with clients to help them overcome challenges and implement innovative growth and cash management strategies. Jeremy graduated from Allegheny College of Maryland with a Bachelor of Arts in Business Administration and Management. Jeremy is actively involved in his community serving on multiple boards and is a volunteer for United Way and Junior Achievement. He lives in Lake Mary with his wife and enjoys everything sports related and spending time outdoors with his family and their 4 legged best friend Lucy.", 5890 }, 5891 { 5892 role: "Member of the Board", 5893 name: "Donna Shelley", 5894 image: "/assets/captured/b4f760b21a54be9b.jpg", 5895 }, 5896 { 5897 role: "Member of the Board, Owner/Operator of RC Pizza", 5898 name: "Cindy Traenkner", 5899 image: "/assets/captured/cc497b65890bcafa.jpg", 5900 }, 5901 { 5902 role: "Member of the Board, VP of Government Relations at CityServe", 5903 name: "Todd Lamphere", 5904 image: "/assets/captured/314500664497c4ce.jpg", 5905 }, 5906 { 5907 role: "Member of the Board, Chief of Police St. Cloud", 5908 name: "Chief Doug Goerke", 5909 image: "/assets/captured/7208949e34b1ff2c.jpg", 5910 }, 5911 { 5912 role: "Member of the Board, Retired Lieutenant General for the United States Army", 5913 name: "General David Ohle", 5914 image: "/assets/captured/fc738a7368a95276.jpeg", 5915 }, 5916 { 5917 role: "Member of the Board, Seminole County Commissioner", 5918 name: "Commissioner Lee Constantine", 5919 image: "/assets/captured/a5b7b892dcb0d395.jpg", 5920 }, 5921 { 5922 role: "Member of the Board, Orange County Commissioner", 5923 name: "Commissioner Nicole Wilson", 5924 image: "/assets/captured/1b1ffcb72bb6841b.jpg", 5925 }, 5926 { 5927 role: "Member of the Board, Former Mayor of Apopka", 5928 name: "Bryan Nelson", 5929 image: "/assets/captured/88c8fca7ee6740cf.jpg", 5930 }, 5931 { 5932 role: "Member of the Board, Divisional Chief Legal Officer for AdventHealth", 5933 name: "Jessica Schuman", 5934 image: "/assets/captured/296423e421bd6a18.jpg", 5935 }, 5936 { 5937 role: "Member of the Board, Orange County Sheriff", 5938 name: "Sheriff John W. Mina", 5939 image: "/assets/captured/c64f186f3bcffcac.jpg", 5940 }, 5941 { 5942 role: "Member of the Board, President/CTO/AI iServ", 5943 name: "James Palmisano", 5944 image: "/assets/updates/james-palmisano.webp", 5945 }, 5946 ]; 5947 5948 const pageContent = document.querySelector("#PAGES_CONTAINER");
5949 const sitePages = pageContent?.querySelector(":scope > #SITE_PAGES"); 5950 const existing = document.querySelector(".ed-board-directors-page"); 5951 5952 document.body.classList.add("ed-board-directors-route"); 5953 if (sitePages) hideElement(sitePages); 5954 5955 if (existing) { 5956 if (pageContent && existing.parentNode !== pageContent) { 5957 pageContent.insertBefore(existing, sitePages || pageContent.firstChild); 5958 } 5959 bindBoardDirectorsReadMore(existing); 5960 revealBoardDirectorsPage(existing); 5961 return; 5962 } 5963 5964 const boardCards = boardMembers 5965 .map((member, index) => { 5966 const hasBio = Boolean(clean(member.bio)); 5967 const bioId = `ed-board-bio-${index}`; 5968 return ` 5969 <article class="ed-board-card ${hasBio ? "ed-board-card-with-bio" : "ed-board-card-compact"}"> 5970 <div class="ed-board-card-photo"> 5971 <img src="${escapeMarkup(member.image)}" alt="${escapeMarkup(`${member.name} portrait`)}" loading="${index < 3 ? "eager" : "lazy"}"> 5972 </div> 5973 <div class="ed-board-card-copy"> 5974 <p class="ed-board-role">${escapeMarkup(member.role)}</p> 5975 <h3>${escapeMarkup(member.name)}</h3> 5976 ${ 5977 hasBio 5978 ? `<p class="ed-board-card-bio" id="${bioId}">${escapeMarkup(member.bio)}</p> 5979 <button class="ed-board-bio-toggle" type="button" aria-expanded="false" aria-controls="${bioId}">Read more</button>` 5980 : "" 5981 } 5982 ${ 5983 member.href 5984 ? `<a class="ed-board-profile-link" href="${escapeMarkup(member.href)}">View profile</a>` 5985 : "" 5986 } 5987 </div> 5988 </article> 5989 `; 5990 }) 5991 .join(""); 5992 5993 const section = document.createElement("section"); 5994 section.className = "ed-board-directors-page"; 5995 section.dataset.edEmailUpdate = "board-directors-page"; 5996 section.setAttribute("aria-labelledby", "ed-board-directors-title"); 5997 section.innerHTML = ` 5998 <section class="ed-board-hero"> 5999 <div class="ed-board-shell"> 6000 <p class="ed-board-kicker">Who We Are</p> 6001 <h1 id="ed-board-directors-title">Board of Directors</h1> 6002 <p>The Lifeboat Project's Board of Directors brings nonprofit leadership, civic service, public safety, finance, business, and community expertise to the mission of supporting survivors and preventing human trafficking.</p> 6003 </div> 6004 </section> 6005 <section class="ed-board-members-section"> 6006 <div class="ed-board-shell"> 6007 <div class="ed-board-grid"> 6008 ${boardCards} 6009 </div> 6010 </div> 6011 </section> 6012 `; 6013 6014 if (pageContent) { 6015 pageContent.insertBefore(section, sitePages || pageContent.firstChild); 6016 } else { 6017 insertBeforeFooter(section); 6018 } 6019 6020 bindBoardDirectorsReadMore(section); 6021 revealBoardDirectorsPage(section); 6022 } 6023 6024 function installFinancialStrategicPlanPage() { 6025 if (path !== "/publications") return; 6026 6027 installMirrorPage( 6028 "/publications", 6029 "ed-financial-page", 6030 ` 6031 <section class="ed-financial-hero" aria-labelledby="ed-financial-title"> 6032 <div class="ed-financial-shell"> 6033 <p class="ed-financial-kicker">Transparency & Planning</p> 6034 <h1 id="ed-financial-title">Financial & Strategic Plan</h1> 6035 <p>The Lifeboat Project makes key planning, financial, and compliance documents available so donors, partners, and community members can see how the organization stewards resources and plans for survivor-centered care.</p> 6036 </div> 6037 </section> 6038 <section class="ed-financial-overview" aria-label="What these resources show"> 6039 <div class="ed-financial-shell ed-financial-overview-grid"> 6040 <article> 6041 <h2>Strategic Direction</h2> 6042 <p>The 2025-2027 Strategic Plan outlines mission priorities, goals, and strategies for the current planning period.</p> 6043 </article> 6044 <article> 6045 <h2>Financial Accountability</h2> 6046 <p>The Form 990 and audited financial statements provide a clearer view of nonprofit reporting and financial stewardship.</p> 6047 </article> 6048 <article> 6049 <h2>Compliance Standing</h2> 6050 <p>The annual corporate filing confirms current registration information and public compliance documentation.</p> 6051 </article> 6052 </div> 6053 </section> 6054 <section class="ed-financial-resources" aria-labelledby="ed-financial-resources-title"> 6055 <div class="ed-financial-shell"> 6056 <div class="ed-financial-section-heading"> 6057 <p class="ed-financial-kicker">Available Documents</p> 6058 <h2 id="ed-financial-resources-title">Planning and accountability resources</h2> 6059 <p>Each document opens as a PDF in a new tab.</p> 6060 </div> 6061 <div class="ed-financial-resource-grid"> 6062 <article> 6063 <h3>Strategic Plan 2025-2027</h3> 6064 <p>Outlines The Lifeboat Project's mission, values, goals, and strategies for the three-year planning period.</p> 6065 <a href="/assets/captured/4ad4052bcbeef908.pdf" target="_blank" rel="noopener noreferrer">Open Strategic Plan</a> 6066 </article> 6067 <article> 6068 <h3>Form 990</h3> 6069 <p>Federal tax-exempt filing for calendar year 2024, maintained as part of the organization's public nonprofit reporting.</p> 6070 <a href="/assets/captured/cebdb18255f5d56d.pdf" target="_blank" rel="noopener noreferrer">Open Form 990</a> 6071 </article> 6072 <article> 6073 <h3>Audited Financial Statements</h3> 6074 <p>Independent financial statements for fiscal years ended December 31, 2024 and 2023.</p> 6075 <a href="/assets/captured/818cda4f36e20898.pdf" target="_blank" rel="noopener noreferrer">Open Financial Statements</a> 6076 </article> 6077 <article> 6078 <h3>
6078Annual Corporate/Compliance Filing</h3> 6079 <p>Current Florida not-for-profit annual report filed April 7, 2026.</p> 6080 <a href="/assets/captured/c20950269423e2bb.pdf" target="_blank" rel="noopener noreferrer">Open Annual Filing</a> 6081 </article> 6082 </div> 6083 </div> 6084 </section> 6085 <section class="ed-financial-summary" aria-labelledby="ed-financial-summary-title"> 6086 <div class="ed-financial-shell"> 6087 <h2 id="ed-financial-summary-title">What these resources cover</h2> 6088 <p>Together, these documents outline the organization's strategic direction, financial accountability, and compliance standing. They are provided for donors, partners, and community members who want a clearer view of the work behind the mission.</p> 6089 </div> 6090 </section> 6091 <section class="ed-financial-contact" aria-label="Questions about financial and strategic resources"> 6092 <div class="ed-financial-shell"> 6093 <h2>Questions about these documents?</h2> 6094 <p>For questions about The Lifeboat Project's planning materials, financial reporting, or compliance documentation, please contact the team directly.</p> 6095 <a href="/contact/">Contact The Lifeboat Project</a> 6096 </div> 6097 </section> 6098 `, 6099 ); 6100 } 6101 6102 function installWhatWeDoVideo() { 6103 if (path !== "/what-we-do") return; 6104 6105 const root = document.getElementById(whatWeDoVideo.rootId); 6106 if (!root) return; 6107 6108 const nativePlayer = root.querySelector("video, iframe"); 6109 if (nativePlayer && !nativePlayer.classList?.contains("lifeboat-what-we-do-video")) { 6110 root.classList.add("lifeboat-what-we-do-video-root"); 6111 return; 6112 } 6113 6114 let video = root.querySelector(".lifeboat-what-we-do-video"); 6115 if (!video) { 6116 video = document.createElement("video"); 6117 video.className = "lifeboat-what-we-do-video"; 6118 video.controls = true; 6119 video.playsInline = true; 6120 video.preload = "metadata"; 6121 video.setAttribute("controls", ""); 6122 video.setAttribute("playsinline", ""); 6123 video.setAttribute("preload", "metadata"); 6124 video.setAttribute("title", whatWeDoVideo.title); 6125 video.setAttribute("aria-label", whatWeDoVideo.title); 6126 root.replaceChildren(video); 6127 } 6128 6129 if (video.getAttribute("src") !== whatWeDoVideo.src) { 6130 video.setAttribute("src", whatWeDoVideo.src); 6131 } 6132 if (video.getAttribute("poster") !== whatWeDoVideo.poster) { 6133 video.setAttribute("poster", whatWeDoVideo.poster); 6134 } 6135 6136 root.classList.add("lifeboat-what-we-do-video-root"); 6137 } 6138 6139 function findWhatWeDoNativeIntro() { 6140 const knownIntro = document.getElementById("comp-lt8rias7"); 6141 if (knownIntro) return knownIntro; 6142 6143 const nativeHeading = [...document.querySelectorAll("h1, [role='heading'], body *")].find((element) => 6144 /We believe in showing people love\s+without conditions/i.test(clean(element.innerText || element.textContent)), 6145 ); 6146 return nativeHeading ? closestPageSection(nativeHeading) : null; 6147 } 6148 6149 function syncWhatWeDoSectionOrder() { 6150 if (path !== "/what-we-do") return; 6151 6152 const pageContent = document.querySelector("#PAGES_CONTAINER"); 6153 const sitePages = pageContent?.querySelector(":scope > #SITE_PAGES"); 6154 if (!pageContent || !sitePages) return; 6155 6156 [ 6157 document.querySelector("[data-ed-email-update='what-we-do-header']"), 6158 document.querySelector("[data-ed-email-update='what-we-do-believe-intro']"), 6159 document.querySelector("[data-ed-email-update='shield-program']"), 6160 document.querySelector("[data-ed-email-update='lifelong-care-redesign']"), 6161 ] 6162 .filter(Boolean) 6163 .forEach((section) => { 6164 pageContent.insertBefore(section, sitePages); 6165 }); 6166 } 6167 6168 function installWhatWeDoHeader() { 6169 if (path !== "/what-we-do") return; 6170 6171 document.body.classList.add("ed-what-we-do-route"); 6172 6173 const existing = document.querySelector("[data-ed-email-update='what-we-do-header']"); 6174 6175 const placeHeader = (section) => { 6176 const pageContent = document.querySelector("#PAGES_CONTAINER");
6177 const sitePages = pageContent?.querySelector(":scope > #SITE_PAGES"); 6178 if (pageContent && sitePages) { 6179 pageContent.insertBefore(section, sitePages); 6180 return; 6181 } 6182 6183 const pageRoot = document.querySelector("[data-mesh-id='ContainercmanbinlineContent-gridContainer']") || document.querySelector("#SITE_PAGES"); 6184 if (pageRoot) { 6185 pageRoot.insertBefore(section, pageRoot.firstChild); 6186 } else { 6187 insertBeforeFooter(section); 6188 } 6189 }; 6190 6191 if (existing) { 6192 placeHeader(existing); 6193 syncWhatWeDoSectionOrder(); 6194 return; 6195 } 6196 6197 const section = document.createElement("section"); 6198 section.className = "ed-what-hero-section"; 6199 section.dataset.edEmailUpdate = "what-we-do-header"; 6200 section.setAttribute("aria-labelledby", "ed-what-hero-title"); 6201 section.innerHTML = ` 6202 <div class="ed-what-hero-frame"> 6203 <img src="${whatWeDoHeaderImage}" alt="What We Do. We exist to end human trafficking and restore hope to survivors." fetchpriority="high"> 6204 </div> 6205 <div class="ed-screen-reader-only"> 6206 <h1 id="ed-what-hero-title">What We Do</h1> 6207 <p>We exist to end human trafficking and restore hope to survivors through prevention, rescue, restoration, and aftercare.</p> 6208 </div> 6209 `; 6210 6211 placeHeader(section); 6212 syncWhatWeDoSectionOrder(); 6213 } 6214 6215 function installWhatWeDoBelieveIntro() { 6216 if (path !== "/what-we-do") return; 6217 6218 const nativeIntro = findWhatWeDoNativeIntro(); 6219 if (nativeIntro) hideElement(nativeIntro); 6220 hideElement(document.getElementById("comp-mm5yvx30")); 6221 6222 const existing = document.querySelector("[data-ed-email-update='what-we-do-believe-intro']"); 6223 const placeIntro = (section) => { 6224 const whatWeDoHeader = document.querySelector("[data-ed-email-update='what-we-do-header']"); 6225 if (whatWeDoHeader?.parentNode) { 6226 whatWeDoHeader.insertAdjacentElement("afterend", section); 6227 return; 6228 } 6229 insertBeforeFooter(section); 6230 }; 6231 6232 if (existing) { 6233 placeIntro(existing); 6234 syncWhatWeDoSectionOrder(); 6235 return; 6236 } 6237 6238 const section = document.createElement("section"); 6239 section.className = "ed-what-believe-section"; 6240 section.dataset.edEmailUpdate = "what-we-do-believe-intro"; 6241 section.setAttribute("aria-labelledby", "ed-what-believe-title"); 6242 section.innerHTML = ` 6243 <div class="ed-what-believe-shell"> 6244 <p class="ed-email-kicker">Our Approach</p> 6245 <h2 id="ed-what-believe-title">We believe in showing people love without conditions.</h2> 6246 <p>Every program begins with dignity, safety, and steady support for survivors as they move from crisis toward lasting freedom.</p> 6247 </div> 6248 `; 6249 6250 placeIntro(section); 6251 syncWhatWeDoSectionOrder(); 6252 } 6253 6254 function installLifelongCareSection() { 6255 if (path !== "/what-we-do") return; 6256 6257 const existing = document.querySelector("[data-ed-email-update='lifelong-care-redesign']"); 6258 const titleElement = elementsByExactText("Lifelong Care")[0]; 6259 const nativeSection = titleElement ? closestPageSection(titleElement) : null; 6260 6261 if (nativeSection && nativeSection.dataset.edEmailUpdate !== "lifelong-care-redesign") { 6262 hideElement(nativeSection); 6263 } 6264 6265 const placeLifelongCare = (targetSection) => { 6266 const believeIntro = document.querySelector("[data-ed-email-update='what-we-do-believe-intro']"); 6267 if (believeIntro?.parentNode) { 6268 believeIntro.insertAdjacentElement("afterend", targetSection); 6269 return; 6270 } 6271 6272 const whatWeDoHeader = document.querySelector("[data-ed-email-update='what-we-do-header']"); 6273 if (whatWeDoHeader?.parentNode) { 6274 whatWeDoHeader.insertAdjacentElement("afterend", targetSection); 6275 return; 6276 } 6277 6278 if (nativeSection?.parentNode) { 6279 nativeSection.parentNode.insertBefore(targetSection, nativeSection); 6280 } else { 6281 insertBeforeFooter(targetSection); 6282 } 6283 }; 6284 6285 if (existing) { 6286 placeLifelongCare(existing); 6287 syncWhatWeDoSectionOrder(); 6288 return; 6289 } 6290 6291 const section = document.createElement("section"); 6292 section.className = "ed-lifelong-care-section"; 6293 section.id = "lifelong-care"; 6294 section.dataset.edEmailUpdate = "lifelong-care-redesign"; 6295 section.setAttribute("aria-labelledby", "ed-lifelong-care-title"); 6296 section.innerHTML = ` 6297 <div class="ed-lifelong-care-shell"> 6298 <div class="ed-lifelong-care-copy"> 6299 <p class="ed-lifelong-care-kicker">Lifelong Care</p> 6300 <h2 id="ed-lifelong-care-title">Care does not end when a survivor is safe.</h2> 6301 <p class="ed-lifelong-care-lede">The Lifeboat Project helps survivors move through the practical next steps: crisis response, counseling, housing, benefits, legal advocacy, and steady relationships that make recovery possible.</p> 6302 <div class="ed-lifelong-care-actions"> 6303 <a class="ed-lifelong-care-button primary" href="${donateUrl}" target="_blank" rel="noopener noreferrer">Support Survivor Care</a> 6304 <a class="ed-lifelong-care-button secondary" href="${requestHelpUrl}" target="_blank" rel="noopener noreferrer">Request Help</a> 6305 </div> 6306 </div> 6307 <figure class="ed-lifelong-care-visual"> 6308 <img src="/assets/captured/b8752ecd9c945a05.jpeg" alt="Interview still from a Lifeboat Project story video" loading="lazy">
6309 <figcaption>Support continues through the appointments, paperwork, housing steps, and relationships that follow stabilization.</figcaption> 6310 </figure> 6311 <div class="ed-lifelong-care-proof" aria-label="Lifelong care priorities"> 6312 <article> 6313 <span>01</span> 6314 <h3>Immediate Safety</h3> 6315 <p>Crisis response, safety planning, and secure support help survivors take the first steps out of danger.</p> 6316 </article> 6317 <article> 6318 <span>02</span> 6319 <h3>Whole-Person Healing</h3> 6320 <p>Trauma-informed counseling, healthcare connections, and daily stability support recovery over time.</p> 6321 </article> 6322 <article> 6323 <span>03</span> 6324 <h3>Advocacy & Access</h3> 6325 <p>Guidance through legal, housing, benefits, education, and employment systems keeps progress moving.</p> 6326 </article> 6327 <article> 6328 <span>04</span> 6329 <h3>Community for Life</h3> 6330 <p>Mentoring, healthy relationships, and continued check-ins help survivors build trust, purpose, and independence.</p> 6331 </article> 6332 </div> 6333 <aside class="ed-lifelong-care-note"> 6334 <strong>Patient, practical, close to home.</strong> 6335 <p>Long-term care means staying present for the paperwork, appointments, housing transitions, setbacks, milestones, and new dreams that come after immediate crisis support.</p> 6336 </aside> 6337 </div> 6338 `; 6339 6340 placeLifelongCare(section); 6341 syncWhatWeDoSectionOrder(); 6342 } 6343 6344 function installShieldProgram() { 6345 if (path !== "/what-we-do") return; 6346 6347 document.querySelectorAll("[data-ed-email-update='shield-program']").forEach((section) => section.remove()); 6348 hideSectionsMatching(/Compass Program|Haven Homes|I\.?\s*SAFE|II\.?\s*HEAL|III\.?\s*GROW/i); 6349 6350 if (document.querySelector("[data-ed-email-update='shield-program']")) return; 6351 6352 const section = document.createElement("section"); 6353 section.className = "ed-email-section ed-shield-section"; 6354 section.id = "shield-program"; 6355 section.tabIndex = -1; 6356 section.dataset.edEmailUpdate = "shield-program"; 6357 section.innerHTML = ` 6358 <div class="ed-shield-shell"> 6359 <div class="ed-shield-top"> 6360 <div class="ed-shield-intro"> 6361 <p class="ed-email-kicker">The S.H.I.E.L.D. Program</p> 6362 <h2>From Crisis to Autonomy: The S.H.I.E.L.D. Program</h2> 6363 <p>The Lifeboat Project's S.H.I.E.L.D. Program is a comprehensive, trauma-informed framework designed to transition survivors of human trafficking from immediate crisis to long-term self-sufficiency and lifelong empowerment.</p> 6364 <div class="ed-email-actions"> 6365 <a class="ed-email-button" href="https://thelifeboatproject.networkforgood.com/projects/120280-donate-to-the-lifeboat-project" target="_blank" rel="noopener noreferrer">Support Our Mission</a> 6366 <a class="ed-email-button secondary" href="mailto:[email protected]?subject=S.H.I.E.L.D.%20Program%20Information">Request Program Information</a> 6367 </div> 6368 </div> 6369 <aside class="ed-shield-continuum"> 6370 <h3>The S.H.I.E.L.D. Continuum of Care</h3> 6371 <p>Recovery is not a single event; it is a lifelong journey. The S.H.I.E.L.D. model represents a holistic approach to restoration by addressing immediate physical safety first, then systematically strengthening a survivor's health, legal standing, financial independence, and community support network.</p> 6372 </aside> 6373 </div> 6374 <div class="ed-shield-steps"> 6375 <article><span class="ed-email-letter">S</span><h3>Stabilization & Safety</h3><p>Immediate crisis intervention, secure emergency housing, and critical safety planning help remove survivors from harm's way and provide a peaceful space to begin decompressing from trauma.</p></article> 6376 <article><span class="ed-email-letter">H</span><h3>Holistic Healthcare</h3><p>Coordinated medical treatment, psychiatric support, long-term counseling, and restorative wellness therapies address both physical and psychological wounds.</p></article> 6377 <article><span class="ed-email-letter">I</span><h3>Institutional Advocacy</h3><p>Advocates walk alongside survivors through criminal justice proceedings, child welfare systems, victim compensation, housing, and government agencies.</p></article> 6378 <article><span class="ed-email-letter">E</span><h3>Economic Empowerment</h3><p>Job readiness training, financial literacy education, resume building, and business partnerships help create safe, dignified employment and education pathways.</p></article> 6379 <article><span class="ed-email-letter">L</span><h3>Lifelong Mentoring & Social Integrity</h3><p>Peer mentoring, community reintegration, healthy social networks, and ongoing mentorship help rebuild trust in community and long-term resilience.</p></article> 6380 <article><span class="ed-email-letter">D</span><h3>Desired Development</h3><p>Individualized planning helps each survivor identify personal, creative, educational, or professional dreams and access resources to pursue them.</p></article> 6381 </div> 6382 <div class="ed-shield-impact"> 6383 <h3>Why the S.H.I.E.L.D. Approach Works</h3> 6384 <div> 6385 <p>Many programs offer crisis shelter, but survivors often struggle when that initial safety net is removed. S.H.I.E.L.D. bridges the gap between immediate stabilization and long-term, self-directed development so survivors can build lives of deep purpose, financial stability, and lasting freedom.</p> 6386 <p>We do not define survivors by what they have been through, but by where they are going. S.H.I.E.L.D. provides the support they need to heal and the tools they need to soar.</p> 6387 </div> 6388 </div> 6389 </div> 6390 `; 6391 6392 const believeIntro = document.querySelector("[data-ed-email-update='what-we-do-believe-intro']"); 6393 if (believeIntro?.parentNode) { 6394 believeIntro.insertAdjacentElement("afterend", section); 6395 } else { 6396 const whatWeDoHeader = document.querySelector("[data-ed-email-update='what-we-do-header']"); 6397 if (whatWeDoHeader?.parentNode) { 6398 whatWeDoHeader.insertAdjacentElement("afterend", section); 6399 } else { 6400 const hiddenCompass = [...document.querySelectorAll(".ed-hidden")].find((candidate) => 6401 /Compass Program|Haven Homes|I\.?\s*SAFE|II\.?\s*HEAL|III\.?\s*GROW/i.test(clean(candidate.innerText || candidate.textContent)), 6402 ); 6403 if (hiddenCompass?.parentNode) { 6404 hiddenCompass.parentNode.insertBefore(section, hiddenCompass); 6405 } else { 6406 insertBeforeFooter(section); 6407 } 6408 } 6409 } 6410 syncWhatWeDoSectionOrder(); 6411 fitPanelToVisualViewport(section); 6412 6413 if (window.location.hash === "#shield-program") { 6414 window.requestAnimationFrame(() => { 6415 section.scrollIntoView({ block: "start" }); 6416 section.focus({ preventScroll: true }); 6417 }); 6418 } 6419 } 6420 6421 function hardStopWhatWeDoFooter() { 6422 if (path !== "/what-we-do") return; 6423 6424 const sitePages = 6425 document.querySelector("#PAGES_CONTAINER > #SITE_PAGES") || 6426 document.querySelector("#SITE_PAGES"); 6427 const contentRoot = 6428 sitePages?.querySelector("#Containercmanb") || 6429 sitePages?.querySelector("[data-mesh-id='ContainercmanbinlineContent-gridContainer']")?.parentElement || 6430 sitePages?.querySelector(".ed-lifelong-care-section")?.parentElement; 6431 if (!sitePages || !contentRoot) return; 6432 6433 const siteTop = sitePages.getBoundingClientRect().top; 6434 const measuredContent = [ 6435 contentRoot, 6436 ...sitePages.querySelectorAll("#comp-lt8rias7:not(.ed-hidden
6436), .ed-lifelong-care-section, .ed-shield-section"), 6437 ]; 6438 const contentBottom = Math.max( 6439 ...measuredContent 6440 .map((element) => element.getBoundingClientRect().bottom - siteTop) 6441 .filter((value) => Number.isFinite(value) && value > 0), 6442 ); 6443 const contentHeight = Math.ceil(contentBottom + 1); 6444 if (!Number.isFinite(contentHeight) || contentHeight < 200) return; 6445 6446 [ 6447 sitePages, 6448 sitePages.querySelector("#SITE_PAGES_TRANSITION_GROUP"), 6449 sitePages.querySelector("#SITE_PAGES_TRANSITION_GROUP > .theme-vars"), 6450 sitePages.querySelector(".wixui-page"), 6451 ].forEach((element) => { 6452 if (!element) return; 6453 element.style.height = `${contentHeight}px`; 6454 element.style.minHeight = "0px"; 6455 element.style.overflow = "hidden"; 6456 }); 6457 } 6458 6459 function trimHomepageFooterGap() { 6460 if (path !== "/" || isMobileShellViewport()) return; 6461 6462 const sitePages = 6463 document.querySelector("#PAGES_CONTAINER > #SITE_PAGES") || 6464 document.querySelector("#SITE_PAGES"); 6465 if (!sitePages) return; 6466 6467 const siteTop = sitePages.getBoundingClientRect().top; 6468 const contentSections = [ 6469 ...sitePages.querySelectorAll( 6470 "#comp-mm5rvriw, #comp-mqtvbr2q, #comp-lt8riarj1, section[data-ed-email-update], .ed-home-mission-video, .ed-yacht-rock-home-promo, .ed-home-get-involved-section", 6471 ), 6472 ].filter((element) => { 6473 const rect = element.getBoundingClientRect(); 6474 const style = getComputedStyle(element); 6475 return ( 6476 rect.width > 1 && 6477 rect.height > 1 && 6478 style.display !== "none" && 6479 style.visibility !== "hidden" && 6480 Number(style.opacity || 1) !== 0 6481 ); 6482 }); 6483 if (!contentSections.length) return; 6484 6485 const contentBottom = Math.max( 6486 ...contentSections 6487 .map((element) => element.getBoundingClientRect().bottom - siteTop) 6488 .filter((value) => Number.isFinite(value) && value > 0), 6489 ); 6490 const contentHeight = Math.ceil(contentBottom + 1); 6491 if (!Number.isFinite(contentHeight) || contentHeight < 800) return; 6492 6493 [ 6494 sitePages, 6495 sitePages.querySelector("#SITE_PAGES_TRANSITION_GROUP"), 6496 sitePages.querySelector("#SITE_PAGES_TRANSITION_GROUP > .theme-vars"), 6497 sitePages.querySelector(".wixui-page"), 6498 ].forEach((element) => { 6499 if (!element) return; 6500 element.style.setProperty("height", `${contentHeight}px`, "important"); 6501 element.style.setProperty("min-height", "0px", "important"); 6502 element.style.setProperty("overflow", "hidden", "important"); 6503 }); 6504 } 6505 6506 function installAdvisoryReadMoreFallbacks() { 6507 if (path !== "/copy-of-meet-the-team-1") return; 6508 6509 document.body.classList.add("ed-advisory-route"); 6510 document.querySelector("[data-ed-email-update='coming-soon']")?.remove(); 6511 6512 const sitePages = document.querySelector("#SITE_PAGES"); 6513 if (sitePages?.classList.contains("ed-hidden")) { 6514 sitePages.classList.remove("ed-hidden"); 6515 sitePages.removeAttribute("aria-hidden"); 6516 } 6517 6518 document.querySelectorAll(".wixui-repeater__item").forEach((card) => { 6519 const bioRoot = card.querySelector(".wixui-collapsible-text"); 6520 const paragraph = bioRoot?.querySelector("p"); 6521 if (!bioRoot || !paragraph) return; 6522 6523 const nativeButton = [...bioRoot.querySelectorAll("button")].find((button) => 6524 /read more|read less/i.test(clean(button.innerText || button.textContent)) || 6525 button.classList.contains("wixui-collapsible-text__button"), 6526 ); 6527 const fallback = card.querySelector(".ed-advisory-read-more"); 6528 6529 if (nativeButton) { 6530 bioRoot.removeAttribute("data-ed-full-bio"); 6531 bioRoot.classList.remove("ed-advisory-expanded"); 6532 card.classList.remove("ed-advisory-expanded", "ed-advisory-collapsed"); 6533 fallback?.remove(); 6534 return; 6535 } 6536 6537 bioRoot.dataset.edFullBio = "true"; 6538 6539 let button = fallback; 6540 if (!button) { 6541 button = document.createElement("button"); 6542 button.type = "button"; 6543 button.className = "ed-advisory-read-more"; 6544 bioRoot.appendChild(button); 6545 } 6546 6547 if (button.dataset.edAdvisoryBound !== "true") { 6548 button.dataset.edAdvisoryBound = "true"; 6549 button.addEventListener("click", () => { 6550 const expanded = !bioRoot.classList.contains("ed-advisory-expanded"); 6551 bioRoot.classList.toggle("ed-advisory-expanded", expanded); 6552 card.classList.toggle("ed-advisory-expanded", expanded); 6553 card.classList.toggle("ed-advisory-collapsed", !expanded); 6554 button.textContent = expanded ? "Read less" : "Read more"; 6555 button.setAttribute("aria-expanded", String(expanded)); 6556 }); 6557 } 6558 6559 if (!card.classList.contains("ed-advisory-expanded")) { 6560 card.classList.add("ed-advisory-collapsed"); 6561 button.textContent = "Read more"; 6562 button.setAttribute("aria-expanded", "false"); 6563 } 6564 }); 6565 } 6566 6567 function repairAdvisoryRepeaterLayout() { 6568 if (path !== "/copy-of-meet-the-team-1") return; 6569 6570 const repeater = document.querySelector("#comp-mmcn315t"); 6571 if (!repeater) return; 6572 6573 const wrapper = repeater.querySelector("#comp-mmcn315t_wrapper"); 6574 const fluid = repeater.querySelector("fluid-columns-repeater"); 6575 const cards = [...repeater.querySelectorAll(".wixui-repeater__item")]; 6576 const section = closestPageSection(repeater); 6577 const visualWidth = Math.min( 6578 document.documentElement.clientWidth || window.innerWidth,
6579 window.visualViewport?.width || window.innerWidth, 6580 ); 6581 const advisoryColumnCount = visualWidth < 700 ? 1 : visualWidth < 1040 ? 2 : 3; 6582 6583 section?.classList.add("ed-advisory-section-repaired"); 6584 repeater.classList.add("ed-advisory-repaired"); 6585 wrapper?.classList.add("ed-advisory-wrapper-repaired"); 6586 fluid?.classList.add("ed-advisory-fluid-repaired"); 6587 6588 [section, repeater, wrapper, fluid].forEach((element) => { 6589 if (!element) return; 6590 element.style.setProperty("height", "auto", "important"); 6591 element.style.setProperty("min-height", "0", "important"); 6592 element.style.setProperty("overflow", "visible", "important"); 6593 }); 6594 6595 if (fluid) { 6596 fluid.style.setProperty("box-sizing", "border-box", "important"); 6597 fluid.style.setProperty("display", "grid", "important"); 6598 fluid.style.setProperty("gap", advisoryColumnCount === 1 ? "30px" : "30px", "important"); 6599 fluid.style.setProperty( 6600 "grid-template-columns", 6601 `repeat(${advisoryColumnCount}, minmax(0, 1fr))`, 6602 "important", 6603 ); 6604 fluid.style.setProperty("justify-content", "center", "important"); 6605 fluid.style.setProperty("left", "auto", "important"); 6606 fluid.style.setProperty("margin", "0 auto", "important"); 6607 fluid.style.setProperty("position", "relative", "important"); 6608 fluid.style.setProperty("transform", "none", "important"); 6609 fluid.style.setProperty("visibility", "visible", "important"); 6610 fluid.style.setProperty("width", "100%", "important"); 6611 } 6612 6613 cards.forEach((card) => { 6614 card.classList.add("ed-advisory-card-repaired"); 6615 card.style.setProperty("height", "auto", "important"); 6616 card.style.setProperty("left", "auto", "important"); 6617 card.style.setProperty("position", "relative", "important"); 6618 card.style.setProperty("top", "auto", "important"); 6619 card.style.setProperty("overflow", "visible", "important"); 6620 card.style.setProperty("width", "100%", "important"); 6621 }); 6622 } 6623 6624 let advisoryRepairObserver = null; 6625 let advisoryRepairTimer = 0; 6626 6627 function scheduleAdvisoryRepair() { 6628 if (path !== "/copy-of-meet-the-team-1") return; 6629 6630 if (advisoryRepairTimer) { 6631 window.clearTimeout(advisoryRepairTimer); 6632 } 6633 6634 advisoryRepairTimer = window.setTimeout(() => { 6635 advisoryRepairTimer = 0; 6636 installAdvisoryReadMoreFallbacks(); 6637 repairAdvisoryRepeaterLayout(); 6638 }, 80); 6639 } 6640 6641 function installAdvisoryRepairObserver() { 6642 if (path !== "/copy-of-meet-the-team-1" || advisoryRepairObserver) return; 6643 6644 const target = document.querySelector("#PAGES_CONTAINER") || document.body; 6645 if (!target) return; 6646 6647 advisoryRepairObserver = new MutationObserver((mutations) => { 6648 const advisoryChanged = mutations.some((mutation) => 6649 [...mutation.addedNodes].some((node) => { 6650 if (node.nodeType !== Node.ELEMENT_NODE) return false; 6651 return ( 6652 node.matches?.("#comp-mmcn315t, .wixui-repeater__item, .wixui-collapsible-text") || 6653 node.querySelector?.("#comp-mmcn315t, .wixui-repeater__item, .wixui-collapsible-text") 6654 ); 6655 }), 6656 ); 6657 6658 if (advisoryChanged) { 6659 scheduleAdvisoryRepair(); 6660 } 6661 }); 6662 advisoryRepairObserver.observe(target, { childList: true, subtree: true }); 6663 } 6664 6665 function installMirrorPage(slug, className, html) { 6666 if (path !== slug) return; 6667 6668 const pageContent = document.querySelector("#PAGES_CONTAINER"); 6669 const sitePages = pageContent?.querySelector(":scope > #SITE_PAGES"); 6670 const existing = document.querySelector(`.${className}`); 6671 6672 if (sitePages) { 6673 sitePages.classList.add("ed-hidden"); 6674 sitePages.setAttribute("aria-hidden", "true"); 6675 } 6676 6677 if (existing) { 6678 if (pageContent && existing.parentNode !== pageContent) { 6679 pageContent.insertBefore(existing, sitePages || pageContent.firstChild); 6680 } 6681 return; 6682 } 6683 6684 const section = document.createElement("section"); 6685 section.className = className; 6686 section.dataset.edEmailUpdate = className; 6687 section.innerHTML = html; 6688 6689 if (pageContent) { 6690 pageContent.insertBefore(section, sitePages || pageContent.firstChild); 6691 return; 6692 } 6693 6694 insertBeforeFooter(section); 6695 } 6696 6697 function partnerFormHtml(options = {}) { 6698 const className = options.className || "ed-partner-form-card"; 6699 const prefix = options.prefix || "ed-partner"; 6700 const statusClassName = options.statusClassName || "ed-partner-form-status"; 6701 6702 return ` 6703 <form class="${className}" data-ed-partner-form action="/api/contact" method="post" aria-label="International partnership form"> 6704 <div class="ed-partner-form-grid"> 6705 <label for="${prefix}-organization">
6706 <span>Organization Name</span> 6707 <input id="${prefix}-organization" name="organization" autocomplete="organization"> 6708 </label> 6709 <label for="${prefix}-organization-type"> 6710 <span>Organization Type</span> 6711 <input id="${prefix}-organization-type" name="organizationType"> 6712 </label> 6713 <label for="${prefix}-contact-name"> 6714 <span>Primary Contact Name *</span> 6715 <input id="${prefix}-contact-name" name="primaryContactName" autocomplete="name" required> 6716 </label> 6717 <label for="${prefix}-email"> 6718 <span>Email *</span> 6719 <input id="${prefix}-email" name="email" type="email" autocomplete="email" required> 6720 </label> 6721 <label for="${prefix}-website"> 6722 <span>Website</span> 6723 <input id="${prefix}-website" name="website" type="url" autocomplete="url"> 6724 </label> 6725 <label for="${prefix}-social"> 6726 <span>LinkedIn / Social Media</span> 6727 <input id="${prefix}-social" name="social"> 6728 </label> 6729 <label class="ed-partner-form-wide" for="${prefix}-interest"> 6730 <span>Areas of Collaboration Interest</span> 6731 <textarea id="${prefix}-interest" name="collaborationInterest" rows="4"></textarea> 6732 </label> 6733 <label class="ed-partner-form-wide" for="${prefix}-introduction"> 6734 <span>Short organization introduction</span> 6735 <textarea id="${prefix}-introduction" name="introduction" rows="4"></textarea> 6736 </label> 6737 <label class="ed-partner-form-wide" for="${prefix}-message"> 6738 <span>What would you like to explore with The Lifeboat Project? *</span> 6739 <textarea id="${prefix}-message" name="message" rows="5" required></textarea> 6740 </label> 6741 <div class="ed-partner-hp" aria-hidden="true"> 6742 <label for="${prefix}-company">Company</label> 6743 <input id="${prefix}-company" name="company" tabindex="-1" autocomplete="off"> 6744 </div> 6745 </div> 6746 <button type="submit">Submit</button> 6747 <p class="${statusClassName}" data-ed-partner-status role="status" aria-live="polite"></p> 6748 </form> 6749 `; 6750 } 6751 6752 function cleanFormValue(value) { 6753 return String(value || "") 6754 .replace(/\r\n/g, "\n") 6755 .replace(/\r/g, "\n") 6756 .trim(); 6757 } 6758 6759 function validEmail(email) { 6760 return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); 6761 } 6762 6763 function setPartnerFormStatus(form, message, state = "info") { 6764 const status = form.querySelector("[data-ed-partner-status]"); 6765 if (!status) return; 6766 status.dataset.state = state; 6767 status.textContent = message; 6768 } 6769 6770 function partnerFormPayload(form) { 6771 const formData = new FormData(form); 6772 const value = (name) => cleanFormValue(formData.get(name)); 6773 const contactName = clean(value("primaryContactName")); 6774 const email = clean(value("email")).toLowerCase(); 6775 const message = value("message"); 6776 const nameParts = contactName.split(/\s+/).filter(Boolean); 6777 const firstName = nameParts.shift() || contactName; 6778 const lastName = nameParts.join(" ") || "Partner"; 6779 const organization = clean(value("organization")); 6780 const subjectTarget = organization || contactName || "International Partnership"; 6781 const fields = [ 6782 ["Organization Name", organization || "Not provided"], 6783 ["Organization Type", clean(value("organizationType")) || "Not provided"], 6784 ["Primary Contact Name", contactName || "Not provided"], 6785 ["Email", email || "Not provided"], 6786 ["Website", clean(value("website")) || "Not provided"], 6787 ["LinkedIn / Social Media", clean(value("social")) || "Not provided"], 6788 ["Areas of Collaboration Interest", value("collaborationInterest") || "Not provided"], 6789 ["Short organization introduction", value("introduction") || "Not provided"], 6790 ["What they would like to explore", message || "Not provided"], 6791 ]; 6792 6793 return { 6794 contactName, 6795 email, 6796 message, 6797 payload: { 6798 firstName, 6799 lastName, 6800 email, 6801 phone: "", 6802 address: "", 6803 subject: `International partnership inquiry: ${subjectTarget}`, 6804 message: [ 6805 "New Lifeboat international partnership form submission", 6806 "", 6807 ...fields.map(([label, fieldValue]) => `${label}: ${fieldValue}`), 6808 ].join("\n"), 6809 company: value("company"), 6810 }, 6811 }; 6812 } 6813 6814 async function submitPartnerForm(form) { 6815 const { contactName, email, message, payload } = partnerFormPayload(form); 6816 6817 if (!contactName || !validEmail(email) || !message) { 6818 setPartnerFormStatus(form, "Please enter your name, email address, and partnership details.", "error"); 6819 return; 6820 } 6821 6822 const button = form.querySelector("button[type='submit']"); 6823 const originalText = button?.textContent || "Submit"; 6824 if (button) { 6825 button.disabled = true; 6826 button.textContent = "Sending..."; 6827 } 6828 setPartnerFormStatus(form, `Sending your partnership form to ${contactEmail}...`); 6829 6830 try { 6831 const response = await fetch("/api/contact", { 6832 method: "POST", 6833 headers: { "content-type": "application/json" }, 6834 body: JSON.stringify(payload), 6835 }); 6836 const result = await response.json().catch(() => ({})); 6837 if (!response.ok || !result.ok) { 6838 throw new Error(result.error || "Unable to send this form right now."); 6839 } 6840 6841 form.reset(); 6842 window.lifeboatAnalytics?.track('partnership_submit_success'); 6843 setPartnerFormStatus(form, result.message || `Thanks, your form was sent to ${contactEmail}.`, "success"); 6844 } catch (error) { 6845 const errorMessage = error instanceof Error ? error.message : "Unable to send this form right now."; 6846 setPartnerFormStatus( 6847 form, 6848 `${errorMessage} You can also email ${contactEmail}.`, 6849 "error", 6850 ); 6851 } finally { 6852 if (button) { 6853 button.disabled = false;
6854 button.textContent = originalText; 6855 } 6856 } 6857 } 6858 6859 function installPartnerForms(root = document) { 6860 root.querySelectorAll("[data-ed-partner-form]").forEach((form) => { 6861 if (form.dataset.edPartnerFormBound === "true") return; 6862 form.dataset.edPartnerFormBound = "true"; 6863 form.setAttribute("action", "/api/contact"); 6864 form.setAttribute("method", "post"); 6865 6866 form.addEventListener( 6867 "submit", 6868 (event) => { 6869 event.preventDefault(); 6870 event.stopImmediatePropagation(); 6871 submitPartnerForm(form); 6872 }, 6873 true, 6874 ); 6875 }); 6876 } 6877 6878 function installInternationalPartnerFormPage() { 6879 if (path !== "/partner-form" || isMobileShellViewport()) return; 6880 6881 document.body.classList.add("ed-partner-form-route"); 6882 6883 const pageContent = document.querySelector("#PAGES_CONTAINER"); 6884 const sitePages = pageContent?.querySelector(":scope > #SITE_PAGES"); 6885 const existing = document.querySelector(".ed-partner-form-page"); 6886 6887 if (sitePages) { 6888 sitePages.classList.add("ed-hidden"); 6889 sitePages.setAttribute("aria-hidden", "true"); 6890 } 6891 6892 if (existing) { 6893 if (pageContent && existing.parentNode !== pageContent) { 6894 pageContent.insertBefore(existing, sitePages || pageContent.firstChild); 6895 } 6896 installPartnerForms(existing); 6897 return; 6898 } 6899 6900 const section = document.createElement("main"); 6901 section.className = "ed-partner-form-page"; 6902 section.dataset.edEmailUpdate = "partner-form"; 6903 section.setAttribute("aria-labelledby", "ed-partner-form-title"); 6904 section.innerHTML = ` 6905 <div class="ed-partner-form-shell"> 6906 <section class="ed-partner-form-intro"> 6907 <p class="ed-intl-kicker">Partner Interest</p> 6908 <h1 id="ed-partner-form-title">Become an International Partner</h1> 6909 <p>Tell The Lifeboat Project who you are, where you work, and what type of collaboration you would like to explore.</p> 6910 <p class="ed-partner-form-note">Submissions are delivered directly to <a href="mailto:${contactEmail}">${contactEmail}</a>.</p> 6911 </section> 6912 ${partnerFormHtml()} 6913 </div> 6914 `; 6915 6916 if (pageContent) { 6917 pageContent.insertBefore(section, sitePages || pageContent.firstChild); 6918 } else { 6919 insertBeforeFooter(section); 6920 } 6921 6922 installPartnerForms(section); 6923 } 6924 6925 function installInternationalPartnershipsPage() { 6926 if (path !== "/international-partnerships") return; 6927 6928 const pageContent = document.querySelector("#PAGES_CONTAINER"); 6929 const sitePages = pageContent?.querySelector(":scope > #SITE_PAGES"); 6930 const blankIntro = document.getElementById("comp-mmji18qe"); 6931 const nativeFormSection = document.getElementById("comp-mmjifiyt"); 6932 const existing = document.querySelector(".ed-international-page"); 6933 6934 if (blankIntro) hideElement(blankIntro); 6935 if (nativeFormSection) nativeFormSection.classList.add("ed-international-native-form"); 6936 document.body.classList.add("ed-international-route"); 6937 6938 if (existing) { 6939 if (pageContent && existing.parentNode !== pageContent) { 6940 pageContent.insertBefore(existing, sitePages || pageContent.firstChild); 6941 } 6942 return; 6943 } 6944 6945 const section = document.createElement("section"); 6946 section.className = "ed-international-page"; 6947 section.dataset.edEmailUpdate = "international-partnerships"; 6948 section.setAttribute("aria-labelledby", "ed-international-title"); 6949 section.innerHTML = ` 6950 <section class="ed-intl-hero"> 6951 <div class="ed-intl-shell ed-intl-hero-grid"> 6952 <div class="ed-intl-copy"> 6953 <p class="ed-intl-kicker">International Partnerships</p> 6954 <h1 id="ed-international-title">Building Global Partnerships Against Human Trafficking</h1> 6955 <p>The Lifeboat Project is committed to building meaningful international partnerships that strengthen prevention, expand education, support survivor-centered solutions, and advance practical collaboration across borders.</p> 6956 <p>We are seeking mission-aligned organizations, institutions, and partners from around the world who are ready to share knowledge, exchange best practices, and explore future joint initiatives.</p> 6957 <a class="ed-intl-button" href="#form">Become a Partner</a> 6958 </div> 6959 <figure class="ed-intl-hero-photo"> 6960 <img src="/assets/updates/international-partnerships/hero-un-partnership.webp" alt="Lifeboat Project representatives at the United Nations General Assembly" loading="eager">
6961 <figcaption>Connecting with international partners at the United Nations.</figcaption> 6962 </figure> 6963 </div> 6964 </section> 6965 6966 <section class="ed-intl-section"> 6967 <div class="ed-intl-shell ed-intl-split"> 6968 <div> 6969 <p class="ed-intl-kicker">The Global Reality</p> 6970 <h2>A crisis that demands international cooperation</h2> 6971 <p>Human trafficking is a global issue that affects vulnerable individuals across regions, industries, and communities. No one organization and no one country can solve it alone.</p> 6972 <p>Lasting progress requires cross-border communication, practical learning, and stronger partnerships between nonprofits, educators, public institutions, researchers, and mission-driven organizations.</p> 6973 </div> 6974 <div class="ed-intl-mini-cards" aria-label="International cooperation priorities"> 6975 <article> 6976 <span>01</span> 6977 <h3>Global Scale</h3> 6978 <p>Trafficking impacts people around the world and requires responses that are informed, connected, and adaptable.</p> 6979 </article> 6980 <article> 6981 <span>02</span> 6982 <h3>Shared Learning</h3> 6983 <p>Organizations grow stronger when they exchange ideas, compare models, and learn from different regions and sectors.</p> 6984 </article> 6985 </div> 6986 </div> 6987 <div class="ed-intl-shell ed-intl-photo-strip"> 6988 <img src="/assets/updates/international-partnerships/meeting-left.png" alt="International meeting room with delegates seated around a conference table" loading="lazy"> 6989 <img src="/assets/updates/international-partnerships/meeting-wide.png" alt="Wide view of an international roundtable discussion" loading="lazy"> 6990 <img src="/assets/updates/international-partnerships/speaker-room.png" alt="Lifeboat Project representative participating in an international meeting" loading="lazy"> 6991 </div> 6992 </section> 6993 6994 <section class="ed-intl-section ed-intl-soft"> 6995 <div class="ed-intl-shell ed-intl-split ed-intl-approach-row"> 6996 <div> 6997 <p class="ed-intl-kicker">Why International Collaboration Matters</p> 6998 <h2>Local experience. Global relevance.</h2> 6999 <p>The Lifeboat Project is based in Central Florida, one of the most internationally connected regions in the United States. With high tourism volume, constant mobility, and global movement through the region, trafficking-related risks are especially relevant.</p> 7000 <p>That reality gives our organization both a strong reason to engage internationally and meaningful experience to contribute. At the same time, we believe the strongest solutions come from collaboration, humility, and a willingness to learn from others doing this work around the world.</p> 7001 <p>This initiative is designed to build relationships that strengthen prevention, education, survivor-centered practice, and future joint efforts.</p> 7002 </div> 7003 <aside class="ed-intl-dark-card"> 7004 <p class="ed-intl-kicker">Our Approach</p> 7005 <h2>We want to contribute, learn, benchmark, and build.</h2> 7006 <p>Through international partnerships, The Lifeboat Project aims to exchange best practices, improve systems, deepen shared understanding, and explore future mission-aligned projects with organizations across the world.</p> 7007 </aside> 7008 </div> 7009 </section> 7010 7011 <section class="ed-intl-section"> 7012 <div class="ed-intl-shell"> 7013 <p class="ed-intl-kicker">Partnership Pillars</p> 7014 <h2>Where collaboration can begin</h2> 7015 <div class="ed-intl-pillar-grid"> 7016 <article><span>A</span><h3>Benchmarking</h3><p>Exchange best practices, compare models, and learn from each other's methods, referral structures, and program approaches.</p></article> 7017 <article><span>B</span><h3>Prevention</h3><p>Strengthen prevention efforts through awareness campaigns, public education, and practical risk-reduction strategies.</p></article> 7018 <article><span>C</span><h3>Education</h3><p>Collaborate on training, resource development, webinars, workshops, and educational partnerships.</p></article> 7019 <article><span>D</span><h3>Joint International Projects</h3><p>Explore research collaboration, pilot programs, grants, and other future cross-border initiatives.</p></article> 7020 </div> 7021 </div> 7022 </section> 7023 7024 <section class="ed-intl-section ed-intl-soft"> 7025 <div class="ed-intl-shell"> 7026 <p class="ed-intl-kicker">What Collaboration Can Look Like</p> 7027 <h2>Practical ways to work together</h2> 7028 <div class="ed-intl-check-list" aria-label="Practical collaboration opportunities"> 7029 <p>
7029Knowledge exchange calls and strategic introductions</p> 7030 <p>Joint webinars, panels, and awareness campaigns</p> 7031 <p>Training partnerships and survivor-centered service model exchange</p> 7032 <p>School, university, and youth engagement collaborations</p> 7033 <p>Research collaboration, data sharing, and benchmarking</p> 7034 <p>Conference participation, speaking opportunities, and international networking</p> 7035 <p>Corporate awareness partnerships and tourism and hospitality training</p> 7036 <p>Joint grant exploration and future cross-border initiatives</p> 7037 </div> 7038 </div> 7039 </section> 7040 7041 <section class="ed-intl-section"> 7042 <div class="ed-intl-shell"> 7043 <p class="ed-intl-kicker">Who We Hope To Connect With</p> 7044 <h2>Mission-aligned partners worldwide</h2> 7045 <div class="ed-intl-partner-grid"> 7046 <article><h3>Nonprofits</h3><p>Organizations working in anti-trafficking, survivor support, prevention, child protection, community education, or victim services.</p></article> 7047 <article><h3>Universities & Schools</h3><p>Institutions interested in educational partnerships, research, applied learning, and training collaboration.</p></article> 7048 <article><h3>Public Institutions</h3><p>Municipalities, agencies, policy groups, and international bodies exploring dialogue, prevention, or pilot initiatives.</p></article> 7049 <article><h3>Private Sector Partners</h3><p>Mission-driven companies, tourism leaders, hospitality organizations, and responsible corporate partners seeking to raise awareness and strengthen training.</p></article> 7050 </div> 7051 <div class="ed-intl-photo-strip ed-intl-photo-strip-small"> 7052 <img src="/assets/updates/international-partnerships/speaker-room.png" alt="International meeting presentation on human trafficking prevention" loading="lazy"> 7053 <img src="/assets/updates/international-partnerships/flags-pin.png" alt="United Nations pin with United States and Hungary flag pins" loading="lazy"> 7054 <img src="/assets/updates/international-partnerships/hero-un-partnership.webp" alt="Lifeboat Project representatives with international partners" loading="lazy"> 7055 </div> 7056 </div> 7057 </section> 7058 7059 <section class="ed-intl-section ed-intl-interest-section"> 7060 <div class="ed-intl-shell ed-intl-interest-grid"> 7061 <div class="ed-intl-interest-card"> 7062 <p class="ed-intl-kicker">Partner Interest</p> 7063 <h2>Start the conversation</h2> 7064 <p>We welcome opportunities to connect with organizations, institutions, and mission-aligned partners who are interested in meaningful collaboration to strengthen the global response to human trafficking.</p> 7065 <p>Whether your interest is in prevention, education, benchmarking, research, awareness, or future international initiatives, we would be honored to explore what partnership could look like together.</p> 7066 <div class="ed-intl-tags" aria-label="Partnership interest areas"> 7067 <span>Benchmarking</span><span>Prevention Campaigns</span><span>Education & Training</span><span>Research & Data Sharing</span><span>Victim-Centered Models</span><span>Cross-Border Referral Pathways</span><span>Policy Dialogue & Advocacy</span><span>Joint Grant Projects</span><span>Corporate Awareness</span><span>Tourism Sector Training</span><span>Youth & School Engagement</span><span>Speaking & Conferences</span> 7068 </div> 7069 </div> 7070 <aside class="ed-intl-dark-card ed-intl-connect-card"> 7071 <p class="ed-intl-kicker">Become A Partner</p> 7072 <h2>Ready to connect with The Lifeboat Project?</h2> 7073 <p>Use the partnership form to share more about your organization, your focus, and the areas where you would like to explore collaboration.</p> 7074 <a class="ed-intl-button ed-intl-button-light" href="#form">Complete the Form</a> 7075 </aside> 7076 </div> 7077 </section> 7078 7079 <section class="ed-intl-final-cta"> 7080 <div class="ed-intl-shell"> 7081 <p class="ed-intl-kicker">Become A Partner</p> 7082 <h2>Let's build a stronger international response together.</h2> 7083 <p>We believe meaningful change is built through partnership, shared knowledge, and practical action. If your organization is ready to explore collaboration, we would love to hear from you.</p> 7084 <a class="ed-intl-button ed-intl-button-light" href="#form">Become a Partner</a> 7085 </div> 7086 </section> 7087 `; 7088 7089 if (pageContent) { 7090 pageContent.insertBefore(section, sitePages || pageContent.firstChild); 7091 return; 7092 } 7093 7094 insertBeforeFooter(section); 7095 } 7096 7097 function installSponsorsMirrorPage() { 7098 if (path !== "/sponsors") return; 7099 if (document.querySelector(".sponsors-shell")) { 7100 document.querySelectorAll(".ed-sponsors-page").forEach((section) => section.remove()); 7101 return; 7102 } 7103 7104 installMirrorPage( 7105 "/sponsors", 7106 "ed-sponsors-page", 7107 ` 7108 <div class="ed-sponsors-shell"> 7109 <section class="ed-sponsors-intro" aria-labelledby="ed-sponsors-title"> 7110 <h1 id="ed-sponsors-title">Our Sponsors</h1> 7111 <p>We are deeply grateful for the partners and sponsors who stand with The Lifeboat Project. Their generosity makes it possible to provide safe housing, long-term care, and meaningful support for survivors of human trafficking. Through their commitment, lives are changed, healing is made possible, and hope continues to grow.</p> 7112 </section> 7113 <div class="ed-sponsors-logo-grid" aria-label="Sponsor logos"> 7114 <article><a href="https://orlandonissan.com" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/orlando-nissan.png" alt="Sutherlin Nissan Orlando"></a></article> 7115 <article><a href="https://www.iheartmedia.com/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/iheartmedia.png" alt="iHeartMedia"></a></article> 7116 <article><a href="https://www.delta.com/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/delta-air-lines.png" alt="Delta Air Lines"></a></article> 7117 <article><a href="https://www.adventhealth.com/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/adventhealth.png" alt="AdventHealth"></a></article> 7118 <article><a href="https://clearchanneloutdoor.com/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/clear-channel-outdoor.png" alt="Clear Channel Outdoor"></a></article> 7119 <article><a href="https://www.audinorthorlando.com/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/audi-north-orlando.jpeg" alt="Audi North Orlando"></a></article> 7120 <article><a href="https://www.parkjewelers.com/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/park-jewelers.png" alt="Park Jewelers"></a></article> 7121 <article><a href="https://www.dominos.com/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/team-snow-domino-s.jpeg" alt="Team Snow Domino's"></a></article> 7122 <article>
7122<a href="https://www.parksquarehomes.com/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/park-square-homes.png" alt="Park Square Homes"></a></article> 7123 <article><a href="https://www.seminolecountyfl.gov/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/seminole-county-florida-s-natural-choice.png" alt="Seminole County"></a></article> 7124 <article><a href="https://www.homeaidorlando.org/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/homeaid-orlando.png" alt="HomeAid Orlando"></a></article> 7125 <article><a href="https://www.53.com/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/fifth-third-bank.jpg" alt="Fifth Third Bank"></a></article> 7126 <article><a href="https://www.orlando.gov/Home" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/city-of-orlando.png" alt="City of Orlando"></a></article> 7127 <article><a href="https://www.seminolesheriff.org/foundation/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/seminole-county-sheriff-s-office-foundation.jpg" alt="Seminole County Sheriff's Office Foundation"></a></article> 7128 <article><a href="https://www.fabulousbuses.com/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/fabulous-buses.png" alt="Fabulous Buses"></a></article> 7129 <article><a href="https://greaterorlandosports.com/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/greater-orlando-sports-commission.png" alt="Greater Orlando Sports Commission"></a></article> 7130 <article>
7130<a href="https://www.keyperformancehospitality.com/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/key-performance-hospitality-management.png" alt="Key Performance Hospitality Management"></a></article> 7131 <article><a href="https://www.jdatransport.com/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/jda.png" alt="JDA"></a></article> 7132 <article><a href="https://disneyspringshotels.com/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/disney-springs-resort-area-hotels.png" alt="Disney Springs Resort Area Hotels"></a></article> 7133 <article><a href="https://www.firsthorizon.com/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/first-horizon.jpg" alt="First Horizon"></a></article> 7134 <article><a href="https://www.raymondjames.com/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/griffis-wealth-strategies.png" alt="Griffis Wealth Strategies"></a></article> 7135 <article><a href="https://drphillips.org/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/dr-phillips-charities.jpeg" alt="Dr. Phillips Charities"></a></article> 7136 <article><a href="https://www.cfhla.org/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/central-florida-hotel-and-lodging-association.jpg" alt="Central Florida Hotel and Lodging Association"></a></article> 7137 <article class="ed-sponsor-visit-orlando"><a href="https://www.visitorlando.com/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/visit-orlando.svg" alt="Visit Orlando"></a></article> 7138 <article class="ed-sponsor-st-margaret"><a href="https://stmargaretmary.org/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/st-margaret-mary-catholic-church.png" alt="St. Margaret Mary Catholic Church"></a></article> 7139 <article class="ed-sponsor-gatorland"><a href="https://www.gatorland.com/" target="_blank" rel="noopener noreferrer"><img src="/assets/sponsor-logos/gatorland.png" alt="Gatorland"></a></article> 7140 </div> 7141 </div> 7142 `, 7143 ); 7144 } 7145 7146 function installLifeboatLifesaversPage() { 7147 if (path !== "/lifeboat-lifesavers") return; 7148 7149 installMirrorPage( 7150 "/lifeboat-lifesavers", 7151 "ed-lifesavers-page", 7152 ` 7153 <section class="ed-lifesavers-hero" aria-labelledby="ed-lifesavers-title"> 7154 <div class="ed-lifesavers-shell ed-lifesavers-hero-grid"> 7155 <div> 7156 <h1 id="ed-lifesavers-title">Lifeboat<br>Lifesavers</h1> 7157 <p class="ed-lifesavers-tagline">Courage in Action</p> 7158 </div> 7159 <div class="ed-lifesavers-hero-copy"> 7160 <p>Human trafficking thrives in silence, but freedom spreads with compassion and commitment.</p> 7161 <p>Lifeboat Lifesavers aren’t just donors; <strong>they are lifelines</strong>. They are the people who choose action over apathy, hope over helplessness, and community over isolation. By joining this group of faithful supporters, Lifesavers fuel the mission that changes the course of lives.</p> 7162 <span aria-hidden="true"></span> 7163 </div> 7164 </div> 7165 </section> 7166 <section class="ed-lifesavers-board-section" aria-labelledby="ed-lifesavers-board-title"> 7167 <div class="ed-lifesavers-shell"> 7168 <h2 id="ed-lifesavers-board-title">Advisory Board</h2> 7169 <span class="ed-lifesavers-board-divider" aria-hidden="true"></span> 7170 <div class="ed-lifesavers-grid"> 7171 ${lifeboatLifesaversProfiles 7172 .map( 7173 (profile, index) => ` 7174 <article class="ed-lifesavers-card"> 7175 <div class="ed-lifesavers-card-photo"> 7176 <img src="${escapeMarkup(profile.image)}" alt="${escapeMarkup(profile.alt)}" loading="${index < 3 ? "eager" : "lazy"}" decoding="async"> 7177 </div> 7178 <div class="ed-lifesavers-card-copy"> 7179 <p>${escapeMarkup(profile.role)}</p> 7180 <h3>${escapeMarkup(profile.name)}</h3> 7181 </div> 7182 </article> 7183 `, 7184 ) 7185 .join("")} 7186 </div> 7187 </div> 7188 </section> 7189 `, 7190 ); 7191 } 7192 7193 function installAdvisoryBoardPage() { 7194 if (path !== "/copy-of-meet-the-team-1") return; 7195 7196 document.body?.classList.add("ed-advisory-board-view"); 7197 document.documentElement?.classList.add("ed-advisory-board-view-root"); 7198 installAdvisoryChatSuppression(); 7199 7200 const pageContent = document.querySelector("#PAGES_CONTAINER");
7201 const sitePages = pageContent?.querySelector(":scope > #SITE_PAGES"); 7202 const existing = document.querySelector(".ed-advisory-board-page"); 7203 7204 if (sitePages) { 7205 sitePages.classList.add("ed-hidden"); 7206 sitePages.setAttribute("aria-hidden", "true"); 7207 } 7208 7209 if (existing) { 7210 if (pageContent && existing.parentNode !== pageContent) { 7211 pageContent.insertBefore(existing, sitePages || pageContent.firstChild); 7212 } 7213 return; 7214 } 7215 7216 const section = document.createElement("section"); 7217 section.className = "ed-advisory-board-page ed-lifesavers-page"; 7218 section.dataset.edEmailUpdate = "ed-advisory-board-page"; 7219 section.setAttribute("aria-labelledby", "ed-advisory-members-title"); 7220 section.innerHTML = ` 7221 <section class="ed-lifesavers-board-section" aria-labelledby="ed-advisory-members-title"> 7222 <div class="ed-lifesavers-shell"> 7223 <div class="ed-advisory-section-heading"> 7224 <p class="ed-advisory-kicker">Members</p> 7225 <h1 id="ed-advisory-members-title">Advisory Board Members</h1> 7226 <p>Meet the people lending their experience, relationships, and stewardship to the organization.</p> 7227 </div> 7228 <span class="ed-lifesavers-board-divider" aria-hidden="true"></span> 7229 <div class="ed-lifesavers-grid" aria-label="Advisory Board profiles"> 7230 ${advisoryBoardProfiles.map((profile, index) => advisoryBoardCardHtml(profile, index)).join("")} 7231 </div> 7232 </div> 7233 </section> 7234 `; 7235 7236 if (pageContent) { 7237 pageContent.insertBefore(section, sitePages || pageContent.firstChild); 7238 return; 7239 } 7240 7241 insertBeforeFooter(section); 7242 } 7243 7244 function installDonorDockMirrorPage() { 7245 if (path !== "/copy-of-lifeboat-lifesavers") return; 7246 if (document.querySelector(".donor-dock")) return; 7247 7248 installMirrorPage( 7249 "/copy-of-lifeboat-lifesavers", 7250 "ed-donor-page", 7251 ` 7252 <section class="ed-donor-hero" aria-labelledby="ed-donor-title"> 7253 <h1 id="ed-donor-title">The Donor Dock: Join the Movement to End Human Trafficking</h1> 7254 <p>Your generosity plays a crucial role in empowering survivors and fighting human trafficking. At The Lifeboat Project, we rely on the support of individuals, organizations, and partners who are committed to making a real difference. Explore our giving tiers and see the powerful impact your donation will have on the lives of those we serve.</p> 7255 <a class="ed-donor-button" href="https://thelifeboatproject.networkforgood.com/projects/120280-donate-to-the-lifeboat-project" target="_blank" rel="noopener noreferrer">Become a Lifesaver Today</a> 7256 </section> 7257 <section class="ed-donor-tiers" aria-label="Donor Dock giving tiers"> 7258 <article> 7259 <h2>Bronze</h2> 7260 <p class="ed-donor-amount">$2,500 — $4,999</p> 7261 <ul> 7262 <li>Featured in our newsletter</li> 7263 <li>Recognition on our website</li> 7264 <li>Spotlight on social media channels</li> 7265 <li>Recognition at events</li> 7266 </ul> 7267 </article> 7268 <article> 7269 <h2>Silver</h2> 7270 <p class="ed-donor-amount">$5,000 — $7,499</p> 7271 <ul> 7272 <li>All Bronze benefits</li> 7273 <li>Exclusive guest speaker feature</li> 7274 <li>Special recognition at major events</li> 7275 <li>1 annual feature article in our newsletter</li> 7276 </ul> 7277 </article> 7278 <article> 7279 <h2>Gold</h2> 7280 <p class="ed-donor-amount"><span>$7,500 —</span><span>$14,999</span></p> 7281 <ul> 7282 <li>All Silver benefits</li> 7283 <li>Special recognition at 2 events</li> 7284 <li>Enhanced marketing exposure</li> 7285 <li>2 bi-annual articles in our newsletter</li> 7286 </ul> 7287 </article> 7288 <article> 7289 <h2>Platinum</h2> 7290 <p class="ed-donor-amount">$15,000+</p> 7291 <ul> 7292 <li>All Gold benefits</li> 7293 <li>Guest speaker at multiple events</li> 7294 <li>
7294Priority marketing and sponsorship opportunities</li> 7295 <li>4 quarterly newsletter features</li> 7296 </ul> 7297 </article> 7298 </section> 7299 `, 7300 ); 7301 } 7302 7303 function installEventUpdates() { 7304 if (path !== "/events") return; 7305 installMirrorPage( 7306 "/events", 7307 "ed-events-page", 7308 ` 7309 <section class="ed-events-directory-hero ed-events-simple-hero" aria-labelledby="ed-events-title"> 7310 <div class="ed-events-hero-copy"> 7311 <p class="ed-events-eyebrow">Events</p> 7312 <h1 id="ed-events-title">Upcoming Events</h1> 7313 <p>Find the next Lifeboat fundraiser, volunteer day, or awareness event in one clear place.</p> 7314 </div> 7315 </section> 7316 7317 <section class="ed-events-featured-directory ed-events-featured-showcase" id="featured-yacht-rock" aria-labelledby="ed-events-feature-title"> 7318 <a class="ed-events-featured-media yacht-rock-flyer" href="${yachtRockEventPath}" aria-label="View Yacht Rock Benefit Bash event details"> 7319 <img src="${yachtRockFlyerImage}" alt="6th Annual Yacht Rock Benefit Bash flyer" width="1536" height="864" loading="eager" decoding="async" fetchpriority="high"> 7320 </a> 7321 <div class="ed-events-featured-copy"> 7322 <div class="ed-events-featured-intro"> 7323 <p class="ed-events-eyebrow">Featured Event</p> 7324 <h2 id="ed-events-feature-title">6th Annual Yacht Rock Benefit Bash</h2> 7325 <p>Join us for dinner, music, and an evening supporting survivors of human trafficking.</p> 7326 </div> 7327 <div class="ed-events-featured-plan"> 7328 <dl class="ed-events-meta-grid"> 7329 <div> 7330 <dt>Date</dt> 7331 <dd>October 17, 2026</dd> 7332 </div> 7333 <div> 7334 <dt>Location</dt> 7335 <dd>Hilton Orlando Lake Buena Vista</dd> 7336 </div> 7337 <div> 7338 <dt>Time</dt> 7339 <dd>5:30–9:30 PM Eastern</dd> 7340 </div> 7341 </dl> 7342 <div class="ed-events-actions"> 7343 <a class="ed-event-cta primary" href="${yachtRockEventPath}">View Event Details</a> 7344 <a class="ed-event-cta secondary" href="https://calendar.google.com/calendar/render?action=TEMPLATE&text=6th%20Annual%20Yacht%20Rock%20Benefit%20Bash&dates=20261017T213000Z/20261018T013000Z&ctz=America%2FNew_York&details=Benefit%20bash%20supporting%20survivors%20of%20human%20trafficking%20%E2%80%94%20https%3A%2F%2Flifeboatproject.org%2Fyacht-rock-benefit-bash&location=Hilton%20Orlando%20Lake%20Buena%20Vista%2C%201751%20Hotel%20Plaza%20Blvd%2C%20Lake%20Buena%20Vista%2C%20FL%2032830" target="_blank" rel="noopener noreferrer">Add to Calendar</a> 7345 </div> 7346 </div> 7347 </div> 7348 </section> 7349 7350 <section class="ed-events-directory-section" aria-labelledby="ed-events-upcoming-title"> 7351 <div class="ed-events-section-heading"> 7352 <p class="ed-events-eyebrow">More Ways to Get Involved</p> 7353 <h2 id="ed-events-upcoming-title">A quick look at what is next.</h2> 7354 </div> 7355 <div class="ed-events-upcoming-grid"> 7356 <article class="ed-event-directory-card ed-event-summary-card coming-soon" data-event-category="fundraiser community"> 7357 <p class="ed-event-date">Fall 2026</p> 7358 <div class="ed-event-card-content"> 7359 <span class="ed-event-summary-status">Coming Soon</span> 7360 <h3>Fall Poker Tournament</h3> 7361 <p>Details are coming soon for a lively fundraising night with sponsorship, volunteer, and guest opportunities.</p> 7362 </div> 7363 <div class="ed-events-card-actions"> 7364 <a class="ed-event-cta quiet" href="/contact/">Notify Me</a> 7365 </div> 7366 </article> 7367 7368 <article class="ed-event-directory-card ed-event-summary-card" data-event-category="volunteer community"> 7369 <p class="ed-event-date">Winter 2026</p> 7370 <div class="ed-event-card-content">
7371 <span class="ed-event-summary-status">Volunteers Needed</span> 7372 <h3>Community Volunteer Day</h3> 7373 <p>Help with outreach, event preparation, guest support, and awareness efforts across Central Florida.</p> 7374 </div> 7375 <div class="ed-events-card-actions"> 7376 <a class="ed-event-cta quiet" href="/volunteer">Volunteer</a> 7377 </div> 7378 </article> 7379 7380 <article class="ed-event-directory-card ed-event-summary-card" data-event-category="education corporate"> 7381 <p class="ed-event-date">TBD</p> 7382 <div class="ed-event-card-content"> 7383 <span class="ed-event-summary-status">Educational</span> 7384 <h3>Lunch & Learn Sessions</h3> 7385 <p>Bring Lifeboat's prevention education to a workplace, civic group, school, or community organization.</p> 7386 </div> 7387 <div class="ed-events-card-actions"> 7388 <a class="ed-event-cta quiet" href="/request-a-speaker/">Request a Speaker</a> 7389 </div> 7390 </article> 7391 7392 <article class="ed-event-directory-card ed-event-summary-card" data-event-category="community corporate"> 7393 <p class="ed-event-date">TBD</p> 7394 <div class="ed-event-card-content"> 7395 <span class="ed-event-summary-status">Community</span> 7396 <h3>Community Partner Pop-Up</h3> 7397 <p>Invite Lifeboat into your venue or workplace for a focused awareness moment, resource table, or partner gathering.</p> 7398 </div> 7399 <div class="ed-events-card-actions"> 7400 <a class="ed-event-cta quiet" href="/contact/">Start a Conversation</a> 7401 </div> 7402 </article> 7403 </div> 7404 </section> 7405 7406 <section class="ed-events-host-cta ed-events-simple-contact" aria-labelledby="ed-events-host-title"> 7407 <div> 7408 <p class="ed-events-eyebrow">Questions?</p> 7409 <h2 id="ed-events-host-title">Looking for sponsorship, volunteer, or event details?</h2> 7410 </div> 7411 <a class="ed-event-cta light" href="/contact/">Start a Conversation</a> 7412 </section> 7413 `, 7414 ); 7415 7416 const section = document.querySelector(".ed-events-page"); 7417 if (!section) return; 7418 7419 const bindEventFilters = () => { 7420 const buttons = [...section.querySelectorAll(".ed-events-filter")]; 7421 const cards = [...section.querySelectorAll("[data-event-category]")]; 7422 if (!buttons.length || !cards.length || section.dataset.edEventsFiltersBound) return; 7423 7424 section.dataset.edEventsFiltersBound = "true"; 7425 buttons.forEach((button) => { 7426 button.addEventListener("click", () => { 7427 const filter = button.dataset.filter || "all"; 7428 buttons.forEach((item) => item.setAttribute("aria-pressed", String(item === button))); 7429 cards.forEach((card) => { 7430 const categories = (card.dataset.eventCategory || "").split(/\s+/); 7431 card.classList.toggle("ed-event-card-hidden", filter !== "all" && !categories.includes(filter)); 7432 }); 7433 }); 7434 }); 7435 }; 7436 7437 const fitEventsPage = () => { 7438 const visualWidth = Math.min( 7439 document.documentElement.clientWidth || window.innerWidth, 7440 window.visualViewport?.width || window.innerWidth, 7441 ); 7442 7443 if (visualWidth <= 700) { 7444 section.classList.add("ed-events-mobile-fit"); 7445 section.style.width = `${Math.max(visualWidth, 320)}px`; 7446 section.style.maxWidth = `${Math.max(visualWidth, 320)}px`; 7447 return; 7448 } 7449 7450 section.classList.remove("ed-events-mobile-fit"); 7451 section.style.removeProperty("width"); 7452 section.style.removeProperty("max-width"); 7453 }; 7454 7455 bindEventFilters(); 7456 fitEventsPage(); 7457 if (!section.dataset.edEventsFitBound) { 7458 section.dataset.edEventsFitBound = "true"; 7459 window.visualViewport?.addEventListener("resize", fitEventsPage); 7460 window.addEventListener("resize", fitEventsPage); 7461 } 7462 } 7463 7464 function updateSubscribeMessage() { 7465 const validEmail = (email) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); 7466 7467 const findSubscribeEmail = (form) => 7468 [...form.querySelectorAll("input[type='email'], input")].find((input) => { 7469 const label = clean(input.getAttribute("aria-label") || input.getAttribute("placeholder")); 7470 const name = clean(input.getAttribute("name")); 7471 return input.type === "email" || /email/i.test(label) || /email/i.test(name); 7472 }); 7473 7474 const findSubscribeButton = (form) => 7475 [...form.querySelectorAll("button, input[type='submit'], [role='button']")].find((button) => 7476 /join our mailing list|subscribe|sign up/i.test(clean(button.innerText || button.textContent || button.value)), 7477 ); 7478 7479 const getSubscribeStatus = (form) => { 7480 let status = form.querySelector(".ed-subscribe-status"); 7481 if (!status) { 7482 status = document.createElement("div"); 7483 status.className = "ed-subscribe-status"; 7484 status.setAttribute("role", "status"); 7485 status.setAttribute("aria-live", "polite"); 7486 form.appendChild(status); 7487 } 7488 return status; 7489 }; 7490 7491 const setSubscribeStatus = (form, message, state = "info") => { 7492 const status = getSubscribeStatus(form); 7493 status.dataset.state = state; 7494 status.textContent = message; 7495 }; 7496 7497 const submitSubscribeForm = async (form) => { 7498 const emailField = findSubscribeEmail(form); 7499 const email = clean(emailField?.value); 7500 const checkbox = [...form.querySelectorAll("input[type='checkbox']")].find((input) => { 7501 const label = clean(input.closest("label")?.innerText || input.parentElement?.innerText); 7502 return /subscribe|mailing list/i.test(label); 7503 }); 7504 7505 if (!validEmail(email)) { 7506 setSubscribeStatus(form, "Please enter a valid email address.", "error"); 7507 emailField?.focus(); 7508 return; 7509 } 7510 7511 if (checkbox && !checkbox.checked) { 7512 setSubscribeStatus(form, "Please confirm the mailing list checkbox.", "error"); 7513 checkbox.focus(); 7514 return; 7515 } 7516 7517 const button = findSubscribeButton(form); 7518 const originalText = clean(button?.innerText || button?.textContent || button?.value) || "Join Our Mailing List"; 7519 if (button) { 7520 button.setAttribute("aria-disabled", "true"); 7521 button.disabled = true; 7522 if ("value" in button && button.tagName === "INPUT") { 7523 button.value = "Joining..."; 7524 } else { 7525 button.textContent = "Joining..."; 7526 } 7527 } 7528 setSubscribeStatus(form, "Joining the mailing list..."); 7529
7530 try { 7531 const response = await fetch("/api/subscribe", { 7532 method: "POST", 7533 headers: { "content-type": "application/json" }, 7534 body: JSON.stringify({ email, company: "" }), 7535 }); 7536 const result = await response.json().catch(() => ({})); 7537 if (!response.ok) { 7538 setSubscribeStatus(form, result.error || "Unable to subscribe right now. Please try again later.", "error"); 7539 return; 7540 } 7541 7542 if (result.ok && result.saved) window.lifeboatAnalytics?.track('subscription_saved'); 7543 setSubscribeStatus( 7544 form, 7545 result.message || "Thank you for signing up. Please check your email for our welcome message.", 7546 "success", 7547 ); 7548 emailField.value = ""; 7549 if (checkbox) checkbox.checked = false; 7550 } catch { 7551 setSubscribeStatus(form, "Unable to subscribe right now. Please try again later.", "error"); 7552 } finally { 7553 if (button) { 7554 button.removeAttribute("aria-disabled"); 7555 button.disabled = false; 7556 if ("value" in button && button.tagName === "INPUT") { 7557 button.value = originalText; 7558 } else { 7559 button.textContent = originalText; 7560 } 7561 } 7562 } 7563 }; 7564 7565 document.querySelectorAll("form").forEach((form) => { 7566 if (form.dataset.edSubscribeBound) return; 7567 if (!/subscribe|mailing list|newsletter/i.test(clean(form.innerText))) return; 7568 if (!findSubscribeEmail(form)) return; 7569 form.dataset.edSubscribeBound = "true"; 7570 form.setAttribute("action", "/api/subscribe"); 7571 form.setAttribute("method", "post"); 7572 7573 form.addEventListener( 7574 "submit", 7575 (event) => { 7576 event.preventDefault(); 7577 event.stopImmediatePropagation(); 7578 submitSubscribeForm(form); 7579 }, 7580 true, 7581 ); 7582 7583 findSubscribeButton(form)?.addEventListener( 7584 "click", 7585 (event) => { 7586 event.preventDefault(); 7587 event.stopImmediatePropagation(); 7588 submitSubscribeForm(form); 7589 }, 7590 true, 7591 ); 7592 }); 7593 } 7594 7595 function correctNewsletterCopy() { 7596 if (!document.body) return; 7597 7598 const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT); 7599 const textNodes = []; 7600 7601 while (walker.nextNode()) { 7602 const node = walker.currentNode; 7603 const parent = node.parentElement; 7604 if (!parent || parent.closest("script, style")) continue; 7605 if (node.nodeValue.includes("recieve")) textNodes.push(node); 7606 } 7607 7608 textNodes.forEach((node) => { 7609 node.nodeValue = node.nodeValue.replace(/\brecieve\b/g, "receive"); 7610 }); 7611 } 7612 7613 function currentHomeVideo() { 7614 return storyVideoLibrary[homeVideoIndex] || storyVideoLibrary[0]; 7615 } 7616 7617 function titleFromPlayButton(button) { 7618 const label = clean(button?.getAttribute("aria-label")); 7619 return label.replace(/^Play video:\s*/i, "") || currentHomeVideo()?.title; 7620 } 7621 7622 function closeVideoModal() { 7623 if (!activeVideoModal) return; 7624 7625 const modal = activeVideoModal; 7626 activeVideoModal = null; 7627 const video = modal.querySelector("video"); 7628 if (video) { 7629 video.pause(); 7630 video.removeAttribute("src"); 7631 video.load(); 7632 } 7633 modal.remove(); 7634 } 7635 7636 function setModalVideo(modal, selectedVideo) { 7637 const title = modal.querySelector(".ed-video-title"); 7638 const video = modal.querySelector("video"); 7639 if (!title || !video || !selectedVideo) return; 7640 7641 title.textContent = selectedVideo.title; 7642 video.src = selectedVideo.src; 7643 video.setAttribute("title", selectedVideo.title); 7644 video.setAttribute("aria-label", selectedVideo.title); 7645 modal.querySelectorAll(".ed-video-list-button").forEach((button) => { 7646 button.classList.toggle("is-active", button.dataset.videoTitle === selectedVideo.title); 7647 }); 7648 video.play().catch(() => {}); 7649 } 7650 7651 function openVideoModal(selectedTitle = currentHomeVideo()?.title) { 7652 const selectedVideo = 7653 storyVideoLibrary.find((video) => video.title === selectedTitle) || currentHomeVideo(); 7654 if (!selectedVideo) return; 7655 7656 closeVideoModal(); 7657 7658 const modal = document.createElement("div"); 7659 modal.className = "ed-video-modal"; 7660 modal.innerHTML = ` 7661 <div class="ed-video-dialog" role="dialog" aria-modal="true" aria-labelledby="ed-video-title"> 7662 <button class="ed-video-close" type="button" aria-label="Close video">x</button> 7663 <div class="ed-video-player"> 7664 <h2 id="ed-video-title" class="ed-video-title"></h2> 7665 <video controls autoplay playsinline preload="metadata"></video> 7666 </div> 7667 <div class="ed-video-list" aria-label="All videos"></div> 7668 </div> 7669 `; 7670 7671 const list = modal.querySelector(".ed-video-list");
7672 storyVideoLibrary.forEach((video) => { 7673 const button = document.createElement("button"); 7674 button.className = "ed-video-list-button"; 7675 button.type = "button"; 7676 button.dataset.videoTitle = video.title; 7677 button.innerHTML = 7678 '<img alt="" loading="lazy">' + 7679 '<span></span>'; 7680 button.querySelector("img").src = video.image; 7681 button.querySelector("span").textContent = video.title; 7682 button.addEventListener("click", () => { 7683 homeVideoIndex = storyVideoLibrary.findIndex((entry) => entry.title === video.title); 7684 updateHomepageVideoPreview(video, true); 7685 setModalVideo(modal, video); 7686 }); 7687 list.appendChild(button); 7688 }); 7689 7690 modal.querySelector(".ed-video-close").addEventListener("click", closeVideoModal); 7691 modal.addEventListener("click", (event) => { 7692 if (event.target === modal) closeVideoModal(); 7693 }); 7694 document.addEventListener( 7695 "keydown", 7696 (event) => { 7697 if (event.key === "Escape") closeVideoModal(); 7698 }, 7699 { once: true }, 7700 ); 7701 7702 document.body.appendChild(modal); 7703 activeVideoModal = modal; 7704 setModalVideo(modal, selectedVideo); 7705 } 7706 7707 function exposeHomepageVideoControls() { 7708 window.LifeboatHomeVideo = { 7709 ...(window.LifeboatHomeVideo || {}), 7710 open: (title) => openVideoModal(title || currentHomeVideo()?.title), 7711 currentTitle: () => currentHomeVideo()?.title || "", 7712 }; 7713 } 7714 7715 function homeMissionVideo() { 7716 return storyVideoLibrary.find((video) => video.title === "Our Impact") || currentHomeVideo(); 7717 } 7718 7719 function openHomeMissionVideoFromTrigger(trigger) { 7720 const fallbackVideo = homeMissionVideo(); 7721 if (!fallbackVideo) return; 7722 7723 const title = trigger?.getAttribute("data-video-title") || fallbackVideo.title; 7724 const index = storyVideoLibrary.findIndex((video) => video.title === title); 7725 if (index >= 0) homeVideoIndex = index; 7726 openVideoModal(title); 7727 } 7728 7729 function bindHomeMissionVideoTriggers(root = document) { 7730 root.querySelectorAll("[data-ed-home-mission-play], [data-ed-home-mission-all]").forEach((trigger) => { 7731 if (trigger.dataset.edHomeMissionTriggerBound === "true") return; 7732 trigger.dataset.edHomeMissionTriggerBound = "true"; 7733 trigger.addEventListener( 7734 "click", 7735 (event) => { 7736 event.preventDefault(); 7737 event.stopPropagation(); 7738 event.stopImmediatePropagation?.(); 7739 openHomeMissionVideoFromTrigger(trigger); 7740 }, 7741 true, 7742 ); 7743 }); 7744 } 7745 7746 function openDirectVideoModal(title, src) { 7747 if (!src) return; 7748 7749 closeVideoModal(); 7750 7751 const modal = document.createElement("div"); 7752 modal.className = "ed-video-modal"; 7753 modal.innerHTML = ` 7754 <div class="ed-video-dialog" role="dialog" aria-modal="true" aria-labelledby="ed-video-title"> 7755 <button class="ed-video-close" type="button" aria-label="Close video">x</button> 7756 <div class="ed-video-player"> 7757 <h2 id="ed-video-title" class="ed-video-title"></h2> 7758 <video controls autoplay playsinline preload="metadata"></video> 7759 </div> 7760 </div> 7761 `; 7762 7763 const videoTitle = title || "Spot It. Stop It"; 7764 const heading = modal.querySelector(".ed-video-title"); 7765 const video = modal.querySelector("video"); 7766 if (heading) heading.textContent = videoTitle; 7767 if (video) { 7768 video.src = src; 7769 video.setAttribute("title", videoTitle); 7770 video.setAttribute("aria-label", videoTitle); 7771 } 7772 7773 modal.querySelector(".ed-video-close")?.addEventListener("click", closeVideoModal); 7774 modal.addEventListener("click", (event) => { 7775 if (event.target === modal) closeVideoModal(); 7776 }); 7777 document.addEventListener( 7778 "keydown", 7779 (event) => { 7780 if (event.key === "Escape") closeVideoModal(); 7781 }, 7782 { once: true }, 7783 ); 7784 7785 document.body.appendChild(modal); 7786 activeVideoModal = modal; 7787 video?.play().catch(() => {}); 7788 } 7789 7790 function bindSpotItStopItVideoTriggers(root = document) { 7791 root.querySelectorAll("[data-ed-spot-video-src]").forEach((trigger) => { 7792 if (trigger.dataset.edSpotVideoBound === "true") return; 7793 trigger.dataset.edSpotVideoBound = "true"; 7794 trigger.addEventListener( 7795 "click", 7796 (event) => { 7797 event.preventDefault(); 7798 event.stopPropagation(); 7799 event.stopImmediatePropagation?.(); 7800 openDirectVideoModal(trigger.dataset.edSpotVideoTitle || "Spot It. Stop It", trigger.dataset.edSpotVideoSrc); 7801 }, 7802 true, 7803 ); 7804 }); 7805 } 7806 7807 function syncMobileSpotItStopItVideos(root = document) { 7808 const grid = root.querySelector("[data-ed-mobile-spot-video-grid]"); 7809 if (!grid) return; 7810 7811 const videos = mobileSpotVideoEntries(); 7812 if (!videos.length) return; 7813 7814 const signature = videos.map((video) => video.src).join("|"); 7815 if (grid.dataset.edSpotVideoSignature !== signature) { 7816 grid.dataset.edSpotVideoSignature = signature; 7817 grid.innerHTML = videos.map((video, index) => renderMobileSpotVideoTile(video, index)).join(""); 7818 } 7819 7820 bindSpotItStopItVideoTriggers(grid); 7821 } 7822 7823 function homeStatsSection() { 7824 return ( 7825 document.getElementById("comp-mm5rvriw") || 7826 document.querySelector(".lifeboat-stats-fallback")?.closest("section, [id^
7826='comp-']") 7827 ); 7828 } 7829 7830 function homeSafetyIntroSection() { 7831 return document.querySelector("[data-ed-email-update='home-safety-intro']"); 7832 } 7833 7834 function installHomeSafetyIntroSection() { 7835 if (path !== "/") return; 7836 7837 const statsSection = homeStatsSection(); 7838 if (!statsSection) return; 7839 7840 let section = homeSafetyIntroSection(); 7841 if (!section) { 7842 section = document.createElement("section"); 7843 section.className = "ed-home-safety-intro"; 7844 section.dataset.edEmailUpdate = "home-safety-intro"; 7845 section.setAttribute("aria-labelledby", "ed-home-safety-title"); 7846 section.innerHTML = ` 7847 <div class="ed-home-safety-inner"> 7848 <div class="ed-home-safety-copy"> 7849 <h2 id="ed-home-safety-title">Helping Survivors Reclaim Safety, Stability, and Hope</h2> 7850 <p>The Lifeboat Project provides long-term, trauma-informed care and housing-first support for survivors of human trafficking.</p> 7851 <div class="ed-home-safety-actions"> 7852 <a href="/who-we-are/">Our Mission</a> 7853 <a href="${requestHelpUrl}" target="_blank" rel="noopener noreferrer">Request Help</a> 7854 </div> 7855 </div> 7856 <figure class="ed-home-safety-visual"> 7857 <img src="${homeSafetyImage}" alt="People standing together with arms around each other" width="1528" height="1600" loading="lazy" decoding="async"> 7858 </figure> 7859 </div> 7860 `; 7861 } 7862 7863 const missionSection = document.querySelector("[data-ed-email-update='home-mission-video']"); 7864 if (missionSection && missionSection.previousElementSibling !== section) { 7865 missionSection.insertAdjacentElement("beforebegin", section); 7866 return; 7867 } 7868 7869 if (statsSection.nextElementSibling !== section) { 7870 statsSection.insertAdjacentElement("afterend", section); 7871 } 7872 } 7873 7874 function installHomeMissionVideoSection() { 7875 if (path !== "/") return; 7876 7877 exposeHomepageVideoControls(); 7878 7879 const statsSection = homeStatsSection(); 7880 if (!statsSection) return; 7881 7882 const featureVideo = homeMissionVideo(); 7883 if (!featureVideo) return; 7884 7885 let section = document.querySelector("[data-ed-email-update='home-mission-video']"); 7886 if (!section) { 7887 section = document.createElement("section"); 7888 section.className = "ed-home-mission-video"; 7889 section.dataset.edEmailUpdate = "home-mission-video"; 7890 section.setAttribute("aria-labelledby", "ed-home-mission-title"); 7891 section.innerHTML = ` 7892 <div class="ed-home-mission-inner"> 7893 <div class="ed-home-mission-copy"> 7894 <p class="ed-home-mission-kicker">Mission Video</p> 7895 <h2 id="ed-home-mission-title">See the work behind safety, stability, and hope.</h2> 7896 <p>Hear how The Lifeboat Project pairs immediate support with long-term, trauma-informed care for survivors rebuilding in Central Florida.</p> 7897 <div class="ed-home-mission-actions"> 7898 <button type="button" data-ed-home-mission-play data-vi
7898deo-title="${escapeMarkup(featureVideo.title)}"> 7899 <span class="ed-home-mission-play-icon" aria-hidden="true"></span> 7900 <span>Play ${escapeMarkup(featureVideo.title)}</span> 7901 </button> 7902 <button type="button" data-ed-home-mission-all>All Videos</button> 7903 </div> 7904 </div> 7905 <button class="ed-home-mission-preview" type="button" data-ed-home-mission-play data-video-title="${escapeMarkup(featureVideo.title)}" aria-label="Play video: ${escapeMarkup(featureVideo.title)}"> 7906 <img data-ed-home-mission-poster src="${escapeMarkup(featureVideo.image)}" alt="${escapeMarkup(featureVideo.title)} video preview" width="1280" height="720" loading="eager" decoding="async"> 7907 <span class="ed-home-mission-overlay"> 7908 <span class="ed-home-mission-play-large" aria-hidden="true"></span> 7909 <span> 7910 <strong>${escapeMarkup(featureVideo.title)}</strong> 7911 <em>Watch the mission story</em> 7912 </span> 7913 </span> 7914 </button> 7915 </div> 7916 `; 7917 } 7918 7919 const poster = section.querySelector("[data-ed-home-mission-poster]"); 7920 if (poster) { 7921 poster.src = featureVideo.image; 7922 poster.alt = featureVideo.title + " video preview"; 7923 } 7924 7925 section.querySelectorAll("[data-ed-home-mission-play]").forEach((button) => { 7926 button.setAttribute("data-video-title", featureVideo.title); 7927 }); 7928 7929 if (section.dataset.edHomeMissionBound !== "true") { 7930 section.dataset.edHomeMissionBound = "true"; 7931 } 7932 7933 const nativeVideoSlot = document.getElementById("comp-mm6zq9vl"); 7934 const eventPromo = document.querySelector("[data-ed-email-update='home-yacht-rock-promo']"); 7935 const missionAnchor = homeSafetyIntroSection() || statsSection; 7936 7937 if (nativeVideoSlot && nativeVideoSlot !== section) { 7938 nativeVideoSlot.replaceWith(section); 7939 } else if (eventPromo && eventPromo.previousElementSibling !== section) { 7940 eventPromo.insertAdjacentElement("beforebegin", section); 7941 } else if (!eventPromo && missionAnchor.nextElementSibling !== section) { 7942 missionAnchor.insertAdjacentElement("afterend", section); 7943 } 7944 7945 bindHomeMissionVideoTriggers(section); 7946 document.body.classList.add("ed-home-mission-video-ready"); 7947 } 7948 7949 function updateHomepageVideoPreview(video = currentHomeVideo(), showLabel = false) { 7950 const section = document.getElementById("comp-mm6zq9vl"); 7951 if (!section || !video) return; 7952 7953 section.dataset.edCurrentVideoTitle = video.title; 7954 section.querySelectorAll("button[data-hook='overlay-play-button']").forEach((button) => { 7955 button.setAttribute("aria-label", "Play video: " + video.title); 7956 }); 7957 7958 const cover = section.querySelector("[data-hook='image-cover']"); 7959 const image = section.querySelector("[data-hook='image-cover'] img"); 7960 const source = section.querySelector("[data-hook='image-cover'] source"); 7961 if (cover) { 7962 cover.style.setProperty( 7963 "background-image", 7964 `url("${video.image}")`, 7965 "important", 7966 ); 7967 } 7968 if (image) { 7969 image.removeAttribute("srcset"); 7970 image.src = video.image; 7971 image.alt = video.title; 7972 } 7973 if (source) { 7974 source.srcset = video.image + " 1x"; 7975 } 7976 7977 if (showLabel) { 7978 let label = section.querySelector(".ed-home-video-label"); 7979 if (!label) { 7980 label = document.createElement("div"); 7981 label.className = "ed-home-video-label"; 7982 label.setAttribute("aria-live", "polite"); 7983 section.appendChild(label); 7984 } 7985 label.textContent = video.title; 7986 } 7987 } 7988 7989 function advanceHomepageVideo(event) { 7990 if (event) { 7991 event.preventDefault(); 7992 event.stopPropagation(); 7993 event.stopImmediatePropagation?.(); 7994 } 7995 7996 homeVideoIndex = (homeVideoIndex + 1) % storyVideoLibrary.length; 7997 updateHomepageVideoPreview(currentHomeVideo(), true); 7998 } 7999 8000 function homepageArrowAreaWasClicked(event, section) { 8001 if (!event || !section) return false; 8002 const rect = section.getBoundingClientRect(); 8003 const rightEdge = rect.right - Math.min(170, rect.width * 0.14); 8004 const belowTop = event.clientY > rect.top + 80; 8005 const aboveBottom = event.clientY < rect.bottom - 90; 8006 return event.clientX >= rightEdge && belowTop && aboveBottom; 8007 } 8008 8009 function installHomepageVideoControls() { 8010 if (path !== "/") return; 8011 8012 const section = document.getElementById("comp-mm6zq9vl"); 8013 if (!section) return; 8014 8015 const activeButton = section.querySelector("button[data-hook='overlay-play-button']"); 8016 const activeTitle = titleFromPlayButton(activeButton); 8017 const activeIndex = storyVideoLibrary.findIndex((video) => video.title === activeTitle); 8018 if (activeIndex >= 0) homeVideoIndex = activeIndex; 8019 8020 updateHomepageVideoPreview(); 8021 8022 if (section.dataset.edHomepageVideosBound === "true") return; 8023 section.dataset.edHomepageVideosBound = "true"; 8024 8025 section.addEventListener( 8026 "click", 8027 (event) => { 8028 const target = event.target instanceof Element ? event.target : null; 8029 if (!target) return; 8030 8031 const playButton = target.closest("button[data-hook='overlay-play-button']"); 8032 if (playButton && section.contains(playButton)) { 8033 event.preventDefault(); 8034 event.stopPropagation(); 8035 event.stopImmediatePropagation?.(); 8036 const title = titleFromPlayButton(playButton); 8037 const index = storyVideoLibrary.findIndex((video) => video.title === title); 8038 if (index >= 0) homeVideoIndex = index; 8039 openVideoModal(title); 8040 return; 8041 } 8042 8043 const allVideosButton = target.closest("button[data-hook='all-videos-button']"); 8044 if (allVideosButton && section.contains(allVideosButton)) { 8045 event.preventDefault(); 8046 event.stopPropagation(); 8047 event.stopImmediatePropagation?.(); 8048 openVideoModal(currentHomeVideo()?.title); 8049 return; 8050 } 8051 8052 const nextButton = target.closest("button[data-hook='next-button']"); 8053 if ((nextButton && section.contains(nextButton)) || homepageArrowAreaWasClicked(event, section)) { 8054 advanceHomepageVideo(event); 8055 } 8056 }, 8057 true, 8058 ); 8059 8060 section.addEventListener("keydown", (event) => { 8061 const target = event.target instanceof Element ? event.target : null; 8062 if (!target || (event.key !== "Enter" && event.key !== " ")) return; 8063 if (target.closest("button[data-hook='next-button']")) { 8064 advanceHomepageVideo(event); 8065 } 8066 }); 8067 } 8068 8069 function nativeHeaderNavLink(label) { 8070 return [...document.querySelectorAll("#SITE_HEADER a")].find((anchor) => 8071 clean(anchor.innerText || anchor.textContent) === label, 8072 ); 8073 } 8074 8075 function installSponsorsDropdown() { 8076 if (document.querySelector(".sponsors-menu .sponsors-subnav")) return; 8077 8078 const navLink = nativeHeaderNavLink("Sponsors"); 8079 const item = navLink?.closest("li") || navLink?.parentElement; 8080 if (!navLink || !item) return; 8081 8082 item.classList.add("ed-sponsors-nav-fix"); 8083 navLink.setAttribute("aria-haspopup", "true"); 8084 navLink.setAttribute("aria-expanded", item.classList.contains("is-open") ? "true" : "false"); 8085 8086 let dropdown = item.querySelector(".ed-sponsors-dropdown"); 8087 if (!dropdown) { 8088 dropdown = document.createElement("div");
8089 dropdown.className = "ed-sponsors-dropdown"; 8090 dropdown.setAttribute("aria-label", "Sponsors pages"); 8091 dropdown.innerHTML = 8092 '<a href="/lifeboat-lifesavers/">Lifeboat Lifesavers</a>' + 8093 '<a href="/donor-dock">The Donor Dock</a>'; 8094 item.appendChild(dropdown); 8095 } 8096 8097 if (item.dataset.edSponsorsDropdownBound) return; 8098 item.dataset.edSponsorsDropdownBound = "true"; 8099 8100 let closeTimer; 8101 8102 const show = () => { 8103 window.clearTimeout(closeTimer); 8104 item.classList.add("is-open"); 8105 navLink.setAttribute("aria-expanded", "true"); 8106 }; 8107 const hide = () => { 8108 window.clearTimeout(closeTimer); 8109 item.classList.remove("is-open"); 8110 navLink.setAttribute("aria-expanded", "false"); 8111 }; 8112 const scheduleHide = () => { 8113 window.clearTimeout(closeTimer); 8114 closeTimer = window.setTimeout(hide, 180); 8115 }; 8116 8117 item.addEventListener("pointerenter", show); 8118 item.addEventListener("pointerleave", scheduleHide); 8119 dropdown.addEventListener("pointerenter", show); 8120 item.addEventListener("focusin", show); 8121 item.addEventListener("focusout", () => { 8122 window.requestAnimationFrame(() => { 8123 if (!item.contains(document.activeElement)) hide(); 8124 }); 8125 }); 8126 } 8127 8128 function installWhoWeAreDropdown() { 8129 const navLink = nativeHeaderNavLink("Who We Are"); 8130 const item = navLink?.closest("li") || navLink?.parentElement; 8131 if (!navLink || !item) return; 8132 8133 item.classList.add("ed-who-we-are-nav-fix"); 8134 navLink.setAttribute("href", "/who-we-are/"); 8135 navLink.setAttribute("aria-haspopup", "true"); 8136 navLink.setAttribute("aria-expanded", item.classList.contains("is-open") ? "true" : "false"); 8137 8138 let dropdown = item.querySelector(".ed-who-we-are-dropdown"); 8139 if (!dropdown) { 8140 dropdown = document.createElement("div"); 8141 dropdown.className = "ed-who-we-are-dropdown"; 8142 dropdown.setAttribute("aria-label", "Who We Are pages"); 8143 dropdown.innerHTML = 8144 '<a href="/meet-the-team">Meet the Team</a>' + 8145 '<a href="/board-of-directors">Board of Directors</a>' + 8146 '<a href="/financial-strategic-plan">Financial & Strategic Plan</a>'; 8147 item.appendChild(dropdown); 8148 } 8149 8150 if (item.dataset.edWhoWeAreDropdownBound) return; 8151 item.dataset.edWhoWeAreDropdownBound = "true"; 8152 8153 let closeTimer; 8154 8155 const show = () => { 8156 window.clearTimeout(closeTimer); 8157 item.classList.add("is-open"); 8158 navLink.setAttribute("aria-expanded", "true"); 8159 }; 8160 const hide = () => { 8161 window.clearTimeout(closeTimer); 8162 item.classList.remove("is-open"); 8163 navLink.setAttribute("aria-expanded", "false"); 8164 }; 8165 const scheduleHide = () => { 8166 window.clearTimeout(closeTimer); 8167 closeTimer = window.setTimeout(hide, 180); 8168 }; 8169 8170 item.addEventListener("pointerenter", show); 8171 item.addEventListener("pointerleave", scheduleHide); 8172 dropdown.addEventListener("pointerenter", show); 8173 item.addEventListener("focusin", show); 8174 item.addEventListener("focusout", () => { 8175 window.requestAnimationFrame(() => { 8176 if (!item.contains(document.activeElement)) hide(); 8177 }); 8178 }); 8179 } 8180 8181 function installGetInvolvedDropdown() { 8182 const navLink = nativeHeaderNavLink("Get Involved"); 8183 const item = navLink?.closest("li") || navLink?.parentElement; 8184 if (!navLink || !item) return; 8185 8186 item.classList.add("ed-get-involved-nav-fix"); 8187 navLink.setAttribute("aria-haspopup", "true"); 8188 navLink.setAttribute("aria-expanded", item.classList.contains("is-open") ? "true" : "false"); 8189 8190 let dropdown = item.querySelector(".ed-get-involved-dropdown"); 8191 if (!dropdown) { 8192 dropdown = document.createElement("div"); 8193 dropdown.className = "ed-get-involved-dropdown"; 8194 dropdown.setAttribute("aria-label", "Get Involved pages"); 8195 dropdown.innerHTML = 8196 '<a href="/international-partnerships/">International Partnerships</a>' + 8197 '<a href="/volunteer">Volunteer</a>' + 8198 '<a href="/request-a-speaker/">Request a Speaker</a>'; 8199 item.appendChild(dropdown); 8200 } 8201 8202 if (item.dataset.edGetInvolvedDropdownBound) return; 8203 item.dataset.edGetInvolvedDropdownBound = "true"; 8204
8205 let closeTimer; 8206 8207 const show = () => { 8208 window.clearTimeout(closeTimer); 8209 item.classList.add("is-open"); 8210 navLink.setAttribute("aria-expanded", "true"); 8211 }; 8212 const hide = () => { 8213 window.clearTimeout(closeTimer); 8214 item.classList.remove("is-open"); 8215 navLink.setAttribute("aria-expanded", "false"); 8216 }; 8217 const scheduleHide = () => { 8218 window.clearTimeout(closeTimer); 8219 closeTimer = window.setTimeout(hide, 180); 8220 }; 8221 8222 item.addEventListener("pointerenter", show); 8223 item.addEventListener("pointerleave", scheduleHide); 8224 dropdown.addEventListener("pointerenter", show); 8225 item.addEventListener("focusin", show); 8226 item.addEventListener("focusout", () => { 8227 window.requestAnimationFrame(() => { 8228 if (!item.contains(document.activeElement)) hide(); 8229 }); 8230 }); 8231 } 8232 8233 function installStoriesDropdown() { 8234 const navLink = nativeHeaderNavLink("Stories"); 8235 const item = navLink?.closest("li") || navLink?.parentElement; 8236 if (!navLink || !item) return; 8237 8238 item.classList.add("lifeboat-stories-nav"); 8239 navLink.setAttribute("aria-haspopup", "true"); 8240 navLink.setAttribute("aria-expanded", item.classList.contains("is-open") ? "true" : "false"); 8241 8242 let dropdown = item.querySelector(".lifeboat-blog-dropdown-link"); 8243 if (!dropdown) { 8244 dropdown = document.createElement("a"); 8245 dropdown.className = "lifeboat-blog-dropdown-link"; 8246 dropdown.href = "/blog/"; 8247 dropdown.textContent = "Blog"; 8248 item.appendChild(dropdown); 8249 } 8250 8251 if (item.dataset.edStoriesDropdownBound) return; 8252 item.dataset.edStoriesDropdownBound = "true"; 8253 8254 let closeTimer; 8255 8256 const show = () => { 8257 window.clearTimeout(closeTimer); 8258 item.classList.add("is-open"); 8259 navLink.setAttribute("aria-expanded", "true"); 8260 }; 8261 const hide = () => { 8262 window.clearTimeout(closeTimer); 8263 item.classList.remove("is-open"); 8264 navLink.setAttribute("aria-expanded", "false"); 8265 }; 8266 const scheduleHide = () => { 8267 window.clearTimeout(closeTimer); 8268 closeTimer = window.setTimeout(hide, 180); 8269 }; 8270 const capturePointerLeave = (event) => { 8271 event.stopImmediatePropagation(); 8272 scheduleHide(); 8273 }; 8274 8275 item.addEventListener("pointerenter", show); 8276 item.addEventListener("pointerleave", capturePointerLeave, true); 8277 dropdown.addEventListener("pointerenter", show); 8278 item.addEventListener("focusin", show); 8279 item.addEventListener("focusout", () => { 8280 window.requestAnimationFrame(() => { 8281 if (!item.contains(document.activeElement)) hide(); 8282 }); 8283 }); 8284 } 8285 8286 function findWhoWeAreReadMoreTarget() { 8287 return ( 8288 document.getElementById("comp-mm5awg46") || 8289 [...document.querySelectorAll("section, div")].find((element) => { 8290 const label = clean(element.innerText || element.textContent); 8291 return label.startsWith("Why it Matters"); 8292 }) 8293 ); 8294 } 8295 8296 function ensureWhyItMattersAnchor(target) { 8297 let anchor = document.getElementById("why-it-matters"); 8298 if (anchor || !target) return anchor || target; 8299 8300 anchor = document.createElement("span"); 8301 anchor.id = "why-it-matters"; 8302 anchor.setAttribute("aria-hidden", "true"); 8303 Object.assign(anchor.style, { 8304 display: "block", 8305 height: "0", 8306 overflow: "hidden", 8307 position: "relative", 8308 top: "0", 8309 }); 8310 target.prepend(anchor); 8311 return anchor; 8312 } 8313 8314 function scrollToWhyItMatters(target) { 8315 if (!target) return false; 8316 8317 ensureWhyItMattersAnchor(target); 8318 const headerHeight = document.querySelector("#SITE_HEADER, header")?.getBoundingClientRect().height || 0; 8319 const top = Math.max(0, window.scrollY + target.getBoundingClientRect().top - headerHeight - 16); 8320 const reduceMotion = window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches; 8321 8322 window.scrollTo({ 8323 top, 8324 behavior: reduceMotion ? "auto" : "smooth", 8325 }); 8326 8327 if (window.location.hash !== "#why-it-matters") { 8328 window.history.pushState(null, "", "#why-it-matters"); 8329 } 8330 return true; 8331 } 8332 8333 function installWhoWeAreReadMoreScroll() { 8334 if (path !== "/who-we-are") return; 8335 8336 const target = findWhoWeAreReadMoreTarget(); 8337 if (!target) return; 8338 8339 const buttons = [ 8340 ...document.querySelectorAll( 8341 "#comp-mm5awg6b button, #comp-mm5awg6x button, button[aria-label='Read More']", 8342 ), 8343 ].filter((button) => clean(button.innerText || button.textContent || button.getAttribute("aria-label")) === "Read More"); 8344 8345 buttons.forEach((button) => { 8346 button.setAttribute("data-ed-scroll-target", "#why-it-matters"); 8347 button.setAttribute("type", "button"); 8348 8349 if (button.dataset.edWhoWeAreReadMoreBound === "true") return; 8350 button.dataset.edWhoWeAreReadMoreBound = "true"; 8351 button.addEventListener( 8352 "click", 8353 (event) => { 8354 if (!scrollToWhyItMatters(target)) return; 8355 event.preventDefault(); 8356 event.stopPropagation(); 8357 event.stopImmediatePropagation?.(); 8358 }, 8359 true, 8360 ); 8361 }); 8362 } 8363 8364 function installStoriesHeroBlogButton() { 8365 if (path !== "/stories") return; 8366 8367 const blogButtons = [...document.querySelectorAll("a, button, [role='button'], [role='link']")].filter( 8368 (element) => { 8369 const label = clean(element.getAttribute("aria-label") || element.innerText || element.textContent); 8370 return label === "BLOG"; 8371 }, 8372 ); 8373 8374 blogButtons.forEach((button) => { 8375 if (button instanceof HTMLAnchorElement) { 8376 button.href = "/blog/"; 8377 button.target = "_self"; 8378 button.removeAttribute("data-anchor"); 8379 } 8380 8381 if (button.dataset.edStoriesHeroBlogBound === "true") return; 8382 button.dataset.edStoriesHeroBlogBound = "true"; 8383 button.addEventListener( 8384 "click", 8385 (event) => { 8386 event.preventDefault(); 8387 event.stopPropagation(); 8388 event.stopImmediatePropagation?.(); 8389 window.location.assign("/blog/"); 8390 }, 8391 true, 8392 ); 8393 }); 8394 } 8395 8396 function normalizeStoriesHashRoute() { 8397 if (path !== "/stories" || window.location.hash !== storiesVideosHash) return; 8398 if (document.documentElement.dataset.edStoriesHashNormalized === "true") return; 8399 8400 document.documentElement.dataset.edStoriesHashNormalized = "true"; 8401 if ("scrollRestoration" in window.history) { 8402 window.history.scrollRestoration = "manual"; 8403 } 8404 window.history.replaceState(null, "", "/stories" + window.location.search); 8405 8406 const scrollToTop = () => window.scrollTo({ top: 0, left: 0, behavior: "auto" }); 8407 scrollToTop(); 8408 window.requestAnimationFrame(scrollToTop); 8409 window.setTimeout(scrollToTop, 100); 8410 window.setTimeout(scrollToTop, 500); 8411 } 8412 8413 function storiesVideosTarget() { 8414 return ( 8415 document.getElementById("comp-mm6udoup") || 8416 document.querySelector('[aria-label*="channel videos widget"]')?.closest("section") || 8417 document.getElementById("comp-mm6ue9no") 8418 ); 8419 } 8420 8421 function scrollToStoriesVideos() { 8422 const target = storiesVideosTarget(); 8423 if (!target) return false;
8424 8425 const reduceMotion = window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches; 8426 target.scrollIntoView({ 8427 behavior: reduceMotion ? "auto" : "smooth", 8428 block: "start", 8429 }); 8430 return true; 8431 } 8432 8433 function bindStoriesVideoAnchor(anchor) { 8434 if (!anchor || anchor.dataset.edStoriesVideosScroll === "true") return; 8435 anchor.dataset.edStoriesVideosScroll = "true"; 8436 8437 if (path !== "/stories") return; 8438 8439 anchor.addEventListener( 8440 "click", 8441 (event) => { 8442 if (!scrollToStoriesVideos()) return; 8443 event.preventDefault(); 8444 event.stopPropagation(); 8445 event.stopImmediatePropagation?.(); 8446 }, 8447 true, 8448 ); 8449 } 8450 8451 function installStoriesVideoScroll() { 8452 document.querySelectorAll("#SITE_HEADER a, header a").forEach((anchor) => { 8453 if (clean(anchor.innerText || anchor.textContent) !== "Stories") return; 8454 anchor.setAttribute("href", storiesPath); 8455 }); 8456 8457 if (path !== "/stories") return; 8458 8459 document 8460 .querySelectorAll('a[data-anchor="anchors-mm6udous2"], a[aria-label="VIDEOS"]') 8461 .forEach((anchor) => { 8462 anchor.setAttribute("href", storiesVideosHash); 8463 anchor.removeAttribute("data-anchor"); 8464 bindStoriesVideoAnchor(anchor); 8465 }); 8466 } 8467 8468 function applyAll() { 8469 normalizeStoriesHashRoute(); 8470 document.body?.classList.toggle("ed-advisory-board-view", path === "/copy-of-meet-the-team-1"); 8471 document.documentElement?.classList.toggle("ed-advisory-board-view-root", path === "/copy-of-meet-the-team-1"); 8472 installAdvisoryBioHandlers(); 8473 installAdvisoryChatSuppression(); 8474 installMobileShell(); 8475 installUnifiedDesktopHeader(); 8476 restoreAboutFourEmbeds(); 8477 applyGlobalLabels(); 8478 applyGlobalLinks(); 8479 installContactOverflowNavItem(); 8480 removeRetiredWhoWeAreLinks(); 8481 normalizeLegacyActionCards(); 8482 repairCapturedSrcsetImages(); 8483 repairFooterSocialIcons(); 8484 promoteStoryThumbnailImages(); 8485 ensureBlogInventory(); 8486 arrangeStoriesBlogCards(); 8487 installEditorialBlogIndex(); 8488 repairCapturedSrcsetImages(); 8489 promoteStoryThumbnailImages(); 8490 installImageRepairObserver(); 8491 installWhoWeAreDropdown(); 8492 installWhoWeAreReadMoreScroll(); 8493 installGetInvolvedDropdown(); 8494 installSponsorsDropdown(); 8495 installStoriesDropdown(); 8496 installStoriesHeroBlogButton(); 8497 installStoriesVideoScroll(); 8498 updateHomeStats(); 8499 installGetInvolvedHeader(); 8500 installVolunteerHeader(); 8501 installVolunteerPageExperience(); 8502 repairGetInvolvedPageCards(); 8503 syncHomeGetInvolvedChat(); 8504 installTeamReadMoreLinks(); 8505 installTinaSoppCard(); 8506 repairTeamPortraitImages(); 8507 installTinaSoppProfile(); 8508 installJonnyProfileGallery(); 8509 removeTeamProfileBlankSpacers(); 8510 updateBoardPage(); 8511 installBoardDirectorsPage(); 8512 installFinancialStrategicPlanPage(); 8513 installWhatWeDoHeader(); 8514 installWhatWeDoBelieveIntro(); 8515 installWhatWeDoVideo(); 8516 installLifelongCareSection(); 8517 installShieldProgram(); 8518 installAdvisoryReadMoreFallbacks(); 8519 repairAdvisoryRepeaterLayout(); 8520 installAdvisoryBoardPage(); 8521 installInternationalPartnershipsPage(); 8522 installInternationalPartnerFormPage(); 8523 installPartnerForms(document); 8524 installLifeboatLifesaversPage(); 8525 installSponsorsMirrorPage(); 8526 installDonorDockMirrorPage(); 8527 installDonorDockFullSponsorList(); 8528 installEventUpdates(); 8529 installKnowSignsHeader(); 8530 installKnowSignsEducation(); 8531 trimKnowSignsFooterGap(); 8532 removeHomeSponsorDuplicate(); 8533 installHomepageYachtRockPromo(); 8534 installHomeSafetyIntroSection(); 8535 installHomeMissionVideoSection(); 8536 installHomeSafetyIntroSection(); 8537 installFooterSponsorBand(); 8538 syncFooterSponsorMarquees(); 8539 correctNewsletterCopy(); 8540 updateSubscribeMessage(); 8541 exposeHomepageVideoControls(); 8542 installHomepageVideoControls(); 8543 installMobileShell(true); 8544 ensureKnowSignsMobilePage(); 8545 bindHomeMissionVideoTriggers(document); 8546 syncWhatWeDoSectionOrder(); 8547 trimHomepageFooterGap(); 8548 hardStopWhatWeDoFooter(); 8549 } 8550 8551 applyAll(); 8552 window.addEventListener("DOMContentLoaded", applyAll); 8553 window.addEventListener("load", applyAll); 8554 window.setTimeout(applyAll, 500); 8555 window.setTimeout(applyAll, 1800); 8556 window.setTimeout(applyAll, 3200); 8557 window.setTimeout(applyAll, 5000); 8558 window.addEventListener("resize", () => { 8559 arrangeStoriesBlogCards(); 8560 installEditorialBlogIndex(); 8561 scheduleAdvisoryRepair(); 8562 repairHomeGetInvolvedLayout(); 8563 syncWhatWeDoSectionOrder(); 8564 trimKnowSignsFooterGap(); 8565 trimHomepageFooterGap(); 8566 hardStopWhatWeDoFooter(); 8567 syncFooterSponsorMarquees(); 8568 }); 8569})();
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.