Huntsville Potholes vs. Your Suspension: Will Your Extended Warranty Cover It?

You’re driving home after work on University Drive, and bam! Your car hits a deep pothole you didn’t see coming. Your heart sinks as you feel that ugly thump under your wheels.

If you’re like most Huntsville drivers, you’re now wondering: will my extended warranty cover this mess? The short answer might surprise you.

Why Huntsville Drivers Need to Worry About Potholes

Let’s be honest. Huntsville roads take a beating. Between our hot summers and those surprise winter freezes, our streets go through a lot.

Huntsville’s Road Conditions and Weather Impact

I’ve lived here for years, and I can tell you that pothole season is real. When water gets into tiny cracks in the road and then freezes, it makes those cracks bigger.

Then the ice melts, and the road breaks apart. Add heavy traffic, and you get those nasty potholes that can really hurt your car.

According to the City of Huntsville, they have crews working hard to fix these problems. But with four trucks trying to cover all our streets, some potholes stick around longer than they should.

How Potholes Form in Alabama’s Climate

Alabama’s freeze-thaw cycles are sneaky. We don’t get snow every week like up north, but when it does freeze, the damage happens fast.

Heavy rain makes it worse. Water seeps into the pavement, weakens the base material underneath, and creates those annoying holes in the road.

Local repair shops in Huntsville see a big jump in suspension damage every winter and spring. That’s not a coincidence.

What Happens When You Hit a Pothole?

When your car slams into a pothole, several things can go wrong. Some you’ll notice right away. Others might show up weeks later.

Tire and Wheel Damage

Tire and Wheel Damage

Your tires take the first hit. I once hit a deep pothole on Memorial Parkway and didn’t think much of it. Two days later, my tire went completely flat.

Tire punctures can happen instantly or develop into slow leaks. Your rims can also bend or crack, especially if you have those nice aluminum wheels.

According to a study from Consumer Reports, pothole damage to tires and wheels is one of the most common vehicle problems in areas with poor road conditions.

Suspension System Problems

Here’s where things get expensive. Your suspension system includes parts like shocks, struts, control arms, and bushings.

When you hit a hard pothole, these parts absorb that impact. Do it enough times, and they start to wear out faster than normal.

Signs of suspension trouble include your car bouncing too much, pulling to one side, or making weird noises when you turn.

Understanding Your Suspension System

Before we talk about warranty coverage, you need to know what parts we’re dealing with.

What Are Shocks and Struts?

People often think shocks and struts are the same thing. They’re not.

Shock absorbers use hydraulic fluid to keep your car from bouncing like a basketball when you hit bumps. They control how much your car’s springs move.

Struts do more work. They support your car’s weight and help with steering and alignment. They’re stronger and more complex than regular shocks.

Here’s the thing: your car has either shocks or struts on each wheel, never both. Check your owner’s manual if you’re not sure which your car has.

Signs Your Suspension Is Damaged

Your car will tell you when something’s wrong. You just need to listen.

Uneven tire wear is a big clue. If your tires look “cupped” or worn in strange patterns, your suspension might be the problem.

Excessive bouncing is another sign. When you hit a bump and your car keeps bouncing several times, that’s not normal.

If your car sits lower than usual or the frame scrapes the road, that’s called bottoming out. It means your suspension is failing, and you need to get it fixed fast.

Leaking fluid near your wheels could mean your shock absorbers are going bad.

Are Shocks and Struts Covered Under Warranty?

This is the million-dollar question. And I wish I had better news for you.

Factory Warranty Coverage Explained

Your factory warranty will cover shocks and struts if they fail because of a manufacturing defect. That means something was wrong with how the part was made.

But here’s the catch: if your shocks or struts wear out from normal driving or pothole damage, your factory warranty won’t cover it.

Most manufacturer warranties call these parts “wear and tear” items, just like brake pads or spark plugs.

According to Endurance Warranty Services, even bumper-to-bumper coverage typically excludes suspension parts that wear out from regular use.

Extended Warranty and Vehicle Service Contracts

Unfortunately, most extended warranties and vehicle service contracts (VSCs) also exclude shocks and struts.

I know that’s frustrating to hear, especially after you spent good money on that warranty.

These parts are considered maintenance items that will eventually need replacing no matter how carefully you drive.

Think of it like this: warranty companies know that everyone’s shocks and struts will wear out eventually. If they covered them, they’d be paying claims constantly.

What Extended Warranties Typically Don’t Cover

Let’s talk about what else usually isn’t covered. This will save you some headaches later.

Wear and Tear vs. Manufacturing Defects

There’s a big difference between these two things.

Wear and tear means the part wore out from normal use over time. No warranty covers this.

Manufacturing defects mean the part was faulty from the factory. This IS covered, but only during your factory warranty period.

Hitting a pothole counts as road damage, not a defect. So even if your strut breaks after hitting a hole, it’s probably not covered.

Common Exclusions You Should Know

Besides suspension parts, most warranties don’t cover windshield wipers, brake pads, tires, or spark plugs.

They also won’t cover damage from accidents, neglect, or misuse.

Always read your warranty contract carefully. I learned this the hard way when I assumed something was covered and it wasn’t.

Other Ways to Get Coverage for Pothole Damage

Don’t give up hope yet. You might have other options.

 

Auto Insurance

Auto Insurance and Collision Coverage

Your auto insurance might help, but only if you have collision coverage.

Collision coverage can pay for damage to hard parts like your suspension components if you hit a pothole. But it usually won’t cover your tires.

Here’s the problem: you’ll need to pay your deductible first. If your deductible is $500 and the repair costs $600, you’re only getting $100 back.

According to insurance experts, you should only file a claim if the damage costs at least twice your deductible. Otherwise, you’re risking higher insurance premiums for not much benefit.

Road Hazard Tire Warranties

Some tire shops offer road hazard warranties when you buy new tires. These special warranties cover damage from potholes, nails, glass, and other road hazards. Companies like Continental, Dunlop, and Kumho offer these warranties, but they usually only last one year.

A Consumer Reports tire expert says these warranties can be worth it if you live in a pothole-plagued area like parts of Huntsville. Just remember: you’ll still probably pay for mounting, balancing, and disposal even if the warranty covers the tire itself.

How Much Does Suspension Repair Cost in Huntsville?

Let’s talk money. Because that’s what you really want to know, right?

Average Repair Costs for Popular Vehicles

According to RepairPal, the average cost to replace shocks or struts ranges from $852 to $928.

But that varies a lot depending on what you drive.

Here are some examples:

  • Ford F-150: $649 to $875
  • Honda Accord: $918 to $1,337
  • Nissan Altima: $978 to $1,144
  • BMW 328i: $2,100 to $2,357
  • Jeep Wrangler: $461 to $671

I asked a mechanic at Damson Service Center in Huntsville, and he told me luxury cars cost way more. The parts are expensive, and the labor takes longer.

Factors That Affect Your Repair Bill

Several things change how much you’ll pay. Your car’s make and model matters most. Luxury cars and sports cars cost more to fix. Whether you need shocks or struts makes a difference. Struts are usually more expensive because they’re more complex. Where you get the repair done also changes the price. Dealerships charge more than independent shops, but they use OEM parts (original equipment from the manufacturer).

