1<!doctype html> 2<!--[if lt IE 7]><html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]--> 3<!--[if IE 7]><html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]--> 4<!--[if IE 8]><html class="no-js lt-ie9" lang="en"> <![endif]--> 5<!--[if IE 9 ]><html class="ie9 no-js"> <![endif]--> 6<!--[if (gt IE 9)|!(IE)]><!--> <html class="no-js"> <!--<![endif]--> 7<head> 8 9 <!-- Basic page needs ================================================== --> 10 <meta charset="utf-8"> 11 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 12 13 14 <link rel="icon" href="https://cdn.store-assets.com/s/396414/f/5322280.png" /> 15 16 17 <!-- Title and description ================================================== --> 18 <title> 19 Login – PA | Peeos Aquatic 20 </title> 21 22 23 24 <!-- Social meta ================================================== --> 25 26 27 <meta property="og:type" content="website"> 28 <meta property="og:title" content="Login"> 29 <meta property="og:url" content="https://peeosaquatic.com/account/login"> 30 31 <meta property="og:image" content="https://cdn.store-assets.com/s/396414/f/5219718.png?width=350&format=webp"> 32 <meta property="og:image:secure_url" content="https://cdn.store-assets.com/s/396414/f/5219718.png?width=350&format=webp"> 33 34 35 36<meta property="og:description" content="Happy Shopping ! 100% Authentic Guarantee 37SSM : 201603368464 (PC0018936-W)"> 38<meta property="og:site_name" content="PA | Peeos Aquatic"> 39 40 41 42 <meta name="twitter:card" content="summary"> 43 44 45 46 <meta name="twitter:site" content="@"> 47 48 49 50 51 52 <!-- Helpers ================================================== --> 53 <link rel="canonical" href="https://peeosaquatic.com/account/login"> 54 <meta name="viewport" content="width=device-width,initial-scale=1"> 55 <meta name="theme-color" content=""> 56 57 <!-- CSS ================================================== --> 58 <link href="https://store-themes.easystore.co/396414/themes/4/assets/timber.css?t=1787076067" rel="stylesheet" type="text/css" media="screen" /> 59 <link href="https://store-themes.easystore.co/396414/themes/4/assets/theme.css?t=1787076067" rel="stylesheet" type="text/css" media="screen" /> 60 61 62 63 64 65 66
66<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js" type="text/javascript" ></script>
66 67 <!-- Header hook for plugins ================================================== --> 68 69<!-- ScriptTags -->
70<script>window.__st={p: "customers",cid: null,cem: null,cph: null,cfn: null,cln: null,cge: null,cdb: null,ccc: null};</script>
70<script src='/assets/events.js'></script>
70<script>(function(){function asyncLoad(){var urls=['/assets/traffic.js?v=1','https://apps.easystore.co/facebook-login/script.js?shop=peeoszheng.easy.co','https://apps.easystore.co/marketplace/shopee-malaysia/script.js?shop=peeoszheng.easy.co'];for(var i=0;i<urls.length;i++){var s=document.createElement('script');s.type='text/javascript';s.async=true;s.src=urls[i];var x=document.getElementsByTagName('script')[0];x.parentNode.insertBefore(s, x);}}window.attachEvent ? window.attachEvent('onload', asyncLoad) : window.addEventListener('load', asyncLoad, false);})();</script>
70 71<!-- /ScriptTags --> 72 73 74 75<!--[if lt IE 9]>
76<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.2/html5shiv.min.js" type="text/javascript" ></script>
vendor: 2 bytes, line 76
76
77<script src="https://store-themes.easystore.co/396414/themes/4/assets/respond.min.js?t=1787076067" type="text/javascript" ></script>
77 78<link href="https://store-themes.easystore.co/396414/themes/4/assets/respond-proxy.html" id="respond-proxy" rel="respond-proxy" /> 79<link href="//peeosaquatic.com/search?q=a932178fff5c37cdf538a936382008ca" id="respond-redirect" rel="respond-redirect" />
80<script src="//peeosaquatic.com/search?q=a932178fff5c37cdf538a936382008ca" type="text/javascript"></script>
80 81<![endif]--> 82 83 84 85
85<script src="https://store-themes.easystore.co/396414/themes/4/assets/modernizr.min.js?t=1787076067" type="text/javascript" ></script>
85 86 87 88 89
89<script src="/assets/shop_common.js" type="text/javascript" ></script>
89 90
90<script src="/assets/customer_area.js" type="text/javascript" ></script>
90 91 92
92<script> 93 (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ 94 (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), 95 m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) 96 })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); 97 98 ga('create', '', 'auto','myTracker'); 99 ga('myTracker.send', 'pageview'); 100 101 </script>
101 102 103<!-- Snippet:global/head: Tawk.to --> 104<!--Start of Tawk.to Script-->
105<script type="text/javascript"> 106var Tawk_API=Tawk_API||{}, Tawk_LoadStart=new Date(); 107(function(){ 108var s1=document.createElement("script"),s0=document.getElementsByTagName("script")[0]; 109s1.async=true; 110s1.src='https://embed.tawk.to/https://tawk.to/chat/5f9bb4e67f0a8e57c2d85ef4/default/default'; 111s1.charset='UTF-8'; 112s1.setAttribute('crossorigin','*'); 113s0.parentNode.insertBefore(s1,s0); 114})(); 115 116</script>
116 117<!--End of Tawk.to Script--> 118<!-- /Snippet --> 119 120<!-- Snippet:global/head: Shopee Malaysia --> 121<link type="text/css" rel="stylesheet" href="https://apps.easystore.co/assets/css/marketplace/main.css?v1.71"> 122<!-- /Snippet --> 123 124<!-- Snippet:global/head: Reperk Rewards & Loyalty Program by OnVoard -->
125<script> 126 (function() { 127 window.OnVoard = window.OnVoard || function() { 128 (window.OnVoard.q = window.OnVoard.q || []).push(arguments); 129 }; 130 var script = document.createElement("script"); 131 var parent = document.getElementsByTagName("script")[0].parentNode; 132 script.async = 1; 133 134 135 script.src = "https://scripts.onvoard.com/apps/loader.js"; 136 137 parent.appendChild(script); 138 })(); 139</script>
139 140 141
142<script> 143 144var ovData = {}; 145ovData["ecommerce_platform"] = "easystore"; 146ovData["account_id"] = "acct_nugd6705esh26gl"; 147 148 149 ovData["template"] = "customers"; 150 ovData["cart"] = {"item_count":0,"total_price":0,"announcements":[]}; 151 ovData["product"] = ""; 152 ovData["shop"] = {}; 153 ovData["customer"] = {}; 154 155 156 ovData["shop"] = { 157 "currency": "MYR", 158 "domain": "peeosaquatic.com", 159 "url": "https://peeosaquatic.com", 160 "money_format": "<span class=money data-ori-price='{{amount}}'>RM {{amount}} </span>", 161 }; 162 163 164 165 166 window.OnVoardData = ovData; 167</script>
167 168 169<!-- /Snippet --> 170 171</head> 172 173<body id="login" class="template-customers" > 174 175<!-- Snippet:global/body_start: Console Extension --> 176<div id='es_console' style='display: none;'>396414</div> 177<!-- /Snippet --> 178 179 180 <style> 181 .search-modal__form{ 182 position: relative; 183 } 184 185 .dropdown-wrapper { 186 position: relative; 187 } 188 189 .dropdown-wrapper:hover .dropdown { 190 display: block; 191 } 192 193 .dropdown { 194 display: none; 195 position: absolute; 196 top: 100%; 197 left: -20px; 198 width: 100%; 199 padding: 8px 0; 200 margin: 0; 201 background-color: #fff; 202 z-index: 1000; 203 border-radius: 5px; 204 border: 1px solid rgba(var(--color-foreground), 1); 205 border-top: none; 206 overflow-x: hidden; 207 overflow-y: auto; 208 max-height: 350px; 209 min-width: 150px; 210 box-shadow: 0 0 5px rgba(0,0,0,0.1); 211 } 212 213 .dropdown li,.dropdown a{ 214 display: block; 215 } 216 .dropdown a{ 217 text-decoration: none; 218 padding: 2px 10px; 219 color: #000 !important; 220 } 221 222 .dropdown-item { 223 padding: 0.4rem 2rem; 224 cursor: pointer; 225 line-height: 1.4; 226 overflow: hidden; 227 text-overflow: ellipsis; 228 white-space: nowrap; 229 } 230 231 .dropdown-item:hover{ 232 background-color: #f3f3f3; 233 } 234 235 .search__input.is-focus{ 236 border-radius: 15px; 237 border-bottom-left-radius: 0; 238 border-bottom-right-radius: 0; 239 border: 1px solid rgba(var(--color-foreground), 1); 240 border-bottom: none; 241 box-shadow: none; 242 } 243 244 .clear-all { 245 text-align: right; 246 padding: 0 2rem 0.2rem; 247 line-height: 1; 248 font-size: 70%; 249 margin-bottom: -2px; 250 } 251 252 .clear-all:hover{ 253 background-color: #fff; 254 } 255 256 .referral-notification { 257 position: absolute; 258 top: 100%; 259 right: -12px; 260 background: white; 261 border: 1px solid #e0e0e0; 262 border-radius: 8px; 263 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); 264 width: 280px; 265 z-index: 1000; 266 padding: 16px; 267 margin-top: 8px; 268 font-size: 14px; 269 line-height: 1.4; 270 } 271 272 .referral-notification::before { 273 content: ''; 274 position: absolute; 275 top: -8px; 276 right: 20px; 277 width: 0; 278 height: 0; 279 border-left: 8px solid transparent; 280 border-right: 8px solid transparent; 281 border-bottom: 8px solid white; 282 } 283 284 .referral-notification::after { 285 content: ''; 286 position: absolute; 287 top: -9px; 288 right: 20px; 289 width: 0; 290 height: 0; 291 border-left: 8px solid transparent; 292 border-right: 8px solid transparent; 293 border-bottom: 8px solid #e0e0e0; 294 } 295 296 .referral-notification h4 { 297 margin: 0 0 8px 0; 298 color: #2196F3; 299 font-size: 16px; 300 font-weight: 600; 301 } 302 303 .referral-notification p { 304 margin: 0 0 12px 0; 305 color: #666; 306 } 307 308 .referral-notification .referral-code { 309 background: #f5f5f5; 310 padding: 8px; 311 border-radius: 4px; 312 font-family: monospace; 313 font-size: 13px; 314 text-align: center; 315 margin: 8px 0; 316 border: 1px solid #ddd; 317 } 318 319 .referral-notification .close-btn { 320 position: absolute; 321 top: 8px; 322 right: 8px; 323 background: none; 324 border: none; 325 font-size: 18px; 326 color: #999; 327 cursor: pointer; 328 padding: 0; 329 width: 20px; 330 height: 20px; 331 line-height: 1; 332 } 333 334 .referral-notification .close-btn:hover { 335 color: #333; 336 } 337 338 .referral-notification .action-btn { 339 background: #2196F3; 340 color: white; 341 border: none; 342 padding: 8px 16px; 343 border-radius: 4px; 344 cursor: pointer; 345 font-size: 12px; 346 margin-right: 8px; 347 margin-top: 8px; 348 } 349 350 .referral-notification .action-btn:hover { 351 background: #1976D2; 352 } 353 354 .referral-notification .dismiss-btn { 355 background: transparent; 356 color: #666; 357 border: 1px solid #ddd; 358 padding: 8px 16px; 359 border-radius: 4px; 360 cursor: pointer; 361 font-size: 12px; 362 margin-top: 8px; 363 } 364 365 .referral-notification .dismiss-btn:hover { 366 background: #f5f5f5; 367 } 368 .referral-modal__dialog { 369 transform: translate(-50%, 0); 370 transition: transform var(--duration-default) ease, visibility 0s; 371 z-index: 10000; 372 position: fixed; 373 top: 20vh; 374 left: 50%; 375 width: 100%; 376 max-width: 350px; 377 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); 378 border-radius: 12px; 379 background-color: #fff; 380 color: #000; 381 padding: 20px; 382 text-align: center; 383 } 384 .modal-overlay.referral-modal-overlay { 385 position: fixed; 386 top: 0; 387 left: 0; 388 width: 100%; 389 height: 100%; 390 background-color: rgba(0, 0, 0, 0.7); 391 z-index: 2001; 392 display: block; 393 opacity: 1;
394 transition: opacity var(--duration-default) ease, visibility 0s; 395 } 396</style> 397 398<div class="header-bar"> 399 <div class="wrapper medium-down--hide"> 400 <div class="large--display-table"> 401 402 <div class="header-bar__left large--display-table-cell"> 403 404 405 406 407 408 409 410 <div class="header-bar__module header-bar__search"> 411 412 <form action="/search" method="get" class="header-bar__search-form clearfix" role="search"> 413 414 <button type="submit" class="btn icon-fallback-text header-bar__search-submit"> 415 <span class="icon icon-search" aria-hidden="true"></span> 416 <span class="fallback-text">Search</span> 417 </button> 418 <input type="search" name="q" value="" aria-label="Search" class="header-bar__search-input" placeholder="Search" autocomplete="off"> 419 <div class="dropdown" id="searchDropdown"></div> 420 <input type="hidden" name="search_history" id="search_history"> 421 </form> 422 423
424<script> 425 var _search_history_listings = "" 426 if(_search_history_listings != "") localStorage.setItem('searchHistory', JSON.stringify(_search_history_listings)); 427 428 function clearAll() { 429 localStorage.removeItem('searchHistory'); 430 431 var customer = ""; 432 if(customer) { 433 // Your logic to clear all data or call an endpoint 434 fetch('/account/search_histories', { 435 method: 'DELETE', 436 headers: { 437 "Content-Type": "application/json", 438 "X-Requested-With": "XMLHttpRequest" 439 }, 440 body: JSON.stringify({ 441 _token: "rn3KVEC8D8eQbFCquuj9KxbJbXA8R7SqtYnkOM0d" 442 }), 443 }) 444 .then(response => response.json()) 445 } 446 } 447 // End - store view history in local storage 448 449 // search history dropdown 450 var searchInputs = document.querySelectorAll('input[type=search]'); 451 452 if(searchInputs.length > 0) { 453 454 searchInputs.forEach((searchInput)=>{ 455 456 searchInput.addEventListener('focus', function() { 457 var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown'); 458 searchDropdown.innerHTML = ''; // Clear existing items 459 460 // retrieve data from local storage 461 var searchHistoryData = JSON.parse(localStorage.getItem('searchHistory')) || []; 462 463 // Convert JSON to string 464 var search_history_json = JSON.stringify(searchHistoryData); 465 466 // Set the value of the hidden input 467 searchInput.closest('form').querySelector("#search_history").value = search_history_json; 468 469 // create dropdown items 470 var clearAllItem = document.createElement('div'); 471 clearAllItem.className = 'dropdown-item clear-all'; 472 clearAllItem.textContent = 'Clear'; 473 clearAllItem.addEventListener('click', function() { 474 clearAll(); 475 searchDropdown.style.display = 'none'; 476 searchInput.classList.remove('is-focus'); 477 }); 478 searchDropdown.appendChild(clearAllItem); 479 480 // create dropdown items 481 searchHistoryData.forEach(function(item) { 482 var dropdownItem = document.createElement('div'); 483 dropdownItem.className = 'dropdown-item'; 484 dropdownItem.textContent = item.term; 485 dropdownItem.addEventListener('click', function() { 486 searchInput.value = item.term; 487 searchDropdown.style.display = 'none'; 488 }); 489 searchDropdown.appendChild(dropdownItem); 490 }); 491 492 if(searchHistoryData.length > 0){ 493 // display the dropdown 494 searchInput.classList.add('is-focus'); 495 document.body.classList.add('search-input-focus'); 496 searchDropdown.style.display = 'block'; 497 } 498 }); 499 500 searchInput.addEventListener("focusout", (event) => { 501 var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown'); 502 searchInput.classList.remove('is-focus'); 503 searchDropdown.classList.add('transparent'); 504 setTimeout(()=>{ 505 searchDropdown.style.display = 'none'; 506 searchDropdown.classList.remove('transparent'); 507 document.body.classList.remove('search-input-focus'); 508 }, 400); 509 }); 510 }) 511 } 512 // End - search history dropdown 513</script>
513 514 </div> 515 516 517 518 </div> 519 520 <div class="header-bar__right large--display-table-cell"> 521 522 <ul class="header-bar__module header-bar__module--list" style="position: relative;"> 523 524 525 526 <li> 527 <a href="/account/login">Log in</a> 528 </li><li>OR</li> 529 530 531 532 <li> 533 <a href="/account/register">Create account</a> 534 </li> 535 536 537 538 <!-- Referral Notification Popup for Desktop --> 539 <div id="referralNotification" class="referral-notification" style="display: none;"> 540 <button class="close-btn" onclick="dismissReferralNotification()">×</button> 541 <div style="text-align: center; margin-bottom: 16px;"> 542 <div style="width: 100px; height: 100px; margin: 0 auto;"> 543 <img src="https://resources.easystore.co/storefront/icons/channels/vector_referral_program.svg"> 544 </div> 545 </div> 546 <p id="referralSignupMessage" style="text-align: center; font-size: 14px; color: #666; margin: 0 0 20px 0;"> 547 Your friend gifted you credit! Sign up now to redeem. 548 </p> 549 <div style="text-align: center;"> 550 <button class="btn" onclick="goToSignupPage()" style="width: 100%; color: #fff;"> 551 Sign Up 552 </button> 553 </div> 554 </div> 555 556 </ul> 557 558 559 560 561 562 <div class="header-bar__module"> 563 <span class="header-bar__sep" aria-hidden="true"></span> 564 <a href="/cart" class="cart-page-link"> 565 <span class="icon icon-cart header-bar__cart-icon" aria-hidden="true"></span> 566 </a> 567 </div> 568 569 <div class="header-bar__module"> 570 571 <a href="/cart" class="cart-page-link"> 572 Cart<span class="hidden-count">:</span> 573 <span class="cart-count header-bar__cart-count hidden-count">0</span> 574 </a> 575 </div> 576 577 578 579 580 581 </div> 582 </div> 583 </div> 584 <div class="wrapper large--hide" style="padding: 5px 30px 0;"> 585 <button type="button" class="mobile-nav-trigger" id="MobileNavTrigger"> 586 <span class="icon icon-hamburger" aria-hidden="true"></span> 587 Menu 588 </button> 589 590 591 592 <!-- Referral Notification Modal for Mobile --> 593 <details-modal class="referral-modal" id="referralMobileModal"> 594 <details> 595 <summary class="referral-modal__toggle" aria-haspopup="dialog" aria-label="Open referral modal" style="display: none;"> 596 </summary> 597 <div class="modal-overlay referral-modal-overlay"></div> 598 <div class="referral-modal__dialog" role="dialog" aria-modal="true" aria-label="Referral notification"> 599 <div class="referral-modal__content"> 600 <button type="button" class="modal__close-button" aria-label="Close" onclick="closeMobileReferralModal()" style="position: absolute; top: 16px; right: 16px; background: none; border: none; font-size: 24px; cursor: pointer;"> 601 × 602 </button> 603 604 <div style="margin-bottom: 24px;"> 605 <div style="width: 120px; height: 120px; margin: 0 auto 20px;"> 606 <img src="https://resources.easystore.co/storefront/icons/channels/vector_referral_program.svg" style="width: 100%; height: 100%;"> 607 </div> 608 </div> 609 610 <p id="referralSignupMessageMobile" style="font-size: 16px; color: #333; margin: 0 0 30px 0; line-height: 1.5;"> 611 Your friend gifted you credit! Sign up now to redeem. 612 </p> 613 614 <button type="button" class="btn" onclick="goToSignupPageFromMobile()" style="width: 100%; color: #fff;"> 615 Sign Up 616 </button> 617 </div> 618 </div> 619 </details> 620 </details-modal> 621 622 623 624 625 <a href="/cart" class="cart-page-link mobile-cart-page-link">
626 <span class="icon icon-cart header-bar__cart-icon" aria-hidden="true"></span> 627 Cart 628 <span class="cart-count hidden-count">0</span> 629 </a> 630 <div class="mobile-cart-page-link" style="margin-right: 20px;"> 631 632 633 634 635 </div> 636 </div> 637 <ul id="MobileNav" class="mobile-nav large--hide"> 638 639 640 641 <li class="mobile-nav__link" aria-haspopup="true"> 642 643 <a href="/" class="mobile-nav"> 644 Home 645 </a> 646 647 </li> 648 649 650 <li class="mobile-nav__link" aria-haspopup="true"> 651 652 653 <a href="/collections/all" class="mobile-nav__sublist-trigger"> 654 Catagories 655 <span class="icon-fallback-text mobile-nav__sublist-expand"> 656 <span class="icon icon-plus" aria-hidden="true"></span> 657 <span class="fallback-text">+</span> 658</span> 659<span class="icon-fallback-text mobile-nav__sublist-contract"> 660 <span class="icon icon-minus" aria-hidden="true"></span> 661 <span class="fallback-text">-</span> 662</span> 663 </a> 664 <ul class="mobile-nav__sublist"> 665 666 667 668 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 669 670 <a href="/collections/new-arrival" class="mobile-nav"> 671 New arrival 672 </a> 673 674 </li> 675 676 677 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 678 679 <a href="/collections/hot-selling" class="mobile-nav"> 680 Hot selling 681 </a> 682 683 </li> 684 685 686 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 687 688 <a href="/collections/aquarium" class="mobile-nav"> 689 Aquarium 690 </a> 691 692 </li> 693 694 695 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 696 697 <a href="/collections/lock" class="mobile-nav"> 698 Lock 699 </a> 700 701 </li> 702 703 704 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 705 706 <a href="/collections/fashion" class="mobile-nav"> 707 Bag 708 </a> 709 710 </li> 711 712 713 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 714 715 <a href="/collections/pet" class="mobile-nav"> 716 Pet 717 </a> 718 719 </li> 720 721 722 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 723 724 <a href="/collections/nano-technology" class="mobile-nav"> 725 Nano Technology 726 </a> 727 728 </li> 729 730 731 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 732 733 <a href="/collections/garden-agriculture" class="mobile-nav"> 734 Garden / Agriculture 735 </a> 736 737 </li> 738 739 </ul> 740 741 </li> 742 743 744 <li class="mobile-nav__link" aria-haspopup="true"> 745 746 <a href="/blogs/news" class="mobile-nav"> 747 News 748 </a> 749 750 </li> 751 752 753 <li class="mobile-nav__link" aria-haspopup="true"> 754 755 <a href="/store-locator" class="mobile-nav"> 756 Contact Us 757 </a> 758 759 </li> 760 761 762 <li class="mobile-nav__link" aria-haspopup="true"> 763 764 <a href="https://peeosaquatic.com/apps/contact-form-plus" class="mobile-nav"> 765 Warranty Registration 766 </a> 767 768 </li> 769 770 771 772 773 774 775 776 <li class="mobile-nav__link"> 777 <a href="/account/login">Log in</a> 778 </li> 779 780 <li class="mobile-nav__link"> 781 <a href="/account/register">Create account</a> 782 </li> 783 784 785 786 787 788 <li class="mobile-nav__link"> 789 790 <div class="header-bar__module header-bar__search"> 791 792 <form action="/search" method="get" class="header-bar__search-form clearfix" role="search"> 793 794 <button type="submit" class="btn icon-fallback-text header-bar__search-submit"> 795 <span class="icon icon-search" aria-hidden="true"></span>
796 <span class="fallback-text">Search</span> 797 </button> 798 <input type="search" name="q" value="" aria-label="Search" class="header-bar__search-input" placeholder="Search" autocomplete="off"> 799 <div class="dropdown" id="searchDropdown"></div> 800 <input type="hidden" name="search_history" id="search_history"> 801 </form> 802 803
804<script> 805 var _search_history_listings = "" 806 if(_search_history_listings != "") localStorage.setItem('searchHistory', JSON.stringify(_search_history_listings)); 807 808 function clearAll() { 809 localStorage.removeItem('searchHistory'); 810 811 var customer = ""; 812 if(customer) { 813 // Your logic to clear all data or call an endpoint 814 fetch('/account/search_histories', { 815 method: 'DELETE', 816 headers: { 817 "Content-Type": "application/json", 818 "X-Requested-With": "XMLHttpRequest" 819 }, 820 body: JSON.stringify({ 821 _token: "rn3KVEC8D8eQbFCquuj9KxbJbXA8R7SqtYnkOM0d" 822 }), 823 }) 824 .then(response => response.json()) 825 } 826 } 827 // End - store view history in local storage 828 829 // search history dropdown 830 var searchInputs = document.querySelectorAll('input[type=search]'); 831 832 if(searchInputs.length > 0) { 833 834 searchInputs.forEach((searchInput)=>{ 835 836 searchInput.addEventListener('focus', function() { 837 var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown'); 838 searchDropdown.innerHTML = ''; // Clear existing items 839 840 // retrieve data from local storage 841 var searchHistoryData = JSON.parse(localStorage.getItem('searchHistory')) || []; 842 843 // Convert JSON to string 844 var search_history_json = JSON.stringify(searchHistoryData); 845 846 // Set the value of the hidden input 847 searchInput.closest('form').querySelector("#search_history").value = search_history_json; 848 849 // create dropdown items 850 var clearAllItem = document.createElement('div'); 851 clearAllItem.className = 'dropdown-item clear-all'; 852 clearAllItem.textContent = 'Clear'; 853 clearAllItem.addEventListener('click', function() { 854 clearAll(); 855 searchDropdown.style.display = 'none'; 856 searchInput.classList.remove('is-focus'); 857 }); 858 searchDropdown.appendChild(clearAllItem); 859 860 // create dropdown items 861 searchHistoryData.forEach(function(item) { 862 var dropdownItem = document.createElement('div'); 863 dropdownItem.className = 'dropdown-item'; 864 dropdownItem.textContent = item.term; 865 dropdownItem.addEventListener('click', function() { 866 searchInput.value = item.term; 867 searchDropdown.style.display = 'none'; 868 }); 869 searchDropdown.appendChild(dropdownItem); 870 }); 871 872 if(searchHistoryData.length > 0){ 873 // display the dropdown 874 searchInput.classList.add('is-focus'); 875 document.body.classList.add('search-input-focus'); 876 searchDropdown.style.display = 'block'; 877 } 878 }); 879 880 searchInput.addEventListener("focusout", (event) => { 881 var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown'); 882 searchInput.classList.remove('is-focus'); 883 searchDropdown.classList.add('transparent'); 884 setTimeout(()=>{ 885 searchDropdown.style.display = 'none'; 886 searchDropdown.classList.remove('transparent'); 887 document.body.classList.remove('search-input-focus'); 888 }, 400); 889 }); 890 }) 891 } 892 // End - search history dropdown 893</script>
893 894 </div> 895 896 </li> 897 898</ul> 899 900</div> 901
902<script> 903 // referral notification popup 904 const referralMessageTemplate = 'Your friend gifted you __CURRENCY_CODE__ __CREDIT_AMOUNT__ credit! Sign up now to redeem.'; 905 const shopPrefix = 'RM'; 906 907 function getCookie(name) { 908 const value = `; ${document.cookie}`; 909 const parts = value.split(`; ${name}=`); 910 if (parts.length === 2) return parts.pop().split(';').shift(); 911 return null; 912 } 913 914 function removeCookie(name) { 915 document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`; 916 } 917 918 function showReferralNotification() { 919 const referralCode = getCookie('customer_referral_code'); 920 921 922 const customerReferralCode = null; 923 924 925 const activeReferralCode = referralCode || customerReferralCode; 926 const referralData = JSON.parse(localStorage.getItem('referral_notification_data')) || {}; 927 928 if (referralData.timestamp && referralData.expirationDays) { 929 const expirationTime = referralData.timestamp + (referralData.expirationDays * 24 * 60 * 60 * 1000); 930 if (Date.now() > expirationTime) { 931 localStorage.removeItem('referral_notification_data'); 932 return; 933 } 934 } 935 936 if (referralData.dismissed) return; 937 938 if (activeReferralCode) { 939 if (referralData.creditAmount) { 940 displayReferralNotification(referralData.creditAmount); 941 } else { 942 fetchReferralCampaignData(activeReferralCode); 943 } 944 } 945 } 946 947 function fetchReferralCampaignData(referralCode) { 948 fetch(`/customer/referral_program/campaigns/${referralCode}`) 949 .then(response => { 950 if (!response.ok) { 951 throw new Error('Network response was not ok'); 952 } 953 return response.json(); 954 }) 955 .then(data => { 956 let refereeCreditAmount = null; 957 if (data.data.campaign && data.data.campaign.referral_rules) { 958 const refereeRule = data.data.campaign.referral_rules.find(rule => 959 rule.target_type === 'referee' && 960 rule.event_name === 'customer/create' && 961 rule.entitlement && 962 rule.entitlement.type === 'credit' 963 ); 964 965 if (refereeRule) { 966 refereeCreditAmount = refereeRule.entitlement.amount; 967 } 968 } 969 970 const referralData = JSON.parse(localStorage.getItem('referral_notification_data')) || {}; 971 referralData.creditAmount = refereeCreditAmount; 972 referralData.dismissed = referralData.dismissed || false; 973 referralData.timestamp = Date.now(); 974 referralData.expirationDays = 3; 975 localStorage.setItem('referral_notification_data', JSON.stringify(referralData)); 976 977 displayReferralNotification(refereeCreditAmount); 978 }) 979 .catch(error => { 980 removeCookie('customer_referral_code'); 981 }); 982 } 983 984 function displayReferralNotification(creditAmount = null) { 985 const isMobile = innerWidth <= 749; 986 987 if (isMobile) { 988 const mobileModal = document.querySelector('#referralMobileModal details'); 989 const mobileMessageElement = document.getElementById('referralSignupMessageMobile'); 990 991 if (mobileModal && mobileMessageElement) { 992 if (creditAmount) { 993 const finalMessage = referralMessageTemplate 994 .replace('__CREDIT_AMOUNT__', creditAmount) 995 .replace('__CURRENCY_CODE__', shopPrefix); 996 997 mobileMessageElement.textContent = finalMessage; 998 } 999 1000 mobileModal.setAttribute('open', ''); 1001 } 1002 } else { 1003 const notification = document.getElementById('referralNotification'); 1004 1005 if (notification) { 1006 if (creditAmount) { 1007 const messageElement = document.getElementById('referralSignupMessage'); 1008 if (messageElement) { 1009 const finalMessage = referralMessageTemplate 1010 .replace('__CREDIT_AMOUNT__', creditAmount) 1011 .replace('__CURRENCY_CODE__', shopPrefix); 1012 1013 messageElement.textContent = finalMessage; 1014 } 1015 } 1016 1017 notification.style.display = 'block'; 1018 } 1019 } 1020 } 1021 1022 showReferralNotification(); 1023 1024 addEventListener('beforeunload', function() { 1025 const referralData = JSON.parse(localStorage.getItem('referral_notification_data')) || {}; 1026 1027 if (referralData.creditAmount !== undefined) { 1028 referralData.creditAmount = null; 1029 localStorage.setItem('referral_notification_data', JSON.stringify(referralData)); 1030 } 1031 }); 1032 1033 function closeReferralNotification() { 1034 const notification = document.getElementById('referralNotification'); 1035 if (notification) { 1036 notification.style.display = 'none'; 1037 } 1038 } 1039 1040 function dismissReferralNotification() { 1041 const referralData = JSON.parse(localStorage.getItem('referral_notification_data')) || {}; 1042 1043 referralData.dismissed = true; 1044 referralData.timestamp = referralData.timestamp || Date.now(); 1045 referralData.expirationDays = referralData.expirationDays || 3; 1046 1047 localStorage.setItem('referral_notification_data', JSON.stringify(referralData)); 1048 1049 closeReferralNotification(); 1050 } 1051 1052 function goToSignupPage() { 1053 location.href = '/account/register'; 1054 dismissReferralNotification(); 1055 } 1056 1057 function closeMobileReferralModal() { 1058 const mobileModal = document.querySelector('#referralMobileModal details'); 1059 if (mobileModal) { 1060 mobileModal.removeAttribute('open'); 1061 } 1062 1063 const referralData = JSON.parse(localStorage.getItem('referral_notification_data')) || {}; 1064 referralData.dismissed = true; 1065 referralData.timestamp = referralData.timestamp || Date.now(); 1066 referralData.expirationDays = referralData.expirationDays || 3; 1067 localStorage.setItem('referral_notification_data', JSON.stringify(referralData)); 1068 } 1069 1070 function goToSignupPageFromMobile() { 1071 location.href = '/account/register'; 1072 closeMobileReferralModal(); 1073 } 1074 // End - referral notification popup 1075</script>
1075 1076 1077 <header class="site-header" role="banner"> 1078 1079 <div class="wrapper"> 1080 1081 1082 1083 <div class="grid--full large--display-table"> 1084 <div class="grid__item large--one-third large--display-table-cell"> 1085 1086 <div class="h1 site-header__logo large--left" itemscope itemtype="http://schema.org/Organization"> 1087 1088 1089 <a href="/" class="logo-wrapper" itemprop="url"> 1090 <img src="https://cdn.store-assets.com/s/396414/f/5219718.png?width=350&format=webp" alt="PA | Peeos Aquatic" itemprop="logo"> 1091 </a> 1092 1093 1094 </div> 1095 1096 1097 <p class="header-message large--hide"> 1098 <small></small> 1099 </p> 1100 1101 </div> 1102 <div class="grid__item large--two-thirds large--display-table-cell medium-down--hide"> 1103 1104<ul class="site-nav large--text-center" id="AccessibleNav"> 1105 1106 1107 1108 <li > 1109 <a href="/" class="site-nav__link">Home</a> 1110 </li> 1111 1112 1113 1114 1115 1116 <li class="site-nav--has-dropdown" aria-haspopup="true"> 1117 <a href="/collections/all" class="site-nav__link"> 1118 Catagories 1119 <span class="icon-fallback-text"> 1120 <span class="icon icon-arrow-down" aria-hidden="true"></span> 1121 </span> 1122 </a> 1123 <ul class="site-nav__dropdown"> 1124 1125 1126 1127 <li > 1128 <a href="/collections/new-arrival" class="site-nav__link">New arrival</a> 1129 </li> 1130 1131 1132 1133 1134 <li > 1135 <a href="/collections/hot-selling" class="site-nav__link">Hot selling</a> 1136 </li> 1137 1138 1139 1140 1141 <li > 1142 <a href="/collections/aquarium" class="site-nav__link">Aquarium</a> 1143 </li> 1144 1145 1146 1147 1148 <li > 1149 <a href="/collections/lock" class="site-nav__link">Lock</a> 1150 </li> 1151 1152 1153 1154 1155 <li > 1156 <a href="/collections/fashion" class="site-nav__link">Bag</a> 1157 </li> 1158 1159 1160 1161 1162 <li > 1163 <a href="/collections/pet" class="site-nav__link">Pet</a> 1164 </li> 1165 1166 1167 1168 1169 <li > 1170 <a href="/collections/nano-technology" class="site-nav__link">Nano Technology</a> 1171 </li> 1172 1173 1174 1175 1176 <li > 1177 <a href="/collections/garden-agriculture" class="site-nav__link">Garden / Agriculture</a> 1178 </li> 1179 1180 1181 </ul> 1182 </li> 1183 1184 1185 1186 1187 <li > 1188 <a href="/blogs/news" class="site-nav__link">News</a> 1189 </li> 1190 1191 1192 1193 1194 <li > 1195 <a href="/store-locator" class="site-nav__link">Contact Us</a> 1196 </li> 1197 1198 1199 1200 1201 <li > 1202 <a href="https://peeosaquatic.com/apps/contact-form-plus" class="site-nav__link">Warranty Registration</a> 1203 </li> 1204 1205 1206 1207</ul> 1208 </div> 1209 </div> 1210 1211 1212 1213 </div> 1214 </header> 1215 1216 <main class="wrapper main-content" role="main"> 1217 <div class="grid"> 1218 <div class="grid__item">
vendor: 97 bytes, lines 1218-1222
1218 1219 1220 1221 1222<script src="https://www.recaptcha.net/recaptcha/enterprise.js?render=
12226LdMNdIqAAAAALegJp7y4weVcCIlnwmIN8TWseEF
vendor: 12 bytes, line 1222
1222"></script>
1223<link rel="preload" href="https://store-themes.easystore.co/396414/themes/4/assets/customer.css?t=1787076067" as="style" onload="this.onload=null;this.rel='stylesheet'"> 1224<style> 1225 main.main-content .field > label{ 1226 display: none; 1227 } 1228 .h3{ 1229 font-size: 18px; 1230 } 1231 .button--full-width{ 1232 width: 100%; 1233 } 1234 .tab-wrapper{ 1235 display: inline-flex; 1236 justify-content: center; 1237 align-items: center; 1238 margin: 10px auto 20px; 1239 background-color: #eaeaea; 1240 border-radius: 200px; 1241 padding: 5px; 1242 gap: 10px; 1243 } 1244 .tab-wrapper .tab-label { 1245 display: inline-block; 1246 min-width: 130px; 1247 padding: 8px 15px; 1248 border-radius: 100px; 1249 cursor: pointer; 1250 font-size: 17px; 1251 line-height: 1.1; 1252 user-select: none; 1253 margin: 0; 1254 color: #000; 1255 } 1256 #register-tos a { 1257 display: inline; 1258 } 1259 @media screen and (max-width: 400px){ 1260 .tab-wrapper .tab-label { 1261 min-width: 110px; 1262 } 1263 } 1264 .tab-wrapper input[type='radio']:checked + .tab-label { 1265 background-color: #fff; 1266 box-shadow: 2px 2px 25px -10px #333; 1267 } 1268 1269 @media screen and (min-width: 500px){ 1270 .large--five-twelfths{ 1271 min-width: 420px; 1272 } 1273 } 1274</style> 1275 1276 1277 1278 1279<div class="customer login section-width-control small-width large--five-twelfths text-center wrapper"> 1280 <div class="card"> 1281 <h1 id="login" tabindex="-1" class="mb-0"> 1282 Welcome 1283 </h1> 1284 <p class="h3 mt-0"> 1285 1286 Sign up or log in to continue 1287 1288 </p> 1289 <div> 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 <div class="tab-wrapper"> 1308 <div> 1309 <input type="radio" name="type" id="tab-register" class="hide hidden" checked> 1310 <label for="tab-register" class="tab-label"> 1311 Sign up 1312 </label> 1313 </div> 1314 <div> 1315 <input type="radio" name="type" id="tab-login" class="hide hidden"> 1316 <label for="tab-login" class="tab-label"> 1317 Login 1318 </label> 1319 </div> 1320 </div> 1321 1322 1323 <form id="form-login" action="/account/auth" method="post" class="mt-2"> 1324 <input type="hidden" name="_token" value="rn3KVEC8D8eQbFCquuj9KxbJbXA8R7SqtYnkOM0d"> 1325 <input type="hidden" name="location_id" value=""> 1326 <input type="hidden" name="staff_id" value=""> 1327 <input type="hidden" id="recaptchaResponse" name="g-recaptcha-response"> 1328 1329 1330 <div id="error-content"></div> 1331 1332 <div class="field"> 1333 <input 1334 type="text" 1335 name="customer[email_or_phone]" 1336 id="CustomerDetail" 1337 autocorrect="off" 1338 autocapitalize="off" 1339 placeholder="Email" 1340 required 1341 > 1342 <label for="CustomerDetail"> 1343 Email 1344 </label> 1345 </div> 1346 1347 <button 1348 type="submit" 1349 form="form-login" 1350 class="btn button--full-width g-recaptcha"> 1351 Continue 1352 </button> 1353 1354 <div class="button-snippet"> 1355 1356<!-- Snippet:login/button: Facebook Login --> 1357 <style> 1358 #fb-login-btn.btn{ 1359 background-color: #fff; 1360 color: #000; 1361 padding: 0; 1362 overflow: hidden; 1363 display: flex; 1364 justify-content: center; 1365 align-items: center; 1366 width: 100%; 1367 margin: 15px auto; 1368 font-size: 14px; 1369 border: 1px solid currentColor; 1370 box-shadow: none; 1371 } 1372 #fb-login-btn.btn:hover{ 1373 background-color: #fff; 1374 } 1375 #fb-login-btn.btn svg{ 1376 width: 45px; 1377 vertical-align: middle; 1378 padding: 5px; 1379 } 1380 #fb-login-btn.btn .fb-login-text{ 1381 padding: 13px 75px 13px 30px; 1382 display: inline-block; 1383 width: calc(100% - 52px); 1384 } 1385 @media screen and (max-width: 500px) { 1386 #fb-login-btn.btn .fb-login-text{ 1387 padding: 13px 25px 13px 8px; 1388 font-size: 13px; 1389 } 1390 } 1391 </style> 1392 <button id="fb-login-btn" type="button" class="btn" onclick="fb_login()" style="background-color: #fff; color: #000; font-weight: normal;"> 1393 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 700"><g><path d="M650,350C650,184.32,515.68,50,350,50S50,184.32,50,350c0,140.69,96.86,258.74,227.53,291.17V441.68H215.66V350h61.87V310.5c0-102.11,46.2-149.44,146.4-149.44,19,0,51.81,3.72,65.22,7.45V251.6c-7.08-.74-19.38-1.12-34.65-1.12-49.2,0-68.2,18.64-68.2,67.08V350h98.1l-16.8,91.68H386.35V647.8C534.88,629.86,650,503.38,650,350Z" fill="#0866ff"/><path d="M467.5,441.68,484.4,350h-98V317.6c0-48.44,19-67.08,68.19-67.08,15.28,0,27.6.37,34.66,1.12V168.51c-13.42-3.73-46.21-7.45-65.22-7.45-100.25,0-146.4,47.33-146.4,149.44V350H2
139315.66v91.68h61.87V641.17a301.61,301.61,0,0,0,108.82,6.63V441.68Z" fill="#fff"/></g></svg> 1394 <span class="fb-login-text">Continue with Facebook</span> 1395 </button> 1396 1397
1397<script> 1398 function fb_login(){ 1399 location.href = 'https://apps.easystore.co/facebook-login/run?domain='+window.location.protocol+'//'+window.location.hostname+'&shop=peeoszheng.easy.co'; 1400 } 1401 </script>
1401 1402<!-- /Snippet --> 1403 1404 </div> 1405 1406 1407 1408 <div id="register-tos"> 1409 By signing up, I agree to the PA | Peeos Aquatic's <a target="_blank" href="/legal/terms-of-service">Terms of Service</a>, <a target="_blank" href="/legal/privacy-policy">Privacy Policy</a>, <a target="_blank" href="/legal/refund-policy">Refund Policy</a>, <a target="_blank" href="/pages/delivery-policy">Delivery Policy</a> and <a target="_blank" href="/pages/zegwei-hotmail-com">[email protected]</a>. 1410 </div> 1411 1412 </form> 1413 </div> 1414 </div> 1415 1416</div> 1417 1418 1419
1420<script> 1421 const register_tab = document.querySelector('#tab-register'); 1422 const login_tab = document.querySelector('#tab-login'); 1423 const register_tos = document.querySelector('#register-tos'); 1424 const isRegistrationEnabled = "1"; 1425 1426 if (register_tab) { 1427 register_tab.addEventListener('click', function() { 1428 if (register_tos) { 1429 register_tos.style.display = 'block'; 1430 } 1431 }); 1432 } 1433 if (login_tab) { 1434 login_tab.addEventListener('click', function() { 1435 if (register_tos) { 1436 register_tos.style.display = 'none'; 1437 } 1438 }); 1439 } 1440 1441 const methodSwitchBtn = document.getElementById('phone-login-btn'); 1442 if (methodSwitchBtn) { 1443 methodSwitchBtn.onclick = function () { 1444 var type = (register_tab && register_tab.checked) ? 'register' : 'login'; 1445 window.location.href = '/account/login?method=phone&type=' + type; 1446 }; 1447 } 1448 1449 let lastPathSegment = window.location.pathname.split('/').filter(segment => segment.length > 0).pop(); 1450 1451 // Redirect to login if trying to access register when self registration is disabled 1452 if (!isRegistrationEnabled) { 1453 if (lastPathSegment === 'register') { 1454 window.location.href = '/account/login'; 1455 } else if (lastPathSegment === 'login' || lastPathSegment === 'auth') { 1456 if (register_tos) { 1457 register_tos.style.display = 'none'; 1458 } 1459 } 1460 } else { 1461 // Only proceed with tab logic if not redirecting 1462 if(lastPathSegment === 'login') { 1463 if (login_tab) { 1464 login_tab.checked = true; 1465 } 1466 if (register_tos) { 1467 register_tos.style.display = 'none'; 1468 } 1469 } else { 1470 if (register_tos) { 1471 register_tos.style.display = 'block'; 1472 } 1473 } 1474 } 1475 1476 const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; 1477 const phonePattern = /^(?:\+?\d{1,3}[\s-]?)?(?:\d{1,14}[\s-]?){1,5}$/; 1478 1479 let form = document.querySelector('#form-login'), 1480 input = document.querySelector('#CustomerDetail'), 1481 error_content = document.querySelector('#error-content'); 1482 1483 1484 // One attempt at a time: the reCAPTCHA wait below is async, so without 1485 // this a double-click starts two continuations and posts the form twice. 1486 var submitting = false; 1487 1488 form.addEventListener('submit', async function (event) { 1489 // preventDefault FIRST: a re-entrant submit must still be cancelled, or the 1490 // browser performs a native post with no captcha token. 1491 event.preventDefault(); 1492 if (submitting) return; 1493 1494 let input_value = input.value 1495 error_content.innerHTML = ''; 1496 if (!input_value.match(emailPattern) && !input_value.match(phonePattern)) { 1497 error_content.innerHTML = `<div class="errors note">Invalid Email or Phone</div>`; 1498 return false; 1499 } 1500 1501 submitting = true; 1502 document.querySelector('#form-login .btn').classList.add('btn--loading','loading'); 1503 1504 // reCAPTCHA is unreachable from some regions (google.com is blocked in 1505 // mainland China). Fail open the same way checkout and forgot-password do: 1506 // submit without a token rather than leave the button spinning forever. 1507 try { 1508 if (window.grecaptcha && typeof window.grecaptcha.enterprise === 'object') { 1509 // The loader defines a stub {ready} synchronously and fetches the real 1510 // implementation asynchronously, so execute() may not exist yet. 1511 // ready() queues until it does; the timeout stops a bundle that never 1512 // arrives from hanging the button. 1513 await new Promise(function (resolve) { 1514 setTimeout(resolve, 3000); 1515 try { grecaptcha.enterprise.ready(resolve); } catch (e) { resolve(); } 1516 }); 1517 1518 const token = await grecaptcha.enterprise.execute('6LdMNdIqAAAAALegJp7y4weVcCIlnwmIN8TWseEF', { action: 'LOGIN' }); 1519 document.getElementById('recaptchaResponse').value = token; 1520 } 1521 } catch (e) { /* fail open */ } 1522 1523 document.getElementById('form-login').submit(); 1524 }); 1525 1526 1527</script>
1527 1528 1529 1530 1531 </div> 1532 </div> 1533 1534 </main> 1535 1536 <footer class="site-footer small--text-center" role="contentinfo"> 1537 1538 <div class="wrapper"> 1539 1540 <div class="grid-uniform"> 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 <div class="grid__item large--one-half medium--one-half"> 1563 1564 <h4>Quick Links</h4> 1565 1566 <ul class="site-footer__links"> 1567 1568 <li><a href="/store-locator" >Contact Us</a></li> 1569 1570 <li><a href="/a/contact-form" >Email Us</a></li> 1571 1572 <li><a href="/pages/easyparcel-widgets" >EasyParcel Widgets</a></li> 1573 1574 1575 </ul> 1576 </div> 1577 1578 1579 1580 <div class="grid__item large--one-half medium--one-half"> 1581 <h4>Follow Us</h4> 1582 1583 <ul class="inline-list social-icons"> 1584 1585 <li> 1586 <a class="icon-fallback-text" href="https://twitter.com/" title="PA | Peeos Aquatic on Twitter" target="_blank"> 1587 <span class="icon icon-twitter" aria-hidden="true"></span> 1588 <span class="fallback-text">Twitter</span> 1589 </a> 1590 </li> 1591 1592 1593 <li> 1594 <a class="icon-fallback-text" href="https://www.facebook.com/peeosaquatic" title="PA | Peeos Aquatic on Facebook" target="_blank"> 1595 <span class="icon icon-facebook" aria-hidden="true"></span> 1596 <span class="fallback-text">Facebook</span> 1597 </a> 1598 </li> 1599 1600 1601 <li> 1602 <a class="icon-fallback-text" href="https://www.pinterest.com/" title="PA | Peeos Aquatic on Pinterest" target="_blank"> 1603 <span class="icon icon-pinterest" aria-hidden="true"></span> 1604 <span class="fallback-text">Pinterest</span> 1605 </a> 1606 </li> 1607 1608 1609 <li> 1610 <a class="icon-fallback-text" href="https://plus.google.com/" title="PA | Peeos Aquatic on Google Plus" rel="publisher" target="_blank"> 1611 <span class="icon icon-google_plus" aria-hidden="true"></span> 1612 <span class="fallback-text">Google</span> 1613 </a> 1614 </li> 1615 1616 1617 <li> 1618 <a class="icon-fallback-text" href="https://instagram.com/" title="PA | Peeos Aquatic on Instagram" target="_blank"> 1619 <span class="icon icon-instagram" aria-hidden="true"></span> 1620 <span class="fallback-text">Instagram</span> 1621 </a> 1622 </li> 1623 1624 1625 <li> 1626 <a class="icon-fallback-text" href="https://www.tumblr.com/" title="PA | Peeos Aquatic on Tumblr" target="_blank"> 1627 <span class="icon icon-tumblr" aria-hidden="true"></span> 1628 <span class="fallback-text">Tumblr</span> 1629 </a> 1630 </li> 1631 1632 1633 <li> 1634 <a class="icon-fallback-text" href="https://www.youtube.com/" title="PA | Peeos Aquatic on YouTube" target="_blank"> 1635 <span class="icon icon-youtube" aria-hidden="true"></span> 1636 <span class="fallback-text">YouTube</span> 1637 </a> 1638 </li> 1639 1640 1641 <li> 1642 <a class="icon-fallback-text" href="https://vimeo.com/" title="PA | Peeos Aquatic on Vimeo" target="_blank"> 1643 <span class="icon icon-vimeo" aria-hidden="true"></span> 1644 <span class="fallback-text">Vimeo</span> 1645 </a> 1646 </li> 1647 1648 1649 1650</ul> 1651 1652 </div> 1653 1654 </div> 1655 1656 <hr class="hr--small hr--clear"> 1657 1658 1659 <div class="grid"> 1660 1661 1662 <div class="grid__item text-center"> 1663 <ul class="inline-list payment-icons"> 1664 1665 <li> 1666 <img src="https://s3.dualstack.ap-southeast-1.amazonaws.com/eesb.public/images/payment/payments_ipay88.svg" alt="payment_ipay88"> 1667 </li> 1668 1669 <li> 1670 <img src="https://s3.dualstack.ap-southeast-1.amazonaws.com/eesb.public/images/payment/payments_m2upay.svg" alt="payment_m2upay"> 1671 </li> 1672 1673 </ul> 1674 </div> 1675 1676 1677 </div> 1678 1679 1680 <div class="grid"> 1681 <div class="grid__item text-center"> 1682 <p class="site-footer__links">© 2026 Peeos Aquatic</p> 1683 1684 <p class="site-footer__links"> 1685 1686 1687 1688 <a href="/legal/terms-of-service">Terms of Service</a> 1689 1690 1691 1692 1693 | <a href="/legal/privacy-policy">Privacy Policy</a> 1694 1695 1696 1697 1698 | <a href="/legal/refund-policy">Refund Policy</a> 1699 1700 1701 1702 1703 | <a href="/pages/delivery-policy">Delivery Policy</a> 1704 1705 1706 1707 1708 | <a href="/pages/zegwei-hotmail-com">[email protected]</a> 1709 1710 1711 1712 </p> 1713 1714 </div> 1715 </div> 1716 1717 </div> 1718 </footer> 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737
1737<script src="https://store-themes.easystore.co/396414/themes/4/assets/jquery.flexslider.min.js?t=1787076067" type="text/javascript" ></script>
1737 1738 1739 1740 <!-- Testing slick slider --> 1741 <!--
1741<script type="text/javascript" src="//cdn.jsdelivr.net/jquery.slick/1.5.9/slick.min.js"></script>
1741 --> 1742 1743
1743<script type="text/javascript"> 1744 // $(document).ready(function(){ 1745 // $('.flexslider .slides').slick({ 1746 // dots: true 1747 // }); 1748 // }); 1749 1750 window.timberSlider = window.timberSlider || {}; 1751 1752 timberSlider.cacheSelectors = function () { 1753 timberSlider.cache = { 1754 // Home Page 1755 $slider: $('.flexslider') 1756 } 1757 }; 1758 1759 timberSlider.init = function () { 1760 timberSlider.cacheSelectors(); 1761 timberSlider.sliders(); 1762 }; 1763 1764 timberSlider.sliders = function () { 1765 var $slider = timberSlider.cache.$slider, 1766 sliderArgs = { 1767 animation: 'slide', 1768 animationSpeed: 500, 1769 pauseOnHover: true, 1770 keyboard: false, 1771 slideshow: 1, 1772 slideshowSpeed: 3000, 1773 controlNav: 1, 1774 smoothHeight: false, 1775 touch: true, 1776 }; 1777 1778 if ($slider.length) { 1779 1780 if ($slider.find('li').length === 1) { 1781 sliderArgs.slideshow = false; 1782 sliderArgs.slideshowSpeed = 0; 1783 sliderArgs.controlNav = false; 1784 sliderArgs.directionNav = false; 1785 } 1786 1787 $slider.flexslider(sliderArgs); 1788 } 1789 }; 1790 1791 // Initialize slider on docready 1792 $(window).on('load', function() { 1793 timberSlider.init(); 1794 }); 1795 1796 </script>
1796 1797 1798 1799
1799<script src="https://store-themes.easystore.co/396414/themes/4/assets/fastclick.min.js?t=1787076067" type="text/javascript" ></script>
1799 1800
1800<script src="https://store-themes.easystore.co/396414/themes/4/assets/timber.js?t=1787076067" type="text/javascript" ></script>
1800 1801
1801<script src="https://store-themes.easystore.co/396414/themes/4/assets/theme.js?t=1787076067" type="text/javascript" ></script>
1801 1802 1803 1804 1805 1806 1807 1808
1809<script src="/assets/currencies.js" type="text/javascript" ></script>
vendor: 2 bytes, line 1809
1809
1810<script src="/assets/jquery.currencies.min.js" type="text/javascript" ></script>
vendor: 2 bytes, line 1810
1810
1811<script src="/assets/currencies_format.js" type="text/javascript" ></script>
1811 1812
1813<script> 1814Currency.format = "money_with_currency_format"; 1815var shopCurrency = 'MYR'; 1816var selectedCurrency = ''; 1817 1818 1819 Currency.convert = function(amount, from, to) { 1820 return amount; 1821 }; 1822 1823 1824if( $.cookie("currency") == null ){ 1825 1826 if( selectedCurrency != false ) { 1827 1828 Currency.convertAll(shopCurrency, selectedCurrency); 1829 jQuery('.selected-currency').text(Currency.currentCurrency); 1830 1831 } 1832 1833} 1834 1835/* Sometimes merchants change their shop currency, let's tell our JavaScript file */ 1836// Currency.moneyFormats[shopCurrency].money_with_currency_format = ""; 1837// Currency.moneyFormats[shopCurrency].money_format = "RM {{amount}} "; 1838 1839/* Default currency */ 1840var defaultCurrency = 'MYR'; 1841 1842/* Cookie currency */ 1843var cookieCurrency = Currency.cookie.read(); 1844 1845 cookieCurrency = shopCurrency; 1846 1847$("input[name=current_currency]").val(cookieCurrency); 1848if(cookieCurrency == null){ 1849 cookieCurrency = shopCurrency; 1850 Currency.cookie.write(shopCurrency); 1851} 1852/* Fix for customer account pages */ 1853jQuery('span.money span.money').each(function() { 1854 jQuery(this).parents('span.money').removeClass('money'); 1855}); 1856/* Saving the current price */ 1857jQuery('span.money').each(function() { 1858 jQuery(this).attr('data-currency-MYR', jQuery(this).html()); 1859}); 1860// If there's no cookie. 1861if (cookieCurrency == null) { 1862 if (shopCurrency !== defaultCurrency) { 1863 Currency.convertAll(shopCurrency, defaultCurrency); 1864 } 1865 else { 1866 Currency.currentCurrency = defaultCurrency; 1867 } 1868} 1869// If the cookie value does not correspond to any value in the currency dropdown. 1870else if (jQuery('[name=currencies]').size() && jQuery('[name=currencies] option[value=' + cookieCurrency + ']').size() === 0) { 1871 Currency.currentCurrency = shopCurrency; 1872 Currency.cookie.write(shopCurrency); 1873} 1874else if (cookieCurrency === shopCurrency) { 1875 Currency.currentCurrency = shopCurrency; 1876 Currency.convertAll(shopCurrency, cookieCurrency); 1877} 1878else { 1879 Currency.convertAll(shopCurrency, cookieCurrency); 1880} 1881jQuery('[name=currencies]').val(Currency.currentCurrency).change(function() { 1882 var newCurrency = jQuery(this).val(); 1883 1884 1885 Currency.cookie.write(newCurrency) 1886 if ('customers' == 'cart') { 1887 const params = new URLSearchParams(window.location.search); 1888 params.set('delete_cache', 1); 1889 window.location.search = params; 1890 } else { 1891 window.location.reload(); 1892 } 1893 1894}); 1895var original_selectCallback = window.selectCallback; 1896var selectCallback = function(variant, selector) { 1897 var currencies = null; 1898 original_selectCallback(variant, selector); 1899 if(typeof jQuery('[name=currencies]').val() == "undefined"){ 1900 currencies = shopCurrency; 1901 } 1902 else{ 1903 currencies = jQuery('[name=currencies]').val(); 1904 } 1905 Currency.convertAll(shopCurrency, currencies); 1906 jQuery('.selected-currency').text(Currency.currentCurrency); 1907}; 1908$('body').on('ajaxCart.afterCartLoad', function(cart) { 1909 Currency.convertAll(shopCurrency, jQuery('[name=currencies]').val()); 1910 jQuery('.selected-currency').text(Currency.currentCurrency); 1911}); 1912jQuery('.selected-currency').text(Currency.currentCurrency); 1913</script>
1913 1914 1915
1916<script> 1917 1918 /* 1919 1920 ------ 1921 Events 1922 ------ 1923 1924 pages/viewed 1925 1926 customers/signup 1927 1928 customers/login 1929 1930 products/searched 1931 1932 collections/viewed 1933 1934 products/viewed 1935 1936 products/shared 1937 1938 wishlists/item_added 1939 1940 carts/items_added 1941 1942 carts/viewed 1943 1944 carts/item_removed 1945 1946 checkouts/initiated 1947 1948 checkouts/shipping_info_added 1949 1950 checkouts/payment_info_added 1951 1952 checkouts/completed 1953 1954 orders/placed 1955 1956 orders/purchased 1957 1958 payments/captured 1959 1960 payments/failed 1961 1962 */ 1963 1964 window.__latest_cart = window.__latest_cart || null; 1965 1966 const _selector = document.querySelector.bind(document), 1967 _selectorAll = document.querySelectorAll.bind(document) 1968 1969 document.addEventListener('DOMContentLoaded', (event) => { 1970 1971 const default_currency = getCookie("currency") 1972 const customer_id = window.__st.cid 1973 const template = window.__st.p 1974 1975 onPageView() 1976 1977 //-----------------------// 1978 // Configs // 1979 //-----------------------// 1980 1981 window.dataLayer = window.dataLayer || [] 1982 1983 Array.prototype.last = Array.prototype.last || function() { 1984 return this[this.length - 1] || null 1985 } 1986 1987 Array.prototype.first = Array.prototype.first || function() { 1988 return this[0] || null 1989 } 1990 1991 //----------------------// 1992 // Triggers // 1993 //----------------------// 1994 1995 const XHR = window.XMLHttpRequest 1996 1997 function xhr() { 1998 1999 const xhr = new XHR() 2000 2001 xhr.addEventListener("readystatechange", function() { 2002 2003 if(xhr.readyState != 4) return 2004 2005 try { 2006 2007 const response_url = xhr.responseURL 2008 2009 if (response_url.includes("cart/add")) { 2010 2011 window.__latest_cart = JSON.parse(xhr.response) 2012 2013 onCartItemsAdded() // ok 2014 2015 } 2016 2017 if (response_url.includes("cart/remove_item_quantity")) { 2018 2019 window.__latest_cart = JSON.parse(xhr.response) 2020 2021 onCartItemRemoved() // ok 2022 2023 } 2024 2025 if (response_url.includes("new_cart?retrieve=true")) { 2026 2027 result = JSON.parse(xhr.response) 2028 2029 if (result.cart) { 2030 window.__latest_cart = result.cart 2031 } 2032 2033 } 2034 2035 } catch(e) { 2036 2037 console.error(e) 2038 2039 } 2040 2041 }, false); 2042 2043 return xhr 2044 2045 } 2046 2047 window.XMLHttpRequest = xhr 2048 2049 switch(template) { 2050 2051 case 'cart': onCartView() // ok 2052 break 2053 case 'product': onProductView() // ok 2054 break 2055 case 'collection': onCollectionView() // ok 2056 break 2057 case 'blog': onBlogView() 2058 break 2059 case 'article': onArticleView() 2060 break 2061 case 'payment_completed': onOrderPlace() 2062 break 2063 case 'payment_fail': onPaymentFail() 2064 break 2065 2066 } 2067 2068 // _selector('form[action="/checkout/payments"]').addEventListener("submit", onPaymentInfoAdded(_selector('form[action="/checkout/payments"]'))) 2069 if (_selector('form[action="/checkout/detail"]')) _selector('form[action="/checkout/detail"]').addEventListener("submit", ()=>{onShippingInfoAdded(_selector('form[action="/checkout/detail"]'))}) // ok 2070 if (_selector('form[action="/checkout/shipping"]')) _selector('form[action="/checkout/shipping"]').addEventListener("submit", ()=>{onShippingInfoAdded(_selector('form[action="/checkout/shipping"]'))}) // ok 2071 if (_selector('form[action="/account/register"]')) _selector('form[action="/account/register"]').addEventListener("submit", onSignUp) // ok 2072 if (_selector('form[action="/account/login"]')) _selector('form[action="/account/login"]').addEventListener("submit", onLogin) // ok 2073 if (_selector('form[action="/search"]')) _selector('form[action="/search"]').addEventListener("submit", onProductSearch()) // ok 2074 if (_selector('#line-login-btn')) _selector('#line-login-btn').addEventListener('click', onLineLogin) // ok 2075 if (_selector('#PlaceOrder')) _selector('#PlaceOrder').addEventListener("click", ()=>{onCheckoutComplete(_selector('form[action="/checkout/payments"]'))}); // ok 2076 if (_selector('#add_wishlist')) _selector('#add_wishlist').addEventListener("click", onWishlistItemAdded) // ok 2077 if (_selectorAll('a[href="/account/logout"]')) _selectorAll('a[href="/account/logout"]').forEach(logoutButton => logoutButton.addEventListener("click", onLogout)) // ok 2078 if (_selector('.CartDrawerTrigger.cart-page-link')) _selector('.CartDrawerTrigger.cart-page-link').addEventListener("click", onCartView) // ok 2079 if (_selector('.CartDrawerTrigger.cart-page-link.mobile-cart-page-link')) _selector('.CartDrawerTrigger.cart-page-link.mobile-cart-page-link').addEventListener("click", onCartView) // ok 2080 if (_selectorAll('a[class^="share-"]')) _selectorAll('a[class^="share-"]').forEach(shareButton => shareButton.addEventListener("click", ()=>{onProductShare(shareButton)}) ) // ok 2081 if (_selectorAll('[name$="checkout"]')) _selectorAll('[name$="checkout"]').forEach(checkoutButton => checkoutButton.addEventListener("click", onCheckoutInitiate)) 2082 2083 // For append elements 2084 const bodyMutationObserver = new MutationObserver(() => { 2085 if (_selector('#form__spc #PlaceOrder')) _selector('#form__spc #PlaceOrder').addEventListener("click", onSinglePageCheckout) // ok 2086 if (_selectorAll('[name$="checkout"]')) _selectorAll('[name$="checkout"]').forEach(checkoutButton => checkoutButton.addEventListener("click", onCheckoutInitiate)) 2087 }); 2088 bodyMutationObserver.observe(_selector("body"), {subtree: true, childList: true}); 2089 2090 //------------------------------// 2091 // Event handlers // 2092 //------------------------------// 2093 2094 function onPageView() { 2095 2096 EasyStore.Event.dispatch('pages/viewed', { 2097 page: { 2098 type: template, 2099 title: document.title, 2100 description: _selector('meta[name=description]') ? _selector('meta[name=description]').getAttribute('content') : null, 2101 url: location.href, 2102 } 2103 }) 2104 2105 } 2106 2107 function onSignUp() { 2108 2109 const email_regex = new RegExp(/^[a-zA-Z0-9.!#$%&"*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/) 2110 const phone_regex = new RegExp(/^(\+?6?01)[0-46-9]-*[0-9]{7,8}$/) 2111 2112 const email_or_phone = _selector(`input[name="customer[email_or_phone]"]`).value.replace("+", "").replace(/\s+/, "") 2113 2114 let data = {} 2115 2116 if (email_regex.test(email_or_phone)) { 2117 data.method = 'email' 2118 data.email = email_or_phone 2119 } 2120 2121 if (phone_regex.test(email_or_phone)) { 2122 data.method = "phone" 2123 data.phone = email_or_phone 2124 } 2125 2126 if (!data.method) return 2127 2128 EasyStore.Event.dispatch('customers/signup', data) 2129 2130 } 2131 2132 function onLogin() { 2133 2134 const email_regex = new RegExp(/^[a-zA-Z0-9.!#$%&"*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/) 2135 const phone_regex = new RegExp(/^(\+?6?01)[0-46-9]-*[0-9]{7,8}$/) 2136 2137 const email_or_phone = _selector(`input[name="customer[email_or_phone]"]`).value.replace("+", "").replace(/\s+/, "") 2138 2139 let data = {} 2140 2141 if (email_regex.test(email_or_phone)) { 2142 data.method = 'email' 2143 data.email = email_or_phone 2144 } 2145 2146 if (phone_regex.test(email_or_phone)) { 2147 data.method = "phone" 2148 data.phone = email_or_phone 2149 } 2150 2151 if (!data.method) return 2152 2153 EasyStore.Event.dispatch('customers/login', data) 2154 2155 } 2156 2157 function onLineLogin() { 2158 2159 EasyStore.Event.dispatch('customers/login', { method: 'line' }) 2160 2161 } 2162 2163 function onLogout() { 2164 2165 EasyStore.Event.dispatch('customers/logout', { customer_id }) 2166 2167 } 2168 2169 function onBlogView() { 2170 2171 const blog = "" 2172 2173 EasyStore.Event.dispatch('blogs/viewed', { blog }) 2174 2175 } 2176 2177 function onArticleView() { 2178 2179 const article = "" 2180 2181 EasyStore.Event.dispatch('articles/viewed', { article }) 2182 2183 } 2184 2185 function onProductSearch() { 2186 2187 const query = _selector('input[name=q]').value 2188 2189 if (!query) return 2190 2191 EasyStore.Event.dispatch('products/searched', { query }) 2192 2193 } 2194 2195 function onCollectionView() { 2196 2197 const collection = "" 2198 2199 EasyStore.Event.dispatch('collections/viewed', { collection }) 2200 2201 } 2202 2203 function onProductView() { 2204 2205 const product = "" 2206 2207 EasyStore.Event.dispatch("products/viewed", { product }) 2208 2209 } 2210 2211 function onProductShare(el) { 2212 2213 const product = "" 2214 2215 const channel = el.getAttribute("class").split("-").last() 2216 2217 EasyStore.Event.dispatch('products/shared', { product, channel }) 2218 2219 } 2220 2221 function onWishlistItemAdded() { 2222 2223 let product = "" 2224 const quantity = _selector("#Quantity").value 2225 2226 EasyStore.Event.dispatch('wishlists/item_added', { product }) 2227 2228 } 2229 2230 async function onCartItemsAdded() { 2231 2232 const cart = await getCart() 2233 2234 if(cart && cart.items != undefined && cart.items.length > 0) { 2235 2236 EasyStore.Event.dispatch('carts/item_added', { cart }) 2237 2238 } 2239 2240 } 2241 2242 async function onCartView() { 2243 2244 const cart = await getCart() 2245 2246 EasyStore.Event.dispatch('carts/viewed', { cart }) 2247 2248 } 2249 2250 async function onCartItemRemoved() { 2251 2252 const cart = await getCart() 2253 2254 cart.items = [] 2255 2256 if(cart) { 2257 2258 EasyStore.Event.dispatch('carts/item_removed', { cart }) 2259 2260 } 2261 2262 } 2263 2264 async function onCheckoutInitiate() { 2265 2266 const cart = await getCart() 2267 2268 EasyStore.Event.dispatch('checkouts/initiated', { cart }) 2269 2270 } 2271 2272 async function onShippingInfoAdded(form) { 2273 let checkout = getCheckout() 2274 2275 let form_data = {} 2276 new FormData(form).forEach((value, key) => form_data[key] = value) 2277 2278 let shipping_tier = null 2279 2280 if (form_data.type && form_data.type.startsWith("r_pickup")) { 2281 shipping_tier = `Pickup - ${form_data.pick_location}` 2282 } 2283 2284 if (form_data.s_id) {
2285 shipping_tier = _selector(`input[id='`+form_data.s_id+`']`).getAttribute("data-shipping-name") 2286 } 2287 2288 if (!shipping_tier) return 2289 2290 EasyStore.Event.dispatch('checkouts/shipping_info_added', { checkout, shipping_tier }) 2291 2292 } 2293 2294 async function onPaymentInfoAdded(form) { 2295 2296 let checkout = getCheckout() 2297 2298 let payment_type = new FormData(form).get('payment_method') 2299 2300 EasyStore.Event.dispatch("checkouts/payment_info_added", { checkout, payment_type }) 2301 2302 } 2303 2304 async function onOrderPlace() { 2305 2306 let cart_token = getCookie("cart_js") 2307 let previous_cart_token = getCookie("previous_cart_ga4_js") 2308 2309 if (previous_cart_token && previous_cart_token == cart_token) { 2310 // Prevent duplicate purchase tracking 2311 return 2312 } 2313 2314 let order = getOrder() 2315 2316 EasyStore.Event.dispatch('orders/placed', { order }) 2317 2318 if(order.is_manual_payment) { 2319 2320 EasyStore.Event.dispatch('orders/purchased', { order }) 2321 2322 } 2323 2324 const last_transaction = order.transactions.last() 2325 2326 if (last_transaction.status) { 2327 2328 EasyStore.Event.dispatch('orders/purchased', { order }) 2329 EasyStore.Event.dispatch('payments/captured', { order }) 2330 2331 } 2332 2333 } 2334 2335 async function onPaymentFail() { 2336 2337 const order = getOrder() 2338 2339 EasyStore.Event.dispatch('payments/failed', { order }) 2340 2341 } 2342 2343 async function onCheckoutComplete(form) { 2344 2345 onPaymentInfoAdded(form) 2346 2347 const checkout = getCheckout() 2348 2349 EasyStore.Event.dispatch('checkouts/completed', { checkout }) 2350 2351 } 2352 2353 async function onSinglePageCheckout() { 2354 2355 // let checkout = $("[data-app-checkout]").data("app-checkout") 2356 2357 let checkout = getCheckout() 2358 2359 // const payment_type = _selector("#app_spc_payment_method").find(`[class*="label-content"]`).first().find("b").first().text() 2360 const payment_type = _selector("#app_spc_payment_method").getElementsByClassName('label-content')[0].getElementsByTagName('b')[0].innerHTML 2361 2362 const shipping_method = _selector("#delivery_method").value 2363 2364 let shipping_tier = null 2365 let app_spc_customer_info_label = _selector("#app_spc_customer_info").getElementsByClassName('label-content') 2366 if (shipping_method == "shipping") { 2367 shipping_tier = app_spc_customer_info_label[app_spc_customer_info_label.length - 1].getElementsByTagName('b')[0].innerHTML 2368 } 2369 2370 if (shipping_method == "pickup") { 2371 shipping_tier = app_spc_customer_info_label[0].innerHTML 2372 } 2373 2374 if (shipping_tier) { 2375 2376 EasyStore.Event.dispatch('checkouts/shipping_info_added', { 2377 checkout, 2378 shipping_tier, 2379 }) 2380 2381 } 2382 2383 if (payment_type) { 2384 2385 EasyStore.Event.dispatch('checkouts/payment_info_added', { 2386 checkout, 2387 payment_type, 2388 }) 2389 2390 } 2391 2392 EasyStore.Event.dispatch('checkouts/completed', { checkout }) 2393 2394 } 2395 2396 }) 2397 2398 2399 //-----------------------// 2400 // Functions // 2401 //-----------------------// 2402 2403 function getCookie(name) { 2404 2405 name += "=" 2406 2407 decodedCookie = decodeURIComponent(document.cookie) 2408 2409 ca = decodedCookie.split(";") 2410 2411 for(i = 0; i < ca.length; i++) { 2412 c = ca[i] 2413 while (c.charAt(0) == " ") { 2414 c = c.substring(1) 2415 } 2416 if (c.indexOf(name) == 0) { 2417 return c.substring(name.length, c.length) 2418 } 2419 } 2420 2421 return "" 2422 2423 } 2424 2425 const parsePrice = price => { 2426 if(typeof price === 'string') { 2427 return parseFloat(price.split(',').join('')) 2428 } 2429 2430 return price 2431 } 2432 2433 const requestCart = async (method, data) => { 2434 2435 let response = await fetch('/cart.json', {method: 'GET',headers: {'Content-Type': 'application/json'}}) 2436 result = await response.json() 2437 2438 return result.cart 2439 2440 } 2441 const getCart = async (latest = false) => { 2442 2443 let cart = window.__latest_cart 2444 2445 const cart_invalid = !cart || !cart.items || (cart.total_price > 0 && !cart.items.length) 2446 2447 if(latest || cart_invalid) { 2448 cart = await requestCart() 2449 } 2450 2451 cart.items = cart.items || [] 2452 2453 return mapCart(cart) 2454 2455 } 2456 2457 const getCheckout = async () => { 2458 mapCheckout(window.__latest_cart || await requestCart()) 2459 } 2460 2461 const getOrder = async () => { 2462 mapOrder(window.__latest_cart || await requestCart()) 2463 } 2464 2465 //-----------------------// 2466 // Mappers // 2467 //-----------------------// 2468 2469 const fallbackAttribute = (object, attribute) => { 2470 2471 if(!Array.isArray(attribute)) { 2472 attribute = [attribute] 2473 } 2474 2475 let final_value = null 2476 2477 do { 2478 2479 final_value = object[attribute.shift()] 2480 2481 } while(!final_value && attribute.length) 2482 2483 return final_value 2484 2485 } 2486 2487 const map = (object, mapper) => { 2488 2489 const newObject = {} 2490 2491 for(const key in mapper) { 2492 2493 // Handle different keys between new and old format
2494 newObject[key] = fallbackAttribute(object, mapper[key]) 2495 2496 // Cast price to float 2497 if(newObject[key] && ['price', 'amount', 'discount', 'discounts'].some(x => key.endsWith(x))) { 2498 newObject[key] = parsePrice(newObject[key]) 2499 } 2500 2501 if(newObject[key] === undefined) { 2502 delete newObject[key] 2503 } 2504 2505 } 2506 2507 return newObject 2508 2509 } 2510 2511 const mapCart = cart => { 2512 2513 const oldCart = cart 2514 2515 const mapper = { 2516 id: 'id', 2517 currency: 'currency', 2518 item_count: 'item_count', 2519 items: 'items', 2520 total_price: 'total_price', 2521 latest_items: 'latest_items' 2522 } 2523 2524 cart = map(cart, mapper) 2525 2526 const discounts = (oldCart.storewide_discounts || []).concat((oldCart.voucher_discounts || [])) 2527 2528 cart.discount_applications = discounts.map(discount => ({ 2529 title: discount.voucher_code || null, 2530 value: parsePrice(discount.amount), 2531 })) 2532 2533 cart.original_total_price = cart.items.length 2534 ? cart.items 2535 .map(item => item.original_price) 2536 .reduce((sum, price) => sum + price) 2537 : 0 2538 2539 cart.total_discount = cart.discount_applications.length 2540 ? cart.discount_applications 2541 .map(discount => parsePrice(discount.value)) 2542 .reduce((sum, value) => sum + value) 2543 : 0 2544 2545 cart.items = cart.items.map(item => mapLineItem(item)) 2546 2547 return cart 2548 2549 } 2550 2551 const mapCheckout = checkout => { 2552 2553 const mapper = { 2554 note: 'note', 2555 attributes: 'note_attributes', 2556 billing_address: 'billing_address', 2557 currency: 'currency', 2558 customer_id: 'customer_id', 2559 discounts_amount: 'total_discount', 2560 id: 'id', 2561 line_items: 'order_item', 2562 order_number: 'order_number', 2563 shipping_address: 'shipping_address', 2564 shipping_price: 'shipping_tax', 2565 shipping_method: 'shipping_method_name', 2566 tax_price: 'total_tax', 2567 } 2568 2569 checkout = map(checkout, mapper) 2570 2571 checkout.requires_shipping = checkout.line_items.some(item => item.shipping_required) 2572 2573 checkout.line_items = checkout.line_items.map(item => mapLineItem(item)) 2574 2575 return checkout 2576 2577 } 2578 2579 const mapOrder = order => { 2580 2581 const mapper = { 2582 attributes: 'note_attributes', 2583 billing_address: 'billing_address', 2584 cancelled: 'is_cancelled', 2585 cancelled_at: 'cancelled_at', 2586 created_at: 'created_at', 2587 customer_id: 'customer_id', 2588 // discount_applications: 'discount_applications', 2589 email: 'email', 2590 financial_status: 'financial_status', 2591 fulfillment_status: 'fulfillment_status', 2592 line_items: 'order_item', 2593 note: 'note', 2594 order_number: 'order_number', 2595 phone: 'phone', 2596 shipping_address: 'shipping_address', 2597 shipping_methods: 'shipping_methods', 2598 shipping_price: 'total_shipping', 2599 subtotal_price: 'subtotal_price', 2600 // tax_lines: 'tax_lines', 2601 tax_price: 'total_tax', 2602 total_discounts: 'total_discount', 2603 total_net_amount: 'total_amount_include_transaction', 2604 total_price: 'total_price', 2605 transactions: 'transaction_records', 2606 is_manual_payment: 'is_manual_payment', 2607 } 2608 2609 order.email = order.billing_address.email 2610 order.phone = order.billing_address.phone 2611 order.shipping_method = order.shipping_method_name 2612 2613 order = map(order, mapper) 2614 2615 order.line_items = order.line_items.map(item => mapLineItem(item)) 2616 order.transactions = order.transactions.map(transaction => mapTransaction(transaction)) 2617 2618 return order 2619 2620 } 2621 2622 const mapLineItem = line_item => { 2623 2624 const old_line_item = line_item 2625 2626 const mapper = { 2627 final_price: 'price', 2628 image: 'img_url', 2629 message: 'message', 2630 original_line_price: 'original_line_price', 2631 original_price: 'original_price', 2632 properties: 'properties', 2633 quantity: 'quantity', 2634 requires_shipping: 'shipping_required', 2635 sku: 'sku', 2636 taxable: 'taxable', 2637 title: 'product_name', 2638 product_name: 'product_name', 2639 url: 'url', 2640 product_id: 'product_id', 2641 variant_id: 'variant_id', 2642 id: ['id', 'i_id'], 2643 } 2644 2645 line_item = map(line_item, mapper) 2646 2647 line_item.product_id = line_item.product_id || (old_line_item.product && old_line_item.product.id) || null 2648 line_item.variant_id = line_item.variant_id || (old_line_item.variant && old_line_item.variant.id) || null 2649 line_item.image = line_item.image || (old_line_item.image && old_line_item.image.url) || null 2650 2651 return line_item 2652 2653 } 2654 2655 const mapTransaction = transaction => { 2656 2657 const mapper = { 2658 amount: 'amount', 2659 created_at: 'created_at', 2660 gateway: 'gateway_type', 2661 id: 'id', 2662 status: 'status', 2663 } 2664 2665 transaction = map(transaction, mapper) 2666 2667 return transaction 2668 2669 } 2670 2671 2672</script>
2672 2673 2674</body> 2675</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.