1<!DOCTYPE HTML> 2<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US"> 3<head> 4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2, user-scalable=1"> 7 8 <!-- Preconnect --> 9 <link rel="preconnect" href="https://www.optimizecdn.com" crossorigin> 10 <link rel="preconnect" href="https://fonts.googleapis.com"> 11 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 12 <link rel="apple-touch-icon" href="/images/favicon.webp"> 13 <link rel="icon" type="image/webp" href="/images/favicon.webp"> 14 15 <!-- Site Meta Data --> 16 <title>Join Retaining Wall Expert - Today!</title> 17 <meta name="description" content="Join Retaining Wall Expert. Create Your Account Today!"> 18 <meta name="keywords" content="Retaining Wall, Retaining Wall Expert"> 19 <meta name="robots" content="index, follow"> 20 21 <!-- Canonical URL --> 22 <link rel="canonical" href="https://www.retainingwallexpert.com/join"> 23 <!-- Social Media Meta Data --> 24 <meta property="og:type" content="website"> 25 <meta property="og:url" content="https://www.retainingwallexpert.com/join"> 26 <meta property="og:site_name" content="Retaining Wall Expert"> 27 <meta property="og:title" content="Join Retaining Wall Expert - Today!"> 28 <meta property="og:description" content="Join Retaining Wall Expert. Create Your Account Today!"> 29 <meta property="og:image" content="https://www.retainingwallexpert.com/images/church-theme-bg.jpg"> 30
30<script> 31 if (window.innerWidth <= 768 && !document.referrer) { 32 document.write('<div id="mobile-loading-message" aria-hidden="true" onwheel="event.preventDefault()" ontouchmove="event.preventDefault()" style="display:block;position:sticky;top:0;width:100vw;height:100vh;background:rgb(250, 250, 250);color:rgb(34, 34, 34);z-index:9999;font-family:Arial,sans-serif;font-size:16px;line-height:24px;padding-top:50px;text-align:center;touch-action:none;overscroll-behavior:none;pointer-events:auto;"><div style="width:24px;height:24px;border:3px solid rgba(99,111,124,0.2);border-top-color:rgb(99,111,124);border-radius:50%;animation:spin 1.5s linear infinite;margin:10px auto"></div><span class="text" role="status">Loading<br>Retaining Wall Expert</span></div><style>@keyframes spin{to{transform:rotate(360deg);}}</style>'); 33 setTimeout(function(){var p=document.getElementById('mobile-loading-message');if(p){p.style.display='none';p.classList.add('hidden-xs','hide');}},7500);} 34 </script>
34 35 36 <!-- Preload --> 37 <link rel="preload" as="style" href="https://www.optimizecdn.com/directory/cdn/assets/bootstrap/css/critical-styles.pkgd.min.css?v=09.05.26" fetchpriority="high" crossorigin> 38 <link rel="preload" as="style" href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700,800,900|Raleway:300,400,600,700,800,900|PT+Sans:300,400,600,700,800,900|Quicksand:300,400,600,700,800,900&display=swap" fetchpriority="high"> 39 <link rel="preload" href="/images/bg202.webp" as="image" fetchpriority="high"> 40 41 <!-- Non-Critical Stylesheet - Render Before Critical Styles --> 42 <link rel="stylesheet" media="print" onload="this.onload=null;this.removeAttribute('media');" href="https://www.optimizecdn.com/directory/cdn/assets/bootstrap/css/non-critical-styles.pkgd.min.css?v=3.3.0" crossorigin> 43 <noscript> 44 <link rel="stylesheet" href="https://www.optimizecdn.com/directory/cdn/assets/bootstrap/css/non-critical-styles.pkgd.min.css" crossorigin> 45 </noscript> 46 47 <!-- Critical Stylesheet --> 48 <link rel="stylesheet" href="https://www.optimizecdn.com/directory/cdn/assets/bootstrap/css/critical-styles.pkgd.min.css?v=09.05.26" crossorigin> 49 50 <!-- Google Fonts Stylesheet --> 51 <link rel="stylesheet" media="print" onload="this.onload=null;this.removeAttribute('media');" href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700,800,900|Raleway:300,400,600,700,800,900|PT+Sans:300,400,600,700,800,900|Quicksand:300,400,600,700,800,900&display=swap"> 52 <noscript> 53 <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700,800,900|Raleway:300,400,600,700,800,900|PT+Sans:300,400,600,700,800,900|Quicksand:300,400,600,700,800,900&display=swap"> 54 </noscript> 55 56 <!-- FontAwesome Stylesheet --> 57 <link rel="stylesheet" media="print" onload="this.onload=null;this.removeAttribute('media');" href="https://www.optimizecdn.com/directory/cdn/assets/bootstrap/font-awesome/css/font-awesome.min.css" crossorigin> 58 <noscript> 59 <link rel="stylesheet" href="https://www.optimizecdn.com/directory/cdn/assets/bootstrap/font-awesome/css/font-awesome.min.css" crossorigin> 60 </noscript> 61 62 <!-- Bootstrap Icons Stylesheet --> 63 <link rel="stylesheet" media="print" onload="this.onload=null;this.removeAttribute('media');" href="https://www.optimizecdn.com/directory/cdn/assets/bootstrap/fonts/bootstrap-icons.min.css?v=1.13.1" crossorigin> 64 <noscript> 65 <link rel="stylesheet" href="https://www.optimizecdn.com/directory/cdn/assets/bootstrap/fonts/bootstrap-icons.min.css?v=1.13.1" crossorigin> 66 </noscript> 67 68 <!-- Critical JavaScript --> 69
69<script src="https://www.optimizecdn.com/directory/cdn/assets/bootstrap/libraries/latest/jquery.min.js"></script>
69 70
70<script src="https://www.optimizecdn.com/directory/cdn/assets/bootstrap/libraries/latest/bootstrap.min.js"></script>
70 71
71<script> 72 /* jQuery.event.special.touchstart = { 73 setup: function( _, ns, handle ) { 74 this.addEventListener("touchstart", handle, { passive: !ns.includes("noPreventDefault") }); 75 } 76 }; */ 77 jQuery.event.special.touchmove = { 78 setup: function( _, ns, handle ) { 79 this.addEventListener("touchmove", handle, { passive: !ns.includes("noPreventDefault") }); 80 } 81 }; 82 jQuery.event.special.wheel = { 83 setup: function( _, ns, handle ){ 84 this.addEventListener("wheel", handle, { passive: true }); 85 } 86 }; 87 jQuery.event.special.mousewheel = { 88 setup: function( _, ns, handle ){ 89 this.addEventListener("mousewheel", handle, { passive: true }); 90 } 91 }; 92 </script>
92 93 94 <!-- Breadcrumb Position --> 95 <style>html.bc-relocate .container:has(> .breadcrumb):has(~ .hero_section_container) .breadcrumb{display:none!important;}html.bc-relocate .hero_section_container + .clearfix + .container::before{content:"";display:block;min-height:24px;}.hero_section_container + .clearfix + .container > .breadcrumb:first-child{position:relative;top:-24px;}</style> 96
96<script>document.documentElement.classList.add('bc-relocate');document.addEventListener('DOMContentLoaded',function(){var bc=document.querySelector('ol.breadcrumb'),hero=document.querySelector('.hero_section_container');if(bc&&hero){var t=hero.nextElementSibling;while(t&&!t.classList.contains('container'))t=t.nextElementSibling;if(t)t.insertBefore(bc,t.firstChild);}document.documentElement.classList.remove('bc-relocate');});</script>
96 97 98 99 <!-- Prefetch --> 100 <link rel="prefetch" href="https://www.optimizecdn.com/directory/cdn/assets/bootstrap/jquery.lazy/1.7.9/jquery.lazy.min.js" as="script"> 101 <link rel="prefetch" href="https://www.optimizecdn.com/directory/cdn/assets/bootstrap/js/websiteScripts.min.js?v=8.0.0" as="script"> 102 103 104</head> 105 106<body class="general-session"><!-- 107IMPORTANT: It is not recommended to customize this widget as it directly connects to fields in DESIGN SETTINGS. If new design settings are created and this widget is already customized, then the website will not be able to apply any new design setitngs. 108 109INSTEAD: If custom CSS rules are needed, add them directly into the DESIGN SETTINGS > CUSTOM CSS section. 110--> 111<style> 112 .upload-form-field::before { 113 content: "choose files"; 114 display: inline-block; 115 border: 1px solid #999; 116 border-radius: 3px; 117 padding: 5px 8px; 118 } 119 #first_container span.input-group-addon,#first_container .datepicker *,#first_container .input-group-addon, #first_container .input-group-addon *,#first_container .fr-action-buttons .fr-submit,.fr-popup .fr-layer.fr-color-hex-layer .fr-action-buttons button.fr-command { 120 white-space: nowrap !important; 121 } 122 /* Main Website Design */ 123 body,.modal-header,.modal-content,.modal-body,.modal-footer { 124 background: rgb(250, 250, 250); 125 color: rgb(34, 34, 34); 126 font-family: 'Open Sans'; 127 font-size: 14px; 128 } 129 .select2-container .select2-choice { 130 font-family: 'Open Sans'!important; 131 } 132 html{ 133 background: rgb(34, 34, 34) } 134 .bootstrap-datetimepicker-widget *:not(.active,[data-action="togglePeriod"]) a, .bootstrap-datetimepicker-widget *:not(.active,[data-action="togglePeriod"]) td,.datepicker th.picker-switch,.datepicker .dow { 135 color: #000 !important; 136 } 137 a,a.h1,a.h2,a.h3,a.h4,a.h5,a.h6,.pricing_menu li ul li a:not(.btn) { 138 color: rgb(3, 113, 102); 139 } 140 a:hover, a:focus,.pricing_menu li ul li a:not(.btn):hover,.pricing_menu li ul li a:not(.btn):focus,.btn:hover,.btn:focus { 141 color: rgb(3, 113, 102); 142 } 143 .breadcrumb a{ 144 color: rgba(34, 34, 34,0.9); 145 } 146 .breadcrumb a:hover, .breadcrumb a:focus,.breadcrumb > .active { 147 color: rgb(34, 34, 34); 148 } 149 .help-inline, .help-block { 150 color: rgba(34, 34, 34,0.5); 151 } 152 .h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { 153 font-family: 'PT Sans'; 154 } 155 @media (min-width:1200px) { 156 .container { 157 width:1420px; 158 max-width: 95vw; 159 } 160 .fr-view .froala-table td .froala-table { 161 max-width: 1420px; 162 max-width: min(95vw, 1420px); 163 } 164 } 165 /* Header Design */ 166 .header, .mobile_website_logo img { 167 background: rgb(250, 250, 250); 168 } 169 .header .mini-nav li a:not(.btn):not(.network-icon), .header .mini-nav span { 170 color: rgb(34, 34, 34); 171 font-size: 14px; 172 } 173 .header .mini-nav li a:not(.btn):hover { 174 color: rgba(34, 34, 34,0.95); 175 } 176 .header .btn_get_listed { 177 background-color: rgb(34, 34, 34); 178 border: 1px solid rgb(34, 34, 34); 179 color: rgb(250, 250, 250)!important; 180 } 181 .header .btn_get_listed:hover, .header .btn_get_listed:focus { 182 background-color: rgba(34, 34, 34,0.97); 183 } 184 .header .btn_search { 185 background-color: rgba(0, 150, 136,0.97); 186 border: 1px solid rgb(0, 150, 136); 187 color: rgb(255, 255, 255); 188 } 189 .header .btn_search:hover, .header .btn_search:focus { 190 background-color: rgb(0, 150, 136); 191 color: rgb(255, 255, 255); 192 } 193 194 /* Logo Design */ 195 .logo,.logo:hover,.logo:focus { 196 color: rgb(3, 113, 102); 197 font-family: 'Raleway'; 198 } 199 .logo .slogan { 200 color: rgb(66, 66, 66); 201 } 202 .logo .fa { 203 color: rgb(3, 113, 102); 204 display: none; 205 } 206 207 /* Main Menu Design */ 208 .member-profile-tabs > ul, .member-profile-tabs .tabs-container { 209 background: rgb(238, 238, 238); 210 position: sticky; 211 z-index: 1; 212 top: 50px; 213 } 214 /* Google Translate When Main Menu Sticky Top */ 215 .skiptranslate:not([style*="display: none;"]) ~ .header .navbar-fixed-top { 216 top: 39px; 217 } 218 .skiptranslate iframe, .skiptranslate:not(.skiptranslate.goog-te-gadget) { 219 position: fixed !important; 220 top: 0 !important; 221 z-index: 999; 222 } 223 @media only screen and (max-width: 1100px) { 224 .member-profile-tabs > ul, .member-profile-tabs .tabs-container { 225 top: 50px; 226 } 227 } 228 .header ul.nav.navbar-nav li ul { 229 background-color: rgb(255, 255, 255); 230 } 231 .header ul.nav.navbar-nav li ul li a, .header ul.nav.navbar-nav li ul li span { 232 color: rgb(0, 150, 136); 233 font-weight: 600; 234 } 235 .header .navbar-default, .pagination > .active > a { 236 background-color: rgb(3, 113, 102); 237 } 238 .header ul.nav.navbar-nav li ul li a:hover, .header ul.nav.navbar-nav li ul li a:focus{ 239 border-left-color: rgb(0, 150, 136); 240 background: rgb(0, 150, 136); 241 color: rgb(255, 255, 255); 242 }
243 .navbar-default .navbar-toggle .icon-bar { 244 background-color: rgb(255, 255, 255); 245 } 246 .user_sidebar, .main_menu, .compact-mobile-search { 247 color: rgb(255, 255, 255); 248 } 249 .navbar-default .navbar-nav > li > a, .navbar-default .navbar-nav > li > span { 250 color: rgb(255, 255, 255); 251 font-weight: 600; 252 } 253 .navbar-default .navbar-nav > li:hover > a,.navbar-default .navbar-nav > li > a:hover,.navbar-default .navbar-nav > li > a:active, .navbar-default .navbar-nav > li > a:focus { 254 color: rgb(255, 255, 255); 255 } 256 .navbar-default .navbar-nav > li { 257 font-family: 'Open Sans'; 258 } 259 260 #website_logo .logo-image { 261 max-width: 400px; 262 } 263 264 265 /* Footer Design */ 266 .footer { 267 background-color: rgb(34, 34, 34); 268 display: block; 269 } 270 .footer, .footer_menu a,.footer_terms a,.footer_menu .content { 271 color: rgb(250, 250, 250); 272 } 273 .footer_menu a:hover, .footer_terms a:hover, .footer_menu a:focus, .footer_terms a:focus { 274 color: rgb(250, 250, 250); 275 } 276 .footer_menu .head { 277 color: rgb(250, 250, 250); 278 } 279 .btn_footer_get_listed { 280 background-color: rgb(244, 67, 54); 281 border: 1px solid rgb(244, 67, 54); 282 color: rgb(255, 255, 255)!important; 283 } 284 .btn_footer_get_listed:hover, .btn_footer_get_listed:focus{ 285 background-color: rgba(244, 67, 54,0.95); 286 } 287 288 /* Homepage Design */ 289 .homepage_settings h1, .homepage_settings h2, .homepage_map h1, .homepage_map h2 { 290 font-family: 'Open Sans'; 291 } 292 .homepage_settings h1, .homepage_map h1 { 293 color: rgb(255, 255, 255); 294 font-weight: 600; 295 text-align: center; 296 } 297 .homepage_settings h2, .homepage_map h2 { 298 color: rgb(255, 255, 255); 299 font-weight: 400; 300 text-align: center; 301 302 } 303 .homepage_settings .search_box label { 304 color: rgb(250, 250, 250); 305 } 306 .btn_home_search, .search_box input[type=submit] { 307 background-color: rgb(0, 150, 136); 308 border: 1px solid rgb(0, 150, 136); 309 color: rgb(255, 255, 255); 310 } 311 .btn_home_search:hover, .btn_home_search:focus, .search_box input[type=submit]:hover, .search_box input[type=submit]:focus { 312 background-color: rgba(0, 150, 136,0.97); 313 color: rgb(255, 255, 255); 314 } 315 .homepage_settings .search_box { 316 padding: 20px; 317 318 background-color: rgba( 34, 34, 34, 0.8); 319 } 320 321 /* Homepage Steps Module */ 322 .homepage_steps { 323 background: none; 324 box-shadow: none; 325 padding: 0; 326 color: rgb(255, 255, 255); 327 } 328 .homepage_steps a.homepage_step_link,.homepage_steps a.homepage_step_link:hover,.homepage_steps a.homepage_step_link:active{ 329 color: rgb(255, 255, 255)!important; 330 } 331 .homepage_steps .fa { 332 color: rgb(255, 255, 255); 333 background-color: rgba(255, 255, 255,0.075); 334 } 335 .homepage_steps h2 + p { 336 opacity: .6; 337 } 338 339 /* Blog Posts Slider Settings */ 340 #myCarousel h2 a, .carousel-caption p,#myCarousel .list-group-item h2, #myCarousel li.list-group-item h4 { 341 color: rgb(51, 51, 51); 342 } 343 #myCarousel .list-group-item { 344 background-color: rgba(222, 210, 183,0.9); 345 border-color: rgba(222, 210, 183,0.80); 346 } 347 #myCarousel .carousel-caption { 348 background-color: rgba(222, 210, 183,0.8); 349 } 350 #myCarousel .list-group, #myCarousel .carousel-inner { 351 background-color: rgb(222, 210, 183) } 352 #myCarousel .list-group .active, #myCarousel .list-group-item:hover { 353 background-color: rgb(222, 210, 183) } 354 #myCarousel .list-group .active h2, #myCarousel .list-group-item:hover h2{ 355 color: rgb(17, 17, 17); 356 } 357 358 /* Additional Settings */ 359 .well blockquote { 360 background: rgb(250, 250, 250) none repeat scroll 0 0; 361 border-color: rgb(238, 238, 238); 362 color: rgb(34, 34, 34); 363 padding: 10px 20px; 364 } 365 .account-form-box form table tr td table { 366 background-color: transparent!important; 367 border: none!important; 368 } 369 370 .account-form-box form table tr td table td { 371 background-color: transparent!important; 372 color: rgb(34, 34, 34)!important; 373 border: none!important; 374 } 375 div.dataTables_length label, div.dataTables_filter label, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active{ 376 color: rgb(34, 34, 34)!important; 377 } 378 .table.dataTable > thead > tr > th, .table > thead > tr > th, .fr-view table th, .fr-view table tfoot td {
379 border-color: rgba(66, 66, 66,0.1); 380 background-color: rgb(224, 224, 224); 381 color: rgb(66, 66, 66); 382 font-weight:600; 383 border-left: none; 384 border-bottom-width: 1px; 385 } 386 .table > tbody > tr > td, .table > tbody > tr > th, .table > tfoot > tr > td, .table > tfoot > tr > th, .table > thead > tr > td, table.dataTable.no-footer { 387 border-color: rgba(66, 66, 66,0.1); 388 } 389 .table > tfoot > tr > td:not(:last-child) { 390 border-right: 1px solid rgba(66, 66, 66,0.1); 391 } 392 table.dataTable.no-footer, table.dataTable { 393 border: 1px solid rgb(238, 238, 238)!important; 394 } 395 .table-view li:not(.table-display-about_me li, .froala-data li), .table-view .table-view-group > div { 396 border-top:1px solid rgb(238, 238, 238); 397 } 398 .table-view .table-view-group:last-child { 399 border-bottom:1px solid rgb(238, 238, 238); 400 } 401 table.dataTable tbody tr, .table-striped.dataTable, .table-striped, .fr-view .table-striped { 402 background-color: rgb(255, 255, 255)!important; 403 } 404 .table-striped.dataTable, .table-striped, .fr-view .table-striped { 405 border: 1px solid rgba(66, 66, 66,0.15); 406 border-collapse: separate; 407 overflow: hidden; 408 } 409 table#feature-body-datatable:has(.dropdown.open),table#digital-products-transactions:has(.dropdown.open), table#example:has(.dropdown.open) { 410 overflow: visible; 411 } 412 .table-striped.dataTable tbody > tr:nth-of-type(2n+1),.table-striped > tbody > tr:nth-of-type(2n+1) { 413 background-color: rgba(250, 250, 250,0.5)!important; 414 } 415 .nav-tabs, hr, .account-menu-title, .modal-header { 416 border-color: rgb(238, 238, 238); 417 } 418 .sidemenu_panel .list-group-item{ 419 background-color: transparent!important; 420 color: rgb(34, 34, 34)!important; 421 } 422 .img-thumbnail { 423 background-color: rgb(255, 255, 255)!important; 424 border: 1px solid rgb(238, 238, 238); 425 } 426 .member_admin_sidemenu p, .member_admin_sidemenu h3 { 427 color: rgb(34, 34, 34)!important; 428 } 429 .close { 430 color: rgb(34, 34, 34); 431 opacity: 1; 432 } 433 .member_results_header h1, .content_w_sidebar.feature-search h1, .feature_results_header h1 { 434 font-size:34px; 435 display: block; 436 } 437 .member_results_header h2, .feature_results_header h2 { 438 font-size:28px; 439 display: block; 440 } 441 .homepage_settings { 442 padding-top: 50px; 443 padding-bottom: 50px; 444 } 445 @media (max-width: 768px) { .mobile_website_logo .visible-xs {display: block !important;}} 446 @media only screen and (max-width: 768px) { 447 .member-profile-header .favorite {float:none} 448 } 449 450 451 @media only screen and (max-width: 1100px) { 452 } 453 .views > i.fa.activeView, .views > i.fa:hover { 454 background-color: rgb(34, 34, 34); 455 color: rgb(250, 250, 250); 456 } 457 .views > i.fa { 458 background-color: rgba(34, 34, 34,0.1); 459 color: rgb(34, 34, 34); 460 } 461 .ui-rangeSlider-label { 462 background-color: rgb(3, 113, 102)!important; 463 color: rgb(255, 255, 255)!important; 464 } 465 .pricing_menu li .title { 466 background: rgb(3, 169, 244); 467 color: rgb(255, 255, 255); 468 } 469 p.account-tip{ 470 color: rgb(34, 34, 34); 471 } 472 .circled_number { 473 background: rgb(51, 51, 51); 474 color: rgb(255, 255, 255); 475 } 476 .pic { 477 background-color: rgba(34, 34, 34,0.8); 478 color: rgb(250, 250, 250); 479 background-repeat: no-repeat; 480 background-position: center; 481 } 482 .pic .pic-caption { 483 background: linear-gradient(0deg, rgba(0, 0, 0, 0) 0%,rgba(34, 34, 34,0.85) 50%); 484 color: rgb(250, 250, 250); 485 } 486 .slick-prev-fa i, .slick-next-fa i{ 487 color: rgb(34, 34, 34); 488 } 489 .module, .well, .tab-content, .nav-tabs>li.active>a, .nav-tabs>li.active>a:focus, .nav-tabs>li.active>a:hover, .nav-tabs>li>a:focus, .nav-tabs>li>a:hover, .nav-tabs.nav-justified>li.active>a, .nav-tabs.nav-justified>li.active>a:focus, .nav-tabs.nav-justified>li.active>a:hover, .nav-tab.nav-justified>li>a:focus, .nav-tabs.nav-justified>li>a:hover, .account-form-box,.account-form-box .module .module,.account-form-box .module .well,.account-form-box .well .well,.account-form-box .well .module,.module .module .module,.module .well .well,.module .module .well,.module .well .module,.well .well .well,.well .module .module,.well .well .module,.well .module .well, .froala-table.module, .froala-table td.module { 490 background-color: rgb(255, 255, 255); 491 border-color: rgb(238, 238, 238); 492 color: rgb(34, 34, 34); 493 } 494 .nav-pills > li.active a, .nav-pills > li > a:hover { 495 background-color: rgb(3, 113, 102)!important; 496 border-color: rgb(3, 113, 102)!important; 497 color: rgb(255, 255, 255)!important; 498 } 499 .sidemenu_panel .panel-heading { 500 color: rgb(34, 34, 34)!important; 501 background-color: rgb(255, 255, 255)!important; 502 } 503 .member-profile-tabs .nav-tabs > li:not(.active) > a, .login-register-tabs.nav-tabs > li:not(.active) > a, .nav-tabs > li:not(.active) > a { 504 background: rgba(255, 255, 255,0.5); 505 color: #595959; 506 } 507 .member-profile-tabs .nav-tabs > li:not(.active) > a:hover, .login-register-tabs.nav-tabs > li:not(.active) > a:hover, .nav-tabs > li:not(.active) > a:hover { 508 background: rgba(255, 255, 255,1); 509 color: rgb(34, 34, 34); 510 }
511 .author-snapshot .well:not(.well.bg-default) { 512 background-color: rgb(255, 255, 255)!important; 513 border-color: rgb(238, 238, 238)!important; 514 color: rgb(34, 34, 34)!important; 515 } 516 .nav-tabs>li>a, .nav-pills>li>a { 517 font-weight: 600; 518 } 519 .module .help-inline,.module .help-block,.well .help-inline,.well .help-block,.account-form-box .help-inline,.account-form-box .help-block,.account-form-box p.account-tip{ 520 color: rgba(34, 34, 34,0.5); 521 } 522 #service_areas_table td,#service_areas_table_wrapper label, #service_areas_table_info, #service_areas_table_paginate > a { 523 color: rgb(34, 34, 34) !important; 524 } 525 .popover { 526 background-color: rgb(255, 255, 255); 527 border-color: rgb(255, 255, 255); 528 padding:0; 529 text-align:left; 530 } 531 .popover-title, .popover-content { 532 background-color: rgb(255, 255, 255); 533 color: rgb(34, 34, 34); 534 border-color: rgb(255, 255, 255); 535 text-align:left; 536 } 537 .popover-content { 538 background-color: rgba(34, 34, 34,.05); 539 border-radius: 4px; 540 transform: translate(-1px, -1px); 541 width: calc(100% + 2px); 542 margin-bottom: -2px; 543 } 544 .popover.left > .arrow::after { 545 border-left-color: rgb(255, 255, 255)!important; 546 } 547 .popover.right > .arrow::after { 548 border-right-color: rgb(255, 255, 255)!important; 549 } 550 .popover.bottom > .arrow::after { 551 border-bottom-color: rgb(255, 255, 255)!important; 552 } 553 .popover.top > .arrow::after { 554 border-top-color: rgb(255, 255, 255)!important; 555 } 556 .progress, .table-view .table-view-group:nth-child(2n-1),.tab-content .well, .tab-content .module,#account-tabs .well,#account-tabs .module,.account-form-box .module,.account-form-box .well,.module .module,.well .well,.module .well,.well .module{ 557 background-color: rgb(250, 250, 250); 558 color: rgb(34, 34, 34); 559 } 560 .module h1, .module h2, .module h3, .module h4, .module h5 { 561 color: rgb(34, 34, 34); 562 } 563 .module p:not(.fr-box.fr-basic .fr-element p) { 564 color: rgb(34, 34, 34); 565 } 566 .pagination>.active>a { 567 border-color: rgba(255, 255, 255,0.2); 568 } 569 .pagination>.active>a { 570 color: rgb(255, 255, 255); 571 } 572 .pagination > .active > a:hover, .pagination > .active > a:focus { 573 border-color: rgba(255, 255, 255,0.2); 574 background-color: rgb(3, 113, 102); 575 color: rgb(255, 255, 255); 576 } 577 .pagination > li > a { 578 color: rgb(3, 113, 102); 579 border-color: rgba(3, 113, 102,0.2); 580 background-color: rgb(255, 255, 255); 581 } 582 .pagination > li > a:focus, .pagination > li > a:hover, .pagination > li > span:focus, .pagination > li > span:hover { 583 background-color: rgb(3, 113, 102); 584 border-color: rgb(3, 113, 102); 585 color: rgb(255, 255, 255); 586 } 587 588 .nav-pills.nav-wizard > li a, .nav-pills.nav-wizard > li a:hover{ 589 background-color: rgb(246, 242, 213)!important; 590 color: rgb(41, 41, 41)!important; 591 } 592 .member_wizard2 li.incomplete a, .member_wizard2 li.incomplete a:hover { 593 background-color: rgb(255, 193, 7)!important; 594 border-color: rgb(255, 193, 7); 595 color: rgb(33, 33, 33); 596 } 597 .nav-pills.nav-wizard > li.active a, .nav-pills.member_wizard > li.active:hover a { 598 background-color: rgb(51, 122, 183)!important; 599 color: rgb(255, 255, 255)!important; 600 } 601 .member_wizard2 li.completed a, .member_wizard2 li.completed a:hover { 602 background-color: rgb(0, 150, 136)!important; 603 border-color: rgb(0, 150, 136); 604 color: rgb(255, 255, 255); 605 } 606 607 .nav-pills.nav-wizard > li.active .nav-arrow, .nav-pills.nav-wizard > li.active:hover .nav-arrow { 608 border-color: transparent transparent transparent rgb(51, 122, 183)!important; 609 } 610 .nav-pills.nav-wizard > li.active .nav-wedge, .nav-pills.nav-wizard > li.active:hover .nav-wedge{ 611 border-color: rgb(51, 122, 183) rgb(51, 122, 183) rgb(51, 122, 183) transparent!important; 612 } 613 614 li.completed .nav-wedge, .nav-pills.nav-wizard > li.completed:hover .nav-wedge { 615 border-color: rgb(42, 178, 123) rgb(42, 178, 123) rgb(42, 178, 123) transparent!important; 616 } 617 618 li.incomplete .nav-wedge, .nav-pills.nav-wizard > li.incomplete:hover .nav-wedge { 619 border-color: rgb(246, 242, 213) rgb(246, 242, 213) rgb(246, 242, 213) transparent!important; 620 } 621 622 .nav-pills.member_wizard > li.completed a, .nav-pills.member_wizard > li.completed a:hover { 623 background-color: rgb(42, 178, 123)!important; 624 color: rgb(255, 255, 255)!important; 625 } 626 627 .member_wizard2 li { 628 color: rgb(255, 255, 255); 629 border-right: 10px solid rgb(250, 250, 250); 630 } 631 632 li.completed .nav-arrow, .nav-pills.nav-wizard > li.completed:hover .nav-arrow { 633 border-color: transparent transparent transparent rgb(42, 178, 123)!important; 634 } 635 636 li.incomplete .nav-arrow, .nav-pills.nav-wizard > li.incomplete:hover .nav-arrow{ 637 border-color: transparent transparent transparent rgb(246, 242, 213)!important; 638 } 639 640 /* Default Colors */ 641 .btn-primary, .btn-primary.disabled, .btn-primary.disabled.active, .btn-primary.disabled.focus, .btn-primary.disabled:active, .btn-primary.disabled:focus, .btn-primary.disabled:hover, .btn-primary[disabled], .btn-primary[disabled].active, .btn-primary[disabled].focus, .btn-primary[disabled]:active, .btn-primary[disabled]:focus, .btn-primary[disabled]:hover, fieldset[disabled] .btn-primary, fieldset[disabled] .btn-primary.active, fieldset[disabled] .btn-primary.focus, fieldset[disabled] .btn-primary:active, fieldset[disabled] .btn-primary:focus, fieldset[disabled] .btn-primary:hover, .btn.dropdown-toggle.btn-primary,.navbar-default .navbar-nav > li > a.btn-primary, .navbar-default .navbar-nav > li > span.btn-primary,.mobile-main-menu .sidebar-nav li a.btn-primary, .mobile-main-menu .sidebar-nav li span.btn-primary { 642 background-color: rgb(3, 113, 102); 643 border-color: rgb(3, 113, 102); 644 color: rgb(255, 255, 255); 645 } 646 .btn-primary:hover, .btn-primary:focus, .btn-primary:active,.btn-primary:active:focus, .btn-primary:active:hover, .nav > li > a.btn-primary:focus, .nav > li > a.btn-primary:hover,.btn-primary.active,.open > .dropdown-toggle.btn-primary, .btn-primary.active.focus, .btn-primary.active:focus, .btn-primary.active:hover, .btn-primary:active.focus, .open>.dropdown-toggle.btn-primary:hover, .open>.dropdown-toggle.btn-primary:focus, .open>.dropdown-toggle.btn-primary.focus,a.bg-primary:focus,a.bg-primary:hover, .panel-primary .panel-heading, .btn.dropdown-toggle.btn-primary:hover,.upload-form-field,.upload-form-field:hover,.upload-form-field:active:focus,.upload-form-field:before, .label-primary[href]:focus, .label-primary[href]:hover { 647 background-color: rgba(3, 113, 102,0.95); 648 border-color: rgb(3, 113, 102); 649 color: rgb(255, 255, 255); 650 } 651 .panel-primary { 652 background-color: #d9eae8; 653 border-color: rgb(3, 113, 102); 654 } 655 .bg-primary,.progress-bar-primary,.module p.bg-primary,.label-primary,.badge-primary,.pricing_menu .title.bg-primary, .
655well .well.bg-primary, .module .well.bg-primary, .well .module.bg-primary,.tab-content .module.bg-primary,.tab-content .well.bg-primary { 656 background-color: rgb(3, 113, 102); 657 color: rgb(255, 255, 255); 658 } 659 .bg-primary .badge { 660 background-color:rgb(255, 255, 255); 661 color: rgb(3, 113, 102); 662 } 663 .btn-primary.btn-outline { 664 background: transparent; 665 color: rgb(3, 113, 102); 666 transition: all 250ms ease-in-out 0ms; 667 } 668 .btn-primary.btn-outline:hover { 669 background: rgba(3, 113, 102,0.1); 670 color: rgb(3, 113, 102); 671 } 672 .alert-primary { 673 background-color:rgba(3, 113, 102,0.7); 674 border-color:rgba(3, 113, 102,0.2); 675 color: rgba(255, 255, 255,0.9); 676 } 677 .alert-primary-subtle, .label-primary-subtle, .badge-primary-subtle { 678 background-color: #cde3e0; 679 border-color: #cde3e0; 680 color: rgb(3, 113, 102); 681 color: color-mix(in srgb, rgb(3, 113, 102) 50%, rgb(34, 34, 34) 50%); 682 } 683 .btn.dropdown-toggle.btn-primary *, .btn-primary a { 684 color: rgb(255, 255, 255); 685 } 686 .text-primary{ 687 color: rgb(3, 113, 102); 688 } 689 .btn-info, .btn-info.disabled, .btn-info.disabled.active, .btn-info.disabled.focus, .btn-info.disabled:active, .btn-info.disabled:focus, .btn-info.disabled:hover, .btn-info[disabled], .btn-info[disabled].active, .btn-info[disabled].focus, .btn-info[disabled]:active, .btn-info[disabled]:focus, .btn-info[disabled]:hover, fieldset[disabled] .btn-info, fieldset[disabled] .btn-info.active, fieldset[disabled] .btn-info.focus, fieldset[disabled] .btn-info:active, fieldset[disabled] .btn-info:focus, fieldset[disabled] .btn-info:hover, .btn.dropdown-toggle.btn-info,.navbar-default .navbar-nav > li > a.btn-info, .navbar-default .navbar-nav > li > span.btn-info,.mobile-main-menu .sidebar-nav li a.btn-info, .mobile-main-menu .sidebar-nav li span.btn-info { 690 background-color: rgb(3, 113, 102); 691 border-color: rgb(3, 113, 102); 692 color: rgb(255, 255, 255); 693 } 694 .btn-info:hover, .btn-info:focus, .btn-info:active,.btn-info:active:focus, .btn-info:active:hover, .nav > li > a.btn-info:focus, .nav > li > a.btn-info:hover,.btn-info.active,.open > .dropdown-toggle.btn-info, .btn-info.active.focus, .btn-info.active:focus, .btn-info.active:hover, .btn-info:active.focus, .open>.dropdown-toggle.btn-info:hover, .open>.dropdown-toggle.btn-info:focus, .open>.dropdown-toggle.btn-info.focus,a.bg-info:focus,a.bg-info:hover, .panel-info .panel-heading, .btn.dropdown-toggle.btn-info:hover, .label-info[href]:focus, .label-info[href]:hover { 695 background-color: rgba(3, 113, 102,0.95); 696 border-color: rgb(3, 113, 102); 697 color: rgb(255, 255, 255); 698 } 699 .panel-info { 700 background-color: #d9eae8; 701 border-color: rgb(3, 113, 102); 702 } 703 .bg-info,.progress-bar-info,.module p.bg-info,.label-info,.badge-info,.pricing_menu .title.bg-info, .well .well.bg-info, .module .well.bg-info, .well .module.bg-info,.tab-content .module.bg-info,.tab-content .well.bg-info { 704 background-color: rgb(3, 113, 102); 705 color: rgb(255, 255, 255); 706 } 707 .bg-info .badge { 708 background-color:rgb(255, 255, 255); 709 color: rgb(3, 113, 102); 710 } 711 .btn-info.btn-outline { 712 background: transparent; 713 color: rgb(3, 113, 102); 714 transition: all 250ms ease-in-out 0ms; 715 } 716 .btn-info.btn-outline:hover { 717 background: rgba(3, 113, 102,0.1); 718 color: rgb(3, 113, 102); 719 } 720 .alert-info { 721 background-color:rgba(3, 113, 102,0.7); 722 border-color:rgba(3, 113, 102,0.2); 723 color: rgba(255, 255, 255,0.9); 724 } 725 .alert-info-subtle, .label-info-subtle, .badge-info-subtle { 726 background-color: #cde3e0; 727 border-color: #cde3e0; 728 color: rgb(3, 113, 102); 729 color: color-mix(in srgb, rgb(3, 113, 102) 50%, rgb(34, 34, 34) 50%); 730 } 731 .btn.dropdown-toggle.btn-info *, .btn-info a { 732 color: rgb(255, 255, 255); 733 } 734 .text-info{ 735 color: rgb(3, 113, 102); 736 } 737 .btn-success, .btn-success.disabled, .btn-success.disabled.active, .btn-success.disabled.focus, .btn-success.disabled:active, .btn-success.disabled:focus, .btn-success.disabled:hover, .btn-success[disabled], .btn-success[disabled].active, .btn-success[disabled].focus, .btn-success[disabled]:active, .btn-success[disabled]:focus, .btn-success[disabled]:hover, fieldset[disabled] .btn-success, fieldset[disabled] .btn-success.active, fieldset[disabled] .btn-success.focus, fieldset[disabled] .btn-success:active, fieldset[disabled] .btn-success:focus, fieldset[disabled] .btn-success:hover, .btn.dropdown-toggle.btn-success,.navbar-default .navbar-nav > li > a.btn-success, .navbar-default .navbar-nav > li > span.btn-success,.mobile-main-menu .sidebar-nav li a.btn-success, .mobile-main-menu .sidebar-nav li span.btn-success { 738 background-color: rgb(0, 150, 136); 739 border-color: rgb(0, 150, 136); 740 color: rgb(255, 255, 255); 741 } 742 .btn-success:hover, .btn-success:focus, .btn-success:active,.btn-success:active:focus, .btn-success:active:hover, .nav > li > a.btn-success:focus, .nav > li > a.btn-success:hover,.btn-success.active,.open > .dropdown-toggle.btn-success, .btn-success.active.focus, .btn-success.active:focus, .btn-success.active:hover, .btn-success:active.focus, .open>.dropdown-toggle.btn-success:hover, .open>.dropdown-toggle.btn-success:focus, .open>.dropdown-toggle.btn-success.focus,a.bg-success:focus,a.bg-success:hover, .panel-success .panel-heading, .btn.dropdown-toggle.btn-success:hover, .label-success[href]:focus, .label-success[href]:hover { 743 background-color: rgba(0, 150, 136,0.95); 744 border-color: rgb(0, 150, 136); 745 color: rgb(255, 255, 255); 746 } 747 .panel-success { 748 background-color: #d9efed; 749 border-color: rgb(0, 150, 136); 750 } 751 .bg-success,.progress-bar-success,.module p.bg-success,.label-success,.badge-success,.pricing_menu .title.bg-success, .well .well.bg-success, .module .well.bg-success, .well .module.bg-success,.tab-content .module.bg-success,.tab-content .well.bg-success { 752 background-color: rgb(0, 150, 136); 753 color: rgb(255, 255, 255); 754 } 755 .bg-success .badge { 756 background-color: rgb(255, 255, 255); 757 color: rgb(0, 150, 136); 758 } 759 .btn-success.btn-outline { 760 background: transparent; 761 color: rgb(0, 150, 136); 762 transition: all 250ms ease-in-out 0ms; 763 } 764 .btn-success.btn-outline:hover { 765 background: rgba(0, 150, 136,0.1); 766 color: rgb(0, 150, 136); 767 } 768 .alert-success { 769 background-color:rgba(0, 150, 136,0.7); 770 border-color:rgba(0, 150, 136,0.2); 771 color: rgba(255, 255, 255,0.9); 772 } 773 .alert-success-subtle, .label-success-subtle, .badge-success-subtle { 774 background-color: #cceae7; 775 border-color: #cceae7; 776 color: rgb(0, 150, 136); 777 color: color-mix(in srgb, rgb(0, 150, 136) 50%, rgb(34, 34, 34) 50%); 778 } 779 .btn.dropdown-toggle.btn-success *, .btn-success a { 780 color: rgb(255, 255, 255); 781 } 782 .text-success{ 783 color: rgb(0, 150, 136); 784 } 785 .btn-warning, .btn-warning.disabled, .btn-warning.disabled.active, .btn-warning.disabled.focus, .btn-warning.disabled:active, .btn-warning.disabled:focus, .btn-warning.disabled:hover, .btn-warning[disabled], .btn-warning[disabled].active, .btn-warning[disabled].focus, .btn-warning[disabled]:active, .btn-warning[disabled]:focus, .btn-warning[disabled]:hover, fieldset[disabled] .btn-warning, fieldset[disabled] .btn-warning.active, fieldset[disabled] .btn-warning.focus, fieldset[disabled] .btn-warning:active, fieldset[disabled] .btn-warning:focus, fieldset[disabled] .btn-warning:hover, .btn.dropdown-toggle.btn-warning,.navbar-default .navbar-nav > li > a.btn-warning, .navbar-default .navbar-nav > li > span.btn-warning,.mobile-main-menu .sidebar-nav li a.btn-warning, .mobile-main-menu .sidebar-nav li span.btn-warning { 786 background-color: rgb(255, 193, 7); 787 border-color: rgb(255, 193, 7); 788 color: rgb(33, 33, 33); 789 } 790 .btn-warning:hover, .btn-warning:focus, .btn-warning:active,.btn-warning:active:focus, .btn-warning:active:hover, .nav > li > a.btn-warning:focus, .nav > li > a.btn-warning:hover,.btn-warning.active,.open > .dropdown-toggle.btn-warning, .btn-warning.active.focus, .btn-warning.active:focus, .btn-warning.active:hover, .btn-warning:active.focus, .open>.dropdown-toggle.btn-warning:hover, .open>.dropdown-toggle.btn-warning:focus, .open>.dropdown-toggle.btn-warning.focus,a.bg-warning:focus,a.bg-warning:hover, .panel-warning .panel-heading, .btn.dropdown-toggle.btn-warning:hover, .label-warning[href]:focus, .label-warning[href]:hover { 791 background-color: rgba(255, 193, 7,0.95); 792 border-color: rgb(255, 193, 7); 793 color: rgb(33, 33, 33); 794 } 795 .panel-warning { 796 background-color: #fff6da; 797 border-color: rgb(255, 193, 7); 798 } 799 .bg-warning,.progress-bar-warning,.module p.bg-warning,.label-warning,.badge-warning,.pricing_menu .title.bg-warning, .well .well.bg-warning, .module .well.bg-warning, .well .module.bg-warning,.tab-content .module.bg-warning,.tab-content .well.bg-warning { 800 background-color: rgb(255, 193, 7); 801 color: rgb(33, 33, 33); 802 } 803 .bg-warning .badge { 804 background-color: rgb(33, 33, 33); 805 color: rgb(255, 193, 7); 806 } 807 .btn-warning.btn-outline { 808 background: transparent; 809 color: rgb(255, 193, 7); 810 transition: all 250ms ease-in-out 0ms; 811 } 812 .btn-warning.btn-outline:hover { 813 background: rgba(255, 193, 7,0.1); 814 color: rgb(255, 193, 7); 815 } 816 .alert-warning { 817 background-color:rgba(255, 193, 7,0.7); 818 border-color:rgba(255, 193, 7,0.2); 819 color: rgba(33, 33, 33,0.9); 820 } 821 .alert-warning-subtle, .label-warning-subtle, .badge-warning-subtle { 822 background-color: #fff3cd; 823 border-color: #fff3cd; 824 color: rgb(255, 193, 7); 825 color: color-mix(in srgb, rgb(255, 193, 7) 50%, rgb(34, 34, 34) 50%); 826 } 827 .btn.dropdown-toggle.btn-warning *, .btn-warning a { 828 color: rgb(33, 33, 33); 829 } 830 .text-warning { 831 color: rgb(255, 193, 7); 832 } 833 .btn-danger, .btn-danger.disabled, .btn-danger.disabled.active, .btn-danger.disabled.focus, .btn-danger.disabled:active, .btn-danger.disabled:focus, .btn-danger.disabled:hover, .btn-danger[disabled], .btn-danger[disabled].active, .btn-danger[disabled].focus, .btn-danger[disabled]:active, .btn-danger[disabled]:focus, .btn-danger[disabled]:hover, fieldset[disabled] .btn-danger, fieldset[disabled] .btn-danger.active, fieldset[disabled] .btn-danger.focus, fieldset[disabled] .btn-danger:active, fieldset[disabled] .btn-danger:focus, fieldset[disabled] .btn-danger:hover, .btn.dropdown-toggle.btn-danger,.navbar-default .navbar-nav > li > a.btn-danger, .navbar-default .navbar-nav > li > span.btn-danger,.mobile-main-menu .sidebar-nav li a.btn-danger, .mobile-main-menu .sidebar-nav li span.btn-danger { 834 background-color: rgb(244, 67, 54); 835 border-color: rgb(244, 67, 54); 836 color: rgb(255, 255, 255); 837 } 838 .btn-danger:hover, .btn-danger:focus, .btn-danger:active,.btn-danger:active:focus, .btn-danger:active:hover, .nav > li > a.btn-danger:focus, .nav > li > a.btn-danger:hover,.btn-danger.active,.open > .dropdown-toggle.btn-danger, .btn-danger.active.focus, .btn-danger.active:focus, .btn-danger.active:hover, .btn-danger:active.focus, .open>.dropdown-toggle.btn-danger:hover, .open>.dropdown-toggle.btn-danger:focus, .open>.dropdown-toggle.btn-danger.focus,a.bg-danger:focus,a.bg-danger:hover, .panel-danger .panel-heading, .btn.dropdown-toggle.btn-danger:hover, .label-danger[href]:focus, .label-danger[href]:hover { 839 background-color: rgba(244, 67, 54,0.95); 840 border-color: rgb(244, 67, 54); 841 color: rgb(255, 255, 255); 842 } 843 .has-error .form-control { 844 border-color: rgb(244, 67, 54); 845 } 846 .has-error .help-block:not(.form-field-help-block), .has-error ~ .help-block:not(.form-field-help-block),.has-error .help-block:not(.form-field-help-block) a, .has-error ~ .help-block:not(.form-field-help-block) a { 847 background: rgb(244, 67, 54); 848 color: rgb(255, 255, 255) !important; 849 } 850 .has-error .checkbox, .has-error .checkbox-inline, .has-error .control-label, .has-error .help-block, .has-error .radio, .has-error .radio-inline, .has-error.checkbox label, .has-error.checkbox-inline label, .has-error.radio label, .has-error.radio-inline label { 851 color: rgb(244, 67, 54); 852 } 853 .panel-danger { 854 background-color: #fde3e1; 855 border-color: rgb(244, 67, 54); 856 } 857 .bg-danger,.progress-bar-danger,.module p.bg-danger,.label-danger,.badge-danger,.pricing_menu .title.bg-danger, .well .well.bg-danger, .module .well.bg-danger, .well .module.bg-danger,.tab-content .module.bg-danger,.tab-content .well.bg-danger { 858 background-color: rgb(244, 67, 54); 859 color: rgb(255, 255, 255); 860 } 861 .bg-danger .badge { 862 background-color: rgb(255, 255, 255); 863 color: rgb(244, 67, 54); 864 } 865 .btn-danger.btn-outline { 866 background: transparent; 867 color: rgb(244, 67, 54); 868 transition: all 250ms ease-in-out 0ms; 869 } 870 .btn-danger.btn-outline:hover { 871 background: rgba(244, 67, 54,0.1); 872 color: rgb(244, 67, 54); 873 } 874 .alert-danger { 875 background-color:rgba(244, 67, 54,0.7); 876 border-color:rgba(244, 67, 54,0.2); 877 color: rgba(255, 255, 255,0.9); 878 } 879 .alert-danger-subtle, .label-danger-subtle, .badge-danger-subtle { 880 background-color: #fdd9d7; 881 border-color: #fdd9d7; 882 color: rgb(244, 67, 54); 883 color: color-mix(in srgb, rgb(244, 67, 54) 50%, rgb(34, 34, 34) 50%); 884 } 885 .btn.dropdown-toggle.btn-danger *, .btn-danger a { 886 color: rgb(255, 255, 255); 887 } 888 .text-danger{ 889 color: rgb(244, 67, 54); 890 } 891 .btn-default, .tags a, .btn-default.disabled, .btn-default.disabled.active, .btn-default.disabled.focus, .btn-default.disabled:active, .btn-default.disabled:focus, .btn-default.disabled:hover, .btn-default[disabled], .btn-default[disabled].active, .btn-default[disabled].focus, .btn-default[disabled]:active, .btn-default[disabled]:focus, .btn-default[disabled]:hover, fieldset[disabled] .btn-default, fieldset[disabled] .btn-default.active, fieldset[disabled] .btn-default.focu
891s, fieldset[disabled] .btn-default:active, fieldset[disabled] .btn-default:focus, fieldset[disabled] .btn-default:hover, .btn.dropdown-toggle.btn-default, #popover .mini_profile_pic,.navbar-default .navbar-nav > li > a.btn-default, .navbar-default .navbar-nav > li > span.btn-default,.mobile-main-menu .sidebar-nav li a.btn-default, .mobile-main-menu .sidebar-nav li span.btn-default { 892 background-color: rgb(224, 224, 224); 893 border-color: rgb(224, 224, 224); 894 color: rgb(66, 66, 66); 895 } 896 .btn-default:hover, .btn-default:focus, .btn-default:active,.btn-default:active:focus, .btn-default:active:hover,.tags a:hover, .nav > li > a.btn-default:focus, .nav > li > a.btn-default:hover,.btn-default.active,.open > .dropdown-toggle.btn-default, .btn-default.active.focus, .btn-default.active:focus, .btn-default.active:hover, .btn-default:active.focus, .open>.dropdown-toggle.btn-default:hover, .open>.dropdown-toggle.btn-default:focus, .open>.dropdown-toggle.btn-default.focus,a.bg-default:focus,a.bg-default:hover, .panel-default .panel-heading, .member_accounts .panel-default > .panel-heading, .panel-default.categories-panel .panel-heading, .btn.dropdown-toggle.btn-default:hover, #popover .mini_profile_pic, .label-default[href]:focus, .label-default[href]:hover { 897 background-color: rgba(224, 224, 224,0.95); 898 border-color: rgb(224, 224, 224); 899 color: rgb(66, 66, 66); 900 } 901 .sidemenu_panel .panel-default .panel_heading { 902 background-color: rgb(224, 224, 224)!important; 903 border-color: rgb(224, 224, 224)!important; 904 color: rgb(66, 66, 66)!important; 905 } 906 .panel-default .panel-heading, .member_accounts .panel-default > .panel-heading, .panel-default.categories-panel .panel-heading { 907 908 box-shadow: 0 0 1000px 0 rgba(66, 66, 66,0.02) inset; 909 background-color: rgb(224, 224, 224); 910 } 911 .panel-default, .member_accounts .panel-default { 912 913 background-color: rgba(224, 224, 224,0.15); 914 border-color: #fcfcfc; 915 border-color: color-mix(in srgb,rgb(224, 224, 224) 100%,rgba(224, 224, 224) 10%); 916 } 917 .member_admin_sidemenu .panel-default { 918 background-color: transparent; 919 } 920 .bg-default,.progress-bar-default,.module p.bg-default,.label-default,.badge-default,.pricing_menu .title.bg-default, .well .well.bg-default, .module .well.bg-default, .well .module.bg-default,.tab-content .module.bg-default,.tab-content .well.bg-default { 921 background-color: rgb(224, 224, 224); 922 color: rgb(66, 66, 66); 923 } 924 .bg-default .badge { 925 background-color: rgb(66, 66, 66); 926 color: rgb(224, 224, 224); 927 } 928 .btn-default.btn-outline { 929 background: transparent; 930 color: rgb(224, 224, 224); 931 transition: all 250ms ease-in-out 0ms; 932 } 933 .btn-default.btn-outline:hover { 934 background: rgba(224, 224, 224,0.1); 935 color: rgb(224, 224, 224); 936 } 937 .alert-default { 938 background-color:rgb(224, 224, 224); 939 border-color:rgb(224, 224, 224); 940 color: rgb(66, 66, 66); 941 } 942 .alert-default-subtle, .label-default-subtle, .badge-default-subtle { 943 background-color:rgba(224, 224, 224,0.5); 944 border-color: rgba(224, 224, 224,0.5); 945 color: rgb(66, 66, 66); 946 color: color-mix(in srgb, rgb(66, 66, 66) 50%, rgb(34, 34, 34) 50%); 947 } 948 .btn.dropdown-toggle.btn-default *, .btn-default a { 949 color: rgb(66, 66, 66); 950 } 951 .text-default{ 952 color: rgb(224, 224, 224); 953 } 954 .btn-secondary, .btn.dropdown-toggle.btn-secondary,.navbar-default .navbar-nav > li > a.btn-secondary, .navbar-default .navbar-nav > li > span.btn-secondary,.mobile-main-menu .sidebar-nav li a.btn-secondary, .mobile-main-menu .sidebar-nav li span.btn-secondary { 955 background-color: rgb(34, 34, 34); 956 border: 1px solid rgb(34, 34, 34); 957 color: rgb(250, 250, 250); 958 } 959 .btn-secondary:hover, .btn-secondary:focus, .btn-secondary:active,.btn-secondary:active:focus, .btn-secondary:active:hover, .nav > li > a.btn-secondary:focus, .nav > li > a.btn-secondary:hover,.btn-secondary.active,.open > .dropdown-toggle.btn-secondary, .btn-secondary.active.focus, .btn-secondary.active:focus, .btn-secondary.active:hover, .btn-secondary:active.focus, .open>.dropdown-toggle.btn-secondary:hover, .open>.dropdown-toggle.btn-secondary:focus, .open>.dropdown-toggle.btn-secondary.focus,a.bg-secondary:focus,a.bg-secondary:hover,.btn.dropdown-toggle.btn-secondary:hover, .panel-secondary .panel-heading, .label-secondary[href]:focus, .label-secondary[href]:hover { 960 background-color: rgba(34, 34, 34,0.95); 961 border-color: rgb(34, 34, 34); 962 color: rgb(250, 250, 250); 963 } 964 .bg-secondary,.progress-bar-secondary,.module p.bg-secondary,.module p.bg-secondary:not(.fr-box.fr-basic .fr-element p),.label-secondary,.badge-secondary,.pricing_menu .title.bg-secondary, .well .well.bg-secondary, .module .well.bg-secondary, .well .module.bg-secondary,.tab-content .module.bg-secondary,.tab-content .well.bg-secondary { 965 background-color: rgb(34, 34, 34); 966 color: rgb(250, 250, 250); 967 } 968 .bg-secondary .badge { 969 background-color:rgb(250, 250, 250); 970 color: rgb(34, 34, 34); 971 } 972 .btn-secondary.btn-outline { 973 background: transparent; 974 color: rgb(34, 34, 34); 975 transition: all 250ms ease-in-out 0ms; 976 } 977 .btn-secondary.btn-outline:hover { 978 background: rgba(34, 34, 34,0.1); 979 color: rgb(34, 34, 34); 980 } 981 .panel-secondary { 982 background-color: #dedede; 983 border-color: rgb(34, 34, 34); 984 } 985 .alert-secondary { 986 background-color:rgb(34, 34, 34); 987 border-color:rgb(34, 34, 34); 988 color: rgb(250, 250, 250); 989 } 990 .alert-secondary-subtle, .label-secondary-subtle, .badge-secondary-subtle { 991 background-color:rgba(34, 34, 34,0.8); 992 border-color: rgba(34, 34, 34,0.5);
993 color: rgb(250, 250, 250); 994 } 995 .btn-outline { 996 -webkit-backdrop-filter: blur(5px); 997 backdrop-filter: blur(5px); 998 } 999 .btn-body, .btn-body.disabled, .btn-body.disabled.active, .btn-body.disabled.focus, .btn-body.disabled:active, .btn-body.disabled:focus, .btn-body.disabled:hover, .btn-body[disabled], .btn-body[disabled].active, .btn-body[disabled].focus, .btn-body[disabled]:active, .btn-body[disabled]:focus, .btn-body[disabled]:hover, fieldset[disabled] .btn-body, fieldset[disabled] .btn-body.active, fieldset[disabled] .btn-body.focus, fieldset[disabled] .btn-body:active, fieldset[disabled] .btn-body:focus, fieldset[disabled] .btn-body:hover, .btn.dropdown-toggle.btn-body,.navbar-default .navbar-nav > li > a.btn-body, .navbar-default .navbar-nav > li > span.btn-body,.mobile-main-menu .sidebar-nav li a.btn-body, .mobile-main-menu .sidebar-nav li span.btn-body { 1000 background-color: rgb(250, 250, 250); 1001 border: 1px solid rgb(250, 250, 250); 1002 color: rgb(34, 34, 34); 1003 } 1004 .btn-body:hover, .btn-body:focus, .btn-body:active,.btn-body:active:focus, .btn-body:active:hover, .nav > li > a.btn-body:focus, .nav > li > a.btn-body:hover,.btn-body.active,.open > .dropdown-toggle.btn-body, .btn-body.active.focus, .btn-body.active:focus, .btn-body.active:hover, .btn-body:active.focus, .open>.dropdown-toggle.btn-body:hover, .open>.dropdown-toggle.btn-body:focus, .open>.dropdown-toggle.btn-body.focus,a.bg-body:focus,a.bg-body:hover, .panel-body .panel-heading, .btn.dropdown-toggle.btn-body:hover, .label-body[href]:focus, .label-body[href]:hover { 1005 background-color: rgba(250, 250, 250,0.95); 1006 border: 1px solid rgb(250, 250, 250); 1007 color: rgb(34, 34, 34); 1008 } 1009 .btn.btn-body.dropdown-toggle * { 1010 color: rgb(34, 34, 34) 1011 } 1012 .btn-body.dropdown-toggle + ul li, .daterangepicker .ranges { 1013 color: #333; 1014 } 1015 .bg-body { 1016 background: rgb(250, 250, 250); 1017 color: rgb(34, 34, 34); 1018 } 1019 .bg-content-box { 1020 background: rgb(255, 255, 255); 1021 color: rgb(34, 34, 34); 1022 } 1023 .bg-content-box-border { 1024 background: rgb(238, 238, 238); 1025 } 1026 .btn.dropdown-toggle.btn-secondary *, .btn-secondary a { 1027 color: rgb(250, 250, 250); 1028 } 1029 .text-secondary { 1030 color: rgb(34, 34, 34); 1031 } 1032 .text-body { 1033 color: rgb(250, 250, 250); 1034 } 1035 .feature-post #post-content .alert-secondary.btn-block, .feature-search .img_section .alert-secondary.btn-block, .search_result .img_section .alert-secondary { 1036 border-radius: 10px; 1037 background-color: rgba(41, 41, 41,0.2); 1038 } 1039 1040 /* Footer Newsletter Row */ 1041 .newsletter_row .alert { 1042 color: rgb(255, 255, 255); 1043 } 1044 .newsletter_row { 1045 background-color: rgb(255, 255, 255); 1046 color: rgb(255, 255, 255); 1047 } 1048 .newsletter_row input[type="submit"],.newsletter_footer_button { 1049 background-color: rgba(0, 150, 136,0.97); 1050 color: rgb(255, 255, 255); 1051 border-color: rgb(0, 150, 136); 1052 } 1053 .newsletter_row input[type="submit"]:hover,.newsletter_row input[type="submit"]:focus,.newsletter_footer_button:hover,.newsletter_footer_button:focus { 1054 background-color: rgb(0, 150, 136); 1055 color: rgb(255, 255, 255); 1056 } 1057 .newsletter_button_left { 1058 border-right: 1px solid rgba(255, 255, 255,0.2); 1059 } 1060 .newsletter_button_right { 1061 border-left: 1px solid rgba(255, 255, 255,0.2); 1062 } 1063 .newsletter_row small.help-block { 1064 background: rgb(255, 255, 255); 1065 margin-top: -5px; 1066 float: left; 1067 padding: 8px; 1068 border-radius: 1px; 1069 color: rgb(255, 255, 255); 1070 text-transform: capitalize; 1071 } 1072 .newsletter_row .has-success .checkbox,.newsletter_row .has-error .checkbox{ 1073 color: rgb(255, 255, 255); 1074 } 1075 @media only screen and (max-width: 767px) { 1076 .newsletter_button_right,.newsletter_button_left{ 1077 border: none; 1078 margin: 5px 0; 1079 } 1080 } 1081 1082 /* Font Sizes */ 1083 1084 .navbar-default .navbar-nav > li > a, .navbar-default .navbar-nav > li > span { 1085 font-size: 16px; 1086 } 1087 .header .logo { 1088 font-size: 36px; 1089 } 1090 .homepage_title h1, .homepage_settings h1 { 1091 letter-spacing: -1px; 1092 font-size: 70px; 1093 margin-bottom: 30px; 1094 } 1095 @media only screen and (max-width: 768px) { 1096 .homepage_title h1, .homepage_settings h1 {margin-bottom: 15px;} 1097 } 1098 .homepage_settings h2 { 1099 font-size: 28px; 1100 } 1101 1102 .ui-rangeSlider-bar{ 1103 background: rgb(0, 150, 136)!important; 1104 } 1105 1106 1107 1108 @media only screen and (max-width: 1024px){ 1109 .modal {margin-top: 40px;} 1110 } 1111 @media only screen and (max-width: 768px){ 1112 .modal {margin-top: 60px;} 1113 } 1114 1115 /* Calendar Styles */ 1116 1117 #cal-slide-content { 1118 color: rgb(66, 66, 66)!important; 1119 background-color: rgb(224, 224, 224)!important; 1120 -webkit-box-shadow: none!important; 1121 box-shadow: none!important; 1122 } 1123 #cal-slide-content a.event-item { 1124 color: rgb(66, 66, 66)!important; 1125 font-weight:bold!important; 1126 } 1127 #cal-slide-content a.event-item small { 1128 display: inline-block; 1129 } 1130 .cal-month-box, .cal-year-box, .cal-week-box { 1131 border: 1px solid rgb(238, 238, 238)!important; 1132 } 1133 .cal-year-box .row-fluid, .cal-month-box .cal-row-fluid { 1134 border-bottom: 1px solid rgb(238, 238, 238)!important; 1135 } 1136 .cal-year-box [class*="span"], .cal-month-box [class*="cal-cell"] { 1137 border-right: 1px solid rgb(238, 238, 238)!important; 1138 } 1139 .cal-year-box .row-fluid, .cal-row-fluid, #cal-day-box .cal-day-hour:nth-child(odd) { 1140 background-color: rgb(250, 250, 250)!important; 1141 } 1142 .cal-month-day span:not(.pull-right):not(.events-count-label):not(.events-label) { 1143 color: rgb(66, 66, 66)!important; 1144 } 1145 .cal-day-today span[data-cal-date] { 1146 color: rgb(34, 34, 34)!important; 1147 } 1148 .cal-year-box .row-fluid [class*="span"]:last-child, .cal-month-box .cal-row-fluid [class*="cal-cell"]:last-child { 1149 border: 0!important; 1150 } 1151 .cal-row-head { 1152 background: rgb(255, 255, 255)!important; 1153 } 1154 .day-highlight:hover, .day-highlight { 1155 background-color: rgb(238, 238, 238)!important; 1156 } 1157 .cal-event-list .event.pull-left { 1158 background-color: rgb(34, 34, 34)!important; 1159 opacity: 0.4; 1160 margin-top: 7px!important; 1161 } 1162 .cal-day-today { 1163 background-color: rgb(238, 238, 238)!important; 1164 } 1165 #cal-day-tick { 1166 border: 1px solid rgb(238, 238, 238)!important; 1167 background-color: rgb(238, 238, 238)!important; 1168 } 1169 .cal-day-weekend span[data-cal-date]{
1170 color: rgb(34, 34, 34)!important; 1171 } 1172 .rsDefault, .rsDefault .rsOverflow, .rsDefault .rsSlide, .rsDefault .rsVideoFrameHolder, .rsDefault .rsThumbs { 1173 border-radius: 10px; 1174 background: #151515!important; 1175 } 1176 .img_section .no-radius-bottom + .alert-secondary .rsDefault .rsSlide, .img_section .no-radius-bottom + .alert-secondary .rsDefault .rsOverflow { 1177 border-radius:0; 1178 } 1179 1180 #first_container .favorite, #first_container .fa.favorite { 1181 color: rgb(170, 184, 194); 1182 background: rgb(224, 224, 224); 1183 border: 1px solid rgb(224, 224, 224); 1184 white-space:nowrap!important; 1185 height:24px; 1186 padding:0 6px; 1187 border-radius:8px; 1188 } 1189 #first_container .favorite span, #first_container .fa.favorite span { 1190 font-family: 'Open Sans'; 1191 white-space:nowrap!important; 1192 } 1193 #first_container .favoriteActive:not(.favorite.comments-count-badge), #first_container .fa.favoriteActive:not(.favorite.comments-count-badge .fa) { 1194 color: rgb(208, 89, 114); 1195 } 1196 #first_container .favorite::after, #first_container .fa.favorite::after { 1197 font-family: 'Open Sans'; 1198 margin-left: 3px; 1199 } 1200 #first_container .favorite span, #first_container .fa.favorite span{ 1201 padding-left: 4px; 1202 font-family: 'Open Sans'; 1203 font-size: 11px; 1204 letter-spacing:.5px; 1205 top:-1px; 1206 position:relative; 1207 font-weight:700; 1208 } 1209 #first_container .favorite span:empty, #first_container .fa.favorite span:empty { 1210 padding: 0; 1211 } 1212 #first_container .favorite .bookmark-number, #first_container .fa.favorite .bookmark-number { 1213 padding: 1px 0; 1214 border-radius: 100px; 1215 display: inline-block; 1216 font-weight: bold; 1217 min-width: 15px; 1218 font-size: .8em; 1219 vertical-align: bottom; 1220 height: 15px; 1221 line-height: 13px; 1222 margin-left: 3px; 1223 text-align: center; 1224 } 1225 #first_container .favorite.favoriteActive .bookmark-number:not(.comments-count-badge .bookmark-number), #first_container .fa.favorite.favoriteActive .bookmark-number { 1226 background: rgb(208, 89, 114); 1227 color: #fff; 1228 } 1229 1230 span.checkbox_value::after { 1231 content: ', '; 1232 } 1233 1234 span.checkbox_value:last-child::after { 1235 content: ''; 1236 } 1237 #first_container .member-profile-tabs .profile-tabs-nav { 1238 overflow-x: auto; 1239 overflow-y: hidden; 1240 display: flex; 1241 flex-direction: row 1242 } 1243 1244 #first_container .member-profile-tabs .profile-tabs-nav > li * { 1245 white-space: nowrap !important 1246 } 1247 1248 .member-profile-tabs .profile-tabs-nav::-webkit-scrollbar { 1249 display: none 1250 } 1251 1252 .member-profile-tabs .profile-tabs-nav { 1253 scrollbar-width: none 1254 } 1255 1256 .member-profile-tabs .tabs-container { 1257 display: flex; 1258 align-items: center; 1259 border-radius:8px 8px 0 0; 1260 } 1261 .member-profile-tabs .tabs-container > ul { 1262 border: none; 1263 } 1264 .member-profile-tabs .scroll-arrow { 1265 display: none; 1266 cursor: pointer; 1267 z-index: 2; 1268 padding: 0 15px; 1269 background-color: rgb(224, 224, 224); 1270 color: rgb(66, 66, 66); 1271 height: 41px; 1272 line-height: 42px; 1273 margin-top: 2px; 1274 margin-left: 5px; 1275 border-radius:4px; 1276 } 1277 1278 .member-profile-tabs .scroll-arrow.left-arrow { 1279 margin-right: -6px; 1280 } 1281 1282 .member-profile-tabs .scroll-arrow.right-arrow { 1283 margin-left: -10px; 1284 margin-right: 5px; 1285 } 1286 1287 1288 1289 1290 /* Homepage Sections Background Color Logic */ 1291 1292 1293 .homepage-section-1 { 1294 padding: 40px 0 40px; 1295 } 1296 1297 1298 .homepage-section-2 { 1299 padding: 40px 0 40px; 1300 } 1301 1302 1303 .homepage-section-3 { 1304 padding: 40px 0 40px; 1305 } 1306 1307 1308 .homepage-section-4 { 1309 padding: 0px 0 0px; 1310 } 1311 1312 1313 .homepage-section-5 { 1314 padding: 90px 0 90px; 1315 } 1316 1317 1318 .homepage-section-6 { 1319 padding: 40px 0 40px; 1320 } 1321 1322 1323 .homepage-section-7 { 1324 padding: 40px 0 40px; 1325 } 1326 1327 1328 .homepage-section-8 { 1329 padding: 40px 0 40px; 1330 } 1331 1332 1333 .homepage-section-9 { 1334 padding: 40px 0 40px; 1335 } 1336 1337 1338 .homepage-section-10 { 1339 padding: 40px 0 40px; 1340 } 1341 1342 1343 .homepage-section-11 { 1344 padding: 40px 0 40px; 1345 } 1346 1347 1348 .homepage-section-12 { 1349 padding: 40px 0 40px; 1350 } 1351 1352 1353 .homepage-section-13 { 1354 padding: 40px 0 40px; 1355 } 1356 1357 1358 .homepage-section-14 { 1359 padding: 40px 0 40px; 1360 } 1361 1362 1363 .homepage-section-15 { 1364 padding: 40px 0 40px; 1365 } 1366 1367 1368 /* Additional Settings */ 1369 1370 1371 /* Streaming Widgets Title Settings */ 1372 1373 .streaming-title { 1374 text-align: center; 1375 font-size: 48px; 1376 line-height:1.5em; 1377 font-weight: 300; 1378 font-family: 'Quicksand'; 1379 padding-bottom: 60px; 1380 } 1381 1382 @media only screen and (max-width: 990px) { 1383 .streaming-title { 1384 line-height:1.1em; 1385 } 1386 } 1387 1388 .streaming-title + hr { 1389 display: none; 1390 } 1391 1392 .homepage-join-module .module h2:first-of-type { 1393 color: rgb(62, 62, 62); 1394 } 1395 1396 .homepage-join-module .module{ 1397 background: rgb(250, 250, 250); 1398 border-color: rgb(238, 238, 238); 1399 } 1400 1401 .homepage-about-module .module h2:first-of-type { 1402 color: rgb(62, 62, 62); 1403 } 1404 1405 .homepage-about-module .module{ 1406 background: rgb(250, 250, 250); 1407 border-color: rgb(238, 238, 238); 1408 1409 } 1410 1411 .the-post-description > :is(h2, h3, h4, h5):not(:first-child) { 1412 font-weight: 600; 1413 margin-top: 20px; 1414 } 1415 1416 /* Keep: Ensure ul/ol respect padding and margins */ 1417 .the-post-description > :is(ul, ol) { 1418 display: flow-root; 1419 } 1420 .the-post-description li { 1421 margin-bottom: 8px; 1422 } 1423
1424 .btn:not(#refcode_submit):not(.input-group-btn .btn):not(.logo-preview-input):not(.cover-preview-input):not(.member_login):not(.img-circle):not(.submit_reply):not(.submit_comment):not(.view-more):not(.image-preview-input):not(.no-radius-bottom):not(.no-radius-top):not(.btn-facebook), .btn-sm:not(.img-circle):not(.view-more):not(.image-preview-input):not(.no-radius-bottom):not(.no-radius-top), .btn-xs:not(.img-circle):not(.view-more):not(.image-preview-input):not(.no-radius-bottom):not(.no-radius-top), button:not(.social_share_buttons button):not(.social_share_buttons a):not(#refcode_submit):not(.input-group-btn button), .btn-group-lg > .btn, .btn-lg, .btn-lg, .btn-xl, .input-group-sm > .input-group-btn > .btn, .favorite, .tags a, select#sid.input-lg, select#tid.input-lg, select#ttid.input-lg, select.combobox.input-lg, select#bd-chained.input-lg, select#category-chained.input-lg, select.infinite-chained.input-lg, select.subcategory-chained.input-lg, select.search-chained.input-lg, select#country-chained.input-lg, select#state-chained.input-lg, select#country-chained-2.input-lg, select#state-chained-2.input-lg, select#profession_id.input-lg, [name^="bd_phone_country_code"].input-lg, select.input-lg, select#sid, select#tid, select#ttid, select.combobox, select#bd-chained, select#category-chained, select.infinite-chained, select.subcategory-chained, select.search-chained, select#country-chained, select#state-chained, select#country-chained-2, select#state-chained-2, select#profession_id, [name^="bd_phone_country_code"] { 1425 border-radius: 100px!important; 1426 } 1427 1428 .write_comment_container, .tab-content, .well:not(.well .well):not(.module .well):not(.tab-content .well):not(.well.make-connection):not(.slick-slide .well), .module:not(.module .module):not(.well .module):not(.tab-content .module):not(.search_box .module):not(.posted-by-snippet), .panel, .pic:not(.slick-slide .pic), .member_accounts > .account-form-box { 1429 box-shadow: 0 8px 8px -4px #0000001a,0 4px 4px -4px #0000001a; 1430 } 1431 1432 .img-circle, .img-rounded.img-circle, .img-circle img, .img-rounded.img-circle img, img.fr-dib.img-circle, img.fr-dib.img-rounded.img-circle { 1433 border-radius:1000px!important; 1434 } 1435 1436 .img-rounded img, img.fr-dib.img-rounded{ 1437 border-radius: 10px!important; 1438 } 1439 1440 /* Google Translate Module */ 1441 .skiptranslate{font-size:0} 1442 .goog-te-gadget-simple{border:1px solid #ccc;border-radius:4px;box-shadow:0 1px 1px rgba(0,0,0,0.075) inset;color:#555} 1443 .skiptranslate.goog-te-gadget span,img.goog-te-gadget-icon{display:none!important} 1444 .goog-te-gadget .goog-te-combo{margin-bottom:-4px} 1445 .skiptranslate.goog-te-gadget select{border:1px solid #ddd;border-radius:3px;font-size:12px;padding:2px 4px;width:100%;background:#fff;margin:0;height:30px;line-height:30px;display:block;color:#555;box-shadow:inset 0 1px 1px rgba(0,0,0,.075)} 1446 @media only screen and (max-width: 1100px) { 1447 .skiptranslate:not(.skiptranslate[style="display: none;"]){height:39px} 1448 .skiptranslate:not(.skiptranslate[style="display: none;"]) ~ .header{margin-top:10px!important} 1449 .skiptranslate:not(.skiptranslate[style="display: none;"]) ~ .announcement-bar{margin-top:10px} 1450 .skiptranslate:not(.skiptranslate[style="display: none;"]) ~ .announcement-bar ~ .header{margin-top:0!important} 1451 .skiptranslate:not(.skiptranslate[style="display: none;"]) ~ .header .mobile-main-menu{top:89px!important;height:calc(100% - 90px)!important} 1452 .skiptranslate:not(.skiptranslate[style="display: none;"]) ~ .header .navbar{top:39px} 1453 .skiptranslate:not(.skiptranslate[style="display: none;"]) ~ #first_container .member_sidebar.open{top: 89px;} 1454 } 1455 @media only screen and (max-width: 767px) { 1456 .skiptranslate:not(.skiptranslate[style="display: none;"]) ~ .announcement-bar.hidden-xs ~ .header{margin-top:10px!important} 1457 } 1458 1459 1460 1461</style> 1462 1463<!--GOOGLE TAG MANAGER CODE--> <!-- ON-PAGE CSS FUNCTIONS --> 1464 <style type="text/css"> 1465 .btn-info{ 1466 border-color: rgb(3,113,102) !important; 1467} </style> 1468 <div class="header"> 1469 <div class="container"> 1470 <div class="row header-main-row"> 1471 <style type='text/css'> .logo-text:has(.logo_title:empty) { 1472 display:none 1473} </style><div id="website_logo" class="col-md-5 xs-nopad xs-hpad sm-text-center xs-bmargin header-left-container"> 1474 1475 <a class="logo logo-text center-block vpad sm-nopad sm-tmargin" title="Retaining Wall Expert" href="https://www.retainingwallexpert.com"> 1476 <i class="fa fa-etsy pull-left hidden-sm hidden-xs bmargin"></i>
1477 <span class="logo_title">Retaining Wall Expert</span> 1478 <span class="line-height-xl slogan">Retaining Wall Information From Retaining Wall Experts</span> 1479 </a> 1480 <div class="clearfix"></div> 1481</div> 1482 <style type='text/css'> body input.tt-hint,body input.form-control.normal-autosuggest-input.tt-query { 1483 background-color: white !important; 1484} 1485.mini-nav:not(:has(li)) { 1486 display: none!important; 1487} 1488/* Parent Container - Main List */ 1489.mini-nav li:has(ul) { 1490 position: relative; 1491 border-radius: 8px 8px 0 0; 1492} 1493.mini-nav > li:has(ul) { 1494 padding-left: 0; 1495 padding-right: 0; 1496 background: rgb(250, 250, 250); 1497} 1498.mini-nav > li:has(ul) > a:not(.btn), .mini-nav > li:has(ul) > span { 1499 padding: 10px 15px; 1500 margin: 0!important; 1501} 1502.mini-nav > li:hover:has(ul), .mini-nav > li:hover:has(ul) { 1503 box-shadow: 0 -1px 3px rgba(34, 34, 34,0.25); 1504} 1505/* Parent Links */ 1506.mini-nav > li > a:not(.btn), .mini-nav > li > span:not(.btn) { 1507 display:inline-block; 1508 border-radius: 8px 8px 0 0; 1509} 1510.mini-nav > li:hover > a:not(.btn), .mini-nav > li:hover > span { 1511 background: rgb(250, 250, 250); 1512 display: inline-block; 1513 position: relative; 1514 z-index: 1000; 1515} 1516/* First Level Dropdowns */ 1517.mini-nav li ul { 1518 background: rgb(250, 250, 250); 1519 box-shadow: 0 0px 3px rgba(34, 34, 34,0.25), 0 5px 5px 5px rgba(34, 34, 34,0.05); 1520 text-align: left; 1521 display: none; 1522 border-radius: 0 8px 8px 8px; 1523 list-style: none; 1524 padding: 10px; 1525 position: absolute; 1526 white-space: nowrap; 1527 min-width: 130%; 1528 width: auto; 1529 top: 100%; 1530 left: 0; 1531 z-index: 999; 1532 margin-top: -1px; 1533} 1534.mini-nav li:hover > ul { 1535 display: block; 1536} 1537/* First Level Dropdown Items */ 1538.mini-nav li ul li { 1539 position: relative; 1540 display: block; 1541 width: 100%; 1542} 1543.mini-nav li ul li a, .mini-nav li ul li span { 1544 font-size: 12.95px !important; 1545 display: block; 1546 font-weight: 400; 1547 padding: 8px 12px; 1548 border-radius: 8px; 1549 text-decoration: none; 1550 width: 100%; 1551} 1552.mini-nav li ul li a:hover, .mini-nav li ul li span:hover { 1553 box-shadow: 0 0 0 25px rgba(34, 34, 34,0.05) inset; 1554} 1555/* Second Level Dropdowns */ 1556.mini-nav li ul li ul { 1557 display: none; 1558 position: absolute; 1559 top: 0; 1560 left: 100%; 1561 margin: 0; 1562 border-radius: 8px; 1563} 1564.mini-nav li ul li:hover > ul { 1565 display: block; 1566} 1567/* Edge Positioning - Last Child Dropdowns */ 1568.mini-nav > li:last-child ul { 1569 right: 0; 1570 left: auto; 1571 border-radius: 8px 0 8px 8px; 1572} 1573.mini-nav > li:last-child ul li ul { 1574 right: 100%; 1575 left: auto; 1576} 1577/* Flex Spacing Utility */ 1578.mini-nav.mini-nav-flex-spaced { 1579 display: flex; 1580 justify-content: space-between; 1581 align-items: center; 1582 flex-wrap: wrap; 1583 row-gap: 0;
1584} 1585.mini-nav.mini-nav-flex-spaced > li { 1586 flex: none; 1587 padding: 0; 1588 margin: 2px 0; 1589 order: 2; 1590} 1591.mini-nav.mini-nav-flex-spaced > li.header-member-account-links, 1592.mini-nav:has(li ul) > li.header-member-account-links { 1593 order: 1; 1594 margin-left: auto; 1595 width: 100%; 1596 margin-bottom: 10px; 1597} 1598.logged-in-member-header .mini-nav.mini-nav-flex-spaced.list-inline > li { 1599 line-height: 1em; 1600 min-height: 0; 1601} 1602@media (min-width: 992px) { 1603 .header-main-row { 1604 display: flex; 1605 align-items: center; 1606 flex-wrap: wrap; 1607 } 1608} 1609@media (max-width: 991px) { 1610 .mini-nav.mini-nav-flex-spaced { 1611 justify-content: center; 1612 } 1613 .mini-nav.mini-nav-flex-spaced > li { 1614 margin-left: 5px !important; 1615 margin-right: 5px !important; 1616 } 1617} </style><div class="col-md-7 text-right sm-text-center header-right-container nolpad xs-hpad"> 1618 <ul class="mini-nav nobmargin list-inline xs-nopad xs-tmargin tpad"> 1619 <li class='bmargin xs-nomargin'><span id='link249' class='bmargin bold'> </span></li><li class='bmargin xs-nomargin'><a href='/about/contact' id='link250' class='fpad-sm bold'><i class="fa fa-envelope-o fa-fw"></i> Contact</a></li><li class='bmargin xs-nomargin'><a href='/login' id='link251' class='fpad-sm bold'><i class="fa fa-sign-in fa-fw"></i> Login</a></li><li class='bmargin norpad xs-vmargin lmargin'><a href='/join' id='link252' class='btn btn-block btn_get_listed '><i class='bi bi-plus-circle fa-fw'></i> Retaining Wall Experts â Join Today</a></li> </ul> 1620 <div class="clearfix"></div> 1621 <style>.network-icon.twitter,.network-icon.tiktok{background:#000}</style> 1622<div class="list-social-links"> 1623 <a class="network-icon contact" href="/about/contact" title="Contact Us Retaining Wall Expert"> 1624 <i class="bi bi-envelope"></i> 1625 </a> 1626 <a class="network-icon facebook" href="https://www.facebook.com/KowalskiEngineeringInc/" target="_blank" title="Retaining Wall Expert Facebook"> 1627 <i class="bi bi-facebook"></i> 1628 </a> 1629 <a class="network-icon twitter" href="https://x.com/WallExpertYes" target="_blank" title="Retaining Wall Expert X"> 1630 <i class="bi bi-twitter-x"></i> 1631 </a> 1632 1633 1634 <a class="network-icon linkedin" href="https://www.linkedin.com/in/contactjoekowalski/" target="_blank" title="Retaining Wall Expert LinkedIn"> 1635 <i class="bi bi-linkedin"></i> 1636 </a> 1637 <a class="network-icon youtube" href="https://www.youtube.com/@RetainingWallExpert" target="_blank" title="Retaining Wall Expert YouTube"> 1638 <i class="bi bi-youtube"></i> 1639 </a> 1640 1641 <a class="network-icon instagram" href="https://www.instagram.com/retainingwallexpert/" target="_blank" title="Retaining Wall Expert Instagram"> 1642 <i class="bi bi-instagram"></i> 1643 </a> 1644 <div class="clearfix"></div> 1645</div> 1646 </div> 1647 </div> 1648 </div> 1649 <style type='text/css'> .mobile-main-menu .hasChildren span a { 1650 padding: 0px; 1651} 1652 1653.user_sidebar > img { 1654 width: 32px; 1655 height: 32px; 1656 position: absolute; 1657 z-index: 10; 1658 border-radius: 100px; 1659 top: -1px; 1660 object-fit: cover; 1661 left: -10px; 1662 background: rgb(224, 224, 224); 1663} 1664#member_sidebar_toggle img+.fa { 1665 display: none; 1666} 1667.main_menu, .user_sidebar, .compact-mobile-search { 1668 padding: 5px 8px; 1669 margin-right:0; 1670 min-height: 33.0333px; 1671 min-width: 38.116px; 1672} 1673.main_menu i, .user_sidebar i { 1674 font-size: 16px; 1675} 1676.navbar-nav li { 1677 float: none!Important; 1678} 1679.navbar-default{ 1680 -webkit-transition: all .6s ease-in-out; 1681 -moz-transition: all .6s ease-in-out; 1682 -o-transition: all .6s ease-in-out; 1683 transition: all .6s ease-in-out; 1684} 1685.transparent_menu { 1686 background-color: rgba(3, 113, 102,0.95)!important; 1687} 1688@media only screen and (max-width: 991px) { 1689 #popover {display: none} 1690} 1691@media only screen and (max-width: 1100px){ 1692 .mobile-main-menu{display:block!important} 1693 .navbar-toggle {display: block} 1694 #bs-main_menu .nav {display: none!important} 1695} 1696.mobile-main-menu { 1697 position: fixed; 1698 height: calc(100% - 50px)!important; 1699 width: 250px; 1700 background: rgb(3, 113, 102); 1701 z-index: 99999; 1702 right: -250px; 1703 top: 50px; 1704 display: none; 1705 -webkit-transition: all .6s ease-in-out; 1706 -moz-transition: all .6s ease-in-out; 1707 -o-transition: all .6s ease-in-out; 1708 transition: all .6s ease-in-out; 1709 overflow-y: auto!important; 1710 overflow-x: hidden!important; 1711} 1712.mobile-main-menu ul li i { 1713 color: rgb(255, 255, 255); 1714 cursor: pointer; 1715 float: right; 1716 padding: 13px; 1717} 1718.mobile-main-menu.opened{ 1719 right: 0px!important; 1720} 1721.mobile-main-menu ul li a, .mobile-main-menu ul li span { 1722 display: inline-block; 1723 float: left; 1724 -webkit-touch-callout: none; 1725 -webkit-user-select: none; 1726 -khtml-user-select: none; 1727 -moz-user-select: none; 1728 -ms-user-select: none; 1729 user-select: none; 1730 padding: 10px 0px; 1731 width: 80%; 1732 width: calc(100% - 40px); 1733} 1734.mobile-main-menu .sidebar-nav li ul { 1735 height: 0px; 1736 overflow: hidden; 1737 list-style: none; 1738 color: rgb(255, 255, 255); 1739 padding-left: 10px; 1740} 1741.mobile-main-menu .sidebar-nav li.sub_open > ul{ 1742 height: 100%; 1743} 1744.mobile-main-menu ul.sidebar-nav { 1745 position: absolute; 1746 width: 250px; 1747 margin: 0; 1748 padding: 0; 1749 list-style: none; 1750 font-size: 14px; 1751} 1752.mobile-main-menu .sidebar-nav > li { 1753 display: block; 1754 line-height: 20px; 1755 padding: 0 15px 0 20px; 1756} 1757.mobile-main-menu .sidebar-nav li a, .mobile-main-menu .sidebar-nav li span { 1758 text-decoration: none; 1759 color: rgb(255, 255, 255); 1760 padding-left:10px; 1761} 1762.mobile-main-menu .sidebar-nav li a i, .mobile-main-menu .sidebar-nav li span i { 1763 display: none; 1764} 1765 1766 </style><div class="mobile-main-menu"> 1767 <ul class="sidebar-nav"> 1768 <li class=''><a href='/home' id='link336'>Home</a></li><li class=''><a href='/about/contact' id='link339'>Contact Us</a></li><li class=''><a href='/discussions' id='link338'>Forum Discussions</a></li><li class=''><a href='/blog' id='link349'>Articles</a></li><li class=''><span id='link346'> Media â¾</span><ul><li class=''><a href='/videos' id='link347'>Videos</a></li><li class=''><a href='/photo-albums' id='link348'>Photos</a></li></ul></li> </ul> 1769</div> 1770<nav class="navbar navbar-default lockedonscroll"> 1771 <div class="container container-fluid"> 1772 1773 <div class="navbar-header"> 1774 <button type="button" class="navbar-toggle collapsed main_menu" data-toggle="collapse" aria-label="main_menu"> 1775 <i class="fa fa-bars fa-fw"></i> 1776 </button> 1777 1778 1779 1780 </div> 1781 1782 1783 <div class="tablet-menu collapse navbar-collapse nopad" id="bs-main_menu"> 1784 <ul class="tablet-menu-ul nav navbar-nav nav-justified"> 1785 <li class=''><a href='/home' id='link336'>Home</a></li><li class=''><a href='/about/contact' id='link339'>Contact Us</a></li><li class=''><a href='/discussions' id='link338'>Forum Discussions</a></li><li class=''><a href='/blog' id='link349'>Articles</a></li><li class=''><span id='link346'> Media â¾</span><ul><li class=''><a href='/videos' id='link347'>Videos</a></li><li class=''><a href='/photo-albums' id='link348'>Photos</a></li></ul></li> </ul> 1786 </div> 1787 </div> 1788</nav> 1789<!--CSS IF MENU IS FIXED TOP--> 1790 1791</div> 1792<!-- 1793 1794IMPORTANT: This widget contains real Adsense code as a sample to show how this widget functions. Please replace the current Adsense code below with your own code in order to generate revenue from this ad space. 1795 1796-->
1797<div class="container clearfix text-center banner-ad-unit above-content-banner-ad"> 1798 <div class="clearfix"></div> 1799</div> 1800<div class="clearfix"></div><div class="clearfix"></div> 1801<!-- Begin Content --> 1802<main role="main" id="main-content"> 1803<div id="first_container" class="content-container fr-view"> 1804 <div class="container"> 1805 <div class="clearfix body-content"></div> 1806 </div> 1807<style> 1808 #first_container > .container:first-child .clearfix.body-content { 1809 display: none !important; 1810 } 1811 .hero_section_container::before { 1812 content: ""; 1813 position: absolute; 1814 width: 100%; 1815 height: 100%; 1816 background: rgb(0,0,0); 1817 opacity: 0.4; 1818 left:0; 1819 top:0; 1820 } 1821 .hero_section_container { 1822 background-image: url("/images/bg202.webp"); 1823 background-position: center center; 1824 background-repeat: no-repeat; 1825 background-size: cover; 1826 position: relative; 1827 } 1828 .hero_section_container .container { 1829 padding-top: 70px; 1830 padding-bottom: 60px; 1831 } 1832 .hero_section_container .hero_h1 { 1833 color: rgb(255, 255, 255); 1834 font-size: 30px; 1835 font-weight: 400; 1836 } 1837 .hero_section_container .hero_h2 { 1838 color: rgb(255, 255, 255); 1839 font-size: 56px; 1840 font-weight: 600; 1841 line-height: 1.2em; 1842 } 1843 .hero_section_container .hero_content { 1844 color: ; 1845 font-size: 10px; 1846 } 1847 .hero_section_container > .container > div { 1848 float: none!important; 1849 text-align: center; 1850 } 1851 </style> 1852 <div class="hero_section_container"> 1853 <div class="container"> 1854 <div class="col-md-12 center-block"> 1855 <h1 class='hero_h1'>Select a Plan to Sign Up</h1><h2 class='hero_h2'>Join Our Website Today</h2> <div class="clearfix"></div> 1856 </div> 1857 </div> 1858 <div class="clearfix"></div> 1859 </div> 1860 <div class="clearfix clearfix-lg"></div> 1861 1862 <div class="container"> 1863 1864 <div class="row"> 1865 1866 <div class="col-md-12"> 1867 <h2 style="text-align: center;">Choose a plan, sign up, and you're ready to go!<br><br></h2><table class="froala-table" style="width: 100%; cursor: default;"><tbody><tr><td class="module" style="width: 30%; vertical-align: top; text-align: center;"><h2><span style="font-size: 36px;"><strong>Plan 1<br></strong></span></h2><p><span style="color: rgb(51, 51, 51);font-size: 24px;">Free to Join</span></p><p style="line-height: 1.5;">There are many benefits<br>and it's easy to join our website!</p><hr><table class="froala-table" style="width: 100%;"><tbody><tr><td class="nopad" style="width: 50%; vertical-align: top;"><ul style="list-style-type: none;padding:0;"><li style="line-height: 2;"><span style="line-height: 2; font-size: 18px;">Membership Plan Benefit</span></li><li style="line-height: 2;"><span style="line-height: 2; font-size: 18px;">Membership Plan Benefit</span></li><li style="line-height: 2;"><span style="line-height: 2; font-size: 18px;">Membership Plan Benefit </span></li><li style="line-height: 2;"><span style="line-height: 2; font-size: 18px;"><span style="color: rgb(184, 49, 47);"><s>Membership Plan Benefit</s></span></span></li><li style="line-height: 2;"><span style="line-height: 2; font-size: 18px;"><span style="color: rgb(184, 49, 47);"><s>Membership Plan Benefit</s></span></span></li><li style="line-height: 2;"><span style="line-height: 2; font-size: 18px;"><span style="color: rgb(184, 49, 47);"><s>Membership Plan Benefit</s></span></span></li></ul><hr><p><a class="btn-lg btn-block btn btn-secondary" href="/checkout/1"><strong>CLICK TO JOIN</strong></a></p></td></tr></tbody></table></td><td style="width: 2.5%;"><br></td><td class="module" style="width: 30%; vertical-align: top; text-align: center;"><h2><span style="font-size: 36px;"><strong>Plan 2</strong></span></h2><p><span style="color: rgb(51, 51, 51);font-size: 24px;">$10</span><span style="color: rgb(51, 51, 51); font-size: 16px;">/month</span></p><p style="line-height: 1.5;">There are many benefits<br>and it's easy to join our website!</p><hr><table class="froala-table" style="width: 100%;"><tbody><tr><td class="nopad" style="width: 50%; vertical-align: top;"><ul style="list-style-type: none;padding:0;"><li style="line-height: 2;"><span style="line-height: 2; font-size: 18px;">
1867Membership Plan Benefit</span></li><li style="line-height: 2;"><span style="line-height: 2; font-size: 18px;">Membership Plan Benefit</span></li><li style="line-height: 2;"><span style="line-height: 2; font-size: 18px;">Membership Plan Benefit</span></li><li style="line-height: 2;"><span style="line-height: 2; font-size: 18px;">Membership Plan Benefit </span></li><li style="line-height: 2;"><span style="line-height: 2; font-size: 18px;"><span style="color: rgb(184, 49, 47);"><s>Membership Plan Benefit</s></span></span></li><li style="line-height: 2;"><span style="line-height: 2; font-size: 18px;"><span style="color: rgb(184, 49, 47);"><s>Membership Plan Benefit</s></span></span></li></ul><hr><p><a class="btn-lg btn-block btn btn-secondary" href="/checkout/2"><strong>CLICK TO JOIN</strong></a></p></td></tr></tbody></table></td><td style="width: 2.5%;"><br></td><td class="module" style="width: 30%; vertical-align: top; text-align: center;"><h2><span style="font-size: 36px;"><strong>Plan 3</strong></span></h2><p><span style="color: rgb(51, 51, 51);font-size: 24px;">$20</span><span style="color: rgb(51, 51, 51); font-size: 16px;">/month</span></p><p style="line-height: 1.5;">There are many benefits<br>and it's easy to join our website!</p><hr><table class="froala-table" style="width: 100%;"><tbody><tr><td class="nopad" style="width: 50%; vertical-align: top;"><ul style="list-style-type: none;padding:0;"><li style="line-height: 2;"><span style="line-height: 2; font-size: 18px;">Membership Plan Benefit</span></li><li style="line-height: 2;"><span style="line-height: 2; font-size: 18px;">Membership Plan Benefit</span></li><li style="line-height: 2;"><span style="line-height: 2; font-size: 18px;">Membership Plan Benefit</span></li><li style="line-height: 2;"><span style="line-height: 2; font-size: 18px;">Membership Plan Benefit</span></li><li style="line-height: 2;"><span style="line-height: 2; font-size: 18px;">Membership Plan Benefit</span></li><li style="line-height: 2;"><span style="line-height: 2; font-size: 18px;">Membership Plan Benefit</span></li></ul><hr><p><a class="btn-lg btn-block btn btn-secondary" href="/checkout/3"><strong>CLICK TO JOIN</strong></a></p></td></tr></tbody></table></td></tr></tbody></table><p><br></p><p><br></p><table class="froala-table" style="width: 100%; cursor: default;"><tbody><tr><td colspan="4"><h2 style="text-align: center;"><strong>Frequently Asked Questions</strong><br><strong><br></strong></h2></td></tr><tr><td style="width: 3%;"><br></td><td style="width: 47%; vertical-align: top;"><h3><strong>This is a Frequently Asked Question</strong></h3>This is an amazing answer to the that question. It's easy to create page layouts and organize content on landing pages using the TABLE tool in the page editor.</td><td style="width: 47%; vertical-align: top;"><h3><strong>This is a Frequently Asked Question</strong></h3>This is an amazing answer to the that question. It's easy to create page layouts and organize content on landing pages using the TABLE tool in the page editor.</td><td style="width: 3%;"><br></td></tr><tr><td style="width: 3%;"><br></td><td style="width: 47%; vertical-align: top;"><h3><strong>This is a Frequently Asked Question</strong></h3>This is an amazing answer to the that question. It's easy to create page layouts and organize content on landing pages using the TABLE tool in the page editor.</td><td style="width: 47%; vertical-align: top;"><h3><strong>This is a Frequently Asked Question</strong></h3>This is an amazing answer to the that question. It's easy to create page layouts and organize content on landing pages using the TABLE tool in the page editor.</td><td style="width: 3%;"><br></td></tr></tbody></table><p><br><br><br><br><br></p> </div> 1868 1869 1870 </div> <!-- Closes Row --> 1871 1872 1873
1873<script type="application/ld+json"> 1874{ 1875 "@context": "https://schema.org/", 1876 "@type": "WebPage", 1877 "@id": "https://www.retainingwallexpert.com/join", 1878 "url": "https://www.retainingwallexpert.com/join", 1879 "name": "Join Retaining Wall Expert - Today!", 1880 "headline": "Join Retaining Wall Expert. Create Your Account Today!", 1881 "about": "Join Our Website Today", 1882 "inLanguage": "en-US", 1883 "mainEntityOfPage": "https://www.retainingwallexpert.com/join", 1884 "author": { 1885 "@id": "https://www.retainingwallexpert.com/#organization" 1886 }, 1887 "publisher": { 1888 "@id": "https://www.retainingwallexpert.com/#organization" 1889 }, 1890 "isPartOf": { 1891 "@id": "https://www.retainingwallexpert.com/#website" 1892 }, 1893 "keywords": [ 1894 "Retaining Wall", 1895 "Retaining Wall Expert" 1896 ], 1897 "dateModified": "2026-08-06T08:04:31-04:00" 1898}</script>
1898 1899 <div class="clearfix"></div> 1900 </div> 1901</div> 1902</main> 1903<!-- End Content --> 1904<div class="clearfix footer-clear-element clearfix-lg"></div> 1905<!-- 1906 1907IMPORTANT: This widget contains real Adsense code as a sample to show how this widget functions. Please replace the current Adsense code below with your own code in order to generate revenue from this ad space. 1908 1909--> 1910<div class="clearfix"></div> 1911<div class="clearfix"></div> 1912<style type='text/css'> .newsletter_row input[type="email"] { 1913 float: none; 1914 margin-left: auto; 1915 margin-right: auto; 1916 width: 62% !important; 1917} </style><div class="content-container newsletter_row"> 1918 <div class="container text-center vpad"> 1919 <div class="col-md-12 xs-nopad"> 1920 <style type='text/css'> @media only screen and (min-width: 768px) { 1921 .newsletter_footer_button { 1922 display: flex; 1923 align-items: center; 1924 margin-left: auto; 1925 margin-right: auto; 1926 } 1927} </style><a href="#" data-toggle="modal" data-target="#newsletter_subscribe_modal" class="btn btn-lg newsletter_footer_button col-xs-12 col-md-6 nofloat fpad bold"> 1928 <div class="col-sm-6 nopad newsletter_button_left"> 1929 Join Our Newsletter 1930 </div> 1931 <div class="col-sm-6 nopad newsletter_button_right"> 1932 Click to Subscribe 1933 <i class='fa fa-chevron-circle-right fa-fw'></i> 1934 </div> 1935 1936 <div class="clearfix"></div> 1937</a> 1938 </div> 1939 </div> 1940</div><div class="footer"> 1941 <div class="container"> 1942 <div class="row"> 1943 <ul class="footer_menu sm-text-center"> 1944 <li class='col-md-5'><span id='link350' class='head'> About</span><ul><li class=''><span id='link351' class='content'> At Retaining Wall Expert, we pride ourselves in being an accurate source of all things retaining walls. From theory to practice and everything in between, we are dedicated to providing you with all the resources you need to learn about retaining walls.</span></li></ul></li><li class='col-md-2 col-md-offset-1'><span id='link352' class='head'> Website</span><ul><li class=''><a href='/about/contact' id='link354'>Contact Us</a></li></ul></li><li class='col-md-12 clearfix'><span id='link361'> </span></li><li class='col-md-5 vpad vmargin'><span id='link362'> <style>.network-icon.twitter,.network-icon.tiktok{background:#000}</style> 1945<div class="list-social-links"> 1946 <a class="network-icon contact" href="/about/contact" title="Contact Us Retaining Wall Expert"> 1947 <i class="bi bi-envelope"></i> 1948 </a> 1949 <a class="network-icon facebook" href="https://www.facebook.com/KowalskiEngineeringInc/" target="_blank" title="Retaining Wall Expert Facebook"> 1950 <i class="bi bi-facebook"></i> 1951 </a> 1952 <a class="network-icon twitter" href="https://x.com/WallExpertYes" target="_blank" title="Retaining Wall Expert X"> 1953 <i class="bi bi-twitter-x"></i> 1954 </a> 1955 1956 1957 <a class="network-icon linkedin" href="https://www.linkedin.com/in/contactjoekowalski/" target="_blank" title="Retaining Wall Expert LinkedIn"> 1958 <i class="bi bi-linkedin"></i> 1959 </a> 1960 <a class="network-icon youtube" href="https://www.youtube.com/@RetainingWallExpert" target="_blank" title="Retaining Wall Expert YouTube"> 1961 <i class="bi bi-youtube"></i> 1962 </a> 1963 1964 <a class="network-icon instagram" href="https://www.instagram.com/retainingwallexpert/" target="_blank" title="Retaining Wall Expert Instagram"> 1965 <i class="bi bi-instagram"></i> 1966 </a> 1967 <div class="clearfix"></div> 1968</div></span></li><li class='col-md-12 clearfix vmargin text-center'><span id='link364'> </span><ul><li class='clearfix vmargin vpad inline-block'><span id='link365'> </span></li><li class='font-sm novpad norpad inline-block'><span id='link366'> © 2026</span></li><li class='font-sm inline-block hpad'><a href='/' id='link367' title='Retaining Wall Expert'>Retaining Wall Expert</a></li><li class='font-sm inline-block'><span id='link368'> All Rights Reserved</span></li><li class='font-sm inline-block hpad'><a href='/about/terms' id='link369' title='Terms of Use'>Terms of Use</a></li><li class='font-sm inline-block'><a href='/about/privacy' id='link370' title='Privacy Policy'>Privacy Policy</a></li></ul></li> </ul> 1969 </div> 1970 </div> 1971</div><style type='text/css'> .scrollup { 1972 border-radius: 3px; 1973 width: 40px; 1974 height: 40px; 1975 opacity: 0.4; 1976 position: fixed; 1977 bottom: 30px; 1978 right: 30px; 1979 display: none; 1980 background: rgba(119, 119, 119, 0.8); 1981 z-index: 1000000; 1982} 1983.scrollup i { 1984 font-size: 36px; 1985 color: white; 1986 position: relative; 1987 top: 0px; 1988 left: 10px; 1989} </style> <div class="myModal modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="mySmallMod
1989alLabel" 1990 data-backdrop="static" data-keyboard="false"> 1991 <div class="modal-dialog" role="document"> 1992 <div class="modal-content"> 1993 <div class="modal-body nohpad nobpad"> 1994 <button type="button" style="z-index:10;position:absolute;right:15px;" class="close hmargin" 1995 data-dismiss="modal">× 1996 </button> 1997 <style> 1998 .member-login-container:not(.modal .module) { 1999 width: 555px; 2000 max-width: 100%; 2001 margin-left: auto; 2002 margin-right: auto; 2003 margin-bottom:0; 2004 background-color: rgb(255, 255, 255)!important; 2005 border-color: rgb(238, 238, 238)!important; 2006 color: rgb(34, 34, 34)!important; 2007 } 2008 .login-register-tabs, .login-register-content { 2009 width: 555px!important; 2010 max-width: 100%; 2011 margin-left: auto!important; 2012 margin-right: auto!important; 2013 background-color: rgb(238, 238, 238); 2014 } 2015 .login-register-content { 2016 background: transparent; 2017 padding: 0; 2018 border: none; 2019 } 2020 .login-register-content h2, .login-register-content h2+hr, .login-register-content .account-menu-title { 2021 display: none!important; 2022 } 2023 .express_login_create_account_prefix hr { 2024 margin: 15px 0 10px; 2025 }
2026 .modal-content #containerFBLogin, .modal-content #containerGoogleLogin { 2027 margin:15px 0; 2028 } 2029 2030 /* CSS When Login Form and Express Registration Rendered in Sidebar */ 2031 .col-md-3 .bd-chat-well-container,.col-md-4 .bd-chat-well-container { 2032 padding: 15px 10px; 2033 } 2034 .col-md-3 .bd-chat-center-text,.col-md-4 .bd-chat-center-text { 2035 margin: 0; 2036 font-size: 20px; 2037 padding: 0 15px; 2038 } 2039 .col-md-3 .member-login-page-container .login-register-tabs *, .col-md-4 .member-login-page-container .login-register-tabs * { 2040 font-size: 12px; 2041 line-height: 1.2em; 2042 vertical-align: bottom; 2043 } 2044 .col-md-3 .member-login-page-container .login-register-tabs a, .col-md-4 .member-login-page-container .login-register-tabs a { 2045 padding: 5px !important; 2046 height: 50px; 2047 vertical-align: middle; 2048 display: table-cell !important; 2049 width: 1%; 2050 } 2051 .col-md-3 .member-login-page-container .login-register-content, .col-md-4 .member-login-page-container .login-register-content { 2052 padding: 0; 2053 } 2054 .col-md-3 .member-login-container, .col-md-4 .member-login-container { 2055 padding: 15px !important; 2056 font-size: 13px; 2057 } 2058 .col-md-3 .member-login-page-container .input-lg, .col-md-4 .member-login-page-container .input-lg { 2059 height: 34px; 2060 padding: 6px 12px; 2061 font-size: 14px; 2062 } 2063 .col-md-3 .member-login-page-container .security_question_label, .col-md-4 .member-login-page-container .security_question_label { 2064 transform: scale(.85); 2065 margin: -1.15em -1.15em 0; 2066 } 2067 .col-md-3 #containerFBLogin, .col-md-4 #containerFBLogin, .col-md-3 #containerGoogleLogin, .col-md-4 #containerGoogleLogin, .col-md-3 .login-cta-buttons li, .col-md-4 .login-cta-buttons li { 2068 width: 100%; 2069 display: block; 2070 margin-top:5px; 2071 } 2072 .col-md-3 .login-cta-buttons li, .col-md-4 .login-cta-buttons li { 2073 padding:0 2074 } 2075 .col-md-3 .login-cta-buttons ul.nav, .col-md-4 .login-cta-buttons ul.nav { 2076 margin-top: -10px; 2077 } 2078 .col-md-3 #googleAction, .col-md-3 #facebookAction, .col-md-4 #googleAction, .col-md-4 #facebookAction { 2079 padding: 0; 2080 min-height: 0; 2081 font-size: 14px; 2082 margin: 0; 2083 } 2084 .col-md-3 #googleAction img, .col-md-3 #facebookAction img, .col-md-4 #googleAction img, .col-md-4 #facebookAction img { 2085 height: 36px !important; 2086 margin-right: 5px; 2087 position: relative!important; 2088 display: inline-block; 2089 } 2090 @media only screen and (max-width: 767px) { 2091 .col-md-3 .member-login-page-container .login-register-tabs a, .col-md-4 .member-login-page-container .login-register-tabs a { 2092 display: block !important; 2093 width: 100%; 2094 line-height: 40px; 2095 } 2096 2097 #containerGoogleLogin { 2098 text-align: center; 2099 margin-top: 10px; 2100 } 2101 #containerGoogleLogin #gBtn { 2102 display: inline-block; 2103 } 2104 } 2105 </style> 2106 <div class="row member-login-page-container"> 2107 <div class="fpad-lg novpad"> 2108 2109 2110 <div class="module fpad-xl member-login-container"> 2111 <style type="text/css">label span.required { color: #B94A48; }span.help-inline, span.help-block {font-size: .9em; }</style><form action="/api/widget/json/get/Bootstrap%20Theme%20-%20Member%20Login%20Page" id="member_login_190" method="post" labelwidth="100" labelpaddingtop="0.5em" enctype="multipart/form-data" form_action_type="redirect" form_action_div return_data_type="" name="member_login_190" class=" ">
2111<input type="hidden" name="sized" value="0" id="member_login_190-element-0"/><input type="hidden" name="form" value="myform" id="member_login_190-element-1"/><input type="hidden" name="formname" value="member_login" id="member_login_190-element-2"/><input type="hidden" name="dowiz" value="1" id="member_login_190-element-3"/><input type="hidden" name="save" value="1" id="member_login_190-element-4"/><input type="hidden" name="url_origin_pars" value="/join" id="member_login_190-element-5"/><input type="hidden" name="action" autocomplete="off" value="login" id="member_login_190-element-6"/><h2 class="nomargin member-login-h2-form-title">Member Login</h2><hr><style type='text/css'> #containerGoogleLogin #gBtn { 2112 display: inline-block; 2113 text-align: center; 2114 width: 216px; 2115} 2116 2117.module #containerFBLogin #facebookAction img, .module #containerFBLogin #facebookAction img { 2118 position: absolute !important; 2119} 2120.module #containerFBLogin a#facebookAction { 2121 max-width: 200px; 2122 position: relative; 2123 left: -8px; 2124 2125} </style><div class="form-group"><label class="vertical-label bd-email" for="member_login_190-element-9"><span class="required">* </span>Email Address</label><input type="email" name="email" required placeholder="[email protected]" autocomplete="off" value class="form-control input-lg" id="member_login_190-element-9"/></div><div class="form-group"><label class="vertical-label bd-password" for="member_login_190-element-10"><span class="required">* </span>Password</label> 2126 <style> 2127 #togglePassword { 2128 background: none; 2129 border: none; 2130 cursor: pointer; 2131 font-weight: bold; 2132 font-size: .85em; 2133 position: absolute; 2134 right: 5px; 2135 top: 0; 2136 } 2137 </style><button type="button" tabindex="-1" id="togglePassword" onclick="showPassword(this);"> <i class="fa fa-lock" aria-hidden="true"></i></button> 2138
2138<script> 2139 function showPassword(node){ 2140 const parent = node.closest('.form-group'); 2141 const passwordField = parent.querySelector(`input[type='password'], input[type='text']`); 2142 const isPassword = passwordField.getAttribute('type') === 'password'; 2143 passwordField.setAttribute('type', isPassword ? 'text' : 'password'); 2144 const iconHTML = isPassword ? `<i class="fa fa-unlock" aria-hidden="true"></i>` : `<i class="fa fa-lock" aria-hidden="true"></i>`; 2145 node.innerHTML = iconHTML; 2146 } 2147 </script>
2147<input type="password" name="pass" required placeholder="Enter Password" autocomplete="off" value class="form-control input-lg" id="member_login_190-element-10"/></div><span class="help-block bpad bmargin notmargin"> <a href="/login/retrieval">Forgot Password? Click to Reset Password</a></span><div class="form-group"><div class="form-group security_question_label"> 2148 <div id="member_login_190-captchaContainer" class="control-group"> 2149 <div class="g-recaptcha" id="member_login_190-google-recaptcha"></div> 2150 </div> 2151 <small class="help-block" id="recaptcha_error" style="display:none;" data-fv-validator="notEmpty" data-fv-for="recaptcha" data-fv-result="INVALID" />The security check was not completed successfully.</small> 2152 <div class="clearfix bmargin"></div> 2153 <input type="hidden" name="recaptcha" id="member_login_190-rcap"> 2154</div> 2155 <style> 2156 .modal .g-recaptcha-scale, .col-md-4 .g-recaptcha-scale, .col-md-3 .g-recaptcha-scale, .col-lg-3 .g-recaptcha-scale, .col-lg-4 .g-recaptcha-scale { 2157 transform: scale(0.77); 2158 -webkit-transform: scale(0.77); 2159 transform-origin: 0 0; 2160 -webkit-transform-origin: 0 0; 2161 margin-bottom: -15px; 2162 } 2163 2164 .modal #member_login_190-captchaContainer, .col-md-4 #member_login_190-captchaContainer, .col-md-3 #member_login_190-captchaContainer, .col-lg-3 #member_login_190-captchaContainer, .col-lg-4 #member_login_190-captchaContainer { 2165 transform: scale(0.77); 2166 -webkit-transform: scale(0.77); 2167 transform-origin: 0 0; 2168 -webkit-transform-origin: 0 0; 2169 margin-bottom: -15px; 2170 } 2171 </style>
2172<script> 2173 $(document).ready(function(){ 2174 $("#member_login_190 input[type=submit]").unbind('click'); 2175 $("#member_login_190 input[type=submit]").click(function (event) { 2176 2177 var formId = $(this.form).attr('id'); 2178 var captchaHolderKey = formId + "-google-recaptcha-" +$(this.form).data('counter'); 2179 2180 if (typeof captchaHolders[captchaHolderKey] != "undefined") { 2181 if (grecaptcha.getResponse(captchaHolders[captchaHolderKey]) === "") { 2182 event.preventDefault(); 2183 $("#" + formId).formValidation('validate'); 2184 $("#" + formId + " .security_question_label").addClass("has-error"); 2185 $("#" + formId + " #recaptcha_error").css("display", "block"); 2186 return false; 2187 } 2188 2189 /* Solved captcha: clear the error UI and let the click proceed untouched. 2190 The browser then fires a REAL, button-initiated submit event, so 2191 FormValidation runs its normal chain (success.form.fv -> AJAX modal on 2192 checkout / native POST on login). Re-submitting here artificially broke 2193 both ways: native form.submit() skips the FV chain (checkout rendered the 2194 raw JSON response), and jQuery .submit() fires a synthetic submit that FV 2195 refuses, leaving the form stuck after the first error (Bug 2). */ 2196 $("#" + formId + " .security_question_label").removeClass("has-error"); 2197 $("#" + formId + " #recaptcha_error").css("display", "none"); 2198 } 2199 }); 2200 }); 2201</script>
2201</div><div class="form-actions"><input type="submit" value="Login Now" name class="btn btn-primary btn-lg btn-block " id="member_login_190-element-13"/></div><div class="login-cta-buttons"><hr class="cta-hr"><ul class="list-inline nomargin inline-block btn-block"><li class='col-md-12 text-center bold nav'><a href='/join' id='link198'>Don't Have an Account? Get Listed Today</a></li></ul><div class="clearfix"></div></div></form>
2201<script type="text/javascript">jQuery(document).ready(function() { jQuery("#member_login_190").bind("submit", function() { 2202 });}); </script>
2202 <div class="clearfix"></div> 2203 </div> 2204 2205 2206 </div> 2207 </div> 2208 </div> 2209 </div> 2210 </div> 2211 </div> 2212 2213 2214 2215 <link rel="stylesheet" type="text/css" href="https://www.optimizecdn.com/directory/cdn/assets/bootstrap/limonte-sweetalert2/6.11.2/sweetalert2.min.css">
2216<script src="https://www.optimizecdn.com/directory/cdn/assets/bootstrap/limonte-sweetalert2/6.11.2/sweetalert2.min.js"></script>
2216 2217
2218<script> 2219 function clearContent(thisObj){ 2220 var size; 2221 if(thisObj.hasClass('input-sm') || thisObj.parents('.input-group').hasClass('input-group-sm')){ 2222 size = "small"; 2223 } else if (thisObj.hasClass('input-lg') || thisObj.parents('.input-group').hasClass('large-autosuggest')){ 2224 size = "large"; 2225 } else { 2226 size = "medium"; 2227 } 2228 if(!thisObj.parent().hasClass('input_wrapper')){ 2229 if(thisObj.parent().hasClass('input-group-sm')){ 2230 thisObj.wrap('<span class="input-group-sm input_wrapper"></span>'); 2231 } else if (thisObj.parent().hasClass('input-group-lg')){ 2232 thisObj.wrap('<span class="input-group-lg input_wrapper"></span>'); 2233 } else { 2234 thisObj.wrap('<span class="input_wrapper"></span>'); 2235 } 2236 } 2237 if(thisObj.val() != ""){ 2238 if(thisObj.hasClass('googleSuggest')){ 2239 thisObj.parent().find('.fill_location').remove(); 2240 } 2241 if (!thisObj.parent().find('.clear_content').length){ 2242 thisObj.parent().append(`<span class="clear_content ${size}"><i class="fa fa-times-circle" aria-hidden="true"></i></span>`); 2243 if (thisObj.hasClass("tt-input")) { 2244 thisObj.focus(); 2245 } 2246 2247 } 2248 } 2249 } 2250 2251 $(document).on('click', '.drp-buttons .applyBtn', function(){ 2252 clearContent($(".dateRange input")); 2253 }); 2254 2255 $('.sm-autosuggest input, .googleSuggest, .large-autosuggest input, .md-autosuggest input, .normal-autosuggest input, .google-writen-location, .dateRange input').keyup(function(){ 2256 clearContent($(this)); 2257 }); 2258 2259 $(document).ready(function(){ 2260 $('.sm-autosuggest input, input.googleSuggest, .large-autosuggest input, .md-autosuggest input, .normal-autosuggest input, .google-writen-location, .dateRange input').each(function(){ 2261 clearContent($(this)); 2262 }) 2263 }) 2264 2265 $(document).on('click', '.clear_content', function(){ 2266 $(this).parent().find('input').val(''); 2267 //tt-input its a class for typeahead auto-suggest 2268 if ($(this).parent().find('input').hasClass("tt-input")) { 2269 $(this).parent().find('input').typeahead('val',''); 2270 } 2271 clearContent($(this).parent().find('input')); 2272 $(this).remove(); 2273 }); 2274 2275 $(window).on('load', function () { 2276 setTimeout(function() { 2277 // add missing href attribute to multi-category options in search modules 2278 $('.bootstrap-select.show-tick .dropdown-menu a').attr('href', '#'); 2279 }, 2000); 2280 }); 2281</script>
2281 2282 2283 2284 2285<a href="#" class="scrollup" title="scrollup"> 2286 <i class="fa fa-caret-up" aria-hidden="true"></i> 2287</a>
2288<script> 2289 $(document).ready(function () { 2290 2291 if ($('.navbar-default').length > 0) { 2292 var menu = $('.navbar-default'); 2293 var origOffsetY = menu.offset().top; 2294 2295 function scroll() { 2296 2297 if ($(window).scrollTop() > origOffsetY) { 2298 $('.navbar-default').addClass('navbar-fixed-top'); 2299 $('.navbar-default').addClass('transparent_menu'); 2300 2301 } else { 2302 $('.navbar-default').removeClass('navbar-fixed-top'); 2303 $('.navbar-default').removeClass('transparent_menu'); 2304 } 2305 } 2306 document.onscroll = scroll; 2307 }; 2308 }); 2309 $(document).ready(function(){ 2310 // .progressbar() comes from bootstrap-progressbar.min.js, loaded only by widgets 1236/1318. 2311 // Elsewhere it used to fall through to jQuery UI's; jQuery UI is no longer global, so an 2312 // unguarded call throws and kills the rest of this ready() handler (scrollup, crop button). 2313 if ($.fn.progressbar) { 2314 $('.progress .progress-bar').progressbar({ 2315 display_text: 'fill' 2316 }); 2317 } 2318 $(window).scroll(function(){ 2319 2320 if ($(this).scrollTop() > 600) { 2321 $('.scrollup').fadeIn(); 2322 2323 } else { 2324 $('.scrollup').fadeOut(); 2325 } 2326 }); 2327 $('.scrollup').click(function(){ 2328 $("html, body").animate({ 2329 scrollTop: 0 2330 }, 600); 2331 return false; 2332 }); 2333 $('#cropButton').click(function(){ 2334 var iframe = $("#cropiFrame"); 2335 iframe.attr("src", iframe.data("src")); 2336 }); 2337 }); 2338</script>
2338 2339
2339<script type="text/javascript"> 2340 /* CT dissolved its county governments in 1960, so Google returns its 8 counties as 2341 colloquial_area instead of administrative_area_level_2 â they must never reach a 2342 city field. Google translates the component name to the site language, so the 2343 language-stable place_id is checked first and the word list only backs it up. */ 2344 if (typeof window.bdIsColloquialCounty !== 'function') { 2345 window.bdIsColloquialCounty = function (componentName, resultPlaceId) { 2346 var countyPlaceIds = [ 2347 'ChIJWRM2Nakw5okRoTCxHvz_5xw', /* Middlesex County, CT */ 2348 'ChIJmeTbuDYH6IkR3xgeNvszpgg', /* Fairfield County, CT */ 2349 'ChIJiT24cvvP54kR2fSPHkp0Akc', /* New Haven County, CT */ 2350 'ChIJvYe7N7eQ54kRL6nZaXRwPkI', /* Litchfield County, CT */ 2351 'ChIJtxC3p6qs54kRIvK-2bctar0', /* Hartford County, CT */ 2352 'ChIJj-lvZQli5okRGCuGRd6xKt0', /* Tolland County, CT */ 2353 'ChIJRWKqeLdi5okRLXWDlSEGeTY', /* Windham County, CT */ 2354 'ChIJwTIQbvVv5okRU5_gSJczUTQ' /* New London County, CT */ 2355 ]; 2356 2357 if (typeof resultPlaceId === 'string' && resultPlaceId !== '' 2358 && countyPlaceIds.indexOf(resultPlaceId) !== -1) { 2359 return true; 2360 } 2361 2362 if (typeof componentName !== 'string' || componentName === '') { 2363 return false; 2364 } 2365 2366 var name = componentName.toLowerCase(); 2367 2368 /* Only unambiguous county words â generic ones (region, district) would strip 2369 legitimate colloquial areas, and their languages already match on place_id. 2370 Word-boundary matched so names like "Countyline, OK" are left alone. */ 2371 var wordTokens = ['county', 'condado', 'comté', 'contea', 2372 'comitatul', 'hrabstwo', 'megye', 'konderria']; 2373 var isAlnum = function (ch) { 2374 return (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9'); 2375 }; 2376 2377 for (var t = 0; t < wordTokens.length; t++) { 2378 var token = wordTokens[t]; 2379 var from = 0; 2380 while (true) { 2381 var at = name.indexOf(token, from); 2382 if (at === -1) { 2383 break; 2384 } 2385 var before = (at > 0) ? name.charAt(at - 1) : ' '; 2386 var after = ((at + token.length) < name.length) ? name.charAt(at + token.length) : ' '; 2387 if (!isAlnum(before) && !isAlnum(after)) { 2388 return true; 2389 } 2390 from = at + 1; 2391 } 2392 } 2393 2394 /* Non-latin scripts have no alphanumeric word boundary. */ 2395 var scriptTokens = ['каÑнÑи', 'کاؤÙÙ¹Û', 'à¤à¤¾à¤à¤à¤à¥', 'ì¹´ì´í°']; 2396 for (var s = 0; s < scriptTokens.length; s++) { 2397 if (name.indexOf(scriptTokens[s]) !== -1) { 2398 return true; 2399 } 2400 } 2401 2402 return false; 2403 }; 2404 } 2405 2406 // Debug mode variable 2407 var isDevMode = ``; 2408 2409 var cityTypes = [ 2410 'colloquial_area', 2411 'locality', 2412 'sublocality', 2413 'sublocality_level_1', 2414 'sublocality_level_2', 2415 'sublocality_level_3', 2416 'sublocality_level_4', 2417 'sublocality_level_5', 2418 'neighborhood', 2419 'ward', 2420 'postal_town' 2421 ]; 2422 2423 var postalTypes = [ 2424 'postal_code', 2425 'postal_code_prefix', 2426 'postal_code_suffix', 2427 'street_number', 2428 'premise', 2429 'subpremise', 2430 'route', 2431 'intersection', 2432 'street_address', 2433 'floor', 2434 'room', 2435 'post_box', 2436 'delivery_address' 2437 ]; 2438 2439 var localizedMainCountry = ''; 2440 // Add debugging for Google Maps loading 2441 window.gm_authFailure = function() { 2442 const errorMessage = document.createElement('div'); 2443 errorMessage.className = 'alert alert-danger'; 2444 errorMessage.innerHTML = `Google Maps authentication failed. Please check the console for more details.`; 2445 document.body.insertBefore(errorMessage, document.body.firstChild); 2446 }; 2447 2448 // Try to load coordinates from sessionStorage on page load 2449 var vlat = 0; 2450 var vlon = 0; 2451 try { 2452 var savedLat = sessionStorage.getItem('bd_geolocation_lat'); 2453 var savedLon = sessionStorage.getItem('bd_geolocation_lon'); 2454 if (savedLat && savedLon) { 2455 vlat = parseFloat(savedLat); 2456 vlon = parseFloat(savedLon); 2457 } 2458 } catch(e) {} 2459 var isSubmit = false; 2460 var mapsLoaded = false; 2461 var mapsLoading = false; 2462 var placesInitialized = false; 2463 let newestRequestId = 0; 2464 var cachedSelectedOption = null; 2465 var warningMessageWasTriggered = false; // Track if warning message was shown 2466 var isGettingLocation = false; // Flag to prevent multiple simultaneous geolocation requests 2467 2468 // Function to save coordinates to sessionStorage 2469 function saveCoordinatesToSession(lat, lon) { 2470 try { 2471 sessionStorage.setItem('bd_geolocation_lat', lat.toString()); 2472 sessionStorage.setItem('bd_geolocation_lon', lon.toString()); 2473 } catch(e) {} 2474 } 2475 2476 // Function to get coordinates from sessionStorage if current ones are 0 2477 function getCoordinatesFromSession() { 2478 if (vlat === 0 && vlon === 0) { 2479 try { 2480 var savedLat = sessionStorage.getItem('bd_geolocation_lat'); 2481 var savedLon = sessionStorage.getItem('bd_geolocation_lon'); 2482 if (savedLat && savedLon) { 2483 vlat = parseFloat(savedLat); 2484 vlon = parseFloat(savedLon); 2485 return true; 2486 } 2487 } catch(e) {} 2488 } 2489 return false; 2490 } 2491 2492 var gmapScriptLoading = false; 2493 var gmapScriptPromise = null; 2494 2495 function googleMapOnFormClick() { 2496 if (typeof google !== "undefined" && google.hasOwnProperty('maps')) { 2497 return Promise.resolve(); 2498 } 2499 if (gmapScriptLoading && gmapScriptPromise) { 2500 return gmapScriptPromise; 2501 } 2502 gmapScriptLoading = true; 2503 gmapScriptPromise = new Promise((resolve, reject) => { 2504 window.isSubmittingMainSearch = false; 2505 let mapUri = "https://maps.googleapis.com/ma
2505ps/api/js?v=quarterly&libraries=places®ion=US&callback=initializeGoogleMaps&language=en"; 2506 2507 let script = document.createElement('script'); 2508 script.type = 'text/javascript'; 2509 script.src = mapUri; 2510 script.async = true; 2511 script.onload = function () { 2512 resolve("ok"); 2513 }; 2514 script.onerror = function () { 2515 gmapScriptLoading = false; 2516 reject("Failed to load Google Maps script."); 2517 }; 2518 document.head.appendChild(script); 2519 }); 2520 return gmapScriptPromise; 2521 } 2522 2523 function loadGoogleMaps() { 2524 return new Promise((resolve, reject) => { 2525 if (mapsLoaded) { 2526 resolve(); 2527 return; 2528 } 2529 2530 if (mapsLoading) { 2531 const checkLoaded = setInterval(() => { 2532 if (mapsLoaded) { 2533 clearInterval(checkLoaded); 2534 resolve(); 2535 } 2536 }, 100); 2537 return; 2538 } 2539 2540 mapsLoading = true; 2541 2542 // Remove any existing Google Maps scripts 2543 const existingScripts = document.querySelectorAll('script[src*="maps.googleapis.com"]'); 2544 existingScripts.forEach(script => script.remove()); 2545 2546 window.initMap = async function() { 2547 try { 2548 let mapExists = document.querySelectorAll('[id^="map"]').length > 0; 2549 const functionsToInvoke = { 2550 setJsMap: true, 2551 setJsMapOverview: mapExists, 2552 setJsMapSR: mapExists, 2553 setJsMapSidebar: mapExists 2554 }; 2555 if (window['maps_loaded'] !== true) { 2556 for (let func in functionsToInvoke) { 2557 if (typeof window[func] === 'function' && functionsToInvoke[func]) { 2558 window['maps_loaded'] = true; 2559 window[func](); 2560 } 2561 } 2562 } 2563 mapsLoaded = true; 2564 mapsLoading = false; 2565 resolve(); 2566 } catch (error) { 2567 reject(error); 2568 } 2569 }; 2570 2571 /* const script = document.createElement('script'); 2572 script.type = 'text/javascript'; 2573 script.src = `https://maps.googleapis.com/maps/api/js?key=&libraries=places&callback=initMap&language=en`; 2574 script.async = true; 2575 script.defer = true; 2576 script.onerror = function(error) { 2577 console.error('Failed to load Google Maps:', error); 2578 mapsLoading = false; 2579 reject(error); 2580 }; 2581 */ 2582 //document.head.appendChild(script); 2583 if((typeof google == "undefined" || !google.hasOwnProperty('maps')) && typeof googleMapOnFormClick !== 'undefined' && typeof googleMapOnFormClick === 'function'){ 2584 googleMapOnFormClick().then(() => { 2585 initMap(); 2586 }); 2587 }else{ 2588 initMap(); 2589 } 2590 }); 2591 } 2592 2593 function normalizePlaceToGeocoder(place) { 2594 if (!place) return null; 2595 2596 return { 2597 formatted_address: place.formattedAddress || null, 2598 place_id: place.id || null, 2599 types: place.types || [], 2600 address_components: place.addressComponents?.map(comp => ({ 2601 long_name: comp.longText || "", 2602 short_name: comp.shortText || "", 2603 types: comp.types || [] 2604 })) || [], 2605 geometry: { 2606 bounds: place.viewport || null, 2607 location: place.location || null, 2608 viewport: place.viewport || null 2609 } 2610 }; 2611 } 2612 2613 async function initializeAutocomplete() { 2614 if (placesInitialized) { 2615 return; 2616 } 2617 2618 try { 2619 if (!window.google || !window.google.maps) { 2620 throw new Error('Maps API not available'); 2621 } 2622 2623 const inputs = document.querySelectorAll('.googleSuggest, #location_google_maps_header, .google-writen-location, input[name="lead_location"], .fill_location'); 2624
2625 inputs.forEach(input => { 2626 if (input.getAttribute('data-autocomplete-initialized')) { 2627 return; 2628 } 2629 2630 // Add value setter interceptor to block unauthorized value changes 2631 const originalValueSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set; 2632 if (originalValueSetter) { 2633 let valueSetterInterceptor = function(newValue) { 2634 const stack = new Error().stack; 2635 const caller = stack.split('\n')[2]?.trim() || 'unknown'; 2636 2637 // Protect the input value if it was set by a valid suggestion selection 2638 if (window.inputValueProtected && 2639 window.protectedInputId === this.id && 2640 window.expectedInputValue && 2641 newValue !== window.expectedInputValue) { 2642 if (isDevMode) { 2643 console.warn('ð« BLOCKED: Attempt to change protected input value'); 2644 } 2645 return; 2646 } 2647 2648 // Allow value changes if a suggestion is being clicked (legitimate selection) 2649 if (window.suggestionBeingClicked) { 2650 const expectedValue = window.expectedInputValue || 2651 (window.cachedSelectedOption && 2652 window.cachedSelectedOption[0] && 2653 (window.cachedSelectedOption[0].displayName || 2654 window.cachedSelectedOption[0].formatted_address || 2655 window.cachedSelectedOption[0].name)); 2656 2657 const isFromOurCode = caller.includes('javascript.php') || 2658 caller.includes('connect?devmode') || 2659 caller.includes('sample-member'); 2660 2661 if (expectedValue && newValue === expectedValue) { 2662 window.inputClearedByUser = false; 2663 window.clearedInputId = null; 2664 } else if (expectedValue && newValue !== expectedValue) { 2665 if (isDevMode) { 2666 console.warn('ð« BLOCKED: Value doesnt match selected suggestion'); 2667 } 2668 return; 2669 } else if (!isFromOurCode) { 2670 // Block external scripts from setting values when suggestion is being clicked 2671 if (isDevMode) { 2672 console.warn('ð« BLOCKED: External script trying to set value while suggestion is being clicked'); 2673 } 2674 return; 2675 } 2676 } 2677 // Block value changes if input was recently cleared by user 2678 else if (window.inputClearedByUser && 2679 window.clearedInputId === this.id && 2680 Date.now() - window.inputClearedTimestamp < 2000 && 2681 newValue && newValue.trim() !== '') { 2682 if (isDevMode) { 2683 console.warn('ð« BLOCKED: Attempt to set value after user cleared input'); 2684 } 2685 return; 2686 } 2687 2688 return originalValueSetter.call(this, newValue); 2689 }; 2690 2691 try { 2692 Object.defineProperty(input, 'value', { 2693 get: Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.get, 2694 set: valueSetterInterceptor, 2695 configurable: true 2696 }); 2697 } catch (e) { 2698 // Ignore if we can't intercept 2699 } 2700 } 2701 2702 try { 2703 // Create the request object with initial configuration 2704 const websiteLanguage = 'en'; 2705 const countryRegion = ''; 2706 2707 const request = { 2708 input: '', 2709 language: 'en',
2710 includedRegionCodes: localizedMainCountry ? [ localizedMainCountry ] : [], 2711 sessionToken: null 2712 }; 2713 2714 // Create and style the suggestions container 2715 const suggestionsContainer = document.createElement('div'); 2716 suggestionsContainer.className = 'pac-container pac-logo'; 2717 suggestionsContainer.setAttribute('data-input-id', input.id || 'input-' + Math.random().toString(36).substr(2, 9)); 2718 suggestionsContainer.style.cssText = ` 2719 position: absolute; 2720 z-index: 1000; 2721 background-color: #fff; 2722 border: 1px solid rgba(0,0,0,0.2); 2723 box-shadow: 0 2px 6px rgba(0,0,0,0.3); 2724 -moz-box-sizing: border-box; 2725 -webkit-box-sizing: border-box; 2726 box-sizing: border-box; 2727 overflow: hidden; 2728 font-family: Arial, sans-serif;
2729 margin-top: 1px; 2730 display: none; 2731 `; 2732 2733 // Add PAC banner header 2734 const header = document.createElement('div'); 2735 header.className = 'pac-header'; 2736 header.setAttribute('role', 'note'); 2737 header.setAttribute('aria-hidden', 'true'); 2738 header.innerHTML = "<span>REQUIRED: Select Location</span>"; 2739 2740 suggestionsContainer.appendChild(header); 2741 document.body.appendChild(suggestionsContainer); 2742 2743 // Add styles for suggestion items 2744 const style = document.createElement('style'); 2745 style.textContent = ` 2746 .pac-container { 2747 background-color: #fff; 2748 position: absolute; 2749 z-index: 1000; 2750 border-radius: 2px; 2751 border-top: 1px solid #d9d9d9; 2752 font-family: Arial, sans-serif; 2753 box-shadow: 0 2px 6px rgba(0,0,0,0.3); 2754 -moz-box-sizing: border-box; 2755 -webkit-box-sizing: border-box; 2756 box-sizing: border-box; 2757 overflow: hidden; 2758 visibility: hidden; 2759 opacity: 0; 2760 } 2761 .pac-container.visible { 2762 visibility: visible; 2763 opacity: 1; 2764 } 2765 .pac-item { 2766 cursor: default; 2767 padding: 0 4px; 2768 text-overflow: ellipsis; 2769 overflow: hidden; 2770 white-space: nowrap; 2771 line-height: 30px; 2772 text-align: left; 2773 border-top: 1px solid #e6e6e6; 2774 font-size: 11px; 2775 color: #999; 2776 height: 40px; 2777 display: flex; 2778 align-items: center; 2779 } 2780 .pac-item:first-child { 2781 border-top: none; 2782 } 2783 .pac-item:hover { 2784 background-color: #fafafa; 2785 } 2786 .pac-item-query { 2787 font-size: 13px; 2788 padding-right: 3px; 2789 color: #000; 2790 } 2791 .pac-matched { 2792 font-weight: 700; 2793 } 2794 .pac-icon-marker { 2795 width: 15px !important; 2796 height: 20px; 2797 margin-right: 7px; 2798 margin-top: 6px; 2799 display: inline-block; 2800 vertical-align: top; 2801 background-image: url(https://maps.gstatic.com/mapfiles/api-3/images/autocomplete-icons.png); 2802 background-position: -1px -161px; 2803 -webkit-background-size: 34px; 2804 background-size: 34px; 2805 min-width: 15px; 2806 box-sizing: content-box; 2807 } 2808 `; 2809 document.head.appendChild(style); 2810 2811 // Function to update container position 2812 function updateContainerPosition() { 2813 const inputRect = input.getBoundingClientRect(); 2814 const scrollTop = window.pageYOffset || document.documentElement.scrollTop; 2815 const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft; 2816 2817 suggestionsContainer.style.top = `${inputRect.bottom + scrollTop}px`; 2818 suggestionsContainer.style.left = `${inputRect.left + scrollLeft}px`; 2819 suggestionsContainer.style.width = `${inputRect.width}px`; 2820 suggestionsContainer.style.zIndex = '9999'; 2821 } 2822 2823 // Update position on scroll and resize 2824 window.addEventListener('scroll', updateContainerPosition); 2825 window.addEventListener('resize', updateContainerPosition); 2826 2827 // Helper function to refresh the session token 2828 function refreshToken() { 2829 request.sessionToken = new google.maps.places.AutocompleteSessionToken(); 2830 } 2831 2832 // Handle input changes 2833 let debounceTimer; 2834 input.addEventListener('input', async () => { 2835 clearTimeout(debounceTimer); 2836 const query = input.value.trim(); 2837 2838 // Clear cached selection when user types new text 2839 if (window.cachedSelectedOption && window.cachedSelectedOption[0]) { 2840 const currentValue = window.cachedSelectedOption[0].displayName || window.cachedSelectedOption[0].formatted_address || window.cachedSelectedOption[0].name || ''; 2841 2842 if (query !== currentValue) { 2843 // User is typing new text - remove input value protection 2844 window.inputValueProtected = false; 2845 window.expectedInputValue = null; 2846 window.protectedInputId = null; 2847 window.cachedSelectedOption = null; 2848 sessionStorage.removeItem("google_result"); 2849 2850 // Show warning when user modifies the text 2851 if (query.length > 0) { 2852 // Add a small delay to allow for suggestion selection 2853 setTimeout(() => { 2854 // Only show warning if no new suggestion was selected during the delay 2855 if (!window.cachedSelectedOption || !window.cachedSelectedOption[0]) { 2856 window.replaceClearIconWithWarning(input); 2857 } 2858 }, 500); 2859 } 2860 } 2861 } 2862 2863 // Update the request with the latest input 2864 request.input = query; 2865 2866 // Store the request ID to avoid race conditions 2867 const requestId = ++newestRequestId; 2868 2869 // Handle case when user deletes all text 2870 if (query.length === 0) { 2871 suggestionsContainer.style.display = 'none'; 2872 suggestionsContainer.classList.remove('visible'); 2873 window.cachedSelectedOption = null; 2874 sessionStorage.removeItem("google_result"); 2875 2876 // Clear any existing warning 2877 const clearIcon = input.parentElement.querySelector('.clear_content.large, .clear_content.medium, .clear_content'); 2878 if (clearIcon) {
2879 // Clear any pending warning timeout 2880 if (clearIcon.dataset.warningTimeoutId) { 2881 clearTimeout(parseInt(clearIcon.dataset.warningTimeoutId)); 2882 delete clearIcon.dataset.warningTimeoutId; 2883 } 2884 2885 $(clearIcon).popover('hide'); 2886 $(clearIcon).popover('destroy'); 2887 clearIcon.classList.remove('clicked'); 2888 2889 // Restore original icon if it was changed 2890 const iconElement = clearIcon.querySelector('i'); 2891 if (iconElement && iconElement.className.includes('fa-exclamation-circle')) { 2892 iconElement.className = 'fa fa-times-circle'; 2893 } 2894 2895 warningMessageWasTriggered = false; 2896 } 2897 return; 2898 } 2899 2900 debounceTimer = setTimeout(async () => { 2901 try { 2902 if (query.length < 2) { 2903 suggestionsContainer.style.display = 'none'; 2904 suggestionsContainer.classList.remove('visible'); 2905 return; 2906 } 2907 2908 // Fetch autocomplete suggestions 2909 const { suggestions } = await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions(request); 2910 2911 // If the request has been superseded by a newer request, do not render 2912 if (requestId !== newestRequestId) { 2913 return; 2914 } 2915 2916 // Filter out unwanted suggestions and limit to 5 items 2917 const filteredSuggestions = suggestions; 2918 2919 if (isDevMode) { 2920 console.log(filteredSuggestions); 2921 } 2922 2923 // Only show container and update if we have suggestions 2924 if (filteredSuggestions.length > 0) { 2925 // Preserve the header when clearing the container 2926 const existingHeader = suggestionsContainer.querySelector('.pac-header'); 2927 suggestionsContainer.innerHTML = ''; 2928 2929 // Re-add the header if it existed 2930 if (existingHeader) { 2931 suggestionsContainer.appendChild(existingHeader); 2932 } 2933 2934 suggestionsContainer.style.display = 'block'; 2935 suggestionsContainer.classList.add('visible'); 2936 updateContainerPosition(); 2937 2938 for (const suggestion of filteredSuggestions) { 2939 const placePrediction = suggestion.placePrediction; 2940 // Don't fetch full details here - save API credits 2941 // Only get basic place object for logging 2942 const placeObject = await placePrediction.toPlace(); 2943 if (isDevMode) { 2944 console.log('place object (basic)',placeObject); 2945 console.log('placePrediction object',placePrediction); 2946 console.log('suggestion',suggestion); 2947 } 2948 const suggestionElement = document.createElement('div'); 2949 suggestionElement.className = 'pac-item'; 2950 2951 // Debug the available properties 2952 let mainText = ''; 2953 let secondaryText = ''; 2954 2955 if(isDevMode){ 2956 console.log('formatted text',placePrediction.formattedSuggestion); 2957 console.log('structured_formatting',placePrediction.structured_formatting); 2958 console.log('description',placePrediction.description); 2959 } 2960 2961 // Try different ways to get the text 2962 if (placePrediction.formattedSuggestion && placePrediction.formattedSuggestion.mainText) { 2963 mainText = placePrediction.formattedSuggestion.mainText; 2964 secondaryText = placePrediction.formattedSuggestion.secondaryText || ''; 2965 2966 // Clean up the secondary text to remove country 2967 if (secondaryText) { 2968 secondaryText = secondaryText.split(',') 2969 .map(part => part.trim()) 2970 .filter(part => part !== 'USA') 2971 .join(', '); 2972 } 2973 } else if (placePrediction.structured_formatting) { 2974 mainText = placePrediction.structured_formatting.main_text; 2975 secondaryText = placePrediction.structured_formatting.secondary_text || ''; 2976 2977 // Clean up the secondary text to remove country 2978 if (secondaryText) { 2979 secondaryText = secondaryText.split(',') 2980 .map(part => part.trim()) 2981 .filter(part => part !== 'USA') 2982 .join(', '); 2983 } 2984 } else if (placePrediction.description) { 2985 const parts = placePrediction.description.split(',').map(part => part.trim()); 2986 mainText = parts[0]; 2987 // Filter out USA and join remaining parts 2988 secondaryText = parts.slice(1) 2989 .filter(part => part !== 'USA') 2990 .join(', '); 2991 } else if (placePrediction.text) { 2992 mainText = secondaryText = placePrediction.text.toString(); 2993 } else { 2994 const parts = (placePrediction.displayName || placePrediction.name || 'Unknown location').split(',').map(part => part.trim()); 2995 mainText = parts[0]; 2996 // Filter out USA and join remaining parts 2997 secondaryText = parts.slice(1) 2998 .filter(part => part !== 'USA') 2999 .join(', '); 3000 } 3001 3002 3003 // Create the suggestion element with the map marker icon 3004 suggestionElement.innerHTML = `
3005 <span class="pac-icon-marker" style="width: 15px !important; min-width: 15px;"></span> 3006 <span class="pac-item-query">${mainText}</span> 3007 <span>${secondaryText}</span> 3008 `; 3009 3010 // Handle suggestion selection with proper mouse event handling 3011 const handleSuggestionSelection = async () => { 3012 try { 3013 // Set flag to prevent warning when suggestion is clicked 3014 window.suggestionBeingClicked = true; 3015 3016 // Clear the input clearing protection since user is selecting a suggestion 3017 window.inputClearedByUser = false; 3018 window.clearedInputId = null; 3019 3020 // Set a temporary expected value based on the prediction text to block external scripts 3021 const predictionText = placePrediction.text ? placePrediction.text.toString() : ''; 3022 if (predictionText) { 3023 const parts = predictionText.split(',').map(part => part.trim()); 3024 const tempDisplayName = parts.filter(part => part !== 'USA').join(', '); 3025 window.expectedInputValue = tempDisplayName; 3026 window.inputValueProtected = true; 3027 window.protectedInputId = input.id; 3028 } 3029 3030 // Clear any existing warnings immediately when suggestion is clicked 3031 const clearIcon = input.parentElement.querySelector('.clear_content.large, .clear_content.medium, .clear_content'); 3032 if (clearIcon) { 3033 // Clear any pending warning timeout 3034 if (clearIcon.dataset.warningTimeoutId) { 3035 clearTimeout(parseInt(clearIcon.dataset.warningTimeoutId)); 3036 delete clearIcon.dataset.warningTimeoutId; 3037 } 3038 3039 $(clearIcon).popover('hide'); 3040 $(clearIcon).popover('destroy'); 3041 clearIcon.classList.remove('clicked'); 3042 3043 // Restore original icon 3044 const iconElement = clearIcon.querySelector('i'); 3045 if (iconElement && iconElement.className.includes('fa-exclamation-circle')) { 3046 iconElement.className = 'fa fa-times-circle'; 3047 } 3048 } 3049 3050 // Store the original input value before setting the suggestion 3051 const originalInputValue = input.value; 3052 3053 // Fetch full place details only when user clicks (saves API credits) 3054 const place = await placePrediction.toPlace(); 3055 if (isDevMode) { 3056 console.log('Place session token:', place.sessionToken); 3057 console.log('Prediction session token:', placePrediction.sessionToken); 3058 } 3059 await place.fetchFields({ 3060 fields: [ 3061 'addressComponents', 3062 'adrFormatAddress', 3063 'formattedAddress', 3064 'location', 3065 'plusCode', 3066 'postalAddress', 3067 'types', 3068 'viewport' 3069 ] 3070 }); 3071 3072 if (!place.location) { 3073 if (isDevMode) console.warn('No location found for selected place'); 3074 return; 3075 } 3076 3077 const cachedOption = normalizePlaceToGeocoder(place); 3078 cachedOption.suggestion_address = placePrediction.text.toString() ; 3079 3080 if (placePrediction.text) { 3081 const parts = placePrediction.text.toString().split(',').map(part => part.trim()); 3082 displayName = parts.filter(part => part !== 'USA').join(', '); 3083 } else { 3084 const parts = displayName.split(',').map(part => part.trim()); 3085 displayName = parts.filter(part => part !== 'USA').join(', '); 3086 } 3087 3088 // Store both the full formatted address and the display name 3089 cachedOption.displayName = displayName; 3090 window.cachedSelectedOption = [cachedOption]; 3091 3092 // Store the expected value to protect it from being changed 3093 window.expectedInputValue = displayName; 3094 window.inputValueProtected = true; 3095 window.protectedInputId = input.id; 3096 3097 input.value = displayName; 3098 suggestionsContainer.style.display = 'none'; 3099 suggestionsContainer.classList.remove('visible'); 3100 3101 // Check if the text actually changed after setting the suggestion 3102 const textChanged = originalInputValue !== displayName; 3103 3104 // If text didn't change, mark this as a valid selection to prevent warning 3105 if (!textChanged && !window.cachedSelectedOption) { 3106 window.cachedSelectedOption = [{ 3107 formatted_address: displayName, 3108 name: displayName, 3109 displayName: displayName 3110 }]; 3111 } 3112 3113 if (typeof makeSearch === 'function') { 3114 makeSearch(cachedOption); 3115 } 3116 3117 // Refresh the session token after a selection 3118 refreshToken(); 3119 warningMessageWasTriggered = false; // Reset flag when suggestion is selected 3120 } catch (error) { 3121 if (isDevMode) { 3122 console.error('Error fetching place details:', error); 3123 console.error('Error stack:', error.stack); 3124 } 3125 } finally { 3126 // Reset the flag after a delay to ensure blur event doesn't interfere 3127 setTimeout(() => { 3128 window.suggestionBeingClicked = false; 3129 }, 500); 3130 } 3131 }; 3132 3133 // Track if mouse was pressed down on this element 3134 let mouseDownOnElement = false; 3135 3136 // Handle mousedown to track where the press started 3137 suggestionElement.addEventListener('mousedown', (e) => { 3138 mouseDownOnElement = true; 3139 if (isDevMode) console.log('ð±ï¸ Mouse down on suggestion'); 3140 e.preventDefault(); // Prevent text selection during drag 3141 }); 3142 3143 // Handle mouseup to trigger selection if press started on this element 3144 suggestionElement.addEventListener('mouseup', async (e) => { 3145 if (mouseDownOnElement) { 3146 if (isDevMode) console.log('ð±ï¸ Mouse up on same suggestion - triggering selection'); 3147 e.preventDefault(); 3148 e.stopPropagation(); 3149 await handleSuggestionSelection(); 3150 } 3151 mouseDownOnElement = false; 3152 }); 3153 3154 // Handle mouseleave to reset flag if user drags away 3155 suggestionElement.addEventListener('mouseleave', () => { 3156 if (mouseDownOnElement && isDevMode) { 3157 console.log('ð±ï¸ Mouse left suggestion during press'); 3158 } 3159 mouseDownOnElement = false; 3160 }); 3161 3162 // Keep click handler as fallback for accessibility (keyboard, etc.) 3163 suggestionElement.addEventListener('click', async (e) => { 3164 // Only handle click if mouseup didn't already handle it 3165 if (!window.suggestionBeingClicked) { 3166 if (isDevMode) console.log('ð±ï¸ Click event fallback triggered'); 3167 await handleSuggestionSelection(); 3168 } 3169 }); 3170 3171 suggestionsContainer.appendChild(suggestionElement); 3172 } 3173 } 3174 } catch (error) { 3175 console.error('Error fetching suggestions:', error); 3176 } 3177 }, 300); 3178 }); 3179 3180 // Function to replace clear icon with warning icon (moved to global scope) 3181 if (typeof window.replaceClearIconWithWarning === 'undefined') { 3182 window.replaceClearIconWithWarning = function(inputElement) { 3183 // Check if this input has a valid suggestion selected 3184 const hasValidSuggestion = window.cachedSelectedOption && 3185 Array.isArray(window.cachedSelectedOption) && 3186 window.cachedSelectedOption.length > 0 && 3187 window.cachedSelectedOption[0] && 3188 window.cachedSelectedOption[0].formatted_address && 3189 window.cachedSelectedOption[0].formatted_address !== ''; 3190 3191 // Don't show warning if a valid suggestion is selected AND the input value matches 3192 if (hasValidSuggestion) { 3193 const cachedValue = window.cachedSelectedOption[0].displayName || window.cachedSelectedOption[0].formatted_address || window.cachedS
3193electedOption[0].name || ''; 3194 const currentValue = inputElement.value.trim(); 3195 3196 if (currentValue === cachedValue) { 3197 return; 3198 } 3199 } 3200 3201 const clearIcon = inputElement.parentElement.querySelector('.clear_content.large, .clear_content.medium, .clear_content'); 3202 if (clearIcon) { 3203 // Store original icon class and container class 3204 const originalIconClass = clearIcon.querySelector('i').className; 3205 const originalContainerClass = clearIcon.className; 3206 3207 // Replace icon class but preserve the container class (large/medium) 3208 clearIcon.querySelector('i').className = 'fa fa-exclamation-circle'; 3209 3210 // Add clicked class for tooltip 3211 clearIcon.classList.add('clicked'); 3212 3213 // Show tooltip with error message 3214 $(clearIcon).popover({ 3215 content: `Please select a location from the suggestions dropdown to continue.`, 3216 container: 'body', 3217 placement: 'top', 3218 trigger: 'manual' 3219 }); 3220 $(clearIcon).popover('show'); 3221 warningMessageWasTriggered = true; 3222 3223 // Restore original icon after 3 seconds 3224 const warningTimeoutId = setTimeout(() => { 3225 if (clearIcon.querySelector('i').className.includes('fa-exclamation-circle')) { 3226 clearIcon.querySelector('i').className = originalIconClass; 3227 clearIcon.className = originalContainerClass; 3228 3229 $(clearIcon).popover('hide'); 3230 $(clearIcon).popover('destroy'); 3231 clearIcon.classList.remove('clicked'); 3232 warningMessageWasTriggered = false; 3233 } 3234 }, 3000); 3235 3236 // Store the timeout ID on the icon element for potential cancellation 3237 clearIcon.dataset.warningTimeoutId = warningTimeoutId; 3238 } 3239 }; 3240 } 3241 3242 // Handle focus/blur 3243 input.addEventListener('focus', () => { 3244 // Clear any existing tooltips when user focuses into the field 3245 const clearIcon = input.parentElement.querySelector('.clear_content.large, .clear_content.medium, .clear_content'); 3246 if (clearIcon) { 3247 // Clear any pending warning timeout 3248 if (clearIcon.dataset.warningTimeoutId) { 3249 clearTimeout(parseInt(clearIcon.dataset.warningTimeoutId)); 3250 delete clearIcon.dataset.warningTimeoutId; 3251 } 3252 3253 $(clearIcon).popover('hide'); 3254 $(clearIcon).popover('destroy'); 3255 clearIcon.classList.remove('clicked'); 3256 3257 // Restore original icon if it was changed 3258 const iconElement = clearIcon.querySelector('i'); 3259 if (iconElement && iconElement.className.includes('fa-exclamation-circle')) { 3260 iconElement.className = 'fa fa-times-circle'; 3261 } 3262 } 3263 3264 if (input.value.trim().length >= 2) { 3265 updateContainerPosition(); 3266 suggestionsContainer.style.display = 'block'; 3267 } 3268 }); 3269 3270 // Handle blur event - when user leaves the field 3271 input.addEventListener('blur', () => { 3272 // Don't show warning if user is clicking a suggestion 3273 if (window.suggestionBeingClicked) { 3274 return; 3275 } 3276 3277 // Store the value at blur start to detect if Google's autocomplete changes it 3278 const valueAtBlurStart = input.value; 3279 3280 // Check if there's a valid suggestion selected 3281 const hasValidSuggestion = window.cachedSelectedOption && 3282 Array.isArray(window.cachedSelectedOption) && 3283 window.cachedSelectedOption.length > 0 && 3284 window.cachedSelectedOption[0] && 3285 window.cachedSelectedOption[0].formatted_address && 3286 window.cachedSelectedOption[0].formatted_address !== ''; 3287 3288 // Wait a bit to see if Google's autocomplete widget changes the value 3289 setTimeout(() => { 3290 // Don't clear if a suggestion is being clicked 3291 if (window.suggestionBeingClicked) { 3292 return; 3293 } 3294 3295 // Re-check if a suggestion was selected during the delay 3296 const currentHasValidSuggestion = window.cachedSelectedOption && 3297 Array.isArray(window.cachedSelectedOption) && 3298 window.cachedSelectedOption.length > 0 && 3299 window.cachedSelectedOption[0] && 3300 window.cachedSelectedOption[0].formatted_address && 3301 window.cachedSelectedOption[0].formatted_address !== ''; 3302 3303 const valueAfterBlur = input.value; 3304 3305 // If no valid suggestion was selected, prevent any auto-filled values 3306 if (!currentHasValidSuggestion) { 3307 // Check if the value changed (Google's autocomplete might have auto-filled) 3308 if (valueAfterBlur !== valueAtBlurStart) { 3309 // Restore the original value the user typed 3310 input.value = valueAtBlurStart; 3311 } 3312 3313 // If the original value was just partial text (like "Lo"), clear it completely 3314 const preloaded_location_value = ``; 3315 const hasPreloadedValue = preloaded_location_value && 3316 preloaded_location_value !== '' && 3317 preloaded_location_value !== 'undefined'; 3318 3319 if ((!hasPreloadedValue || valueAtBlurStart !== preloaded_location_value) && 3320 (valueAtBlurStart.length < 3 || (!valueAtBlurStart.includes(',') && !valueAtBlurStart.match(/\d/)))) { 3321 // Set a flag to prevent other scripts from setting values 3322 window.inputClearedByUser = true; 3323 window.inputClearedTimestamp = Date.now(); 3324 window.clearedInputId = input.id; 3325 3326 // Clear the input 3327 input.value = ''; 3328 3329 // Monitor and block any attempts to set a value for the next 2 seconds 3330 const blockValueChanges = () => { 3331 if (input.value && input.value.trim() !== '' && input.value !== valueAtBlurStart) { 3332 input.value = ''; 3333 } 3334 }; 3335 3336 // Check immediately and repeatedly 3337 blockValueChanges(); 3338 setTimeout(blockValueChanges, 10); 3339 setTimeout(blockValueChanges, 50); 3340 setTimeout(blockValueChanges, 100); 3341 setTimeout(blockValueChanges, 200); 3342 setTimeout(blockValueChanges, 500); 3343 setTimeout(blockValueChanges, 1000); 3344 3345 // Remove the flag after 2 seconds 3346 setTimeout(() => { 3347 window.inputClearedByUser = false; 3348 window.clearedInputId = null; 3349 }, 2000); 3350 } 3351 } 3352 }, 200); 3353 3354 // Check if we should show warning 3355 const hasValue = input.value && input.value.trim().length > 0;
3356 3357 // Check if there's preloaded data from URL parameters 3358 const preloaded_place_id = ``; 3359 const preloaded_location_value = ``; 3360 const hasPreloadedData = (preloaded_place_id && preloaded_place_id !== '' && preloaded_place_id !== 'undefined') || 3361 (preloaded_location_value && preloaded_location_value !== '' && preloaded_location_value !== 'undefined'); 3362 3363 // Check if current input value matches preloaded data 3364 const currentValue = input.value.trim(); 3365 const preloadedValueMatches = preloaded_location_value && 3366 preloaded_location_value !== '' && 3367 preloaded_location_value !== 'undefined' && 3368 currentValue === preloaded_location_value; 3369 3370 // Hide suggestions container after a short delay to allow for clicks 3371 setTimeout(() => { 3372 suggestionsContainer.style.display = 'none'; 3373 suggestionsContainer.classList.remove('visible'); 3374 }, 150); 3375 3376 // Show warning if: 3377 // 1. Input has value AND 3378 // 2. No valid suggestion AND (no preloaded data OR preloaded value doesn't match) AND 3379 // 3. Values don't match (if there is a valid suggestion) 3380 if (hasValue) { 3381 // If we have preloaded data AND the current value matches the preloaded value, don't show warning 3382 if (hasPreloadedData && preloadedValueMatches) { 3383 return; 3384 } 3385 3386 if (!hasValidSuggestion) { 3387 // Add a small delay to allow for suggestion selection 3388 setTimeout(() => { 3389 const currentHasValidSuggestion = window.cachedSelectedOption && 3390 Array.isArray(window.cachedSelectedOption) && 3391 window.cachedSelectedOption.length > 0 && 3392 window.cachedSelectedOption[0] && 3393 window.cachedSelectedOption[0].formatted_address && 3394 window.cachedSelectedOption[0].formatted_address !== ''; 3395 3396 if (!currentHasValidSuggestion && !window.suggestionBeingClicked) { 3397 window.replaceClearIconWithWarning(input); 3398 } 3399 }, 100); 3400 } else { 3401 // Check if values match 3402 const cachedValue = window.cachedSelectedOption[0].displayName || window.cachedSelectedOption[0].formatted_address || window.cachedSelectedOption[0].name || ''; 3403 const currentValue = input.value.trim(); 3404 3405 if (currentValue !== cachedValue) { 3406 window.replaceClearIconWithWarning(input); 3407 } 3408 } 3409 } 3410 }); 3411 3412 // Close suggestions when clicking outside 3413 document.addEventListener('click', (e) => { 3414 if (!input.contains(e.target) && !suggestionsContainer.contains(e.target)) { 3415 suggestionsContainer.style.display = 'none'; 3416 } 3417 }); 3418 3419 // Handle keyboard navigation 3420 input.addEventListener('keydown', (e) => { 3421 const pacItems = suggestionsContainer.querySelectorAll('.pac-item'); 3422 const selectedItem = suggestionsContainer.querySelector('.pac-item.selected'); 3423 let currentIndex = selectedItem ? Array.from(pacItems).indexOf(selectedItem) : -1; 3424 3425 // Prevent form submission when suggestions are visible 3426 if (e.key === 'Enter' || e.keyCode === 13) { 3427 const visibleContainers = document.querySelectorAll('.pac-container'); 3428 let visibleCount = 0;
3429 visibleContainers.forEach(container => { 3430 if (container.style.display !== 'none') { 3431 visibleCount++; 3432 } 3433 }); 3434 if (visibleCount > 0) { 3435 e.preventDefault(); 3436 if (selectedItem) { 3437 // Create and dispatch a click event on the selected item 3438 const clickEvent = new MouseEvent('click', { 3439 bubbles: true, 3440 cancelable: true, 3441 view: window 3442 }); 3443 selectedItem.dispatchEvent(clickEvent); 3444 suggestionsContainer.style.display = 'none'; 3445 } 3446 return; 3447 } 3448 } 3449 3450 if (e.key === 'ArrowDown') { 3451 e.preventDefault(); 3452 if (suggestionsContainer.style.display !== 'none' && pacItems.length > 0) { 3453 // Remove selection from current item 3454 if (selectedItem) { 3455 selectedItem.classList.remove('selected'); 3456 } 3457 // Select next item or first item if at end 3458 currentIndex = (currentIndex + 1) % pacItems.length; 3459 pacItems[currentIndex].classList.add('selected'); 3460 } 3461 } else if (e.key === 'ArrowUp') { 3462 e.preventDefault(); 3463 if (suggestionsContainer.style.display !== 'none' && pacItems.length > 0) { 3464 // Remove selection from current item 3465 if (selectedItem) { 3466 selectedItem.classList.remove('selected'); 3467 } 3468 // Select previous item or last item if at start 3469 currentIndex = currentIndex <= 0 ? pacItems.length - 1 : currentIndex - 1; 3470 pacItems[currentIndex].classList.add('selected'); 3471 } 3472 } else if (e.key === 'Escape') { 3473 suggestionsContainer.style.display = 'none'; 3474 } 3475 }); 3476 3477 // Add styles for selected item 3478 const selectedStyle = document.createElement('style'); 3479 selectedStyle.textContent = ` 3480 .pac-item.selected { 3481 background-color: #f5f5f5; 3482 } 3483 .pac-item { 3484 cursor: pointer; 3485 } 3486 `; 3487 document.head.appendChild(selectedStyle); 3488 3489 // Initialize with a session token 3490 refreshToken(); 3491 3492 // Set initialization flags 3493 input.setAttribute('data-autocomplete-initialized', 'true'); 3494 input.setAttribute('data-google-autocomplete-initialized', 'true'); 3495 input.setAttribute('data-pac-initialized', 'true'); 3496 } catch (error) { 3497 console.error('Error initializing autocomplete:', error); 3498 input.setAttribute('data-autocomplete-error', 'true'); 3499 } 3500 }); 3501 3502 placesInitialized = true; 3503 3504 3505 3506 // Trigger PAC banners after places are initialized 3507 // console.log('Checking if triggerPacBanners function exists...'); 3508 if (typeof window.triggerPacBanners === 'function') { 3509 window.triggerPacBanners(); 3510 } else { 3511 // console.log('triggerPacBanners function not found'); 3512 } 3513 3514 } catch (error) { 3515 console.error('Failed to initialize Places API:', error); 3516 throw error; 3517 } 3518 } 3519 3520 // Initialize Google Maps when needed 3521 async function initializeGoogleMaps() { 3522 try { 3523 await loadGoogleMaps(); 3524 await initializeAutocomplete(); 3525 } catch (error) { 3526 console.error('Error in Google Maps initialization:', error); 3527 } 3528 } 3529 3530 // Initialize event listeners once DOM is loaded 3531 document.addEventListener('DOMContentLoaded', () => { 3532 // Restore cached data from sessionStorage if it exists 3533 const cachedData = sessionStorage.getItem("google_result"); 3534 3535 if (cachedData) { 3536 try { 3537 const parsedData = JSON.parse(cachedData); 3538 3539 // Reconstruct the geometry object with proper methods 3540 if (parsedData[0] && parsedData[0].geometry) { 3541 const lat = parsedData[0].geometry.location.lat; 3542 const lng = parsedData[0].geometry.location.lng; 3543 const sw = parsedData[0].geometry.viewport.sw; 3544 const ne = parsedData[0].geometry.viewport.ne; 3545 3546 parsedData[0].geometry = { 3547 location: { 3548 lat: () => lat, 3549 lng: () => lng 3550 }, 3551 viewport: { 3552 getSouthWest: () => ({ 3553 lat: () => sw.lat, 3554 lng: () => sw.lng 3555 }), 3556 getNorthEast: () => ({ 3557 lat: () => ne.lat, 3558 lng: () => ne.lng 3559 }) 3560 }, 3561 bounds: { 3562 getSouthWest: () => ({ 3563 lat: () => sw.lat, 3564 lng: () => sw.lng 3565 }), 3566 getNorthEast: () => ({ 3567 lat: () => ne.lat, 3568 lng: () => ne.lng 3569 }) 3570 } 3571 }; 3572 } 3573 3574 window.cachedSelectedOption = parsedData; 3575 3576 // Update the input field with the cached location 3577 const inputs = document.querySelectorAll('.googleSuggest, #location_google_maps_header, .google-writen-location, input[name="lead_location"], .fill_location');
3578 inputs.forEach(input => { 3579 if (parsedData[0] && parsedData[0].name) { 3580 input.value = parsedData[0].name; 3581 } 3582 }); 3583 } catch (error) { 3584 console.error('Error restoring cached data:', error); 3585 } 3586 } 3587 3588 const inputs = document.querySelectorAll('.googleSuggest, #location_google_maps_header, .google-writen-location, input[name="lead_location"], .fill_location'); 3589 3590 inputs.forEach(input => { 3591 if (input.getAttribute('data-listeners-initialized')) { 3592 return; 3593 } 3594 /** 3595 * 3596 * <div class="views pull-right "> 3597 <i class="fa fa-th-list activeView listView"></i> 3598 <i class="fa fa-th js-click gridView hidden-xs"></i> 3599 <i class="fa fa-map-marker mapView" style="display: inline-block;"></i> 3600 </div> 3601 */ 3602 3603 // Initialize immediately for the header location input 3604 input.addEventListener('focus', initializeGoogleMaps, { once: true }); 3605 // Add input change handler to clear cache when input is manually changed 3606 let lastValue = input.value; 3607 input.addEventListener('input', () => { 3608 if (input.value !== lastValue) { 3609 lastValue = input.value; 3610 3611 // Clear cached selection when user types new text 3612 if (window.cachedSelectedOption && window.cachedSelectedOption[0]) { 3613 const currentValue = window.cachedSelectedOption[0].formatted_address || window.cachedSelectedOption[0].name || ''; 3614 3615 if (input.value !== currentValue) { 3616 window.cachedSelectedOption = null; 3617 sessionStorage.removeItem("google_result"); 3618 } 3619 } 3620 3621 if (!input.value.trim()) { 3622 window.cachedSelectedOption = null; 3623 sessionStorage.removeItem("google_result"); 3624 } 3625 } 3626 }); 3627 3628 input.setAttribute('data-listeners-initialized', 'true'); 3629 }); 3630 // Add form submission handler 3631 $('.website-search').submit(function (e) { 3632 if (window.isSubmittingMainSearch) { 3633 e.preventDefault(); 3634 return false; 3635 } 3636 3637 var currentForm = $(this); 3638 var locationInput = $(this).find(".googleLocation"); 3639 cachedSelectedOption = window.cachedSelectedOption; 3640 3641 var $submitButton = currentForm.find('input[type=submit], button[type=submit]'); 3642 3643 3644 if (locationInput.val() != "" && typeof locationInput.val() != 'undefined') { 3645 // Check if a valid suggestion was selected 3646 const hasValidSuggestion = window.cachedSelectedOption && 3647 Array.isArray(window.cachedSelectedOption) && 3648 window.cachedSelectedOption.length > 0 && 3649 window.cachedSelectedOption[0] && 3650 window.cachedSelectedOption[0].formatted_address && 3651 window.cachedSelectedOption[0].formatted_address !== ''; 3652 3653 // Check if there's preloaded data from URL parameters 3654 const preloaded_place_id = ``; 3655 const preloaded_location_value = ``; 3656 const hasPreloadedData = (preloaded_place_id && preloaded_place_id !== '' && preloaded_place_id !== 'undefined') || 3657 (preloaded_location_value && preloaded_location_value !== '' && preloaded_location_value !== 'undefined'); 3658 3659 // Check if current input value matches preloaded data 3660 const currentInputValue = locationInput.val().trim(); 3661 const preloadedValueMatches = preloaded_location_value && 3662 preloaded_location_value !== '' && 3663 preloaded_location_value !== 'undefined' && 3664 currentInputValue === preloaded_location_value; 3665 3666 if (isDevMode) { 3667 console.log('Location input value:', currentInputValue); 3668 console.log('Preloaded location value:', preloaded_location_value); 3669 console.log('Preloaded value matches current input
3669:', preloadedValueMatches); 3670 } 3671 3672 if (!hasValidSuggestion && !(hasPreloadedData && preloadedValueMatches)) { 3673 if (isDevMode) { 3674 console.log('â No valid suggestion selected and preloaded data does not match current input - preventing form submission'); 3675 console.log('cachedSelectedOption:', window.cachedSelectedOption); 3676 console.log('hasPreloadedData:', hasPreloadedData); 3677 console.log('preloadedValueMatches:', preloadedValueMatches); 3678 } 3679 3680 // Show warning icon and prevent submission 3681 const inputElement = locationInput[0]; 3682 if (inputElement && typeof window.replaceClearIconWithWarning === 'function') { 3683 window.replaceClearIconWithWarning(inputElement); 3684 } 3685 3686 e.preventDefault(); 3687 return false; 3688 } 3689 3690 if (hasPreloadedData && preloadedValueMatches) { 3691 if (isDevMode) console.log('â Preloaded data matches current input - allowing form submission'); 3692 } 3693 3694 // Check if warning message was triggered 3695 if (warningMessageWasTriggered) { 3696 if (isDevMode) console.log('â Warning message was triggered - preventing form submission'); 3697 e.preventDefault(); 3698 return false; 3699 } 3700 3701 if (isDevMode) console.log('â Valid suggestion selected - allowing form submission'); 3702 3703 // Disable submit button immediately 3704 window.isSubmittingMainSearch = true; 3705 $submitButton.prop('disabled', true); 3706 3707 e.preventDefault(); 3708 var form = currentForm; 3709 var urlGET = form.serialize(); 3710 var formActionUrl = form.attr("action"); 3711 var locationValue = locationInput.val(); 3712 var place_id_in_url = ``; 3713 var location_value_in_url = ``; 3714 const mainCountry = ''; 3715 var inputOptions = {}; 3716 var placeIdFound = false; 3717 3718 // Prioritize selected suggestion over preloaded data 3719 if(cachedSelectedOption && cachedSelectedOption[0] && cachedSelectedOption[0].formatted_address && cachedSelectedOption[0].formatted_address != ''){ 3720 if (isDevMode) console.log('???? Using selected suggestion for geocoding:', cachedSelectedOption[0].formatted_address); 3721 inputOptions = { 3722 address:cachedSelectedOption[0].formatted_address 3723 } 3724 }else if (place_id_in_url != '' && place_id_in_url != 'undefined' && place_id_in_url != null){ 3725 if (isDevMode) console.log('???? Using preloaded place_id for geocoding:', place_id_in_url); 3726 inputOptions = { 3727 placeId:place_id_in_url 3728 } 3729 placeIdFound = true; 3730 }else{ 3731 if (isDevMode) console.log('???? Using current input value for geocoding:', locationValue); 3732 inputOptions = { 3733 address:locationValue 3734 } 3735 } 3736 3737 const language = "en"; 3738 3739 if (language) { 3740 inputOptions.language = language; 3741 } 3742 if (mainCountry && placeIdFound == false) { 3743 inputOptions.componentRestrictions = {country: mainCountry}; 3744 inputOptions.region = mainCountry; 3745 } 3746 3747 if (typeof cachedSelectedOption == 'undefined' || !cachedSelectedOption || typeof cachedSelectedOption[0] == 'undefined') { 3748 cachedSelectedOption = [{ 3749 'formatted_address': '' 3750 }]; 3751 } 3752 3753 if (isDevMode) { 3754 console.log(inputOptions); 3755 console.log('cachedSelectedOption',cachedSelectedOption); 3756 } 3757 3758 if (isDevMode) { 3759 console.log('locationValue',locationValue); 3760 if (cachedSelectedOption && cachedSelectedOption[0]) { 3761 console.log('cachedSelectedOption[0][formatted_address]',cachedSelectedOption[0]['formatted_address']); 3762 } else { 3763 console.log('cachedSelectedOption[0][formatted_address]', 'null or undefined'); 3764 } 3765 } 3766 geocoder = new google.maps.Geocoder(); 3767 geocoder.geocode(inputOptions, function (results, status) { 3768 if (status == google.maps.GeocoderStatus.OK) { 3769 if(isDevMode){ 3770 console.log('geocode result with formatted_address:',results[0].formatted_address); 3771 console.log('original geocode result',results[0]); 3772 } 3773 3774 // Prioritize selected suggestion over preloaded data for formatted_address 3775 if(cachedSelectedOption && cachedSelectedOption[0] && cachedSelectedOption[0]['suggestion_address'] != '' && cachedSelectedOption[0]['suggestion_address'] != 'undefined' && cachedSelectedOption[0]['suggestion_address'] != null){ 3776 if (isDevMode) console.log('???? Using selected suggestion address:', cachedSelectedOption[0]['suggestion_address']); 3777 results[0].formatted_address = cachedSelectedOption[0]['suggestion_address']; 3778 }else if(location_value_in_url != '' && location_value_in_url != 'undefined' && location_value_in_url != null){ 3779 if (isDevMode) console.log('???? Using preloaded location value:', location_value_in_url); 3780 results[0].formatted_address = location_value_in_url; 3781 } 3782 3783 if(cachedSelectedOption && cachedSelectedOption[0] && cachedSelectedOption[0]['geometry']){ 3784 results[0].geometry = cachedSelectedOption[0]['geometry']; 3785 } 3786 3787 if(cachedSelectedOption && cachedSelectedOption[0] && cachedSelectedOption[0]['types']){ 3788 results[0].types = cachedSelectedOption[0]['types']; 3789 } 3790 3791 parseInfoToSearch(results, urlGET, formActionUrl); 3792 } else { 3793 var urlPath = formActionUrl; 3794 var redirect = urlPath + "?" + urlGET; 3795 window.location.href = redirect; 3796 } 3797 }); 3798 3799 } 3800 }); 3801 3802 // Add click handlers for submit buttons 3803 $('.website-search [type=submit]').click(async function (e) { 3804 e.preventDefault(); 3805 var nativeForm = $(this).closest('form')[0]; 3806 if (nativeForm && typeof nativeForm.reportValidity === 'function' && !nativeForm.reportValidity()) { 3807 return false; 3808 } 3809 await initializeGoogleMaps(); 3810 $(this).closest('form').submit(); 3811 }); 3812 3813 // Auto-detect location on page load if settings are enabled
3814 var geocodeVisitorsSetting = '0'; 3815 var geocodingMethod = 'HTML5'; 3816 if (geocodeVisitorsSetting == 1 && (geocodingMethod === "HTML5" || geocodingMethod === "IP") && $('.googleSuggest').length > 0 && $('.googleSuggest').val() == '') { 3817 initializeGoogleMaps().then(function() { 3818 populateSearchFields(); 3819 }); 3820 } 3821 }); 3822 3823 function parseInfoToSearch(results, urlGET, formActionUrl) { 3824 var parameters = {}; 3825 3826 if (!results || !results.length) { 3827 return; 3828 } 3829 3830 const result = results[0]; 3831 // console.log('geocode result',result); 3832 3833 let remainingComponents = [...(result.address_components || [])]; 3834 3835 // Find components in hierarchical order and remove them from the search pool 3836 const countryComponent = remainingComponents.find(comp => comp.types.includes('country')); 3837 if (countryComponent) { 3838 remainingComponents = remainingComponents.filter(comp => comp !== countryComponent); 3839 } 3840 3841 const stateComponent = remainingComponents.find(comp => comp.types.includes('administrative_area_level_1')); 3842 if (stateComponent) { 3843 remainingComponents = remainingComponents.filter(comp => comp !== stateComponent); 3844 } 3845 3846 const countyComponent = remainingComponents.find(comp => comp.types.includes('administrative_area_level_2')); 3847 if (countyComponent) { 3848 remainingComponents = remainingComponents.filter(comp => comp !== countyComponent); 3849 } 3850 3851 const cityComponent = remainingComponents.find(comp => { 3852 if (!comp.types.some(type => cityTypes.includes(type))) { 3853 return false; 3854 } 3855 /* CT counties come back as colloquial_area â never match them as the city. */ 3856 if (comp.types.includes('colloquial_area') 3857 && window.bdIsColloquialCounty(comp.long_name, result.place_id)) { 3858 return false; 3859 } 3860 return true; 3861 }); 3862 if (cityComponent) { 3863 remainingComponents = remainingComponents.filter(comp => comp !== cityComponent); 3864 } 3865 3866 // Match ONLY true postal-code types. postalTypes also contains 3867 // street_number/route/premise (used for city detection), which on 3868 // a premise result captured the street number as the ZIP. 3869 const postalComponent = remainingComponents.find(comp => comp.types.some(type => ['postal_code', 'postal_code_prefix'].includes(type))); 3870 if (postalComponent) { 3871 remainingComponents = remainingComponents.filter(comp => comp !== postalComponent); 3872 } 3873 3874 // Set location value using the formatted address but remove USA 3875 if (result.formatted_address) { 3876 const addressParts = result.formatted_address.split(',').map(part => part.trim()); 3877 // Remove USA from the end if present 3878 if (addressParts[addressParts.length - 1].trim() === 'USA') { 3879 addressParts.pop(); 3880 } 3881 parameters.location_value = addressParts.join(', '); 3882 } else if (result.name) { 3883 parameters.location_value = result.name; 3884 } 3885 3886 // Set address components. 3887 // Preserve the (cityComponent || postalComponent) guard so postal-only 3888 // geocodes still trigger downstream city handling, but only assign 3889 // long_name when cityComponent is actually defined â filtering out 3890 // CT colloquial counties (above) makes cityComponent undefined more 3891 // often, and the previous unconditional .long_name access would throw. 3892 if (cityComponent || postalComponent) { 3893 if (cityComponent) { 3894 parameters.city = cityComponent.long_name; 3895 } 3896 } 3897 if (countyComponent) { 3898 // Remove the extra "County" word 3899 parameters.county_sn = countyComponent.long_name; 3900 if (parameters.county_sn.endsWith('County County')) { 3901 parameters.county_sn = parameters.county_sn.replace('County County', 'County'); 3902 } 3903 } 3904 if (stateComponent) { 3905 parameters.adm_lvl_1_sn = stateComponent.short_name; 3906 parameters.stateSearchLN = stateComponent.long_name; 3907 parameters.stateSearch = stateComponent.short_name; 3908 } 3909 if (countryComponent) { 3910 parameters.country_sn = countryComponent.short_name; 3911 } 3912 if (postalComponent) { 3913 parameters.postal_code = postalComponent.long_name; 3914 } 3915 3916 // Improved location type handling 3917 const types = result.types || []; 3918 3919 // Map Google Places types to our location types 3920 const typeMapping = { 3921 'route': 'route', 3922 'street_address': 'street_address', 3923 'premise': 'premise', 3924 'locality': 'locality', 3925 'postal_code': 'postal_code', 3926 'administrative_area_level_2': 'administrative_area_level_2', 3927 'administrative_area_level_1': 'administrative_area_level_1', 3928 'country': 'country', 3929 'colloquial_area': 'locality', 3930 'sublocality': 'locality', 3931 'sublocality_level_1': 'locality', 3932 'sublocality_level_2': 'locality', 3933 'sublocality_level_3': 'locality', 3934 'sublocality_level_4': 'locality', 3935 'sublocality_level_5': 'locality', 3936 'neighborhood': 'locality', 3937 'political': 'locality', 3938 'postal_town': 'locality', 3939 'natural_feature': 'natural_feature', 3940 'point_of_interest': 'point_of_interest', 3941 'establishment': 'establishment', 3942 'intersection': 'intersection', 3943 'park': 'park', 3944 'ward': 'locality' 3945 }; 3946 3947 // Find the first matching type 3948 parameters.location_type = null; 3949 for (const type of types) { 3950 if (typeMapping[type]) { 3951 parameters.location_type = typeMapping[type]; 3952 break; 3953 } 3954 } 3955 3956 // If no matching type found, use a default 3957 if (!parameters.location_type) { 3958 parameters.location_type = 'locality'; 3959 } 3960 3961 // When searching by city/locality, omit postal_code â Google returns 3962 // a partial zip prefix that doesn't match all members in the city 3963 if (parameters.location_type == 'locality' && parameters.postal_code) { 3964 delete parameters.postal_code; 3965 } 3966 3967 // Set formatted address without USA 3968 if (result.formatted_address) { 3969 parameters.faddress = result.formatted_address.split(',').map(part => part.trim()).filter(part => part !== 'USA').join(', '); 3970 } else { 3971 parameters.faddress = parameters.location_value; 3972 } 3973 3974 // Handle geometry and bounds 3975 if (result.geometry) { 3976 const location = result.geometry.location; 3977 const viewport = result.geometry.viewport; 3978 3979 if (location) { 3980 parameters.lat = typeof location.lat === 'function' ? location.lat() : location.lat; 3981 parameters.lng = typeof location.lng === 'function' ? location.lng() : location.lng; 3982 } 3983 3984 if (viewport) { 3985 const sw = typeof viewport.getSouthWest === 'function' ? viewport.getSouthWest
3985() : viewport.sw; 3986 const ne = typeof viewport.getNorthEast === 'function' ? viewport.getNorthEast() : viewport.ne; 3987 3988 parameters.swlat = typeof sw.lat === 'function' ? sw.lat() : sw.lat; 3989 parameters.nelat = typeof ne.lat === 'function' ? ne.lat() : ne.lat; 3990 parameters.swlng = typeof sw.lng === 'function' ? sw.lng() : sw.lng; 3991 parameters.nelng = typeof ne.lng === 'function' ? ne.lng() : ne.lng; 3992 } 3993 } 3994 3995 parameters.place_id = result.place_id; 3996 3997 // Parse urlGET into a URLSearchParams object 3998 const mergedParams = new URLSearchParams(urlGET); 3999 4000 // Add/override with new parameters 4001 Object.entries(parameters).forEach(([key, value]) => { 4002 if (value !== undefined && value !== null && value !== '') { 4003 mergedParams.set(key, value); // set() will override if already present 4004 } 4005 }); 4006 4007 // Get the final URL 4008 const finalUrl = formActionUrl + "?" + mergedParams.toString(); 4009 window.location.href = finalUrl; 4010 } 4011 4012 async function populateSearchFields(){ 4013 var prePopulateLocationSetting = '0'; 4014 var geolocationMethod = 'HTML5'; 4015 4016 // If coordinates are 0, try to get from sessionStorage 4017 if (vlat === 0 || vlon === 0) { 4018 getCoordinatesFromSession(); 4019 } 4020 4021 if (typeof google != 'undefined' && prePopulateLocationSetting == 1 && (geolocationMethod === "HTML5" || geolocationMethod === "IP") && (vlat !== '' && vlon !== '' && vlat != undefined && vlon != undefined && vlat != 0 && vlon != 0)) { 4022 const visitorLatLng = new google.maps.LatLng(parseFloat(vlat), parseFloat(vlon)); 4023 const geocoder = new google.maps.Geocoder(); 4024 4025 try { 4026 const results = await geocoder.geocode({ location: visitorLatLng }); 4027 4028 if (results.results && results.results[0]) { 4029 const formattedAddress = []; 4030 window.cachedSelectedOption = results.results; 4031 const preFormattedStructure = { 4032 "locality": "long_name", 4033 "administrative_area_level_2": "long_name", 4034 "administrative_area_level_1": "long_name", 4035 "country": "long_name" 4036 }; 4037 4038 Object.entries(preFormattedStructure).forEach(([type, nameType]) => { 4039 const component = results.results[0].address_components.find(comp => comp.types[0] === type); 4040 if (component) { 4041 formattedAddress.push(component[nameType]); 4042 } 4043 }); 4044 4045 $('.googleSuggest').each(function () { 4046 if ($(this).val() == '') { 4047 if (formattedAddress.length > 0) { 4048 $(this).val(formattedAddress.join(', ')); 4049 clearContent($(this)); 4050 } 4051 } 4052 }); 4053 } 4054 } catch (error) { 4055 $('.googleSuggest').each(function () { 4056 $(this).val(''); 4057 }); 4058 } 4059 } 4060 } 4061 4062 function showError(error) { 4063 switch (error.code) { 4064 case error.PERMISSION_DENIED: 4065 $('.fill_location.clicked').popover({ 4066 content: `Your local browser settings have prevented location targeting. Please enable location permissions in your browser settings.`, 4067 container: 'body' 4068 }); 4069 $('.fill_location.clicked').popover('toggle'); 4070 setTimeout(function () { 4071 $('.fill_location.clicked').popover('hide'); 4072 $('.fill_location.clicked').removeClass('clicked'); 4073 }, 2000); 4074 break; 4075 case error.POSITION_UNAVAILABLE: 4076 console.log("Location information is unavailable."); 4077 break; 4078 case error.TIMEOUT: 4079 console.log("The request to get user location timed out."); 4080 break; 4081 case error.UNKNOWN_ERROR: 4082 console.log("An unknown error occurred."); 4083 break; 4084 } 4085 } 4086 4087 if (navigator.geolocation) { 4088 if ($(".googleSuggest")[0]) { 4089 $(document).on('click', '.fill_location', function getCXPosition() { 4090 // Prevent multiple simultaneous geolocation requests 4091 if (isGettingLocation) { 4092 return; 4093 } 4094 4095 var $button = $(this); 4096 $button.addClass('clicked'); 4097 var startPos; 4098 4099 // Set flag to prevent concurrent requests 4100 isGettingLocation = true; 4101 4102 // Function to actually get the position 4103 var attemptGetPosition = function() { 4104 // Try with shorter timeout first for faster response 4105 var geoOptions = {
4106 enableHighAccuracy: false, // Use false for faster response 4107 timeout: 8000, // 8 second timeout (reduced for faster failure) 4108 maximumAge: 300000 // Accept cached position up to 5 minutes old 4109 }; 4110 4111 navigator.geolocation.getCurrentPosition(function (position) { 4112 startPos = position; 4113 vlat = startPos.coords.latitude; 4114 vlon = startPos.coords.longitude; 4115 4116 // Validate coordinates before proceeding 4117 if (!vlat || !vlon || vlat === 0 || vlon === 0) { 4118 isGettingLocation = false; 4119 $button.removeClass('clicked'); 4120 return; 4121 } 4122 4123 // Save coordinates to sessionStorage 4124 saveCoordinatesToSession(vlat, vlon);
4125 4126 $.get("/api/data/html/get/data_widgets/widget_name", { 4127 "vlat": vlat, 4128 "vlon": vlon, 4129 "name": "Website - Save Coordinates Session" 4130 }); 4131 (async function () { 4132 await initializeGoogleMaps(); 4133 populateSearchFields(); 4134 isGettingLocation = false; 4135 $button.removeClass('clicked'); 4136 })(); 4137 }, function(error) { 4138 // Clear flag on error 4139 isGettingLocation = false; 4140 $button.removeClass('clicked'); 4141 4142 // For timeout errors, try sessionStorage as fallback 4143 if (error.code === 3) { 4144 if (getCoordinatesFromSession()) { 4145 // Use cached coordinates 4146 $.get("/api/data/html/get/data_widgets/widget_name", { 4147 "vlat": vlat, 4148 "vlon": vlon, 4149 "name": "Website - Save Coordinates Session" 4150 }); 4151 (async function () { 4152 await initializeGoogleMaps(); 4153 populateSearchFields(); 4154 isGettingLocation = false; 4155 $button.removeClass('clicked'); 4156 })(); 4157 } else { 4158 $button.popover({ 4159 content: `Location request timed out. Please ensure location services are enabled and grant permission when prompted.`, 4160 container: 'body' 4161 }); 4162 $button.popover('show'); 4163 setTimeout(function() { 4164 $button.popover('hide'); 4165 }, 5000); 4166 } 4167 } else { 4168 showError(error); 4169 } 4170 }, geoOptions); 4171 }; 4172 4173 // Check if geolocation permission is already denied (but don't block if it's prompt) 4174 if (navigator.permissions && navigator.permissions.query) { 4175 navigator.permissions.query({name: 'geolocation'}).then(function(result) { 4176 if (result.state === 'denied') { 4177 isGettingLocation = false; 4178 $button.removeClass('clicked'); 4179 showError({code: 1, message: 'Permission denied'}); 4180 return; 4181 } else { 4182 // Permission is granted or prompt - proceed with geolocation 4183 attemptGetPosition(); 4184 } 4185 }).catch(function(err) { 4186 // If permission API not supported, proceed anyway 4187 attemptGetPosition(); 4188 }); 4189 } else { 4190 // Permission API not available, proceed with geolocation 4191 attemptGetPosition(); 4192 } 4193 }) 4194 } 4195 } else { 4196 console.log('Geolocation is not supported for this Browser/OS version yet.'); 4197 } 4198 4199 function getUrlParameter(sParam) { 4200 var sPageURL = window.location.search.substring(1); 4201 var sURLVariables = sPageURL.split('&'); 4202 4203 for (var i = 0; i < sURLVariables.length; i++) { 4204 var sParameterName = sURLVariables[i].split('='); 4205 4206 if (sParameterName[0] == sParam) { 4207 return decodeURIComponent(sParameterName[1]); 4208 } 4209 } 4210 } 4211 </script>
4211 4212 <style> 4213/* YouTube Lazy Load Styles */ 4214.youtube-lazy-container { 4215 position: relative; 4216 display: block; 4217 cursor: pointer; 4218 overflow: hidden; 4219 background: #000; 4220 margin: 0; 4221} 4222.youtube-lazy-thumbnail { 4223 display: block !important; 4224 width: 100% !important; 4225 height: 100% !important; 4226 object-fit: cover !important; 4227 position: absolute !important; 4228 top: 0 !important; 4229 left: 0 !important; 4230 transition: opacity 0.3s; 4231} 4232.youtube-lazy-container iframe { 4233 display: block !important; 4234 width: 100% !important; 4235 height: 100% !important; 4236 position: absolute !important; 4237 top: 0 !important; 4238 left: 0 !important; 4239 border: 0 !important; 4240} 4241.youtube-lazy-play { 4242 position: absolute; 4243 top: 50%; 4244 left: 50%; 4245 transform: translate(-50%, -50%); 4246 width: clamp(40px, 12vw, 68px); 4247 height: clamp(28px, 8.5vw, 48px); 4248 background: rgba(255, 0, 0, 0.8); 4249 border-radius: clamp(8px, 2vw, 12px); 4250 display: flex; 4251 align-items: center; 4252 justify-content: center; 4253 transition: background 0.2s; 4254 z-index: 1; 4255} 4256.youtube-lazy-container:hover .youtube-lazy-play { 4257 background: rgba(255, 0, 0, 1); 4258} 4259.youtube-lazy-play::before { 4260 content: '\F4F4'; 4261 font-family: 'bootstrap-icons'; 4262 color: white; 4263 font-size: clamp(14px, 4vw, 24px); 4264 display: flex; 4265 align-items: center; 4266 justify-content: center; 4267} 4268.fr-view .fr-video { 4269 visibility: hidden; 4270} 4271.fr-box[role="application"] .fr-video { 4272 visibility: visible !important; 4273} 4274.fr-view .fr-video.fr-dvi.fr-fvc:has(.youtube-lazy-container) { 4275 display: inline-block; 4276 position: relative; 4277 left: 50%; 4278 transform: translateX(-50%); 4279} 4280@media only screen and (max-width: 768px) { 4281 .youtube-lazy-container { 4282 aspect-ratio: 16 / 9 !important; 4283 max-width: calc(100vw - 30px) !important; 4284 padding-bottom: 56.25% !important; 4285 } 4286 .fr-video, div:not(.fr-element) p .fr-video.fr-dvi.fr-fvr { 4287 float: none !important; 4288 margin: 0 auto !important; 4289 width: 100% !important; 4290 text-align: center !important; 4291 display: block !important; 4292 max-width: 100% !important; 4293 } 4294} 4295</style>
4296<script> 4297/* YouTube Lazy Load Script */ 4298(function() { 4299 /* CRITICAL: Remove src IMMEDIATELY to prevent YouTube from loading */ 4300 var iframes = document.querySelectorAll('iframe[src*="youtube.com/embed"], iframe[src*="youtube-nocookie.com/embed"]'); 4301 if (!iframes.length) return; 4302 var firstIframe = iframes[0]; 4303 /* ULTRA-PRIORITY: Preload first thumbnail BEFORE anything else for maximum LCP speed */ 4304 try { 4305 var rect = firstIframe.getBoundingClientRect(); 4306 if (rect && rect.top < (window.innerHeight + 50)) { 4307 var src = firstIframe.src || firstIframe.getAttribute('data-src'); 4308 if (src) { 4309 var videoId = null; 4310 var playlistMatch = src.match(/[?&]playlist=([a-zA-Z0-9_-]+)/); 4311 if (playlistMatch && playlistMatch[1]) { 4312 videoId = playlistMatch[1]; 4313 } else { 4314 var embedMatch = src.match(/youtube(?:-nocookie)?\.com\/embed\/([a-zA-Z0-9_-]+)/); 4315 if (embedMatch && embedMatch[1]) { 4316 videoId = embedMatch[1]; 4317 } 4318 } 4319 if (videoId && document.head) { 4320 var thumbnailUrl = 'https://img.youtube.com/vi/' + videoId + '/sddefault.jpg'; 4321 var preloadLink = document.createElement('link'); 4322 preloadLink.rel = 'preload'; 4323 preloadLink.as = 'image'; 4324 preloadLink.href = thumbnailUrl; 4325 preloadLink.fetchpriority = 'high'; 4326 document.head.appendChild(preloadLink); 4327 var img = new Image(); 4328 img.fetchpriority = 'high'; 4329 img.src = thumbnailUrl; 4330 } 4331 } 4332 } 4333 } catch(e) {}; 4334 Array.prototype.forEach.call(iframes, function(iframe) { 4335 if (!iframe.getAttribute('data-youtube-lazy')) { 4336 iframe.setAttribute('data-youtube-src', iframe.src); 4337 iframe.removeAttribute('src'); 4338 iframe.setAttribute('data-youtube-lazy', 'src-removed'); 4339 } 4340 }); 4341 var playerPreconnected = false; 4342 var debounceTimer; 4343 /* Check if we should wait for mobile preloader */ 4344 var isMobile = window.innerWidth <= 768; 4345 var hasPreloader = document.getElementById('mobile-loading-message'); 4346 var shouldWaitForPreloader = isMobile && hasPreloader; 4347 /* Parse pixel values from styles */ 4348 function parsePxValue(value) { 4349 if (!value) return null; 4350 var str = String(value); 4351 if (str.indexOf('%') > -1) return null; 4352 var num = parseInt(str, 10); 4353 return (num > 0) ? num : null; 4354 } 4355 /* Extract video ID from URL */ 4356 function extractYouTubeVideoId(src) { 4357 if (!src) return null; 4358 /* Check for playlist param first (priority) */ 4359 var playlistMatch = src.match(/[?&]playlist=([a-zA-Z0-9_-]+)/); 4360 if (playlistMatch && playlistMatch[1]) { 4361 return playlistMatch[1]; 4362 } 4363 /* Fallback to embed ID */ 4364 var embedMatch = src.match(/youtube(?:-nocookie)?\.com\/embed\/([a-zA-Z0-9_-]+)/); 4365 if (embedMatch && embedMatch[1]) { 4366 return embedMatch[1]; 4367 } 4368 return null; 4369 } 4370 /* Preconnect to www.youtube.com on demand (for player) */ 4371 function preconnectYouTube() { 4372 if (playerPreconnected) return; 4373 if (!document.head) return; 4374 playerPreconnected = true; 4375 var link = document.createElement('link'); 4376 link.rel = 'preconnect'; 4377 link.href = 'https://www.youtube.com'; 4378 document.head.appendChild(link); 4379 } 4380 /* Handle thumbnail loading with fallback */ 4381 function setThumbnailErrorHandler(thumbnail) { 4382 thumbnail.onerror = function() { 4383 thumbnail.style.background = '#333'; 4384 thumbnail.onerror = null; 4385 }; 4386 } 4387 /* Load thumbnail with play button */ 4388 function loadThumbnail(container, videoId, iframe, width, height, parentElement) { 4389 var thumbnail = new Image(); 4390 thumbnail.className = 'youtube-lazy-thumbnail img-rounded'; 4391 var finalWidth = width || 640; 4392 var finalHeight = height || 360; 4393 thumbnail.width = finalWidth; 4394 thumbnail.height = finalHeight; 4395 thumbnail.style.aspectRatio = finalWidth + ' / ' + finalHeight; 4396 var iframeTitle = iframe.getAttribute('title') || iframe.getAttribute('alt'); 4397 if (iframeTitle) { 4398 thumbnail.alt = iframeTitle; 4399 } 4400 var isInViewport = false; 4401 try { 4402 var rect = container.getBoundingClientRect(); 4403 isInViewport = rect.top < (window.innerHeight + 50); 4404 } catch(e) { 4405 isInViewport = true; 4406 } 4407 thumbnail.loading = isInViewport ? 'eager' : 'lazy'; 4408 if (isInViewport) { 4409 thumbnail.fetchPriority = 'high'; 4410 thumbnail.decoding = 'sync'; 4411 } 4412 if (parentElement) { 4413 var revealed = false; 4414 var revealParent = function() { 4415 if (!revealed && parentElement.style.visibility === 'hidden') { 4416 revealed = true; 4417 parentElement.style.visibility = 'visible'; 4418 } 4419 }; 4420 thumbnail.onload = thumbnail.onerror = revealParent; 4421 setTimeout(revealParent, 3000); 4422 } 4423 if (isInViewport) { 4424 thumbnail.src = 'https://img.youtube.com/vi/' + videoId + '/sddefault.jpg'; 4425 setThumbnailErrorHandler(thumbnail);
4426 container.appendChild(thumbnail); 4427 } else { 4428 if (typeof IntersectionObserver !== 'undefined') { 4429 thumbnail.style.opacity = '0'; 4430 container.appendChild(thumbnail); 4431 var observer = new IntersectionObserver(function(entries) { 4432 entries.forEach(function(entry) { 4433 if (entry.isIntersecting) { 4434 thumbnail.src = 'https://img.youtube.com/vi/' + videoId + '/sddefault.jpg'; 4435 setThumbnailErrorHandler(thumbnail); 4436 thumbnail.style.transition = 'opacity 0.3s'; 4437 thumbnail.style.opacity = '1'; 4438 observer.unobserve(container); 4439 } 4440 }); 4441 }, { rootMargin: '100px' }); 4442 observer.observe(container); 4443 } else { 4444 thumbnail.src = 'https://img.youtube.com/vi/' + videoId + '/sddefault.jpg'; 4445 setThumbnailErrorHandler(thumbnail); 4446 container.appendChild(thumbnail); 4447 } 4448 } 4449 /* Add play button and click handler */ 4450 var playButton = document.createElement('div'); 4451 playButton.className = 'youtube-lazy-play'; 4452 container.appendChild(playButton); 4453 var isLoading = false; 4454 container.addEventListener('mouseenter', preconnectYouTube, { once: true }); 4455 container.addEventListener('click', function() { 4456 if (isLoading) return; 4457 isLoading = true; 4458 preconnectYouTube(); 4459 playButton.style.display = 'none'; 4460 thumbnail.style.pointerEvents = 'none'; 4461 var iframeSrc = iframe.getAttribute('data-youtube-src'); 4462 if (!iframeSrc) return; 4463 /* Mobile: the tap gesture is delegated to the iframe via allow="autoplay" so playback can start unmuted */ 4464 var isMobile = window.innerWidth <= 768; 4465 if (isMobile) { 4466 var allowAttr = iframe.getAttribute('allow') || ''; 4467 if (allowAttr.indexOf('autoplay') === -1) { 4468 iframe.setAttribute('allow', (allowAttr ? allowAttr + '; ' : '') + 'autoplay'); 4469 } 4470 iframeSrc += (iframeSrc.indexOf('?') > -1 ? '&' : '?') + 'autoplay=1&playsinline=1'; 4471 } else { 4472 iframeSrc += (iframeSrc.indexOf('?') > -1 ? '&' : '?') + 'autoplay=1'; 4473 } 4474 iframe.setAttribute('loading', 'lazy'); 4475 iframe.src = iframeSrc; 4476 iframe.className = (iframe.className + ' img-rounded').trim(); 4477 iframe.style.opacity = '0'; 4478 container.appendChild(iframe); 4479 setTimeout(function() { 4480 thumbnail.style.transition = 'opacity 0.3s'; 4481 thumbnail.style.opacity = '0'; 4482 iframe.style.transition = 'opacity 0.3s'; 4483 iframe.style.opacity = '1'; 4484 }, 250); 4485 }); 4486 } 4487 /* Process all YouTube iframes on page */ 4488 function processYouTubeIframes() { 4489 var iframes = document.querySelectorAll('iframe[src*="youtube.com/embed"], iframe[src*="youtube-nocookie.com/embed"], iframe[data-youtube-src*="youtube.com/embed"], iframe[data-youtube-src*="youtube-nocookie.com/embed"]'); 4490 Array.prototype.forEach.call(iframes, function(iframe) { 4491 var lazyState = iframe.getAttribute('data-youtube-lazy'); 4492 if (lazyState === 'processed' || lazyState === 'pending') return; 4493 /* Get src - prioritize data-youtube-src over src */ 4494 var originalSrc = iframe.getAttribute('data-youtube-src') || iframe.src; 4495 if (!originalSrc) return; 4496 /* Skip nolazy/forceplay iframes - check for params in URL */ 4497 var hasNoLazy = originalSrc.indexOf('nolazy=1') > -1; 4498 var hasForcePlay = originalSrc.indexOf('forceplay=1') > -1; 4499 if (hasNoLazy || hasForcePlay) { 4500 var cleanSrc = originalSrc.replace(/[?&](nolazy|forceplay)=1/g, '').replace(/\?&/, '?').replace(/[&?]$/, ''); 4501 if (hasForcePlay) { 4502 var separator = cleanSrc.indexOf('?') > -1 ? '&' : '?'; 4503 iframe.src = cleanSrc + separator + 'autoplay=1&mute=1&playsinline=1'; 4504 } else { 4505 iframe.src = cleanSrc; 4506 } 4507 iframe.className = (iframe.className + ' img-rounded').trim(); 4508 /* Reveal parent fr-video span if hidden */ 4509 var parentElement = iframe.parentNode; 4510 if (parentElement && parentElement.classList && parentElement.classList.contains('fr-video')) { 4511 parentElement.style.visibility = 'visible'; 4512 } 4513 iframe.setAttribute('data-youtube-lazy', 'processed'); 4514 return; 4515 } 4516 /* Check if iframe is in or near viewport */ 4517 var rect = iframe.getBoundingClientRect(); 4518 var isNearViewport = rect.top < (window.innerHeight + 200); 4519 if (!isNearViewport) { 4520 /* Below fold - mark as pending */ 4521 iframe.setAttribute('data-youtube-lazy', 'pending'); 4522 /* Set up IntersectionObserver to process later */ 4523 var observer = new IntersectionObserver(function(entries) {
4524 entries.forEach(function(entry) { 4525 if (entry.isIntersecting) { 4526 processSingleIframe(entry.target); 4527 observer.unobserve(entry.target); 4528 } 4529 }); 4530 }, { rootMargin: '200px' }); 4531 observer.observe(iframe); 4532 return; 4533 } 4534 /* In/near viewport - process immediately */ 4535 processSingleIframe(iframe); 4536 }); 4537 } 4538 /* Process a single iframe */ 4539 function processSingleIframe(iframe) { 4540 if (iframe.getAttribute('data-youtube-lazy') === 'processed') return; 4541 iframe.setAttribute('data-youtube-lazy', 'processed'); 4542 var src = iframe.getAttribute('data-youtube-src'); 4543 if (!src) return; 4544 var videoId = extractYouTubeVideoId(src); 4545 if (!videoId) return; 4546 /* Set title for accessibility if missing */ 4547 if (!iframe.getAttribute('title')) { 4548 iframe.setAttribute('title', 'YouTube video player - ' + videoId); 4549 } 4550 /* Create container with proper dimensions */ 4551 var container = document.createElement('div'); 4552 container.className = 'youtube-lazy-container img-rounded'; 4553 var inlineWidth = parsePxValue(iframe.style.width); 4554 var inlineHeight = parsePxValue(iframe.style.height); 4555 var attrWidth = parsePxValue(iframe.getAttribute('width')); 4556 var attrHeight = parsePxValue(iframe.getAttribute('height')); 4557 var width = inlineWidth || attrWidth || iframe.offsetWidth || null; 4558 var height = inlineHeight || attrHeight || iframe.offsetHeight || null; 4559 if (!width && !height) { 4560 width = 560; 4561 height = 315; 4562 } else if (width && !height) { 4563 height = Math.round(width * 9 / 16); 4564 } else if (!width && height) { 4565 width = Math.round(height * 16 / 9); 4566 } 4567 if (width <= 0 || height <= 0) { 4568 width = 560; 4569 height = 315; 4570 } 4571 /* Find constraining parent width (skip wrapper containers like fr-video and embed-responsive) */ 4572 var parentElement = iframe.parentNode; 4573 var constrainingWidth = null; 4574 var isFrVideo = parentElement && parentElement.classList && parentElement.classList.contains('fr-video'); 4575 var isEmbedResponsive = parentElement && parentElement.classList && parentElement.classList.contains('embed-responsive'); 4576 if (parentElement) { 4577 if (isFrVideo) { 4578 /* For fr-video, check grandparent width, use smaller of 2 */ 4579 var grandparent = parentElement.parentNode; 4580 if (grandparent) { 4581 constrainingWidth = grandparent.offsetWidth; 4582 } 4583 } else if (isEmbedResponsive) { 4584 /* For embed-responsive, check grandparent width and use it (ignore iframe dimensions) */ 4585 var grandparent = parentElement.parentNode; 4586 if (grandparent) { 4587 constrainingWidth = grandparent.offsetWidth; 4588 } 4589 } else { 4590 constrainingWidth = parentElement.offsetWidth; 4591 } 4592 } 4593 /* Set responsive dimensions with padding-bottom trick */ 4594 var maxWidth; 4595 if (isEmbedResponsive && constrainingWidth && constrainingWidth > 0) { 4596 /* For embed-responsive, always use grandparent width (fluid container) */ 4597 maxWidth = constrainingWidth; 4598 } else { 4599 /* For fr-video and others, use smaller of: grandparent or iframe width */ 4600 maxWidth = (constrainingWidth && constrainingWidth > 0 && constrainingWidth < width) ? constrainingWidth : width; 4601 } 4602 var paddingBottom = ((height / width) * 100).toFixed(2) + '%'; 4603 container.style.width = '100%'; 4604 container.style.paddingBottom = paddingBottom; 4605 container.style.height = '0'; 4606 /* Set parent fr-video span dimensions to prevent CLS */ 4607 if (isFrVideo) { 4608 parentElement.style.visibility = 'hidden'; 4609 parentElement.className = (parentElement.className + ' img-rounded').trim(); 4610 parentElement.style.width = '100%'; 4611 parentElement.style.maxWidth = maxWidth + 'px'; 4612 parentElement.style.aspectRatio = width + ' / ' + height; 4613 parentElement.setAttribute('width', maxWidth); 4614 parentElement.setAttribute('height', Math.round(maxWidth * (height / width))); 4615 } 4616 if (iframe.style.cssText) { 4617 var inlineStyles = iframe.style.cssText.split(';'); 4618 for (var i = 0; i < inlineStyles.length; i++) { 4619 var style = inlineStyles[i].trim(); 4620 if (style && style.indexOf('width') === -1 && style.indexOf('height') === -1) { 4621 container.style.cssText += style + ';'; 4622 } 4623 } 4624 } 4625 var clonedIframe = iframe.cloneNode(true); 4626 var outerWrapper = document.createElement('div'); 4627 outerWrapper.className = 'youtube-lazy-outer bmargin img-rounded'; 4628 outerWrapper.style.maxWidth = maxWidth + 'px'; 4629 outerWrapper.style.aspectRatio = width + ' / ' + height; 4630 outerWrapper.setAttribute('width', maxWidth); 4631 outerWrapper.setAttribute('height', Math.round(maxWidth * (height / width))); 4632 outerWrapper.appendChild(container); 4633 iframe.parentNode.replaceChild(outerWrapper, iframe); 4634 loadThumbnail(container, videoId, clonedIframe, width, height, isFrVideo ? parentElement : null); 4635 } 4636 /* Remove src from dynamically added iframes (used by MutationObserver) */ 4637 function removeSrcFromAllIframes() { 4638 var iframes = document.querySelectorAll('iframe[src*="youtube.com/embed"], iframe[src*="youtube-nocookie.com/embed"]'); 4639 Array.prototype.forEach.call(iframes, function(iframe) { 4640 if (!iframe.getAttribute('data-youtube-lazy')) { 4641 iframe.setAttribute('data-youtube-src', iframe.src); 4642 iframe.removeAttribute('src'); 4643 iframe.setAttribute('data-youtube-lazy', 'src-removed'); 4644 } 4645 }); 4646 } 4647 /* Wait for preloader on mobile, then init */ 4648 document.addEventListener('DOMContentLoaded', function() { 4649 if (shouldWaitForPreloader) { 4650 setTimeout(initYouTubeLazyLoad, 8000); 4651 } else { 4652 initYouTubeLazyLoad(); 4653 } 4654 }); 4655 /* Initialize lazy load and watch for new videos */ 4656 function initYouTubeLazyLoad() { 4657 try { 4658 processYouTubeIframes(); 4659 if (typeof MutationObserver !== 'undefined') { 4660 var observer = new MutationObserver(function(mutations) { 4661 clearTimeout(debounceTimer); 4662 debounceTimer = setTimeout(function() { 4663 var hasNewIframes = false; 4664 mutations.forEach(function(mutation) { 4665 if (mutation.addedNodes.length > 0) {
4666 mutation.addedNodes.forEach(function(node) { 4667 if (node.nodeType === 1) { 4668 if (node.tagName === 'IFRAME' || (node.querySelectorAll && node.querySelectorAll('iframe').length > 0)) { 4669 hasNewIframes = true; 4670 } 4671 } 4672 }); 4673 } 4674 }); 4675 if (hasNewIframes) { 4676 removeSrcFromAllIframes(); 4677 processYouTubeIframes(); 4678 } 4679 }, 100); 4680 }); 4681 if (document.body) { 4682 observer.observe(document.body, { 4683 childList: true, 4684 subtree: true 4685 }); 4686 } 4687 } 4688 } catch(e) { 4689 // Silently fail - prevent page breaking 4690 } 4691 } 4692})(); 4693</script>
vendor: 2 bytes, line 4693
4693
4694<script> 4695/* === NON-YOUTUBE VIDEO PROVIDERS LAZY LOAD === */ 4696/* Added for Vimeo, Wistia, Spotify, etc. - Independent of YouTube system */ 4697(function() { 4698 try { 4699 var videoProviders = ["brightcove","dailymotion","embedly","facebook.com","giphy","imgur","instagram.com","jwplatform","khanacademy","linkedin.com","loom","pinterest.com","podcasts.apple","reddit","rumble","soundcloud","spotify.com","streamable","ted.com","tiktok","twitch","twitter.com","udemy","vimeo","vidyard","wistia","x.com"]; 4700 if (!videoProviders || videoProviders.length === 0) return; 4701 /* Check if iframe domain matches provider list */ 4702 function isVideoProvider(src) { 4703 if (!src) return false; 4704 var domainMatch = src.match(/^https?:\/\/([^\/\?#]+)/); 4705 if (!domainMatch) return false; 4706 var domain = domainMatch[1].toLowerCase(); 4707 for (var i = 0; i < videoProviders.length; i++) { 4708 if (domain.indexOf(videoProviders[i]) > -1) return true; 4709 } 4710 return false; 4711 } 4712 /* Parse pixel values from styles */ 4713 function parsePx(value) { 4714 if (!value) return null; 4715 var str = String(value); 4716 if (str.indexOf('%') > -1) return null; 4717 var num = parseInt(str, 10); 4718 return (num > 0) ? num : null; 4719 } 4720 /* Check if we should wait for mobile preloader */ 4721 var isMobile = window.innerWidth <= 768; 4722 var hasPreloader = document.getElementById('mobile-loading-message'); 4723 var shouldWaitForPreloader = isMobile && hasPreloader; 4724 /* Strip src from video provider iframes immediately */ 4725 var iframes = document.querySelectorAll('iframe[src]'); 4726 Array.prototype.forEach.call(iframes, function(iframe) { 4727 if (!iframe.getAttribute('data-video-lazy') && isVideoProvider(iframe.src)) { 4728 iframe.setAttribute('data-video-src', iframe.src); 4729 iframe.removeAttribute('src'); 4730 iframe.setAttribute('data-video-lazy', 'removed'); 4731 } 4732 }); 4733 /* Process video iframes */ 4734 function processVideoIframes() { 4735 var iframes = document.querySelectorAll('iframe[data-video-src], iframe[src]'); 4736 Array.prototype.forEach.call(iframes, function(iframe) { 4737 var state = iframe.getAttribute('data-video-lazy'); 4738 if (state === 'processed') return; 4739 var src = iframe.getAttribute('data-video-src') || iframe.src; 4740 if (!src || !isVideoProvider(src)) return; 4741 /* Set title for accessibility if missing (do this early for PageSpeed) */ 4742 if (!iframe.getAttribute('title')) { 4743 var providerName = 'Video'; 4744 for (var i = 0; i < videoProviders.length; i++) { 4745 if (src.indexOf(videoProviders[i]) > -1) { 4746 providerName = videoProviders[i].charAt(0).toUpperCase() + videoProviders[i].slice(1); 4747 break; 4748 } 4749 } 4750 iframe.setAttribute('title', providerName + ' embed player'); 4751 } 4752 /* Check for nolazy/forceplay params */ 4753 if (src.indexOf('nolazy=1') > -1 || src.indexOf('forceplay=1') > -1) { 4754 var cleanSrc = src.replace(/[?&](nolazy|forceplay)=1/g, '').replace(/\?&/, '?').replace(/[&?]$/, ''); 4755 iframe.src = cleanSrc; 4756 iframe.setAttribute('data-video-lazy', 'processed'); 4757 return; 4758 } 4759 /* Check viewport position */ 4760 var rect = iframe.getBoundingClientRect(); 4761 var isNearViewport = rect.top < (window.innerHeight + 200); 4762 if (!isNearViewport) { 4763 iframe.setAttribute('data-video-lazy', 'pending'); 4764 if (typeof IntersectionObserver !== 'undefined') { 4765 var observer = new IntersectionObserver(function(entries) { 4766 entries.forEach(function(entry) { 4767 if (entry.isIntersecting) { 4768 loadVideoIframe(entry.target); 4769 observer.unobserve(entry.target); 4770 } 4771 }); 4772 }, { rootMargin: '200px' }); 4773 observer.observe(iframe); 4774 } 4775 return; 4776 } 4777 /* In viewport - load immediately */ 4778 loadVideoIframe(iframe); 4779 }); 4780 } 4781 /* Load iframe by restoring src */ 4782 function loadVideoIframe(iframe) { 4783 if (iframe.getAttribute('data-video-lazy') === 'processed') return; 4784 iframe.setAttribute('data-video-lazy', 'processed'); 4785 var src = iframe.getAttribute('data-video-src'); 4786 if (!src) return; 4787 /* Check if wrapped in Froala .fr-video span */ 4788 var parentElement = iframe.parentNode; 4789 var isFrVideo = parentElement && parentElement.classList && parentElement.classList.contains('fr-video'); 4790 /* Check if wrapped in Bootstrap .embed-responsive container - its CSS already sizes the iframe to 100% of the container, so inline px dimensions would clobber the responsive sizing */ 4791 var isEmbedResponsive = parentElement && parentElement.classList && parentElement.classList.contains('embed-responsive'); 4792 /* Calculate and set dimensions to prevent CLS */ 4793 var inlineWidth = parsePx(iframe.style.width); 4794 var inlineHeight = parsePx(iframe.style.height); 4795 var attrWidth = parsePx(iframe.getAttribute('width')); 4796 var attrHeight = parsePx(iframe.getAttribute('height')); 4797 var width = inlineWidth || attrWidth || iframe.offsetWidth || 640; 4798 var height = inlineHeight || attrHeight || iframe.offsetHeight || 360; 4799 if (width <= 0 || height <= 0) { 4800 width = 640; 4801 height = 360; 4802 } 4803 if (!isEmbedResponsive) { 4804 iframe.style.width = width + 'px'; 4805 iframe.style.height = height + 'px'; 4806 iframe.style.aspectRatio = width + ' / ' + height; 4807 }
4808 /* Reveal parent .fr-video after load or timeout */ 4809 if (isFrVideo) { 4810 var revealed = false; 4811 var revealParent = function() { 4812 if (!revealed) { 4813 revealed = true; 4814 parentElement.style.visibility = 'visible'; 4815 } 4816 }; 4817 iframe.onload = revealParent; 4818 setTimeout(revealParent, 3000); 4819 } 4820 iframe.src = src; 4821 } 4822 /* Watch for dynamically added iframes */ 4823 function removeNewIframeSrc() { 4824 var iframes = document.querySelectorAll('iframe[src]'); 4825 Array.prototype.forEach.call(iframes, function(iframe) { 4826 if (!iframe.getAttribute('data-video-lazy') && isVideoProvider(iframe.src)) { 4827 iframe.setAttribute('data-video-src', iframe.src); 4828 iframe.removeAttribute('src'); 4829 iframe.setAttribute('data-video-lazy', 'removed'); 4830 } 4831 }); 4832 } 4833 /* Initialize video iframe lazy load */ 4834 function initVideoIframeLazyLoad() { 4835 processVideoIframes(); 4836 if (typeof MutationObserver !== 'undefined') { 4837 var debounce; 4838 var observer = new MutationObserver(function(mutations) { 4839 clearTimeout(debounce); 4840 debounce = setTimeout(function() { 4841 var hasIframes = false; 4842 mutations.forEach(function(mutation) { 4843 if (mutation.addedNodes.length > 0) { 4844 mutation.addedNodes.forEach(function(node) { 4845 if (node.nodeType === 1 && (node.tagName === 'IFRAME' || (node.querySelectorAll && node.querySelectorAll('iframe').length > 0))) { 4846 hasIframes = true; 4847 } 4848 }); 4849 } 4850 }); 4851 if (hasIframes) { 4852 removeNewIframeSrc(); 4853 processVideoIframes(); 4854 } 4855 }, 100); 4856 }); 4857 if (document.body) { 4858 observer.observe(document.body, { childList: true, subtree: true }); 4859 } 4860 } 4861 } 4862 /* Wait for preloader on mobile, then init */ 4863 document.addEventListener('DOMContentLoaded', function() { 4864 if (shouldWaitForPreloader) { 4865 setTimeout(initVideoIframeLazyLoad, 8000); 4866 } else { 4867 initVideoIframeLazyLoad(); 4868 } 4869 }); 4870 } catch(e) { 4871 // Silently fail - prevent page breaking 4872 } 4873})(); 4874</script>
vendor: 2 bytes, line 4874
4874
4875<script> 4876 // switchClass() is jQuery UI (Effects), which is no longer loaded on every page. 4877 // removeClass().addClass() is the same class swap, applied immediately instead of 4878 // after animateClass()'s queued 400ms default. 4879 $(document).ready(function(){ 4880 $('.navbar-header .navbar-toggle.main_menu').click(function(){ 4881 $('.mobile-main-menu').toggleClass('opened'); 4882 }); 4883 $('.mobile-main-menu .sidebar-nav').find('li').each(function(){ 4884 $(this).addClass('hasChildren'); 4885 if ($(this).children('ul').length > 0){ 4886 $(this).prepend('<i class="fa fa-plus" aria-hidden="true"></i>'); 4887 $(this).find('a').after('<div class="clearfix"></div>'); 4888 $(this).find('span').after('<div class="clearfix"></div>'); 4889 } 4890 $(this).append('<div class="clearfix"></div>'); 4891 }); 4892 4893 $('.mobile-main-menu .sidebar-nav li i').click(function(){ 4894 if ($(this).parent().children('ul').length > 0){ 4895 $(this).parent().toggleClass('sub_open'); 4896 } 4897 if ($(this).hasClass('fa-plus')){ 4898 $(this).removeClass('fa-plus').addClass('fa-minus'); 4899 } else { 4900 $(this).removeClass('fa-minus').addClass('fa-plus'); 4901 } 4902 }); 4903 }) 4904 4905 if ($(window).width() > 740 && $(window).width() < 1100) { 4906 4907 $(document).ready(function(){ 4908 $('.tablet-menu .tablet-menu-ul').find('li').each(function(){ 4909 4910 if ($(this).children('ul').length > 0){ 4911 $(this).prepend('<i class="fa fa-plus tablet-fa hidden-sm hidden-md hidden-lg" aria-hidden="true"></i>'); 4912 $(this).find('a').after('<div class="clearfix"></div>'); 4913 var this_link = $(this).children('a').text().replace(/[^\x00-\x7F]/g, "");; 4914 $(this).children('a').html(this_link); 4915 $(this).find('span').after('<div class="clearfix"></div>'); 4916 } 4917 $(this).append('<div class="clearfix"></div>'); 4918 }); 4919 4920 $('.tablet-menu .tablet-menu-ul li i').click(function(){ 4921 4922 if ($(this).parent().children('ul').length > 0){ 4923 $(this).parent().toggleClass('sub_open'); 4924 4925 if ($(this).siblings( "ul" ).hasClass('tablet-block')){ 4926 $(this).siblings( "ul" ).removeClass('tablet-block').addClass('tablet-none'); 4927 } else { 4928 $(this).siblings( "ul" ).addClass( "tablet-block" ); 4929 4930 if ($(this).siblings( "ul" ).hasClass('tablet-none')){ 4931 $(this).siblings( "ul" ).removeClass('tablet-none') 4932 } 4933 4934 if ($(this).parent().siblings().children('ul').hasClass('tablet-block')) { 4935 $(this).parent().siblings().children('ul').removeClass('tablet-block').addClass('tablet-none'); 4936 $(this).parent().siblings().children('i').removeClass('fa-minus').addClass('fa-plus'); 4937 } 4938 4939 if ($(this).parent().siblings().children('ul').children().children('ul').hasClass('tablet-block')) { 4940 $(this).parent().siblings().children('ul').children().children('ul').removeClass('tablet-block').addClass('tablet-none'); 4941 $(this).parent().siblings().children('ul').children().children('i').removeClass('fa-minus').addClass('fa-plus'); 4942 } 4943 4944 if ($(this).siblings('ul').children('ul').children().children('ul').hasClass('tablet-block')) { 4945 $(this).siblings('ul').children('ul').children().children('ul').removeClass('tablet-block').addClass('tablet-none'); 4946 $(this).siblings('ul').children('ul').children().children('i').removeClass('fa-minus').addClass('fa-plus'); 4947 } 4948 4949 } 4950 4951 } 4952 4953 if ($(this).hasClass('fa-plus')){ 4954 $(this).removeClass('fa-plus').addClass('fa-minus'); 4955 } else { 4956 $(this).removeClass('fa-minus').addClass('fa-plus'); 4957 } 4958 }); 4959 }) 4960 } 4961 // Append unique ID attribute for mobile main menu links 4962 $('.mobile-main-menu a,.mobile-main-menu span').attr("id", function() { return $(this).attr("id") + "-mobile" }); 4963</script>
4963 4964
4965<script> 4966 $('#captchaContainer').removeClass('form-control '); 4967 $(".website_url_field").keyup(function(){ 4968 var fieldName = $(this).attr('name'); 4969 $(this).val($(this).val().replace(/\s+/g, '')); 4970 $('#myform').formValidation('revalidateField', fieldName); 4971 }); 4972</script>
vendor: 2 bytes, line 4972
4972
4973<script> 4974 $('#newsletter input[name="email"]').on('keypress', function() { 4975 $("#newsletter > .gdpr_consent_email").show(); 4976 }); 4977 $('#newsletter_signup_footer input[name="email"]').on('keypress', function() { 4978 $("#newsletter_signup_footer > .gdpr_consent_email").show(); 4979 }); 4980</script>
4980
4980<script src="https://www.optimizecdn.com/directory/cdn/bootstrap/formvalidation/current/dist/js/formValidation.min.js"></script>
4980 4981
4981<script src="https://www.optimizecdn.com/directory/cdn/bootstrap/formvalidation/current/dist/js/framework/bootstrap.min.js"></script>
4981 4982
4982<script type="text/javascript"> 4983 function decodeHtml(html) { 4984 var txt = document.createElement("textarea"); 4985 txt.innerHTML = html; 4986 return txt.value; 4987 } 4988 4989 // Override FormValidation URI validator to prevent recursion with URLs that contain @ characters 4990 $(function() { 4991 function applyFix() { 4992 // Check if FormValidation library and URI validator are loaded 4993 if (FormValidation && FormValidation.Validator && FormValidation.Validator.uri) { 4994 FormValidation.Validator.uri.validate = function(validator, $field, options) { 4995 var value = validator.getFieldValue($field, 'uri').trim(); 4996 return value === '' || new RegExp('^https?://[^\\s]+\\.[^\\s]{2,}').test(value); 4997 }; 4998 return true; 4999 } 5000 return false; 5001 } 5002 5003 if (!applyFix()) { 5004 setTimeout(applyFix, 50); 5005 } 5006 }); 5007 </script>
5007 5008
5008<script type="text/javascript"> 5009 5010 var counterSubmit = 0; 5011 $(document).ready(function() { 5012 /* grecaptcha.reset() with no argument always resets widget 0. On a page with two 5013 captcha holders that clears the wrong checkbox, so the widget the visitor solved 5014 keeps a token Google has already spent and every retry fails the security check. 5015 captchaHolders is published by widget 1995 keyed by "<formId>-google-recaptcha"; 5016 an undefined id means no per-form id is known and the arg-less call is used, 5017 exactly as before. */ 5018 function bdCaptchaWidgetId(formId) { 5019 if (typeof captchaHolders === "undefined" || !formId) { 5020 return undefined; 5021 } 5022 /* recaptcha.php renames each holder to "<id>-<counter>" before render (recaptcha.php ~L84), 5023 so captchaHolders is keyed by the RENAMED id - not "<formId>-google-recaptcha". Resolve from 5024 the holder element itself so the counter never has to be reconstructed. */ 5025 var form = document.getElementById(formId); 5026 var holder = form && form.querySelector(".g-recaptcha"); 5027 return holder ? captchaHolders[holder.id] : undefined; 5028 } 5029 5030 function bdCaptchaReset(formId) { 5031 if (typeof grecaptcha === "undefined" || typeof grecaptcha.reset !== "function") { 5032 return; 5033 } 5034 var widgetId = bdCaptchaWidgetId(formId); 5035 if (widgetId === undefined) { 5036 grecaptcha.reset(); 5037 } else { 5038 grecaptcha.reset(widgetId); 5039 } 5040 } 5041 5042 // Ghost-field strip (card d4tk1CMp): the server-side validator config can carry 5043 // rules for fields that are NOT rendered in this form (conditionally-rendered or 5044 // duplicated form configs). Those phantom rules make formValidation mis-evaluate 5045 // isValid(), so an empty required field bypasses validation and submits natively. 5046 // Remove any rule whose field has no matching element before initializing. 5047 // NOTE: this is the ONLY layer re-applied from reverted PR #5902. It strictly 5048 // REMOVES rules (never adds validators, never overrides native submit, never 5049 // intercepts on capture phase, never re-validates on click) â so it cannot 5050 // reproduce the "Save button slides down / nav broken / no success message" 5051 // regression that caused #5902 to be rolled back on site 19413. 5052 var validatorConfig = {"framework":"bootstrap","addOns":{"reCaptcha2":{"element":"captchaContainer","language":"en","theme":"light","siteKey":"","timeout":"120","message":"The captcha is not valid"}},"fields":{"email":{"validators":{"notEmpty":{"message":"Required Field"},"emailAddress":{"message":"Please enter a valid email address"}}}}}; 5053 var formElement = $(`form[name='newsletter_modal_signup_380']`); 5054 if(validatorConfig && validatorConfig.fields) { 5055 Object.keys(validatorConfig.fields).forEach(function(fieldName) { 5056 if(formElement.find('[name="' + fieldName + '"]').length === 0) { 5057 delete validatorConfig.fields[fieldName]; 5058 } 5059 }); 5060 } 5061 5062 // Scroll to the first invalid field when submit fails validation, 5063 // so the user can immediately see why the form will not submit 5064 formElement.on('err.form.fv', function(e) { 5065 var $firstError = $(e.target).find('.form-group.has-error').first(); 5066 if ($firstError.length) { 5067 $('html, body').animate({ scrollTop: $firstError.offset().top - 100 }, 700); 5068 } 5069 }); 5070 5071 formElement.formValidation(validatorConfig).on('success.form.fv', function(e,fvdata) { 5072 5073 if('newsletter_modal_signup' == 'unsubscribe_email'){ 5074 return true; 5075 } 5076 // Prevent form submission 5077 e.preventDefault(); 5078 $form = $(e.target), 5079 fv = $form.data('formValidation'); 5080 5081 // Check HTML5 required fields that FormValidation may not know about 5082 var requiredEmpty = false; 5083 $form.find('[required]').each(function() { 5084 var val = $(this).val(); 5085 if (val === '' || val === null || (typeof val === 'string' && val.trim() === '')) { 5086 requiredEmpty = true; 5087 $(this).closest('.form-group').addClass('has-error'); 5088 if ($(this).siblings('.required-error').length === 0) { 5089 $(this).after('<small class="required-error help-block" style="color:#a94442;">Required Field</small>'); 5090 } 5091 } else { 5092 var $reqGroup = $(this).closest('.form-group'); 5093 $(this).siblings('.required-error').remove(); 5094 // Keep has-error if another validator is still failing for this field 5095 if ($reqGroup.find('small[data-fv-validator][data-fv-result="INVALID"]').length === 0) { 5096 $reqGroup.removeClass('has-error'); 5097 } 5098 } 5099 }); 5100 if (requiredEmpty) { 5101 fv.disableSubmitButtons(false); 5102 counterSubmit = 0; 5103 // Scroll to the first field with an error (HTML5-required scan does 5104 // not trigger err.form.fv, so handle the scroll here too) 5105 var $firstReqError = $form.find('.form-group.has-error').first(); 5106 if ($firstReqError.length) { 5107 $('html, body').animate({ scrollTop: $firstReqError.offset().top - 100 }, 700); 5108 } 5109 return false; 5110 } 5111 5112 var values = $(this).serialize(); 5113 5114 5115 var locationFieldCorrect = true; 5116 5117 if($("#newsletter_modal_signup_380 .location_required").length > 0){ 5118 $("#newsletter_modal_signup_380 .location_required").each(function (index) { 5119 if($(this).data('state') == 1){ 5120 if($('#newsletter_modal_signup_380 input[name="lead_location"]').val() == "" || $('#newsletter_modal_signup_380 input[name="lat"]').val() == "" || $('#newsletter_modal_signup_380 input[name="lng"]').val() == "") { 5121 locationFieldCorrect = false; 5122 } 5123 } 5124 }); 5125 } 5126 5127 if(locationFieldCorrect === false){ 5128 //check that there is a latitude or longitude 5129 swal(`Whoops!`, `The location information is required to submit this form`, "error"); 5130 return false; 5131 } 5132 5133 5134 if (!$(this).attr("action")) { 5135 var action = ''; 5136 5137 } else { 5138 var action = $(this).attr("action"); 5139 } 5140 if (!$(this).attr("method")) { 5141 var method = 'post'; 5142 5143 } else { 5144 var method = $(this).attr("method"); 5145 } 5146 if (!$(this).attr("form_action_type")) { 5147 var form_action_type = 'notification'; 5148 5149 } else { 5150 var form_action_type = $(this).attr("form_action_type"); 5151 } 5152 if (!$(this).attr("form_action_div")) { 5153 /* Empty "ID to Replace" default: prefer #main-content, fall back to legacy #first_container if absent */ 5154 var form_action_div = $('#main-content').length ? '#main-content' : '#first_container'; 5155 5156 } else { 5157 var form_action_div = $(this).attr("form_action_div"); 5158 } 5159 if (!$(this).attr("return_data_type")) { 5160 var return_data_type = 'json'; 5161 5162 } else { 5163 var return_data_type = $(this).attr("return_data_type"); 5164 } 5165 var submitInFlight = counterSubmit != 0 || (Date.now() - ($form.data('bdLastSubmitAt') || 0) < 5000); 5166 if (!submitInFlight) { 5167 if ($("#newsletter_modal_signup_380-notification").html() != "") { 5168 $("#newsletter_modal_signup_380-notification").remove(); 5169 } 5170 if ($(this).find('input[type="submit"]').length > 0) { 5171 $(this).find('input[type="submit"]').before('<div id="newsletter_modal_signup_380-notification" class="alert"></div>'); 5172 5173 } else { 5174 $(this).prepend('<div id="newsletter_modal_signup_380-notification" class="alert"></div>'); 5175 } 5176 } 5177 var notification = $("#newsletter_modal_signup_380-notification"); 5178 5179 if ((form_action_type == "" || form_action_type == "default") && action.indexOf("account") >= 0) { 5180 notification.html(`Processing Request...`).addClass("alert-warning-subtle"); 5181 setTimeout(function(){ 5182 fv.defaultSubmit(); 5183 }, 100); 5184 } else { 5185 notification.html(`Processing Request...`).addClass("alert-warning-subtle"); 5186 if(!submitInFlight) { 5187 counterSubmit++; 5188 $form.data('bdLastSubmitAt', Date.now()); 5189 5190 var fields = $(this).serializeArray(); 5191 var formField = []; 5192 var processData = true; 5193 var contentType = "application/x-www-form-urlencoded; charset=UTF-8"; 5194 5195 5196 5197 if($("#newsletter_modal_signup_380 input[type=file]").length > 0){ 5198 5199 var formObject = new FormData(); 5200 processData = false; 5201 contentType = false; 5202 5203 $(fields).each(function(index,field){ 5204 formField.push(field.name+"="+field.value); 5205 }); 5206 5207 values = formField.join("&"); 5208 5209 $(formField).each(function(index,fieldValue){ 5210 var fieldInfo = fieldValue.split('='); 5211 formObject.append(fieldInfo[0],fieldInfo[1]); 5212 }); 5213 5214 $("#newsletter_modal_signup_380 input[type=file]").each(function(index,node){ 5215 var file = this.files[0]; 5216 if(typeof file != "undefined"){ 5217 formObject.append("file_addon["+$(node).attr('name')+"]", file, file.name); 5218 } 5219 }); 5220 }else{ 5221 5222 $(fields).each(function(index,field){ 5223 formField.push(field.name+"="+encodeURIComponent(field.value)); 5224 }); 5225 5226 var formObject = formField.join("&"); 5227 } 5228 5229 $.ajax({
5230 url: action, 5231 type: method, 5232 data: formObject, 5233 dataType: return_data_type, 5234 processData: processData, 5235 contentType: contentType, 5236 success: function (data) { 5237 // Re-query live node: success.form.fv fires twice, orphaning the closure ref captured above. 5238 notification = $("#newsletter_modal_signup_380-notification"); 5239 if (return_data_type == "html") { 5240 var result = 'success'; 5241 5242 if (!data != "") { 5243 var result_widget = data['result_widget']; 5244 } 5245 5246 } else { 5247 5248 5249 if (!data['result']) { 5250 var result = 'error'; 5251 } else { 5252 var result = data['result']; 5253 } 5254 if (!data['result_widget']) { 5255 var result_widget = ''; 5256 5257 } else { 5258 var result_widget = data['result_widget']; 5259 } 5260 } 5261 if (result == "success") { 5262 5263 if (!data['message']) { 5264 var message = `Your information has submitted successfully!`; 5265 5266 } else { 5267 var message = data['message']; 5268 } 5269 if (!data['redirect_url']) { 5270 var redirect_url = ''; 5271 5272 } else { 5273 var redirect_url = data['redirect_url']; 5274 } 5275 5276 5277 5278 if (form_action_type == "notification") { 5279 if (redirect_url && (action.indexOf('Member%20Login%20Page') >= 0 || action.indexOf('Member Login Page') >= 0)) { 5280 if (redirect_url.substring(0, 1) != "/" && redirect_url.substring(0, 1) != "h") { 5281 redirect_url = "/" + redirect_url; 5282 } 5283 if (notification.parents('.modal').length) { 5284 $('.modal-backdrop').hide(); 5285 $('.modal').modal('hide'); 5286 } 5287 window.location.href = redirect_url; 5288 fv.resetForm(true); 5289 } else { 5290 notification.html(message + '<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>') 5291 .addClass('alert-dismissible') 5292 .addClass("alert-success-subtle") 5293 .removeClass("alert-danger-subtle") 5294 .removeClass("alert-warning-subtle") 5295 5296 5297 5298 if(notification.parents('.modal').length && 'newsletter_modal_signup_380' == 'whmcs_billing_address'){ 5299 setTimeout(function(){ 5300 notification.parents('.modal').modal('hide'); 5301 }, 1000); 5302 } 5303 } 5304 5305 } else if (form_action_type == "widget") { 5306 5307 if (result_widget != '') { 5308 5309 setTimeout(function(){ 5310 if(form_action_div != '.newsletter_modal_form_container'){ 5311 $("html, body").animate({ scrollTop: 0 }, 600); 5312 } 5313 $(form_action_div).html(decodeHtml(result_widget)).text(); 5314 5315 }, 1000); 5316 } 5317 5318 } else if (form_action_type == "redirect") { 5319 5320 if (redirect_url == "") { 5321 redirect_url = decodeURIComponent(""); 5322 } 5323 5324 if (redirect_url.substring(0, 1) != "/" && redirect_url.substring(0, 1) != "h") { 5325 redirect_url = "/" + redirect_url; 5326 } 5327 current_location = "/join"; 5328 refresh_pages_string = "/login"; 5329 refresh_pages_string = refresh_pages_string.replace(/ /g,''); 5330 refresh_pages_array = refresh_pages_string.split(','); 5331 notification.html(message) 5332 .addClass("alert-success-subtle") 5333 .removeClass("alert-danger-subtle") 5334 .removeClass("alert-warning-subtle") 5335 .delay(2000).slideUp(); 5336 if(action == "/api/widget/json/get/Bootstrap%20Theme%20-%20Member%20Login%20Page" && current_location.indexOf("/login") == -1 && refresh_pages_string != '' && (!refresh_pages_array.includes(current_location) || refresh_pages_string == "/login" )){ 5337 window.location.href = window.location.href+'?logged'; 5338 } else { 5339 window.location.href = redirect_url; 5340 } 5341 5342 fv.resetForm(true); 5343 } 5344 if(form_action_div != '.newsletter_modal_form_container' && 'newsletter_modal_signup_380' != 'whmcs_billing_address'){ 5345 $('.modal-backdrop').hide(); 5346 } 5347 } else { 5348 bdCaptchaReset(formElement.attr('id')); 5349 if (!data['message']) { 5350 var message = `You entered invali
5350d data. Please try to save again.`; 5351 5352 } else { 5353 var message = data['message']; 5354 } 5355 $("#newsletter_modal_signup_380-notification").html(message) 5356 .addClass("alert-danger-subtle") 5357 .removeClass("alert-success-subtle") 5358 .removeClass("alert-warning-subtle") 5359 .fadeIn(); 5360 fv.disableSubmitButtons(false); 5361 } 5362 counterSubmit = 0; 5363 }, 5364 error: function (e) { 5365 5366 if(typeof grecaptcha !== "undefined" && typeof grecaptcha.reset === "function"){ 5367 bdCaptchaReset(formElement.attr('id')); 5368 $("#newsletter_modal_signup_380-notification").html(`Recaptcha Error`); 5369 } else { 5370 $("#newsletter_modal_signup_380-notification").html(`A connection error occurred while saving. Please try to save again.`); 5371 } 5372 $("#newsletter_modal_signup_380-notification").addClass("alert-warning-subtle") 5373 .removeClass("alert-success-subtle") 5374 .removeClass("alert-warning-subtle") 5375 .fadeIn(); 5376 counterSubmit = 0; 5377 } 5378 });/// End Ajax 5379 } 5380 }//END else 5381 }).bind('keydown', function(event) { 5382 5383 if (event.ctrlKey || event.metaKey) { 5384 5385 switch (String.fromCharCode(event.which).toLowerCase()) { 5386 5387 case 's': 5388 var nativeForm = $(this)[0]; 5389 if (nativeForm && typeof nativeForm.reportValidity === 'function' && !nativeForm.reportValidity()) { 5390 event.preventDefault(); 5391 return false; 5392 } 5393 $(this).submit(); 5394 break; 5395 } 5396 } 5397 }); 5398 5399 /// This will turn any select2 that are required in the form builder to being required elements. 5400 $('#newsletter_modal_signup_380 select').each(function (i, obj) { 5401 setTimeout(function(){ 5402 if ($(obj).prop("required") && $(obj).attr("style") == "display: none;") { 5403 $(obj).css("z-index","-999"); 5404 $(obj).css("height","0"); 5405 $(obj).css("width","0"); 5406 $(obj).css("display","block"); 5407 $(obj).css("position","absolute"); 5408 } 5409 }, 3000); 5410 }); 5411 5412 // Clear required-error messages when user fills in a required field 5413 $('#newsletter_modal_signup_380').on('keyup change', '[required]', function() { 5414 var val = $(this).val(); 5415 if (val !== '' && val !== null && val.trim() !== '') { 5416 var $group = $(this).closest('.form-group'); 5417 // Remove only this handler's own required message 5418 $(this).siblings('.required-error').remove(); 5419 // Keep has-error if another FormValidation validator is still failing 5420 // (e.g. stringLength, regexp). has-error is shared, so removing it 5421 // wholesale would clobber other validators' red styling. 5422 if ($group.find('small[data-fv-validator][data-fv-result="INVALID"]').length === 0) { 5423 $group.removeClass('has-error'); 5424 } 5425 } 5426 }); 5427 5428 });//END $('# echo $_SERVER[form_element_id]; ').formValidation( 5429 </script>
5429 5430 <div class="modal fade" id="newsletter_subscribe_modal" tabindex="-1" role="dialog" aria-hidden="true"> 5431 <div class="modal-dialog"> 5432 <div class="modal-content"> 5433 <div class="container-fluid"> 5434 <div class="row"> 5435 <div class="col-md-12"> 5436 <br> 5437 <button type="button" class="close" data-dismiss="modal" aria-label="Close"> 5438 <span aria-hidden="true">×</span> 5439 </button> 5440 <h3 class="nomargin"> 5441 Join Our Newsletter 5442 </h3> 5443 <hr> 5444 <div class="newsletter_modal_form_container"> 5445 <style type="text/css">label span.required { color: #B94A48; }span.help-inline, span.help-block {font-size: .9em; }</style><form action="/api/widget/json/get/Bootstrap%20Theme%20-%20Module%20-%20Newsletter%20Actions" id="newsletter_modal_signup_380" method="post" labelwidth="100" labelpaddingtop="0.5em" enctype="multipart/form-data" form_action_type="widget" form_action_div=".newsletter_modal_form_container" return_data_type="" name="newsletter_modal_signup_380" class=" "><input type="hidden" name="sized" value="0" id="newsletter_modal_signup_380-element-0"/><input type="hidden" name="form" value="myform" id="newsletter_modal_signup_380-element-1"/><input type="hidden" name="formname" value="newsletter_modal_signup" id="newsletter_modal_signup_380-element-2"/><input type="hidden" name="dowiz" value="1" id="newsletter_modal_signup_380-element-3"/><input type="hidden" name="save" value="1" id="newsletter_modal_signup_380-element-4"/><input type="hidden" name="url_origin_pars" value="/join" id="newsletter_modal_signup_380-element-5"/><input type="hidden" name="action" autocomplete="off" value="subscribe" id="newsletter_modal_signup_380-element-6"/><div class="form-group"><input type="text" name="first_name" placeholder="Name" autocomplete="off" value class="form-control control-group form-control " id="newsletter_modal_signup_380-element-7"/></div><div class="form-group"><input type="email" name="email" required placeholder="Enter email address" autocomplete="off" value class="form-control control-group form-control" id="newsletter_modal_signup_380-element-8"/></div><div class="form-group"><div class="form-group security_question_label"> 5446 <div id="newsletter_modal_signup_380-captchaContainer" class="control-group"> 5447 <div class="g-recaptcha" id="newsletter_modal_signup_380-google-recaptcha"></div> 5448 </div> 5449 <small class="help-block" id="recaptcha_error" style="display:none;" data-fv-validator="notEmpty" data-fv-for="recaptcha" data-fv-result="INVALID" />The security check was not completed successfully.</small> 5450 <div class="clearfix bmargin"></div> 5451 <input type="hidden" name="recaptcha" id="newsletter_modal_signup_380-rcap"> 5452</div> 5453 <style> 5454 .modal .g-recaptcha-scale, .col-md-4 .g-recaptcha-scale, .col-md-3 .g-recaptcha-scale, .col-lg-3 .g-recaptcha-scale, .col-lg-4 .g-recaptcha-scale { 5455 transform: scale(0.77); 5456 -webkit-transform: scale(0.77); 5457 transform-origin: 0 0; 5458 -webkit-transform-origin: 0 0; 5459 margin-bottom: -15px; 5460 } 5461 5462 .modal #newsletter_modal_signup_380-captchaContainer, .col-md-4 #newsletter_modal_signup_380-captchaContainer, .col-md-3 #newsletter_modal_signup_380-captchaContainer, .col-lg-3 #newsletter_modal_signup_380-captchaContainer, .col-lg-4 #newsletter_modal_signup_380-captchaContainer { 5463 transform: scale(0.77); 5464 -webkit-transform: scale(0.77); 5465 transform-origin: 0 0; 5466 -webkit-transform-origin: 0 0; 5467 margin-bottom: -15px; 5468 } 5469 </style>
5470<script> 5471 $(document).ready(function(){ 5472 $("#newsletter_modal_signup_380 input[type=submit]").unbind('click'); 5473 $("#newsletter_modal_signup_380 input[type=submit]").click(function (event) { 5474 5475 var formId = $(this.form).attr('id'); 5476 var captchaHolderKey = formId + "-google-recaptcha-" +$(this.form).data('counter'); 5477 5478 if (typeof captchaHolders[captchaHolderKey] != "undefined") { 5479 if (grecaptcha.getResponse(captchaHolders[captchaHolderKey]) === "") { 5480 event.preventDefault(); 5481 $("#" + formId).formValidation('validate'); 5482 $("#" + formId + " .security_question_label").addClass("has-error"); 5483 $("#" + formId + " #recaptcha_error").css("display", "block"); 5484 return false; 5485 } 5486 5487 /* Solved captcha: clear the error UI and let the click proceed untouched. 5488 The browser then fires a REAL, button-initiated submit event, so 5489 FormValidation runs its normal chain (success.form.fv -> AJAX modal on 5490 checkout / native POST on login). Re-submitting here artificially broke 5491 both ways: native form.submit() skips the FV chain (checkout rendered the 5492 raw JSON response), and jQuery .submit() fires a synthetic submit that FV 5493 refuses, leaving the form stuck after the first error (Bug 2). */ 5494 $("#" + formId + " .security_question_label").removeClass("has-error"); 5495 $("#" + formId + " #recaptcha_error").css("display", "none"); 5496 } 5497 }); 5498 }); 5499</script>
5499</div><div class="form-group"><input type="hidden" name="bd_hpc" autocomplete="off" value class="form-control control-group " id="newsletter_modal_signup_380-element-11"/></div><div class="form-actions"><input type="submit" value="Subscribe Now" name class="btn btn-primary btn-block btn-lg bold " id="newsletter_modal_signup_380-element-12"/></div><input type='hidden' name='origin' value='/join'></form>
5499<script type="text/javascript">jQuery(document).ready(function() { jQuery("#newsletter_modal_signup_380").bind("submit", function() { 5500 });}); </script>
5500 </div> 5501 <br> 5502 </div> 5503 </div> 5504 </div> 5505 </div> 5506 </div> 5507</div>
5507<script type="text/javascript"> 5508(function () { 5509 try { 5510 var email = new URLSearchParams(window.location.search).get('email'); 5511 if (!email) { return; } 5512 email = email.trim(); 5513 if (email.indexOf('@') === -1) { return; } 5514 /* Sets the input value property (never HTML) -> XSS-safe regardless of the query value. */ 5515 var fill = function () { 5516 var fields = document.querySelectorAll('input[name="email_r"]'); 5517 for (var i = 0; i < fields.length; i++) { 5518 if (!fields[i].value) { fields[i].value = email; } 5519 } 5520 }; 5521 if (document.readyState === 'loading') { 5522 document.addEventListener('DOMContentLoaded', fill); 5523 } else { 5524 fill(); 5525 } 5526 } catch (e) {} 5527})(); 5528</script>
5528 5529
5529<script type="text/javascript"> 5530 5531 var counterSubmit = 0; 5532 $(document).ready(function() { 5533 /* grecaptcha.reset() with no argument always resets widget 0. On a page with two 5534 captcha holders that clears the wrong checkbox, so the widget the visitor solved 5535 keeps a token Google has already spent and every retry fails the security check. 5536 captchaHolders is published by widget 1995 keyed by "<formId>-google-recaptcha"; 5537 an undefined id means no per-form id is known and the arg-less call is used, 5538 exactly as before. */ 5539 function bdCaptchaWidgetId(formId) { 5540 if (typeof captchaHolders === "undefined" || !formId) { 5541 return undefined; 5542 } 5543 /* recaptcha.php renames each holder to "<id>-<counter>" before render (recaptcha.php ~L84), 5544 so captchaHolders is keyed by the RENAMED id - not "<formId>-google-recaptcha". Resolve from 5545 the holder element itself so the counter never has to be reconstructed. */ 5546 var form = document.getElementById(formId); 5547 var holder = form && form.querySelector(".g-recaptcha"); 5548 return holder ? captchaHolders[holder.id] : undefined; 5549 } 5550 5551 function bdCaptchaReset(formId) { 5552 if (typeof grecaptcha === "undefined" || typeof grecaptcha.reset !== "function") { 5553 return; 5554 } 5555 var widgetId = bdCaptchaWidgetId(formId); 5556 if (widgetId === undefined) { 5557 grecaptcha.reset(); 5558 } else { 5559 grecaptcha.reset(widgetId); 5560 } 5561 } 5562 5563 // Ghost-field strip (card d4tk1CMp): the server-side validator config can carry 5564 // rules for fields that are NOT rendered in this form (conditionally-rendered or 5565 // duplicated form configs). Those phantom rules make formValidation mis-evaluate 5566 // isValid(), so an empty required field bypasses validation and submits natively. 5567 // Remove any rule whose field has no matching element before initializing. 5568 // NOTE: this is the ONLY layer re-applied from reverted PR #5902. It strictly 5569 // REMOVES rules (never adds validators, never overrides native submit, never 5570 // intercepts on capture phase, never re-validates on click) â so it cannot 5571 // reproduce the "Save button slides down / nav broken / no success message" 5572 // regression that caused #5902 to be rolled back on site 19413. 5573 var validatorConfig = {"framework":"bootstrap","addOns":{"reCaptcha2":{"element":"captchaContainer","language":"en","theme":"light","siteKey":"","timeout":"120","message":"The captcha is not valid"}},"fields":{"email":{"validators":{"notEmpty":{"message":"Required Field"},"emailAddress":{"message":"Please enter a valid email address"}}},"pass":{"validators":{"notEmpty":{"message":"Required Field"}}}}}; 5574 var formElement = $(`form[name='member_login_190']`); 5575 if(validatorConfig && validatorConfig.fields) { 5576 Object.keys(validatorConfig.fields).forEach(function(fieldName) { 5577 if(formElement.find('[name="' + fieldName + '"]').length === 0) { 5578 delete validatorConfig.fields[fieldName]; 5579 } 5580 }); 5581 } 5582 5583 // Scroll to the first invalid field when submit fails validation, 5584 // so the user can immediately see why the form will not submit 5585 formElement.on('err.form.fv', function(e) { 5586 var $firstError = $(e.target).find('.form-group.has-error').first(); 5587 if ($firstError.length) { 5588 $('html, body').animate({ scrollTop: $firstError.offset().top - 100 }, 700); 5589 } 5590 }); 5591 5592 formElement.formValidation(validatorConfig).on('success.form.fv', function(e,fvdata) { 5593 5594 if('member_login' == 'unsubscribe_email'){ 5595 return true; 5596 } 5597 // Prevent form submission 5598 e.preventDefault(); 5599 $form = $(e.target), 5600 fv = $form.data('formValidation'); 5601 5602 // Check HTML5 required fields that FormValidation may not know about 5603 var requiredEmpty = false; 5604 $form.find('[required]').each(function() { 5605 var val = $(this).val(); 5606 if (val === '' || val === null || (typeof val === 'string' && val.trim() === '')) { 5607 requiredEmpty = true; 5608 $(this).closest('.form-group').addClass('has-error'); 5609 if ($(this).siblings('.required-error').length === 0) { 5610 $(this).after('<small class="required-error help-block" style="color:#a94442;">Required Field</small>'); 5611 } 5612 } else { 5613 var $reqGroup = $(this).closest('.form-group'); 5614 $(this).siblings('.required-error').remove(); 5615 // Keep has-error if another validator is still failing for this field 5616 if ($reqGroup.find('small[data-fv-validator][data-fv-result="INVALID"]').length === 0) { 5617 $reqGroup.removeClass('has-error'); 5618 } 5619 } 5620 }); 5621 if (requiredEmpty) { 5622 fv.disableSubmitButtons(false); 5623 counterSubmit = 0; 5624 // Scroll to the first field with an error (HTML5-required scan does 5625 // not trigger err.form.fv, so handle the scroll here too) 5626 var $firstReqError = $form.find('.form-group.has-error').first(); 5627 if ($firstReqError.length) { 5628 $('html, body').animate({ scrollTop: $firstReqError.offset().top - 100 }, 700); 5629 } 5630 return false; 5631 } 5632 5633 var values = $(this).serialize(); 5634 5635 5636 var locationFieldCorrect = true; 5637 5638 if($("#member_login_190 .location_required").length > 0){ 5639 $("#member_login_190 .location_required").each(function (index) { 5640 if($(this).data('state') == 1){ 5641 if($('#member_login_190 input[name="lead_location"]').val() == "" || $('#member_login_190 input[name="lat"]').val() == "" || $('#member_login_190 input[name="lng"]').val() == "") { 5642 locationFieldCorrect = false; 5643 } 5644 } 5645 }); 5646 } 5647 5648 if(locationFieldCorrect === false){ 5649 //check that there is a latitude or longitude 5650 swal(`Whoops!`, `The location information is required to submit this form`, "error"); 5651 return false; 5652 } 5653 5654 5655 if (!$(this).attr("action")) { 5656 var action = ''; 5657 5658 } else { 5659 var action = $(this).attr("action"); 5660 } 5661 if (!$(this).attr("method")) { 5662 var method = 'post'; 5663 5664 } else { 5665 var method = $(this).attr("method"); 5666 } 5667 if (!$(this).attr("form_action_type")) { 5668 var form_action_type = 'notification'; 5669 5670 } else { 5671 var form_action_type = $(this).attr("form_action_type"); 5672 } 5673 if (!$(this).attr("form_action_div")) { 5674 /* Empty "ID to Replace" default: prefer #main-content, fall back to legacy #first_container if absent */ 5675 var form_action_div = $('#main-content').length ? '#main-content' : '#first_container'; 5676 5677 } else { 5678 var form_action_div = $(this).attr("form_action_div"); 5679 } 5680 if (!$(this).attr("return_data_type")) { 5681 var return_data_type = 'json'; 5682 5683 } else { 5684 var return_data_type = $(this).attr("return_data_type"); 5685 } 5686 var submitInFlight = counterSubmit != 0 || (Date.now() - ($form.data('bdLastSubmitAt') || 0) < 5000); 5687 if (!submitInFlight) { 5688 if ($("#member_login_190-notification").html() != "") { 5689 $("#member_login_190-notification").remove(); 5690 } 5691 if ($(this).find('input[type="submit"]').length > 0) { 5692 $(this).find('input[type="submit"]').before('<div id="member_login_190-notification" class="alert"></div>'); 5693 5694 } else { 5695 $(this).prepend('<div id="member_login_190-notification" class="alert"></div>'); 5696 } 5697 } 5698 var notification = $("#member_login_190-notification"); 5699 5700 if ((form_action_type == "" || form_action_type == "default") && action.indexOf("account") >= 0) { 5701 notification.html(`Processing Request...`).addClass("alert-warning-subtle"); 5702 setTimeout(function(){ 5703 fv.defaultSubmit(); 5704 }, 100); 5705 } else { 5706 notification.html(`Processing Request...`).addClass("alert-warning-subtle"); 5707 if(!submitInFlight) { 5708 counterSubmit++; 5709 $form.data('bdLastSubmitAt', Date.now()); 5710 5711 var fields = $(this).serializeArray(); 5712 var formField = []; 5713 var processData = true; 5714 var contentType = "application/x-www-form-urlencoded; charset=UTF-8"; 5715 5716 5717 5718 if($("#member_login_190 input[type=file]").length > 0){ 5719 5720 var formObject = new FormData(); 5721 processData = false; 5722 contentType = false; 5723 5724 $(fields).each(function(index,field){ 5725 formField.push(field.name+"="+field.value); 5726 }); 5727 5728 values = formField.join("&"); 5729 5730 $(formField).each(function(index,fieldValue){ 5731 var fieldInfo = fieldValue.split('='); 5732 formObject.append(fieldInfo[0],fieldInfo[1]); 5733 }); 5734 5735 $("#member_login_190 input[type=file]").each(function(index,node){ 5736 var file = this.files[0]; 5737 if(typeof file != "undefined"){ 5738 formObject.append("file_addon["+$(node).attr('name')+"]", file, file.name); 5739 } 5740 }); 5741 }else{ 5742 5743 $(fields).each(function(index,field){ 5744 formField.push(field.name+"="+encodeURIComponent(field.value)); 5745 }); 5746 5747 var formObject = formField.join("&"); 5748 } 5749 5750 $.ajax({
5751 url: action, 5752 type: method, 5753 data: formObject, 5754 dataType: return_data_type, 5755 processData: processData, 5756 contentType: contentType, 5757 success: function (data) { 5758 // Re-query live node: success.form.fv fires twice, orphaning the closure ref captured above. 5759 notification = $("#member_login_190-notification"); 5760 if (return_data_type == "html") { 5761 var result = 'success'; 5762 5763 if (!data != "") { 5764 var result_widget = data['result_widget']; 5765 } 5766 5767 } else { 5768 5769 5770 if (!data['result']) { 5771 var result = 'error'; 5772 } else { 5773 var result = data['result']; 5774 } 5775 if (!data['result_widget']) { 5776 var result_widget = ''; 5777 5778 } else { 5779 var result_widget = data['result_widget']; 5780 } 5781 } 5782 if (result == "success") { 5783 5784 if (!data['message']) { 5785 var message = `Your information has submitted successfully!`; 5786 5787 } else { 5788 var message = data['message']; 5789 } 5790 if (!data['redirect_url']) { 5791 var redirect_url = ''; 5792 5793 } else { 5794 var redirect_url = data['redirect_url']; 5795 } 5796 5797 5798 5799 if (form_action_type == "notification") { 5800 if (redirect_url && (action.indexOf('Member%20Login%20Page') >= 0 || action.indexOf('Member Login Page') >= 0)) { 5801 if (redirect_url.substring(0, 1) != "/" && redirect_url.substring(0, 1) != "h") { 5802 redirect_url = "/" + redirect_url; 5803 } 5804 if (notification.parents('.modal').length) { 5805 $('.modal-backdrop').hide(); 5806 $('.modal').modal('hide'); 5807 } 5808 window.location.href = redirect_url; 5809 fv.resetForm(true); 5810 } else { 5811 notification.html(message + '<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>') 5812 .addClass('alert-dismissible') 5813 .addClass("alert-success-subtle") 5814 .removeClass("alert-danger-subtle") 5815 .removeClass("alert-warning-subtle") 5816 5817 5818 5819 if(notification.parents('.modal').length && 'member_login_190' == 'whmcs_billing_address'){ 5820 setTimeout(function(){ 5821 notification.parents('.modal').modal('hide'); 5822 }, 1000); 5823 } 5824 } 5825 5826 } else if (form_action_type == "widget") { 5827 5828 if (result_widget != '') { 5829 5830 setTimeout(function(){ 5831 if(form_action_div != '.newsletter_modal_form_container'){ 5832 $("html, body").animate({ scrollTop: 0 }, 600); 5833 } 5834 $(form_action_div).html(decodeHtml(result_widget)).text(); 5835 5836 }, 1000); 5837 } 5838 5839 } else if (form_action_type == "redirect") { 5840 5841 if (redirect_url == "") { 5842 redirect_url = decodeURIComponent(""); 5843 } 5844 5845 if (redirect_url.substring(0, 1) != "/" && redirect_url.substring(0, 1) != "h") { 5846 redirect_url = "/" + redirect_url; 5847 } 5848 current_location = "/join"; 5849 refresh_pages_string = "/login"; 5850 refresh_pages_string = refresh_pages_string.replace(/ /g,''); 5851 refresh_pages_array = refresh_pages_string.split(','); 5852 notification.html(message) 5853 .addClass("alert-success-subtle") 5854 .removeClass("alert-danger-subtle") 5855 .removeClass("alert-warning-subtle") 5856 .delay(2000).slideUp(); 5857 if(action == "/api/widget/json/get/Bootstrap%20Theme%20-%20Member%20Login%20Page" && current_location.indexOf("/login") == -1 && refresh_pages_string != '' && (!refresh_pages_array.includes(current_location) || refresh_pages_string == "/login" )){ 5858 window.location.href = window.location.href+'?logged'; 5859 } else { 5860 window.location.href = redirect_url; 5861 } 5862 5863 fv.resetForm(true); 5864 } 5865 if(form_action_div != '.newsletter_modal_form_container' && 'member_login_190' != 'whmcs_billing_address'){ 5866 $('.modal-backdrop').hide(); 5867 } 5868 } else { 5869 bdCaptchaReset(formElement.attr('id')); 5870 if (!data['message']) { 5871 var message = `You entered invali
5871d data. Please try to save again.`; 5872 5873 } else { 5874 var message = data['message']; 5875 } 5876 $("#member_login_190-notification").html(message) 5877 .addClass("alert-danger-subtle") 5878 .removeClass("alert-success-subtle") 5879 .removeClass("alert-warning-subtle") 5880 .fadeIn(); 5881 fv.disableSubmitButtons(false); 5882 } 5883 counterSubmit = 0; 5884 }, 5885 error: function (e) { 5886 5887 if(typeof grecaptcha !== "undefined" && typeof grecaptcha.reset === "function"){ 5888 bdCaptchaReset(formElement.attr('id')); 5889 $("#member_login_190-notification").html(`Recaptcha Error`); 5890 } else { 5891 $("#member_login_190-notification").html(`A connection error occurred while saving. Please try to save again.`); 5892 } 5893 $("#member_login_190-notification").addClass("alert-warning-subtle") 5894 .removeClass("alert-success-subtle") 5895 .removeClass("alert-warning-subtle") 5896 .fadeIn(); 5897 counterSubmit = 0; 5898 } 5899 });/// End Ajax 5900 } 5901 }//END else 5902 }).bind('keydown', function(event) { 5903 5904 if (event.ctrlKey || event.metaKey) { 5905 5906 switch (String.fromCharCode(event.which).toLowerCase()) { 5907 5908 case 's': 5909 var nativeForm = $(this)[0]; 5910 if (nativeForm && typeof nativeForm.reportValidity === 'function' && !nativeForm.reportValidity()) { 5911 event.preventDefault(); 5912 return false; 5913 } 5914 $(this).submit(); 5915 break; 5916 } 5917 } 5918 }); 5919 5920 /// This will turn any select2 that are required in the form builder to being required elements. 5921 $('#member_login_190 select').each(function (i, obj) { 5922 setTimeout(function(){ 5923 if ($(obj).prop("required") && $(obj).attr("style") == "display: none;") { 5924 $(obj).css("z-index","-999"); 5925 $(obj).css("height","0"); 5926 $(obj).css("width","0"); 5927 $(obj).css("display","block"); 5928 $(obj).css("position","absolute"); 5929 } 5930 }, 3000); 5931 }); 5932 5933 // Clear required-error messages when user fills in a required field 5934 $('#member_login_190').on('keyup change', '[required]', function() { 5935 var val = $(this).val(); 5936 if (val !== '' && val !== null && val.trim() !== '') { 5937 var $group = $(this).closest('.form-group'); 5938 // Remove only this handler's own required message 5939 $(this).siblings('.required-error').remove(); 5940 // Keep has-error if another FormValidation validator is still failing 5941 // (e.g. stringLength, regexp). has-error is shared, so removing it 5942 // wholesale would clobber other validators' red styling. 5943 if ($group.find('small[data-fv-validator][data-fv-result="INVALID"]').length === 0) { 5944 $group.removeClass('has-error'); 5945 } 5946 } 5947 }); 5948 5949 });//END $('# echo $_SERVER[form_element_id]; ').formValidation( 5950 </script>
5950 5951
5951<script> 5952 function decision(message, url) { 5953 if (confirm(message)) { 5954 setTimeout(function () { 5955 window.location = url; 5956 }, 0); 5957 } 5958 } 5959</script>
vendor: 2 bytes, line 5959
5959
5960<script> 5961 // Function to add alt, width, and height attributes to <img> elements without them 5962 function addAttributesToImages() { 5963 var images = document.querySelectorAll('img:not([alt]), img:not([width]), img:not([height])'); 5964 Array.prototype.forEach.call(images, function(img) { 5965 // Skip if we've already processed this image 5966 if (img.dataset.processed === 'true') { 5967 return; 5968 } 5969 5970 // Mark this image as being processed 5971 img.dataset.processed = 'true'; 5972 5973 // Add alt attribute if missing 5974 if (!img.hasAttribute('alt')) { 5975 var src = img.getAttribute('src') || 'image'; // Default src to 'image' if missing 5976 var altText = src.split('/').pop().split('?')[0].replace(/\.\w+$/, ''); 5977 5978 try { 5979 altText = decodeURIComponent(altText) 5980 .replace(/[_\-+,.:;]+/g, ' ') 5981 .replace(/\s+/g, ' ') 5982 .trim(); 5983 } catch (e) { 5984 altText = 'image'; // Fallback to 'image' if decoding fails 5985 } 5986 5987 // Ensure altText is not empty, otherwise use 'image' 5988 altText = altText || 'image'; 5989 5990 img.setAttribute('alt', altText); 5991 } 5992 5993 // Add width and height attributes if missing 5994 if (!img.hasAttribute('width') || !img.hasAttribute('height')) { 5995 // Handle SVG differently 5996 if (img.src && img.src.endsWith('.svg')) { 5997 // For SVG, use the viewBox to set width and height, if available 5998 fetch(img.src) 5999 .then(response => { 6000 if (!response.ok) { 6001 throw new Error('Failed to fetch SVG: ' + response.status); 6002 } 6003 return response.text(); 6004 }) 6005 .then(svgText => { 6006 var parser = new DOMParser(); 6007 var svgDoc = parser.parseFromString(svgText, "image/svg+xml"); 6008 var svgElement = svgDoc.querySelector('svg'); 6009 6010 if (svgElement) { 6011 var viewBox = svgElement.getAttribute('viewBox'); 6012 if (viewBox) { 6013 var viewBoxValues = viewBox.split(' '); 6014 var width = viewBoxValues[2]; 6015 var height = viewBoxValues[3]; 6016 6017 if (!img.hasAttribute('width')) { 6018 img.setAttribute('width', width); 6019 } 6020 if (!img.hasAttribute('height')) { 6021 img.setAttribute('height', height); 6022 } 6023 } 6024 } 6025 }) 6026 .catch(error => { 6027 // Fallback to default dimensions for SVG 6028 if (!img.hasAttribute('width')) { 6029 img.setAttribute('width', '100'); 6030 } 6031 if (!img.hasAttribute('height')) { 6032 img.setAttribute('height', '100'); 6033 } 6034 }); 6035 } else { 6036 // For non-SVG images, use natural dimensions 6037 var tempImg = new Image(); 6038 tempImg.src = img.src; 6039 6040 tempImg.onload = function() { 6041 if (!img.hasAttribute('width')) { 6042 img.setAttribute('width', tempImg.naturalWidth); 6043 } 6044 if (!img.hasAttribute('height')) { 6045 img.setAttribute('height', tempImg.naturalHeight); 6046 } 6047 }; 6048 6049 tempImg.onerror = function() { 6050 // Fallback to default dimensions 6051 if (!img.hasAttribute('width')) { 6052 img.setAttribute('width', '100'); 6053 } 6054 if (!img.hasAttribute('height')) { 6055 img.setAttribute('height', '100'); 6056 } 6057 }; 6058 } 6059 } 6060 }); 6061 } 6062 6063 document.addEventListener('DOMContentLoaded', function() { 6064 // Run the function initially to catch images already in the DOM 6065 addAttributesToImages(); 6066 6067 // Create a MutationObserver to monitor the DOM for added/changed images 6068 var observer = new MutationObserver(function(mutations) { 6069 mutations.forEach(function(mutation) { 6070 if (mutation.addedNodes.length > 0 || mutation.type === 'attributes') { 6071 // Only process if we have new images or src attribute changes 6072 var hasNewImages = false; 6073 6074 if (mutation.addedNodes.length > 0) { 6075 mutation.addedNodes.forEach(function(node) { 6076 if (node.nodeType === 1) { // Element node 6077 if (node.tagName === 'IMG' || node.querySelectorAll) { 6078 hasNewImages = true; 6079 } 6080 } 6081 }); 6082 } 6083 6084 if (mutation.type === 'attributes' && mutation.attributeName === 'src') { 6085 hasNewImages = true; 6086 } 6087 6088 if (hasNewImages) { 6089 addAttributesToImages(); 6090 } 6091 } 6092 }); 6093 }); 6094 6095 // Start observing the document body for changes 6096 observer.observe(document.body, { 6097 childList: true, // Watch for added or removed nodes 6098 subtree: true, // Watch the entire subtree 6099 attributes: true, // Watch for attribute changes 6100 attributeFilter: ['src'] // Specifically watch for changes in the 'src' attribute 6101 }); 6102 }); 6103</script>
6103<style type='text/css'> select#sid[disabled], select#tid[disabled], select.combobox[disabled], select#bd-chained[disabled], select#category-chained[disabled], select.infinite-chained[disabled], select.subcategory-chained[disabled], select.search-chained[disabled], select#country-chained[disabled], select#state-chained[disabled], select#country-chained-2[disabled], select#state-chained-2[disabled], select#profession_id[disabled] { 6104 cursor: wait 6105} 6106select.select2-preload { 6107 line-height: initial; 6108} 6109 6110select#sid, select#tid, select#ttid, select.combobox, select#bd-chained, select#category-chained, select.infinite-chained, select.subcategory-chained, select.search-chained, select#country-chained, select#state-chained, select#country-chained-2, select#state-chained-2, select#profession_id, [name^="bd_phone_country_code"] { 6111 -webkit-appearance: none; 6112 -moz-appearance: none; 6113 appearance: none; 6114 background-image: url(/images/select2ArrowDown.png) !important; 6115 background-repeat: no-repeat !important; 6116 background-size: 10px 9px !important; 6117 background-position: 99% 16px; 6118 border-radius: 6px; 6119 overflow: hidden; 6120} 6121.module select#sid, .module select#tid, .module select.combobox, .module select#bd-chained, .module select#category-chained, .module select.infinite-chained, .module select.subcategory-chained, .module select.search-chained, .module select#country-chained, .module select#state-chained, .module select#country-chained-2, .module select#state-chained-2, .module select#profession_id, [name^="bd_phone_country_code"] { 6122 background-position: 98.2% 12px; 6123} </style>
6123<script> 6124 // Function to add aria-label to <select> elements without it, for better pagespeed accessibility score 6125 $(document).ready(function() { 6126 var ariaLabelCounter = {}; // Object to keep track of aria-label counts for uniqueness 6127 6128 // Iterate over each select element that does not have an aria-label 6129 $('select:not([aria-label])').each(function() { 6130 // Use the ID or placeholder as the base for the aria-label, stripping HTML tags 6131 var baseLabel = this.id || $(this).attr('placeholder') || 'select'; 6132 baseLabel = baseLabel.replace(/<[^>]*>/g, '').trim(); // Remove HTML tags and trim 6133 6134 // Ensure uniqueness of each aria-label 6135 ariaLabelCounter[baseLabel] = (ariaLabelCounter[baseLabel] || 0) + 1; 6136 var ariaLabel = baseLabel + '-' + ariaLabelCounter[baseLabel]; 6137 6138 // Truncate aria-label to 100 characters 6139 ariaLabel = ariaLabel.length > 100 ? ariaLabel.substring(0, 100) : ariaLabel; 6140 6141 // Set the aria-label attribute to the unique label 6142 $(this).attr('aria-label', ariaLabel); 6143 }); 6144 }); 6145</script>
vendor: 2 bytes, line 6145
6145
6146<script type="application/ld+json"> 6147{ 6148 "@context": "https://schema.org", 6149 "@graph": [ 6150 { 6151 "@type": "WebSite", 6152 "@id": "https://www.retainingwallexpert.com/#website", 6153 "name": "Retaining Wall Expert", 6154 "url": "https://www.retainingwallexpert.com/", 6155 "inLanguage": "en-US", 6156 "potentialAction": { 6157 "@type": "SearchAction", 6158 "target": "https://www.retainingwallexpert.com/search?q={search_term_string}", 6159 "query-input": "required name=search_term_string", 6160 "name": "Search Directory: Retaining Wall Expert" 6161 }, 6162 "publisher": { 6163 "@id": "https://www.retainingwallexpert.com/#organization" 6164 } 6165 }, 6166 { 6167 "@type": "Organization", 6168 "@id": "https://www.retainingwallexpert.com/#organization", 6169 "name": "Retaining Wall Expert", 6170 "description": "Search the most complete retaining wall expert directory. Find retaining wall experts.", 6171 "url": "https://www.retainingwallexpert.com/", 6172 "mainEntityOfPage": { 6173 "@type": "WebPage", 6174 "@id": "https://www.retainingwallexpert.com/#webpage" 6175 }, 6176 "contactPoint": [ 6177 { 6178 "@type": "ContactPoint", 6179 "email": "[email protected]", 6180 "contactType": "customer support", 6181 "availableLanguage": [ 6182 "en" 6183 ], 6184 "areaServed": "US" 6185 } 6186 ], 6187 "areaServed": { 6188 "@type": "Country", 6189 "name": "US" 6190 }, 6191 "sameAs": [ 6192 "https://www.facebook.com/KowalskiEngineeringInc/", 6193 "https://x.com/WallExpertYes", 6194 "https://www.linkedin.com/in/contactjoekowalski/", 6195 "https://www.youtube.com/@RetainingWallExpert", 6196 "https://www.instagram.com/retainingwallexpert/" 6197 ], 6198 "logo": { 6199 "@type": "ImageObject", 6200 "@id": "https://www.retainingwallexpert.com/#logo", 6201 "url": "/images/favicon.webp" 6202 }, 6203 "image": { 6204 "@type": "ImageObject", 6205 "@id": "https://www.retainingwallexpert.com/#image", 6206 "url": "/images/favicon.webp" 6207 }, 6208 "keywords": [ 6209 "Retaining Wall", 6210 "Retaining Wall Expert", 6211 "Retaining Wall Expert", 6212 "Retaining Wall Expert", 6213 "Retaining Wall" 6214 ] 6215 } 6216 ] 6217}</script>
6217 6218
6219<script> 6220// Bootstrap Icons fallback loader - ensures Bootstrap Icons work even if HEAD widget is customized, do not delete 6221(function() { 6222 if (!document.querySelector('link[href*="bootstrap-icons"]')) { 6223 var link = document.createElement('link'); 6224 link.rel = 'stylesheet'; 6225 link.href = 'https://www.optimizecdn.com/directory/cdn/assets/bootstrap/fonts/bootstrap-icons.min.css?v=1.13.1'; 6226 document.head.appendChild(link); 6227 } 6228})(); 6229</script>
vendor: 2 bytes, line 6229
6229
6230<script> 6231 window.addEventListener('load', () => { 6232 let embedlyClass = document.querySelector('.fr-embedly'); 6233 if (typeof embedlyClass != "undefined" && embedlyClass != null) { 6234 let embedlyURI = "https://www.optimizecdn.com/directory/cdn/assets/bootstrap/js/embedly_widget.min.js"; 6235 let head = document.getElementsByTagName("head")[0]; 6236 let script = document.createElement('script'); 6237 script.type = 'text/javascript'; 6238 script.src = embedlyURI; 6239 script.async = true; 6240 script.onload = function() { 6241 setTimeout(function() { 6242 if (typeof embedly !== 'undefined' && embedly.card) { 6243 document.querySelectorAll('.embedly-card').forEach(function(card) { 6244 embedly.card(card); 6245 }); 6246 } 6247 }, 500); 6248 }; 6249 head.appendChild(script); 6250 } 6251 }); 6252</script>
6252<script type="text/javascript" src="https://www.optimizecdn.com/directory/cdn/assets/bootstrap/jquery.lazy/1.7.9/jquery.lazy.min.js"></script>
6252<script> 6253 $(function () { 6254 $(".lazyloader").Lazy({ 6255 afterLoad: function(element) { 6256 $(".gridView.activeView").click(); 6257 } 6258 }); 6259 6260 }); 6261 $("button[class*='slick'],button[id*='slick']").click(function () { 6262 $(this).parents(".row").find(".lazyloader").lazy({ 6263 bind: "event", 6264 delay: 0 6265 }); 6266 }); 6267 $("[class*='slick'],[id*='slick']").on("swipe",function(){ 6268 $(this).parents(".row").find(".lazyloader").lazy({ 6269 bind: "event", 6270 delay: 0 6271 }); 6272 }); 6273 </script>
6273<script defer src="https://www.optimizecdn.com/directory/cdn/assets/bootstrap/js/websiteScripts.min.js?v=8.0.0"></script>
6273 6274 </body> 6275 </html>
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.