What to Do If You Hit a Pothole in Huntsville

Okay, you just hit a pothole. Here’s exactly what you should do.

Immediate Steps After Impact

First, pull over safely and look at your car. Check for obvious damage like a flat tire or bent rim. If you can drive safely, go to a nearby parking lot for a better look. Take pictures of everything. Your damaged tire, the wheel, any fluid leaks, and any other problems you see. According to car experts, photos are your best friend if you plan to file any kind of claim.

Filing a Claim with the City of Huntsville

Here’s something many people don’t know: you can file a claim with Huntsville for pothole damage.

The City of Huntsville has a claims process. Whether they pay depends on if they knew about the pothole long enough to fix it.

Here’s what you need to do:

  1. Write down the date, time, and exact location of the pothole
  2. Take pictures of the pothole and your vehicle damage
  3. Get at least two repair estimates
  4. Report the pothole through Huntsville Connect
  5. Fill out a claim form (you can get it online or from the city attorney’s office)

Be warned: the process can take a while, and there’s no guarantee you’ll get paid. But it’s worth trying, especially if the damage is expensive.

How to Protect Your Car from Pothole Damage

Prevention is way cheaper than repair. Trust me on this one.

Driving Tips for Huntsville Roads

Keep a safe distance from the car in front of you. This gives you more time to spot potholes and avoid them. Slow down on roads you know have problems. Memorial Parkway, University Drive, and some parts of Highway 72 can be rough. Don’t swerve suddenly to avoid a pothole if there’s traffic around you. Sometimes it’s safer to hit the pothole slowly than to cause an accident. If you can’t avoid a pothole, slow down as much as safely possible before you hit it. This reduces the impact.

Regular Maintenance to Prevent Bigger Problems

Keep your tires properly inflated. Under-inflated tires get damaged more easily. Get your alignment checked regularly, especially if you drive on rough roads a lot. Have a certified technician inspect your suspension during regular service visits. According to local repair shops in Huntsville, catching small problems early can save you hundreds of dollars later.Most manufacturers recommend replacing shocks and struts every 50,000 to 100,000 miles, depending on your driving conditions.

Conclusion

So here’s the bottom line: your extended warranty probably won’t cover suspension damage from hitting potholes in Huntsville.That stinks, I know. But now you know other options. Your auto insurance might help if you have collision coverage. The City of Huntsville has a claims process. And tire road hazard warranties can protect your wheels. The best strategy? Drive carefully, keep your car maintained, and save some money for unexpected repairs. Because on Huntsville roads, it’s not if you’ll hit a pothole—it’s when.

FAQs

Does my extended warranty cover pothole damage to my suspension?

Most extended warranties and vehicle service contracts do not cover suspension damage from potholes because it’s considered wear and tear, not a manufacturing defect. Your factory warranty only covers defects, not road damage.

How much does it cost to replace shocks and struts?

The average cost ranges from $852 to $928, but it depends on your vehicle. A Ford F-150 might cost $649 to $875, while a BMW 328i could cost $2,100 to $2,357. Luxury cars and sports cars are always more expensive to repair.

Can I file a claim with the city of Huntsville for pothole damage?

Yes! The City of Huntsville has a claims process for pothole damage. You need to document everything (date, time, location, photos), get repair estimates, and file a claim form. Whether they pay depends on if they knew about the pothole long enough to fix it.

What’s the difference between shocks and struts?

Shocks use hydraulic fluid to control bouncing and keep your ride smooth. Struts do more—they support your car’s weight, help with steering and alignment, and include a spring and shock absorber. Your car has either shocks or struts on each wheel, never both.

Will my auto insurance cover suspension damage from potholes?

Maybe. If you have collision coverage, your insurance might pay for suspension damage (but not usually tires). You’ll pay your deductible first, and filing a claim could raise your premiums. Only file if the damage costs at least twice your deductible.

We Are Your Warranty Advocates.

Latests Posts

WE DON’T JUST WORK ON CARS, WE FIX THEM!

Auto Repair & Tire Service in Huntsville, AL

At Brian’s Tire & Service we work hard to earn your trust and loyalty. We know how important it is to find a Huntsville car service you can rely on, so your satisfaction is our top priority each and every day.

WE DON’T JUST WORK ON CARS,
WE FIX THEM!

Your Full-Service Automotive Repair Shop

At Brian’s Tire & Service we work hard to earn your trust and loyalty. We know how important it is to find a Huntsville car service you can rely on, so your satisfaction is our top priority each and every day.

Our Automotive Services

Get trusted auto repair and maintenance for your vehicle in Huntsville, AL. From routine care to complex repairs, our team is here to keep your vehicle safe and reliable.

Advanced Diagnostics 1

Advanced Diagnostics

Professional vehicle diagnostics to identify warning lights, performance issues and hard-to-find problems before they become costly repairs.

Maintenance & Repair

Auto Maintenance Services

Comprehensive routine maintenance and repair programs designed to keep your vehicle reliable, safe, efficient, and ready for the road every day.

Suspension Steering maintenance and repair

Suspension & Steering

Keep your vehicle safe and comfortable with professional suspension and steering care for a smoother, safer, and more controlled ride overall.

Engine Maintenance & Repair

Engine Diagnostics & Repair

Identify engine problems early and get reliable repairs to keep your vehicle running smoothly, safely, efficiently, and confidently on the road.

Complete Tire Services

Complete Tire Services

Keep your vehicle safe and road-ready with dependable tire services for improved traction, handling, performance, and long-lasting road safety.

See All Services

From engine repair to tire services, view our complete list of automotive services.

Our Commitment

A Better Automotive Service Experience

At Brian’s Tire & Service, we believe great automotive care goes beyond fixing vehicles, it’s about treating every customer with honesty, respect, and transparency throughout the entire process.

Our team takes the time to explain what your vehicle needs and why, so you can make informed decisions with confidence. No surprises, no pressure, just straightforward service from people who genuinely care.

 

A Better Automotive Service

Comprehensive Tire Services We Offer:

Brian’s Tire & Service is your neighborhood hub for all tire-related needs. Our range of services includes but is not limited to:
Routine Tire Maintenance at Brians Tire and Service

Routine Tire Maintenance

Regular maintenance is key to extending the life of your tires. Our expert team performs thorough inspections and tire rotations every 5,000 miles to promote even wear across all four tires, saving you money and enhancing fuel efficiency.

Prompt Tire Repairs at Brians Tire and Service

Prompt Tire Repairs

Encountered a flat tire or a slow leak? Bring your vehicle to us. With meticulous attention to detail, we’ll uncover the cause of the issue and carry out the necessary repairs, getting you back on the road swiftly and safely.

Precise Wheel Balancing at Brians Tire and Service

Precise Wheel Balancing

Over time, wheel imbalances can lead to unpleasant vibrations, especially at higher speeds. Utilizing state-of-the-art computerized wheel balancing equipment, we rectify these imbalances, ensuring a smooth and comfortable drive.

Rectangle 56 1

Tire Sales and Installation

