1<!DOCTYPE html> 2<html lang="en"> 3 4<head>
vendor: 75 bytes, lines 4-7
4 5 6 7 <script async src="https://www.googletagmanager.com/gtag/js?id=
7UA-46909897-1
vendor: 12 bytes, line 7
7"></script>
8<script>
vendor: 129 bytes, lines 9-12
9window.dataLayer = window.dataLayer || []; 10function gtag() { dataLayer.push(arguments);} 11gtag("js", new Date()); 12gtag("config", "
12UA-46909897-1
vendor: 4 bytes, line 12
12");
13</script>
13 14 15 16 17 <meta charset="utf-8" /> 18 <title>The North Face W Altamesa 300 V2 Calacatta/Citrus Rust</title> 19 <meta name="viewport" content="width=device-width, initial-scale=1" /> 20 <meta name="keywords" content="" /> 21 <meta name="description" content="Sweet-spot cushioning for moderate trails and road sections Stickier rubber outsole for wet-surface grip Significantly lighter than before" /> 22 <!-- Icons --> 23 <meta name="msapplication-TileColor" content="#1bb8de" /> 24 <meta name="msapplication-TileImage" content="/assets/branding/shop.skinnyraven.com/ms-icon-144x144.png" /> 25 <meta name="theme-color" content="#490e74" /> 26 <meta property="og:title" content="The North Face W Altamesa 300 V2 Calacatta/Citrus Rust" /> 27 <meta property="og:image" content="https://shop.skinnyraven.com/image/500/100_273570_1777412983067.jpg" /> 28 <meta property="og:description" content="Sweet-spot cushioning for moderate trails and road sections Stickier rubber outsole for wet-surface grip Significantly lighter than before" /> 29 <link rel="canonical" href="https://shop.skinnyraven.com/product/5970565/the-north-face/w-altamesa-300-v2" /> 30 <link rel="shortcut icon" id="appFavicon" href="/assets/branding/shop.skinnyraven.com/favicon.ico" /> 31 <link rel="apple-touch-icon" id="appFaviconApple57" sizes="57x57" href="/assets/branding/shop.skinnyraven.com/apple-icon-57x57.png" /> 32 <link rel="apple-touch-icon" id="appFaviconApple60" sizes="60x60" href="/assets/branding/shop.skinnyraven.com/apple-icon-60x60.png" /> 33 <link rel="apple-touch-icon" id="appFaviconApple72" sizes="72x72" href="/assets/branding/shop.skinnyraven.com/apple-icon-72x72.png" /> 34 <link rel="apple-touch-icon" id="appFaviconApple76" sizes="76x76" href="/assets/branding/shop.skinnyraven.com/apple-icon-76x76.png" /> 35 <link rel="apple-touch-icon" id="appFaviconApple114" sizes="114x114" href="/assets/branding/shop.skinnyraven.com/apple-icon-114x114.png" /> 36 <link rel="apple-touch-icon" id="appFaviconApple120" sizes="120x120" href="/assets/branding/shop.skinnyraven.com/apple-icon-120x120.png" /> 37 <link rel="apple-touch-icon" id="appFaviconApple144" sizes="144x144" href="/assets/branding/shop.skinnyraven.com/apple-icon-144x144.png" /> 38 <link rel="apple-touch-icon" id="appFaviconApple152" sizes="152x152" href="/assets/branding/shop.skinnyraven.com/apple-icon-152x152.png" /> 39 <link rel="apple-touch-icon" id="appFaviconApple180" sizes="180x180" href="/assets/branding/shop.skinnyraven.com/apple-icon-180x180.png" /> 40 <link rel="icon" type="image/png" id="appFavicon192" sizes="192x192" href="/assets/branding/shop.skinnyraven.com/android-icon-192x192.png" /> 41 <link rel="icon" type="image/png" id="appFavicon32" sizes="32x32" href="/assets/branding/shop.skinnyraven.com/favicon-32x32.png" /> 42 <link rel="icon" type="image/png" id="appFavicon96" sizes="96x96" href="/assets/branding/shop.skinnyraven.com/favicon-96x96.png" /> 43 <link rel="icon" type="image/png" id="appFavicon16" sizes="16x16" href="/assets/branding/shop.skinnyraven.com/favicon-16x16.png" /> 44 <!-- Font Preloading - Optimized for Performance --> 45 <link rel="preconnect" href="https://fonts.googleapis.com" crossorigin> 46 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 47 <link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;600;700;800&display=swap"> 48 <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;600;700;800&display=swap" media="print" onload="this.media='all'"> 49 <noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;600;700;800&display=swap"></noscript> 50 <!-- Styles --> 51 <link href="/assets/styles/font-variables.css?v=1.2.0" rel="stylesheet" type="text/css" media="all" /> 52 <style>:root { --font-primary: "Nunito", "Open Sans", "Helvetica Neue", sans-serif; }</style> 53 <link href="/assets/admin/styles/spectrum.css?v=1.2.0" rel="stylesheet" type="text/css" media="all" /> 54 <link href="/assets/styles/bootstrap.css?v=1.2.0" rel="stylesheet" type="text/css" media="all"/> 55 <link href="/assets/styles/themify-icons.css?v=1.2.0" rel="stylesheet" type="text/css" media="all" /> 56 <link href="/assets/styles/flexslider.css?v=1.2.0" rel="stylesheet" type="text/css" media="all" /> 57 <link href="/assets/styles/theme.css?v=1.2.0" rel="stylesheet" type="text/css" media="all" /> 58 <link href="/assets/styles/custom.css?v=1.2.0" rel="stylesheet" type="text/css" media="all" /> 59 <link href="/assets/styles/runfree.css?v=1.2.0" rel="stylesheet" type="text/css" media="all" /> 60 <link href="/assets/styles/modal.css?v=1.2.0" rel="stylesheet" type="text/css" /> 61 <link href="/assets/styles/datetimepicker.css?v=1.2.0" rel="stylesheet" type="text/css" media="all" /> 62 <link href="/assets/styles/font-awesome.min.css?v=1.2.0" rel="stylesheet" type="text/css" media="all" /> 63 <link rel="stylesheet" href="/assets/styles/tooltips.css?v=1.2.0" rel="stylesheet" type="text/css" media="all" /> 64 <link href="/assets/styles/runfreefont.css?v=1.2.0" rel="stylesheet" type="text/css" media="all" /> 65 <link href="/assets/styles/search-overlay.css?v=1.2.0" rel="stylesheet" type="text/css" media="all" /> 66 <link href="/assets/branding/shop.skinnyraven.com/branding.css?v=1.2.0" rel="stylesheet" type="text/css" media="all" /> 67
67<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
67 68
68<script> 69 // Universal tracking helper - supports both GTM and direct gtag 70 window.dataLayer = window.dataLayer || []; 71 function trackEvent(eventName, eventData) { 72 // Clear previous ecommerce object (GTM best practice) 73 dataLayer.push({ ecommerce: null }); 74 75 // Map UA field names to GA4 schema (keep both for store GTM compatibility) 76 if (eventData && eventData.items) { 77 eventData.items = eventData.items.map(function(item) { 78 var mapped = { 79 item_id: item.item_id || item.id, 80 item_name: item.item_name || item.name, 81 item_brand: item.item_brand || item.brand, 82 item_category: item.item_category || item.category, 83 item_variant: item.item_variant || item.variant, 84 item_list_name: item.item_list_name || item.list_name, 85 index: item.index != null ? item.index : item.list_position, 86 quantity: item.quantity, 87 price: item.price, 88 id: item.id, 89 name: item.name, 90 brand: item.brand, 91 category: item.category, 92 variant: item.variant, 93 list_name: item.list_name, 94 list_position: item.list_position 95 }; 96 if (item.affiliation) mapped.affiliation = item.affiliation; 97 return mapped; 98 }); 99 } 100 101 // Map legacy UA event names to GA4 equivalents 102 var ga4EventName = eventName; 103 if (eventName === 'checkout_progress') { 104 ga4EventName = 'add_shipping_info'; 105 } 106 107 // GTM format: push object with event property (sends both legacy and GA4 names) 108 var gtmData = { event: eventName }; 109 if (eventData) { 110 if (eventData.items) gtmData.ecommerce = eventData; 111 for (var key in eventData) { 112 if (eventData.hasOwnProperty(key)) gtmData[key] = eventData[key]; 113 } 114 } 115 dataLayer.push(gtmData); 116 117 // Also push GA4 event name if different (for GTM GA4 triggers) 118 if (ga4EventName !== eventName) { 119 dataLayer.push({ ecommerce: null }); 120 var ga4GtmData = { event: ga4EventName }; 121 if (eventData) { 122 if (eventData.items) ga4GtmData.ecommerce = eventData; 123 for (var key in eventData) { 124 if (eventData.hasOwnProperty(key)) ga4GtmData[key] = eventData[key]; 125 } 126 } 127 dataLayer.push(ga4GtmData); 128 } 129 130 // Direct gtag format (for stores using GA4 directly) - always use GA4 event name 131 if (typeof gtag === 'function') { 132 gtag('event', ga4EventName, eventData); 133 } 134 } 135 </script>
135 136
136<script>
vendor: 397 bytes, lines 136-142
136 137!function(f,b,e,v,n,t,s) { 138if(f.fbq)return;n=f.fbq=function(){n.callMethod?n.callMethod.apply(n,arguments):n.queue.push(arguments)}; 139if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0; 140t.src=v;s=b.getElementsByTagName(e)[0]; 141s.parentNode.insertBefore(t,s)}(window, document,'script','https://connect.facebook.net/en_US/fbevents.js'); 142fbq('init', '
142583023725831757
vendor: 29 bytes, line 142
142');fbq('track', 'PageView');
143</script>
143<noscript><img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=583023725831757&ev=PageView&noscript=1" /></noscript> 144 <style> 145 :root { 146 --primary: #490e74; 147 --primaryOpaque: rgba(73,14,116,0.1); 148 --secondary: #434c5e; 149 --white: #FFF; 150 --almostblack: #252525; 151 --grey: #eff1f5; 152 --red: #ff104b; 153 --shadow: 0px 0px 8px 2px rgba(0, 0, 0, 0.08); 154 --bigShadow: 0px 12px 23px 0px rgba(0, 0, 0, .1); 155 --transition: 0.5s; 156 --even: #FCFCFC; 157 --siteLogo: url(/assets/branding/shop.skinnyraven.com/logo.png); 158 --input: #F5F6FA; 159 --border: #f5f6fa; 160 --inputfocus: #e7ebf1; 161 --glass: rgba(250, 250, 250, 0.7); 162 --navutility: #f5f8fb; 163 --menu: #434c5e; 164 --filterhr: #d2d8e5; 165 --bggrey: #f5f6fa; 166 --thumbloader: linear-gradient(90deg, #eef1f5 0px, #fbfbfd 40px, #eef1f5 80px); 167 --skeleton-one: #eff1f5; 168 --skeleton-two: #F5F6FA; 169 --disappearing-header: linear-gradient(to bottom, rgba(245, 246, 250, 1) 0%, rgba(245, 246, 250, 0) 100%); 170 --disappearing-footer: linear-gradient(to bottom, rgba(245, 246, 250, 0) 0%, rgba(245, 246, 250, 1) 100%); 171 } 172 </style> 173 174
174<script> 175 var logoCard = '/assets/branding/shop.skinnyraven.com/logo.png'; 176 var logoUrl = '/'; 177 </script>
177 178 179
179<script>var cdnOn = false;</script>
vendor: 1 bytes, line 179
179
180<script type="text/javascript">var _learnq;</script>
vendor: 1 bytes, line 180
180
181<script type="text/javascript"> 182window._blueshiftid="7c086316647a004f6f5b410e1b48054c";window.blueshift=window.blueshift||[];if(blueshift.constructor===Array){blueshift.load=function(){var d=function(a){return function(){blueshift.push([a].concat(Array.prototype.slice.call(arguments,0)))}},e=["identify","track","click","pageload","capture","retarget"];for(var f=0;f<e.length;f++)blueshift[e[f]]=d(e[f])};} 183blueshift.load(); 184blueshift.pageload(); 185if(blueshift.constructor===Array){(function(){var b=document.createElement("script");b.type="text/javascript",b.async=!0,b.src=("https:"===document.location.protocol?"https:":"http:")+"//cdn.getblueshift.com/blueshift.js";var c=document.getElementsByTagName("script")[0];c.parentNode.insertBefore(b,c);})()} 186</script>
186 187
187<script type="application/ld+json">[{"@context":"https://schema.org","@type":"Organization","@id":"https://www.skinnyraven.com/#organization","name":"Skinny Raven Sports","url":"https://www.skinnyraven.com/","logo":"https://www.skinnyraven.com/logo.png","sameAs":["https://shop.skinnyraven.com"]},{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Skinny Raven Sports","item":"https://www.skinnyraven.com/"},{"@type":"ListItem","position":2,"name":"Shop","item":"https://shop.skinnyraven.com/"},{"@type":"ListItem","position":3,"name":"The North Face","item":"https://shop.skinnyraven.com/brand//the-north-face"},{"@type":"ListItem","position":4,"name":"W Altamesa 300 V2"}]},{"@context":"https://schema.org/","@type":"Product","name":"W Altamesa 300 V2","image":["https://shop.skinnyraven.com/image/600/100_273570_1777412983067.jpg"],"description":"Sweet-spot cushioning for moderate trails and road sections Stickier rubber outsole for wet-surface grip Significantly lighter than before","sku":"NF0A8G6CKA31100000","brand":{"@type":"Brand","name":"The North Face"},"offers":{"@type":"Offer","url":"https://shop.skinnyraven.com/product/5970565/the-north-face/w-altamesa-300-v2","priceCurrency":"USD","price":"150.00","itemCondition":"https://schema.org/NewCondition","availability":"https://schema.org/InStock","seller":{"@id":"https://www.skinnyraven.com/#organization"}}}]</script>
187 188 <!-- End Header Script --> 189</head> 190 191<body class="scroll-assist"> 192 193 194 <!-- Cart Template //--> 195 <li id="CartTemplate" class="cartItem template"> 196 <div class="productImage" style="background-image: url('{{product.url}}')"></div> 197 <div class="rel"> 198 <div class="productName">{{product.name}}</div> 199 <div class="productPrice"> 200 {{product.quantity}} at ${{product.cost}} - {{product.options}} 201 </div> 202 <div class="remove" data-index="{{index}}"></div> 203 </div> 204 </li> 205 206 <div class="nav-container"> 207 <nav> 208 <div class="nav-bar"> 209 <div class="module left"> 210 <img id="StoreLogo" class="logo logo-dark" alt="Skinny Raven Sports" src="/assets/branding/shop.skinnyraven.com/logo.png" /> 211 </div> 212 213 <!-- Mobile toggle (hamburger) --> 214 <div class="module right widget-handle mobile-toggle visible-sm visible-xs"> 215 <i class="icon-Main-Menu mobilemenu"></i> 216 </div> 217 218 <!-- Cart icon - visible on mobile only --> 219 <div id="MobileCartMenu" class="module right widget-handle visible-sm visible-xs ecomtrue" style="width: 65px; padding: 0; border-left: 2px solid var(--border); text-align: center;"> 220 <a href="/cart" style="text-decoration: none; position: relative; display: block; height: 69px; filter: brightness(100%);"> 221 <i class="icon-ti-Cart" style="line-height: 69px !important; font-size: 24px; display: inline-block; vertical-align: middle;"></i> 222 <span id="MobileCartItemCount" class="label number"></span> 223 </a> 224 </div> 225 226 <div class="module-group right pt0 pb0"> 227 228 <!-- Account Pod --> 229 <div id="AccountMenu" class="module right widget-handle hidden-sm hidden-xs"> 230 <ul class="menu"> 231 <li class="has-dropdown-account" style="border-top: unset;"><i class="icon-Profile"></i> 232 <span class="title">My Account</span> 233 <ul style="margin-top: -7px; margin-right: -20px;"><li><a href="/login"><i class="icon-Log-In dropdown-icon"></i> Login</a></li><li><a href="/signup"><i class="icon-Signup dropdown-icon"></i> Signup</i></a></li></ul> 234 </li> 235 </ul> 236 </div> 237 238 <!-- Cart Pod --> 239 <div id="CartMenuSize" class="module widget-handle cart-widget-handle right ecomtrue hidden-sm hidden-xs"> 240 <div class="cart max" data-url="/cart"> 241 <i class="icon-ti-Cart"></i> 242 <span id="CartItemCount" class="label number"></span> 243 <span class="title">Shopping Cart</span> 244 </div> 245 <div id="CartMenu" class="function"> 246 <div class="widget" style="padding: 16px;"> 247 <h6 class="title">Shopping Cart</h6> 248 <hr /> 249 <ul id="CartInfo" class="cart-overview"></ul> 250 <div class="cart-controls mt16"> 251 <a class="btn btn-sm btn-filled" href="/cart">View Cart</a> 252 <div class="list-inline pull-right"> 253 <span class="cart-total">Total: </span> 254 <span id="CartTotal" class="number"></span> 255 </div> 256 </div> 257 </div> 258 </div> 259 </div> 260 261 <!-- Search Pod - Overlay Trigger --> 262 <div id="SearchOverlayTrigger" class="module widget-handle search-widget-handle right ecomtrue hidden-sm hidden-xs" style="cursor: pointer; -webkit-tap-highlight-color: transparent; touch-action: manipulation;"> 263 <div class="search max"> 264 <i class="icon-aisearch" style="pointer-events: none;"></i> 265 <span class="title" style="pointer-events: none;">Search Site</span> 266 </div> 267 </div> 268 269 <!-- Menu Pod --> 270 <div id="TheMenu" class="module left pt0 pb16"> 271 <ul id="MainMenu" class="menu"><li class="has-dropdown"><a href="#">Shop by Category</a><ul class="mega-menu"><li><ul id="HeaderCategories"></ul></li></ul></li><li id="GiftCardCart"><a href="/giftcard">Gift Cards</a></li><li style="display:none"></li></ul> 272 </div> 273 274 </div> 275 <!-- End Modal Group --> 276 277 </div> 278 </nav> 279 </div> 280 281 <!-- Search Overlay Component -->
282 <!-- RunFree Search Overlay - Modular Component --> 283<div id="SearchOverlay" class="search-overlay" role="dialog" aria-modal="true" aria-label="Search Products" aria-hidden="true"> 284 <div class="search-overlay-header"> 285 <div class="search-logo"> 286 <img id="SearchStoreLogo" alt="" src="" /> 287 </div> 288 <div class="search-input-container"> 289 <i class="icon-aisearch search-icon" aria-hidden="true"></i> 290 <input 291 type="search" 292 id="SearchOverlayInput" 293 class="search-overlay-input" 294 placeholder="Search for Products, Brands..." 295 autocomplete="off" 296 spellcheck="false" 297 aria-label="Search for products, brands, or categories" 298 aria-expanded="false" 299 aria-controls="SearchProductPreviews SearchSuggestions" 300 aria-describedby="SearchOverlayDescription" 301 /> 302 <span id="SearchOverlayDescription" class="sr-only">Type to search. Use arrow keys to navigate results. Press enter to view all results.</span> 303 <button 304 class="icon-Broswer-Close clear-search x" 305 id="ClearSearchInput" 306 style="display: none;" 307 aria-label="Clear search" 308 type="button" 309 ></button> 310 </div> 311 <button class="search-cancel mb0" id="SearchOverlayCancel">Cancel</button> 312 </div> 313 314 <div class="search-overlay-content"> 315 <!-- Left: Suggestions --> 316 <div class="search-suggestions"> 317 <!-- Popular Searches --> 318 <div class="suggestions-section" id="PopularSearches" role="region" aria-label="Popular searches"> 319 <h4 class="suggestions-title">Popular Searches</h4> 320 <ul id="PopularSearchesList" class="suggestions-list" role="list" aria-live="polite"> 321 <!-- Loading skeleton --> 322 <li class="suggestion-skeleton" aria-hidden="true"><span></span></li> 323 <li class="suggestion-skeleton" aria-hidden="true"><span></span></li> 324 <li class="suggestion-skeleton" aria-hidden="true"><span></span></li> 325 </ul> 326 </div> 327 328 <!-- Top Searched Brands --> 329 <div class="suggestions-section" id="TopBrands" role="region" aria-label="Top brands"> 330 <h4 class="suggestions-title">Top Brands</h4> 331 <ul id="TopBrandsList" class="suggestions-list" role="list" aria-live="polite"> 332 <!-- Loading skeleton --> 333 <li class="suggestion-skeleton"><span></span></li> 334 <li class="suggestion-skeleton"><span></span></li> 335 <li class="suggestion-skeleton"><span></span></li> 336 </ul> 337 </div> 338 339 <!-- Top Searched Categories --> 340 <div class="suggestions-section" id="TopCategories" role="region" aria-label="Top categories"> 341 <h4 class="suggestions-title">Top Categories</h4> 342 <ul id="TopCategoriesList" class="suggestions-list" role="list" aria-live="polite"> 343 <!-- Loading skeleton --> 344 <li class="suggestion-skeleton"><span></span></li> 345 <li class="suggestion-skeleton"><span></span></li> 346 <li class="suggestion-skeleton"><span></span></li> 347 </ul> 348 </div> 349 350 <!-- Dynamic Search Suggestions (shown when typing) --> 351 <div class="suggestions-section" id="SearchSuggestions" style="display: none;"> 352 <h4 class="suggestions-title">Top Suggestions</h4> 353 <ul id="SuggestionsList" class="suggestions-list"> 354 <!-- Dynamic suggestions populated here --> 355 </ul> 356 </div> 357 </div> 358 359 <!-- Right: Product Previews --> 360 <div class="search-products"> 361 <div class="search-loading-bar" id="SearchLoadingBar"> 362 <div class="search-loading-bar-progress"></div> 363 </div> 364 <div class="search-products-fade"></div> 365 <div id="SearchProductPreviews" class="product-previews-grid"> 366 <!-- Dynamic product tiles populated here --> 367 </div> 368 <div id="SearchSearching" class="search-searching" style="display: none;"> 369 <h3>Searching...</h3> 370 </div> 371 <div id="SearchEmptyState" class="search-empty-state" style="display: none;"> 372 <div class="icon-aisearch empty-icon"></div> 373 <p id="SearchEmptyStateText">Start Typing to Search</p> 374 <div class="recent-searches-inline mt8" id="RecentSearches" style="display: none;" role="region" aria-label="Recent searches"> 375 <div class="recent-searches-container">
376 <span class="recent-searches-label">Your Recent Searches:</span> 377 <span id="RecentSearchesList" class="recent-searches-links" role="list"> 378 <!-- Dynamic recent searches --> 379 </span> 380 </div> 381 </div> 382 </div> 383 <div id="SearchNoResults" class="search-no-results" style="display: none;"> 384 <div class="sad-search"></div> 385 <p>Hmmm... We didn't find any matches</p> 386 <span>Modify your search and try again</span> 387 </div> 388 </div> 389 </div> 390 391 <!-- Search All Button --> 392 <div class="search-overlay-footer"> 393 <button id="SearchAllButton" class="search-all-button"> 394 <div>Search All Products</div> 395 </button> 396 </div> 397</div> 398 399<!-- Product Preview Template --> 400<div id="SearchProductTemplate" class="search-product-tile product clickable template" data-url="{{url}}" style="display: none;"> 401 <div class="search-product-image image" style="background-image: url('{{product.url}}')"> 402 <span class="search-sale-badge{{onsale}}">SALE</span> 403 </div> 404 <div class="colorswatches" data-product-name="{{product.name}}" data-site-id="{{siteId}}" data-total-colors="{{totalColors}}"></div> 405 <div class="search-product-info"> 406 <div class="search-product-name">{{product.name}}</div> 407 <div class="search-product-brand">{{product.brandName}}</div> 408 <div class="search-product-price">{{product.price}}</div> 409 </div> 410</div> 411 412<!-- Color Swatches Component -->
413<script src="/assets/scripts/shared/colorSwatches.js"></script>
413 414 415 416 <div class="main-container"></div> 417 418 <!-- Search Overlay Script --> 419
419<script src="/assets/scripts/search-overlay.js?v=1.2.0"></script>
419 420
420<script> 421 // Initialize search overlay triggers - use immediate execution to avoid race conditions 422 (function() { 423 function attachSearchTriggers() { 424 var trigger = document.getElementById('SearchOverlayTrigger'); 425 426 if (trigger && typeof SearchOverlay !== 'undefined') { 427 // Remove any existing listener first 428 trigger.replaceWith(trigger.cloneNode(true)); 429 trigger = document.getElementById('SearchOverlayTrigger'); 430 431 trigger.addEventListener('click', function(e) { 432 e.preventDefault(); 433 e.stopPropagation(); 434 SearchOverlay.open(); 435 }); 436 } 437 } 438 439 // Attach immediately if DOM is ready, otherwise wait 440 if (document.readyState === 'loading') { 441 document.addEventListener('DOMContentLoaded', attachSearchTriggers); 442 } else { 443 attachSearchTriggers(); 444 } 445 })(); 446 447 // Sync mobile cart count with desktop cart count - run after DOM is ready 448 (function() { 449 function syncMobileCart() { 450 var desktopCount = document.getElementById('CartItemCount'); 451 var mobileCount = document.getElementById('MobileCartItemCount'); 452 if (desktopCount && mobileCount) { 453 mobileCount.textContent = desktopCount.textContent; 454 mobileCount.className = desktopCount.className; 455 } 456 } 457 458 function initCartSync() { 459 syncMobileCart(); 460 461 var observer = new MutationObserver(syncMobileCart); 462 var desktopCount = document.getElementById('CartItemCount'); 463 if (desktopCount) { 464 observer.observe(desktopCount, { childList: true, characterData: true, subtree: true }); 465 } 466 } 467 468 if (document.readyState === 'loading') { 469 document.addEventListener('DOMContentLoaded', initCartSync); 470 } else { 471 initCartSync(); 472 } 473 })(); 474 </script>
474<style> 475 label { 476 width: 100%; 477 } 478 479 #ImageThumbs li { 480 cursor: pointer; 481 } 482 483 #ImageLightbox { 484 display: flex; 485 position: fixed; 486 inset: 0; 487 z-index: 9999; 488 background: rgba(0,0,0,0); 489 align-items: center; 490 justify-content: center; 491 opacity: 0; 492 pointer-events: none; 493 transition: background 0.25s ease, opacity 0.25s ease; 494 } 495 #ImageLightbox.open { 496 background: rgba(0,0,0,0.88); 497 opacity: 1; 498 pointer-events: all; 499 } 500 #ImageLightbox .lb-img-wrap { 501 position: relative; 502 transform: scale(0.82); 503 transition: transform 0.3s cubic-bezier(0.34,1.56,0.64,1); 504 max-width: 92vw; 505 max-height: 92vh; 506 } 507 #ImageLightbox.open .lb-img-wrap { 508 transform: scale(1); 509 } 510 #ImageLightbox .lb-img-wrap img { 511 max-width: 92vw; 512 max-height: 92vh; 513 display: block; 514 border-radius: 4px; 515 box-shadow: 0 8px 40px rgba(0,0,0,0.6); 516 background: #fff; 517 } 518 #ImageLightbox .lb-close { 519 position: absolute; 520 top: -16px; 521 right: -16px; 522 width: 36px; 523 height: 36px; 524 border-radius: 50%; 525 background: #fff; 526 border: none; 527 cursor: pointer; 528 font-size: 20px; 529 line-height: 36px; 530 text-align: center; 531 color: #222; 532 box-shadow: 0 2px 8px rgba(0,0,0,0.3); 533 z-index: 1; 534 padding: 0; 535 } 536 #ImageLightbox .lb-close:hover { 537 background: #eee; 538 } 539</style> 540<section class="page-title page-title-4 image-bg overlay hideshopheaders"> 541 <div class="background-image-holder"> 542 <img alt="Background Image" class="background-image" src="/branding/shop.skinnyraven.com/running2.jpg" /> 543 </div> 544 <div class="headeroverlay"></div> 545 <div class="container wide"> 546 <div class="row"> 547 <div class="col-md-6"> 548 <h3 class="uppercase mb0 text-shadow">Product Details</h3> 549 </div> 550 <div class="col-md-6 text-right"> 551 <ol class="breadcrumb breadcrumb-2 text-shadow"> 552 <li><a href="/">Shop</a></li> 553 <li id="SubArea"></li> 554 <li id="SubProduct" class="active"></li> 555 </ol> 556 </div> 557 </div> 558 <!--end of row--> 559 </div> 560 <!--end of container--> 561 562 <!--Needed before remaining html for loading animations--> 563 <style> 564 @keyframes fadeInUp { 565 from { 566 opacity: 0; 567 transform: translateY(80px); 568 } 569 570 to { 571 opacity: 1; 572 transform: translateY(0); 573 } 574 } 575 576 .animate { 577 opacity: 0; 578 animation: fadeInUp 0.9s cubic-bezier(0.22, 0.61, 0.36, 1) forwards; 579 } 580 581 @media screen and (prefers-reduced-motion: reduce) { 582 .animate { 583 animation: none !important; 584 } 585 } 586 587 /* Product Page Skeleton Loader Styles */ 588 .product-skeleton { 589 display: block; 590 position: relative; 591 } 592 593 .product-skeleton.hidden { 594 display: none; 595 } 596 597 /* Create a shimmer overlay that covers all skeleton elements */ 598 .product-skeleton::before { 599 content: ''; 600 position: absolute; 601 top: 0; 602 left: 0; 603 width: 100%; 604 height: 100%; 605 background: linear-gradient(90deg, 606 rgba(255, 255, 255, 0) 0%, 607 rgba(255, 255, 255, 0.3) 50%, 608 rgba(255, 255, 255, 0) 100%); 609 background-size: 1000px 100%; 610 animation: shimmer 1.5s infinite linear; 611 pointer-events: none; 612 z-index: 1; 613 } 614 615 .product-skeleton-image { 616 width: 100%; 617 height: 513px; 618 background: linear-gradient(90deg, 619 var(--skeleton-one) 0%, 620 var(--skeleton-two) 100%); 621 border-radius: 8px; 622 margin-bottom: 15px; 623 } 624 625 .product-skeleton-thumbnails { 626 display: flex; 627 gap: 10px; 628 margin-bottom: 15px; 629 } 630 631 .product-skeleton-thumbnail { 632 width: 25%; 633 height: 115px; 634 background: linear-gradient(90deg, 635 var(--skeleton-one) 0%, 636 var(--skeleton-two) 100%); 637 border-radius: 4px; 638 } 639 640 @media (max-width: 768px) { 641 .product-skeleton-image { 642 width: 100%; 643 height: 300px; 644 } 645 646 .product-skeleton-thumbnail { 647 height: 60px; 648 } 649 } 650 651 .product-skeleton-text { 652 height: 20px; 653 background: linear-gradient(90deg, 654 var(--skeleton-one) 0%, 655 var(--skeleton-two) 100%); 656 border-radius: 4px; 657 margin-bottom: 12px; 658 } 659 660 .product-skeleton-text.small { 661 width: 40%; 662 height: 16px; 663 } 664 665 .product-skeleton-text.medium { 666 width: 70%; 667 height: 16px; 668 } 669 670 .product-skeleton-text.large { 671 width: 90%; 672 height: 24px; 673 } 674 675 .product-skeleton-text.title { 676 width: 60%; 677 height: 32px; 678 margin-bottom: 16px; 679 } 680 681 .product-skeleton-text.price { 682 width: 30%; 683 height: 28px; 684 margin-bottom: 16px; 685 } 686 687 .product-skeleton-button { 688 width: 150px; 689 height: 45px; 690 background: linear-gradient(90deg, 691 var(--skeleton-one) 0%, 692 var(--skeleton-two) 100%); 693 border-radius: 4px; 694 margin-top: 20px; 695 } 696 697 .product-skeleton-color-swatches { 698 display: flex; 699 gap: 8px; 700 margin-top: 12px; 701 } 702 703 .product-skeleton-color-swatch { 704 width: 100px; 705 height: 100px; 706 border-radius: 4px; 707 background: linear-gradient(90deg, 708 var(--skeleton-one) 0%, 709 var(--skeleton-two) 100%); 710 } 711 712 .product-single.loaded .product-skeleton { 713 display: none; 714 } 715 716 .product-single .description, 717 .product-single .image-slider, 718 .product-single .add-to-cart, 719 .product-single .widget,
720 .product-single .tabbed-content { 721 display: none; 722 } 723 724 .product-single.loaded .description, 725 .product-single.loaded .image-slider, 726 .product-single.loaded .add-to-cart, 727 .product-single.loaded .widget, 728 .product-single.loaded .tabbed-content { 729 display: block; 730 } 731 732 .product-single .back-title, 733 .product-single #BrandArea { 734 display: block; 735 } 736 737 #ProductBrand { 738 text-decoration: none; 739 transition: text-decoration 0.2s ease; 740 } 741 742 #ProductBrand:hover { 743 text-decoration: underline; 744 } 745 746 @keyframes shimmer { 747 0% { 748 background-position: -1000px 0; 749 } 750 751 100% { 752 background-position: 1000px 0; 753 } 754 } 755 756 /* Wishlist Toggle Styles */ 757 .wishlist-toggle { 758 background: none; 759 border: 2px solid #e0e0e0; 760 border-radius: 50%; 761 width: 44px; 762 height: 44px; 763 display: flex; 764 align-items: center; 765 justify-content: center; 766 cursor: pointer; 767 transition: border 0.15s ease-in-out; 768 flex-shrink: 0; 769 padding: 8px; 770 position: relative; 771 margin-bottom: 0px; 772 } 773 .wishlist-toggle .btn__effect { 774 display: inline-block; 775 position: relative; 776 width: 20px; 777 height: 20px; 778 } 779 .wishlist-toggle .heart-stroke { 780 width: 20px; 781 height: 20px; 782 fill: #cccccc; 783 transition: fill 0.3s ease; 784 } 785 .wishlist-toggle .heart-full { 786 position: absolute; 787 left: 0; 788 top: 0; 789 width: 20px; 790 height: 20px; 791 fill: var(--red); 792 opacity: 0; 793 } 794 .wishlist-toggle:hover { 795 border-color: var(--red); 796 } 797 .wishlist-toggle:hover .heart-stroke { 798 animation: pulse 1s ease-out infinite; 799 } 800 .wishlist-toggle.active .heart-stroke { 801 opacity: 0; 802 } 803 .wishlist-toggle.active .heart-full { 804 opacity: 1; 805 animation: bounceIn 0.5s linear; 806 } 807 .wishlist-toggle.active .effect:before { 808 animation: fireworkLine 0.5s linear 0.1s; 809 } 810 .wishlist-toggle.active .effect:after { 811 animation: fireworkPoint 0.5s linear 0.1s; 812 } 813 .wishlist-toggle .broken-heart { 814 position: absolute; 815 left: -14px; 816 top: -1px; 817 opacity: 0; 818 } 819 .wishlist-toggle .broken-heart--left { 820 transform: rotate(0deg); 821 transform-origin: 60% 200%; 822 } 823 .wishlist-toggle .broken-heart--right { 824 transform: rotate(0deg); 825 transform-origin: 63% 200%; 826 } 827 .wishlist-toggle .broken-heart--crack { 828 stroke-dasharray: 15; 829 stroke-dashoffset: 15; 830 } 831 .wishlist-toggle.deactivate .broken-heart { 832 opacity: 1; 833 margin-top: 4px; 834 } 835 .wishlist-toggle.deactivate .broken-heart--left { 836 animation: crackLeft 0.35s cubic-bezier(0.68, -0.55, 0.265, 2.85) 0.15s forwards, hide 0.25s ease-in 0.55s forwards; 837 } 838 .wishlist-toggle.deactivate .broken-heart--right { 839 animation: crackRight 0.35s cubic-bezier(0.68, -0.55, 0.265, 2.85) 0.15s forwards, hide 0.25s ease-in 0.55s forwards; 840 } 841 .wishlist-toggle.deactivate .broken-heart--crack { 842 animation: crack 0.2s ease-in forwards; 843 } 844 .wishlist-toggle .effect-group { 845 position: absolute; 846 top: 0; 847 left: 0; 848 width: 100%; 849 height: 100%; 850 transform: rotate(25deg); 851 } 852 .wishlist-toggle .effect-group .effect { 853 display: block; 854 position: absolute; 855 top: 38%; 856 left: 50%;
857 width: 20px; 858 transform-origin: 0px 2px; 859 } 860 .wishlist-toggle .effect-group .effect:nth-child(2) { transform: rotate(72deg); } 861 .wishlist-toggle .effect-group .effect:nth-child(3) { transform: rotate(144deg); } 862 .wishlist-toggle .effect-group .effect:nth-child(4) { transform: rotate(216deg); } 863 .wishlist-toggle .effect-group .effect:nth-child(5) { transform: rotate(288deg); } 864 .wishlist-toggle .effect-group .effect:before { 865 content: ""; 866 display: block; 867 position: absolute; 868 right: 0; 869 border-radius: 1.5px; 870 height: 3px; 871 background: var(--red); 872 } 873 .wishlist-toggle .effect-group .effect:after { 874 content: ""; 875 display: block; 876 position: absolute; 877 top: 10px; 878 right: 10%; 879 border-radius: 50%; 880 width: 3px; 881 height: 3px; 882 background: var(--red); 883 transform: scale(0, 0); 884 } 885 @keyframes pulse { 886 0% { opacity: 1; transform-origin: center center; transform: scale(1); } 887 50% { opacity: 0.6; transform: scale(1.15); } 888 100% { opacity: 1; transform: scale(1); } 889 } 890 @keyframes bounceIn { 891 0% { transform: scale(0); } 892 30% { transform: scale(1.25); } 893 50% { transform: scale(0.9); } 894 70% { transform: scale(1.1); } 895 80% { transform: scale(1); } 896 } 897 @keyframes fireworkLine { 898 0% { right: 20%; transform: scale(0, 0); } 899 25% { right: 20%; width: 6px; transform: scale(1, 1); } 900 35% { right: 0; width: 35%; } 901 70% { right: 0; width: 4px; transform: scale(1, 1); } 902 100% { right: 0; transform: scale(0, 0); } 903 } 904 @keyframes fireworkPoint { 905 30% { transform: scale(0, 0); } 906 60% { transform: scale(1, 1); } 907 100% { transform: scale(0, 0); } 908 } 909 @keyframes crackLeft { 910 0% { transform: rotate(0deg); } 911 100% { transform: rotate(-45deg); } 912 } 913 @keyframes crackRight { 914 0% { transform: rotate(0deg); } 915 100% { transform: rotate(45deg); } 916 } 917 @keyframes crack { 918 0% { stroke-dasharray: 15; stroke-dashoffset: 15; } 919 80% { stroke-dasharray: 15; stroke-dashoffset: 0; opacity: 1; } 920 100% { opacity: 0; } 921 } 922 @keyframes hide { 923 0% { opacity: 1; } 924 100% { opacity: 0; } 925 } 926 @media (max-width: 768px) { 927 .wishlist-toggle { 928 width: 38px; 929 height: 38px; 930 } 931 } 932 </style> 933 934</section> 935<div class="threshold hidden">Free Shipping<span class="freeterms hidden"> on orders totaling more than $<span id="Threshold" class="freeamount"></span></span></div> 936<section class="pt24 pt-xs-16 pt24 pt-xs-16 white"> 937 <div class="container wide"> 938 <div class="row"> 939 <div class="col-md-12"> 940 <div class="product-single"> 941 <div class="row mb24 mb-xs-16"> 942 <div class="col-md-6 col-sm-6"> 943 <div class="back-title"><a href="javascript:history.go(-1);" style="font-weight: 800; color: var(--menu);"> <i class="icon-ti-back" style="font-size: 13px; color: var(--primary);"></i> Back</a></div> 944 <!-- Product Skeleton Loader - Image --> 945 <div class="product-skeleton"> 946 <div class="product-skeleton-image"></div> 947 <div class="product-skeleton-thumbnails"> 948 <div class="product-skeleton-thumbnail"></div> 949 <div class="product-skeleton-thumbnail"></div> 950 <div class="product-skeleton-thumbnail"></div> 951 <div class="product-skeleton-thumbnail"></div> 952 </div> 953 </div> 954 <div class="image-slider slider-thumb-control
954s controls-inside animate"> 955 <ul id="ImageThumbs" class="slides "></ul> 956 </div> 957 <!--end of image slider--> 958 </div> 959 <div class="col-md-5 col-md-offset-1 col-sm-6"> 960 <!-- Product Skeleton Loader - Details --> 961 <div class="product-skeleton"> 962 <div class="product-skeleton-text small"></div> 963 <div class="product-skeleton-text title"></div> 964 <div class="product-skeleton-text price"></div> 965 <div class="product-skeleton-text large"></div> 966 <div class="product-skeleton-text large"></div> 967 <div class="product-skeleton-text large"></div> 968 <div style="margin-top: 24px;"> 969 <div class="product-skeleton-text small"></div> 970 <div class="product-skeleton-color-swatches"> 971 <div class="product-skeleton-color-swatch"></div> 972 <div class="product-skeleton-color-swatch"></div> 973 <div class="product-skeleton-color-swatch"></div> 974 <div class="product-skeleton-color-swatch"></div> 975 </div> 976 </div> 977 <div style="margin-top: 32px;"> 978 <div class="product-skeleton-text medium"></div> 979 <div class="product-skeleton-text medium"></div> 980 <div class="product-skeleton-text medium"></div> 981 </div> 982 <div class="product-skeleton-button"></div> 983 </div> 984 <div class="description"> 985 <a id="ProductBrand" class="uppercase mb0" style="color: var(--menu); font-weight: 800; display: block; font-size: 0.83em;" href="#"> 986 </a> 987 <div> 988 <h1 id="ProductTitle" class="uppercase productname mt8 mb8" style="margin: 0; flex: 1;"> 989 </h1> 990 </div> 991 <div class="mt0"> 992 <span id="ProductPrice" class="number price"></span> USD <span class="productsalelabel">SALE</span> 993 </div> 994 <div id="Savings" class="savings mb8" style="display: none;"></div> 995 <p class="mt16 mb16" id="ProductShortDescription"></p> 996 997 <ul> 998 <li><strong style="color: var(--almostblack);">OPTIONS:</strong> <span id="ProductColor"></span><br><span id="ColorList"></span></li> 999 </ul> 1000 </div> 1001 <!--end of widget--> 1002 <form class="add-to-cart"> 1003 <div id="OptionsArea" class="instock select-option mb16"> 1004 <label>SELECT A SIZE:</label> 1005 <div id="SizesChoices"></div> 1006 <select id="PurchaseOptions" style="display: none;"></select> 1007 </div> 1008 <div id="DetailOptionsArea" class="select-option" style="display: none;"> 1009 <label>DETAILS:</label> 1010 <div id="SelectOptions"></div> 1011 </div> 1012 <div class="outofstock mt64 mb48" style="display: none; font-weight: 800;">Out of Stock</div> 1013 <div id="QuantityArea" class="select-option mb16" style="display: none; clear: both; max-width: 185px;"> 1014 <label for="Quantity" style="width: 100%;" class="mt16">SELECT QUANTITY:</label> 1015 <i class="ti-angle-down quantitydropdown"></i> 1016 <select id="Quantity"></select> 1017 </div> 1018 <div id="PickupArea"> 1019 <div id="PickUpOptions" class="options" style="display:none"> 1020 <label class="mb0 mt8">DELIVERY OPTIONS:</label> 1021 <div id="ShipToMe" class="option on"> 1022 <div class="mark"></div> 1023 <div class="markLabel">Ship to Me</div> 1024 </div> 1025 </div> 1026 </div> 1027 <div id="InStore" class="instoreonly" style="display: none; font-weight: 800;">Available for Purchase In-Store Only ðï¸</div> 1028 <div id="ReleaseAvailability" class="releaseavailability" style="display: none;"></div> 1029 <div style="display: flex; align-items: center; gap: 12px;"> 1030 <div class="addArea mt24" style="clear: both; display: flex; align-items: center; gap: 12px;"> 1031 <a href="javascript:page.addCart()" style="color:#FFF"><div id="AddCartButton" class="button instock" style="display: none;">Add To Cart</div></a> 1032 </div> 1033 <button id="WishlistToggle" class="wishlist-toggle inactive" aria-label="Add to Wishlist" data-balloon-pos="right" style="margin-top: 24px;"> 1034 <div class="btn__effect"> 1035 <svg class="heart-stroke" viewBox="20 18 29 28" aria-hidden="true" focusable="false">
1035<path d="M28.3 21.1a4.3 4.3 0 0 1 4.1 2.6 2.5 2.5 0 0 0 2.3 1.7c1 0 1.7-.6 2.2-1.7a3.7 3.7 0 0 1 3.7-2.6c2.7 0 5.2 2.7 5.3 5.8.2 4-5.4 11.2-9.3 15a2.8 2.8 0 0 1-2 1 3.4 3.4 0 0 1-2.2-1c-9.6-10-9.4-13.2-9.3-15 0-1 .6-5.8 5.2-5.8m0-3c-5.3 0-7.9 4.3-8.2 8.5-.2 3.2.4 7.2 10.2 17.4a6.3 6.3 0 0 0 4.3 1.9 5.7 5.7 0 0 0 4.1-1.9c1.1-1 10.6-10.7 10.3-17.3-.2-4.6-4-8.6-8.4-8.6a7.6 7.6 0 0 0-6 2.7 8.1 8.1 0 0 0-6.2-2.7z"></path></svg> 1036 <svg class="heart-full" viewBox="0 0 19.2 18.5" aria-hidden="true" focusable="false"><path d="M9.66 18.48a4.23 4.23 0 0 1-2.89-1.22C.29 10.44-.12 7.79.02 5.67.21 2.87 1.95.03 5.42.01c1.61-.07 3.16.57 4.25 1.76A5.07 5.07 0 0 1 13.6 0c2.88 0 5.43 2.66 5.59 5.74.2 4.37-6.09 10.79-6.8 11.5-.71.77-1.7 1.21-2.74 1.23z"></path></svg> 1037 <svg class="broken-heart" xmlns="http://www.w3.org/2000/svg" width="48" height="16" viewBox="5.707 17 48 16"><g fill="var(--red)"><path class="broken-heart--left" d="M29.865 32.735V18.703a4.562 4.562 0 0 0-3.567-1.476c-2.916.017-4.378 2.403-4.538 4.756-.118 1.781.227 4.006 5.672 9.737a3.544 3.544 0 0 0 2.428 1.025l-.008-.008.013-.002z"/><path class="broken-heart--right" d="M37.868 22.045c-.135-2.588-2.277-4.823-4.697-4.823a4.258 4.258 0 0 0-3.302 1.487l-.004-.003v14.035a3.215 3.215 0 0 0 2.289-1.033c.598-.596 5.882-5.99 5.714-9.663z"/></g><path class="broken-heart--crack" fill="none" stroke="#FFF" stroke-miterlimit="10" d="M29.865 18.205v14.573"/></svg> 1038 <div class="effect-group"> 1039 <span class="effect"></span> 1040 <span class="effect"></span> 1041 <span class="effect"></span> 1042 <span class="effect"></span> 1043 <span class="effect"></span> 1044 </div> 1045 </div> 1046 </button> 1047 </div> 1048 <div id="InStorePickup" class="instoreonly red" style="display: none; font-weight: 800">This product can be purchased online, but must be picked up in the store. ð§¾</div> 1049 </form> 1050 <div class="widget" style="margin-top: 20px;"> 1051 <hr class="mb0 mt24 mt-xs-12"> 1052 <ul> 1053 <li>SKU: <span id="ProductSku"></span></li> 1054 </ul> 1055 </div> 1056 </div> 1057 </div> 1058 <!--end of row--> 1059 <div class="row"> 1060 <div class="col-sm-12"> 1061 <div class="tabbed-content text-tabs"> 1062 <ul class="tabs mb16 mb-xs-8"> 1063 <li class="active"> 1064 <div class="tab-title"> 1065 <span>Description</span> 1066 </div> 1067 <div id="ProductDescription" class="tab-content"></div> 1068 </li> 1069 <li class="bridaloff"> 1070 <div class="tab-title"> 1071 <span>Sizing</span> 1072 </div> 1073 <div class="tab-content" data-content="6"></div> 1074 </li> 1075 <li> 1076 <div class="tab-title"> 1077 <span>Reviews<div class="review-count-container" style="display: none"> 1078 <div id="ReviewCount"></div> 1079 </div> 1080 </span> 1081 </div> 1082 <div class="tab-content"> 1083 <ul id="Reviews" class="ratings mb8"></ul> 1084 <!--end of ratings--> 1085 <h6 class="uppercase mb8 reviewForm" style="display: none;">Write A Review</h6> 1086 <form class="ratings-form reviewForm" style="display: none;"> 1087 <div class="select-option mb16"> 1088 <i class="ti-angle-down"></i> 1089 <select id="StarRating" class="grey"> 1090 <option selected value="Default">Select A Rating</option> 1091 <option value="5">5 Stars</option> 1092 <option value="4">4 Stars</option> 1093 <option value="3">3 Stars</option> 1094 <option value="2">2 Stars</option> 1095 <option value="1">1 Star</option> 1096 </select> 1097 </div> 1098 <textarea id="ReviewText" placeholder="What do you think about this product?" rows="3" class="mb16 pt16"></textarea> 1099 <div id="SaveReviewButton" class="button" >Submit Review</div> 1100 </form> 1101 </div> 1102 </li> 1103 </ul> 1104 </div> 1105 </div> 1106 </div> 1107 </div> 1108 </div> 1109 <!--end of row--> 1110 </div> 1111 <!--end of container--> 1112</section> 1113 1114<!-- Wishlist Login Modal --> 1115<div id="WishlistLoginModal" class="modal box"> 1116 <div class="close"></div> 1117 <div class="modal-header"> 1118 <div class="wishlist-color-modal mb24"></div> 1119 <div> 1120 <div class="title mt0 text-left">Save to Wishlist</div> 1121 <div class="subtitle mt0 mb8">Please login or sign up to save items to your wishlist</div> 1122 </div> 1123 </div> 1124 <div class="grid two" style="gap: 12px; margin-top: 24px;"> 1125 <a href="/login" class="button hollow" style="text-decoration: none; color: white; text-align: center;" onclick="modal.close();">Login</a> 1126 <a href="/signup" class="button" style="text-decoration: none; color: white; text-align: center;" onclick="modal.close();">Sign Up</a> 1127 </div> 1128</div> 1129 1130<!-- Repeater Templates --> 1131<li id="ThumbTemplate" class="template" data-thumb-alt="" style="height: auto"><img src="{{imageurl}}" alt="{{altLabel}}" data-thumb-alt="{{altLabel}}" title="{{altLabel}}" /></li> 1132 1133<div id="ImageLightbox" role="dialog" aria-modal="true"> 1134 <div class="lb-img-wrap"> 1135 <button class="lb-close" aria-label="Close">×</button> 1136 <img src="" alt="" id="LightboxImg" /> 1137 </div> 1138</div> 1139 1140<li id="ReviewTemplate" class="template mb16"> 1141 <div class="user"> 1142 <ul class="list-inline star-rating"> 1143 <li class="star1" style="display: none"> 1144 <i class="fa fa-star"></i> 1145 </li> 1146 <li class="star2" style="display: none"> 1147 <i class="fa fa-star"></i> 1148 </li> 1149 <li class="star3" style="display: none"> 1150 <i class="fa fa-star"></i> 1151 </li> 1152 <li class="star4" style="display: none"> 1153 <i class="fa fa-star"></i> 1154 </li> 1155 <li class="star5" style="display: none"> 1156 <i class="fa fa-star"></i> 1157 </li> 1158 </ul>
1159 <span class="bold-h6">{{firstName}}</span> 1160 <span class="date number">{{reviewDate}}</span> 1161 </div> 1162 <p class="mb0"> 1163 {{reviewMessage}} 1164 </p> 1165</li>
1166<script src="/assets/scripts/productRelease.js"></script>
vendor: 2 bytes, line 1166
1166
1167<script language="javascript" type="text/javascript"> 1168 var threshold = Number('150'); 1169 var flatRate = Number('10'); 1170 var shipType = 'flat'; 1171 var allowInStore = 'true'; 1172 var currency = 'USD'; 1173 var LSCode = '1'; 1174 var posId = '3'; 1175 var id = 5970565; 1176 1177 var page = { 1178 id: null, 1179 data: null, 1180 color: "", 1181 optionsIsLoaded: false, 1182 productIsLoaded: false, 1183 options: [], 1184 sizes: [], 1185 inventory: {}, 1186 isRelay: false, 1187 init: function () { 1188 store.get(); 1189 if (page.id == null) { 1190 try { 1191 if (id) page.id = id; 1192 } catch (e) { 1193 page.id = $.param("id"); 1194 } 1195 } 1196 if (isNaN(page.id)) window.location = '/'; 1197 else { 1198 page.events(); 1199 // Check if user is already loaded 1200 if (user && user.data && user.data.memberId) { 1201 page.userLoaded(); 1202 } 1203 page.get(); 1204 category.get(); 1205 brand.get(); 1206 service.post("product/options", { id: page.id }, page.optionsLoaded); 1207 } 1208 1209 if (shipType=='flat'&&flatRate<=0) { 1210 $(".threshold").removeClass("hidden"); 1211 } else { 1212 if (threshold!=null && threshold >= 0) { 1213 $(".threshold").removeClass("hidden"); 1214 if (threshold>0) { 1215 $(".freeterms").removeClass("hidden"); 1216 $("#Threshold").html(threshold.toFixed(2)); 1217 } 1218 } 1219 } 1220 }, 1221 productDetails: (e) => { 1222 page.returned(e); 1223 }, 1224 hasProductOption: (options, id) => { 1225 for (var i=0; i<options.length; i++) { 1226 var option = options[i]; 1227 if (option.id.trim().toLowerCase()==id.trim().toLowerCase()) return i; 1228 } 1229 return -1; 1230 }, 1231 optionsLoaded: (e) => { 1232 var useOptions = []; 1233 for (var i=0; i<e.data.length; i++) { 1234 var optionItem = e.data[i]; 1235 var index = page.hasProductOption(useOptions, optionItem.label); 1236 if (index==-1) { 1237 useOptions.push({ 1238 id: optionItem.label, 1239 items: [ 1240 optionItem.value 1241 ] 1242 }) 1243 } else { 1244 useOptions[index].items.push(optionItem.value); 1245 } 1246 } 1247 1248 1249 if (useOptions.length>0) { 1250 var html = ""; 1251 for (var i=0; i<useOptions.length; i++) { 1252 var option = useOptions[i]; 1253 html += `<label for="Detail_${i}">${option.id}</label>`; 1254 html += `<div class="content-area">`; 1255 if (option.items.length>1) { 1256 html += `<select class="option-detail" data-label="${option.id}">`; 1257 for (var j=0; j<option.items.length; j++) { 1258 var item = option.items[j]; 1259 html += `<option value="${item}">${item}</option>`; 1260 } 1261 html += '</select>'; 1262 } else { 1263 html += `<input type="checkbox" class="option-detail" data-label="${option.id} - ${option.items[0]}" value="${option.items[0]}"> ${option.items[0]}`; 1264 } 1265 html += '</div>'; 1266 } 1267 $("#SelectOptions").html(html); 1268 // $("#DetailOptionsArea").show(); 1269 } 1270 }, 1271 events: function () { 1272 //context.addListener("product", page.returned); 1273 context.addListener("categories", page.categoriesLoaded); 1274 context.addListener("brands", page.brandsLoaded); 1275 context.addListener("user", page.userLoaded); 1276 // context.addListener("productinventory", page.inventoryLoaded); 1277 $("#SearchFor").keypress(page.search); 1278 //$("#AddCartButton").click(page.addCart); 1279 $("#PurchaseOptions").change(page.selected); 1280 $("#SaveReviewButton").click(page.saveReview);
1281 $("#WishlistToggle").click(page.toggleWishlist); 1282 $("#WishlistLoginCancel").click(modal.close); 1283 $("#AddCartButton").on("mouseenter focus", page.showReleaseButtonDate); 1284 $("#AddCartButton").on("mouseleave blur", page.hideReleaseButtonDate); 1285 }, 1286 userLoaded: function() { 1287 // Update wishlist button when user data is loaded 1288 if (user && user.data && user.data.memberId && typeof wishlist !== 'undefined' && page.id) { 1289 // Always try to load/update in case it hasn't loaded yet 1290 if (!wishlist.isLoaded) { 1291 wishlist.load(function() { 1292 page.updateWishlistButton(); 1293 }); 1294 } else { 1295 page.updateWishlistButton(); 1296 } 1297 } 1298 }, 1299 toggleWishlist: function(e) { 1300 e.preventDefault(); 1301 if (!user || !user.data || !user.data.memberId) { 1302 // Show the custom modal 1303 modal.show('WishlistLoginModal'); 1304 return; 1305 } 1306 1307 var $button = $("#WishlistToggle"); 1308 1309 // Remove focus to hide tooltip immediately 1310 $button.blur(); 1311 1312 // Handle deactivate animation 1313 if ($button.hasClass("deactivate")) { 1314 $button.removeClass("deactivate"); 1315 } 1316 if ($button.hasClass("active")) { 1317 $button.addClass("deactivate"); 1318 } 1319 1320 wishlist.toggle(page.id, function(response) { 1321 if (response.error) { 1322 growler.error("Failed to update wishlist"); 1323 } else { 1324 if (response.isAdded) { 1325 $button.removeClass("inactive deactivate").addClass("active"); 1326 growler.success("Added to wishlist"); 1327 } else { 1328 // Deactivate animation will run, then switch to inactive 1329 setTimeout(function() { 1330 $button.removeClass("active deactivate").addClass("inactive"); 1331 }, 800); 1332 growler.success("Removed from wishlist"); 1333 } 1334 page.updateWishlistButton(); 1335 } 1336 }); 1337 }, 1338 updateWishlistButton: function() { 1339 if (wishlist.has(page.id)) { 1340 $("#WishlistToggle").removeClass("inactive").addClass("active"); 1341 $("#WishlistToggle").attr("title", "Remove from wishlist"); 1342 $("#WishlistToggle").attr("aria-label", "Remove from wishlist"); 1343 $("#WishlistToggle").attr("data-balloon-pos", "right"); 1344 } else { 1345 $("#WishlistToggle").removeClass("active").addClass("inactive"); 1346 $("#WishlistToggle").attr("title", "Add to Wishlist"); 1347 $("#WishlistToggle").attr("aria-label", "Add to Wishlist"); 1348 $("#WishlistToggle").attr("data-balloon-pos", "right"); 1349 } 1350 }, 1351 hasSize: function(code, size, sizeAppend) { 1352 var stores = page.inventory.data; 1353 for (var i=0; i<stores.length; i++) { 1354 if (stores[i].code==code) { 1355 var items = stores[i].inventory; 1356 for (var j=0; j<items.length; j++) { 1357 if (items[j].osize) { 1358 if (items[j].osize==size&&items[j].sizeAppend==sizeAppend) return true; 1359 else if (items[j].size==size&&items[j].sizeAppend==sizeAppend) return true; 1360 } else { 1361 if (items[j].size==size&&items[j].sizeAppend==sizeAppend) return true; 1362 } 1363 } 1364 } 1365 } 1366 return false; 1367 }, 1368 selectedCost: 0.00, 1369 releaseTimer: null, 1370 showReleaseButtonDate: function() { 1371 var button = $("#AddCartButton"); 1372 if (!button.hasClass("release-disabled")) return; 1373 var releaseLabel = button.attr("data-release-label"); 1374 if (releaseLabel) button.text(releaseLabel).addClass("release-hover"); 1375 }, 1376 hideReleaseButtonDate: function() { 1377 var button = $("#AddCartButton"); 1378 if (!button.hasClass("release-disabled")) return; 1379 button.text("Available Soon").removeClass("release-hover"); 1380 }, 1381 applyReleaseState: function() { 1382 var releaseLabel = productRelease.getAvailabilityLabel(page.data?.dateReleased); 1383 if (page.releaseTimer) { 1384 clearTimeout(page.releaseTimer); 1385 page.releaseTimer = null; 1386 } 1387 if (page.countdownInterval) { 1388 clearInterval(page.countdownInterval); 1389 page.countdownInterval = null; 1390 } 1391 if (releaseLabel.length > 0) { 1392 page.renderCountdown(); 1393 $("#ReleaseAvailability").show(); 1394 var releaseDateLabel = productRelease.formatReleaseDate(page.data?.dateReleased) || releaseLabel; 1395 $("#AddCartButton").text("Available Soon").attr("aria-disabled", "true").attr("data-release-label", releaseDateLabel).removeClass("release-hover").addClass("disabled release-disabled").show(); 1396 page.countdownInterval = setInterval(page.tickCountdown, 1000); 1397 } else { 1398 $("#ReleaseAvailability").hide(); 1399 $("#AddCartButton").text("Add To Cart").removeAttr("aria-disabled data-release-label").removeClass("disabled release-disabled release-hover"); 1400 } 1401 }, 1402 renderCountdown: function() { 1403 var parts = productRelease.getTimeParts(page.data?.dateReleased); 1404 var dateText = productRelease.formatReleaseDate(page.data?.dateReleased); 1405 var html = '<div class="release-countdown mb0">' 1406 + '<div class="release-countdown__head">ð Launching Soon...</div>' 1407 + (dateText ? '<div class="release-countdown__date">Launching ' + dateText + '</div>' : '') 1408 + '<div class="release-countdown__timer">' 1409 + page.countdownUnit('days', parts.days, 'Days') 1410 + page.countdownUnit('hours', parts.hours, 'Hours') 1411 + page.countdownUnit('minutes', parts.minutes, 'Mins') 1412 + page.countdownUnit('seconds', parts.seconds, 'Secs') 1413 + '</div></div>'; 1414 $("#ReleaseAvailability").html(html); 1415 }, 1416 countdownUnit: function(key, value, label) { 1417 var num = (key === 'days') ? String(value) : ('0' + value).slice(-2); 1418 return '<div class="rc-unit"><span class="rc-num" data-unit="' + key + '">' + num + '</span><span class="rc-label">' + label + '</span></div>'; 1419 }, 1420 tickCountdown: function() { 1421 var parts = productRelease.getTimeParts(page.data?.dateReleased); 1422 if (parts.total <= 0) { 1423 if (page.countdownInterval) { 1424 clearInterval(page.countdownInterval); 1425 page.countdownInterval = null; 1426 } 1427 page.applyReleaseState(); 1428 return; 1429 } 1430 $('#ReleaseAvailability .rc-num[data-unit="days"]').text(String(parts.days)); 1431 $('#ReleaseAvailability .rc-num[data-unit="hours"]').text(('0' + parts.hours).slice(-2)); 1432 $('#ReleaseAvailability .rc-num[data-unit="minutes"]').text(('0' + parts.minutes).slice(-2)); 1433 $('#ReleaseAvailability .rc-num[data-unit="seconds"]').text(('0' + parts.seconds).slice(-2)); 1434 }, 1435 selected: function() { 1436 /* 1437 var items = $("#PurchaseOptions").val(); 1438 var sizes = items.split('~'); 1439 var size = ""; 1440 var sizeAppend = ""; 1441 if (sizes.length>0) size = sizes[0].split('â').join('"'); 1442 if (sizes.length>1) sizeAppend = sizes[1]; 1443 */ 1444 var size = $(".sizeBox.selected").data("size"); 1445 var sizeAppend = $(".widthBox.selected").data("width"); 1446 1447 1448 var addresses = 0; 1449 var cost = 0; 1450 var markdown = 0; 1451 var retail = page.data.retail; 1452 var savings = 0; 1453 const shipOnly = page.data.isShipOnly === true || Number(page.data.isShipOnly) === 1; 1454 const pickupOnly = Number(page.data.inStorePickupOnly) === 1 || Number(page.data.isInStorePickupOnly) === 1; 1455 1456 1457 cost = page.data.cost; 1458 if (!page.data.isAuto) cost = page.data.realCost; 1459 1460 if (page.data.markdown!=null && page.data.markdown>0 && page.data.markdown<retail && page.data.isAuto) { 1461 savings = retail-page.data.markdown; 1462 } 1463 1464 let defaultApplied = true; 1465 $("#PickUpOptions").html('<div id="ShipToMe" class="option on" data-id="-1"><div><div class="mark"><div class="dot"></div></div></div><div class="markLabel"> ð¦ Ship to Me</div></div>'); 1466 if (!shipOnly && pickupOnly) { 1467 defaultApplied = false; 1468 $("#PickUpOptions").html(''); 1469 } 1470 1471 var codesAdded = []; 1472 var quantity = 0; 1473 1474 if (!shipOnly && (allowInStore === "true" || pickupOnly)) { 1475 1476 var stores = page.inventory.data; 1477 for (var i=0; i<stores.length; i++) { 1478 if (page.hasSize(stores[i].code, size, sizeAppend)) { 1479 var details = store.detailsFromCode(stores[i].code); 1480 if (details) { 1481 if (details.allowInStore) { 1482 addresses++; 1483 var address = details.name+'<br><i>'+details.street+' '+details.city+' '+details.state+', '+details.postalCode+'</i>'; 1484 let selectMe = false; 1485 if (!defaultApplied) { 1486 selectMe = true; 1487 defaultApplied = true; 1488 } 1489 $("#PickUpOptions").append(`<div id="InStore${details.code}" class="option${ selectMe ? " on" : ""}" data-rid="${details.storeId}" data-id="${details.code}"> <div><div class="mark"><div class="dot"></div></div></div><div class="markLabel"> ð Pick Up at ${address}</div></div>`); 1490 } 1491 } 1492 } 1493 } 1494 } 1495 1496 1497 var skus = []; 1498 for (var i=0; i<page.inventory.data.length; i++) { 1499 for (var j=0; j<page.inventory.data[i].inventory.length; j++) { 1500 if (page.inventory.data[i].inventory[j].osize) { 1501 if (page.inventory.data[i].inventory[j].osize==size&&page.inventory.data[i].inventory[j].sizeAppend==sizeAppend) { 1502 quantity += page.inventory.data[i].inventory[j].quantity; 1503 if (skus.indexOf(page.inventory.data[i].inventory[j].sku)==-1) skus.push(page.inventory.data[i].inventory[j].sku); 1504 if (page.inventory.data[i].inventory[j].siteId!=41) { 1505 if (page.inventory.data[i].inventory[j].lineCost) cost = page.inventory.data[i].inventory[j].lineCost; 1506 else { 1507 if (page.inventory.data[i].inventory[j].isAuto) cost = page.inventory.data[i].inventory[j].cost; 1508 else cost = page.inventory.data[i].inventory[j].realCost; 1509 } 1510 } 1511 } else if (page.inventory.data[i].inventory[j].size==size&&page.inventory.data[i].inventory[j].sizeAppend==sizeAppend) { 1512 quantity += page.inventory.data[i].inventory[j].quantity; 1513 if (skus.indexOf(page.inventory.data[i].inventory[j].sku)==-1) skus.push(page.inventory.data[i].inventory[j].sku); 1514 if (page.inventory.data[i].inventory[j].siteId!=41) { 1515 if (page.inventory.data[i].inventory[j].lineCost) cost = page.inventory.data[i].inventory[j].lineCost; 1516 else { 1517 if (page.inventory.data[i].inventory[j].isAuto) cost = page.inventory.data[i].inventory[j].cost; 1518 else cost = page.inventory.data[i].inventory[j].realCost; 1519 } 1520 1521 markdown = page.inventory.data[i].inventory[j].markdown; 1522 if (page.inventory.data[i].inventory[j].retail>0) retail = page.inventory.data[i].inventory[j].retail; 1523 } 1524 } 1525 } else { 1526 if (page.inventory.data[i].inventory[j].size==size&&page.inventory.data[i].inventory[j].sizeAppend==sizeAppend) { 1527 quantity += page.inventory.data[i].inventory[j].quantity; 1528 if (skus.indexOf(page.inventory.data[i].inventory[j].sku)==-1) skus.push(page.inventory.data[i].inventory[j].sku); 1529 if (page.inventory.data[i].inventory[j].siteId!=41) { 1530 if (page.inventory.data[i].inventory[j].lineCost) cost = page.inventory.data[i].inventory[j].lineCost; 1531 else { 1532 if (page.inventory.data[i].isAuto) cost = page.inventory.data[i].inventory[j].cost; 1533 else cost = page.inventory.data[i].inventory[j].realCost; 1534 } 1535 1536 markdown = page.inventory.data[i].inventory[j].markdown; 1537 if (page.inventory.data[i].inventory[j].retail>0) retail = page.inventory.data[i].inventory[j].retail; 1538 } 1539 } 1540 } 1541 } 1542 } 1543 if (skus.length>0) $("#ProductSku").html(skus.join(', ')); 1544 page.selectedCost = cost; 1545 1546 if (cost>0) { 1547 if (cost<retail) { 1548 var savings = retail-cost; 1549 var htmlString = '$'+cost.toFixed(2)+'<span class="struckout">$'+retail.toFixed(2)+'</span>'; 1550 $("#ProductPrice").html(htmlString); 1551 $("#Savings").html('Save $'+savings.toFixed(2)); 1552 $("#Savings").show(); 1553 } else { 1554 $("#ProductPrice").html("$"+cost.toFixed(2)); 1555 } 1556 } 1557 1558 if (markdown!=null && markdown>0 && markdown<retail) { 1559 var savings = retail-markdown; 1560 var htmlString = '$'+markdown.toFixed(2)+'<span class="struckout">$'+retail.toFixed(2)+'</span>'; 1561 $("#ProductPrice").html(htmlString); 1562 $("#Savings").html('Save $'+savings.toFixed(2)); 1563 $("#Savings").show(); 1564 } 1565 1566 if (page.inventory.unassigned&&page.inventory.unassigned.length>0) { 1567 var inventory = page.inventory.unassigned; 1568 for (var j=0; j<inventory.length; j++) { 1569 if (inventory[j].osize) { 1570 if (inventory[j].osize==size&&inventory[j].sizeAppend==sizeAppend) quantity += inventory[j].quantity; 1571 else if (inventory[j].size==size&&inventory[j].sizeAppend==sizeAppend) quantity += inventory[j].quantity; 1572 } else { 1573 if (inventory[j].size==size&&inventory[j].sizeAppend==sizeAppend) quantity += inventory[j].quantity; 1574 } 1575 } 1576 } 1577 1578 $("#Quantity").html(""); 1579 for (var i=1; i<=quantity&&i<21; i++) { 1580
1580 $("#Quantity").append('<option value="'+i+'">'+i+'</option>'); 1581 } 1582 $("#Quantity").val("1"); 1583 $("#QuantityArea").show(); 1584 1585 if (shipOnly) { 1586 $("#PickUpOptions").append('<div id="ShipOnlyMessage" class="red">This product is available for shipping only. ð</div>'); 1587 $("#PickUpOptions").show(); 1588 } else if (addresses>0) $("#PickUpOptions").show(); 1589 else $("#PickUpOptions").hide(); 1590 1591 var storeCode = -1; 1592 var stores = page.inventory.data; 1593 for (var i=0; i<stores.length; i++) { 1594 if (page.hasSize(stores[i].code, size, sizeAppend)) { 1595 storeCode = stores[i].code; 1596 break; 1597 } 1598 } 1599 if (!shipOnly && (storeCode === null || storeCode === undefined || Number(storeCode) === -1)) { 1600 if (page.getRelay(size+"~"+sizeAppend)>-1) { 1601 if (page.data.brandName.toLowerCase().indexOf("hoka")==0) $("#PickUpOptions").html('<div class="red" style="margin-bottom: 20px; font-weight: 700;">This selection is available online only. Get it shipped to your door. Shipping may vary due to vendor warehouse delays, some orders may ship slower than normal. ð</div>'); 1602 else $("#PickUpOptions").html('<div class="red" style="margin-bottom: 20px; font-weight: 700;">This selection is available online only. Get it shipped to your door. Shipping may vary due to vendor warehouse delays, some orders may ship slower than normal. ð</div>'); 1603 $("#PickUpOptions").show(); 1604 } 1605 } 1606 1607 $(".option").click(app.optionToggle); 1608 page.applyReleaseState(); 1609 }, 1610 addCart: function () { 1611 if (productRelease.isFuture(page.data?.dateReleased)) { 1612 growler.error(productRelease.getUnavailableMessage(page.data.dateReleased)); 1613 return; 1614 } 1615 1616 var size = $(".sizeBox.selected").data("size"); 1617 var width = $(".widthBox.selected").data("width"); 1618 var details = []; 1619 1620 $(".option-detail").each((i, e) => { 1621 var elem = $(e); 1622 var type = elem.attr("type"); 1623 var label = elem.data("label"); 1624 if (type=="checkbox") { 1625 if (elem.is(':checked')) { 1626 details.push({ 1627 label: label, 1628 value: "Checked" 1629 }); 1630 } else { 1631 details.push({ 1632 label: label, 1633 value: "Not Checked" 1634 }); 1635 } 1636 } else { 1637 details.push({ 1638 label: label, 1639 value: elem.val() 1640 }); 1641 } 1642 }); 1643 1644 var theOption = {}; 1645 var stores = page.inventory.data; 1646 for (var i=0; i<stores.length; i++) { 1647 var items = stores[i].inventory; 1648 for (var j=0; j<items.length; j++) { 1649 if (items[j].size==size && items[j].sizeAppend==width && items[j].osize != null && items[j].osize != "") { 1650 size = items[j].osize; 1651 theOption = items[j]; 1652 break; 1653 } 1654 } 1655 } 1656 1657 var options = size+"~"+width; 1658 1659 if (page.selectedCost>0) page.data.cost = page.selectedCost; 1660 if (options != "") { 1661 1662 var pickup = -1; 1663 var oPickup = $("#PickUpOptions").find(".option.on").data("id"); 1664 pickup = $("#PickUpOptions").find(".option.on").data("id"); 1665 var runfreepickup = $("#PickUpOptions").find(".option.on").data("rid"); 1666 if (pickup==null||pickup==-1) { 1667 if ((page.data.inStorePickupOnly && page.data.inStorePickupOnly == 1) || (page.data.isInStorePickupOnly && page.data.isInStorePickupOnly == 1)) pickup = page.getStore(options); 1668 else pickup = -1; 1669 } 1670 1671 1672 var storeCode = pickup; 1673 if (isNaN(pickup)) pickup = runfreepickup; 1674 1675 if (storeCode==null||storeCode==-1||storeCode==-2) storeCode = page.getStore(options); 1676 if (theOption!=null && theOption.productId!=null && theOption.productId != page.data.productId && page.data.relayId != theOption.productId) { 1677 service.call("product", { id: theOption.productId }, (e) => { 1678 if (e.siteId==41) { 1679 e.cost = page.data.cost; 1680 try { 1681 page.data.relayId = e.productId; 1682 page.data.sku = e.sku; 1683 page.data.name = e.name; 1684 page.data.straightSku = e.straightSku; 1685 page.data.brandName = e.brandName; 1686 } catch (e) { 1687 1688 } 1689 cart.add(page.data, Number($("#Quantity").val()), pickup, options.split('â').join('"'), storeCode, page.getAddress(options, storeCode), page.getExternal(options), page.getRelay(options), page.getInventoryId(options), oPickup, details); 1690 } else { 1691 if (page.data.cost>e.cost) { 1692 e.cost = page.data.cost; 1693 } 1694 cart.add(e, Number($("#Quantity").val()), pickup, options.split('â').join('"'), storeCode, page.getAddress(options, storeCode), page.getExternal(options), page.getRelay(options), page.getInventoryId(options), oPickup, details); 1695 } 1696 }); 1697 } else { 1698 cart.add(page.data, Number($("#Quantity").val()), pickup, options.split('â').join('"'), storeCode, page.getAddress(options, storeCode), page.getExternal(options), page.getRelay(options), page.getInventoryId(options), oPickup, details); 1699 } 1700 } else growler.error("You must select the size"); 1701 }, 1702 getStore: function (options) { 1703 var sizes = options.split('~'); 1704 var size = ""; 1705 var sizeAppend = ""; 1706 if (sizes.length>0) size = sizes[0]; 1707 if (sizes.length>1) sizeAppend = sizes[1]; 1708 1709 1710 var stores = page.inventory.data; 1711 for (var i=0; i<stores.length; i++) { 1712 if (stores[i].code!=null&&page.hasSize(stores[i].code, size, sizeAppend)) return stores[i].code; 1713 } 1714 if (LSCode=='') return stores[0].code; 1715 else { 1716 for (let i=0; i<stores.length; i++) { 1717 if (stores[i].code==LSCode) return stores[i].code; 1718 } 1719 } 1720 return stores[0].code; 1721 }, 1722 getAddress: function (options, code) { 1723 var details = store.data[0]; 1724 if (Number(code)>0) { 1725 details = store.detailsFromCode(code);
1726 if (!details) details = store.data[0]; 1727 } else { 1728 for (var i=0; i<store.data.length; i++) { 1729 if (store.data[i].code==code) { 1730 details = store.data[i]; 1731 break; 1732 } 1733 } 1734 } 1735 var address = ''; 1736 if (details.street) address += details.street + " "; 1737 if (details.city) address += details.city + " "; 1738 if (details.state) address += details.state + " "; 1739 if (details.postalCode) address += details.postalCode; 1740 return address; 1741 }, 1742 getInventoryId: function(options) { 1743 var sizes = options.split('~'); 1744 var size = ""; 1745 var sizeAppend = ""; 1746 if (sizes.length>0) size = sizes[0]; 1747 if (sizes.length>1) sizeAppend = sizes[1]; 1748 var stores = page.inventory.data; 1749 for (var i=0; i<stores.length; i++) { 1750 var items = stores[i].inventory; 1751 for (var j=0; j<items.length; j++) { 1752 if (items[j].osize) { 1753 if (items[j].osize==size&&items[j].sizeAppend==sizeAppend) return items[j].inventoryId; 1754 else if (items[j].size==size&&items[j].sizeAppend==sizeAppend) return items[j].inventoryId; 1755 } else { 1756 if (items[j].size==size&&items[j].sizeAppend==sizeAppend) return items[j].inventoryId; 1757 } 1758 } 1759 } 1760 return ""; 1761 1762 }, 1763 getId: function(size, sizeAppend) { 1764 var stores = page.inventory.data; 1765 for (var i=0; i<stores.length; i++) { 1766 var items = stores[i].inventory; 1767 for (var j=0; j<items.length; j++) { 1768 if (items[j].osize) { 1769 if (items[j].osize==size&&items[j].sizeAppend==sizeAppend) return items[j].integrationId; 1770 else if (items[j].size==size&&items[j].sizeAppend==sizeAppend) return items[j].integrationId; 1771 } else { 1772 if (items[j].size==size&&items[j].sizeAppend==sizeAppend) return items[j].integrationId; 1773 } 1774 } 1775 } 1776 return ""; 1777 }, 1778 getExternal: function (options) { 1779 var sizes = options.split('~'); 1780 var size = ""; 1781 var sizeAppend = ""; 1782 if (sizes.length>0) size = sizes[0]; 1783 if (sizes.length>1) sizeAppend = sizes[1]; 1784 1785 return page.getId(size, sizeAppend); 1786 }, 1787 getRelayId: function(size, sizeAppend) { 1788 var stores = page.inventory.data; 1789 stores.push({ inventory: page.inventory.unassigned }); 1790 var relayId = -1; 1791 for (var i=0; i<stores.length; i++) { 1792 var items = stores[i].inventory; 1793 for (var j=0; j<items.length; j++) { 1794 if (items[j].osize) { 1795 if (items[j].osize==size&&items[j].sizeAppend==sizeAppend) { 1796 if (items[j].siteId==41) relayId = items[j].productId; 1797 else return -1; 1798 } else if (items[j].size==size&&items[j].sizeAppend==sizeAppend) { 1799 if (items[j].siteId==41) relayId = items[j].productId; 1800 else return -1; 1801 } 1802 } else { 1803 if (items[j].size==size&&items[j].sizeAppend==sizeAppend) { 1804 if (items[j].siteId==41) relayId = items[j].productId; 1805 else return -1; 1806 } 1807 } 1808 } 1809 } 1810 return relayId; 1811 }, 1812 getRelay: function (options) { 1813 var sizes = options.split('~'); 1814 var size = ""; 1815 var sizeAppend = ""; 1816 if (sizes.length>0) size = sizes[0]; 1817 if (sizes.length>1) sizeAppend = sizes[1]; 1818 1819 return page.getRelayId(size, sizeAppend); 1820 }, 1821 search: function (e) { 1822 if (e.keyCode == 13 && $("#SearchFor").val().trim().length > 0) { 1823 window.location = "/?search=" + $("#SearchFor").val().trim(); 1824 } 1825 }, 1826 get: function () { 1827 products.details(page.id); 1828 products.productView(page.id); 1829 }, 1830 inventoryReturned: (e) => { 1831 page.inventoryLoaded(e); 1832 }, 1833 returned: function (e) { 1834 page.data = e; 1835 1836 var isGone = ((page.data.dateDeleted!=null && moment(page.data.dateDeleted).isValid()) || !page.data.isLive); 1837 1838 if (isGone) $(".addArea").hide(); 1839 1840 products.getOptions(page.data.sku, page.data.productId, page.data.relayId, true); 1841 page.productIsLoaded = true; 1842 page.setup(); 1843 1844 var quant = Number.parseInt($("#Quantity").val()); 1845 page.quant = Number.isNaN(quant) ? 1 : quant; 1846 try { 1847 trackEvent('view_item', { 1848 "items": [ 1849 { 1850 "id": page.data.productId, 1851 "name": page.data.name, 1852 "list_name": "Products", 1853 "brand": page.data.brandName, 1854 "category": page.data.categories && page.data.categories[0] ? page.data.categories[0].name : 'All Categories', 1855 "variant": page.data.color, 1856 "list_position": 0, 1857 "quantity": page.quant, 1858 "price": page.data.cost 1859 } 1860 ] 1861 }); 1862 } catch (e) {} 1863 try { 1864 fbq('track', 'ViewContent', { 1865 currency: currency, 1866 value: page.data.cost, 1867 content_name: page.data.name, 1868 content_type: page.data.categories && page.data.categories[0] ? page.data.categories[0].name : 'All Categories', 1869 itemIds: [page.data.sku], 1870 contents: [{ 1871 "id": page.data.sku, 1872 "sku": page.data.sku, 1873 "name": page.data.name, 1874 "brand": page.data.brandName, 1875 "category": page.data.categories && page.data.categories[0] ? page.data.categories[0].name : 'All Categories', 1876 "color": page.data.color, 1877 "quantity": page.quant, 1878 "price": page.data.cost 1879 }], 1880 }); 1881 } catch (e) {} 1882 }, 1883 setup: function () { 1884 $("#ProductTitle").html(page.data.name); 1885 var brandText = page.data.label && page.data.label.trim().length>0 ? page.data.label : page.data.brandName; 1886 var brandSlug = (brandText || '') 1887 .toLowerCase() 1888 .replace(/[^a-z0-9]+/g, '-') 1889 .replace(/^-+|-+$/g, ''); 1890 var brandUrl = page.data.brandId ? '/brand/' + page.data.brandId + '/' + brandSlug : '/shop'; 1891 $("#ProductBrand").html(brandText).attr('href', brandUrl); 1892 $("#ProductSku").html(page.data.sku); 1893 $("#ProductColor").html(page.data.color); 1894 if (page.data.isOnSale || (page.data.markdown!=null && page.data.markdown>0 && page.isAuto)) $(".productsalelabel").addClass("show"); 1895 $("#ColorList").html(""); 1896 var colorsShown = []; 1897 for (var i=0; i<page.data.colors.length; i++) { 1898 if (page.data.colors[i]==null) page.data.colors[i] = ""; 1899 } 1900 page.data.colors.sort((a,b) => (a.color > b.color) ? 1 : ((b.color > a.color) ? -1 : 0)); 1901 for (var i = 0; i < page.data.colors.length; i++) { 1902 var color = page.data.colors[i].color; 1903 if (color!=null ) color = color.replace(/\W/g, ''); 1904 else color = ""; 1905 if (!colorsShown.includes(color)) { 1906 if (page.data.colors[i].productId == page.data.productId) { 1907 $("#ColorList").append('<span class="color selected" style="background-image: url(\'' + products.getSize(150, page.data.colors[i].url) + '\')" title="' + page.data.colors[i].color + '"></span>'); 1908 } else { 1909 if (!page.data.colors[i].color) page.data.colors[i].color = page.data.colors[i].name.replace(/\W/g, '');; 1910 var url = products.getCanonical(page.data.colors[i]); 1911 $("#ColorList").append('<span class="color" style="background-image: url(\'' + products.getSize(150, page.data.colors[i].url) + '\')" data-product="' + url + '" aria-label="' + page.data.colors[i].color + '" data-balloon-pos="up"></span>'); 1912 } 1913 colorsShown.push(color); 1914 } else { 1915 } 1916 } 1917 $("*[data-product]").click(function (e) { 1918 window.location = $(e.currentTarget).data("product"); 1919 }); 1920 const description = page.data.description || ""; 1921 $("#ProductDescription").html(description); 1922 var shortDesc = ''; 1923 if (page.data.blurb&&page.data.blurb.trim().length>
19230) shortDesc = page.data.blurb; 1924 else { 1925 shortDesc = description.replace(/<(?:.|\n)*?>/gm, ''); 1926 if (shortDesc.length > 300) shortDesc = shortDesc.substring(0, 300) + "..."; 1927 } 1928 1929 $("#ProductShortDescription").html(shortDesc); 1930 1931 var cost = page.data.cost; 1932 if (!page.data.isAuto) cost = page.data.realCost; 1933 if (page.data.isOnSale) { 1934 var retail = page.data.retail; 1935 if (retail>cost) { 1936 var savings = retail-cost; 1937 var htmlString = '$'+cost.toFixed(2)+'<span class="struckout">$'+retail.toFixed(2)+'</span>'; 1938 $("#ProductPrice").html(htmlString); 1939 $("#Savings").html('Save $'+savings.toFixed(2)); 1940 $("#Savings").show(); 1941 } else { 1942 $("#ProductPrice").html("$"+cost.toFixed(2)); 1943 } 1944 } else { 1945 $("#ProductPrice").html("$"+cost.toFixed(2)); 1946 } 1947 1948 if (page.data.markdown!=null && page.data.markdown>0 && page.data.markdown<retail && page.data.isAuto) { 1949 var retail = page.data.retail; 1950 var savings = retail-page.data.markdown; 1951 var htmlString = '$'+page.data.markdown.toFixed(2)+'<span class="struckout">$'+retail.toFixed(2)+'</span>'; 1952 $("#ProductPrice").html(htmlString); 1953 $("#Savings").html('Save $'+savings.toFixed(2)); 1954 $("#Savings").show(); 1955 } 1956 1957 var name = page.data.name; 1958 if (name.length > 25) name = name.substring(0, 25) + "..."; 1959 $("#SubProduct").html(name); 1960 1961 var brand = page.data.brandName; 1962 if (page.data.label&&page.data.label.trim().length>0) brand = page.data.label; 1963 if (brand.length > 25) brand = brand.substring(0, 25) + "..."; 1964 $("#SubArea").html('<a href="' + brandUrl + '">' + brand + '</a>'); 1965 1966 var altLabel = page.data.name.trim(); 1967 if (page.data.metaAlt && page.data.metaAlt.trim().length>0) altLabel = page.data.metaAlt.trim(); 1968 1969 $("#ImageThumbs").html(""); 1970 var used = []; 1971 for (var i = 0; i < page.data.images.length; i++) { 1972 if (!used.includes(page.data.images[i].url)) { 1973 var thumbElement = $("#ThumbTemplate").clone(); 1974 thumbElement.removeClass("template"); 1975 thumbElement.attr("id", "Row" + i); 1976 thumbElement.attr("data-thumb-alt", altLabel); 1977 1978 const imageUrl = products.getSize(600, page.data.images[i].url); 1979 const img = thumbElement.find("img"); 1980 img.attr("src", imageUrl); 1981 img.attr("alt", altLabel); 1982 img.attr("title", altLabel); 1983 img.attr("data-thumb-alt", altLabel); 1984 1985 img.attr("data-full-url", page.data.images[i].url); 1986 $("#ImageThumbs").append(thumbElement); 1987 used.push(page.data.images[i].url); 1988 } 1989 } 1990 1991 $("#ImageThumbs").off("click.lightbox").on("click.lightbox", "img", function() { 1992 var url = $(this).attr("data-full-url"); 1993 var alt = $(this).attr("alt"); 1994 var fullUrl = products.getSize(2048, url); 1995 $("#LightboxImg").attr("src", fullUrl).attr("alt", alt); 1996 $("#ImageLightbox").addClass("open"); 1997 }); 1998 $("#ImageLightbox").off("click.lightbox").on("click.lightbox", function(e) { 1999 if ($(e.target).hasClass("lb-close") || $(e.target).is("#ImageLightbox")) { 2000 $("#ImageLightbox").removeClass("open"); 2001 } 2002 }); 2003 $(document).off("keydown.lightbox").on("keydown.lightbox", function(e) { 2004 if (e.key === "Escape") $("#ImageLightbox").removeClass("open"); 2005 }); 2006 2007 page.loadReviews(); 2008 2009 if ((page.data.isInStorePurchaseOnly && page.data.isInStorePurchaseOnly == 1) || (page.data.inStorePurchaseOnly && page.data.inStorePurchaseOnly == 1)) { 2010 $(".addArea").hide(); 2011 $("#PickupArea").hide(); 2012 $("#InStore").show(); 2013 } else { 2014 if ((page.data.inStorePickupOnly && page.data.inStorePickupOnly == 1) || (page.data.isInStorePickupOnly && page.data.isInStorePickupOnly == 1)) { 2015 if (page.data.relayId==-1) $("#InStorePickup").show(); 2016 } 2017 } 2018 2019 if (page.optionsIsLoaded) { 2020 page.selected(); 2021 $("#AddCartButton").show(); 2022 } 2023 2024 if (user.data.memberId) { 2025 $(".reviewForm").show(); 2026 } 2027 2028 // Hide skeleton and show product content after brief delay, then initialize slider 2029 setTimeout(function() { 2030 $(".product-single").addClass("loaded"); 2031 page.setupSlider(); 2032 }, 250); 2033 }, 2034 saveReview: function() { 2035 var reviewText = $("#ReviewText").val(); 2036 var userName = user.data.firstName+" "+user.data.lastName; 2037 var date = new Date(); 2038 var year = date.getFullYear();
2039 var month = (1 + date.getMonth()).toString(); 2040 month = month.length > 1 ? month : '0' + month; 2041 var day = date.getDate().toString(); 2042 day = day.length > 1 ? day : '0' + day; 2043 var reviewDate = month + '/' + day + '/' + year; 2044 var rating = $('#StarRating').val(); 2045 var review = {userName: userName, reviewMessage: reviewText, reviewDate: reviewDate, rating: rating}; 2046 page.data.reviews.push(review); 2047 var callback = (e) => { 2048 if (e.error) growler.error(e.error); 2049 else { 2050 growler.success("Review submitted. It will be displayed once it's approved."); 2051 $('#StarRating').val('Default'); 2052 $('#ReviewText').val(''); 2053 $(".reviewForm").hide(); 2054 page.loadReviews(); 2055 } 2056 }; 2057 brand.saveReview(page.data.productId, userName, reviewText, reviewDate, rating, callback); 2058 }, 2059 loadReviews: function() { 2060 var callback = (e) => { 2061 if (e.error) growler.error(e.error); 2062 else { 2063 page.data.reviews = e.data; 2064 $("#Reviews").empty(); 2065 2066 let reviewCount = 0; 2067 let reviewTotal = 0; 2068 for (var i = 0; i < e.data.length; i++) { 2069 if (e.data[i].isApproved) { 2070 reviewCount++; 2071 } 2072 } 2073 if (reviewCount <= 0) { 2074 $('.review-count-container').hide(); 2075 var message = "This product has not been reviewed. "; 2076 if (user.data.memberId) message += "Be the first one to leave a review!"; 2077 else message += "Please login to leave the first!"; 2078 $("#Reviews").html(message); 2079 } else { 2080 $('.review-count-container').show(); 2081 $('#ReviewCount').text(reviewCount); 2082 } 2083 for (var i = 0; i < page.data.reviews.length; i++) { 2084 var review = page.data.reviews[i]; 2085 if (!review.isApproved) { 2086 continue; 2087 } 2088 reviewTotal += review.stars; 2089 var reviewElement = $("#ReviewTemplate").clone(); 2090 reviewElement.removeClass("template"); 2091 const id = "Row" + i; 2092 const date = Date.parse(review.datePosted); 2093 reviewElement.attr("id", id); 2094 reviewElement.html(reviewElement.html().split("{{firstName}}").join(review.firstName)); 2095 reviewElement.html(reviewElement.html().split("{{reviewDate}}").join(new Date(date).toLocaleDateString())); 2096 reviewElement.html(reviewElement.html().split("{{reviewMessage}}").join(review.message)); 2097 $("#Reviews").append(reviewElement); 2098 if (review.stars === 1) { 2099 $('#' + id + ' .star1').show(); 2100 } 2101 if (review.stars === 2) { 2102 $('#' + id + ' .star1').show(); 2103 $('#' + id + ' .star2').show(); 2104 } 2105 if (review.stars === 3) { 2106 $('#' + id + ' .star1').show(); 2107 $('#' + id + ' .star2').show(); 2108 $('#' + id + ' .star3').show(); 2109 } 2110 if (review.stars === 4) { 2111 $('#' + id + ' .star1').show(); 2112 $('#' + id + ' .star2').show(); 2113 $('#' + id + ' .star3').show(); 2114 $('#' + id + ' .star4').show(); 2115 } 2116 if (review.stars === 5) { 2117 $('#' + id + ' .star1').show(); 2118 $('#' + id + ' .star2').show(); 2119 $('#' + id + ' .star3').show(); 2120 $('#' + id + ' .star4').show(); 2121 $('#' + id + ' .star5').show(); 2122 } 2123 } 2124 let reviewAgg = 0; 2125 if (reviewCount > 0) { 2126 reviewAgg = reviewTotal/reviewCount; 2127 } 2128 let item = page.data; 2129 item.reviewCount = reviewCount; 2130 item.reviewAgg = reviewAgg.toFixed(1); 2131 // products.setGoogleProductSchema(item); 2132 } 2133 } 2134 brand.getReviews(page.data.productId, callback); 2135 }, 2136 setupSlider: function() {
2137 $('.slider-all-controls').flexslider({ 2138 start: function(slider){ 2139 if(slider.find('.slides li:first-child').find('.fs-vid-background video').length){ 2140 slider.find('.slides li:first-child').find('.fs-vid-background video').get(0).play(); 2141 } 2142 }, 2143 after: function(slider){ 2144 if(slider.find('.fs-vid-background video').length){ 2145 if(slider.find('li:not(.flex-active-slide)').find('.fs-vid-background video').length){ 2146 slider.find('li:not(.flex-active-slide)').find('.fs-vid-background video').get(0).pause(); 2147 } 2148 if(slider.find('.flex-active-slide').find('.fs-vid-background video').length){ 2149 slider.find('.flex-active-slide').find('.fs-vid-background video').get(0).play(); 2150 } 2151 } 2152 } 2153 }); 2154 $('.slider-paging-controls').flexslider({ 2155 animation: "slide", 2156 directionNav: false 2157 }); 2158 $('.slider-arrow-controls').flexslider({ 2159 controlNav: false 2160 }); 2161 $('.slider-thumb-controls .slides li').each(function() { 2162 var imgSrc = $(this).find('img').attr('src'); 2163 $(this).attr('data-thumb', imgSrc); 2164 }); 2165 $('.slider-thumb-controls').flexslider({ 2166 animation: "slide", 2167 controlNav: "thumbnails", 2168 directionNav: true 2169 }); 2170 $('.logo-carousel').flexslider({ 2171 minItems: 1, 2172 maxItems: 4, 2173 move: 1, 2174 itemWidth: 200, 2175 itemMargin: 0, 2176 animation: "slide", 2177 slideshow: true, 2178 slideshowSpeed: 3000, 2179 directionNav: false, 2180 controlNav: false 2181 }); 2182 }, 2183 brand: function (e) { 2184 var brand = $(e.currentTarget).val(); 2185 if (brand.trim().length > 0) { 2186 window.location = "/#brand=" + brand; 2187 } 2188 }, 2189 categoriesLoaded: function (e) { 2190 page.categories = context.get("categories"); 2191 $("#CategoryList").html(""); 2192 var link = '<li><a href="/">All Categories</a></li>'; 2193 $("#CategoryList").append(link); 2194 if (page.categories.length > 0) { 2195 for (var i = 0; i < page.categories.length; i++) { 2196 $("#CategoryList").append("<li><a href=\"/shop#category=" + page.categories[i].categoryId + "\">" + page.categories[i].name.toLowerCase() + "</a></li>"); 2197 } 2198 $("#CategoryArea").show(); 2199 } else { 2200 $("#CategoryArea").hide(); 2201 } 2202 }, 2203 brandsLoaded: function (e) { 2204 page.brands = context.get("brands"); 2205 $("#BrandList").html(""); 2206 $("#BrandList").append('<option value="" selected>All Brands</option>'); 2207 if (page.brands.length > 0) { 2208 for (var i = 0; i < page.brands.length; i++) { 2209 $("#BrandList").append('<option value="' + page.brands[i].brandId + '">' + page.brands[i].name + '</option>'); 2210 } 2211 $("#BrandArea").show(); 2212 } else { 2213 $("#BrandArea").hide(); 2214 } 2215 $("#BrandList").change(page.brand); 2216 }, 2217 hasOption: function(options, option) { 2218 for (var i=0; i<options.length; i++) { 2219 if (options[i].label==option.label||((options[i].upc!=null&&options[i].upc.trim().length>0)&&options[i].upc==option.upc)) return true; 2220 } 2221 return false; 2222 }, 2223 inventoryLoaded: function (e) { 2224 page.inventory = e; 2225 var stores = page.inventory.data; 2226 $("#PurchaseOptions").html(""); 2227 $("#PurchaseOptions").append('<option value="">Select One...</option>'); 2228 2229 var options = []; 2230 var sizeLabels = []; 2231 var widthLabels = []; 2232 for (var i=0; i<stores.length; i++) { 2233 var inventory = stores[i].inventory; 2234 if (inventory.length>0) { 2235 for (var j=0; j<inventory.length; j++) { 2236 if (inventory[j].size&&inventory[j].size.trim().length>0) { 2237 if (!isNaN(Number(inventory[j].size.trim()))) { 2238 inventory[j].osize = inventory[j].size; 2239 if (posId=="6") inventory[j].size = inventory[j].size; 2240 else inventory[j].size = Number(inventory[j].size).toFixed(1); 2241 } else inventory[j].osize = inventory[j].size; 2242 } 2243 } 2244 for (var j=0; j<inventory.length; j++) { 2245 if (inventory[j].quantity>0) { 2246 var option = { 2247 label: inventory[j].size+'~'+inventory[j].sizeAppend, 2248 value: inventory[j].size+'~'+inventory[j].sizeAppend, 2249 upc: inventory[j].upc, 2250 size: inventory[j].size, 2251 width: inventory[j].sizeAppend, 2252 productId: inventory[j].productId, 2253 sku: inventory[j].sku 2254 } 2255 if (inventory[j].osize) option.value = inventory[j].osize+'~'+inventory[j].sizeAppend; 2256 if (!page.hasOption(options, option)) { 2257 options.push(option); 2258 } 2259 if (!sizeLabels.includes(inventory[j].size)) sizeLabels.push(inventory[j].size); 2260 if (!widthLabels.includes(inventory[j].sizeAppend)) widthLabels.push(inventory[j].sizeAppend); 2261 } 2262 } 2263 } 2264 } 2265 2266 if (page.inventory.unassigned&&page.inventory.unassigned.length>0) { 2267 var inventory = page.inventory.unassigned; 2268 for (var j=0; j<inventory.length; j++) { 2269 if (inventory[j].size&&inventory[j].size.trim().length>0) { 2270 if (!isNaN(Number(inventory[j].size.trim()))) { 2271 inventory[j].osize = inventory[j].size; 2272 if (posId=="6") inventory[j].size = inventory[j].size; 2273 else inventory[j].size = Number(inventory[j].size).toFixed(1); 2274 } else inventory[j].osize = inventory[j].size; 2275 } 2276 } 2277 for (var j=0; j<inventory.length; j++) { 2278 var option = { 2279 label: inventory[j].size+'~'+inventory[j].sizeAppend, 2280 value: inventory[j].size+'~'+inventory[j].sizeAppend, 2281 upc: inventory[j].upc, 2282 size: inventory[j].size, 2283 width: inventory[j].sizeAppend 2284 } 2285 if (inventory[j].osize) option.value = inventory[j].osize+'~'+inventory[j].sizeAppend; 2286 if (!page.hasOption(options, option)) { 2287 options.push(option); 2288 if (!sizeLabels.includes(inventory[j].size)) sizeLabels.push(inventory[j].size); 2289 if (!widthLabels.includes(inventory[j].sizeAppend)) widthLabels.push(inventory[j].sizeAppend); 2290 } 2291 } 2292 } 2293 if (options.length>0) { 2294 2295 options.sort(function(a, b) { 2296 var left = a.label.split('~')[0]; 2297 var right = b.label.split('~')[0]; 2298 if (left.indexOf("/")>0) left = left.split('/')[0]; 2299 if (right.indexOf("/")>0) right = right.split('/')[0]; 2300 if (left.indexOf("-")>0) left = left.split('-')[0]; 2301 if (right.indexOf("-")>0) right = right.split('-')[0]; 2302 if (isNaN(left)) left.localeCompare(right); 2303 else return ((Number(left)>Number(right))?1:-1); 2304 }); 2305 2306 if (options.length==1) { 2307 $("#PurchaseOptions").html(""); 2308 } 2309 var order = [ 2310 'extrasmall', 2311 'xs', 2312 'ysmall', 2313 'ladiessmall', 2314 'youthsmall', 2315 'small', 2316 's', 2317 'ys', 2318 'sm', 2319 'ls', 2320 'youthmedium', 2321 'ladiesmedium', 2322 'medium', 2323 'm', 2324 'mlong',
2325 'ym', 2326 'ml', 2327 'lm', 2328 'large', 2329 'ylarge', 2330 'youthlarge', 2331 'ladieslarge', 2332 'llarge', 2333 'lg', 2334 'l', 2335 'llong', 2336 'yl', 2337 'ly', 2338 'lxl', 2339 'yextralarge', 2340 'ladiesextralarge', 2341 'youthextralarge', 2342 'extralarge', 2343 'xllong', 2344 'xl', 2345 'xlarge', 2346 'xlg', 2347 'lxl', 2348 'yxl', 2349 'xxl', 2350 'xxlg', 2351 'yxxl', 2352 'lxxl', 2353 'xxxl', 2354 'yxxxl', 2355 'lxxxl', 2356 'xxxxl', 2357 'yxxxxl', 2358 'xxxxl' 2359 ]; 2360 options.sort(function(a, b) { 2361 var aSize = a.value.replace(/[^A-Za-z]+/g, '').toLowerCase(); 2362 aSize = aSize.replace(/\s/g, '').toLowerCase(); 2363 var bSize = b.value.replace(/[^A-Za-z]+/g, '').toLowerCase();;
2364 bSize = bSize.replace(/\s/g, ''); 2365 return order.indexOf(aSize) - order.indexOf(bSize); 2366 }); 2367 for (var i=0; i<options.length; i++) { 2368 var label = options[i].label.split('~').join(' '); 2369 if (!isNaN(label)) label = label.split('.0').join(''); 2370 $("#PurchaseOptions").append('<option value="' + options[i].value.split('"').join('“').trim()+'"'+((options.length == 1)?" selected":"")+'>'+label + '</option>'); 2371 } 2372 $(".instock").show(); 2373 $(".outofstock").hide(); 2374 var html = ""; 2375 sizeLabels.sort(function(a, b) { 2376 2377 function base(v) { 2378 v = (v ?? '').toString(); 2379 v = v.split('~')[0]; 2380 if (v.indexOf("/") > -1) v = v.split('/')[0]; 2381 if (v.indexOf("-") > -1) v = v.split('-')[0]; 2382 return v.trim(); 2383 } 2384 2385 var left = base(a); 2386 var right = base(b); 2387 2388 var aSize = left.replace(/[^A-Za-z]+/g, '').toLowerCase().replace(/\s/g, ''); 2389 var bSize = right.replace(/[^A-Za-z]+/g, '').toLowerCase().replace(/\s/g, ''); 2390 var ai = order.indexOf(aSize); 2391 var bi = order.indexOf(bSize); 2392 2393 if (ai >= 0 && bi >= 0 && ai !== bi) return ai - bi; 2394 2395 var am = left.match(/^(\d+(?:\.\d+)?)(.*)$/); 2396 var bm = right.match(/^(\d+(?:\.\d+)?)(.*)$/); 2397 2398 var aNum = am ? parseFloat(am[1]) : NaN; 2399 var bNum = bm ? parseFloat(bm[1]) : NaN; 2400 var aSuf = (am ? am[2] : '').trim().toUpperCase(); 2401 var bSuf = (bm ? bm[2] : '').trim().toUpperCase(); 2402 2403 if (!isNaN(aNum) && !isNaN(bNum)) { 2404 if (aNum !== bNum) return aNum - bNum; 2405 return aSuf.localeCompare(bSuf); 2406 } 2407 if (!isNaN(aNum)) return -1; 2408 if (!isNaN(bNum)) return 1; 2409 2410 return left.toLowerCase().localeCompare(right.toLowerCase()); 2411 }); 2412 var mySize = context.get("mySize"); 2413 for (var i=0; i<sizeLabels.length; i++) { 2414 html += '<div class="sizeBox'+((mySize==sizeLabels[i])?" selected":"")+'" data-size="'+sizeLabels[i]+'">'+sizeLabels[i]+'</div>'; 2415 } 2416 html += '<br/>'; 2417 var hideStyle = ""; 2418 if (widthLabels.length>0) { 2419 if (widthLabels.length==1&&widthLabels[0]=="") { 2420 hideStyle = "display:none;"; 2421 } 2422 } else { 2423 hideStyle = "display:none;"; 2424 } 2425 2426 widthLabels.sort(function (a, b) { 2427 a = (a ?? '').toString().trim(); 2428 b = (b ?? '').toString().trim(); 2429 2430 if (a === '') return 1; 2431 if (b === '') return -1; 2432 2433 var am = a.match(/^(\d+(?:\.\d+)?)(.*)$/); 2434 var bm = b.match(/^(\d+(?:\.\d+)?)(.*)$/); 2435 2436 var aNum = am ? parseFloat(am[1]) : NaN; 2437 var bNum = bm ? parseFloat(bm[1]) : NaN; 2438 var aSuf = (am ? am[2] : a).trim().toUpperCase(); 2439 var bSuf = (bm ? bm[2] : b).trim().toUpperCase(); 2440 2441 if (!isNaN(aNum) && !isNaN(bNum)) { 2442 if (aNum !== bNum) return aNum - bNum; 2443 return aSuf.localeCompare(bSuf); 2444 } 2445 if (!isNaN(aNum)) return -1; 2446 if (!isNaN(bNum)) return 1; 2447 2448 return a.toUpperCase().localeCompare(b.toUpperCase()); 2449 }); 2450 2451 for (var i=0; i<widthLabels.length; i++) { 2452 if (i==0) html += '<label class="mt16" style="width: 100%;'+hideStyle+'">SELECT A STYLE:</label>'; 2453 html += '<div class="widthBox" data-width="'+widthLabels[i]+'" style="'+hideStyle+'">'+((widthLabels[i]=='')?'-':widthLabels[i])+'</div>'; 2454 } 2455 $("#SizesChoices").html(html); 2456 if ($(".sizeBox.selected").length==0) $(".sizeBox").first().addClass("selected"); 2457 var autoSelected = $(".sizeBox.selected").data("size"); 2458 $(".widthBox").addClass("unselectable"); 2459 2460 for (var i=0; i<options.length; i++) { 2461 if (options[i].size==autoSelected) { 2462 $('.widthBox[data-width="'+options[i].width+'"]').removeClass("unselectable"); 2463 } 2464 } 2465 $(".widthBox:not(.unselectable)").first().addClass("selected"); 2466 $(".sizeBox").click((e) => { 2467 if (!$(e.currentTarget).hasClass("unselectable")) { 2468 $(".sizeBox").removeClass("unselectable"); 2469 $(".sizeBox").removeClass("selected"); 2470 $(e.currentTarget).addClass("selected"); 2471 var selected = $(e.currentTarget).data("size"); 2472 $(".widthBox").addClass("unselectable"); 2473 context.set("mySize", selected); 2474 for (var i=0; i<options.length; i++) { 2475 if (options[i].size==selected) { 2476 $('.widthBox[data-width="'+options[i].width+'"]').removeClass("unselectable"); 2477 } 2478 } 2479 if ($(".widthBox.selected").hasClass("unselectable")) { 2480 $(".widthBox").removeClass("selected"); 2481 $(".widthBox:not(.unselectable)").first().addClass("selected"); 2482 } 2483 page.selected(); 2484 } 2485 }); 2486 $(".widthBox").click((e) => { 2487 if (!$(e.currentTarget).hasClass("unselectable")) { 2488 $(".widthBox").removeClass("selected"); 2489 $(e.currentTarget).addClass("selected"); 2490 $(".sizeBox").addClass("unselectable"); 2491 var selected = $(e.currentTarget).data("width"); 2492 for (var i=0; i<options.length; i++) { 2493 if (options[i].width==selected) { 2494 $('.sizeBox[data-size="'+options[i].size+'"]').removeClass("unselectable"); 2495 } 2496 } 2497 if ($(".sizeBox.selected").hasClass("unselectable")) { 2498 $(".sizeBox").removeClass("selected");
2499 $(".sizeBox:not(.unselectable)").first().addClass("selected"); 2500 } 2501 page.selected(); 2502 } 2503 }); 2504 if (options.length==1) { 2505 page.optionsIsLoaded = true; 2506 if (options[0].value.split('~').join('').trim().length == 0) { 2507 $("#OptionsArea").hide(); 2508 $(".instock").hide(); 2509 if (page.productIsLoaded) { 2510 $("#AddCartButton").show(); 2511 } 2512 } 2513 } 2514 page.selected(); 2515 } else { 2516 $(".instock").hide(); 2517 $(".outofstock").show(); 2518 } 2519 }, 2520 popularLoaded: function (e) { 2521 $("#PopularList").html(""); 2522 page.products = context.get("products"); 2523 if (page.products.length > 0) { 2524 for (var i = 0; i < page.products.length; i++) { 2525 var element = $("#PopularTemplate").clone(); 2526 element.css("display", "grid"); 2527 element.attr("id", "Product" + i); 2528 element.attr("data-url", "/product/" + page.products[i].productId + "/" + page.products[i].name.split(' ').join('-')); 2529 element.html(element.html().split("{{product.url}}").join(page.products[i].url)); 2530 element.html(element.html().split("{{product.productId}}").join(page.products[i].productId)); 2531 element.html(element.html().split("{{product.name}}").join(page.products[i].name)); 2532 element.html(element.html().split("{{product.price}}").join(page.products[i].cost.toFixed(2))); 2533 $("#PopularList").append(element); 2534 } 2535 $("#PopularArea").show(); 2536 $(".clicker").click(page.goto); 2537 } else { 2538 $("#PopularArea").hide(); 2539 } 2540 } 2541 } 2542</script>
2542 2543
2544<script language="javascript" type="text/javascript"> 2545 blueshift.track("view", { products: [{sku: "NF0A8G6CKA31100000" }]}); 2546</script>
2546 2547<footer class="footer-1 storefooter"> 2548 <div id="SocialArea"> 2549 <div class="footer-title" style="margin-bottom: 10px; font-weight: 600;">Follow Us, We're Social</div> 2550 <div id="SocialLinks" class="list-inline social-list" style="margin-bottom: 8px;"></div> 2551 </div> 2552 <div class="row"> 2553 <div class="col-sm-12 text-center"> 2554 <p style="margin-bottom: 0px;"><a href="/terms">Terms</a> ⢠<a href="/privacy">Privacy</a><span class="ecomtrue"> ⢠<a href="/returns">Shipping + Returns</a></span></p> 2555 <p style="margin-bottom: 0px;">© Copyright Skinny Raven Sports - All Rights Reserved</p> 2556 <p style="margin-bottom: 0px;"><a href="https://www.runfreeproject.com" class="proud box-shadow-wide-link bridaloff" style="margin-top: 10px;" target="_blank"><img alt="Background Image" class="background-image" width="200px" height="47px" style="margin-left: -15px;" src="/assets/images/proud.webp"></a></p> 2557 </div> 2558 </div> 2559 <a class="btn btn-sm back-to-top inner-link" href="#top">Top</a> 2560</footer> 2561 2562</div> 2563<div class="fullLoading"> 2564 <div id="progress"> 2565 <span class="spinner-icon"></span> 2566 </div> 2567 <div class="running"> 2568 <div class="outer"> 2569 <div class="body"> 2570 <div class="arm behind"></div> 2571 <div class="arm front"></div> 2572 <div class="leg behind"></div> 2573 <div class="leg front"></div> 2574 </div> 2575 </div> 2576 </div> 2577 </div> 2578</div> 2579<div class="fullLoadingOrders"> 2580 <div id="progress"> 2581 <span class="spinner-icon"></span> 2582 </div> 2583 <div class="running"> 2584 <div class="outer"> 2585 <div class="body"> 2586 <div class="arm behind"></div> 2587 <div class="arm front"></div> 2588 <div class="leg behind"></div> 2589 <div class="leg front"></div> 2590 </div> 2591 </div> 2592 </div> 2593 <div class="loadMessage"> 2594 <span class="header">Processing, Please be patient</span><br/> 2595 <span style="color: #ff0072; font-weight: 800;"> 2596 Don't Tap Back or Close the Window!<br> 2597 This could cause the order to duplicate or fail.<br> 2598 </span> 2599 <span id="CheckoutStatus"></span> 2600 </div> 2601</div> 2602 2603<!-- 3rd Party Includes -->
2604<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
vendor: 2 bytes, line 2604
2604
2605<script src="/assets/scripts/flexslider.min.js"></script>
2605
2606<script src="/assets/scripts/masonry.min.js"></script>
vendor: 2 bytes, line 2606
2606
2607<script src="/assets/scripts/smooth-scroll.min.js"></script>
vendor: 2 bytes, line 2607
2607
2608<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script>
vendor: 2 bytes, line 2608
2608
2609<script type="text/javascript" src="/assets/admin/scripts/spectrum.js?v=1.2.0"></script>
2609 2610<!-- Model Objects -->
2611<script type="text/javascript" src="/assets/admin/scripts/models/products.js?v=1.2.0"></script>
vendor: 2 bytes, line 2611
2611
2612<script type="text/javascript" src="/assets/admin/scripts/models/category.js?v=1.2.0"></script>
vendor: 2 bytes, line 2612
2612
2613<script type="text/javascript" src="/assets/admin/scripts/models/brand.js?v=1.2.0"></script>
vendor: 2 bytes, line 2613
2613
2614<script type="text/javascript" src="/assets/scripts/collection.js?v=1.2.0"></script>
vendor: 2 bytes, line 2614
2614
2615<script type="text/javascript" src="/assets/admin/scripts/models/discounts.js?v=1.2.0"></script>
vendor: 2 bytes, line 2615
2615
2616<script type="text/javascript" src="/assets/admin/scripts/models/orders.js?v=1.2.0"></script>
vendor: 2 bytes, line 2616
2616
2617<script type="text/javascript" src="/assets/admin/scripts/models/taxes.js?v=1.2.0"></script>
vendor: 2 bytes, line 2617
2617
2618<script type="text/javascript" src="/assets/admin/scripts/models/states.js?v=1.2.0"></script>
vendor: 2 bytes, line 2618
2618
2619<script type="text/javascript" src="/assets/admin/scripts/models/country.js?v=1.2.0"></script>
vendor: 2 bytes, line 2619
2619
2620<script type="text/javascript" src="/assets/admin/scripts/models/homepage.js?v=1.2.0"></script>
vendor: 2 bytes, line 2620
2620
2621<script type="text/javascript" src="/assets/admin/scripts/models/customers.js?v=1.2.0"></script>
vendor: 2 bytes, line 2621
2621
2622<script type="text/javascript" src="/assets/admin/scripts/models/site.js?v=1.2.0"></script>
vendor: 2 bytes, line 2622
2622
2623<script type="text/javascript" src="/assets/admin/scripts/models/user.js?v=1.2.0"></script>
vendor: 2 bytes, line 2623
2623
2624<script type="text/javascript" src="/assets/admin/scripts/models/address.js?v=1.2.0"></script>
vendor: 2 bytes, line 2624
2624
2625<script type="text/javascript" src="/assets/admin/scripts/models/contents.js?v=1.2.0"></script>
vendor: 2 bytes, line 2625
2625
2626<script type="text/javascript" src="/assets/admin/scripts/models/socials.js?v=1.2.0"></script>
vendor: 2 bytes, line 2626
2626
2627<script type="text/javascript" src="/assets/admin/scripts/models/orders.js?v=1.2.0"></script>
vendor: 2 bytes, line 2627
2627
2628<script type="text/javascript" src="/assets/admin/scripts/models/merchant.js?v=1.2.0"></script>
vendor: 2 bytes, line 2628
2628
2629<script type="text/javascript" src="/assets/admin/scripts/models/store.js?v=1.2.0"></script>
2629
2630<script type="text/javascript" src="/assets/admin/scripts/models/settings.js?v=1.2.0"></script>
2630
2631<script type="text/javascript" src="/assets/scripts/models/wishlist.js?v=1.2.0"></script>
2631 2632<!-- Application Core -->
2633<script type="text/javascript" src="/assets/admin/scripts/context.js?v=1.2.0"></script>
vendor: 2 bytes, line 2633
2633
2634<script type="text/javascript" src="/assets/admin/scripts/growler.js?v=1.2.0"></script>
vendor: 2 bytes, line 2634
2634
2635<script type="text/javascript" src="/assets/admin/scripts/modal.js?v=1.2.0"></script>
vendor: 2 bytes, line 2635
2635
2636<script type="text/javascript" src="/assets/scripts/jquery.datetimepicker.js"></script>
vendor: 2 bytes, line 2636
2636
2637<script type="text/javascript" src="/assets/admin/scripts/service.js?v=1.2.0"></script>
vendor: 2 bytes, line 2637
2637
2638<script type="text/javascript" src="/assets/admin/scripts/cart.js?v=1.2.0"></script>
2638
2639<script type="text/javascript" src="/assets/admin/scripts/store.js?v=1.2.0"></script>
2639
2640<script src="/assets/scripts/scripts.js?v=1.2.0"></script>
2640 2641 2642</body> 2643</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.