PageSourceSearch

https://www.tiptopfruits.com.my/account/login

html tiptopfruits.com.my collected 2026-09-28 03:31:49 UTC 119,584 bytes, 3,477 lines download raw bytes

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/861942/f/8088793.png" />
15  
16
17  <!-- Title and description ================================================== -->
18  <title>
19  Login &ndash; Tip Top Fruits &amp; Groceries
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://www.tiptopfruits.com.my/account/login">
30  
31  <meta property="og:image" content="https://cdn.store-assets.com/s/861942/f/8388694.png?width=350&format=webp">
32  <meta property="og:image:secure_url" content="https://cdn.store-assets.com/s/861942/f/8388694.png?width=350&format=webp">
33  
34
35
36<meta property="og:description" content="Your premier source for fresh fruits and vegetables wholesaler and supplier  deliver in Kuala Lumpur and Selangor.">
37<meta property="og:site_name" content="Tip Top Fruits &amp; Groceries">
38
39
40
41  <meta name="twitter:card" content="summary">
42
43
44
45
46
47
48
49  <!-- Helpers ================================================== -->
50  <link rel="canonical" href="https://www.tiptopfruits.com.my/account/login">
51  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=3.0">
52  <meta name="theme-color" content="">
53
54  <!-- CSS ================================================== -->
55  <link href="https://store-themes.easystore.co/861942/themes/2877/assets/timber.css?t=1787079718" rel="stylesheet" type="text/css" media="screen" />
56  <link href="https://store-themes.easystore.co/861942/themes/2877/assets/theme.css?t=1787079718" rel="stylesheet" type="text/css" media="screen" />
57
58  
59
60
61
62<link href="https://fonts.googleapis.com/css?family=Rajdhani:400,600&display=swap" rel="stylesheet">
63
64
65  
65<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js" type="text/javascript" ></script>
65
66  <!-- Header hook for plugins ================================================== -->
67  
68<!-- ScriptTags -->
69<script>window.__st={p: "customers",cid: null,cem: null,cph: null,cfn: null,cln: null,cge: null,cdb: null,ccc: null};</script>
69<script src='/assets/events.js'></script>
69<script>(function(){function asyncLoad(){var urls=['/assets/traffic.js?v=1','https://apps.easystore.co/marketplace/shopee-malaysia/script.js?shop=christiewttfg.easy.co','https://apps.easystore.co/google-analytics-4/script.js?shop=christiewttfg.easy.co&t=1719763460','https://apps.easystore.co/google-tag-manager/script.js?shop=christiewttfg.easy.co&t=1720542078'];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>
69
70<!-- /ScriptTags -->
71
72
73  
74<!--[if lt IE 9]>
75<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.2/html5shiv.min.js" type="text/javascript" ></script>
vendor: 2 bytes, line 75
75
76<script src="https://store-themes.easystore.co/861942/themes/2877/assets/respond.min.js?t=1787079718" type="text/javascript" ></script>
76
77<link href="https://store-themes.easystore.co/861942/themes/2877/assets/respond-proxy.html" id="respond-proxy" rel="respond-proxy" />
78<link href="//www.tiptopfruits.com.my/search?q=3872116bcc37ba006840ea0601517c4e" id="respond-redirect" rel="respond-redirect" />
79<script src="//www.tiptopfruits.com.my/search?q=3872116bcc37ba006840ea0601517c4e" type="text/javascript"></script>
79
80<![endif]-->
81
82
83
84  
84<script src="https://store-themes.easystore.co/861942/themes/2877/assets/modernizr.min.js?t=1787079718" type="text/javascript" ></script>
84
85
86  
87  
88    
88<script src="/assets/shop_common.js" type="text/javascript" ></script>
88
89    
89<script src="/assets/customer_area.js" type="text/javascript" ></script>
89
90  
91  
91<script>
92  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
93  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
94  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
95  })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
96
97  ga('create', '', 'auto','myTracker');
98  ga('myTracker.send', 'pageview');
99
100  </script>
100
101  
102<!-- Snippet:global/head: Shopee Malaysia -->
103<link type="text/css" rel="stylesheet" href="https://apps.easystore.co/assets/css/marketplace/main.css?v1.7">
104<!-- /Snippet -->
105
106<!-- Snippet:global/head: Google Search Console -->
107<meta name="google-site-verification" content="uDJw81-WI_bgpsUn0pJISYdwEZDAeRcVjIk36xYHBus" />
108<!-- /Snippet -->
109
110</head>
111
112<body id="login" class="template-customers  " >
113
114  <ul id="MobileNav" class="mobile-nav">
115  
116  <li class="mobile-nav_icon-x">
117    
118      
119
120
121  	
122  	<span class="MobileNavTrigger icon icon-x"></span>
123  </li>
124  
125  
126  <li class="mobile-nav__link" aria-haspopup="true">
127    
128    <a href="/" >
129      HOME
130    </a>
131    
132  </li>
133  
134  
135  <li class="mobile-nav__link" aria-haspopup="true">
136    
137    <a href="/pages/about" >
138      ABOUT US
139    </a>
140    
141  </li>
142  
143  
144  <li class="mobile-nav__link" aria-haspopup="true">
145    
146    
147    <a href="/collections/all" class="mobile-nav__parent-link">
148      PRODUCTS
149    </a>
150    <span class="mobile-nav__sublist-trigger">
151      <span class="icon-fallback-text mobile-nav__sublist-expand">
152  <span class="icon icon-plus" aria-hidden="true"></span>
153  <span class="fallback-text">+</span>
154</span>
155<span class="icon-fallback-text mobile-nav__sublist-contract">
156  <span class="icon icon-minus" aria-hidden="true"></span>
157  <span class="fallback-text">-</span>
158</span>
159
160    </span>
161    <ul class="mobile-nav__sublist">
162      
163      
164      <li class="mobile-nav__sublist-link" aria-haspopup="true">
165        
166        <a href="/collections/all-1" >
167          All
168        </a>
169        
170      </li>
171      
172      
173      <li class="mobile-nav__sublist-link" aria-haspopup="true">
174        
175        <a href="/collections/new" >
176          NEW
177        </a>
178        
179      </li>
180      
181      
182      <li class="mobile-nav__sublist-link" aria-haspopup="true">
183        
184        <a href="/collections/promotion" >
185          Promotion
186        </a>
187        
188      </li>
189      
190      
191      <li class="mobile-nav__sublist-link" aria-haspopup="true">
192        
193        <a href="/collections/fruits" >
194          Fruits
195        </a>
196        
197      </li>
198      
199      
200      <li class="mobile-nav__sublist-link" aria-haspopup="true">
201        
202        <a href="/collections/vegetables" >
203          Vegetables
204        </a>
205        
206      </li>
207      
208    </ul>
209    
210  </li>
211  
212  
213  <li class="mobile-nav__link" aria-haspopup="true">
214    
215    <a href="/collections/promotion" >
216      PROMOTION
217    </a>
218    
219  </li>
220  
221  
222  <li class="mobile-nav__link" aria-haspopup="true">
223    
224    <a href="/pages/supply" >
225      SUPPLY
226    </a>
227    
228  </li>
229  
230  
231  <li class="mobile-nav__link" aria-haspopup="true">
232    
233    <a href="/pages/delivery-area" >
234      DELIVERY AREA
235    </a>
236    
237  </li>
238  
239  
240  <li class="mobile-nav__link" aria-haspopup="true">
241    
242    <a href="/pages/guarantee" >
243      GUARANTEE
244    </a>
245    
246  </li>
247  
248  
249  <li class="mobile-nav__link" aria-haspopup="true">
250    
251    <a href="https://tiptopfruits.com.my/a/contact-form" >
252      CONTACT US
253    </a>
254    
255  </li>
256  
257
258  
259
260  
261  
262  
263  <li class="mobile-nav__link">
264    <a href="/account/login">Log in</a>
265  </li>
266  
267  <li class="mobile-nav__link">
268    <a href="/account/register">Create account</a>
269  </li>
270  
271  
272  
273  
274  <li class="mobile-nav__link header-bar__search-wrapper">
275    
276    <div class="header-bar__module header-bar__search mobile-nav_search">
277      
278  <form action="/search" method="get" class="header-bar__search-form clearfix" role="search">
279    
280    <button type="submit" class="btn icon-fallback-text header-bar__search-submit">
281      <span class="icon icon-search" aria-hidden="true"></span>
282      <span class="fallback-text">Search</span>
283    </button>
284    <input type="search" name="q" value="" aria-label="Search" class="header-bar__search-input" placeholder="Search" autocomplete="off">
285    <div class="dropdown" id="searchDropdown"></div>
286    <input type="hidden" name="search_history" id="search_history">
287  </form>
288
289
290
291
292<script>
293  var _search_history_listings = ""
294  if(_search_history_listings != "") localStorage.setItem('searchHistory', JSON.stringify(_search_history_listings));
295
296  function clearAll() {
297    localStorage.removeItem('searchHistory');
298  
299    var customer = "";
300    if(customer) {
301      // Your logic to clear all data or call an endpoint
302      fetch('/account/search_histories', {
303          method: 'DELETE',
304          headers: {
305            "Content-Type": "application/json",
306            "X-Requested-With": "XMLHttpRequest"
307          },
308          body: JSON.stringify({
309            _token: "TNYibZpXzUp6Eo3mau1Sbxad4gLDzXZSpgvdPVE9"
310          }),
311      })
312      .then(response => response.json())
313    }
314  }
315  // End - store view history in local storage
316  
317  // search history dropdown  
318  var searchInputs = document.querySelectorAll('input[type=search]');
319  
320  if(searchInputs.length > 0) {
321    
322    searchInputs.forEach((searchInput)=>{
323    
324      searchInput.addEventListener('focus', function() {
325        var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown');
326        searchDropdown.innerHTML = ''; // Clear existing items
327  
328        // retrieve data from local storage
329        var searchHistoryData = JSON.parse(localStorage.getItem('searchHistory')) || [];
330  
331        // Convert JSON to string
332        var search_history_json = JSON.stringify(searchHistoryData);
333  
334        // Set the value of the hidden input
335        searchInput.closest('form').querySelector("#search_history").value = search_history_json;
336  
337        // create dropdown items
338        var clearAllItem = document.createElement('div');
339        clearAllItem.className = 'dropdown-item clear-all';
340        clearAllItem.textContent = 'Clear';
341        clearAllItem.addEventListener('click', function() {
342            clearAll();
343            searchDropdown.style.display = 'none';
344            searchInput.classList.remove('is-focus');
345        });
346        searchDropdown.appendChild(clearAllItem);
347  
348        // create dropdown items
349        searchHistoryData.forEach(function(item) {
350          var dropdownItem = document.createElement('div');
351          dropdownItem.className = 'dropdown-item';
352          dropdownItem.textContent = item.term;
353          dropdownItem.addEventListener('click', function() {
354            searchInput.value = item.term;
355            searchDropdown.style.display = 'none';
356          });
357          searchDropdown.appendChild(dropdownItem);
358        });
359  
360        if(searchHistoryData.length > 0){
361          // display the dropdown
362          searchInput.classList.add('is-focus');
363          document.body.classList.add('search-input-focus');
364          searchDropdown.style.display = 'block';
365        }
366      });
367  
368      searchInput.addEventListener("focusout", (event) => {
369        var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown');
370        searchInput.classList.remove('is-focus');
371        searchDropdown.classList.add('transparent');
372        setTimeout(()=>{
373          searchDropdown.style.display = 'none';
374          searchDropdown.classList.remove('transparent');
375          document.body.classList.remove('search-input-focus');
376        }, 400);
377      });
378    })
379  }
380  // End - search history dropdown
381</script>
381
382    </div>
383    
384  </li>
385  
386  
387</ul>
388<div id="MobileNavOutside" class="mobile-nav-outside"></div>
389
390
391<div id="PageContainer" class="page-container">
392  
393<!-- Snippet:global/body_start: Announcement Bar -->
394<link rel="stylesheet" href="https://apps.easystore.co/assets/css/annoucement-bar/slider.css?v1.01">
395
396<input type="hidden" id="total_announcement_left" name="total_announcement_left" value="1">
397<input type="hidden" id="locale" name="locale" value="en_US">
398
399<slider-announcement-bar-app id="announcement-bar" name="announcement-bar" style="
400    border: unset;
401    padding: 4px 0px;
402    margin: 0px;
403    z-index:2999;
404    background:rgba(177, 162, 0, 0.88);
405    color:rgb(255, 255, 255);
406    position: -webkit-sticky; position: sticky; top: 0;
407">
408
409  <div style="
410    display: flex;
411    justify-content: space-between;
412    align-items: center;
413    padding: 0px 0px;
414    border-top: 0px;
415    border-bottom: 0px;
416    border-color: transparent;
417  ">
418    <div style="height: 24px;">
419          </div>
420
421    <ul style="flex-grow: 2; margin: 0px;">
422            <li id="announcement_bar_0" style="
423          display: flex;
424          justify-content: center;
425          align-items: center;
426          flex-wrap: wrap;
427          margin: 0px;
428          width: 100%;
429          word-wrap: break-word;
430        ">
431        Wholesale Fresh Fruits &amp; Vegetables Supplier in KL and Selangor.
432                <a class="announcement-bar-button" href="https://wa.me/60183833772?text=Hello,%20I%20want%20to%20get%20quotation%20of" style="color: rgb(255, 255, 255); background: rgba(136, 126, 0, 0.88);">GET QUOTE NOW</a>
433                        <input type="hidden" id="expired_at_0" name="expired_at_0" value="2025-01-26 00:00">
434      </li>
435          </ul>
436
437    <div style="display: flex;">
438                </div>
439  </div>
440
441
442</slider-announcement-bar-app>
443
444<script>
445  $(function() {
446    var is_top_enabled =  1;
447
448    const loadScript = function(url, callback) {
449      const script = document.createElement("script");
450      script.type = "text/javascript";
451      // If the browser is Internet Explorer.
452      if (script.readyState) {
453        script.onreadystatechange = function() {
454          if (script.readyState == "loaded" || script.readyState == "complete") {
455            script.onreadystatechange = null;
456            callback();
457          }
458        };
459        // For any other browser.
460      } else {
461        script.onload = function() {
462          callback();
463        };
464      }
465      script.src = url;
466      document.getElementsByTagName("head")[0].appendChild(script);
467    };
468
469    const announcementBarAppJS = function($) {
470
471      $('#announcement-close-button').on('click', function() {
472        $('#announcement-bar, #announcement-bar-top').hide();
473        $('#easystore-section-header, .sticky-topbar').css('top', '');
474      });
475    }
476
477    if (typeof jQuery === 'undefined') {
478      loadScript('//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js', function() {
479        jQuery = jQuery.noConflict(true);
480        announcementBarAppJS(jQuery);
481      });
482    } else {
483      announcementBarAppJS(jQuery);
484    }
485
486
487    
488    if(is_top_enabled){
489      // Prevent announcement bar block header
490      setTimeout(()=>{
491        $('#easystore-section-header, .sticky-topbar').css('top', $('#announcement-bar').height()+'px');
492      }, 2000);
493    }
494  });
495
496  setInterval(function() {
497    const total_announcement = "1"
498    var total_announcement_left = $("#total_announcement_left").val();
499
500    for (let i = 0; i <= total_announcement; i++) {
501      const startDate = new Date();
502      const endDateStr = $("#expired_at_" + i).val();
503      const endDate = endDateStr == undefined ? new Date() : new Date(endDateStr.replace(/-/g, "/"));
504      const seconds = (endDate.getTime() - startDate.getTime()) / 1000;
505
506      const days = parseInt(seconds / 86400);
507      const hours = parseInt((seconds % 86400) / 3600);
508      const mins = parseInt((seconds % 86400 % 3600) / 60);
509      const secs = parseInt((seconds % 86400 % 3600) % 60);
510
511      // use to translate countdown unit
512      // (translate based on the preferred language when save announcement bar setting)
513      String.prototype.translate = function() {
514        try {
515          if ($("#locale").val() == "zh_TW") {
516            if (this.toString() === 'day') {
517              return "天";
518            }
519            if (this.toString() === 'hour') {
520              return "小時";
521            }
522            if (this.toString() === 'min') {
523              return "分鐘";
524            }
525            if (this.toString() === 'sec') {
526              return "秒";
527            }
528          } else {
529            if (this.toString() === 'day') {
530              if (days > 0) {
531                return "Days";
532              } else {
533                return "Day";
534              }
535            } else if (this.toString() === 'hour') {
536              if (hours > 0) {
537                return "Hours";
538              } else {
539                return "Hour";
540              }
541            } else if (this.toString() === 'min') {
542              if (mins > 0) {
543                return "Mins";
544              } else {
545                return "Min";
546              }
547            } else if (this.toString() === 'sec') {
548              if (secs > 0) {
549                return "Secs";
550              } else {
551                return "Sec";
552              }
553            }
554          }
555        } catch (error) {
556          console.log("Some errors heres", error);
557        }
558      };
559
560      const announcementBar_countdown = document.getElementById("announcementBar_countdown_" + i);
561      if (announcementBar_countdown && seconds > 0) {
562
563        $(announcementBar_countdown).show()
564        announcementBar_countdown.innerHTML = `
565          <div>
566            ${days} <small>${'day'.translate()}</small>
567          </div>
568          <div>
569            ${hours} <small>${'hour'.translate()}</small>
570          </div>
571          <div>
572            ${mins} <small>${'min'.translate()}</small>
573          </div>
574          <div>
575            ${secs} <small>${'sec'.translate()}</small>
576          </div>
577        `;
578
579
580      } else if (announcementBar_countdown && seconds <= 0) {
581        $("#announcement_bar_" + i).remove();
582        total_announcement_left = total_announcement_left - 1;
583        $("#total_announcement_left").val(total_announcement_left);
584      }
585    }
586
587    showOrHide(total_announcement_left);
588  }, 1000);
589
590
591  function showOrHide(total_announcement_left) {
592    if (total_announcement_left <= 1) {
593      $("#previous-announcement-bar-button,#next-announcement-bar-button").hide();
594    } else {
595      $("#previous-announcement-bar-button,#next-announcement-bar-button").show();
596    }
597
598    if (total_announcement_left == 0) {
599      $("#announcement-close-button").hide();
600      $("#announcement-bar").hide();
601      $('#announcement-bar-top').hide();
602      $('#easystore-section-header, .sticky-topbar').css('top', '');
603    }
604  };
605
606  let annoucementBarAutoMoveInterval = '';
607  class AnnouncementBarAppSlider extends HTMLElement {
608    constructor() {
609      super();
610      this.slider = this.querySelector('ul');
611      this.sliderItems = this.querySelectorAll('li');
612      this.prevButton = this.querySelector('a[name="previous"]');
613      this.nextButton = this.querySelector('a[name="next"]');
614
615      if (!this.slider || !this.nextButton) return;
616
617      const resizeObserver = new ResizeObserver(entries => this.initPages());
618      resizeObserver.observe(this.slider);
619
620      this.slider.addEventListener('scroll', this.update.bind(this));
621      this.prevButton.addEventListener('click', this.onButtonClick.bind(this));
622      this.nextButton.addEventListener('click', this.onButtonClick.bind(this));
623
624
625    }
626
627    initPages() {
628      const sliderItemsToShow = Array.from(this.sliderItems).filter(element => element.clientWidth > 0);
629      this.sliderLastItem = sliderItemsToShow[sliderItemsToShow.length - 1];
630      if (sliderItemsToShow.length === 0) return;
631      this.slidesPerPage = Math.floor(this.slider.clientWidth / sliderItemsToShow[0].clientWidth);
632      this.totalPages = sliderItemsToShow.length - this.slidesPerPage + 1;
633      this.update();
634      let self = this
635      var total_announcement_left = $("#total_announcement_left").val();
636      annoucementBarAutoMoveInterval = setInterval(function() {
637        if (total_announcement_left > 1) {
638          self.moveSlide('next')
639        }
640      }, 5000)
641    }
642
643    update() {
644      this.currentPage = Math.round(this.slider.scrollLeft / this.sliderLastItem.clientWidth) + 1;
645    }
646
647    onButtonClick(event) {
648      event.preventDefault();
649      let self = this;
650      self.moveSlide(event.currentTarget.name);
651    }
652
653
654    moveSlide(move_to) {
655
656      clearInterval(annoucementBarAutoMoveInterval);
657      let self = this;
658      annoucementBarAutoMoveInterval = setInterval(function() {
659        self.moveSlide('next');
660      }, 5000)
661
662      if (move_to === 'previous' && this.currentPage === 1) {
663        this.slider.scrollTo({
664          left: this.sliderLastItem.clientWidth * (this.totalPages - 1)
665        });
666      } else if (move_to === 'next' && this.currentPage === this.totalPages) {
667        this.slider.scrollTo({
668          left: 0
669        });
670      } else {
671        const slideScrollPosition = move_to === 'next' ? this.slider.scrollLeft + this.sliderLastItem
672          .clientWidth : this.slider.scrollLeft - this.sliderLastItem.clientWidth;
673        this.slider.scrollTo({
674          left: slideScrollPosition
675        });
676      }
677    }
678
679  }
680
681  customElements.define('slider-announcement-bar-app', AnnouncementBarAppSlider);
682</script>
682
683
684<!-- /Snippet -->
685
686<!-- Snippet:global/body_start: Console Extension -->
687<div id='es_console' style='display: none;'>861942</div>
688<!-- /Snippet -->
689
690  
691    <style>
692  .search-modal__form{
693    position: relative;
694  }
695  
696  .dropdown-wrapper {
697    position: relative;
698  }
699  
700  .dropdown-wrapper:hover .dropdown {
701    display: block;
702  }
703  
704  .header-icon-nav .dropdown {
705    left: -80px;
706  }
707  
708  .dropdown {
709    display: none;
710    position: absolute;
711    top: 100%;
712    left: 0px;
713    width: 100%;
714    padding: 8px;
715    background-color: #fff;
716    z-index: 1000;
717    border-radius: 5px;
718    border: 1px solid rgba(var(--color-foreground), 1);
719    border-top: none;
720    overflow-x: hidden;
721    overflow-y: auto;
722    max-height: 350px;
723    min-width: 150px;
724    box-shadow: 0 0 5px rgba(0,0,0,0.1);
725  }
726    
727  .dropdown a{
728    text-decoration: none;
729    color: #000 !important;
730  }
731  
732  .dropdown-item {
733    padding: 0.4rem 2rem;
734    cursor: pointer;
735    line-height: 1.4;
736    overflow: hidden;
737    text-overflow: ellipsis;
738    white-space: nowrap;
739  }
740  
741  .dropdown-item:hover{
742    background-color: #f3f3f3;
743  }
744  
745  .search__input.is-focus{
746    border-radius: 15px;
747    border-bottom-left-radius: 0;
748    border-bottom-right-radius: 0;
749    border: 1px solid rgba(var(--color-foreground), 1);
750    border-bottom: none;
751    box-shadow: none;
752  }
753  
754  .clear-all {
755    text-align: right;
756    padding: 0 2rem 0.2rem;
757    line-height: 1;
758    font-size: 70%;
759    margin-bottom: -2px;
760  }
761  
762  .clear-all:hover{
763    background-color: #fff;
764  }
765  
766  .referral-notification {
767    position: absolute;
768    top: 100%;
769    right: -12px;
770    background: white;
771    border: 1px solid #e0e0e0;
772    border-radius: 8px;
773    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
774    width: 280px;
775    z-index: 1000;
776    padding: 16px;
777    margin-top: 8px;
778    font-size: 14px;
779    line-height: 1.4;
780  }
781  
782  .referral-notification::before {
783    content: '';
784    position: absolute;
785    top: -8px;
786    right: 20px;
787    width: 0;
788    height: 0;
789    border-left: 8px solid transparent;
790    border-right: 8px solid transparent;
791    border-bottom: 8px solid white;
792  }
793  
794  .referral-notification::after {
795    content: '';
796    position: absolute;
797    top: -9px;
798    right: 20px;
799    width: 0;
800    height: 0;
801    border-left: 8px solid transparent;
802    border-right: 8px solid transparent;
803    border-bottom: 8px solid #e0e0e0;
804  }
805  
806  .referral-notification h4 {
807    margin: 0 0 8px 0;
808    color: #2196F3;
809    font-size: 16px;
810    font-weight: 600;
811  }
812  
813  .referral-notification p {
814    margin: 0 0 12px 0;
815    color: #666;
816  }
817  
818  .referral-notification .referral-code {
819    background: #f5f5f5;
820    padding: 8px;
821    border-radius: 4px;
822    font-family: monospace;
823    font-size: 13px;
824    text-align: center;
825    margin: 8px 0;
826    border: 1px solid #ddd;
827  }
828  
829  .referral-notification .close-btn {
830    position: absolute;
831    top: 8px;
832    right: 8px;
833    background: none;
834    border: none;
835    font-size: 18px;
836    color: #999;
837    cursor: pointer;
838    padding: 0;
839    width: 20px;
840    height: 20px;
841    line-height: 1;
842  }
843  
844  .referral-notification .close-btn:hover {
845    color: #333;
846  }
847  
848  .referral-notification .action-btn {
849    background: #2196F3;
850    color: white;
851    border: none;
852    padding: 8px 16px;
853    border-radius: 4px;
854    cursor: pointer;
855    font-size: 12px;
856    margin-right: 8px;
857    margin-top: 8px;
858  }
859  
860  .referral-notification .action-btn:hover {
861    background: #1976D2;
862  }
863  
864  .referral-notification .dismiss-btn {
865    background: transparent;
866    color: #666;
867    border: 1px solid #ddd;
868    padding: 8px 16px;
869    border-radius: 4px;
870    cursor: pointer;
871    font-size: 12px;
872    margin-top: 8px;
873  }
874  
875  .referral-notification .dismiss-btn:hover {
876    background: #f5f5f5;
877  }
878  .referral-modal__dialog {
879    transform: translate(-50%, 0);
880    transition: transform var(--duration-default) ease, visibility 0s;
881    z-index: 10000;
882    position: fixed;
883    top: 20vh;
884    left: 50%;
885    width: 100%;
886    max-width: 350px;
887    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
888    border-radius: 12px;
889    background-color: #fff;
890    color: #000;
891    padding: 20px;
892    text-align: center;
893  }
894  .modal-overlay.referral-modal-overlay {
895    position: fixed;
896    top: 0;
897    left: 0;
898    width: 100%;
899    height: 100%;
900    background-color: rgba(0, 0, 0, 0.7);
901    z-index: 2001;
902    display: block;
903    opacity: 1;
904    transition: opacity var(--duration-default) ease, visibility 0s;
905  }
906</style>
907
908<header class="header-bar  sticky-topbar">
909  <div class="header-bg-wrapper">
910    <div class="header-wrapper wrapper">
911      
912
913<div class="logo-header" role="banner">
914      
915        <div class="h1 site-header__logo" itemscope itemtype="http://schema.org/Organization">
916          
917              
918                <a href="/" class="logo-wrapper" itemprop="url">
919                  <img src="https://cdn.store-assets.com/s/861942/f/8388694.png?width=350&format=webp" alt="Tip Top Fruits &amp; Groceries" itemprop="logo">
920                </a>
921              
922          
923        </div>
924      
925</div>
926
927      <div class="header-nav-bar medium-down--hide">
928          
929<ul class="site-nav large--text-center" id="AccessibleNav">
930  
931    
932    
933      <li >
934        <a href="/"  class="site-nav__link">HOME</a>
935      </li>
936    
937  
938    
939    
940      <li >
941        <a href="/pages/about"  class="site-nav__link">ABOUT US</a>
942      </li>
943    
944  
945    
946    
947      
948      <li class="site-nav--has-dropdown" aria-haspopup="true">
949        <a href="/collections/all"  class="site-nav__link">
950          PRODUCTS
951          <span class="arrow-icon">
952            <svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><title>arrow down</title><path d="M50,78.18A7.35,7.35,0,0,1,44.82,76L3.15,34.36A7.35,7.35,0,1,1,13.55,24L50,60.44,86.45,24a7.35,7.35,0,1,1,10.4,10.4L55.21,76A7.32,7.32,0,0,1,50,78.18Z"/></svg>
953          </span>
954        </a>
955        <ul class="site-nav__dropdown">
956          
957            
958            
959              <li >
960                <a href="/collections/all-1"  class="site-nav__link">All</a>
961              </li>
962            
963          
964            
965            
966              <li >
967                <a href="/collections/new"  class="site-nav__link">NEW</a>
968              </li>
969            
970          
971            
972            
973              <li >
974                <a href="/collections/promotion"  class="site-nav__link">Promotion</a>
975              </li>
976            
977          
978            
979            
980              <li >
981                <a href="/collections/fruits"  class="site-nav__link">Fruits</a>
982              </li>
983            
984          
985            
986            
987              <li >
988                <a href="/collections/vegetables"  class="site-nav__link">Vegetables</a>
989              </li>
990            
991          
992        </ul>
993      </li>
994    
995  
996    
997    
998      <li >
999        <a href="/collections/promotion"  class="site-nav__link">PROMOTION</a>
1000      </li>
1001    
1002  
1003    
1004    
1005      <li >
1006        <a href="/pages/supply"  class="site-nav__link">SUPPLY</a>
1007      </li>
1008    
1009  
1010    
1011    
1012      <li >
1013        <a href="/pages/delivery-area"  class="site-nav__link">DELIVERY AREA</a>
1014      </li>
1015    
1016  
1017    
1018    
1019      <li >
1020        <a href="/pages/guarantee"  class="site-nav__link">GUARANTEE</a>
1021      </li>
1022    
1023  
1024    
1025    
1026      <li >
1027        <a href="https://tiptopfruits.com.my/a/contact-form"  class="site-nav__link">CONTACT US</a>
1028      </li>
1029    
1030  
1031  
1032  
1033      
1034        
1035          
1036        
1037          
1038        
1039      
1040  
1041  
1042  
1043</ul>
1044
1045      </div>
1046
1047      <div class="desktop-header-nav medium-down--hide">
1048
1049
1050        <div class="header-subnav">
1051          
1052
1053
1054
1055
1056          <div class="header-icon-nav">
1057
1058                
1059
1060                
1061
1062
1063                
1064                  
1065                    <div class="header-bar__module">
1066                      
1067  <a class="popup-with-form" href="#search-form">
1068    
1069
1070
1071
1072	<svg class="icon-search svg-icon" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><title>icon-search</title><path d="M68.5,65.87a35.27,35.27,0,1,0-5.4,4.5l23.11,23.1a3.5,3.5,0,1,0,5-4.94ZM14.82,41A28.47,28.47,0,1,1,43.28,69.43,28.5,28.5,0,0,1,14.82,41Z"/></svg>    
1073
1074  
1075
1076  </a>
1077
1078
1079
1080<!-- form itself -->
1081<div id="search-form" class="white-popup-block mfp-hide popup-search">
1082  <div class="popup-search-content">
1083    <form action="/search" method="get" class="input-group search-bar" role="search">
1084      
1085      <input type="search" name="q" value="" placeholder="Search" class="input-group-field" aria-label="Search" placeholder="Search" autocomplete="off">
1086      <div class="dropdown" id="searchDropdown"></div>
1087      <input type="hidden" name="search_history" id="search_history">
1088      <span class="input-group-btn">
1089        <button type="submit" class="btn icon-fallback-text">
1090          <span class="icon icon-search" aria-hidden="true"></span>
1091          <span class="fallback-text">Search</span>
1092        </button>
1093      </span>
1094    </form>
1095  </div>
1096</div>
1097
1098<script src="https://store-themes.easystore.co/861942/themes/2877/assets/magnific-popup.min.js?t=1787079718" type="text/javascript" ></script>
vendor: 1 bytes, line 1098
1098
1099<script>
1100$(document).ready(function() {
1101	$('.popup-with-form').magnificPopup({
1102		type: 'inline',
1103		preloader: false,
1104		focus: '#name',
1105      	mainClass: 'popup-search-bg-wrapper',
1106
1107		// When elemened is focused, some mobile browsers in some cases zoom in
1108		// It looks not nice, so we disable it:
1109		callbacks: {
1110			beforeOpen: function() {
1111				if($(window).width() < 700) {
1112					this.st.focus = false;
1113				} else {
1114					this.st.focus = '#name';
1115				}
1116			}
1117		}
1118	});
1119  	$('.popup-search-content').click(function(event) {
1120      	if($(event.target).attr('class') == "popup-search-content") {
1121          $.magnificPopup.close();
1122        }
1123    });
1124});
1125</script>
1125
1126
1127
1128<script>
1129  var _search_history_listings = ""
1130  if(_search_history_listings != "") localStorage.setItem('searchHistory', JSON.stringify(_search_history_listings));
1131
1132  function clearAll() {
1133    localStorage.removeItem('searchHistory');
1134  
1135    var customer = "";
1136    if(customer) {
1137      // Your logic to clear all data or call an endpoint
1138      fetch('/account/search_histories', {
1139          method: 'DELETE',
1140          headers: {
1141            "Content-Type": "application/json",
1142            "X-Requested-With": "XMLHttpRequest"
1143          },
1144          body: JSON.stringify({
1145            _token: "TNYibZpXzUp6Eo3mau1Sbxad4gLDzXZSpgvdPVE9"
1146          }),
1147      })
1148      .then(response => response.json())
1149    }
1150  }
1151  // End - store view history in local storage
1152  
1153  // search history dropdown  
1154  var searchInputs = document.querySelectorAll('input[type=search]');
1155  
1156  if(searchInputs.length > 0) {
1157    
1158    searchInputs.forEach((searchInput)=>{
1159    
1160      searchInput.addEventListener('focus', function() {
1161        var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown');
1162        searchDropdown.innerHTML = ''; // Clear existing items
1163  
1164        // retrieve data from local storage
1165        var searchHistoryData = JSON.parse(localStorage.getItem('searchHistory')) || [];
1166  
1167        // Convert JSON to string
1168        var search_history_json = JSON.stringify(searchHistoryData);
1169  
1170        // Set the value of the hidden input
1171        searchInput.closest('form').querySelector("#search_history").value = search_history_json;
1172  
1173        // create dropdown items
1174        var clearAllItem = document.createElement('div');
1175        clearAllItem.className = 'dropdown-item clear-all';
1176        clearAllItem.textContent = 'Clear';
1177        clearAllItem.addEventListener('click', function() {
1178            clearAll();
1179            searchDropdown.style.display = 'none';
1180            searchInput.classList.remove('is-focus');
1181        });
1182        searchDropdown.appendChild(clearAllItem);
1183  
1184        // create dropdown items
1185        searchHistoryData.forEach(function(item) {
1186          var dropdownItem = document.createElement('div');
1187          dropdownItem.className = 'dropdown-item';
1188          dropdownItem.textContent = item.term;
1189          dropdownItem.addEventListener('click', function() {
1190            searchInput.value = item.term;
1191            searchDropdown.style.display = 'none';
1192          });
1193          searchDropdown.appendChild(dropdownItem);
1194        });
1195  
1196        if(searchHistoryData.length > 0){
1197          // display the dropdown
1198          searchInput.classList.add('is-focus');
1199          document.body.classList.add('search-input-focus');
1200          searchDropdown.style.display = 'block';
1201        }
1202      });
1203  
1204      searchInput.addEventListener("focusout", (event) => {
1205        var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown');
1206        searchInput.classList.remove('is-focus');
1207        searchDropdown.classList.add('transparent');
1208        setTimeout(()=>{
1209          searchDropdown.style.display = 'none';
1210          searchDropdown.classList.remove('transparent');
1211          document.body.classList.remove('search-input-focus');
1212        }, 400);
1213      });
1214    })
1215  }
1216  // End - search history dropdown
1217</script>
1217
1218                    </div>
1219                  
1220                
1221
1222
1223
1224
1225                
1226                  <div class="header-bar__module dropdown-wrapper">
1227                    
1228                      <a href="/account/login">
1229
1230
1231
1232    <svg class="svg-icon" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><title>icon-profile</title><path d="M50,51.8A24.4,24.4,0,1,0,25.6,27.4,24.43,24.43,0,0,0,50,51.8ZM50,10A17.4,17.4,0,1,1,32.6,27.4,17.43,17.43,0,0,1,50,10Z"/><path d="M62.66,57.66H37.34a30.54,30.54,0,0,0-30.5,30.5V93.5a3.5,3.5,0,0,0,3.5,3.5H89.66a3.5,3.5,0,0,0,3.5-3.5V88.16A30.54,30.54,0,0,0,62.66,57.66ZM86.16,90H13.84V88.16a23.53,23.53,0,0,1,23.5-23.5H62.66a23.53,23.53,0,0,1,23.5,23.5Z"/></svg>
1233
1234  
1235</a>
1236
1237                      <!-- Referral Notification Popup for Desktop -->
1238                      <div id="referralNotification" class="referral-notification" style="display: none;">
1239                        <button class="close-btn" onclick="dismissReferralNotification()">&times;</button>
1240                        <div style="text-align: center; margin-bottom: 16px;">
1241                          <div style="width: 100px; height: 100px; margin: 0 auto;">
1242                            <img src="https://resources.easystore.co/storefront/icons/channels/vector_referral_program.svg">
1243                          </div>
1244                        </div>
1245                        <p id="referralSignupMessage" style="text-align: center; font-size: 14px; color: #666; margin: 0 0 20px 0;">
1246                          Your friend gifted you   credit! Sign up now to redeem.
1247                        </p>
1248                        <div style="text-align: center;">
1249                          <button class="btn" onclick="goToSignupPage()" style="width: 100%; color: #fff;">
1250                            Sign Up
1251                          </button>
1252                        </div>
1253                      </div>
1254                    
1255                  </div>
1256                
1257
1258 
1259
1260          </div>
1261        </div>
1262
1263
1264
1265      </div>
1266      
1267	  <div class="mobile-header-icons large--hide">
1268        
1269        <div class="large--hide">
1270          
1271  <a class="popup-with-form" href="#search-form">
1272    
1273
1274
1275
1276	<svg class="icon-search svg-icon" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><title>icon-search</title><path d="M68.5,65.87a35.27,35.27,0,1,0-5.4,4.5l23.11,23.1a3.5,3.5,0,1,0,5-4.94ZM14.82,41A28.47,28.47,0,1,1,43.28,69.43,28.5,28.5,0,0,1,14.82,41Z"/></svg>    
1277
1278  
1279
1280  </a>
1281
1282
1283
1284<!-- form itself -->
1285<div id="search-form" class="white-popup-block mfp-hide popup-search">
1286  <div class="popup-search-content">
1287    <form action="/search" method="get" class="input-group search-bar" role="search">
1288      
1289      <input type="search" name="q" value="" placeholder="Search" class="input-group-field" aria-label="Search" placeholder="Search" autocomplete="off">
1290      <div class="dropdown" id="searchDropdown"></div>
1291      <input type="hidden" name="search_history" id="search_history">
1292      <span class="input-group-btn">
1293        <button type="submit" class="btn icon-fallback-text">
1294          <span class="icon icon-search" aria-hidden="true"></span>
1295          <span class="fallback-text">Search</span>
1296        </button>
1297      </span>
1298    </form>
1299  </div>
1300</div>
1301
1302<script src="https://store-themes.easystore.co/861942/themes/2877/assets/magnific-popup.min.js?t=1787079718" type="text/javascript" ></script>
vendor: 1 bytes, line 1302
1302
1303<script>
1304$(document).ready(function() {
1305	$('.popup-with-form').magnificPopup({
1306		type: 'inline',
1307		preloader: false,
1308		focus: '#name',
1309      	mainClass: 'popup-search-bg-wrapper',
1310
1311		// When elemened is focused, some mobile browsers in some cases zoom in
1312		// It looks not nice, so we disable it:
1313		callbacks: {
1314			beforeOpen: function() {
1315				if($(window).width() < 700) {
1316					this.st.focus = false;
1317				} else {
1318					this.st.focus = '#name';
1319				}
1320			}
1321		}
1322	});
1323  	$('.popup-search-content').click(function(event) {
1324      	if($(event.target).attr('class') == "popup-search-content") {
1325          $.magnificPopup.close();
1326        }
1327    });
1328});
1329</script>
1329
1330
1331
1332<script>
1333  var _search_history_listings = ""
1334  if(_search_history_listings != "") localStorage.setItem('searchHistory', JSON.stringify(_search_history_listings));
1335
1336  function clearAll() {
1337    localStorage.removeItem('searchHistory');
1338  
1339    var customer = "";
1340    if(customer) {
1341      // Your logic to clear all data or call an endpoint
1342      fetch('/account/search_histories', {
1343          method: 'DELETE',
1344          headers: {
1345            "Content-Type": "application/json",
1346            "X-Requested-With": "XMLHttpRequest"
1347          },
1348          body: JSON.stringify({
1349            _token: "TNYibZpXzUp6Eo3mau1Sbxad4gLDzXZSpgvdPVE9"
1350          }),
1351      })
1352      .then(response => response.json())
1353    }
1354  }
1355  // End - store view history in local storage
1356  
1357  // search history dropdown  
1358  var searchInputs = document.querySelectorAll('input[type=search]');
1359  
1360  if(searchInputs.length > 0) {
1361    
1362    searchInputs.forEach((searchInput)=>{
1363    
1364      searchInput.addEventListener('focus', function() {
1365        var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown');
1366        searchDropdown.innerHTML = ''; // Clear existing items
1367  
1368        // retrieve data from local storage
1369        var searchHistoryData = JSON.parse(localStorage.getItem('searchHistory')) || [];
1370  
1371        // Convert JSON to string
1372        var search_history_json = JSON.stringify(searchHistoryData);
1373  
1374        // Set the value of the hidden input
1375        searchInput.closest('form').querySelector("#search_history").value = search_history_json;
1376  
1377        // create dropdown items
1378        var clearAllItem = document.createElement('div');
1379        clearAllItem.className = 'dropdown-item clear-all';
1380        clearAllItem.textContent = 'Clear';
1381        clearAllItem.addEventListener('click', function() {
1382            clearAll();
1383            searchDropdown.style.display = 'none';
1384            searchInput.classList.remove('is-focus');
1385        });
1386        searchDropdown.appendChild(clearAllItem);
1387  
1388        // create dropdown items
1389        searchHistoryData.forEach(function(item) {
1390          var dropdownItem = document.createElement('div');
1391          dropdownItem.className = 'dropdown-item';
1392          dropdownItem.textContent = item.term;
1393          dropdownItem.addEventListener('click', function() {
1394            searchInput.value = item.term;
1395            searchDropdown.style.display = 'none';
1396          });
1397          searchDropdown.appendChild(dropdownItem);
1398        });
1399  
1400        if(searchHistoryData.length > 0){
1401          // display the dropdown
1402          searchInput.classList.add('is-focus');
1403          document.body.classList.add('search-input-focus');
1404          searchDropdown.style.display = 'block';
1405        }
1406      });
1407  
1408      searchInput.addEventListener("focusout", (event) => {
1409        var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown');
1410        searchInput.classList.remove('is-focus');
1411        searchDropdown.classList.add('transparent');
1412        setTimeout(()=>{
1413          searchDropdown.style.display = 'none';
1414          searchDropdown.classList.remove('transparent');
1415          document.body.classList.remove('search-input-focus');
1416        }, 400);
1417      });
1418    })
1419  }
1420  // End - search history dropdown
1421</script>
1421
1422        </div>
1423
1424
1425       
1426
1427        <!--  Mobile hamburger  -->
1428        <div class="large--hide">
1429          <a class="mobile-nav-trigger MobileNavTrigger">
1430            
1431
1432
1433
1434    <svg class="svg-icon" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><title>icon-nav-menu</title><path d="M6.7,26.34H93a3.5,3.5,0,0,0,0-7H6.7a3.5,3.5,0,0,0,0,7Z"/><path d="M93.3,46.5H7a3.5,3.5,0,0,0,0,7H93.3a3.5,3.5,0,1,0,0-7Z"/><path d="M93.3,73.66H7a3.5,3.5,0,1,0,0,7H93.3a3.5,3.5,0,0,0,0-7Z"/></svg>
1435
1436  
1437
1438          </a>
1439        </div>
1440      
1441        
1442          
1443          <!-- Referral Notification Modal for Mobile -->
1444          <details-modal class="referral-modal" id="referralMobileModal">
1445            <details>
1446              <summary class="referral-modal__toggle" aria-haspopup="dialog" aria-label="Open referral modal" style="display: none;">
1447              </summary>
1448              <div class="modal-overlay referral-modal-overlay"></div>
1449              <div class="referral-modal__dialog" role="dialog" aria-modal="true" aria-label="Referral notification">
1450                <div class="referral-modal__content">
1451                  <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;">
1452                    &times;
1453                  </button>
1454
1455                  <div style="margin-bottom: 24px;">
1456                    <div style="width: 120px; height: 120px; margin: 0 auto 20px;">
1457                      <img src="https://resources.easystore.co/storefront/icons/channels/vector_referral_program.svg" style="width: 100%; height: 100%;">
1458                    </div>
1459                  </div>
1460
1461                  <p id="referralSignupMessageMobile" style="font-size: 16px; color: #333; margin: 0 0 30px 0; line-height: 1.5;">
1462                    Your friend gifted you   credit! Sign up now to redeem.
1463                  </p>
1464
1465                  <button type="button" class="btn" onclick="goToSignupPageFromMobile()" style="width: 100%; color: #fff;">
1466                    Sign Up
1467                  </button>
1468                </div>
1469              </div>
1470            </details>
1471          </details-modal>
1472          
1473        
1474      
1475      </div>
1476
1477
1478    </div>
1479  </div>
1480</header>
1481
1482
1483
1484
1485
1486
1487    
1488    <main class="wrapper main-content" role="main">
1489      <div class="grid">
1490          <div class="grid__item">
vendor: 100 bytes, lines 1490-1494
1490
1491            
1492  
1493            
1494<script src="https://www.recaptcha.net/recaptcha/enterprise.js?render=
14946LdMNdIqAAAAALegJp7y4weVcCIlnwmIN8TWseEF
vendor: 12 bytes, line 1494
1494"></script>
1495<link rel="preload" href="https://store-themes.easystore.co/861942/themes/2877/assets/customer.css?t=1787079718" as="style" onload="this.onload=null;this.rel='stylesheet'">
1496<style>
1497  main.main-content .field > label{
1498    display: none;
1499  }
1500  .h3{
1501    font-size: 18px;
1502  }
1503  .button--full-width{
1504    width: 100%;
1505  }
1506  .tab-wrapper{
1507    display: inline-flex;
1508    justify-content: center;
1509    align-items: center;
1510    margin: 10px auto 20px;
1511    background-color: #eaeaea;
1512    border-radius: 200px;
1513    padding: 5px;
1514    gap: 10px;
1515  }
1516  .tab-wrapper .tab-label {
1517    display: inline-block;
1518    min-width: 130px;
1519    padding: 8px 15px;
1520    border-radius: 100px;
1521    cursor: pointer;
1522    font-size: 17px;
1523    line-height: 1.1;
1524    user-select: none;
1525    margin: 0;
1526    color: #000;
1527  }
1528  #register-tos a {
1529    display: inline;
1530  }
1531  @media screen and (max-width: 400px){
1532    .tab-wrapper .tab-label {
1533      min-width: 110px;
1534    }
1535  }
1536  .tab-wrapper input[type='radio']:checked + .tab-label {
1537    background-color: #fff;
1538    box-shadow: 2px 2px 25px -10px #333;
1539  }
1540
1541  @media screen and (min-width: 500px){
1542    .large--five-twelfths{
1543      min-width: 420px;
1544    }
1545  }
1546</style>
1547
1548
1549
1550
1551<div class="customer login section-width-control small-width large--five-twelfths text-center wrapper">
1552  <div class="card">
1553    <h1 id="login" tabindex="-1" class="mb-0">
1554      Welcome
1555    </h1>
1556    <p class="h3 mt-0">
1557      
1558        Sign up or log in to continue
1559      
1560    </p>
1561    <div>
1562      
1563
1564      
1565
1566      
1567
1568      
1569
1570      
1571
1572      
1573
1574      
1575
1576      
1577
1578      
1579      <div class="tab-wrapper">
1580        <div>
1581          <input type="radio" name="type" id="tab-register" class="hide hidden" checked>
1582          <label for="tab-register" class="tab-label">
1583            Sign up
1584          </label>
1585        </div>
1586        <div>
1587          <input type="radio" name="type" id="tab-login" class="hide hidden">
1588          <label for="tab-login" class="tab-label">
1589            Login
1590          </label>
1591        </div>
1592      </div>
1593      
1594
1595      <form id="form-login" action="/account/auth" method="post" class="mt-2">
1596        <input type="hidden" name="_token" value="TNYibZpXzUp6Eo3mau1Sbxad4gLDzXZSpgvdPVE9">
1597        <input type="hidden" name="location_id" value="">
1598        <input type="hidden" name="staff_id" value="">
1599        <input type="hidden" id="recaptchaResponse" name="g-recaptcha-response">
1600
1601        
1602        <div id="error-content"></div>
1603
1604        <div class="field">
1605          <input
1606            type="text"
1607            name="customer[email_or_phone]"
1608            id="CustomerDetail"
1609            autocorrect="off"
1610            autocapitalize="off"
1611            placeholder="Email"
1612            required
1613          >
1614          <label for="CustomerDetail">
1615            Email
1616          </label>
1617        </div>
1618
1619        <button
1620          type="submit"
1621          form="form-login"
1622          class="btn button--full-width g-recaptcha">
1623          Continue
1624        </button>
1625
1626        <div class="button-snippet">
1627                          
1628        </div>
1629
1630        
1631
1632        <div id="register-tos">
1633          By signing up, I agree to the Tip Top Fruits & Groceries's <a target="_blank" href="/legal/refund-policy">Refund Policy</a>, <a target="_blank" href="/legal/privacy-policy">Privacy Policy</a>, <a target="_blank" href="/legal/terms-of-service">Terms of Service</a> and <a target="_blank" href="/legal/delivery-policy">Delivery Policy</a>.
1634        </div>
1635
1636      </form>
1637    </div>
1638  </div>
1639
1640</div>
1641
1642
1643
1644<script>
1645  const register_tab = document.querySelector('#tab-register');
1646  const login_tab = document.querySelector('#tab-login');
1647  const register_tos = document.querySelector('#register-tos');
1648  const isRegistrationEnabled = "1";
1649
1650  if (register_tab) {
1651    register_tab.addEventListener('click', function() {
1652      if (register_tos) {
1653        register_tos.style.display = 'block';
1654      }
1655    });
1656  }
1657  if (login_tab) {
1658    login_tab.addEventListener('click', function() {
1659      if (register_tos) {
1660        register_tos.style.display = 'none';
1661      }
1662    });
1663  }
1664
1665  const methodSwitchBtn = document.getElementById('phone-login-btn');
1666  if (methodSwitchBtn) {
1667    methodSwitchBtn.onclick = function () {
1668      var type = (register_tab && register_tab.checked) ? 'register' : 'login';
1669      window.location.href = '/account/login?method=phone&type=' + type;
1670    };
1671  }
1672
1673  let lastPathSegment = window.location.pathname.split('/').filter(segment => segment.length > 0).pop();
1674  
1675  // Redirect to login if trying to access register when self registration is disabled
1676  if (!isRegistrationEnabled) {
1677    if (lastPathSegment === 'register') {
1678      window.location.href = '/account/login';
1679    } else if (lastPathSegment === 'login' || lastPathSegment === 'auth') {
1680      if (register_tos) {
1681        register_tos.style.display = 'none';
1682      }
1683    } 
1684  } else {
1685    // Only proceed with tab logic if not redirecting
1686    if(lastPathSegment === 'login') {
1687      if (login_tab) {
1688        login_tab.checked = true;
1689      }
1690      if (register_tos) {
1691        register_tos.style.display = 'none';
1692      }
1693    } else {
1694      if (register_tos) {
1695        register_tos.style.display = 'block';
1696      }
1697    }
1698  }
1699
1700  const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
1701  const phonePattern = /^(?:\+?\d{1,3}[\s-]?)?(?:\d{1,14}[\s-]?){1,5}$/;
1702
1703  let form = document.querySelector('#form-login'),
1704      input = document.querySelector('#CustomerDetail'),
1705      error_content = document.querySelector('#error-content');
1706
1707
1708  // One attempt at a time: the reCAPTCHA wait below is async, so without
1709  // this a double-click starts two continuations and posts the form twice.
1710  var submitting = false;
1711
1712  form.addEventListener('submit', async function (event) {
1713    // preventDefault FIRST: a re-entrant submit must still be cancelled, or the
1714    // browser performs a native post with no captcha token.
1715    event.preventDefault();
1716    if (submitting) return;
1717
1718    let input_value = input.value
1719    error_content.innerHTML = '';
1720    if (!input_value.match(emailPattern) && !input_value.match(phonePattern)) {
1721      error_content.innerHTML = `<div class="errors note">Invalid Email or Phone</div>`;
1722      return false;
1723    }
1724
1725    submitting = true;
1726    document.querySelector('#form-login .btn').classList.add('btn--loading','loading');
1727
1728    // reCAPTCHA is unreachable from some regions (google.com is blocked in
1729    // mainland China). Fail open the same way checkout and forgot-password do:
1730    // submit without a token rather than leave the button spinning forever.
1731    try {
1732      if (window.grecaptcha && typeof window.grecaptcha.enterprise === 'object') {
1733        // The loader defines a stub {ready} synchronously and fetches the real
1734        // implementation asynchronously, so execute() may not exist yet.
1735        // ready() queues until it does; the timeout stops a bundle that never
1736        // arrives from hanging the button.
1737        await new Promise(function (resolve) {
1738          setTimeout(resolve, 3000);
1739          try { grecaptcha.enterprise.ready(resolve); } catch (e) { resolve(); }
1740        });
1741
1742        const token = await grecaptcha.enterprise.execute('6LdMNdIqAAAAALegJp7y4weVcCIlnwmIN8TWseEF', { action: 'LOGIN' });
1743        document.getElementById('recaptchaResponse').value = token;
1744      }
1745    } catch (e) { /* fail open */ }
1746
1747    document.getElementById('form-login').submit();
1748  });
1749
1750
1751</script>
1751
1752
1753  
1754            
1755          </div>
1756      </div>
1757      
1758      
1759  
1760    </main>
1761  
1762    <footer class="site-footer small--text-center" role="contentinfo">
1763      
1764      
1765      
1766      <div class="wrapper">
1767  
1768        <div class="grid-uniform">
1769  
1770          
1771          
1772          
1773          
1774            
1775          
1776          
1777          
1778            
1779          
1780          
1781          
1782  
1783          
1784              
1785            
1786  
1787          
1788      
1789          
1790          
1791          <div class="grid__item large--one-half ">
1792            <a href="/" class="logo-wrapper" itemprop="url" >
1793              
1794                <img style="max-width: 250px" src="https://cdn.store-assets.com/s/861942/f/8082524.png?width=350&format=webp" alt="Tip Top Fruits &amp; Groceries" itemprop="logo">
1795              <div style="display:inline;position:relative;top: -5px;padding: 20px;">
1796                <img src="https://cdn.store-assets.com/s/861942/f/8371592.png" style="max-width: 250px;
1797  height: inherit;
1798  object-fit: cover;
1799  object-positon: center center;">
1800              </div>
1801              
1802            </a>
1803            <p class="site-footer__links">Copyright © 2026 Tip Top Fruits & Groceries  (002450675-D). All right reserved.</p>
1804          </div>
1805          
1806          
1807            <div class="grid__item large--one-quarter medium--one-half">
1808              
1809              <h4>Quick Links</h4>
1810              
1811              <ul class="site-footer__links">
1812                
1813                  <li><a href="/store-locator" >Store Locator</a></li>
1814                
1815                  <li><a href="/a/contact-form" >Contact us</a></li>
1816                
1817                
1818              </ul>
1819            </div>
1820          
1821  
1822          
1823            <div class="grid__item large--one-quarter medium--one-half">
1824              <h4>Follow Us</h4>
1825                
1826                <ul class="inline-list social-icons">
1827  
1828  
1829    <li>
1830      <a class="icon-fallback-text" href="https://www.facebook.com/" title="Tip Top Fruits & Groceries on Facebook" target="_blank">
1831        
1832
1833
1834
1835    <svg xmlns="http://www.w3.org/2000/svg" class="facebook-icon-svg social-icon-svg" viewBox="0 0 1024 1024">
1836        <title>icon-facebook</title>
1837        <path d="M837.66,223.9a33.73,33.73,0,0,0-3.11-15c-6.78-13.85-17.87-21.09-33.37-21.09q-288.46,0-576.91,0c-.62,0-1.24,0-1.85,0a34.51,34.51,0,0,0-25.88,12.11c-6.31,7.13-8.85,15.57-8.85,25.07q.08,287.7,0,575.4c0,1,0,1.9,0,2.86A32.93,32.93,0,0,0,190,814.71c4.45,11.79,16.3,23.11,35,23.1q153.61-.1,307.24,0c2.36,0,2.36,0,2.36-2.37q0-123.3,0-246.6c0-2.55,0-2.55-2.53-2.55H452.27c-2.26,0-2.26,0-2.26-2.17v-96.3h84.63v-2.46c0-22.12-.11-44.24.06-66.36.07-8.29.57-16.59,1.28-24.85a129.58,129.58,0,0,1,7.43-33c10.86-30,30.59-51.74,60-64.51A133.44,133.44,0,0,1,653,285.82c12.45-.37,24.93,0,37.38.34,9.64.27,19.27.95,28.9,1.6,5.36.36,10.7,1.07,16.06,1.5,1.46.12,1.65.75,1.65,2q0,42.2,0,84.39c0,.59-.06,1.18-.09,1.85h-2.39c-16.28,0-32.56,0-48.84.05-7.63,0-15.23.54-22.65,2.61-11.61,3.23-19.86,10.09-23.65,21.78a55.66,55.66,0,0,0-2.74,16.86c-.14,22.23-.1,44.47-.13,66.7,0,2.25,0,2.25,2.31,2.25h94.66a15.13,15.13,0,0,1,0,1.54c-.38,2.94-.81,5.88-1.18,8.82-1.17,9.16-2.3,18.33-3.48,27.5-1.29,10-2.63,20-3.94,30-1.23,9.44-2.43,18.88-3.67,28.32-.31,2.32-.35,2.32-2.78,2.32h-79a4.62,4.62,0,0,0-1.67,0,2.5,2.5,0,0,0-1.2,1.16,3.68,3.68,0,0,0,0,1.49V835.21c0,2.56,0,2.56,2.53,2.56H797.83c2.13,0,4.27-.07,6.39-.21,11.56-.78,20.61-6.07,27.23-15.48,4.66-6.6,6.24-14.09,6.24-22.11q-.06-287.19,0-574.38Z" fill="#999"/>
1838    </svg>
1839
1840  
1841
1842        <span class="fallback-text">Facebook</span>
1843      </a>
1844    </li>
1845  
1846  
1847  
1848    <li>
1849      <a class="icon-fallback-text" href="https://instagram.com/" title="Tip Top Fruits & Groceries on Instagram" target="_blank">
1850        
1851
1852
1853
1854    <svg xmlns="http://www.w3.org/2000/svg" class="instagram-icon-svg social-icon-svg" viewBox="0 0 1024 1024">
1855        <title>icon-instagram</title>
1856        <path d="M834.35,341.22a231.23,231.23,0,0,0-9.59-46.45,166.71,166.71,0,0,0-52.17-78.33c-17-14.41-36.33-24.44-57.44-31.3-21.52-7-43.69-10.21-66.19-11.12-22.28-.9-44.58-1.73-66.87-1.85-47.68-.26-95.37-.16-143.06,0-27.47.11-54.95.69-82.32,3.39a220.7,220.7,0,0,0-37.43,6.95c-26.2,7.26-50,19-70.24,37.45-18.06,16.4-32.3,35.52-41.87,58.05-9.89,23.29-15.13,47.68-16.69,72.82-1.23,19.78-2.06,39.6-2.32,59.41-.38,28.91-.1,57.82-.1,86.73-.23,39.92-.67,79.85,1,119.76.72,17.66,1.57,35.3,4.6,52.76,3.22,18.52,8.32,36.51,16.71,53.34C232.83,768,268.81,797,317.12,811a246.28,246.28,0,0,0,59.24,9.11c25.3.95,50.63,1.78,75.95,1.94,43.83.28,87.66.1,131.5,0,26-.08,52.08-.72,78.06-2.74a234.52,234.52,0,0,0,45.76-8c24.54-6.92,46.82-18.12,66.22-34.79,24.65-21.17,41.5-47.44,51.3-78.36,6.7-21.14,9.83-42.88,10.73-64.94.9-21.84,1.73-43.69,1.82-65.55q.33-78.21-.15-156.44C837.42,387.82,836.72,364.47,834.35,341.22Zm-55.3,232.84c-.12,20.41-1,40.84-2,61.24-1,19.2-4.13,38.08-11.74,55.92q-18.43,43.24-62.47,60c-14.36,5.48-29.3,8.3-44.55,9.53-27.07,2.18-54.21,2.63-81.36,2.73-21.31.07-42.62,0-63.93,0v-.16c-28.47,0-56.94.22-85.4-.09-17.5-.18-35-1-52.49-1.89-19.94-1-39.51-4.31-57.95-12.38q-41.6-18.2-58-60.68a162.37,162.37,0,0,1-9.95-45.62c-2-24.66-2.62-49.38-2.66-74.1-.09-50.88-.16-101.77.12-152.65.11-19,1-38.09,2-57.11a180,180,0,0,1,8.78-48.23c8.32-24.84,23.63-44.14,45.66-58.12,11.78-7.48,24.85-11.91,38.36-15,15.57-3.61,31.43-4.65,47.34-5.32,54.32-2.28,108.68-1.46,163-1.5,18.67,0,37.34.12,56,.56,15.84.38,31.7,1,47.51,2,18.33,1.18,36.27,4.59,53.19,12q41.67,18.25,58.1,60.83c5.67,14.7,8.64,30,9.91,45.63,2,25,2.63,50,2.67,75.09C779.25,475.82,779.35,524.94,779.05,574.06Z" fill="#999"/><path d="M513,330.12c-92-.34-167,74.55-167.08,166.87s74.71,167,167,167A166.86,166.86,0,0,0,679.77,497.12C679.87,405,605.46,330.45,513,330.12Zm-.29,275.31A108.38,108.38,0,1,1,621.21,497.15,108.38,108.38,0,0,1,512.7,605.43Z" fill="#999"/><path d="M686.47,284.5a39,39,0,1,0,38.92,39.14A39,39,0,0,0,686.47,284.5Z" fill="#999"/>
1857    </svg>
1858
1859  
1860
1861        <span class="fallback-text">Instagram</span>
1862      </a>
1863    </li>
1864  
1865  
1866  
1867    <li>
1868      <a class="icon-fallback-text" href="https://www.youtube.com/" title="Tip Top Fruits & Groceries on YouTube" target="_blank">
1869        
1870
1871
1872
1873    <svg xmlns="http://www.w3.org/2000/svg" class="youtube-icon-svg social-icon-svg" viewBox="0 0 1024 1024">
1874        <title>icon-youtube</title>
1875        <path d="M870.81,327.93c-7.44-35.32-28.1-59.52-60.39-71.9-16.32-6.27-33.58-8-50.71-9.35-31.74-2.54-63.52-4.94-95.32-6.05q-68.85-2.41-137.75-2.8c-75.45-.43-150.91.42-226.25,5.31a672.25,672.25,0,0,0-68,7.84c-35.52,6-75.56,36.22-83.33,86.62a946.72,946.72,0,0,0-10.15,116.2c-1.48,49.67-1.33,99.34,1.42,149,1.57,28.34,4.16,56.51,9,84.49,6.1,35.11,25.46,59,54.45,75.29,17.17,9.66,36,12.91,54.91,14.37,38.69,3,77.44,5.58,116.21,7,42.47,1.56,85,1.63,127.49,2.35v-.91c27.2,0,54.4.26,81.6-.06,59.05-.68,118.09-1.91,176.89-8.23,14.61-1.57,29.51-3.48,43.44-8.06,29.6-9.75,52.29-29.47,63.23-60.8,5.32-15.27,7.62-31.93,9.82-48.18,5.81-43.06,7.61-86.47,8.39-129.92a1196.45,1196.45,0,0,0-5.15-133.62C878.49,373.5,875.55,350.44,870.81,327.93ZM440.45,633.7V390L627.17,511.81Z" fill="#999"/>
1876    </svg>
1877
1878  
1879
1880        <span class="fallback-text">YouTube</span>
1881      </a>
1882    </li>
1883  
1884  
1885  
1886    <li>
1887      <a class="icon-fallback-text" href="https://www.wechat.com/" title="Tip Top Fruits & Groceries on Wechat" target="_blank">
1888        
1889
1890
1891
1892    <svg xmlns="http://www.w3.org/2000/svg" class="wechat-icon-svg social-icon-svg" viewBox="0 0 1024 1024">
1893        <title>icon-wechat</title>
1894        <path d="M509.37,482.16c29.49-24.59,63.48-40.07,100.86-48.3a294.69,294.69,0,0,1,44.64-6.5c5.71-.37,11.4-.79,17.11-1.08,1.86-.1,2.77-.6,2.42-2.69s-.42-4.28-.61-6.43a220.51,220.51,0,0,0-7.19-40C656,339.07,635.46,306.83,607.75,279c-28.36-28.5-61.83-49-99.56-62.69A283.2,283.2,0,0,0,417,199.23a213.94,213.94,0,0,0-24.16.59c-13,1.2-26.13,2.3-38.94,4.79-26.94,5.23-52.62,14.48-77.2,26.72C223.21,258,183.68,297.88,161,353.71c-9.81,24.2-15.95,49.33-16.92,75.46a264.06,264.06,0,0,0,1.51,35.32c2,19.79,7.67,38.67,15.79,56.79,16.2,36.18,40.74,65.8,71.65,90.31,5.36,4.25,10.89,8.29,16.38,12.37,4.93,3.67,7.12,8.26,5.36,14.43-1.42,4.94-2.86,9.89-4,14.9-4.58,20.71-9.05,41.45-13.55,62.18-.67,3.09-1.31,6.2-2.13,10.06,1.92-1.16,3-1.81,4.14-2.49,24.62-15.41,49.21-30.88,73.89-46.2,5.56-3.46,11.19-7,17.2-9.49,8.12-3.39,16.8-2,25.27-1.09,10.7,1.12,21.38,2.41,32,3.73,11.14,1.37,22.26,2.87,33.39,4.3,4.15.53,8.32,1,12.79,1.55,0-1.4,0-2.24,0-3.07-.54-8.87-1.34-17.74-1.6-26.63a203.63,203.63,0,0,1,5.42-53.2C448.47,547.52,474,511.61,509.37,482.16ZM514.5,349a39.34,39.34,0,1,1,.23,78.68c-22.59,0-40.23-17.22-40.22-39.24C474.53,366.87,492.52,349.12,514.5,349ZM318.71,427.66c-22.27,0-39.42-17.12-39.48-39.51-.06-21.76,17.28-39,39.35-39.11s40.28,17.87,40.3,39.75C358.9,410.07,340.76,427.61,318.71,427.66Z" fill="#999"/><path d="M872.26,588.13c-17.12-52.29-51.4-89.71-100.43-113.63-36.54-17.84-75.42-25-116.08-22.74a229.67,229.67,0,0,0-41.87,6c-46,11.25-84.79,34.59-115,71.23-29.36,35.63-42.93,76.58-38.61,122.87a159.58,159.58,0,0,0,20.55,64.22c17.53,30.94,42.08,55.13,72,74.06a197.32,197.32,0,0,0,60.32,25.26A226.27,226.27,0,0,0,653.94,821c14.18.73,28.34.55,42.24-2.35,11.7-2.43,23.17-5.94,34.79-8.79,13.65-3.36,27.33-3.68,40.59,1.46,9.31,3.61,18.3,8.06,27.42,12.15,1,.44,1.94.94,2.91,1.41l.44-.56-1.2-3.12A45.11,45.11,0,0,1,798.44,798c1.49-9.7,6.24-17.84,12.75-24.89,5.4-5.85,11.26-11.28,17-16.82,30.25-29.33,48-64.76,51.33-106.91A156.1,156.1,0,0,0,872.26,588.13ZM571.12,613.35a34.25,34.25,0,1,1,.73-68.5c19.32.06,34.27,15.33,34.16,34.9C605.9,598.49,590.39,613.47,571.12,613.35Zm158.69-.1c-19.24-.43-33.87-15.38-33.57-34.53A34,34,0,0,1,730.63,545c18.66,0,33.41,15.37,33.4,34.69A33.63,33.63,0,0,1,729.81,613.25Z" fill="#999"/>
1895    </svg>
1896
1897  
1898
1899        <span class="fallback-text">Wechat</span>
1900      </a>
1901    </li>
1902    
1903  
1904    <li>
1905      <a class="icon-fallback-text" href="https://whatsapp.com/" title="Tip Top Fruits & Groceries on Whatsapp" target="_blank">
1906        
1907
1908
1909
1910    <svg xmlns="http://www.w3.org/2000/svg" class="whatsapp-icon-svg social-icon-svg" viewBox="0 0 1024 1024">
1911        <title>icon-whatsapp</title>
1912        <path d="M816.7,348.82A345.81,345.81,0,0,0,694.1,218.71c-44.79-28-93.6-44.39-146.07-49.88a345.45,345.45,0,0,0-92,2.72,339.05,339.05,0,0,0-94.38,29.87A343.85,343.85,0,0,0,238,302.05Q177.25,381,167.56,480.22a345,345,0,0,0,43.29,203.46,6.68,6.68,0,0,1,.57,4.56q-16.36,60.35-32.93,120.63c-5.08,18.56-10.2,37.12-15.43,56.13,1.15-.24,1.8-.34,2.43-.51Q254.72,841.08,344,817.7a7.88,7.88,0,0,1,4.84.57c11.92,5.41,23.56,11.5,35.68,16.39a344.42,344.42,0,0,0,274.43-8.3,343.9,343.9,0,0,0,122.89-97q64.35-80.48,74.57-183.1a344.59,344.59,0,0,0-2.88-89.12A336.49,336.49,0,0,0,816.7,348.82ZM799.12,528.11c-3.35,60.82-23.74,115.33-61.56,163C695.72,743.88,641.71,778,576.15,793.47A277.11,277.11,0,0,1,491.09,800a284.89,284.89,0,0,1-129.36-41.68,16.37,16.37,0,0,0-14.17-2c-33.08,8.93-66.26,17.47-99.4,26.13-.46.12-.93.19-2,.42,1.61-5.94,3.07-11.39,4.56-16.83q11.91-43.44,23.73-86.9a6.64,6.64,0,0,0-.91-4.73c-11.53-18-21.73-36.58-29.45-56.51a287.49,287.49,0,0,1-17.41-68.71c-5.7-46-.87-90.81,15-134.35a287.26,287.26,0,0,1,479.82-98.72c32.53,34.66,55.29,74.85,67.86,120.72A284,284,0,0,1,799.12,528.11Z" fill="#999"/><path d="M679.23,590c-12.9-6.08-25.57-12.63-38.44-18.75-10.69-5.09-21.41-10.15-32.36-14.63-8.48-3.47-12.2-1.6-17.82,5.65-8.75,11.27-17.79,22.32-26.93,33.28-4.38,5.25-8.82,6.33-15,3.54-11.48-5.18-23.13-10.16-34.09-16.32C477.68,562,449.73,532.17,428.22,496c-4.54-7.64-4-11.33,2-17.83,8.45-9.23,17.15-18.29,22.45-29.93a16.29,16.29,0,0,0,.44-13.68c-8.9-21.42-17.75-42.87-26.8-64.23a70.6,70.6,0,0,0-6.52-11.83c-2.39-3.56-6.15-5.12-10.51-5-3.28,0-6.56,0-9.84,0,0-.17,0-.34,0-.52-5.1.27-10.26.1-15.27.89-8.07,1.27-14,6.29-19.53,12.06-23.72,24.67-32.22,53.95-26.71,87.44a135.88,135.88,0,0,0,19.34,50.09c9.28,14.85,19.38,29.25,29.94,43.23a405.65,405.65,0,0,0,65.73,68.21c29.34,24.26,62.45,41.51,98.38,53.66,15,5.07,29.89,10.33,46,10.64,10.73.21,21.46.08,31.83-3a103.21,103.21,0,0,0,39.24-22c5.11-4.48,9.77-9.49,12.29-15.89a103.2,103.2,0,0,0,7.06-34.67C687.88,597,685.22,592.79,679.23,590Z" fill="#999"/>
1913    </svg>
1914
1915  
1916
1917        <span class="fallback-text">Whatsapp</span>
1918      </a>
1919    </li>
1920    
1921  
1922  
1923  
1924</ul>
1925
1926            </div>
1927          
1928        </div>
1929  
1930        <hr class="hr--small hr--clear">
1931  
1932        
1933          <div class="grid">
1934            
1935             
1936           
1937            
1938             <div class="grid__item text-center">
1939               <ul class="inline-list payment-icons">
1940                    <li>
1941                    <img src="https://s3-ap-southeast-1.amazonaws.com/eesb.public/images/payment/ssl_certified.png">
1942                    </li>
1943               </ul>
1944             </div>
1945           
1946           </div>
1947         
1948        <div class="grid">
1949    		<div class="grid__item text-center">
1950              	
1951        		<img width="100px" src="https://cdn.store-assets.com/s/861942/f/8407418.png">
1952              <img width="100px" src="https://cdn.store-assets.com/s/861942/f/8407403.png">
1953        	</div>
1954		</div>
1955  
1956         <div class="grid">
1957           <div class="grid__item text-center">
1958             
1959             
1960             <p class="site-footer__links">
1961              
1962              
1963                
1964                  <a href="/legal/refund-policy">Refund Policy</a>
1965                
1966                
1967              
1968                
1969                  | <a href="/legal/privacy-policy">Privacy Policy</a>
1970                
1971                
1972              
1973                
1974                  | <a href="/legal/terms-of-service">Terms of Service</a>
1975                
1976                
1977              
1978                
1979                  | <a href="/legal/delivery-policy">Delivery Policy</a>
1980                
1981                
1982              
1983             </p>
1984             
1985           </div>
1986         </div>
1987  
1988      </div>
1989    </footer>
1990    
1991      
1992<div class="footer-bar large--hide">
1993  <div>
1994    
1995        
1996        
1997        
1998    
1999        
2000        <a href="/">
2001          
2002          	<img src="https://cdn.easystore.blue/s/201/f/5590.png?width=150&format=webp"/>
2003          
2004            <div>
2005              Home
2006            </div>
2007        </a>
2008        
2009
2010    
2011        
2012        
2013        
2014    
2015        
2016        <a href="/collections/all">
2017          
2018          	<img src="https://cdn.easystore.blue/s/201/f/5591.png?width=150&format=webp"/>
2019          
2020            <div>
2021              All products
2022            </div>
2023        </a>
2024        
2025
2026    
2027        
2028        
2029        
2030    
2031        
2032        <a href="/collections/promotion">
2033          
2034          	<img src="https://cdn.store-assets.com/s/861942/f/8317616.png?width=150&format=webp"/>
2035          
2036            <div>
2037              Promotion
2038            </div>
2039        </a>
2040        
2041
2042    
2043        
2044        
2045        
2046    
2047        
2048        <a href="/account/login">
2049          
2050          	<img src="https://cdn.easystore.blue/s/201/f/5593.png?width=150&format=webp"/>
2051          
2052            <div>
2053              Account
2054            </div>
2055        </a>
2056        
2057
2058    
2059  </div>
2060</div>
2061
2062
2063    
2064
2065    
2066    
2067      <div id="scrollTopButton" class="on-right" style="display: none">
2068        <svg class="svg-icon" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M22,18.25a1.21,1.21,0,0,1-.88-.37L12,8.77,2.88,17.88a1.24,1.24,0,0,1-1.76-1.76l10-10a1.24,1.24,0,0,1,1.76,0l10,10a1.24,1.24,0,0,1,0,1.76A1.21,1.21,0,0,1,22,18.25Z"/></svg>
2069      </div>
2070      
2070<script>
2071        $( document ).ready(function() {
2072          var winScroll = $(this).scrollTop(),
2073          this_el = $("#scrollTopButton");
2074
2075          // Header bar
2076          if(winScroll > 400){
2077            this_el.fadeIn();
2078          }else{
2079            this_el.fadeOut();
2080          }
2081
2082          $("#scrollTopButton").click(function() {
2083            $('html,body').animate({ scrollTop: 0 });
2084          });
2085
2086          $(window).scroll(function(){
2087            var winScroll = $(this).scrollTop();
2088
2089            // Header bar
2090            if(winScroll > 400){
2091              this_el.fadeIn();
2092            }else{
2093              this_el.fadeOut();
2094            }
2095
2096          });
2097        });
2098      </script>
2098
2099    
2100
2101  
2102    
2103  
2104    
2104<script src="https://store-themes.easystore.co/861942/themes/2877/assets/fastclick.min.js?t=1787079718" type="text/javascript" ></script>
2104
2105    
2105<script src="https://store-themes.easystore.co/861942/themes/2877/assets/timber.js?v1.1?t=1787079718" type="text/javascript" ></script>
2105
2106    
2106<script src="https://store-themes.easystore.co/861942/themes/2877/assets/theme.js?t=1787079718" type="text/javascript" ></script>
2106
2107  
2108    
2109  
2110    
2111  
2112    
2113
2114<script src="/assets/currencies.js" type="text/javascript" ></script>
vendor: 1 bytes, line 2114
2114
2115<script src="/assets/jquery.currencies.min.js" type="text/javascript" ></script>
vendor: 1 bytes, line 2115
2115
2116<script src="/assets/currencies_format.js" type="text/javascript" ></script>
2116
2117
2118<script>
2119Currency.format = "money_with_currency_format";
2120var shopCurrency = 'MYR';
2121var selectedCurrency = '';
2122
2123
2124  Currency.convert = function(amount, from, to) {
2125    return amount;
2126  };
2127
2128  
2129if( $.cookie("currency") == null ){
2130  
2131  if( selectedCurrency != false ) {
2132
2133  Currency.convertAll(shopCurrency, selectedCurrency);
2134  jQuery('.selected-currency').text(Currency.currentCurrency);  
2135
2136  }
2137
2138}
2139
2140/* Sometimes merchants change their shop currency, let's tell our JavaScript file */
2141// Currency.moneyFormats[shopCurrency].money_with_currency_format = "";
2142// Currency.moneyFormats[shopCurrency].money_format = "RM {{amount}} ";
2143  
2144/* Default currency */
2145var defaultCurrency = 'MYR';
2146  
2147/* Cookie currency */
2148var cookieCurrency = Currency.cookie.read();
2149
2150  cookieCurrency = shopCurrency;
2151
2152$("input[name=current_currency]").val(cookieCurrency);
2153if(cookieCurrency == null){
2154  cookieCurrency = shopCurrency;
2155  Currency.cookie.write(shopCurrency);
2156}
2157/* Fix for customer account pages */
2158jQuery('span.money span.money').each(function() {
2159  jQuery(this).parents('span.money').removeClass('money');
2160});
2161/* Saving the current price */
2162jQuery('span.money').each(function() {
2163  jQuery(this).attr('data-currency-MYR', jQuery(this).html());
2164});
2165// If there's no cookie.
2166if (cookieCurrency == null) {
2167  if (shopCurrency !== defaultCurrency) {
2168    Currency.convertAll(shopCurrency, defaultCurrency);
2169  }
2170  else {
2171    Currency.currentCurrency = defaultCurrency;
2172  }
2173}
2174// If the cookie value does not correspond to any value in the currency dropdown.
2175else if (jQuery('[name=currencies]').size() && jQuery('[name=currencies] option[value=' + cookieCurrency + ']').size() === 0) {
2176  Currency.currentCurrency = shopCurrency;
2177  Currency.cookie.write(shopCurrency);
2178}
2179else if (cookieCurrency === shopCurrency) {
2180  Currency.currentCurrency = shopCurrency;
2181  Currency.convertAll(shopCurrency, cookieCurrency);
2182}
2183else {
2184  Currency.convertAll(shopCurrency, cookieCurrency);
2185}
2186jQuery('[name=currencies]').val(Currency.currentCurrency).change(function() {
2187  var newCurrency = jQuery(this).val();
2188  
2189  
2190    Currency.cookie.write(newCurrency)
2191    if ('customers' == 'cart') {
2192      const params = new URLSearchParams(window.location.search);
2193      params.set('delete_cache', 1);
2194      window.location.search = params;
2195    } else {
2196      window.location.reload();
2197    }
2198  
2199});
2200var original_selectCallback = window.selectCallback;
2201var selectCallback = function(variant, selector) {
2202  var currencies = null;
2203  original_selectCallback(variant, selector);
2204  if(typeof jQuery('[name=currencies]').val() == "undefined"){
2205    currencies = shopCurrency;
2206  }
2207  else{
2208    currencies = jQuery('[name=currencies]').val();
2209  }
2210  Currency.convertAll(shopCurrency, currencies);
2211  jQuery('.selected-currency').text(Currency.currentCurrency);
2212};
2213$('body').on('ajaxCart.afterCartLoad', function(cart) {
2214  Currency.convertAll(shopCurrency, jQuery('[name=currencies]').val());
2215  jQuery('.selected-currency').text(Currency.currentCurrency);  
2216});
2217jQuery('.selected-currency').text(Currency.currentCurrency);
2218</script>
2218
2219
2220
2221  
2222<!-- Snippet:global/body_end: Product Label -->
2223<link href='https://apps.easystore.co/assets/css/product-label/main.css?v2.3' rel='stylesheet' type='text/css' media='screen' />
2223<script src='https://apps.easystore.co/product-labels/productlabelv2.js?shop=christiewttfg.easy.co' type='text/javascript'></script>
2223
2224<!-- /Snippet -->
2225<script>
2226
2227  /*
2228
2229    ------
2230    Events
2231    ------
2232
2233    pages/viewed
2234
2235    customers/signup
2236
2237    customers/login
2238
2239    products/searched
2240
2241    collections/viewed
2242
2243    products/viewed
2244
2245    products/shared
2246
2247    wishlists/item_added
2248
2249    carts/items_added
2250
2251    carts/viewed
2252
2253    carts/item_removed
2254
2255    checkouts/initiated
2256
2257    checkouts/shipping_info_added
2258
2259    checkouts/payment_info_added
2260
2261    checkouts/completed
2262
2263    orders/placed
2264
2265    orders/purchased
2266
2267    payments/captured
2268
2269    payments/failed
2270
2271  */
2272
2273  window.__latest_cart = window.__latest_cart || null;
2274
2275  const _selector = document.querySelector.bind(document),
2276        _selectorAll = document.querySelectorAll.bind(document)
2277
2278  document.addEventListener('DOMContentLoaded', (event) => {
2279
2280    const default_currency = getCookie("currency")
2281    const customer_id = window.__st.cid
2282    const template    = window.__st.p
2283
2284    onPageView()
2285
2286    //-----------------------//
2287    //        Configs        //
2288    //-----------------------//
2289
2290    window.dataLayer = window.dataLayer || []
2291
2292    Array.prototype.last = Array.prototype.last || function() {
2293      return this[this.length - 1] || null
2294    }
2295
2296    Array.prototype.first = Array.prototype.first || function() {
2297      return this[0] || null
2298    }
2299
2300    //----------------------//
2301    //       Triggers       //
2302    //----------------------//
2303
2304    const XHR = window.XMLHttpRequest
2305
2306    function xhr() {
2307
2308      const xhr = new XHR()
2309
2310      xhr.addEventListener("readystatechange", function() {
2311
2312        if(xhr.readyState != 4) return
2313
2314        try {
2315
2316          const response_url = xhr.responseURL
2317
2318          if (response_url.includes("cart/add")) {
2319
2320            window.__latest_cart = JSON.parse(xhr.response)
2321
2322            onCartItemsAdded() // ok
2323
2324          }
2325
2326          if (response_url.includes("cart/remove_item_quantity")) {
2327
2328            window.__latest_cart = JSON.parse(xhr.response)
2329
2330            onCartItemRemoved() // ok
2331
2332          }
2333
2334          if (response_url.includes("new_cart?retrieve=true")) {
2335
2336            result = JSON.parse(xhr.response)
2337
2338            if (result.cart) {
2339              window.__latest_cart = result.cart
2340            }
2341
2342          }
2343
2344        } catch(e) {
2345
2346          console.error(e)
2347
2348        }
2349
2350      }, false);
2351
2352      return xhr
2353
2354    }
2355
2356    window.XMLHttpRequest = xhr
2357
2358    switch(template) {
2359
2360      case 'cart': onCartView() // ok
2361      break
2362      case 'product': onProductView() // ok
2363      break
2364      case 'collection': onCollectionView() // ok
2365      break
2366      case 'blog': onBlogView()
2367      break
2368      case 'article': onArticleView()
2369      break
2370      case 'payment_completed': onOrderPlace()
2371      break
2372      case 'payment_fail': onPaymentFail()
2373      break
2374
2375    }
2376
2377    // _selector('form[action="/checkout/payments"]').addEventListener("submit", onPaymentInfoAdded(_selector('form[action="/checkout/payments"]')))
2378    if (_selector('form[action="/checkout/detail"]'))                            _selector('form[action="/checkout/detail"]').addEventListener("submit", ()=>{onShippingInfoAdded(_selector('form[action="/checkout/detail"]'))})  // ok
2379    if (_selector('form[action="/checkout/shipping"]'))                          _selector('form[action="/checkout/shipping"]').addEventListener("submit", ()=>{onShippingInfoAdded(_selector('form[action="/checkout/shipping"]'))})  // ok
2380    if (_selector('form[action="/account/register"]'))                           _selector('form[action="/account/register"]').addEventListener("submit", onSignUp)  // ok
2381    if (_selector('form[action="/account/login"]'))                              _selector('form[action="/account/login"]').addEventListener("submit", onLogin)  // ok
2382    if (_selector('form[action="/search"]'))                                     _selector('form[action="/search"]').addEventListener("submit", onProductSearch()) // ok
2383    if (_selector('#line-login-btn'))                                            _selector('#line-login-btn').addEventListener('click', onLineLogin) // ok
2384    if (_selector('#PlaceOrder'))                                                _selector('#PlaceOrder').addEventListener("click", ()=>{onCheckoutComplete(_selector('form[action="/checkout/payments"]'))});  // ok
2385    if (_selector('#add_wishlist'))                                              _selector('#add_wishlist').addEventListener("click", onWishlistItemAdded) // ok
2386    if (_selectorAll('a[href="/account/logout"]'))                               _selectorAll('a[href="/account/logout"]').forEach(logoutButton => logoutButton.addEventListener("click", onLogout)) // ok
2387    if (_selector('.CartDrawerTrigger.cart-page-link'))                          _selector('.CartDrawerTrigger.cart-page-link').addEventListener("click", onCartView) // ok
2388    if (_selector('.CartDrawerTrigger.cart-page-link.mobile-cart-page-link'))    _selector('.CartDrawerTrigger.cart-page-link.mobile-cart-page-link').addEventListener("click", onCartView) // ok
2389    if (_selectorAll('a[class^="share-"]'))                                      _selectorAll('a[class^="share-"]').forEach(shareButton => shareButton.addEventListener("click", ()=>{onProductShare(shareButton)}) ) // ok
2390    if (_selectorAll('[name$="checkout"]'))                                      _selectorAll('[name$="checkout"]').forEach(checkoutButton => checkoutButton.addEventListener("click", onCheckoutInitiate))
2391
2392    // For append elements
2393    const bodyMutationObserver = new MutationObserver(() => {
2394      if (_selector('#form__spc #PlaceOrder'))             _selector('#form__spc #PlaceOrder').addEventListener("click", onSinglePageCheckout) // ok
2395      if (_selectorAll('[name$="checkout"]'))              _selectorAll('[name$="checkout"]').forEach(checkoutButton => checkoutButton.addEventListener("click", onCheckoutInitiate))
2396    });
2397    bodyMutationObserver.observe(_selector("body"), {subtree: true, childList: true});
2398
2399    //------------------------------//
2400    //        Event handlers        //
2401    //------------------------------//
2402
2403    function onPageView() {
2404
2405      EasyStore.Event.dispatch('pages/viewed', {
2406        page: {
2407          type: template,
2408          title: document.title,
2409          description: _selector('meta[name=description]') ? _selector('meta[name=description]').getAttribute('content') : null,
2410          url: location.href,
2411        }
2412      })
2413
2414    }
2415
2416    function onSignUp() {
2417
2418      const email_regex = new RegExp(/^[a-zA-Z0-9.!#$%&"*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/)
2419      const phone_regex = new RegExp(/^(\+?6?01)[0-46-9]-*[0-9]{7,8}$/)
2420
2421      const email_or_phone = _selector(`input[name="customer[email_or_phone]"]`).value.replace("+", "").replace(/\s+/, "")
2422
2423      let data = {}
2424
2425      if (email_regex.test(email_or_phone)) {
2426        data.method = 'email'
2427        data.email = email_or_phone
2428      }
2429
2430      if (phone_regex.test(email_or_phone)) {
2431        data.method = "phone"
2432        data.phone = email_or_phone
2433      }
2434
2435      if (!data.method) return
2436
2437      EasyStore.Event.dispatch('customers/signup', data)
2438
2439    }
2440
2441    function onLogin() {
2442
2443      const email_regex = new RegExp(/^[a-zA-Z0-9.!#$%&"*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/)
2444      const phone_regex = new RegExp(/^(\+?6?01)[0-46-9]-*[0-9]{7,8}$/)
2445
2446      const email_or_phone = _selector(`input[name="customer[email_or_phone]"]`).value.replace("+", "").replace(/\s+/, "")
2447
2448      let data = {}
2449
2450      if (email_regex.test(email_or_phone)) {
2451        data.method = 'email'
2452        data.email = email_or_phone
2453      }
2454
2455      if (phone_regex.test(email_or_phone)) {
2456        data.method = "phone"
2457        data.phone = email_or_phone
2458      }
2459
2460      if (!data.method) return
2461
2462      EasyStore.Event.dispatch('customers/login', data)
2463
2464    }
2465
2466    function onLineLogin() {
2467
2468      EasyStore.Event.dispatch('customers/login', { method: 'line' })
2469
2470    }
2471
2472    function onLogout() {
2473
2474      EasyStore.Event.dispatch('customers/logout', { customer_id })
2475
2476    }
2477
2478    function onBlogView() {
2479
2480      const blog = ""
2481
2482      EasyStore.Event.dispatch('blogs/viewed', { blog })
2483
2484    }
2485
2486    function onArticleView() {
2487
2488      const article = ""
2489
2490      EasyStore.Event.dispatch('articles/viewed', { article })
2491
2492    }
2493
2494    function onProductSearch() {
2495
2496      const query = _selector('input[name=q]').value
2497
2498      if (!query) return
2499
2500      EasyStore.Event.dispatch('products/searched', { query })
2501
2502    }
2503
2504    function onCollectionView() {
2505
2506      const collection = ""
2507
2508      EasyStore.Event.dispatch('collections/viewed', { collection })
2509
2510    }
2511
2512    function onProductView() {
2513
2514      const product = ""
2515
2516      EasyStore.Event.dispatch("products/viewed", { product })
2517
2518    }
2519
2520    function onProductShare(el) {
2521
2522      const product = ""
2523
2524      const channel = el.getAttribute("class").split("-").last()
2525
2526      EasyStore.Event.dispatch('products/shared', { product, channel })
2527
2528    }
2529
2530    function onWishlistItemAdded() {
2531
2532      let product  = ""
2533      const quantity = _selector("#Quantity").value
2534
2535      EasyStore.Event.dispatch('wishlists/item_added', { product })
2536
2537    }
2538
2539    async function onCartItemsAdded() {
2540
2541      const cart = await getCart()
2542
2543      if(cart && cart.items != undefined && cart.items.length > 0) {
2544
2545        EasyStore.Event.dispatch('carts/item_added', { cart })
2546
2547      }
2548
2549    }
2550
2551    async function onCartView() {
2552
2553      const cart = await getCart()
2554
2555      EasyStore.Event.dispatch('carts/viewed', { cart })
2556
2557    }
2558
2559    async function onCartItemRemoved() {
2560
2561      const cart = await getCart()
2562
2563      cart.items = []
2564
2565      if(cart) {
2566
2567        EasyStore.Event.dispatch('carts/item_removed', { cart })
2568
2569      }
2570
2571    }
2572
2573    async function onCheckoutInitiate() {
2574
2575      const cart = await getCart()
2576
2577      EasyStore.Event.dispatch('checkouts/initiated', { cart })
2578
2579    }
2580
2581    async function onShippingInfoAdded(form) {
2582      let checkout = getCheckout()
2583
2584      let form_data = {}
2585      new FormData(form).forEach((value, key) => form_data[key] = value)
2586
2587      let shipping_tier = null
2588
2589      if (form_data.type && form_data.type.startsWith("r_pickup")) {
2590        shipping_tier = `Pickup - ${form_data.pick_location}`
2591      }
2592
2593      if (form_data.s_id) {
2594        shipping_tier = _selector(`input[id='`+form_data.s_id+`']`).getAttribute("data-shipping-name")
2595      }
2596
2597      if (!shipping_tier) return
2598
2599      EasyStore.Event.dispatch('checkouts/shipping_info_added', { checkout, shipping_tier })
2600
2601    }
2602
2603    async function onPaymentInfoAdded(form) {
2604
2605      let checkout = getCheckout()
2606
2607      let payment_type = new FormData(form).get('payment_method')
2608
2609      EasyStore.Event.dispatch("checkouts/payment_info_added", { checkout, payment_type })
2610
2611    }
2612
2613    async function onOrderPlace() {
2614
2615      let cart_token  = getCookie("cart_js")
2616      let previous_cart_token = getCookie("previous_cart_ga4_js")
2617
2618      if (previous_cart_token && previous_cart_token == cart_token) {
2619        // Prevent duplicate purchase tracking
2620        return
2621      }
2622
2623      let order = getOrder()
2624
2625      EasyStore.Event.dispatch('orders/placed', { order })
2626
2627      if(order.is_manual_payment) {
2628
2629        EasyStore.Event.dispatch('orders/purchased', { order })
2630
2631      }
2632
2633      const last_transaction = order.transactions.last()
2634
2635      if (last_transaction.status) {
2636
2637        EasyStore.Event.dispatch('orders/purchased', { order })
2638        EasyStore.Event.dispatch('payments/captured', { order })
2639
2640      }
2641
2642    }
2643
2644    async function onPaymentFail() {
2645
2646      const order = getOrder()
2647
2648      EasyStore.Event.dispatch('payments/failed', { order })
2649
2650    }
2651
2652    async function onCheckoutComplete(form) {
2653
2654      onPaymentInfoAdded(form)
2655
2656      const checkout = getCheckout()
2657
2658      EasyStore.Event.dispatch('checkouts/completed', { checkout })
2659
2660    }
2661
2662    async function onSinglePageCheckout() {
2663
2664      // let checkout = $("[data-app-checkout]").data("app-checkout")
2665
2666      let checkout = getCheckout()
2667
2668      // const payment_type = _selector("#app_spc_payment_method").find(`[class*="label-content"]`).first().find("b").first().text()
2669      const payment_type = _selector("#app_spc_payment_method").getElementsByClassName('label-content')[0].getElementsByTagName('b')[0].innerHTML
2670
2671      const shipping_method = _selector("#delivery_method").value
2672
2673      let shipping_tier = null
2674      let app_spc_customer_info_label = _selector("#app_spc_customer_info").getElementsByClassName('label-content')
2675      if (shipping_method == "shipping") {
2676        shipping_tier = app_spc_customer_info_label[app_spc_customer_info_label.length - 1].getElementsByTagName('b')[0].innerHTML
2677      }
2678
2679      if (shipping_method == "pickup") {
2680        shipping_tier = app_spc_customer_info_label[0].innerHTML
2681      }
2682
2683      if (shipping_tier) {
2684
2685        EasyStore.Event.dispatch('checkouts/shipping_info_added', {
2686          checkout,
2687          shipping_tier,
2688        })
2689
2690      }
2691
2692      if (payment_type) {
2693
2694        EasyStore.Event.dispatch('checkouts/payment_info_added', {
2695          checkout,
2696          payment_type,
2697        })
2698
2699      }
2700
2701      EasyStore.Event.dispatch('checkouts/completed', { checkout })
2702
2703    }
2704
2705  })
2706
2707
2708  //-----------------------//
2709  //       Functions       //
2710  //-----------------------//
2711
2712  function getCookie(name) {
2713
2714    name += "="
2715
2716    decodedCookie = decodeURIComponent(document.cookie)
2717
2718    ca = decodedCookie.split(";")
2719
2720    for(i = 0; i < ca.length; i++) {
2721      c = ca[i]
2722      while (c.charAt(0) == " ") {
2723        c = c.substring(1)
2724      }
2725      if (c.indexOf(name) == 0) {
2726        return c.substring(name.length, c.length)
2727      }
2728    }
2729
2730    return ""
2731
2732  }
2733
2734  const parsePrice = price => {
2735    if(typeof price === 'string') {
2736      return parseFloat(price.split(',').join(''))
2737    }
2738
2739    return price
2740  }
2741
2742  const requestCart = async (method, data) => {
2743
2744  let response = await fetch('/cart.json', {method: 'GET',headers: {'Content-Type': 'application/json'}})
2745    result = await response.json()
2746
2747    return result.cart
2748
2749  }
2750  const getCart = async (latest = false) => {
2751
2752    let cart = window.__latest_cart
2753
2754    const cart_invalid = !cart || !cart.items || (cart.total_price > 0 && !cart.items.length)
2755
2756    if(latest || cart_invalid) {
2757      cart = await requestCart()
2758    }
2759
2760    cart.items = cart.items || []
2761
2762    return mapCart(cart)
2763
2764  }
2765
2766  const getCheckout = async () => {
2767    mapCheckout(window.__latest_cart || await requestCart())
2768  }
2769
2770  const getOrder = async () => {
2771    mapOrder(window.__latest_cart || await requestCart())
2772  }
2773
2774  //-----------------------//
2775  //        Mappers        //
2776  //-----------------------//
2777
2778  const fallbackAttribute = (object, attribute) => {
2779
2780    if(!Array.isArray(attribute)) {
2781      attribute = [attribute]
2782    }
2783
2784    let final_value = null
2785
2786    do {
2787
2788      final_value = object[attribute.shift()]
2789
2790    } while(!final_value && attribute.length)
2791
2792    return final_value
2793
2794  }
2795
2796  const map = (object, mapper) => {
2797
2798    const newObject = {}
2799
2800    for(const key in mapper) {
2801
2802      // Handle different keys between new and old format
2803      newObject[key] = fallbackAttribute(object, mapper[key])
2804
2805      // Cast price to float
2806      if(newObject[key] && ['price', 'amount', 'discount', 'discounts'].some(x => key.endsWith(x))) {
2807        newObject[key] = parsePrice(newObject[key])
2808      }
2809
2810      if(newObject[key] === undefined) {
2811        delete newObject[key]
2812      }
2813
2814    }
2815
2816    return newObject
2817
2818  }
2819
2820  const mapCart = cart => {
2821
2822    const oldCart = cart
2823
2824    const mapper = {
2825      id: 'id',
2826      currency: 'currency',
2827      item_count: 'item_count',
2828      items: 'items',
2829      total_price: 'total_price',
2830      latest_items: 'latest_items'
2831    }
2832
2833    cart = map(cart, mapper)
2834
2835    const discounts = (oldCart.storewide_discounts || []).concat((oldCart.voucher_discounts || []))
2836
2837    cart.discount_applications = discounts.map(discount => ({
2838      title: discount.voucher_code || null,
2839      value: parsePrice(discount.amount),
2840    }))
2841
2842    cart.original_total_price = cart.items.length
2843    ? cart.items
2844      .map(item => item.original_price)
2845      .reduce((sum, price) => sum + price)
2846    : 0
2847
2848    cart.total_discount = cart.discount_applications.length
2849    ? cart.discount_applications
2850      .map(discount => parsePrice(discount.value))
2851      .reduce((sum, value) => sum + value)
2852    : 0
2853
2854    cart.items = cart.items.map(item => mapLineItem(item))
2855
2856    return cart
2857
2858  }
2859
2860  const mapCheckout = checkout => {
2861
2862    const mapper = {
2863      note: 'note',
2864      attributes: 'note_attributes',
2865      billing_address: 'billing_address',
2866      currency: 'currency',
2867      customer_id: 'customer_id',
2868      discounts_amount: 'total_discount',
2869      id: 'id',
2870      line_items: 'order_item',
2871      order_number: 'order_number',
2872      shipping_address: 'shipping_address',
2873      shipping_price: 'shipping_tax',
2874      shipping_method: 'shipping_method_name',
2875      tax_price: 'total_tax',
2876    }
2877
2878    checkout = map(checkout, mapper)
2879
2880    checkout.requires_shipping = checkout.line_items.some(item => item.shipping_required)
2881
2882    checkout.line_items = checkout.line_items.map(item => mapLineItem(item))
2883
2884    return checkout
2885
2886  }
2887
2888  const mapOrder = order => {
2889
2890    const mapper = {
2891      attributes: 'note_attributes',
2892      billing_address: 'billing_address',
2893      cancelled: 'is_cancelled',
2894      cancelled_at: 'cancelled_at',
2895      created_at: 'created_at',
2896      customer_id: 'customer_id',
2897      // discount_applications: 'discount_applications',
2898      email: 'email',
2899      financial_status: 'financial_status',
2900      fulfillment_status: 'fulfillment_status',
2901      line_items: 'order_item',
2902      note: 'note',
2903      order_number: 'order_number',
2904      phone: 'phone',
2905      shipping_address: 'shipping_address',
2906      shipping_methods: 'shipping_methods',
2907      shipping_price: 'total_shipping',
2908      subtotal_price: 'subtotal_price',
2909      // tax_lines: 'tax_lines',
2910      tax_price: 'total_tax',
2911      total_discounts: 'total_discount',
2912      total_net_amount: 'total_amount_include_transaction',
2913      total_price: 'total_price',
2914      transactions: 'transaction_records',
2915      is_manual_payment: 'is_manual_payment',
2916    }
2917
2918    order.email = order.billing_address.email
2919    order.phone = order.billing_address.phone
2920    order.shipping_method = order.shipping_method_name
2921
2922    order = map(order, mapper)
2923
2924    order.line_items = order.line_items.map(item => mapLineItem(item))
2925    order.transactions = order.transactions.map(transaction => mapTransaction(transaction))
2926
2927    return order
2928
2929  }
2930
2931  const mapLineItem = line_item => {
2932
2933    const old_line_item = line_item
2934
2935    const mapper = {
2936      final_price: 'price',
2937      image: 'img_url',
2938      message: 'message',
2939      original_line_price: 'original_line_price',
2940      original_price: 'original_price',
2941      properties: 'properties',
2942      quantity: 'quantity',
2943      requires_shipping: 'shipping_required',
2944      sku: 'sku',
2945      taxable: 'taxable',
2946      title: 'product_name',
2947      product_name: 'product_name',
2948      url: 'url',
2949      product_id: 'product_id',
2950      variant_id: 'variant_id',
2951      id: ['id', 'i_id'],
2952    }
2953
2954    line_item = map(line_item, mapper)
2955
2956    line_item.product_id = line_item.product_id || (old_line_item.product && old_line_item.product.id) || null
2957    line_item.variant_id = line_item.variant_id || (old_line_item.variant && old_line_item.variant.id) || null
2958    line_item.image      = line_item.image || (old_line_item.image && old_line_item.image.url) || null
2959
2960    return line_item
2961
2962  }
2963
2964  const mapTransaction = transaction => {
2965
2966    const mapper = {
2967      amount: 'amount',
2968      created_at: 'created_at',
2969      gateway: 'gateway_type',
2970      id: 'id',
2971      status: 'status',
2972    }
2973
2974    transaction = map(transaction, mapper)
2975
2976    return transaction
2977
2978  }
2979
2980
2981</script>
2981
2982
2983</div>
2984
2985  
2986    
2987<style>
2988  #CartTemplate{
2989    min-height: 80vh;
2990  }
2991  .cart-drawer .cart__row .small--one-whole,
2992  .cart-drawer .cart-sticky-button-wrapper{
2993    width: 100%;
2994  }
2995  .cart-drawer .promotion__code-input .input-group{
2996    margin-top: 20px;
2997    max-width: 100%;
2998  }
2999  .cart-drawer-wrapper{
3000    display: flex;
3001    flex-wrap: wrap;
3002    flex-direction: row;
3003  }
3004  .cart-drawer-wrapper > div{
3005    width: 100%;
3006  }
3007  vouchers-modal .vouchers-modal.active ,
3008  vouchers-modal #vouchers-modal-backdrop.active{
3009    z-index: 2147483647;
3010  }
3011</style>
3012
3013<div id="CartDrawer" class="cart-drawer" data-fetch="0">
3014  
3015
3016  <div class="cart-drawer-wrapper">
3017    
3018<!-- Snippet:cart/content_top: Google Analytics 4 -->
3019<div id="CartDataStorage" data-cart='{"item_count":0,"total_price":0,"announcements":[]}'></div>
3020
3021<!-- /Snippet -->
3022<div id="cart-promotion-top"></div>
3023
3024
3025    <div id="CartTemplate">
3026      
3027
3028
3029  
3030
3031  <div id="noCartItem" class="cart-drawer-content">
3032    <div class="cart-drawer-content-wrapper text-center">
3033      <div class="section-header">
3034        <span></span>
3035        <span class="CartDrawerTrigger icon icon-x"></span>
3036      </div>
3037      <div class="section-header__title h2">Your cart is currently empty.</div>
3038      <a class="btn btn--secondary" href="/collections/all">Continue shopping</a>
3039    </div>
3040  </div>
3041
3042
3043
3044    </div>
3045
3046    <link href="/assets/css/promotion.css?v2.94" rel="stylesheet" type="text/css" media="screen" />
3047<div id="cart-promotion-section"></div>
3048
3049<script>var shop_money_format = "<span class=money data-ori-price='{{amount}}'>RM {{amount}} </span>";</script>
vendor: 1 bytes, line 3049
3049
3050<script src="/assets/js/promotion/promotion.js?v1.11" type="text/javascript"></script>
3050
3051
3052<script>
3053
3054    window.EasyStore = window.EasyStore || {};
3055    window.EasyStore.Promotion = window.EasyStore.Promotion || {};
3056
3057    var get_cart_promo_initial = false,
3058        current_template = 'customers';
3059
3060    window.EasyStore.Promotion.updateCartPromotion = function (){
3061        get_cart_promo_initial = true
3062        $.ajax({
3063        type: "GET",
3064        dataType: 'json',
3065        url: "/new_cart/promotion",
3066        success: function(response){
3067            $("#cart-promotion-section").html(response["cart/content_bottom"].trim());
3068            $("#cart-promotion-top").html(response["cart/content_top"].trim());
3069
3070            promoVariantDetailInitial()
3071        },
3072        error: function(xhr){
3073        }
3074        });
3075    }
3076
3077
3078    if(current_template == 'cart') {
3079        document.addEventListener("DOMContentLoaded", function() {
3080            window.EasyStore.Promotion.updateCartPromotion()
3081        });
3082    }
3083
3084</script>
vendor: 1 bytes, line 3084
3084
3085<script>
3086  document.addEventListener('DOMContentLoaded', function () {
3087    window._getVoucherErrorTranslation = Object.assign(window._getVoucherErrorTranslation || {}, {
3088      "condition_not_matched":    "Voucher condition not matched",
3089      "promotion_unavailable":    "This promotion is currently unavailable",
3090      "available_on":             "Available on channels",
3091      "available_on_only":        "Available on channels only",
3092      "available_with_locations": "Available on channels (locations only)",
3093      "pos_at_locations":         "Retail Store at locations only",
3094      "channel_website":          "Website",
3095      "channel_mobile":           "Mobile Apps",
3096      "channel_pos":              "Retail Store"
3097    });
3098  });
3099</script>
3099
3100
3101  </div>
3102  
3103
3104  
3105</div>
3106
3107<div id="toast"><div id="toastContent"></div></div>
3108<style>
3109  .cart-drawer .cart-drawer-content .cart-sticky-button-wrapper a.btn.CartDrawerTrigger{margin-bottom: 10px !important;}
3110  #toastContent a{color: #fff;text-decoration: underline;margin-top: 10px;display: block;}
3111  #toastContent .svg-icon{margin-right: 8px;margin-top: -1px;}
3112</style>
3113
3114<script type="text/javascript">
3115  $('body').on("submit", "#CartForm", function() {
3116    $(this).find('[type=submit]').addClass('btn--loading');
3117  });
3118  
3119  $("input[name=current_currency]").val($( "select.currency-picker" ).val());
3120  $( "select.currency-picker" ).change(function(){
3121    $("select.currency-picker").val($(this).val());
3122    url=window.location.href;
3123    newParam="currency=" + $( "select.currency-picker" ).val();
3124    if(url.indexOf("currency=")===-1){
3125      separator = (url.indexOf("?")===-1)?"?":"&";
3126      newUrl= url + separator + newParam;
3127    }else{
3128      oldParam= new URL(url);
3129      oldParam = oldParam.searchParams.get("currency");
3130      newParam= $(this).val();
3131      newUrl=url.replace(oldParam,newParam);
3132    }
3133    $("input[name=current_currency]").val($( "select.currency-picker" ).val());
3134    // window.location.href =newUrl;
3135    $('#CartDrawer').attr('data-fetch', 0);
3136  });
3137
3138  $("body").on("click", ".cart__remove", function() {
3139    $('#CartTemplate').addClass('is-loading');
3140    $.ajax({
3141      type: 'POST',
3142      url: '/cart/remove_item_quantity',
3143      data: {
3144        variant_id: $(this).data( "variant-id"),
3145        item_id: $(this).data( "item-id"),
3146        quantity: $(this).data( "quantity"),
3147        i_id: $(this).data("i_id"),
3148      },
3149      dataType: 'json',
3150      success: function(response){
3151
3152        theme.cartDrawer(response);
3153        $('#CartTemplate').removeClass('is-loading');
3154
3155        if (window.checkProductProperties !== undefined){
3156          window.checkProductProperties();
3157        }      
3158      },
3159      error: function(xhr){
3160        console.log('error',xhr);
3161        $('#CartTemplate').removeClass('is-loading');
3162      }
3163    });
3164
3165  });
3166
3167
3168  $('body').on("click", "#applycode",function() {
3169    
3170    if($("input[name='voucher_code']").val() != '') {
3171
3172      $('#CartTemplate').addClass('is-loading');
3173
3174      $.ajax({
3175        type: 'POST',
3176        url: '/new_cart/voucher',
3177        data: {
3178          voucher_code: $("input[name='voucher_code']").val(),
3179          category: 'create'
3180        },
3181        dataType: 'json',
3182        success: function(response){
3183
3184          // console.log(response);
3185
3186          if(response.error != undefined){
3187            
3188            if(response.error.message != undefined) popToast(response.error.message); 
3189          
3190            $("input[name='voucher_code']").val('')
3191          
3192          } 
3193          
3194          if(response.cart_content != undefined) theme.cartDrawer(response); 
3195
3196          
3197          $('#CartTemplate').removeClass('is-loading');
3198          
3199        },
3200        error: function(xhr){
3201          console.log('error',xhr);
3202          $('#CartTemplate').removeClass('is-loading');
3203        }
3204      });
3205
3206    }
3207
3208  });
3209
3210
3211  $("body").on("click", ".remove_voucher_btn", function() {
3212        $('#CartTemplate').addClass('is-loading');
3213        $.ajax({
3214          type: 'DELETE',
3215          url: '/new_cart/voucher',
3216          data: {
3217            category: 'remove',
3218            order_discount_id: $(this).data( "discount-id")
3219          },
3220          dataType: 'json',
3221          success: function(data){
3222            // console.log(data);
3223            theme.cartDrawer(data);
3224            $('#CartTemplate').removeClass('is-loading');
3225          },
3226          error: function(xhr){
3227            console.log('error',xhr);
3228            $('#CartTemplate').removeClass('is-loading');
3229          }
3230        });
3231
3232    });
3233  
3234
3235  theme.cartDrawer = function(data){
3236    
3237      $('#CartDrawer').attr('data-fetch', 1);
3238      $('#CartTemplate').addClass('is-loading');
3239
3240      
3241      if(typeof data.cart_content  == 'string'){
3242        $('#CartTemplate').html(data.cart_content);
3243      }
3244
3245      let cart_item_count = data.item_count || data.cart.item_count;
3246
3247      if(cart_item_count > 0){
3248        $('.cart-count').removeClass('hidden-count');
3249      }else{
3250        $('.cart-count').addClass('hidden-count');
3251      }
3252
3253      $('.cart-count').text(cart_item_count);
3254      $('#CartTemplate').removeClass('is-loading');
3255      $(".cart-drawer-content").animate({ scrollTop: 0 });
3256
3257      if(window.EasyStore != undefined && window.EasyStore.Promotion != undefined && window.EasyStore.Promotion.updateCartPromotion != undefined) window.EasyStore.Promotion.updateCartPromotion()
3258
3259  }
3260
3261  theme.fetchCartDrawer = function(data){
3262      $('#CartTemplate').addClass('is-loading');
3263      $.ajax({
3264        url: '/new_cart?retrieve=true',
3265        type: 'GET',
3266        success: function(data, status) {
3267          // console.log(data);
3268          theme.cartDrawer(data);
3269
3270          $('#CartTemplate').removeClass('is-loading');
3271
3272          if (window.checkProductProperties !== undefined){
3273            window.checkProductProperties();
3274          }
3275        },
3276        error: function(XMLHttpRequest, textStatus) {
3277          console.log('error',XMLHttpRequest,textStatus);
3278          $('#CartTemplate').removeClass('is-loading');
3279        }
3280      });
3281  }
3282
3283  theme.updateCartDrawer = function(data){
3284    $('#CartTemplate').addClass('is-loading');
3285
3286    $.ajax({
3287      url: '/new_cart/update',
3288      type: 'PUT',
3289      dataType: 'json',
3290      data: $('#CartDrawer form').serialize(),
3291      success: function(data, status) {
3292        theme.cartDrawer(data);
3293
3294        if (window.checkProductProperties !== undefined){
3295          window.checkProductProperties();
3296        }
3297      },
3298      error: function(XMLHttpRequest, textStatus) {
3299        console.log('error',XMLHttpRequest,textStatus);
3300      }
3301    });
3302  }
3303
3304  function debounce(func, wait, immediate) {
3305    var timeout;
3306    return function() {
3307        var context = this, args = arguments;
3308        var later = function() {
3309            timeout = null;
3310            if (!immediate) func.apply(context, args);
3311        };
3312        var callNow = immediate && !timeout;
3313        clearTimeout(timeout);
3314        timeout = setTimeout(later, wait);
3315        if (callNow) func.apply(context, args);
3316    };
3317  };
3318
3319  $('body').on("change", 'input.cart__quantity-selector', function (){
3320    theme.updateCartDrawer();
3321  });
3322
3323
3324  $('#updateCartDrawer').click(function() {
3325    theme.updateCartDrawer();
3326  });
3327
3328  $('body').on("click", ".btn-qty-adjust", function() {
3329
3330    var $button = $(this);
3331    var oldValue = $button.parent().find("input.cart__quantity-selector").val();
3332
3333    if ($button.attr('data-adjust') == 1) {
3334      var newVal = parseFloat(oldValue) + 1;
3335    } else {
3336    // Don't allow decrementing below zero
3337      if (oldValue > 0) {
3338        var newVal = parseFloat(oldValue) - 1;
3339      } else {
3340        newVal = 0;
3341      }
3342    }
3343
3344    $button.parent().find("input").val(newVal);
3345  });
3346    
3347  $('body').on("click", ".btn-qty-adjust", debounce(function() {
3348    theme.updateCartDrawer();
3349  },350));
3350
3351  $('button.checkout').click(function() {
3352    $(this).addClass('btn--loading');
3353  });
3354
3355  var add_cart_success_html = '<svg class="svg-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve"> <g> <g> <path d="M383.841,171.838c-7.881-8.31-21.02-8.676-29.343-0.775L221.987,296.732l-63.204-64.893 c-8.005-8.213-21.13-8.393-29.35-0.387c-8.213,7.998-8.386,21.137-0.388,29.35l77.492,79.561 c4.061,4.172,9.458,6.275,14.869,6.275c5.134,0,10.268-1.896,14.288-5.694l147.373-139.762 C391.383,193.294,391.735,180.155,383.841,171.838z"/> </g> </g> <g> <g> <path d="M256,0C114.84,0,0,114.84,0,256s114.84,256,256,256s256-114.84,256-256S397.16,0,256,0z M256,470.487 c-118.265,0-214.487-96.214-214.487-214.487c0-118.265,96.221-214.487,214.487-214.487c118.272,0,214.487,96.221,214.487,214.487 C470.487,374.272,374.272,470.487,256,470.487z"/> </g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> </svg>';
3356      add_cart_success_html += 'Added to cart <br><a class="CartDrawerTrigger">View cart</a>';
3357
3358  function popToast(content) {
3359    var x = document.getElementById("toast"),
3360        y = document.getElementById("toastContent");
3361
3362    y.innerHTML = content;
3363    x.className += " show";
3364    
3365    var hideToast = setTimeout(function(){ x.className = x.className.replace(" show", ""); }, 3000);
3366  }
3367
3368</script>
3368
3369
3370<link href="/assets/css/vouchers.css?v1.3" rel="stylesheet" type="text/css" media="screen" />
3371<link href="/assets/account/vouchers/vouchers.css" rel="stylesheet" type="text/css" media="screen" />
3372<link href="/assets/account/vouchers/voucher-widget.css" rel="stylesheet" type="text/css" media="screen" />
3373<script src="/assets/js/promotion/vouchers.js?v1.4" type="text/javascript" ></script>
vendor: 1 bytes, line 3373
3373
3374<script src="/assets/account/vouchers/voucher-widget.js" type="text/javascript" ></script>
3374
3375
3376<vouchers-modal>
3377  <div id="vouchers-modal-backdrop" class="vouchers-modal__close"></div>
3378  <div class="vouchers-modal-wrapper page-width">
3379    <div id="vouchers-modal" class="vouchers-modal focus-inset" aria-modal="true" role="dialog" tabindex="-1">
3380      <div class="vouchers-modal__header">
3381        <div class="vouchers-modal__heading">Vouchers</div>
3382        <button type="button" class="vouchers-modal__close modal__close-button link link--text focus-inset" aria-label="accessibility.close">
3383          <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" role="presentation" class="icon icon-close " fill="none" viewBox="0 0 18 17">
3384            <path d="M.865 15.978a.5.5 0 00.707.707l7.433-7.431 7.579 7.282a.501.501 0 00.846-.37.5.5 0 00-.153-.351L9.712 8.546l7.417-7.416a.5.5 0 10-.707-.708L8.991 7.853 1.413.573a.5.5 0 10-.693.72l7.563 7.268-7.418 7.417z" fill="currentColor">
3385            </path>
3386          </svg>
3387        </button>
3388      </div>
3389
3390      <discount-input>
3391        <div class="field">
3392          <input type="text" id="input-discount_code" class="search__input field__input" name="voucher_code" placeholder="Discount code">
3393          <button type="button" name="apply" class="btn btn--secondary button button--secondary">Apply</button>
3394        </div>
3395        <div class="form__message hidden" tabindex="-1" autofocus>
3396          <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-error " viewBox="0 0 13 13">
3397            <circle cx="6.5" cy="6.50049" r="5.5" stroke="white" stroke-width="2"></circle>
3398            <circle cx="6.5" cy="6.5" r="5.5" fill="#EB001B" stroke="#EB001B" stroke-width="0.7"></circle>
3399            <path d="M5.87413 3.52832L5.97439 7.57216H7.02713L7.12739 3.52832H5.87413ZM6.50076 9.66091C6.88091 9.66091 7.18169 9.37267 7.18169 9.00504C7.18169 8.63742 6.88091 8.34917 6.50076 8.34917C6.12061 8.34917 5.81982 8.63742 5.81982 9.00504C5.81982 9.37267 6.12061 9.66091 6.50076 9.66091Z" fill="white"></path>
3400            <path d="M5.87413 3.17832H5.51535L5.52424 3.537L5.6245 7.58083L5.63296 7.92216H5.97439H7.02713H7.36856L7.37702 7.58083L7.47728 3.537L7.48617 3.17832H7.12739H5.87413ZM6.50076 10.0109C7.06121 10.0109 7.5317 9.57872 7.5317 9.00504C7.5317 8.43137 7.06121 7.99918 6.50076 7.99918C5.94031 7.99918 5.46982 8.43137 5.46982 9.00504C5.46982 9.57872 5.94031 10.0109 6.50076 10.0109Z" fill="white" stroke="#EB001B" stroke-width="0.7"></path>
3401          </svg>
3402          <div class="js-error-content"></div>
3403        </div>
3404      </discount-input>
3405      <br>
3406
3407      
3408      
3409        <div class="empty-vouchers_placeholder">No available vouchers</div>
3410      
3411
3412       <!-- For voucher widget -->
3413      
3413<script type="text/javascript">
3414        let settings = {"logo_use_image":"1","logo_img":"https:\/\/cdn.store-assets.com\/s\/861942\/f\/8388694.png?width=350&format=webp","footer_logo_img":"https:\/\/cdn.store-assets.com\/s\/861942\/f\/8082524.png?width=350&format=webp","nav_below_logo":"","logo_alignment":"center","heading_font_family":["'HelveticaNeue','Helvetica Neue',Helvetica,Arial,sans-serif"],"left_aligned_logo":"0","favicon_enable":"1","favicon_img":"https:\/\/cdn.store-assets.com\/s\/861942\/f\/8088793.png","header_message":"","header_search_enable":true,"topbar_sticky":"1","footer_quicklinks_enable":true,"footer_quicklinks_linklist":"footer","footer_social_enable":true,"footer_show_credit_card_logo":0,"footer_show_methods_of_payment":0,"footer_visa":true,"footer_master":"1","footer_american_express":true,"footer_jcb":0,"footer_diners_club":0,"footer_discover":0,"footer_ssl":true,"show_footer_lines":"1","home_section_1":"home-content","home_section_2":"featured-product","home_section_3":"parallax-section","home_section_4":"","home_section_5":"","home_section_6":"","featured_title":"","featured_1_img":"https:\/\/cdn.store-assets.com\/s\/278885\/f\/3915939.jpeg?width=650&format=webp","featured_1_text":"DRONE","featured_1_link":"","featured_2_img":"https:\/\/cdn.store-assets.com\/s\/278885\/f\/3915945.jpeg?width=650&format=webp","featured_2_text":"TRAVEL","featured_2_link":"\/collections\/travel-pack","featured_3_img":"https:\/\/cdn.store-assets.com\/s\/278885\/f\/3915949.jpeg?width=650&format=webp","featured_3_text":"ACTION","featured_3_link":"\/collections\/action","featured_4_img":"https:\/\/cdn.store-assets.com\/s\/278885\/f\/3915973.jpeg?width=650&format=webp","featured_4_text":"STYLE","featured_4_link":"\/collections\/style","featured_5_img":"","featured_5_text":"","featured_5_link":"\/collections\/all","featured_6_img":"","featured_6_text":"","featured_6_link":"\/collections\/all","featured_7_img":"","featured_7_text":"","featured_7_link":"","featured_8_img":"","featured_8_text":"","featured_8_link":"","parallax_img":"https:\/\/cdn.store-assets.com\/s\/861942\/f\/8235649.jpeg?width=1500&format=webp","parallax_mobile_img":"","parallax_title":"Company History","parallax_subtitle":"Tip-Top Fruits delivers fruits, vegetables and groceries to hotel, restaurant, food court and other F&B business not only in KL but all across the Klang Valley market. We do this with the fastest speeds and the most reliable delivery. If you are in need of fruits, vegetables and other grocery for your business, you can do no better than to partner with Tip- Top Fruits ...","parallax_button_text":"Why us","parallax_button_link":"\/pages\/about","parallax_full_width":"1","slider_home_auto":"1","slider_home_show_dots":"1","slider_home_rate":"5000","slider_home_transition":"slide","slider_full_screen":"0","slide_1":"1","slide_1_jpg":"https:\/\/cdn.store-assets.com\/s\/861942\/f\/14792189.jpg?width=1500&format=webp","slide_1_mobile_jpg":"https:\/\/cdn.store-assets.com\/s\/861942\/f\/14792191.jpg?width=900&format=webp","slide_1_link":"https:\/\/wa.me\/60183833772?text=Hello,%20I%20want%20to%20get%20quotation%20of","slide_1_alt":"","slide_1_title":"","slide_1_subtitle":"","slide_1_button_text":"order now!","slide_2":"1","slide_2_jpg":"https:\/\/cdn.store-assets.com\/s\/861942\/f\/14792200.jpg?width=1500&format=webp","slide_2_mobile_jpg":"https:\/\/cdn.store-assets.com\/s\/861942\/f\/14792202.jpg?width=900&format=webp","slide_2_link":"https:\/\/wa.me\/60183833772?text=Hello,%20I%20want%20to%20get%20quotation%20of","slide_2_alt":"","slide_2_title":"","slide_2_subtitle":"","slide_2_button_text":"get quotation","slide_3":"","slide_3_jpg":"https:\/\/cdn.store-assets.com\/s\/861942\/f\/14792205.jpg?width=1500&format=webp","slide_3_mobile_jpg":"https:\/\/cdn.store-assets.com\/s\/861942\/f\/14792208.jpg?width=900&format=webp","slide_3_link":"https:\/\/wa.me\/60183833772?text=Hello,%20I%20want%20to%20get%20quotation%20of","slide_3_alt":"","slide_3_title":"","slide_3_subtitle":"","slide_3_button_text":"","slide_4":"","slide_4_jpg":"https:\/\/cdn.store-assets.com\/s\/861942\/f\/14792209.jpg?width=1500&format=webp","
3414slide_4_mobile_jpg":"https:\/\/cdn.store-assets.com\/s\/861942\/f\/14792210.jpg?width=900&format=webp","slide_4_link":"https:\/\/wa.me\/60183833772?text=Hello,%20I%20want%20to%20get%20quotation%20of","slide_4_alt":"","slide_4_title":"","slide_4_subtitle":"","slide_4_button_text":"","slide_5":"","slide_5_jpg":"https:\/\/cdn.store-assets.com\/s\/861942\/f\/14792211.jpg?width=1500&format=webp","slide_5_mobile_jpg":"https:\/\/cdn.store-assets.com\/s\/861942\/f\/14792212.jpg?width=900&format=webp","slide_5_link":"https:\/\/wa.me\/60183833772?text=Hello,%20I%20want%20to%20get%20quotation%20of","slide_5_alt":"","slide_5_title":"","slide_5_subtitle":"","slide_5_button_text":"","slide_6":"","slide_6_jpg":"","slide_6_mobile_jpg":"","slide_6_link":"","slide_6_alt":"","slide_6_title":"","slide_6_subtitle":"","slide_6_button_text":"","testimonial_slide_img_crop":0,"testimonial_slide_1_img":"https:\/\/cdn.store-assets.com\/s\/278885\/f\/3915980.jpeg?width=1500&format=webp","testimonial_slide_1_title":"Aleksejs Bergmanis","testimonial_slide_1_content":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur non mattis dui, sit amet hendrerit nibh. Duis congue volutpat urna ut accumsan.","testimonial_slide_1_text_link":"Read more","testimonial_slide_1_link":"#","testimonial_slide_2_img":"https:\/\/cdn.store-assets.com\/s\/278885\/f\/3915981.jpeg?width=1500&format=webp","testimonial_slide_2_title":"Thiago Japyassu","testimonial_slide_2_content":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur non mattis dui, sit amet hendrerit nibh. Duis congue volutpat urna ut accumsan. Vivam mauris augue, ultrices at faucibus vitae, mattis eu lacus.","testimonial_slide_2_text_link":"Read more","testimonial_slide_2_link":"#","testimonial_slide_3_img":"","testimonial_slide_3_title":"","testimonial_slide_3_content":"","testimonial_slide_3_text_link":"","testimonial_slide_3_link":"","testimonial_slide_4_img":"","testimonial_slide_4_title":"","testimonial_slide_4_content":"","testimonial_slide_4_text_link":"","testimonial_slide_4_link":"","testimonial_slide_5_img":"","testimonial_slide_5_title":"","testimonial_slide_5_content":"","testimonial_slide_5_text_link":"","testimonial_slide_5_link":"","testimonial_slide_6_img":"","testimonial_slide_6_title":"","testimonial_slide_6_content":"","testimonial_slide_6_text_link":"","testimonial_slide_6_link":"","logo_list_on_footer":0,"logo_list_title":"","logo_list_1_img":"https:\/\/cdn.store-assets.com\/s\/278885\/f\/3916892.png?width=350&format=webp","logo_list_1_link":"\/collections\/all","logo_list_2_img":"https:\/\/cdn.store-assets.com\/s\/278885\/f\/3916893.png?width=350&format=webp","logo_list_2_link":"\/collections\/all","logo_list_3_img":"https:\/\/cdn.store-assets.com\/s\/278885\/f\/3916894.png?width=350&format=webp","logo_list_3_link":"\/collections\/all","logo_list_4_img":"https:\/\/cdn.store-assets.com\/s\/278885\/f\/3916895.png?width=350&format=webp","logo_list_4_link":"\/collections\/all","logo_list_5_img":"","logo_list_5_link":"\/collections\/all","logo_list_6_img":"","logo_list_6_link":"\/collections\/all","logo_list_7_img":"","logo_list_7_link":"\/collections\/all","logo_list_8_img":"","logo_list_8_link":"\/collections\/all","home_featured_products":"feature-on-homepage","home_featured_products_num":"20","home_featured_products_row_num":"7","home_featured_products_show_heading":"","home_page_content":"home","home_page_show_heading":"0","home_page_add_to_cart":true,"scroll_to_top_button":"on-right","product_quantity_enable":"1","product_image_zoom_type":"lightbox","product_thumbnails_position":"below","product_related_enable":true,"products_per_row":4,"products_list_per_row":"4","product_page_float_btn":"1","product_page_variants_tag":"1","featured_product_title":"Featured products","product_img_res":"grande","product_img_crop":"product_img-crop ratio_1-1","collections_show_sale_circle":"1","collections_show_sold_out_circle":"1","collections_sort_enable":true,"collections_tags_enable":"0","collections_products_per_row":"3","collections_rows":"6","footer_bar":"1","footer_bar_icon_product_page":"1","footer_bar_icon_1":"https:\/\/cdn.easystore.blue\/s\/201\/f\/5590.png?width=150&format=webp","footer_bar_icon_1_text":"Home","footer_bar_icon_1_link":"\/","footer_bar_icon_2":"https:\/\/cdn.easystore.blue\/s\/201\/f\/5591.png?width=150&format=webp","footer_bar_icon_2_text":"All products","footer_bar_icon_2_link":"\/collections\/all","footer_bar_icon_3":"https:\/\/cdn.store-assets.com\/s\/861942\/f\/8317616.png?width=150&format=webp","footer_bar_icon_3_text":"Promotion","footer_bar_icon_3_link":"\/collections\/promotion","footer_bar_icon_4":"https:\/\/cdn.easystore.blue\/s\/201\/f\/5593.png?width=150&format=webp","footer_bar_icon_4_text":"Account","footer_bar_icon_4_link":"\/account\/login","cart_enable_ajax":"1","social_sharing_products":"1","social_sharing_blog":"1","social_sharing_count":"1","share_facebook":"1","share_twitter":"1","share_line":"1","share_pinterest":"1","facebook_url":"https:\/\/www.facebook.com\/","twitter_url":"","pinterest_url":"","instagram_url":"https:\/\/instagram.com\/","tumblr_url":"","youtube_url":"https:\/\/www.youtube.com\/","vimeo_url":"","wechat_url":"https:\/\/www.wechat.com\/","whatsapp_url":"https:\/\/whatsapp.com\/","line_url":"","featured_blog":"","featured_blog_title":"Blog","articles_handle_1":"","articles_handle_2":"","articles_handle_3":"","promotion_uis":{"primary_color":"#F56F00","header_bg_color":"#F56F00","header_text_color":"#fff","recommendation":{"is_show_product_page":true,"is_show_cart_page_top":true,"is_show_cart_page_bottom":true},"voucher_widget":{"primary_color":"#4089e4"}},"show_multiple_currencies":true,"supported_currencies":"MYR ","theme_id":2877,"theme_is_edited":1,"theme_updated_at":"2026-08-18T19:01:58.000Z","phone_account_enabled":false,"line_login_enabled":false,"apple_login_enabled":false,"timezone":"Asia\/Kuala_Lumpur","is_server_side_currency_conversion":true,"is_self_registration_enabled":true,"is_highlight_enabled":false,"is_auto_gen_highlight_enabled":false,"is_common_question_enabled":false,"is_auto_gen_common_question_enabled":false,"highlight_section_title":"Highlights","common_question_section_title":"Frequently asked questions","is_new_promotion_enabled":true}
3415        if (settings.promotion_uis.voucher_widget != null) {
3416          setVoucherTheme(settings.promotion_uis.voucher_widget)
3417        }
3418        var shop = {
3419          money_prefix: "",
3420          format_decimals: ""
3421        };
3422        var _getEntitlementTranslation = {
3423          "free_shipping": "FREE SHIPPING",
3424          "free_of_charge": "FREE GIFT",
3425        }
3426        var _getTargetTypeTranslation = {
3427          "amount_credit": " CREDIT",
3428          "amount_off": " OFF",
3429        }
3430        var _getPrerequisiteTranslation = {
3431          "min_quantity": "Min formatValue item(s) purchase",
3432          "every_quantity": "Every formatValue item(s) purchase",
3433          "min_amount": "Min formatCurrency spend",
3434          "every_amount": "Every formatCurrency spend"
3435        }
3436        var _getPrerequisiteConditionTranslation = {
3437          "selected_items": "Selected Items",
3438          "selected_collections": "Selected Collections",
3439          "storewide": "Storewide",
3440          "order_subtotal": "Order Subtotal"
3441        }
3442        var _getVoucherButtonTextTranslation = {
3443          "apply": "Apply",
3444        }
3445        var _getVoucherErrorTranslation = {
3446          "condition_not_matched": "Voucher condition not matched"
3447        }
3448      </script>
3448
3449
3450    </div>
3451  </div>
3452</vouchers-modal>
3453  
3454  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
3455<a href="https://api.whatsapp.com/send/?phone=60183833772&text&app_absent=0" 
3456   style="position:fixed;
3457	width:45px;
3458	height:45px;
3459	bottom:60px;
3460	left:40px;
3461	background-color:#25d366;
3462    margin-left: -15px;
3463    background-size: 200px 200px;
3464    background-position:top 6px;
3465    background-repeat: no-repeat;
3466	color:#FFF;
3467	border-radius:50px;
3468	text-align:center;
3469  font-size:30px;
3470	box-shadow: 2px 2px 3px #999;
3471  z-index:100;" target="_blank">
3472  <div  style="margin-top:-2px;margin-right:-1px;">
3473    <i class="fa fa-whatsapp"></i>
3474  </div>
3475</a>
3476</body>
3477</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.