When it's time for a new set of tires, our vast selection caters to every preference, whether you seek high-performance or budget-friendly options. Our professionals will guide you in choosing the perfect tires and ensure they are installed correctly.

ABOUT US

Brian's Tire & Service in Huntsville

For years Brian’s Tire & Service has been there for the people of Huntsville. We love what we do, and that basic fact fuels our business. We are dedicated to our customers, and that’s why they stick with us—the best auto repair Huntsville has to offer.

Our family of technicians and service staff see their work here as more than a job. It’s their vocation and livelihood. Each member of our team is invested in your satisfaction.

Brian’s Tire & Service was founded on the basic idea that everyone deserves respect. It is our mission to treat each person that comes through our door with dignity and sensitivity. We believe this attention to detail has paid off by providing us with our loyal, friendly family of customers. That’s what makes Brian’s Tire & Service the best car service in Huntsville!

Are you ready to experience the best Huntsville car service available? Please give us a call or book an appointment:

Group 174

Brian Lombardino
Owner

Contact Information

Customer satisfaction is our number one priority. We want to hear from you if you have questions or comments, we’d love to hear from you.

Our Client Reviews

{ "@context": "https://schema.org", "@type": "LocalBusiness", "name": "Brian's Tire & Service", "aggregateRating": { "@type": "AggregateRating", "ratingValue": "4.8", "reviewCount": 605, "bestRating": "5", "worstRating": "1" }, "address": "1024 Putman Dr NW, Huntsville, AL 35816" }

Brian's Buddy Membership

**12 month minimum required per member**

Only $299.95 annually

We offer up to 12 months interest free financing for qualified customers

Wheel

Affiliates & Certification

