(function( $ ) {
	'use strict';

	/**
	 * Debug logging function that only logs when debug is enabled AND pinnerpressdebug=1 URL param is present
	 * @param {...any} args - Arguments to log
	 */
	function pinnerpressDebugLog() {
		// Check if debug URL parameter is present
		var urlParams = new URLSearchParams(window.location.search);
		var debugParam = urlParams.get('pinnerpress_debug');
		
		if (typeof pinnerpress_data !== 'undefined' && pinnerpress_data.debug_enabled && debugParam === '1') {
			console.log.apply(console, arguments);
		}
	}

	/**
	 * Debug error function that only logs when debug is enabled AND pinnerpressdebug=1 URL param is present
	 * @param {...any} args - Arguments to log
	 */
	function pinnerpressDebugError() {
		// Check if debug URL parameter is present
		var urlParams = new URLSearchParams(window.location.search);
		var debugParam = urlParams.get('pinnerpress_debug');
		
		if (typeof pinnerpress_data !== 'undefined' && pinnerpress_data.debug_enabled && debugParam === '1') {
			console.error.apply(console, arguments);
		}
	}

	/**
	 * Track analytics event
	 * @param {string} eventType - The type of event to track
	 * @param {object} eventData - Additional data for the event
	 */
	function pinnerpressTrackEvent(eventType, eventData) {
		// Check if analytics is enabled
		if (typeof pinnerpress_data === 'undefined' || pinnerpress_data.analytics_enabled !== '1') {
			pinnerpressDebugLog('PinnerPress Analytics: Analytics is disabled, not tracking event:', eventType);
			return;
		}

		// Check if we have the required data
		if (typeof pinnerpress_data.analytics_nonce === 'undefined') {
			pinnerpressDebugLog('PinnerPress Analytics: Missing analytics nonce, cannot track event:', eventType);
			return;
		}

		pinnerpressDebugLog('PinnerPress Analytics: Tracking event:', eventType, eventData);

		// Prepare data for AJAX request
		var data = {
			action: 'pinnerpress_track_event',
			nonce: pinnerpress_data.analytics_nonce,
			event_type: eventType,
			event_data: eventData || {},
			post_id: pinnerpress_data.post_id
		};

		// Send AJAX request
		$.post(pinnerpress_data.ajaxurl, data, function(response) {
			if (response.success) {
				pinnerpressDebugLog('PinnerPress Analytics: Event tracked successfully', eventType, eventData);
			} else {
				pinnerpressDebugLog('PinnerPress Analytics: Failed to track event', response);
				pinnerpressDebugError('PinnerPress Analytics Error:', response.data || 'Unknown error');
			}
		}).fail(function(xhr, status, error) {
			pinnerpressDebugLog('PinnerPress Analytics: AJAX request failed', status, error);
			pinnerpressDebugError('PinnerPress Analytics AJAX Error:', status, error, xhr.responseText);
		});
	}
	
	// Make the tracking function available globally for external use
	window.pinnerpressTrackEvent = pinnerpressTrackEvent;

	/**
	 * Generate a consistent image ID from URL
	 * @param {string} imageUrl - The image URL
	 * @returns {string} The generated image ID
	 */
	function generateImageId(imageUrl) {
		if (!imageUrl) return null;

		// Remove query parameters, hash, and trailing slashes
		var cleanUrl = imageUrl.split('?')[0].split('#')[0].replace(/\/+$/, '');

		// Handle Cloudflare Images URLs (e.g. imagedelivery.net/.../filename.jpg/variant)
		// The last segment is a variant name like "public", so use the second-to-last segment
		var parts = cleanUrl.split('/');
		var filename = parts[parts.length - 1];
		if (cleanUrl.includes('imagedelivery.net') && parts.length > 2 && !/\.\w{2,5}$/.test(filename)) {
			filename = parts[parts.length - 2];
		}

		// Remove WordPress size suffix (e.g., -150x150) before removing extension
		var nameWithoutSize = filename.replace(/-\d+x\d+(\.\w+)$/, '$1');
		var nameWithoutExt = nameWithoutSize.replace(/\.[^/.]+$/, '');
		
		// FIXED: Convert to lowercase for consistent case handling
		nameWithoutExt = nameWithoutExt.toLowerCase();
		
		// If filename is too generic, use a hash
		var genericNames = ['image', 'img', 'photo', 'pic', 'public', 'original', 'default'];
		if (nameWithoutExt.length < 3 || genericNames.indexOf(nameWithoutExt) !== -1) {
			// Simple hash function
			var hash = 0;
			for (var i = 0; i < cleanUrl.length; i++) {
				var char = cleanUrl.charCodeAt(i);
				hash = ((hash << 5) - hash) + char;
				hash = hash & hash; // Convert to 32bit integer
			}
			var hashId = 'img_' + Math.abs(hash).toString(16).substring(0, 8);
			pinnerpressDebugLog('Generated hash ID for generic image:', hashId, 'from URL:', imageUrl);
			return hashId;
		}
		
		// FIXED: Sanitize and ensure lowercase for consistent results
		var imageId = nameWithoutExt.replace(/[^a-zA-Z0-9_-]/g, '_').toLowerCase().substring(0, 255);
		pinnerpressDebugLog('Generated image ID:', imageId, 'from URL:', imageUrl);
		return imageId;
	}
	
	/**
	 * Extract attachment ID from WordPress image classes
	 * @param {jQuery} $img - The image jQuery element
	 * @returns {number|null} The attachment ID or null
	 */
	function getAttachmentId($img) {
		var classes = $img.attr('class') || '';
		var match = classes.match(/wp-image-(\d+)/);
		return match ? parseInt(match[1], 10) : null;
	}

	/**
	 * Resolve the real image URL for an <img> element.
	 * Lazy-loading plugins replace src with a tiny placeholder (data:image/svg+xml,
	 * data:image/gif, etc.) and store the real URL in a data attribute.  This
	 * helper returns the actual image URL regardless of lazy-load state.
	 *
	 * @param {jQuery} $img - The image jQuery element
	 * @returns {string} The resolved image URL (may still be empty if no URL found)
	 */
	function resolveImageSrc($img) {
		var src = $img.attr('src') || '';
		if (src && !src.startsWith('data:') && src !== '' && src !== '#') {
			return src;
		}
		// Try common lazy-loading data attributes
		var lazyAttrs = [
			'data-lazy-src', 'data-src', 'data-original', 'data-full-src',
			'data-img-src', 'data-image', 'data-large', 'data-medium'
		];
		for (var i = 0; i < lazyAttrs.length; i++) {
			var val = $img.attr(lazyAttrs[i]);
			if (val && !val.startsWith('data:') && val !== '' && val !== '#') {
				return val;
			}
		}
		// Try srcset as last resort
		var srcset = $img.attr('srcset') || $img.attr('data-srcset') || $img.attr('data-lazy-srcset');
		if (srcset) {
			var firstUrl = srcset.split(',')[0].trim().split(' ')[0];
			if (firstUrl && !firstUrl.startsWith('data:')) {
				return firstUrl;
			}
		}
		return src; // Return whatever we have, even if it's a placeholder
	}

	/**
	 * All of the code for your public-facing JavaScript source
	 * should reside in this file.
	 */
	$(document).ready(function() {
		// Add Pin buttons to content images
		addPinButtons();
		
		// Initialize follow box functionality
		initFollowBox();

		// Check if we should show the follow box on page load
		checkShowFollowBoxOnPageLoad();

		// Console log the follow box status for debugging
		pinnerpressDebugLog('Follow Box Status:', typeof pinnerpress_data !== 'undefined' ? pinnerpress_data.follow_box_status : 'undefined');
		pinnerpressDebugLog('Follow Box Cookie:', hasFollowBoxCookie());
		
		// DISABLED: Impression tracking removed
		// Track post impression
		// trackPostImpression();

		// Initialize image viewport tracking
		// initImageViewportTracking();
		
		// Initialize hidden pins modal
		initHiddenPinsModal();
		
		// Also run after window load to catch any late-loading images
		$(window).on('load', function() {
			pinnerpressDebugLog('Window loaded, running addPinButtons again for late-loading images');
			setTimeout(function() {
				addPinButtons();
			}, 500);
		});


		// Add general analytics tracking for elements with data-pinnerpress-track attribute
		$(document).on('click', '[data-pinnerpress-track]', function() {
			var eventType = $(this).data('pinnerpress-track');
			var eventData = {
				element_type: this.tagName.toLowerCase(),
				element_class: $(this).attr('class') || '',
				href: $(this).attr('href') || '',
				text: $(this).text().trim()
			};
			
			pinnerpressTrackEvent(eventType, eventData);
		});
		
		// Track clicks on block editor follow buttons
		$(document).on('click', '.pinnerpress-follow-button', function() {
			pinnerpressDebugLog('FOLLOW BUTTON CLICKED');
			pinnerpressDebugLog('Block editor follow button clicked.');
			
			// Track analytics event
			pinnerpressTrackEvent('block_editor_button_click', {
				source: 'block_editor_follow_button',
				pinterest_url: $(this).attr('href') || '',
				button_text: $(this).text().trim(),
				button_class: $(this).attr('class') || ''
			});
			
			// Let the click continue (open Pinterest profile in new tab)
			return true;
		});
	});
	
	/**
	 * Add Pinterest Pin It buttons to all eligible images
	 */
	function addPinButtons() {
		// Exclude home and front pages
		if ($('body').hasClass('home') || $('body').hasClass('blog')) {
			pinnerpressDebugLog('Pin Buttons disabled on home/blog pages.');
			return;
		}
		
		// Check if this is a single post page
		var isValidPage = $('body').hasClass('single-post') || $('body').hasClass('single');
		
		if (!isValidPage) {
			pinnerpressDebugLog('Pin Buttons only display on single post pages.');
			return;
		}
		
		// Check if Pin Button is enabled in the settings
		if (typeof pinnerpress_data !== 'undefined' && pinnerpress_data.pin_button_status === 'off') {
			pinnerpressDebugLog('Pin Button is disabled in settings.');
			return;
		}
		
		// NOTE: We don't return early for post/category pin button disables anymore
		// because Image Banners might still need to be added (they have separate disable flags)
		
		// Enable debug logging for this function
		pinnerpressDebugLog('PinnerPress Debug: Starting addPinButtons()');
		pinnerpressDebugLog('PinnerPress Settings:', pinnerpress_data);
		
		// FIRST: Fix any existing containers that don't have buttons (especially in galleries)
		pinnerpressDebugLog('PinnerPress: Checking for existing containers to fix...');
		
		// Find ALL elements with the pinnerpress-pin-it-container class
		var $allContainers = $('.pinnerpress-pin-it-container');
		pinnerpressDebugLog('PinnerPress: Found ' + $allContainers.length + ' total containers on page');
		
		$allContainers.each(function() {
			var $container = $(this);
			var $img = $container.find('img').first();
			
			// Check if this container has a button
			var hasButton = $container.find('.pinnerpress-pin-it-button').length > 0;
			var hasBanner = $container.find('.pinnerpress-image-banner').length > 0;
			
			pinnerpressDebugLog('Container check:', {
				'has_image': $img.length > 0,
				'has_button': hasButton,
				'has_banner': hasBanner,
				'image_src': $img.attr('src') || 'no image'
			});
			
			// If container has an image but no button, add the button
			if ($img.length > 0 && !hasButton) {
				pinnerpressDebugLog('Found orphaned container without button, checking if button should be added for:', resolveImageSrc($img));

				// Get image details (resolve lazy-load placeholders)
				var imgUrl = resolveImageSrc($img);
				var pageUrl = window.location.href;
				var description = '';
				var title = '';

				// Get description and title
				if ($img.attr('data-pin-description')) {
					description = $img.attr('data-pin-description');
				} else if ($img.attr('alt')) {
					description = $img.attr('alt');
				} else if ($img.attr('title')) {
					description = $img.attr('title');
				} else {
					description = document.title;
				}

				if ($img.attr('data-pin-title')) {
					title = $img.attr('data-pin-title');
				}

				// Check if this is a gallery image
				var isGalleryImage = $container.closest('.wp-block-gallery').length > 0 || $container.hasClass('wp-block-image');

				// Add the pin button to the existing container (unless disabled for this post/category)
				var shouldAddPinButton = true;
				if (typeof pinnerpress_data !== 'undefined') {
					if (pinnerpress_data.post_disable_pin_buttons === '1') {
						pinnerpressDebugLog('Pin Buttons are disabled for this post.');
						shouldAddPinButton = false;
					} else if (pinnerpress_data.category_disable_pin_button === '1') {
						pinnerpressDebugLog('Pin Buttons are disabled for this post category.');
						shouldAddPinButton = false;
					}
				}

				if (shouldAddPinButton) {
					createPinButton($container, imgUrl, pageUrl, description, title, 0, isGalleryImage);
				}

				// Add banner if enabled (banners have their own disable checks)
				if (typeof pinnerpress_data !== 'undefined' && pinnerpress_data.banner_status === 'on') {
					if (pinnerpress_data.post_disable_image_banners !== '1' && pinnerpress_data.category_disable_banner !== '1') {
						createImageBanner($container, imgUrl, pageUrl, description, title, 0, isGalleryImage);
					}
				}
			}
		});

		var $images = $();

		// Check if custom selectors are enabled
		if (typeof pinnerpress_data !== 'undefined' && pinnerpress_data.pin_button_custom_selectors_enabled === '1') {
			var customSelectors = pinnerpress_data.pin_button_custom_selectors;

			if (customSelectors && customSelectors.trim() !== '') {
				// Split selectors by newline and clean them
				var selectors = customSelectors.split('\n').map(function(s) {
					return s.trim();
				}).filter(function(s) {
					return s !== '';
				});

				if (selectors.length > 0) {
					if (pinnerpress_data.pin_button_find_images_in_selectors === '1') {
						// Find all images inside the specified selectors
						$images = $();
						selectors.forEach(function(selector) {
							try {
								$images = $images.add($(selector).find('img'));
							} catch (e) {
								pinnerpressDebugLog('PinnerPress: Invalid selector:', selector, e);
							}
						});
					} else {
						// Use selectors directly (they should point to images)
						var combinedSelector = selectors.join(', ');
						try {
							$images = $(combinedSelector);
						} catch (e) {
							pinnerpressDebugLog('PinnerPress: Invalid custom selectors:', e);
							$images = $();
						}
					}

					pinnerpressDebugLog('PinnerPress: Using custom selectors, found', $images.length, 'images');
					// Skip the default selector logic
				} else {
					pinnerpressDebugLog('PinnerPress: Custom selectors enabled but no valid selectors provided');
					$images = $();
				}
			} else {
				pinnerpressDebugLog('PinnerPress: Custom selectors enabled but empty');
				$images = $();
			}
		} else {
			// Check if we're on a single post page
			var isSinglePost = $('body').hasClass('single-post') || $('body').hasClass('single');

			if (isSinglePost) {
				// Method 1: Find images in common content containers
				var contentSelectors = [
				'.entry-content',
				'.post-content',
				'.content-area',
				'.site-content',
				'article .inside-article',
				'.wp-block-post-content',
				'.et_pb_post_content', // Divi theme
				'main',
				'.wp-block-gallery' // Add specific selector for galleries
			];
			
			// Try each content selector until we find one with images
			for (var i = 0; i < contentSelectors.length; i++) {
				var $contentArea = $(contentSelectors[i]);
				if ($contentArea.length > 0) {
					// Find all img tags within the content area
					var $foundImages = $contentArea.find('img').filter(function() {
						var $img = $(this);
						var src = $img.attr('src') || '';
						
						// Resolve the real image URL for lazy-loaded images.
						// Many lazy-loading plugins set src to a tiny placeholder
						// (data:image/svg+xml, data:image/gif) and store the real
						// URL in a data attribute.  We need the real URL to decide
						// whether this is a content image worth pinning.
						var realSrc = src;
						if (!realSrc || realSrc.startsWith('data:') || realSrc === '' || realSrc === '#') {
							var lazyAttrs = ['data-lazy-src', 'data-src', 'data-original', 'data-full-src', 'data-img-src'];
							for (var j = 0; j < lazyAttrs.length; j++) {
								var val = $img.attr(lazyAttrs[j]);
								if (val && !val.startsWith('data:') && val !== '' && val !== '#') {
									realSrc = val;
									break;
								}
							}
						}
						
						// Filter out non-content images
						if ($img.closest('#wpadminbar').length > 0) return false;
						if ($img.closest('.admin-bar-menu').length > 0) return false;
						if ($img.hasClass('avatar') || $img.hasClass('gravatar')) return false;
						if ($img.hasClass('emoji')) return false;
						if (realSrc.includes('gravatar.com') || realSrc.includes('emoji')) return false;
						// Only exclude actual .svg file URLs, not data:image/svg+xml placeholders
						if (realSrc.split('?')[0].split('#')[0].toLowerCase().endsWith('.svg')) return false;
						
						// If src is still a data URI placeholder with no real URL found,
						// this is likely a tracking pixel or spacer — skip it
						if (realSrc.startsWith('data:')) return false;
						
						// Include images that are likely content images
						// Check if it's in wp-content/uploads or has wp-image class or is in a figure tag
						var isWpImage = $img.attr('class') && $img.attr('class').includes('wp-image-');
						var isInUploads = realSrc.includes('/wp-content/uploads/');
						var isInFigure = $img.closest('figure').length > 0;
						var isInBlockImage = $img.closest('.wp-block-image, .gb-block-image').length > 0;
						// Also include images served from known CDNs (Cloudflare Images, imgix, etc.)
						var isFromCdn = realSrc.includes('imagedelivery.net') || realSrc.includes('imgix.net') || realSrc.includes('cdn.shopify.com');
						// Include any image with a data-lazy-src (it was intentionally placed in content)
						var hasLazySrc = $img.attr('data-lazy-src') && !$img.attr('data-lazy-src').startsWith('data:');
						
						// Include if any of these conditions are true
						return isWpImage || isInUploads || isInFigure || isInBlockImage || isFromCdn || hasLazySrc;
					});
					
					if ($foundImages.length > 0) {
						$images = $images.add($foundImages);
						pinnerpressDebugLog('Found ' + $foundImages.length + ' images in ' + contentSelectors[i]);
					}
				}
			}
			} else if ($('article').length > 0) {
				// Fallback for archive pages or other non-single pages with articles
				$images = $('article').find('img[class*="wp-image-"], figure img, .wp-block-image img');
			}
		}

		// Remove duplicates
		var uniqueImages = [];
		$images.each(function() {
			if (uniqueImages.indexOf(this) === -1) {
				uniqueImages.push(this);
			}
		});
		$images = $(uniqueImages);
		
		pinnerpressDebugLog('PinnerPress: Found ' + $images.length + ' total unique images to process');
		
		// Also specifically look for gallery images that might have been missed
		var $galleryImages = $('.wp-block-gallery img');
		pinnerpressDebugLog('PinnerPress: Found ' + $galleryImages.length + ' gallery images specifically');
		
		// Debug: List all gallery images found
		$galleryImages.each(function(index) {
			pinnerpressDebugLog('Gallery image ' + index + ':', $(this).attr('src'), 'Classes:', $(this).attr('class'));
		});
		
		// Add gallery images that aren't already in our list
		$galleryImages.each(function() {
			var img = this;
			var found = false;
			$images.each(function() {
				if (this === img) {
					found = true;
					return false;
				}
			});
			if (!found) {
				$images = $images.add($(img));
				pinnerpressDebugLog('PinnerPress: Added missing gallery image:', $(img).attr('src'));
			}
		});

		pinnerpressDebugLog('PinnerPress: Final image count after gallery check: ' + $images.length);

		$images.each(function() {
			var $img = $(this);
			
			// Check if image already has a button (more specific check)
			var $parentContainer = $img.closest('.pinnerpress-pin-it-container');
			var hasButton = false;
			
			if ($parentContainer.length) {
				hasButton = $parentContainer.find('.pinnerpress-pin-it-button').length > 0;
				if (hasButton) {
					pinnerpressDebugLog('Skipping image - already has pin button:', $img.attr('src'));
					return;
				} else {
					pinnerpressDebugLog('Image in container but no button, will process:', $img.attr('src'));
				}
			}
			
			// Skip images with no-pin class
			if ($img.hasClass('pinnerpress-no-pin')) {
				pinnerpressDebugLog('Skipping image - has no-pin class:', $img.attr('src'));
				return;
			}
            
            // Check if pinning is disabled for this image via data attribute
            if ($img.attr('data-pin-nopin') === 'true') {
                pinnerpressDebugLog('Skipping image - has data-pin-nopin attribute:', $img.attr('src'));
                return;
            }
			
			// Check if this image is in a gallery
			var $galleryFigure = $img.closest('.wp-block-gallery figure.wp-block-image');
			var isInGallery = $galleryFigure.length > 0;
			
			// Resolve the real image URL (handles lazy-loading placeholders)
			var imgSrc = resolveImageSrc($img);
			
			// Skip actual SVG files (not data:image/svg placeholders — those are resolved above)
			if (imgSrc.split('?')[0].split('#')[0].toLowerCase().endsWith('.svg')) {
				pinnerpressDebugLog('Skipping SVG image:', imgSrc);
				return;
			}
			
			// Skip admin bar, navigation, avatar, and other non-content images
			// Check for specific non-content areas (more restrictive)
			if ($img.closest('#wpadminbar').length || 
				$img.closest('.admin-bar-menu').length ||
				$img.hasClass('avatar') || 
				$img.hasClass('gravatar') || 
				$img.hasClass('emoji') ||
				(imgSrc && (imgSrc.includes('gravatar.com') || imgSrc.includes('emoji')))) {
				pinnerpressDebugLog('Skipping image - avatar, gravatar, or emoji:', imgSrc);
				return;
			}
			
			// Get image URL, page URL and description
			var imgUrl = imgSrc;
			var pageUrl = window.location.href;
			var description = '';
            var title = '';
			
			pinnerpressDebugLog('Processing image:', {
				src: imgUrl,
				classes: $img.attr('class'),
				width: $img.width(),
				height: $img.height(),
				container: $img.parent().prop('tagName')
			});
			
			// Use a priority order for description
            // 1. Custom Pinterest description from block editor has highest priority
            if ($img.attr('data-pin-description')) {
                description = $img.attr('data-pin-description');
                pinnerpressDebugLog('Using custom Pinterest description:', description);
            }
            // 2. OpenGraph description from the page's meta tags (set by SEO plugins like Yoast, RankMath, AIOSEO, etc.)
            else {
				var ogDesc = $('meta[property="og:description"]').attr('content');
				if (ogDesc) {
					description = ogDesc;
				} else {
					description = document.title;
				}
			}
            
            // Check for custom Pinterest title (from block editor)
            if ($img.attr('data-pin-title')) {
                title = $img.attr('data-pin-title');
                pinnerpressDebugLog('Using custom Pinterest title:', title);
            }
			
			// Different handling for gallery images vs regular images
			var $container;
			
			// Check if image is already in a container
			if ($parentContainer.length) {
				// Image is already in a container, just use it
				pinnerpressDebugLog('Using existing container for image');
				$container = $parentContainer;
			} else if (isInGallery) {
				// For gallery images, use the figure as the container
				pinnerpressDebugLog('Gallery image detected, using figure as container');
				$galleryFigure.addClass('pinnerpress-pin-it-container');
				$galleryFigure.css({
					'position': 'relative'
				});
				$container = $galleryFigure;
			} else {
				// For regular images, wrap them
				$container = $('<div class="pinnerpress-pin-it-container"></div>');

				// Check if image is inside a Kadence ratio container
				// In that case, don't add position:relative as Kadence already has it on parent
				var isInKadenceRatio = $img.closest('.kb-is-ratio-image').length > 0;

				if (isInKadenceRatio) {
					pinnerpressDebugLog('Kadence ratio image detected, using position:static');
					$container.css({
						'position': 'static',
						'display': 'inline-block',
						'max-width': '100%',
						'font-size': '0' // Eliminate whitespace
					});
				} else {
					$container.css({
						'position': 'relative',
						'display': 'inline-block',
						'max-width': '100%',
						'font-size': '0' // Eliminate whitespace
					});
				}

				// Move the image into the container
				$img.wrap($container);
				$container = $img.parent();
			}
			
			// Create the pin button (pass isInGallery as the isGalleryImage parameter)
			// But only if pin buttons are not disabled for this post/category
			var shouldAddPinButton = true;
			if (typeof pinnerpress_data !== 'undefined') {
				if (pinnerpress_data.post_disable_pin_buttons === '1') {
					pinnerpressDebugLog('Pin Buttons are disabled for this post.');
					shouldAddPinButton = false;
				} else if (pinnerpress_data.category_disable_pin_button === '1') {
					pinnerpressDebugLog('Pin Buttons are disabled for this post category.');
					shouldAddPinButton = false;
				}
			}

			if (shouldAddPinButton) {
				createPinButton($container, imgUrl, pageUrl, description, title, 0, isInGallery);
			}

            // Add banner if enabled (banners have their own disable checks)
            if (typeof pinnerpress_data !== 'undefined' && pinnerpress_data.banner_status === 'on') {
                // Check if image banners are disabled for this specific post or category
                if (pinnerpress_data.post_disable_image_banners !== '1' && pinnerpress_data.category_disable_banner !== '1') {
                    createImageBanner($container, imgUrl, pageUrl, description, title, 0, isInGallery);
                }
            }
		});
	}
	
	/**
	 * Create a Pinterest Pin It button for an image
	 * @param {jQuery} $container - The container element to append the button to
	 * @param {string} imgUrl - The URL of the image
	 * @param {string} pageUrl - The URL of the current page
	 * @param {string} description - The description to use for the pin
	 * @param {string} title - The title to use for the pin (optional)
	 */
	function createPinButton($container, imgUrl, pageUrl, description, title, retryCount, isGalleryImage) {
		// Default retry count to 0 if not provided
		retryCount = retryCount || 0;
		// Get button settings from localized data (if available) or use defaults
		var position = 'top-right'; // Default position
		var shape = 'rectangular'; // Default shape
		var size = 'medium'; // Default size
		var color = '#E60023'; // Default Pinterest red
		var textColor = '#FFFFFF'; // Default white text
		var showText = true; // Default to showing text
		var buttonText = 'Pin It'; // Default text
		var imageShadow = false; // Default - no shadow
		
		// If we have localized data from WordPress, use those settings
		if (typeof pinnerpress_data !== 'undefined') {
			position = pinnerpress_data.position || position;
			shape = pinnerpress_data.shape || shape;
			size = pinnerpress_data.size || size;
			color = pinnerpress_data.color || color;
			textColor = pinnerpress_data.text_color || textColor;
			showText = pinnerpress_data.button_style === 'default';
			buttonText = pinnerpress_data.custom_button_text || buttonText;
			imageShadow = pinnerpress_data.image_shadow === '1'; // Convert to boolean
		}
		
		// Check if we should apply size filter to pin buttons
		var applyToButtons = (typeof pinnerpress_data !== 'undefined' && pinnerpress_data.size_filter_pin_buttons === '1');

		// Check if we should exclude gallery images from minimum size
		var excludeGalleryMinimum = (typeof pinnerpress_data !== 'undefined' && pinnerpress_data.exclude_gallery_minimum === '1');

		// Simple size check with retry mechanism
		var minimumSize = (typeof pinnerpress_data !== 'undefined' && pinnerpress_data.minimum_image_size)
			? parseInt(pinnerpress_data.minimum_image_size) : 250;

		// If size filter is not enabled for pin buttons, set minimum size to 0
		if (!applyToButtons) {
			pinnerpressDebugLog('Size filter not enabled for pin buttons, bypassing minimum size check');
			minimumSize = 0;
		}
		// If this is a gallery image and we're excluding them, set minimum size to 0
		else if (isGalleryImage && excludeGalleryMinimum) {
			pinnerpressDebugLog('Gallery image detected, bypassing minimum size check');
			minimumSize = 0;
		}
		
		// Find the image element within the container
		var $img = $container.find('img').first();
		if ($img.length > 0) {
			var imgElement = $img[0];

			// Detect lazy-loaded images that are still showing a placeholder.
			// Only bypass the size check when the src is still a data: URI or
			// empty — once the real image has loaded, apply the normal size
			// filter so small thumbnails/icons are correctly excluded.
			var isLazyPlaceholder = false;
			var currentSrc = $img.attr('src') || '';
			if (currentSrc.startsWith('data:') || currentSrc === '' || currentSrc === '#') {
				// src is a placeholder — check if there's a real URL in a lazy attr
				var hasLazyUrl = $img.attr('data-lazy-src') || $img.attr('data-src') || $img.attr('data-lazy-srcset');
				if (hasLazyUrl) {
					isLazyPlaceholder = true;
				}
			}

			if (!isLazyPlaceholder) {
				// Normal image — apply size check
				var rect = imgElement.getBoundingClientRect();
				var imgWidth = rect.width;
				var imgHeight = rect.height;

				// If getBoundingClientRect returns 0, try computed style
				if (imgWidth === 0 || imgHeight === 0) {
					var computedStyle = window.getComputedStyle(imgElement);
					imgWidth = parseFloat(computedStyle.width) || 0;
					imgHeight = parseFloat(computedStyle.height) || 0;
				}

				if (imgWidth > 0 && imgHeight > 0 && (imgWidth < minimumSize || imgHeight < minimumSize)) {
					pinnerpressDebugLog('PinnerPress: Skipping image - too small (' + imgWidth + 'x' + imgHeight + ', minimum: ' + minimumSize + ')');
					return;
				}

				// If dimensions are still 0, the image might not be loaded yet
				if ((imgWidth === 0 || imgHeight === 0) && retryCount < 3) {
					setTimeout(function() {
						createPinButton($container, imgUrl, pageUrl, description, title, retryCount + 1);
					}, 200);
					return;
				}
			} else {
				pinnerpressDebugLog('PinnerPress: Lazy-managed image detected, bypassing size check for:', imgUrl);
			}
		}
		
		// Determine size-related styles
		var iconSize, fontSize, padding, verticalAlign;
		switch(size) {
			case 'small':
				iconSize = '0.85em';
				fontSize = '12px';
				padding = '6px 10px';
				verticalAlign = '-0.1em'; // Adjusted for small button size
				break;
			case 'large':
				iconSize = '1.2em';
				fontSize = '16px';
				padding = '10px 15px';
				verticalAlign = '-0.15em'; // Slightly adjusted for large buttons
				break;
			default: // medium
				iconSize = '1em';
				fontSize = '14px';
				padding = '8px 12px';
				verticalAlign = '-0.125em'; // Default alignment
		}
		
		// Determine border-radius based on shape
		var borderRadius = shape === 'round' ? '20px' : '3px';
		
		// Create button wrapper with positioning
		var $wrapper = $('<div class="pinnerpress-pin-it-button-wrapper"></div>');
		$wrapper.css({
			'position': 'absolute',
			'z-index': '10'
		});
		
		// Set position
		var offset = '10px';
		switch(position) {
			case 'top-left':
				$wrapper.css({
					'top': offset,
					'left': offset
				});
				break;
			case 'top-right':
				$wrapper.css({
					'top': offset,
					'right': offset
				});
				break;
			case 'center':
				$wrapper.css({
					'top': '50%',
					'left': '50%',
					'transform': 'translate(-50%, -50%)'
				});
				break;
			case 'bottom-left':
				$wrapper.css({
					'bottom': offset,
					'left': offset
				});
				break;
			case 'bottom-right':
				$wrapper.css({
					'bottom': offset,
					'right': offset
				});
				break;
		}
		
		// Create the button itself
		var $button = $('<a class="pinnerpress-pin-it-button" data-pinnerpress-button="true"></a>');
		
		// Don't set static href - we'll generate it dynamically on click
		$button.attr({
			'href': '#',
			'target': '_blank',
			'rel': 'noopener noreferrer',
			'data-pin-do': 'buttonBookmark',
			'data-pin-custom': 'true'
		});
		
		// Apply button styles
		var buttonStyles = {
			'display': 'inline-flex',
			'align-items': 'center',
			'font-size': fontSize,
			'font-weight': '500',
			'padding': padding,
			'background-color': color,
			'color': textColor,
			'border-radius': borderRadius,
			'text-decoration': 'none',
			'cursor': 'pointer'
		};
		
		// Add shadow if enabled
		if (imageShadow) {
			buttonStyles['box-shadow'] = '0 2px 4px rgba(0,0,0,0.15)';
		}
		
		$button.css(buttonStyles);
		
		// Add Pinterest icon (SVG)
		var iconHtml = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="pinnerpress-pin-icon" style="width: 1em; height: 1em; vertical-align: -0.125em; margin-right: 0.3em; fill: currentColor; shape-rendering: geometricPrecision; text-rendering: optimizeLegibility; image-rendering: optimizeQuality;"><path d="M12 0C5.373 0 0 5.373 0 12c0 4.99 3.657 9.132 8.48 10.099-.118-.859-.224-2.178.045-3.116.244-.834 1.577-5.313 1.577-5.313s-.402-.803-.402-1.986c0-1.863 1.08-3.254 2.42-3.254 1.142 0 1.693.859 1.693 1.89 0 1.151-.733 2.87-1.11 4.467-.318 1.322.672 2.401 1.99 2.401 2.388 0 4.224-2.516 4.224-6.14 0-3.204-2.303-5.442-5.581-5.442-3.803 0-6.037 2.849-6.037 5.794 0 1.148.438 2.382 1.054 3.049.117.13.134.244.099.377-.109.427-.354 1.35-.398 1.539-.062.248-.2.302-.461.182-1.723-.796-2.797-3.294-2.797-5.301 0-4.33 3.141-8.306 9.067-8.306 4.754 0 8.442 3.384 8.442 7.917 0 4.715-2.969 8.502-7.085 8.502-1.381 0-2.681-.712-3.123-1.557l-.847 3.216c-.306 1.156-1.14 2.6-1.699 3.487C9.19 23.414 10.573 24 12 24c6.627 0 12-5.373 12-12S18.627 0 12 0z"></path></svg>';
		
		$button.html(iconHtml);
		
		// Add button text if showText is true
		if (showText) {
			$button.append(document.createTextNode(buttonText));
		}
		
		// Add click handler to dynamically get image URL and create Pinterest URL
		$button.on('click', function(e) {
			e.preventDefault();

			pinnerpressDebugLog('PIN BUTTON CLICKED');
			pinnerpressDebugLog('Pin It button clicked. Getting current image URL...');
			
			// Get the image element and its current src
			var $img = $container.find('img');
			var currentImgUrl = $img.attr('src') || imgUrl; // Use current src or fallback to original
			
			// Enhanced image URL detection for mobile and various lazy loading scenarios
			pinnerpressDebugLog('Initial currentImgUrl:', currentImgUrl);
			
			// Handle data URLs, empty URLs, or invalid URLs from lazy loading
			if (!currentImgUrl || currentImgUrl.startsWith('data:') || currentImgUrl === '' || currentImgUrl === '#') {
				pinnerpressDebugLog('Detected data/empty URL, searching for actual image URL...');
				
				// Extended list of lazy loading attributes (mobile plugins often use different ones)
				var lazyAttributes = [
					'data-src', 'data-lazy-src', 'data-original', 'data-full-src', 
					'data-srcset', 'data-lazy-srcset', 'data-orig', 'data-echo',
					'data-thumb', 'data-img-src', 'data-image', 'data-large',
					'data-medium', 'data-mobile-src', 'data-desktop-src'
				];
				
				// Try each lazy loading attribute
				for (var i = 0; i < lazyAttributes.length; i++) {
					var attrValue = $img.attr(lazyAttributes[i]);
					if (attrValue && !attrValue.startsWith('data:') && attrValue !== '' && attrValue !== '#') {
						currentImgUrl = attrValue;
						pinnerpressDebugLog('Found valid URL in', lazyAttributes[i], ':', currentImgUrl);
						break;
					}
				}
				
				// If still no valid URL, try to get from srcset
				if (!currentImgUrl || currentImgUrl.startsWith('data:') || currentImgUrl === '' || currentImgUrl === '#') {
					var srcset = $img.attr('srcset') || $img.attr('data-srcset');
					if (srcset) {
						// Extract first URL from srcset
						var srcsetUrls = srcset.split(',');
						if (srcsetUrls.length > 0) {
							var firstUrl = srcsetUrls[0].trim().split(' ')[0];
							if (firstUrl && !firstUrl.startsWith('data:')) {
								currentImgUrl = firstUrl;
								pinnerpressDebugLog('Found valid URL in srcset:', currentImgUrl);
							}
						}
					}
				}
				
				// If still no valid URL, try to force lazy loading
				if (!currentImgUrl || currentImgUrl.startsWith('data:') || currentImgUrl === '' || currentImgUrl === '#') {
					pinnerpressDebugLog('Still no valid URL, attempting to trigger lazy loading...');
					
					// Multiple approaches to trigger lazy loading
					// 1. Scroll into view
					if ($img[0].scrollIntoView) {
						$img[0].scrollIntoView({ behavior: 'smooth', block: 'center' });
					}
					
					// 2. Trigger common lazy loading events
					$img.trigger('scroll');
					$img.trigger('resize');
					$img.trigger('appear');
					$img.trigger('unveil');
					
					// 3. Add/remove classes that might trigger lazy loading
					$img.addClass('lazyload').addClass('in-view');
					
					// 4. Wait longer for mobile lazy loading to complete
					setTimeout(function() {
						var updatedImgUrl = $img.attr('src');
						pinnerpressDebugLog('After lazy loading attempt, src is:', updatedImgUrl);
						
						// Check again for valid URL
						if (updatedImgUrl && !updatedImgUrl.startsWith('data:') && updatedImgUrl !== '' && updatedImgUrl !== '#') {
							currentImgUrl = updatedImgUrl;
						} else {
							// Last resort: try lazy attributes again
							for (var j = 0; j < lazyAttributes.length; j++) {
								var attrValue = $img.attr(lazyAttributes[j]);
								if (attrValue && !attrValue.startsWith('data:') && attrValue !== '' && attrValue !== '#') {
									currentImgUrl = attrValue;
									pinnerpressDebugLog('Found URL in lazy attribute after trigger:', currentImgUrl);
									break;
								}
							}
						}
						
						// If we still don't have a valid URL, use the original fallback
						if (!currentImgUrl || currentImgUrl.startsWith('data:') || currentImgUrl === '' || currentImgUrl === '#') {
							currentImgUrl = imgUrl; // Use original URL passed to function
							pinnerpressDebugLog('Using original fallback URL:', currentImgUrl);
						}
						
						// Proceed with Pinterest URL generation
						generateAndOpenPinterestUrl(currentImgUrl);
					}, 1000); // Longer wait for mobile
					
					return; // Exit early to wait for lazy loading
				}
			}
			
			// Generate Pinterest URL and open it
			generateAndOpenPinterestUrl(currentImgUrl);
			
			function generateAndOpenPinterestUrl(finalImgUrl) {
				// Validate the final image URL before sending to Pinterest
				if (!finalImgUrl || finalImgUrl === '' || finalImgUrl === '#' || finalImgUrl.startsWith('data:')) {
					pinnerpressDebugLog('Warning: Invalid image URL for Pinterest:', finalImgUrl);
					// Show user-friendly error
					alert('Unable to find a valid image URL for Pinterest. Please try refreshing the page.');
					return;
				}
				
				// Ensure URL is absolute
				if (finalImgUrl.startsWith('//')) {
					finalImgUrl = 'https:' + finalImgUrl;
				} else if (finalImgUrl.startsWith('/') && !finalImgUrl.startsWith('//')) {
					finalImgUrl = window.location.origin + finalImgUrl;
				}
				
				pinnerpressDebugLog('Final validated image URL:', finalImgUrl);
				
				// Generate Pinterest sharing URL with current image URL (using official format)
				var pinUrl = 'https://www.pinterest.com/pin/create/button/' +
							 '?url=' + encodeURIComponent(pageUrl) +
							 '&media=' + encodeURIComponent(finalImgUrl) +
							 '&description=' + encodeURIComponent(description);
				
				// Add title parameter if available
				if (title) {
					pinUrl += '&title=' + encodeURIComponent(title);
				}
				
				// Check for repin ID
				var repinId = $img.attr('data-pin-id');
				if (repinId) {
					pinUrl += '&id=' + encodeURIComponent(repinId);
				}
				
				pinnerpressDebugLog('Opening Pinterest URL:', pinUrl);
				
				// Open Pinterest in new window
				window.open(pinUrl, '_blank', 'noopener,noreferrer');
			}
			
			var attachmentId = getAttachmentId($img);
			var imageId = generateImageId(currentImgUrl);
			
			pinnerpressDebugLog('Image tracking data:', {
				image_url: currentImgUrl,
				image_id: imageId,
				attachment_id: attachmentId,
				src_from_img: $img.attr('src')
			});
			
			// Track analytics event with enhanced image data
			pinnerpressTrackEvent('pin_button_click', {
				image_url: currentImgUrl,
				image_id: imageId,
				attachment_id: attachmentId,
				page_url: pageUrl,
				description: description,
				title: title,
				button_position: position,
				button_size: size,
				button_shape: shape,
				source: 'inline'
			});
			
			// Let the pin action happen first (open the Pinterest page)
			setTimeout(function() {
				pinnerpressDebugLog('Attempting to show follow box...');
				showFollowBoxIfEnabled();
			}, 100);
		});
		
		// Append button to wrapper, then wrapper to container
		$wrapper.append($button);
		$container.append($wrapper);
	}

	/**
	 * Initialize follow box functionality
	 */
	function initFollowBox() {
		// Create follow box modal if it doesn't exist
		if ($('#pinnerpress-follow-box-modal').length === 0) {
			createFollowBoxModal();
		}
		
		// Handle follow box modal close button click - DO NOT set cookie
		$(document).on('click', '.pinnerpress-follow-box-close', function() {
			hideFollowBoxModal();
			pinnerpressDebugLog('Follow box closed via X button, cookie NOT set.');
		});
		
		// Handle clicking outside the follow box to close it - DO NOT set cookie
		$(document).on('click', '#pinnerpress-follow-box-modal', function(e) {
			if ($(e.target).is('#pinnerpress-follow-box-modal')) {
				hideFollowBoxModal();
				pinnerpressDebugLog('Follow box closed via outside click, cookie NOT set.');
			}
		});
		
		// Handle follow button click - DO NOT set cookie here anymore
		$(document).on('click', '.pinnerpress-follow-box-button', function() {
			pinnerpressDebugLog('FOLLOW BOX CLICKED');
			pinnerpressDebugLog('Follow button clicked. Opening Pinterest link.');
			
			// Track analytics event
			pinnerpressTrackEvent('follow_button_click', {
				source: 'follow_box',
				pinterest_url: $(this).attr('href')
			});
			
			// Let the click continue (open Pinterest profile in new tab)
			return true;
		});

		// Handle "don't remind me" link click - SET cookie here
		$(document).on('click', '.pinnerpress-follow-box-dismiss-link', function(e) {
			e.preventDefault(); // Prevent link from navigating
			hideFollowBoxModal();
			setFollowBoxCookie(30); // Set cookie for 30 days
			pinnerpressDebugLog('Don\'t remind me clicked, cookie set for 30 days.');
		});
	}
	
	/**
	 * Create the follow box modal in the DOM
	 */
	function createFollowBoxModal() {
		// Use follow box HTML from localized data if available
		// Otherwise build default structure
		var followBoxHTML = '';
		
		if (typeof pinnerpress_data !== 'undefined' && pinnerpress_data.follow_box_html) {
			followBoxHTML = pinnerpress_data.follow_box_html;
		} else {
			// Get settings from localized data or use defaults
			var pinterestUrl = 'https://www.pinterest.com/pinnerpress';
			var displayName = 'PinnerPress';
			var description = 'Follow us on Pinterest for more inspiration!';
			var buttonBgColor = '#E60023';
			var buttonTextColor = '#FFFFFF';
			var allowDismiss = false;
			
			if (typeof pinnerpress_data !== 'undefined') {
				// pinterest_username already contains the full validated URL
				pinterestUrl = pinnerpress_data.pinterest_username || pinterestUrl;
				displayName = pinnerpress_data.display_name || displayName;
				description = pinnerpress_data.account_description || description;
				buttonBgColor = pinnerpress_data.follow_button_bg_color || buttonBgColor;
				buttonTextColor = pinnerpress_data.follow_button_text_color || buttonTextColor;
				allowDismiss = pinnerpress_data.follow_box_allow_dismiss === '1';
			}
			
			// Create the follow box HTML
			followBoxHTML = '<div class="pinnerpress-follow-box-wrapper">' +
							'<div class="pinnerpress-follow-box pinnerpress-shadow-lg">' +
							'<div class="pinnerpress-follow-box-header" style="background-image: url(' + (pinnerpress_data.header_image || '') + ');">' +
							'<button type="button" aria-label="close" class="pinnerpress-follow-box-close">' +
							'<svg width="12" height="18" viewBox="0 0 12 18" fill="none" xmlns="http://www.w3.org/2000/svg">' +
							'<g clip-path="url(#clip0)">' +
							'<path d="M3.72545 9L0.313977 5.48191C-0.10466 5.0502 -0.10466 4.35023 0.313977 3.91816L1.07216 3.13629C1.4908 2.70457 2.16954 2.70457 2.58852 3.13629L6 6.65437L9.41148 3.13629C9.83011 2.70457 10.5089 2.70457 10.9278 3.13629L11.686 3.91816C12.1047 4.34988 12.1047 5.04984 11.686 5.48191L8.27455 9L11.686 12.5181C12.1047 12.9498 12.1047 13.6498 11.686 14.0818L10.9278 14.8637C10.5092 15.2954 9.83011 15.2954 9.41148 14.8637L6 11.3456L2.58852 14.8637C2.16989 15.2954 1.4908 15.2954 1.07216 14.8637L0.313977 14.0818C-0.10466 13.6501 -0.10466 12.9502 0.313977 12.5181L3.72545 9Z"/>' +
							'</g>' +
							'<defs>' +
							'<clipPath id="clip0">' +
							'<rect width="12" height="18" fill="white" transform="matrix(-1 0 0 1 12 0)"></rect>' +
							'</clipPath>' +
							'</defs>' +
							'</svg>' +
							'</button>' +
							'<div class="pinnerpress-follow-box-logo" style="background-image: url(' + (pinnerpress_data.profile_image || '') + '); background-color: #FFFFFF;"></div>' +
							'</div>' +
							'<div class="pinnerpress-follow-box-inner">' +
							'<h3>' + displayName + '</h3>' +
							'<p>' + description + '</p>' +
							'<a class="pinnerpress-follow-box-button" href="' + pinterestUrl + '" style="background-color: ' + buttonBgColor + '; color: ' + buttonTextColor + ';" data-pin-do="buttonFollow" target="_blank">' +
							'<span class="pinnerpress-follow-button-text">Follow on</span>' +
							'<svg class="pinnerpress-pinterest-button-logo" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">' +
							'<path d="M23.25 12C23.25 5.57812 18.0469 0.375 11.625 0.375C5.20312 0.375 0 5.57812 0 12C0 16.9688 3.04688 21.1406 7.35938 22.8281C7.26562 21.9375 7.17188 20.5312 7.40625 19.5C7.64062 18.6094 8.76562 13.7344 8.76562 13.7344C8.76562 13.7344 8.4375 13.0312 8.4375 12C8.4375 10.4062 9.375 9.1875 10.5469 9.1875C11.5312 9.1875 12 9.9375 12 10.8281C12 11.8125 11.3438 13.3125 11.0156 14.7188C10.7812 15.8438 11.625 16.7812 12.75 16.7812C14.8125 16.7812 16.4062 14.625 16.4062 11.4844C16.4062 8.67188 14.3906 6.75 11.5781 6.75C8.25 6.75 6.32812 9.23438 6.32812 11.7656C6.32812 12.7969 6.70312 13.875 7.17188 14.4375C7.26562 14.5312 7.26562 14.6719 7.26562 14.7656C7.17188 15.1406 6.9375 15.9375 6.9375 16.0781C6.89062 16.3125 6.75 16.3594 6.51562 16.2656C5.0625 15.5625 4.17188 13.4531 4.17188 11.7188C4.17188 8.0625 6.84375 4.6875 11.8594 4.6875C15.8906 4.6875 19.0312 7.59375 19.0312 11.4375C19.0312 15.4219 16.5 18.6562 12.9844 18.6562C11.8125 18.6562 10.6875 18.0469 10.3125 17.2969C10.3125 17.2969 9.75 19.5469 9.60938 20.0625C9.32812 21.0938 8.625 22.3594 8.15625 23.1094C9.23438 23.4844 10.4062 23.625 11.625 23.625C18.0469 23.625 23.25 18.4219 23.25 12Z" fill="currentColor"></path>' +
							'</svg>' +
							'</a>';
							
			// Add "Don't remind me" link if dismissal is allowed
			if (allowDismiss) {
				followBoxHTML += '<div class="pinnerpress-follow-box-dismiss">' +
								 '<a href="#" class="pinnerpress-follow-box-dismiss-link">Don\'t remind me</a>' +
								 '</div>';
			}
			
			followBoxHTML += '</div>' +
							 '</div>' +
							 '</div>';
		}
		
		// Create follow box modal container
		var $modal = $(
			'<div id="pinnerpress-follow-box-modal" class="pinnerpress-follow-box-modal" style="display: none;">' +
			followBoxHTML +
			'</div>'
		);
		
		// Append modal to body
		$('body').append($modal);
	}
	
	/**
	 * Show the follow box modal if it's enabled and the cookie is not set
	 */
	function showFollowBoxIfEnabled() {
		// Check if follow box is enabled in the settings
		var followBoxEnabled = false;
		var showOnPinClick = false;
		
		if (typeof pinnerpress_data !== 'undefined') {
			followBoxEnabled = pinnerpress_data.follow_box_status === 'on';
			showOnPinClick = pinnerpress_data.follow_box_display_pin_click === '1';
		}
		
		// Check if follow box is disabled for this specific post
		if (typeof pinnerpress_data !== 'undefined' && pinnerpress_data.post_disable_follow_box === '1') {
			pinnerpressDebugLog('Follow box is disabled for this post.');
			return;
		}

		// Check if follow box is disabled for this post's categories
		if (typeof pinnerpress_data !== 'undefined' && pinnerpress_data.category_disable_follow_box === '1') {
			pinnerpressDebugLog('Follow box is disabled for this post category.');
			return;
		}
		
		var cookieSet = hasFollowBoxCookie();
		
		pinnerpressDebugLog('showFollowBoxIfEnabled check: Enabled=', followBoxEnabled, 'Show on pin click=', showOnPinClick, 'Cookie Set=', cookieSet);
		
		// Only show follow box if it's enabled, configured to show on pin click, and cookie is not set
		if (followBoxEnabled && showOnPinClick && !cookieSet) {
			pinnerpressDebugLog('Follow box enabled and cookie not set, calling showFollowBoxModal()');
			showFollowBoxModal();
		}
	}
	
	/**
	 * Show the follow box modal
	 */
	function showFollowBoxModal() {
		pinnerpressDebugLog('Fading in follow box modal...');
		$('#pinnerpress-follow-box-modal').fadeIn(300);
	}
	
	/**
	 * Hidden Pins Modal Functionality
	 */
	function initHiddenPinsModal() {
		// Handle button click
		$(document).on('click', '.pinnerpress-hidden-pins-button', function(e) {
			e.preventDefault();
			
			var postId = $(this).data('post-id');
			showHiddenPinsModal(postId);
		});
		
		// Handle modal close
		$(document).on('click', '.pinnerpress-modal-close, .pinnerpress-modal-overlay', function(e) {
			e.preventDefault();
			$('#pinnerpress-hidden-pins-modal').animate({
				'opacity': '0'
			}, 200, function() {
				$(this).css('display', 'none');
			});
		});
		
		// Handle ESC key
		$(document).on('keydown', function(e) {
			if (e.key === 'Escape' && $('#pinnerpress-hidden-pins-modal').is(':visible')) {
				$('#pinnerpress-hidden-pins-modal').animate({
					'opacity': '0'
				}, 200, function() {
					$(this).css('display', 'none');
				});
			}
		});
	}
	
	/**
	 * Scan the current page DOM for images using the same logic as addPinButtons
	 */
	function scanDOMForImages() {
		pinnerpressDebugLog('PinnerPress: Scanning DOM for images (fallback method)');

		var $images = $();

		// Check if custom selectors are enabled
		if (typeof pinnerpress_data !== 'undefined' && pinnerpress_data.pin_button_custom_selectors_enabled === '1') {
			var customSelectors = pinnerpress_data.pin_button_custom_selectors;

			if (customSelectors && customSelectors.trim() !== '') {
				// Split selectors by newline and clean them
				var selectors = customSelectors.split('\n').map(function(s) {
					return s.trim();
				}).filter(function(s) {
					return s !== '';
				});

				if (selectors.length > 0) {
					if (pinnerpress_data.pin_button_find_images_in_selectors === '1') {
						// Find all images inside the specified selectors
						$images = $();
						selectors.forEach(function(selector) {
							try {
								$images = $images.add($(selector).find('img'));
							} catch (e) {
								pinnerpressDebugLog('PinnerPress: Invalid selector:', selector, e);
							}
						});
					} else {
						// Use selectors directly (they should point to images)
						var combinedSelector = selectors.join(', ');
						try {
							$images = $(combinedSelector);
						} catch (e) {
							pinnerpressDebugLog('PinnerPress: Invalid custom selectors:', e);
							$images = $();
						}
					}

					pinnerpressDebugLog('PinnerPress: Using custom selectors, found', $images.length, 'images');
				}
			}
		} else {
			// Use default content area selectors
			var contentSelectors = [
				'.entry-content',
				'.post-content',
				'.content-area',
				'.site-content',
				'article .inside-article',
				'.wp-block-post-content',
				'main'
			];

			for (var i = 0; i < contentSelectors.length; i++) {
				var $contentArea = $(contentSelectors[i]);
				if ($contentArea.length > 0) {
					var $foundImages = $contentArea.find('img').filter(function() {
						var $img = $(this);
						var src = $img.attr('src') || '';

						// Resolve real URL for lazy-loaded images
						var realSrc = src;
						if (!realSrc || realSrc.startsWith('data:') || realSrc === '' || realSrc === '#') {
							var lazyAttrs = ['data-lazy-src', 'data-src', 'data-original', 'data-full-src', 'data-img-src'];
							for (var j = 0; j < lazyAttrs.length; j++) {
								var val = $img.attr(lazyAttrs[j]);
								if (val && !val.startsWith('data:') && val !== '' && val !== '#') {
									realSrc = val;
									break;
								}
							}
						}

						// Filter out non-content images
						if ($img.closest('#wpadminbar').length > 0) return false;
						if ($img.closest('.admin-bar-menu').length > 0) return false;
						if ($img.hasClass('avatar') || $img.hasClass('gravatar')) return false;
						if ($img.hasClass('emoji')) return false;
						if (realSrc.includes('gravatar.com') || realSrc.includes('emoji')) return false;
						if (realSrc.split('?')[0].split('#')[0].toLowerCase().endsWith('.svg')) return false;
						if (realSrc.startsWith('data:')) return false;

						// Include images that are likely content images
						var isWpImage = $img.attr('class') && $img.attr('class').includes('wp-image-');
						var isInUploads = realSrc.includes('/wp-content/uploads/');
						var isInFigure = $img.closest('figure').length > 0;
						var isInBlockImage = $img.closest('.wp-block-image, .gb-block-image').length > 0;
						var isFromCdn = realSrc.includes('imagedelivery.net') || realSrc.includes('imgix.net') || realSrc.includes('cdn.shopify.com');
						var hasLazySrc = $img.attr('data-lazy-src') && !$img.attr('data-lazy-src').startsWith('data:');

						return isWpImage || isInUploads || isInFigure || isInBlockImage || isFromCdn || hasLazySrc;
					});

					if ($foundImages.length > 0) {
						$images = $images.add($foundImages);
					}
				}
			}
		}

		// Remove duplicates — use resolved URL as the dedupe key so lazy-loaded
		// images with identical placeholder src values are not collapsed
		var uniqueImages = [];
		var imageUrls = [];
		$images.each(function() {
			var src = resolveImageSrc($(this));
			if (src && !src.startsWith('data:') && imageUrls.indexOf(src) === -1) {
				uniqueImages.push(this);
				imageUrls.push(src);
			}
		});

		pinnerpressDebugLog('PinnerPress: DOM scan found', uniqueImages.length, 'unique images');

		return $(uniqueImages);
	}

	/**
	 * Show the hidden pins modal
	 */
	function showHiddenPinsModal(postId) {
		var $modal = $('#pinnerpress-hidden-pins-modal');
		var $loading = $modal.find('.pinnerpress-modal-loading');
		var $grid = $modal.find('.pinnerpress-modal-images-grid');

		// Show modal with loading state (using CSS to maintain flexbox)
		$modal.css({
			'display': 'flex',
			'opacity': '0'
		}).animate({
			'opacity': '1'
		}, 200);
		$loading.show();
		$grid.hide().empty();

		// Load images via AJAX first
		$.ajax({
			url: pinnerpress_data.ajaxurl,
			type: 'POST',
			data: {
				action: 'pinnerpress_get_modal_images',
				post_id: postId,
				nonce: pinnerpress_data.analytics_nonce
			},
			success: function(response) {
				var imagesToShow = [];
				var postUrl = window.location.href;
				var postTitle = document.title;

				// Check if we got images from database
				if (response.success && response.data.images && response.data.images.length > 0) {
					pinnerpressDebugLog('PinnerPress: Found', response.data.images.length, 'images from database');
					imagesToShow = response.data.images;
					postUrl = response.data.post_url || postUrl;
					postTitle = response.data.post_title || postTitle;
				} else {
					// No images from database, scan the DOM
					pinnerpressDebugLog('PinnerPress: No images from database, scanning DOM...');
					var $domImages = scanDOMForImages();

					// Convert DOM images to the same format
					$domImages.each(function() {
						var $img = $(this);
						var imgUrl = resolveImageSrc($img);

						// Skip if no real URL found
						if (imgUrl && !imgUrl.startsWith('data:')) {
							imagesToShow.push({
								url: imgUrl,
								id: 'dom-' + imagesToShow.length,
								is_hidden: false
							});
						}
					});

					pinnerpressDebugLog('PinnerPress: DOM scan added', imagesToShow.length, 'images');
				}

				// Now display the images
				if (imagesToShow.length > 0) {
					// Hide loading, show grid
					$loading.hide();
					$grid.show();

					// Add images to grid
					imagesToShow.forEach(function(image) {
						var $imageItem = $('<div class="pinnerpress-modal-image-item"></div>');

						// Create image element first
						var $img = $('<img>').attr('src', image.url).attr('alt', postTitle);

						// Append image to the item first
						$imageItem.append($img);

						// Create container the same way as regular images
						var $container = $('<div class="pinnerpress-pin-it-container"></div>');
						$container.css({
							'position': 'relative',
							'display': 'inline-block',
							'width': '100%',
							'height': '100%',
							'font-size': '0'
						});

						// Wrap the image with the container (same as regular flow)
						$img.wrap($container);

						// Ensure image is loaded before creating button
						$img.on('load', function() {
							pinnerpressDebugLog('Modal image loaded:', image.url);

							// Temporarily override minimum size for modal (but keep all other settings)
							var originalMinSize = pinnerpress_data.minimum_image_size;
							pinnerpress_data.minimum_image_size = '0'; // Disable size check for modal

							// Create the pin button on the parent container (which is now the wrapper)
							// This will use all the user's settings including position, colors, shape, etc.
							createPinButton($img.parent(), image.url, postUrl, postTitle, postTitle);

							// Restore original minimum size
							pinnerpress_data.minimum_image_size = originalMinSize;

							// Check if button was created
							var $buttonWrapper = $img.parent().find('.pinnerpress-pin-it-button-wrapper');
							if ($buttonWrapper.length) {
								pinnerpressDebugLog('Modal pin button created for image:', image.url);
							} else {
								pinnerpressDebugLog('Warning: Pin button not found for modal image:', image.url);
							}
						});

						// If image is already loaded (cached), trigger the load event
						if ($img[0].complete) {
							$img.trigger('load');
						}

						$grid.append($imageItem);
					});
				} else {
					// No images found via either method
					$loading.hide();
					$grid.show().html('<p style="text-align: center; color: #666; padding: 40px;">No images found for this post.</p>');
				}
			},
			error: function() {
				// On AJAX error, still try DOM scanning as fallback
				pinnerpressDebugLog('PinnerPress: AJAX error, falling back to DOM scan');

				var $domImages = scanDOMForImages();
				var imagesToShow = [];

				$domImages.each(function() {
					var $img = $(this);
					var imgUrl = resolveImageSrc($img);

					if (imgUrl && !imgUrl.startsWith('data:')) {
						imagesToShow.push({
							url: imgUrl,
							id: 'dom-' + imagesToShow.length,
							is_hidden: false
						});
					}
				});

				if (imagesToShow.length > 0) {
					$loading.hide();
					$grid.show();

					var postUrl = window.location.href;
					var postTitle = document.title;

					imagesToShow.forEach(function(image) {
						var $imageItem = $('<div class="pinnerpress-modal-image-item"></div>');
						var $img = $('<img>').attr('src', image.url).attr('alt', postTitle);
						$imageItem.append($img);

						var $container = $('<div class="pinnerpress-pin-it-container"></div>');
						$container.css({
							'position': 'relative',
							'display': 'inline-block',
							'width': '100%',
							'height': '100%',
							'font-size': '0'
						});

						$img.wrap($container);

						$img.on('load', function() {
							var originalMinSize = pinnerpress_data.minimum_image_size;
							pinnerpress_data.minimum_image_size = '0';
							createPinButton($img.parent(), image.url, postUrl, postTitle, postTitle);
							pinnerpress_data.minimum_image_size = originalMinSize;
						});

						if ($img[0].complete) {
							$img.trigger('load');
						}

						$grid.append($imageItem);
					});
				} else {
					$loading.hide();
					$grid.show().html('<p style="text-align: center; color: #e60023; padding: 40px;">Error loading images. Please try again.</p>');
				}
			}
		});
	}
	
	/**
	 * Hide the follow box modal
	 */
	function hideFollowBoxModal() {
		$('#pinnerpress-follow-box-modal').fadeOut(200);
	}
	
	/**
	 * Check if the follow box cookie is set
	 * @return {boolean} True if cookie exists, false otherwise
	 */
	function hasFollowBoxCookie() {
		return getCookie('pinnerpress_followed') === 'true';
	}
	
	/**
	 * Set the follow box cookie for a specified number of days
	 * @param {number} days - Number of days until the cookie expires
	 */
	function setFollowBoxCookie(days) {
		var date = new Date();
		date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
		var expires = "expires=" + date.toUTCString();
		document.cookie = "pinnerpress_followed=true;" + expires + ";path=/";
	}
	
	/**
	 * Get a cookie value by name
	 * @param {string} name - Name of the cookie
	 * @return {string} Cookie value or empty string if not found
	 */
	function getCookie(name) {
		var nameEQ = name + "=";
		var ca = document.cookie.split(';');
		for (var i = 0; i < ca.length; i++) {
			var c = ca[i];
			while (c.charAt(0) == ' ') c = c.substring(1, c.length);
			if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
		}
		return "";
	}

	/**
	 * Create an Image Banner overlay for an image
	 * @param {jQuery} $container - The container element to append the banner to
	 * @param {string} imgUrl - The URL of the image
	 * @param {string} pageUrl - The URL of the current page
	 * @param {string} description - The description to use for the pin
	 * @param {string} title - The title to use for the pin (optional)
	 */
	function createImageBanner($container, imgUrl, pageUrl, description, title, retryCount, isGalleryImage) {
		// Default retry count to 0 if not provided
		retryCount = retryCount || 0;
		
		// Check if we should apply size filter to image banners
		var applyToBanners = (typeof pinnerpress_data !== 'undefined' && pinnerpress_data.size_filter_image_banners === '1');

		// Check if we should exclude gallery images from minimum size
		var excludeGalleryMinimum = (typeof pinnerpress_data !== 'undefined' && pinnerpress_data.exclude_gallery_minimum === '1');

		// Simple size check with retry mechanism
		var minimumSize = (typeof pinnerpress_data !== 'undefined' && pinnerpress_data.minimum_image_size)
			? parseInt(pinnerpress_data.minimum_image_size) : 250;

		// If size filter is not enabled for image banners, set minimum size to 0
		if (!applyToBanners) {
			pinnerpressDebugLog('Size filter not enabled for image banners, bypassing minimum size check');
			minimumSize = 0;
		}
		// If this is a gallery image and we're excluding them, set minimum size to 0
		else if (isGalleryImage && excludeGalleryMinimum) {
			pinnerpressDebugLog('Gallery image detected for banner, bypassing minimum size check');
			minimumSize = 0;
		}
		
		// Find the image element within the container
		var $img = $container.find('img').first();
		if ($img.length > 0) {
			var imgElement = $img[0];
			
			// Check if this is a lazy-loaded placeholder (same logic as createPinButton)
			var isLazyPlaceholder = false;
			var currentSrc = $img.attr('src') || '';
			if (currentSrc.startsWith('data:') || currentSrc === '' || currentSrc === '#') {
				var lazyUrl = $img.attr('data-lazy-src') || $img.attr('data-src') || '';
				if (lazyUrl && !lazyUrl.startsWith('data:')) {
					isLazyPlaceholder = true;
				}
			}
			
			// Function to get actual rendered size
			function getRenderedSize() {
				var rect = imgElement.getBoundingClientRect();
				var width = rect.width;
				var height = rect.height;
				
				// If getBoundingClientRect returns 0, try computed style
				if (width === 0 || height === 0) {
					var computedStyle = window.getComputedStyle(imgElement);
					width = parseFloat(computedStyle.width) || 0;
					height = parseFloat(computedStyle.height) || 0;
				}
				
				return { width: width, height: height };
			}
			
			if (!isLazyPlaceholder) {
				// Normal image — apply size check
				var size = getRenderedSize();
				
				// If image is too small, skip it
				if (size.width > 0 && size.height > 0 && (size.width < minimumSize || size.height < minimumSize)) {
					pinnerpressDebugLog('PinnerPress: Skipping image banner - too small (' + size.width + 'x' + size.height + ', minimum: ' + minimumSize + ')');
					return;
				}
				
				// If dimensions are still 0, the image might not be loaded yet
				if ((size.width === 0 || size.height === 0) && retryCount < 3) {
					setTimeout(function() {
						createImageBanner($container, imgUrl, pageUrl, description, title, retryCount + 1);
				}, 200);
				return;
				}
			} else {
				pinnerpressDebugLog('PinnerPress: Lazy-load placeholder detected for banner, bypassing size check for:', imgUrl);
			}
		}
		
		// Get banner settings from localized data or use defaults
		var bgColor = 'rgba(255, 255, 255, 0.5)';
		var textColor = '#BD081C';
		var bannerText = 'Pin this';
		var opacity = '50';
		
		// If we have localized data from WordPress, use those settings
		if (typeof pinnerpress_data !== 'undefined') {
			bgColor = pinnerpress_data.banner_bg_color || bgColor;
			textColor = pinnerpress_data.banner_text_color || textColor;
			bannerText = pinnerpress_data.banner_text || bannerText;
			opacity = pinnerpress_data.banner_opacity || opacity;
		}
		
		// Convert opacity to decimal for CSS
		var opacityDecimal = parseInt(opacity) / 100;
		
		// Apply opacity to background color
		if (bgColor.indexOf('rgba') === -1) {
			// Convert hex or rgb to rgba
			var rgbColor = bgColor;
			if (bgColor.indexOf('rgb') === -1) {
				// Convert hex to rgb
				rgbColor = hexToRgb(bgColor);
			}
			// Extract the rgb values
			var rgbMatch = rgbColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
			if (rgbMatch) {
				var r = rgbMatch[1];
				var g = rgbMatch[2];
				var b = rgbMatch[3];
				// Create rgba with new opacity
				bgColor = 'rgba(' + r + ', ' + g + ', ' + b + ', ' + opacityDecimal + ')';
			}
		} else {
			// It's already rgba, just update the opacity
			bgColor = bgColor.replace(/rgba\((\d+),\s*(\d+),\s*(\d+),\s*[\d\.]+\)/, 'rgba($1, $2, $3, ' + opacityDecimal + ')');
		}
		
		// Create banner wrapper as a link
		var $banner = $('<a class="pinnerpress-image-banner"></a>');
		
		// Generate Pinterest sharing URL (using official format)
		var pinUrl = 'https://www.pinterest.com/pin/create/button/' +
					 '?url=' + encodeURIComponent(pageUrl) +
					 '&media=' + encodeURIComponent(imgUrl) +
					 '&description=' + encodeURIComponent(description);
                     
        // Add title parameter if available
        if (title) {
            pinUrl += '&title=' + encodeURIComponent(title);
        }
        
        // Check for repin ID
        var repinId = $container.find('img').attr('data-pin-id');
        if (repinId) {
            pinUrl += '&id=' + encodeURIComponent(repinId);
        }
		
		$banner.attr({
			'href': pinUrl,
			'target': '_blank',
			'rel': 'noopener noreferrer',
			'data-pin-do': 'buttonBookmark',
			'data-pin-custom': 'true'
		});
		
		// Standard banner styles - always horizontal at the bottom
		$banner.css({
			'position': 'absolute',
			'bottom': '0',
			'left': '0',
			'right': '0',
			'width': '100%',
			'height': 'auto',
			'background-color': bgColor,
			'color': textColor,
			'padding': '8px 15px',
			'font-size': '22px',
			'font-weight': '500',
			'display': 'flex',
			'align-items': 'center',
			'justify-content': 'center',
			'text-align': 'center',
			'text-decoration': 'none',
			'cursor': 'pointer',
			'z-index': '9',
			'box-sizing': 'border-box'
		});
		
		// Create Pinterest icon (SVG)
		var iconHtml = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="pinnerpress-banner-icon" style="width: 1em; height: 1em; vertical-align: -0.125em; margin-right: 0.4em; fill: currentColor;"><path d="M12 0C5.373 0 0 5.373 0 12c0 4.99 3.657 9.132 8.48 10.099-.118-.859-.224-2.178.045-3.116.244-.834 1.577-5.313 1.577-5.313s-.402-.803-.402-1.986c0-1.863 1.08-3.254 2.42-3.254 1.142 0 1.693.859 1.693 1.89 0 1.151-.733 2.87-1.11 4.467-.318 1.322.672 2.401 1.99 2.401 2.388 0 4.224-2.516 4.224-6.14 0-3.204-2.303-5.442-5.581-5.442-3.803 0-6.037 2.849-6.037 5.794 0 1.148.438 2.382 1.054 3.049.117.13.134.244.099.377-.109.427-.354 1.35-.398 1.539-.062.248-.2.302-.461.182-1.723-.796-2.797-3.294-2.797-5.301 0-4.33 3.141-8.306 9.067-8.306 4.754 0 8.442 3.384 8.442 7.917 0 4.715-2.969 8.502-7.085 8.502-1.381 0-2.681-.712-3.123-1.557l-.847 3.216c-.306 1.156-1.14 2.6-1.699 3.487C9.19 23.414 10.573 24 12 24c6.627 0 12-5.373 12-12S18.627 0 12 0z"></path></svg>';
		
		// Add the text content
		var contentHtml = '<span>' + bannerText + '</span>';
		
		// Add content to banner
		$banner.html(iconHtml + contentHtml);
		
		// Add click handler to show follow box modal after pin (if enabled) - same as pin button
		$banner.on('click', function(e) {
			pinnerpressDebugLog('IMAGE BANNER CLICKED');

			// Get the image element
			var $img = $container.find('img');
			var attachmentId = getAttachmentId($img);
			var imageId = generateImageId(imgUrl);
			
			// Track analytics event with enhanced image data
			pinnerpressTrackEvent('image_banner_click', {
				image_url: imgUrl,
				image_id: imageId,
				attachment_id: attachmentId,
				page_url: pageUrl,
				description: description,
				title: title,
				banner_text: bannerText,
				source: 'image_banner'
			});
			
			// Let the pin action happen first (open the Pinterest page)
			setTimeout(function() {
				showFollowBoxIfEnabled();
			}, 100);
		});
		
		// Append banner to container
		$container.append($banner);
	}

	/**
	 * Check if the follow box should be shown on page load
	 */
	function checkShowFollowBoxOnPageLoad() {
		// Skip if no data or follow box is disabled
		if (typeof pinnerpress_data === 'undefined' || pinnerpress_data.follow_box_status !== 'on') {
			return;
		}
		
		// Check if follow box is disabled for this specific post
		if (pinnerpress_data.post_disable_follow_box === '1') {
			pinnerpressDebugLog('Follow box is disabled for this post (page load check).');
			return;
		}

		// Check if follow box is disabled for this post's categories
		if (pinnerpress_data.category_disable_follow_box === '1') {
			pinnerpressDebugLog('Follow box is disabled for this post category (page load check).');
			return;
		}
		
		// Check if the show on page load option is enabled
		var showOnPageLoad = pinnerpress_data.follow_box_display_page_load === '1';
		
		// Check if the cookie is set (don't show if cookie exists)
		var cookieSet = hasFollowBoxCookie();
		
		pinnerpressDebugLog('Page load check: Show on load=', showOnPageLoad, 'Cookie Set=', cookieSet);
		
		// Show the follow box if it should be shown on page load and the cookie is not set
		if (showOnPageLoad && !cookieSet) {
			// Delay showing the follow box slightly to prevent immediate popup
			setTimeout(function() {
				showFollowBoxModal();
			}, 1500);
		}
	}

	// Helper function to convert hex color to rgb
	function hexToRgb(hex) {
		// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
		var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
		hex = hex.replace(shorthandRegex, function(m, r, g, b) {
			return r + r + g + g + b + b;
		});
		
		var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
		return result ? 
			'rgb(' + parseInt(result[1], 16) + ', ' + parseInt(result[2], 16) + ', ' + parseInt(result[3], 16) + ')' :
			'rgb(0, 0, 0)';
	}

})( jQuery ); 