Car Quest
Technet
OReilly v2
AC Delco red and blue
Be Car Care Aware2
ASA
ASE Certified Logo
BBB
{"prefetch":[{"source":"document","where":{"and":[{"href_matches":"/*"},{"not":{"href_matches":["/wp-*.php","/wp-admin/*","/wp-content/uploads/*","/wp-content/*","/wp-content/plugins/*","/wp-content/themes/brians-warranty-child/*","/wp-content/themes/hello-elementor/*","/*\\?(.+)"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]}
(function() { // Global page view and session tracking for UAEL Modal Popup feature try { // Session tracking: increment if this is a new session // Check if any popup on this page uses current page tracking var hasCurrentPageTracking = false; var currentPagePopups = []; // Check all modal popups on this page for current page tracking if (typeof jQuery !== 'undefined') { jQuery('.uael-modal-parent-wrapper').each(function() { var scope = jQuery(this).data('page-views-scope'); var enabled = jQuery(this).data('page-views-enabled'); var popupId = jQuery(this).attr('id').replace('-overlay', ''); if (enabled === 'yes' && scope === 'current') { hasCurrentPageTracking = true; currentPagePopups.push(popupId); } }); } // Global tracking: ALWAYS increment if ANY popup on the site uses global tracking // Current page tracking: increment per-page counters if (hasCurrentPageTracking && currentPagePopups.length > 0) { var currentUrl = window.location.href; var urlKey = 'uael_page_views_' + btoa(currentUrl).replace(/[^a-zA-Z0-9]/g, '').substring(0, 50); var currentPageViews = parseInt(localStorage.getItem(urlKey) || '0'); currentPageViews++; localStorage.setItem(urlKey, currentPageViews.toString()); // Store URL mapping for each popup for (var i = 0; i < currentPagePopups.length; i++) { var popupUrlKey = 'uael_popup_' + currentPagePopups[i] + '_url_key'; localStorage.setItem(popupUrlKey, urlKey); } } } catch (e) { // Silently fail if localStorage is not available } })();
( () => { const lazyloadRunObserver = () => { const lazyloadBackgrounds = document.querySelectorAll( `.e-con.e-parent:not(.e-lazyloaded)` ); const lazyloadBackgroundObserver = new IntersectionObserver( ( entries ) => { entries.forEach( ( entry ) => { if ( entry.isIntersecting ) { let lazyloadBackground = entry.target; if( lazyloadBackground ) { lazyloadBackground.classList.add( 'e-lazyloaded' ); } lazyloadBackgroundObserver.unobserve( entry.target ); } }); }, { rootMargin: '200px 0px 200px 0px' } ); lazyloadBackgrounds.forEach( ( lazyloadBackground ) => { lazyloadBackgroundObserver.observe( lazyloadBackground ); } ); }; const events = [ 'DOMContentLoaded', 'elementor/lazyload/observe', ]; events.forEach( ( event ) => { document.addEventListener( event, lazyloadRunObserver ); } ); } )(); jQuery.uiBackCompat = true; //# sourceURL=jquery-ui-core-js-before var uael_particles_script = {"uael_particles_url":"https://brianstireandservice.com/wp-content/plugins/ultimate-elementor/assets/min-js/uael-particles.min.js","particles_url":"https://brianstireandservice.com/wp-content/plugins/ultimate-elementor/assets/lib/particles/particles.min.js","snowflakes_image":"https://brianstireandservice.com/wp-content/plugins/ultimate-elementor/assets/img/snowflake.svg","gift":"https://brianstireandservice.com/wp-content/plugins/ultimate-elementor/assets/img/gift.png","tree":"https://brianstireandservice.com/wp-content/plugins/ultimate-elementor/assets/img/tree.png","skull":"https://brianstireandservice.com/wp-content/plugins/ultimate-elementor/assets/img/skull.png","ghost":"https://brianstireandservice.com/wp-content/plugins/ultimate-elementor/assets/img/ghost.png","moon":"https://brianstireandservice.com/wp-content/plugins/ultimate-elementor/assets/img/moon.png","bat":"https://brianstireandservice.com/wp-content/plugins/ultimate-elementor/assets/img/bat.png","pumpkin":"https://brianstireandservice.com/wp-content/plugins/ultimate-elementor/assets/img/pumpkin.png"}; //# sourceURL=elementor-frontend-js-extra var elementorFrontendConfig = {"environmentMode":{"edit":false,"wpPreview":false,"isScriptDebug":false},"i18n":{"shareOnFacebook":"Share on Facebook","shareOnX":"Share on X","pinIt":"Pin it","download":"Download","downloadImage":"Download image","fullscreen":"Fullscreen","zoom":"Zoom","share":"Share","playVideo":"Play Video","previous":"Previous","next":"Next","close":"Close","a11yCarouselPrevSlideMessage":"Previous slide","a11yCarouselNextSlideMessage":"Next slide","a11yCarouselFirstSlideMessage":"This is the first slide","a11yCarouselLastSlideMessage":"This is the last slide","a11yCarouselPaginationBulletMessage":"Go to slide"},"is_rtl":false,"breakpoints":{"xs":0,"sm":480,"md":768,"lg":1025,"xl":1440,"xxl":1600},"responsive":{"breakpoints":{"mobile":{"label":"Mobile Portrait","value":767,"default_value":767,"direction":"max","is_enabled":true},"mobile_extra":{"label":"Mobile Landscape","value":880,"default_value":880,"direction":"max","is_enabled":false},"tablet":{"label":"Tablet Portrait","value":1024,"default_value":1024,"direction":"max","is_enabled":true},"tablet_extra":{"label":"Tablet Landscape","value":1200,"default_value":1200,"direction":"max","is_enabled":false},"laptop":{"label":"Laptop","value":1366,"default_value":1366,"direction":"max","is_enabled":false},"widescreen":{"label":"Widescreen","value":2400,"default_value":2400,"direction":"min","is_enabled":false}},"hasCustomBreakpoints":false},"version":"4.3.6","is_static":false,"experimentalFeatures":{"additional_custom_breakpoints":true,"container":true,"theme_builder_v2":true,"hello-theme-header-footer":true,"nested-elements":true,"import-export-customization":true,"e_pro_atomic_form":true,"mega-menu":true,"e_pro_variables":true,"e_pro_interactions":true},"urls":{"assets":"https:\/\/brianstireandservice.com\/wp-content\/plugins\/elementor\/assets\/","ajaxurl":"https:\/\/brianstireandservice.com\/wp-admin\/admin-ajax.php","uploadUrl":"https:\/\/brianstireandservice.com\/wp-content\/uploads"},"nonces":{"floatingButtonsClickTracking":"cce75da8da","atomicFormsSendForm":"d3ea069d70"},"swiperClass":"swiper","settings":{"page":[],"editorPreferences":[]},"kit":{"active_breakpoints":["viewport_mobile","viewport_tablet"],"global_image_lightbox":"yes","lightbox_enable_counter":"yes","lightbox_enable_fullscreen":"yes","lightbox_enable_zoom":"yes","lightbox_enable_share":"yes","lightbox_title_src":"title","lightbox_description_src":"description","hello_header_logo_type":"logo","hello_header_menu_layout":"horizontal","hello_footer_logo_type":"logo"},"post":{"id":24,"title":"Auto%20Repair%20%26%20Tires%20In%20Huntsville%2C%20AL%20%7C%20Brian%27s%20Tire%20%26%20Auto","excerpt":"","featuredImage":"https:\/\/brianstireandservice.com\/wp-content\/uploads\/2023\/11\/brians-Tire-Service-Home-1024x536.jpg"}}; //# sourceURL=elementor-frontend-js-before window.scope_array = []; window.backend = 0; jQuery.cachedScript = function( url, options ) { // Allow user to set any option except for dataType, cache, and url. options = jQuery.extend( options || {}, { dataType: "script", cache: true, url: url }); // Return the jqXHR object so we can chain callbacks. return jQuery.ajax( options ); }; jQuery( window ).on( "elementor/frontend/init", function() { elementorFrontend.hooks.addAction( "frontend/element_ready/global", function( $scope, $ ){ if ( "undefined" == typeof $scope ) { return; } if ( $scope.hasClass( "uael-particle-yes" ) ) { window.scope_array.push( $scope ); $scope.find(".uael-particle-wrapper").addClass("js-is-enabled"); }else{ return; } if(elementorFrontend.isEditMode() && $scope.find(".uael-particle-wrapper").hasClass("js-is-enabled") && window.backend == 0 ){ var uael_url = uael_particles_script.uael_particles_url; jQuery.cachedScript( uael_url ); window.backend = 1; }else if(elementorFrontend.isEditMode()){ var uael_url = uael_particles_script.uael_particles_url; jQuery.cachedScript( uael_url ).done(function(){ var flag = true; }); } }); }); // Added both `document` and `window` event listeners to address issues where some users faced problems with the `document` event not triggering as expected. // Define cachedScript globally to avoid redefining it. jQuery.cachedScript = function(url, options) { options = jQuery.extend(options || {}, { dataType: "script", cache: true, url: url }); return jQuery.ajax(options); // Return the jqXHR object so we can chain callbacks }; let uael_particle_loaded = false; //flag to prevent multiple script loads. jQuery( document ).on( "ready elementor/popup/show", () => { loadParticleScript(); }); jQuery( window ).one( "elementor/frontend/init", () => { if (!uael_particle_loaded) { loadParticleScript(); } }); function loadParticleScript(){ // Use jQuery to check for the presence of the element if (jQuery(".uael-particle-yes").length < 1) { return; } uael_particle_loaded = true; var uael_url = uael_particles_script.uael_particles_url; // Call the cachedScript function jQuery.cachedScript(uael_url); } //# sourceURL=elementor-frontend-js-after var mdpReadablerOptions = {"ajaxurl":"https://brianstireandservice.com/wp-admin/admin-ajax.php","nonce":"cebc04f094","pluginURL":"https://brianstireandservice.com/wp-content/plugins/readabler/","postID":"24","postType":"page","translation":{"voiceGuide":"","voiceRecognitionStart":"Say a command...","voiceRecognitionEnd":"Voice recognition has stopped","voiceRecognitionWait":"Wait...","voiceRecognitionLegend":"Voice recognition","voiceRecognitionCommands":"Voice commands","voiceRecognitionHistory":"History","voiceRecognitionClose":"Close and stop voice navigation","voiceRecognitionErrorNoVoice":"Voice recognition has stopped, no voice detected. Click the button to restart recognition.","voiceRecognitionErrorNoNetwork":"Network error. Check is you online and try again.","voiceRecognitionErrorNoMic":"No microphone. Check is your microphone connected and try again.","voiceRecognitionErrorNoPermission":"Permission denied. Check is your microphone connected and try again.","voiceRecognitionErrorNotAllowed":"Microphone access denied. Check is your microphone connected and try again.","voiceRecognitionErrorUnknown":"Voice recognition error. Try again.","voiceRecognitionNumbers":["zero","one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen","twenty","twenty one","twenty two","twenty three","twenty four","twenty five","twenty six","twenty seven","twenty eight","twenty nine","thirty","thirty one","thirty two","thirty three","thirty four","thirty five","thirty six","thirty seven","thirty eight","thirty nine","forty","forty one","forty two","forty three","forty four","forty five","forty six","forty seven","forty eight","forty nine","fifty","fifty one","fifty two","fifty three","fifty four","fifty five","fifty six","fifty seven","fifty eight","fifty nine","sixty","sixty one","sixty two","sixty three","sixty four","sixty five","sixty six","sixty seven","sixty eight","sixty nine","seventy","seventy one","seventy two","seventy three","seventy four","seventy five","seventy six","seventy seven","seventy eight","seventy nine","eighty","eighty one","eighty two","eighty three","eighty four","eighty five","eighty six","eighty seven","eighty eight","eighty nine","ninety","ninety one","ninety two","ninety three","ninety four","ninety five","ninety six","ninety seven","ninety eight","ninety nine","one hundred","one hundred one","one hundred two","one hundred three","one hundred four","one hundred five","one hundred six","one hundred seven","one hundred eight","one hundred nine","one hundred ten","one hundred eleven","one hundred twelve","one hundred thirteen","one hundred fourteen","one hundred fifteen","one hundred sixteen","one hundred seventeen","one hundred eighteen","one hundred nineteen","one hundred twenty","one hundred twenty one","one hundred twenty two","one hundred twenty three","one hundred twenty four","one hundred twenty five","one hundred twenty six","one hundred twenty seven","one hundred twenty eight","one hundred twenty nine","one hundred thirty","one hundred thirty one","one hundred thirty two","one hundred thirty three","one hundred thirty four","one hundred thirty five","one hundred thirty six","one hundred thirty seven","one hundred thirty eight","one hundred thirty nine","one hundred forty","one hundred forty one","one hundred forty two","one hundred forty three","one hundred forty four","one hundred forty five","one hundred forty six","one hundred forty seven","one hundred forty eight","one hundred forty nine","one hundred fifty","one hundred fifty one","one hundred fifty two","one hundred fifty three","one hundred fifty four","one hundred fifty five","one hundred fifty six","one hundred fifty seven","one hundred fifty eight","one hundred fifty nine","one hundred sixty","one hundred sixty one","one hundred sixty two","one hundred sixty three","one hundred sixty four","one hundred sixty five","one hundred sixty six","one hundred sixty seven","one hundred sixty eight","one hundred sixty nine","one hundred seventy","one hundred seventy one","one hundred seventy two","one hundred seventy three","one hundred seventy four","one hundred seventy five","one hundred seventy six","one hundred seventy seven","one hundred seventy eight","one hundred seventy nine","one hundred eighty","one hundred eighty one","one hundred eighty two","one hundred eighty three","one hundred eighty four","one hundred eighty five","one hundred eighty six","one hundred eighty seven","one hundred eighty eight","one hundred eighty nine","one hundred ninety","one hundred ninety one","one hundred ninety two","one hundred ninety three","one hundred ninety four","one hundred ninety five","one hundred ninety six","one hundred ninety seven","one hundred ninety eight","one hundred ninety nine","two hundred"]},"popupPosition":"center","popupOverlay":"","buttons":{"resetButton":true,"hideButton":true},"headers":{"accessibilityProfiles":true,"onlineDictionary":true,"readableExperience":true,"visuallyPleasing":true,"visualAssistance":true,"easyOrientation":true},"onlineDictionary":"1","language":"auto","profileEpilepsy":"1","profileVisuallyImpaired":"1","profileCognitiveDisability":"1","profileAdhdFriendly":"","profileBlindUsers":"1","contentScaling":"1","readableFont":"1","dyslexiaFont":"1","highlightTitles":"1","highlightLinks":"1","textMagnifier":"1","fontSizing":"1","lineHeight":"1","letterSpacing":"1","alignCenter":"1","alignLeft":"1","alignRight":"1","darkContrast":"1","lightContrast":"1","monochrome":"1","highSaturation":"1","highContrast":"1","lowSaturation":"1","textColors":"1","titleColors":"1","backgroundColors":"1","muteSounds":"1","hideImages":"1","hideEmoji":"1","virtualKeyboard":"1","readingGuide":"1","cognitiveReading":"1","cognitiveReadingFocus":"","cognitiveReadingFixation":"normal","usefulLinks":"1","stopAnimations":"1","readingMask":"1","highlightHover":"1","highlightFocus":"1","bigBlackCursor":"1","bigWhiteCursor":"1","textToSpeech":"","voiceNavigation":{"help":["help","help_me","show_commands"],"hide_help":["hide_help","hide_commands","hide_commands_list"],"scroll_down":["scroll_down","down","page_down"],"scroll_up":["scroll_up","up","page_up"],"go_to_top":["go_to_top","top","page_top"],"go_to_bottom":["go_to_bottom","bottom","page_bottom"],"tab":["tab","next","next_tab"],"tab_back":["tab_back","previous","previous_tab"],"show_numbers":["show_numbers","display_numbers","enable_numbers"],"number":["click","press","open"],"hide_numbers":["hide_numbers","disable_numbers","remove_numbers"],"clear_input":["clear_input","clear","remove"],"enter":["enter","submit","ok"],"reload":["reload","refresh","update"],"stop":["stop","cancel","stop_listening"],"exit":["exit","quit","close"]},"keyboardNavigation":"1","startConfig":"","startContentScaling":"0","startFontSizing":"0","startLineHeight":"0","startLetterSpacing":"0","ignoreSavedConfig":"off","showOpenButton":"1","buttonPosition":"right-center","buttonCaption":"","buttonIcon":"_readabler/readabler.svg","buttonIconPosition":"before","buttonSize":"24","buttonMargin":"10","buttonPadding":"20","buttonBorderRadius":"50","buttonColor":"rgba(255, 255, 255, 1)","buttonColorHover":"rgba(33, 111, 243, 1)","buttonBgcolor":"rgba(33, 111, 243, 1)","buttonBgcolorHover":"rgba(255, 255, 255, 1)","buttonEntranceTimeout":"0","buttonEntranceAnimation":"fade","buttonHoverAnimation":"none","buttonShowAfterScrolling":{"desktop":"0","mobile":"0"},"popupOverlayColor":"rgba(2, 83, 238, 1)","popupBackgroundColor":"rgba(255, 255, 255, 1)","popupKeyColor":"rgba(33, 111, 243, 1)","popupBorderRadius":"20","popupAnimation":"fade","popupScroll":"","closeAnywhere":"","popupDraggable":"1","highlightP":"","readAlt":"","hotKeyOpenInterface":"Alt+9","saveConfig":"on","analytics":"off","analyticsSendInterval":"2","analyticsGDPR":"off","statementType":"inline","LEARN_MORE_IN_WIKIPEDIA":"Learn more in Wikipedia","DEFAULT":"Default","HOME":"Home","HIDE_ACCESSIBILITY_INTERFACE":"If you choose to hide the accessibility interface, you won't be able to see it anymore, unless you clear clear cookies for this site. Are you sure that you wish to hide the interface?","readingMaskHeight":"100","virtualKeyboardLayout":["english"],"virtualKeyboardLayouts":{"en":"{\"default\":[\"` 1 2 3 4 5 6 7 8 9 0 - = {bksp}\",\"{tab} q w e r t y u i o p [ ] \\\\\",\"{lock} a s d f g h j k l ; ' {enter}\",\"{shift} z x c v b n m , . \\/ {shift}\",\".com @ {space}\"],\"shift\":[\"~ ! @ # $ % ^ & * ( ) _ + {bksp}\",\"{tab} Q W E R T Y U I O P { } |\",\"{lock} A S D F G H J K L : \\\" {enter}\",\"{shift} Z X C V B N M \u003C \u003E ? {shift}\",\".com @ {space}\"],\"lang\":{\"en\":\"English\"}}"},"hotKeyMenu":"","hotKeyHeadings":"","hotKeyForms":"","hotKeyButtons":"","hotKeyGraphics":"","highlightFocusColor":"#639af9","voiceNavigationAliases":{"help":"Help","help_me":"Help me","show_commands":"Show commands","what_can_i_say":"What can I say","what_can_i_do":"What can I do","what_can_you_do":"What can you do","available_commands":"Available commands","commands_list":"Commands list","hide_help":"Hide help","hide_commands":"Hide commands","hide_commands_list":"Hide commands list","hide_available_commands":"Hide available commands","collapse_commands":"Collapse commands","scroll_down":"Scroll down","down":"Down","page_down":"Page Down","go_down":"Go down","scroll_up":"Scroll up","up":"Up","page_up":"Page Up","go_up":"Go up","go_to_top":"Go to top","top":"Top","page_top":"Page Top","go_to_start":"Go to start","scroll_to_top":"Scroll to top","go_to_bottom":"Go to bottom","bottom":"Bottom","page_bottom":"Page Bottom","go_to_end":"Go to end","scroll_to_bottom":"Scroll to bottom","tab":"Tab","next":"Next","next_tab":"Next Tab","go_to_next":"Go to next","go_to_next_tab":"Go to next tab","tab_back":"Tab back","previous":"Previous","previous_tab":"Previous Tab","go_to_previous":"Go to previous","go_to_previous_tab":"Go to previous tab","show_numbers":"Show numbers","display_numbers":"Display numbers","enable_numbers":"Enable numbers","navigation_numbers":"Navigation numbers","mark_links":"Mark links","number_links":"Number links","click":"Click","press":"Press","open":"Open","go_to":"Go to","go":"Go","select":"Select","hide_numbers":"Hide numbers","disable_numbers":"Disable numbers","remove_numbers":"Remove numbers","hide_mark_links":"Mark links","hide_number_links":"Number links","clear_input":"Clear input","clear":"Clear","remove":"Remove","delete":"Delete","clear_text":"Clear text","clear_search":"Clear search","enter":"Enter","submit":"Submit","ok":"Ok","confirm":"Confirm","accept":"Accept","return":"Return","yes":"Yes","reload":"Reload","refresh":"Refresh","update":"Update","refresh_page":"Refresh page","reload_page":"Reload page","reload_website":"Reload website","refresh_website":"Refresh website","stop":"Stop","cancel":"Cancel","stop_listening":"Stop listening","cancel_listening":"Cancel listening","stop_recording":"Stop recording","stop_voice_navigation":"Stop voice navigation","abort":"Abort","exit":"Exit","quit":"Quit","close":"Close","close_window":"Close window","close_navigation":"Close navigation","close_panel":"Close panel","number":"Number ... "},"voiceNavigationDescription":{"help":"Display a list of available voice commands","hide_help":"Hide a list of available voice commands","scroll_down":"Scroll page down 200 px","scroll_up":"Scroll page down 200 px","go_to_top":"Scroll page to top","go_to_bottom":"Scroll page to bottom","tab":"Move to next interactive element","tab_back":"Move to previous interactive element","show_numbers":"Show numbers for interactive elements","number":"Click on element number...","hide_numbers":"Hide numbers for interactive elements","clear_input":"Clear selected text field","enter":"Click on the selected element","reload":"Reload page","stop":"Stop speech recognition","exit":"Disable voice navigation mode"},"voiceNavigationRerun":"off","scrollDownValue":"200","scrollUpValue":"-200","scrollLeftValue":"-200","scrollRightValue":"200","voiceNavigationVoiceGraph":"on","voiceNavigationInterimResults":"on","voiceNavigationFeedback":"on","voiceNavigationFeedbackOk":["OK","Yes","Done"],"voiceNavigationFeedbackStart":["Start listening","Begin listening","Listening"],"voiceNavigationFeedbackEnd":["End listening","Stop listening","Finish listening"]}; //# sourceURL=mdp-readabler-js-extra For full functionality of this site it is necessary to enable JavaScript. window._googlesitekit = window._googlesitekit || {}; window._googlesitekit.contentEvents = {"postID":24,"isReadableSinglePost":false,"hasVimeoEmbed":false,"wordCount":0,"estimatedReadTimeSeconds":0,"isLastPageOfMultiPagePost":false,"readTimeThresholdPercent":85,"minimumReadTimeSeconds":5}; //# sourceURL=googlesitekit-events-provider-content-events-js-before window.gtranslateSettings = /* document.write */ window.gtranslateSettings || {};window.gtranslateSettings['81955390'] = {"default_language":"en","languages":["en","es"],"url_structure":"none","native_language_names":1,"detect_browser_language":1,"flag_style":"2d","wrapper_selector":"#gt-wrapper-81955390","alt_flags":{"en":"usa"},"float_switcher_open_direction":"top","switcher_horizontal_position":"left","switcher_vertical_position":"bottom","flags_location":"\/wp-content\/plugins\/gtranslate\/flags\/"}; //# sourceURL=gt_widget_script_81955390-js-before wp.i18n.setLocaleData( { 'text direction\u0004ltr': [ 'ltr' ] } ); //# sourceURL=wp-i18n-js-after var ElementorProFrontendConfig = {"ajaxurl":"https:\/\/brianstireandservice.com\/wp-admin\/admin-ajax.php","nonce":"ef95be8132","urls":{"assets":"https:\/\/brianstireandservice.com\/wp-content\/plugins\/elementor-pro\/assets\/","rest":"https:\/\/brianstireandservice.com\/wp-json\/"},"settings":{"lazy_load_background_images":true},"popup":{"hasPopUps":true},"shareButtonsNetworks":{"facebook":{"title":"Facebook","has_counter":true},"twitter":{"title":"Twitter"},"linkedin":{"title":"LinkedIn","has_counter":true},"pinterest":{"title":"Pinterest","has_counter":true},"reddit":{"title":"Reddit","has_counter":true},"vk":{"title":"VK","has_counter":true},"odnoklassniki":{"title":"OK","has_counter":true},"tumblr":{"title":"Tumblr"},"digg":{"title":"Digg"},"skype":{"title":"Skype"},"stumbleupon":{"title":"StumbleUpon","has_counter":true},"mix":{"title":"Mix"},"telegram":{"title":"Telegram"},"pocket":{"title":"Pocket","has_counter":true},"xing":{"title":"XING","has_counter":true},"whatsapp":{"title":"WhatsApp"},"email":{"title":"Email"},"print":{"title":"Print"},"x-twitter":{"title":"X"},"threads":{"title":"Threads"}},"facebook_sdk":{"lang":"en_US","app_id":""},"lottie":{"defaultAnimationUrl":"https:\/\/brianstireandservice.com\/wp-content\/plugins\/elementor-pro\/modules\/lottie\/assets\/animations\/default.json"}}; //# sourceURL=elementor-pro-frontend-js-before {"baseUrl":"https://s.w.org/images/core/emoji/17.0.2/72x72/","ext":".png","svgUrl":"https://s.w.org/images/core/emoji/17.0.2/svg/","svgExt":".svg","source":{"concatemoji":"https://brianstireandservice.com/wp-includes/js/wp-emoji-release.min.js?ver=7.1.4"}} /*! This file is auto-generated */ var e="script#wp-emoji-settings",t=document.querySelector(e);if(!(t instanceof HTMLScriptElement))throw new Error("Element missing: "+e);const r=JSON.parse(t.text),s=(window._wpemojiSettings=r,"wpEmojiSettingsSupports"),o=["flag","emoji"];function i(e){try{var t={supportTests:e,timestamp:(new Date).valueOf()};sessionStorage.setItem(s,JSON.stringify(t))}catch(e){}}function c(e,t,n){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);t=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(n,0,0);const r=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);return t.every((e,t)=>e===r[t])}function p(e,t){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);var n=e.getImageData(16,16,1,1);for(let e=0;e{o[e]=t(s,e,n,r)}),o}function a(e){var t=document.createElement("script");t.src=e,t.defer=!0,document.head.appendChild(t)}r.supports={everything:!0,everythingExceptFlag:!0},new Promise(t=>{let n=function(){try{var e=JSON.parse(sessionStorage.getItem(s));if("object"==typeof e&&"number"==typeof e.timestamp&&(new Date).valueOf(){i(n=e.data),a.terminate(),t(n)})}catch(e){}i(n=f(o,u,c,p))}t(n)}).then(e=>{for(const n in e)r.supports[n]=e[n],r.supports.everything=r.supports.everything&&r.supports[n],"flag"!==n&&(r.supports.everythingExceptFlag=r.supports.everythingExceptFlag&&r.supports[n]);var t;r.supports.everythingExceptFlag=r.supports.everythingExceptFlag&&!r.supports.flag,r.supports.everything||((t=r.source||{}).concatemoji?a(t.concatemoji):t.wpemoji&&t.twemoji&&(a(t.twemoji),a(t.wpemoji)))}); //# sourceURL=https://brianstireandservice.com/wp-includes/js/wp-emoji-loader.min.js /** * Leadflow Collector — client-side tracking engine. * * Auto-detects every on the page. No manual configuration of * individual forms is required. * * For each form it: * 1. Starts a timer on the first field interaction. * 2. On submit, compiles a JSON payload covering the four pillars: * - usage_data (page url, title, referrer, viewport) * - behavior_metrics (seconds spent filling the form) * - lead_payload (form id/class + every field name -> value) * - lead_email (best-guess email, promoted to top level) * 3. Sends the payload via fetch() WITHOUT blocking or preventing the * native submit — the host site's form behaves exactly as before. * * https://inceptial.team/SEO-Dashboard/wp-json/hub-leads/v1/capture, 5U50fReBFK3oJEP1pCgWeODjtthGfeALafZYt3V2, https://brianstireandservice.com/wp-admin/admin-ajax.php, and a623cc6a42 are replaced * server-side (PHP) before this file is ever printed to the page. */ ( function () { 'use strict'; var HUB_ENDPOINT = 'https://inceptial.team/SEO-Dashboard/wp-json/hub-leads/v1/capture'; var HUB_API_KEY = '5U50fReBFK3oJEP1pCgWeODjtthGfeALafZYt3V2'; var HUB_LOG_URL = 'https://brianstireandservice.com/wp-admin/admin-ajax.php'; var HUB_LOG_NONCE = 'a623cc6a42'; // URL of the Collector's store-sync-key REST endpoint. Empty string once // the sync_key has been persisted server-side (PHP outputs '' at that point). var HUB_STORE_SYNC_KEY_URL = ''; // Click Trackers — phone/email/location/anything else defined on the // Collector's settings page. Substituted server-side as a raw JSON // array literal (valid JSON is valid JS), NOT a quoted string — a // tracker label containing an apostrophe (e.g. "Book It's Time") // would otherwise break out of a quoted string. See attachClickTrackers(). var CLICK_TRACKERS = [{"id":"call","label":"Call","href_prefixes":["tel:"],"href_contains":[],"keywords":["call 256-704-8473"],"selector":"","text_pattern":"phone"},{"id":"email-click","label":"Email Click","href_prefixes":["mailto:"],"href_contains":[],"keywords":["info@brians.tires"],"selector":"","text_pattern":"email"},{"id":"location-click","label":"Location Click","href_prefixes":[],"href_contains":[],"keywords":["1024 putman dr nw","huntsville","al 35816","united states"],"selector":"","text_pattern":""},{"id":"book-an-appointment","label":"book an appointment","href_prefixes":[],"href_contains":[],"keywords":["book an appointment"],"selector":"","text_pattern":""},{"id":"call-2","label":"Call","href_prefixes":["tel:"],"href_contains":[],"keywords":["call: 256-704-8473"],"selector":"","text_pattern":"phone"}]; if ( ! Array.isArray( CLICK_TRACKERS ) ) { CLICK_TRACKERS = []; } // Page Trackers — fire a page_view event when the current URL matches // one of the configured tracked pages. Substituted server-side as a // raw JSON array literal. var PAGE_TRACKERS = [{"id":"car-engine","label":"car engine","page_url":"https:\/\/brianstireandservice.com\/auto-engine-repair\/","match_type":"contains","href_prefixes":[],"href_contains":[],"keywords":["learn more"],"selector":"","text_pattern":""}]; if ( ! Array.isArray( PAGE_TRACKERS ) ) { PAGE_TRACKERS = []; } // Belt-and-suspenders: the PHP injector already guards this, but never // run a half-configured tracker. if ( ! HUB_ENDPOINT || ! HUB_API_KEY ) { return; } /** * Cookie-based visitor ID — persists across sessions so returning * visitors can be identified even after closing and reopening the browser. * A new random ID is assigned on first visit (or after cookie clearance). * Expires after 2 years. Never contains personal data — just a random hex string. */ function getVisitorId() { var COOKIE_NAME = 'hub_vid'; var COOKIE_DAYS = 730; // 2 years // Try to read existing cookie. var existing = ''; var cookies = document.cookie ? document.cookie.split( ';' ) : []; for ( var i = 0; i < cookies.length; i++ ) { var parts = cookies[ i ].trim().split( '=' ); if ( parts[ 0 ] === COOKIE_NAME ) { existing = decodeURIComponent( parts[ 1 ] || '' ); break; } } if ( existing ) { return existing; } // Generate a new random ID: 16 hex chars. var id = ''; var chars = '0123456789abcdef'; for ( var j = 0; j < 16; j++ ) { id += chars[ Math.floor( Math.random() * 16 ) ]; } // Persist in cookie. var expires = new Date(); expires.setTime( expires.getTime() + COOKIE_DAYS * 24 * 60 * 60 * 1000 ); document.cookie = COOKIE_NAME + '=' + encodeURIComponent( id ) + '; expires=' + expires.toUTCString() + '; path=/' + '; SameSite=Lax'; return id; } // Resolve visitor ID once at page load and reuse across all payloads. var HUB_VISITOR_ID = getVisitorId(); /** * Lightweight User-Agent parse — device type, OS, browser. Good enough * for lead-gen reporting; not meant to rival a full UA-parsing library. * Order matters (e.g. iPad must be checked before "Mac" substring * traps, Edge before Chrome, etc.). */ function getDeviceInfo() { var ua = navigator.userAgent || ''; var deviceType = 'Desktop'; if ( /iPad/i.test( ua ) || ( /Macintosh/i.test( ua ) && 'ontouchend' in document ) ) { deviceType = 'Tablet'; } else if ( /Android/i.test( ua ) && ! /Mobile/i.test( ua ) ) { deviceType = 'Tablet'; } else if ( /Mobi|iPhone|Android/i.test( ua ) ) { deviceType = 'Mobile'; } var os = 'Unknown'; if ( /iPhone|iPad|iPod/i.test( ua ) ) { os = 'iOS'; } else if ( /Android/i.test( ua ) ) { os = 'Android'; } else if ( /Windows/i.test( ua ) ) { os = 'Windows'; } else if ( /Macintosh|Mac OS X/i.test( ua ) ) { os = 'macOS'; } else if ( /CrOS/i.test( ua ) ) { os = 'ChromeOS'; } else if ( /Linux/i.test( ua ) ) { os = 'Linux'; } var browser = 'Unknown'; if ( /Edg\// .test( ua ) ) { browser = 'Edge'; } else if ( /OPR\/|Opera/.test( ua ) ) { browser = 'Opera'; } else if ( /Firefox\//.test( ua ) ) { browser = 'Firefox'; } else if ( /CriOS\//.test( ua ) ) { browser = 'Chrome'; } else if ( /Chrome\//.test( ua ) && ! /Chromium\//.test( ua ) ) { browser = 'Chrome'; } else if ( /Safari\//.test( ua ) && /Version\//.test( ua ) ) { browser = 'Safari'; } return { type: deviceType, os: os, browser: browser, user_agent: ua.slice( 0, 300 ) }; } // Shared de-dupe registry between the native-submit-event path and the // network-level path (see patchFetch/patchXhr below), so a builder // that fires BOTH signals for the same real submission — e.g. no // CAPTCHA involved, so the native submit event works AND we also see // the underlying AJAX call — doesn't create two leads for one // submission. Keyed by form_type rather than a specific form // instance/id, since the network path only knows the builder, not // which exact on the page fired it. var recentlySent = {}; var DEDUPE_WINDOW_MS = 4000; function shouldSendForKey( key ) { var now = Date.now(); var last = recentlySent[ key ] || 0; if ( now - last < DEDUPE_WINDOW_MS ) { return false; } recentlySent[ key ] = now; return true; } /** * Fire-and-forget report to this site's OWN Activity Log (not the Hub). * Records metadata only — never field values or the email itself — so * the person managing this client site can see, locally, whether * submissions are making it out. Failures here are swallowed; a logging * hiccup must never affect the real lead delivery above. */ function logEvent( fields ) { if ( ! HUB_LOG_URL || ! HUB_LOG_NONCE ) { return; } try { var params = new URLSearchParams(); params.set( 'action', 'hub_collector_log_event' ); params.set( 'nonce', HUB_LOG_NONCE ); Object.keys( fields ).forEach( function ( key ) { var value = fields[ key ]; params.set( key, null === value || undefined === value ? '' : String( value ) ); } ); fetch( HUB_LOG_URL, { method: 'POST', keepalive: true, headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: params.toString() } ).catch( function () {} ); } catch ( e ) { // no-op } } // Per-form interaction state (when the visitor first touched a field). var formState = new WeakMap(); /** * Form-builder signature registry — Layer 1 of the detection system. * Every signature below was verified against each plugin's actual * rendered markup (official docs / source / GitHub), not guessed. * Checked top-to-bottom, first match wins. Unmatched forms fall through * to 'other' — they're still tracked normally, just unlabeled. * * Each `test` receives the element itself. `form.closest()` also * checks the form itself, so signatures work whether the matching class * lives on the tag or on a wrapping container around it. */ var FORM_BUILDER_SIGNATURES = [ { key: 'contact_form_7', test: function ( form ) { return form.classList.contains( 'wpcf7-form' ); } }, { key: 'wpforms', test: function ( form ) { return form.classList.contains( 'wpforms-form' ) || /^wpforms-form-/.test( form.id || '' ); } }, { key: 'gravity_forms', test: function ( form ) { return /^gform_\d+$/.test( form.id || '' ) || !! form.closest( '.gform_wrapper' ); } }, { key: 'ninja_forms', test: function ( form ) { return form.classList.contains( 'nf-form-layout' ) || !! form.closest( '.nf-form-cont' ); } }, { key: 'formidable', test: function ( form ) { return form.classList.contains( 'frm-show-form' ) || !! form.closest( '.frm_forms' ); } }, { key: 'fluent_forms', test: function ( form ) { return form.classList.contains( 'frm-fluent-form' ); } }, { key: 'elementor', // Elementor Pro submits via AJAX — the network watcher (fetch/XHR // patch) already captures the real submission. Skipping the DOM // submit event here prevents a duplicate lead. networkOnly: true, test: function ( form ) { return form.classList.contains( 'elementor-form' ); } }, { key: 'forminator', test: function ( form ) { return form.classList.contains( 'forminator-custom-form' ) || /^forminator-module-/.test( form.id || '' ); } }, { key: 'caldera_forms', test: function ( form ) { return form.classList.contains( 'caldera-forms-form' ) || /^caldera_forms_form/.test( form.id || '' ); } }, { key: 'divi', test: function ( form ) { return form.classList.contains( 'et_pb_contact_form' ); } }, { key: 'woocommerce_checkout', test: function ( form ) { return form.classList.contains( 'woocommerce-checkout' ); } }, { key: 'jetpack', test: function ( form ) { return !! form.closest( '.contact-form-container' ) || !! form.closest( '.wp-block-jetpack-contact-form' ); } }, { key: 'hubspot', test: function ( form ) { return form.classList.contains( 'hs-form' ); } }, { key: 'mailchimp', test: function ( form ) { return 'mc-embedded-subscribe-form' === form.id; } } ]; /** * Returns a signature key ('wpforms', 'elementor', etc.) or 'other' if * nothing matched. A single broken test must never crash detection for * the rest of the registry or for the form's own submission. */ function detectFormBuilder( form ) { for ( var i = 0; i < FORM_BUILDER_SIGNATURES.length; i++ ) { try { if ( FORM_BUILDER_SIGNATURES[ i ].test( form ) ) { return FORM_BUILDER_SIGNATURES[ i ].key; } } catch ( e ) { // Skip this signature, keep checking the rest. } } return 'other'; } /** * Returns true for builders that submit via AJAX and are already captured * by the network watcher. The DOM submit listener skips these to prevent * sending a duplicate lead. */ function isNetworkOnlyBuilder( form ) { for ( var i = 0; i < FORM_BUILDER_SIGNATURES.length; i++ ) { try { if ( FORM_BUILDER_SIGNATURES[ i ].networkOnly && FORM_BUILDER_SIGNATURES[ i ].test( form ) ) { return true; } } catch ( e ) {} } return false; } /** * Forms that are never leads: WordPress's own login form, the default * comment form, and search forms. Excluded by default so they never * pollute lead data — these never get a listener attached at all. */ function isExcludedForm( form ) { if ( 'loginform' === form.id || 'commentform' === form.id ) { return true; } if ( 'search' === ( form.getAttribute( 'role' ) || '' ).toLowerCase() ) { return true; } if ( form.classList.contains( 'search-form' ) ) { return true; } return false; } function cssEscape( value ) { if ( window.CSS && typeof window.CSS.escape === 'function' ) { return window.CSS.escape( value ); } return String( value ).replace( /([^\w-])/g, '\\$1' ); } /** * Best-effort human-readable label for a field: