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/196384/f/16718342.jpg" /> 15 16 17 <!-- Title and description ================================================== --> 18 <title> 19 Our Blog – ButterflyReptile 20 </title> 21 22 23 <meta name="description" content="Makmal Rama-rama melupuskan 3000 ulat beluncas ketika perintah PKP"> 24 25 26 <!-- Social meta ================================================== --> 27 28 29 <meta property="og:type" content="blog"> 30 <meta property="og:title" content="Our Blog"> 31 <meta property="og:url" content="https://www.butterflyreptile.com/blogs/makmal-rama-rama-melupuskan-3000-ulat-beluncas-ketika-perintah-pkp"> 32 33 34<meta property="og:description" content="Makmal Rama-rama melupuskan 3000 ulat beluncas ketika perintah PKP"> 35<meta property="og:site_name" content="ButterflyReptile"> 36 37 38 39 <meta name="twitter:card" content="summary"> 40 41 42 43 <meta name="twitter:site" content="@"> 44 45 46 <meta name="twitter:title" content="Our Blog"> 47 <meta name="twitter:description" content="Makmal Rama-rama melupuskan 3000 ulat beluncas ketika perintah PKP"> 48 49 50 51 52 <!-- Helpers ================================================== --> 53 <link rel="canonical" href="https://www.butterflyreptile.com/blogs/makmal-rama-rama-melupuskan-3000-ulat-beluncas-ketika-perintah-pkp"> 54 <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"> 55 <meta name="theme-color" content="#000000"> 56 57
57<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js" type="text/javascript" ></script>
57 58 59 <!-- Header hook for plugins ================================================== --> 60 61<!-- ScriptTags -->
62<script>window.__st={p: "blog",cid: null,cem: null,cph: null,cfn: null,cln: null,cge: null,cdb: null,ccc: null};</script>
62<script src='/assets/events.js'></script>
62<script>(function(){function asyncLoad(){var urls=['/assets/traffic.js?v=1','https://apps.easystore.co/marketplace/shopee-malaysia/script.js?shop=butterflyreptile.easy.co','https://apps.easystore.co/instagram-feed/script.js?shop=butterflyreptile.easy.co'];for(var i=0;i<urls.length;i++){var s=document.createElement('script');s.type='text/javascript';s.async=true;s.src=urls[i];var x=document.getElementsByTagName('script')[0];x.parentNode.insertBefore(s, x);}}window.attachEvent ? window.attachEvent('onload', asyncLoad) : window.addEventListener('load', asyncLoad, false);})();</script>
62 63<!-- /ScriptTags --> 64 65 66 67
67<script src="https://store-themes.easystore.co/196384/themes/181882/assets/global.js?t=1787072441" defer="defer"></script>
67 68 69 70 71
71<script> 72 (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ 73 (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), 74 m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) 75 })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); 76 77 ga('create', '', 'auto','myTracker'); 78 ga('myTracker.send', 'pageview'); 79 80 </script>
80 81 82
82<script src="/assets/storefront.js?id=1d419de2011a5572c98b" type="text/javascript" ></script>
82 83 84 85 <!-- CSS ================================================== --> 86 <style> 87 @font-face { 88 font-family: 'Alata'; 89 font-style: normal; 90 font-weight: regular; 91 src: local('Alata regular'), local('Alata-regular'), url(https://fonts.gstatic.com/s/alata/v2/PbytFmztEwbIofe6xKcRQEOX.ttf) format('truetype'); 92 } 93 94 @font-face { 95 font-family: 'Alata'; 96 font-style: normal; 97 font-weight: regular; 98 src: local('Alata regular'), local('Alata-regular'), url(https://fonts.gstatic.com/s/alata/v2/PbytFmztEwbIofe6xKcRQEOX.ttf) format('truetype'); 99 } 100 101 :root { 102 --font-body-family: 'Alata', sans-serif; 103 --font-body-style: normal; 104 --font-body-weight: 500; 105 106 --font-heading-family: 'Alata', sans-serif; 107 --font-heading-style: normal; 108 --font-heading-weight: 700; 109 110 --color-heading-text: 0,0,0; 111 --color-base-text: 0,0,0; 112 --color-base-background-1: 255,255,255; 113 --color-base-background-2: 255,255,255; 114 115 --color-base-solid-button-labels: 255,255,255; 116 --color-base-outline-button-labels: 5,28,98; 117 118 --color-base-accent-1: 0,0,0; 119 --color-base-accent-2: 0,0,0; 120 --payment-terms-background-color: 255,255,255; 121 122 --gradient-base-background-1: 255,255,255; 123 --gradient-base-background-2: 255,255,255; 124 --gradient-base-accent-1: 0,0,0; 125 --gradient-base-accent-2: 0,0,0; 126 127 --page-width: 145rem; 128 } 129 130 *, 131 *::before, 132 *::after { 133 box-sizing: inherit; 134 } 135 136 html { 137 box-sizing: border-box; 138 font-size: 62.5%; 139 height: 100%; 140 } 141 142 body { 143 display: grid; 144 grid-template-rows: auto auto 1fr auto; 145 grid-template-columns: 100%; 146 min-height: 100%; 147 margin: 0; 148 font-size: 1.5rem; 149 letter-spacing: 0.06rem; 150 line-height: 1.8; 151 font-family: var(--font-body-family); 152 font-style: var(--font-body-style); 153 font-weight: var(--font-body-weight); 154 155 } 156 157 @media screen and (min-width: 750px) { 158 body { 159 font-size: 1.6rem; 160 } 161 } 162 </style> 163 164 <link href="https://store-themes.easystore.co/196384/themes/181882/assets/base.css?t=1787072441" rel="stylesheet" type="text/css" media="screen" /> 165 166 167 168<!-- Snippet:global/head: Shopee Malaysia --> 169<link type="text/css" rel="stylesheet" href="https://apps.easystore.co/assets/css/marketplace/main.css?v1.7"> 170<!-- /Snippet --> 171 172<!-- Snippet:global/head: Instagram Feed --> 173<link rel="stylesheet" href="https://apps.easystore.co/assets/css/instagram-feed/insta-feed-style.css?v3"> 174<!-- /Snippet --> 175 176 177
177<script>document.documentElement.className = document.documentElement.className.replace('no-js', 'js');</script>
177 178</head> 179 180<body id="our-blog" class="template-blog" > 181 182 183<!-- Snippet:global/body_start: Announcement Bar --> 184<style type="text/css"> 185 body { 186 background-position: top 45px center; 187 } 188 189 div#announcement-bar-top { 190 height: 45px; 191 } 192 193 span .announcement-close-button { 194 text-align: center; 195 display: -webkit-flex; 196 display: -moz-flex; 197 display: -ms-flex; 198 display: -o-flex; 199 display: inline-block; 200 align-items: center; 201 flex-wrap: wrap; 202 justify-content: center; 203 } 204 205 #announcementBar_countdown:empty { 206 display: none; 207 } 208 209 210 .announcementBar_timer { 211 margin: 5px 0px; 212 } 213 214 .announcementBar_timer.style_1, 215 .announcementBar_timer.style_2 { 216 display: -webkit-inline-flex; 217 display: -moz-inline-flex; 218 display: -ms-inline-flex; 219 display: -o-inline-flex; 220 display: inline-flex; 221 align-items: center; 222 padding: 5px 8px; 223 margin: 3px 0px 3px 10px; 224 border-radius: 8px; 225 font-weight: bold; 226 } 227 228 .announcementBar_timer.style_1>div, 229 .announcementBar_timer.style_2>div { 230 margin: 0 5px; 231 line-height: 1; 232 } 233 234 .announcementBar_timer.style_1 small, 235 .announcementBar_timer.style_2 small { 236 display: block; 237 font-size: 55%; 238 line-height: 1; 239 } 240 241 .announcementBar_timer.style_2 { 242 flex-direction: row; 243 } 244 245 .announcementBar_timer.style_2>div { 246 position: relative; 247 } 248 249 .announcementBar_timer.style_2>div:not(:last-child):after { 250 position: absolute; 251 content: ':'; 252 top: 0; 253 right: 0; 254 margin-right: -7px; 255 } 256 257 .announcementBar_timer.style_3 { 258 display: -webkit-inline-flex; 259 display: -moz-inline-flex; 260 display: -ms-inline-flex; 261 display: -o-inline-flex; 262 display: inline-flex; 263 align-items: center; 264 border-radius: 5px; 265 padding: 5px 5px; 266 margin-left: 10px; 267 font-weight: bold; 268 } 269 270 .announcementBar_timer.style_3>div { 271 margin: 0 3px; 272 line-height: 1; 273 } 274 275 .announcementBar_timer.style_3 small { 276 font-weight: bold; 277 line-height: 1.1; 278 font-size: 65%; 279 } 280 281 .announcement-close-button { 282 position: relative; 283 width: 24px; 284 height: 24px; 285 opacity: 1; 286 background: #000; 287 border-radius: 50%; 288 cursor: pointer; 289 top: 30%; 290 } 291 292 .announcement-close-button:hover { 293 opacity: 0.6; 294 } 295 296 .announcement-close-button:before, 297 .announcement-close-button:after { 298 position: absolute; 299 left: 11px; 300 top: 5px; 301 content: ' '; 302 height: 14px; 303 width: 2px; 304 background-color: #fff; 305 border-radius: 3px; 306 } 307 308 .announcement-close-button:before { 309 transform: rotate(45deg); 310 } 311 312 .announcement-close-button:after { 313 transform: rotate(-45deg); 314 } 315 316 .announcement-bar-button { 317 padding: 4px 8px; 318 vertical-align: baseline; 319 border-radius: 5px; 320 margin-left: 10px; 321 opacity: 1; 322 line-height: 1.1; 323 text-decoration: none; 324 display: inline-block; 325 font-weight: 500; 326 } 327 328 .announcement-bar-button:hover { 329 opacity: 0.8; 330 } 331 332 .announcement-bar-direction-button { 333 cursor: pointer; 334 padding: 0px 8px; 335 } 336 337 .announcement-bar-direction-button:hover { 338 opacity: 0.8; 339 } 340 341 slider-announcement-bar-app { 342 display: block; 343 text-align: center; 344 margin: 0px; 345 padding: 6px 10px; 346 border-top: 1px dashed transparent; 347 border-bottom: 1px dashed transparent; 348 width: 100%; 349 } 350 351 slider-announcement-bar-app ul::-webkit-scrollbar {
352 height: 0.4rem; 353 width: 0.4rem; 354 display: none; 355 } 356 357 slider-announcement-bar-app ul { 358 position: relative; 359 display: flex; 360 overflow-x: auto; 361 -ms-overflow-style: none; 362 /* IE 11 */ 363 scrollbar-width: none; 364 /* Firefox 64 */ 365 scroll-snap-type: x mandatory; 366 scroll-behavior: smooth; 367 /* scroll-padding-left: 1rem; */ 368 -webkit-overflow-scrolling: touch; 369 margin-bottom: 0; 370 padding: 0; 371 list-style: none; 372 align-items: center; 373 } 374 375 slider-announcement-bar-app ul li { 376 width: 100vw; 377 scroll-snap-align: start; 378 flex-shrink: 0; 379 } 380</style> 381 382<input type="hidden" id="total_announcement_left" name="total_announcement_left" value="1"> 383<input type="hidden" id="locale" name="locale" value="en_US"> 384<div id="announcement-bar-top"> </div> 385 386<slider-announcement-bar-app id="announcement-bar" name="announcement-bar" style=" 387 border: unset; 388 padding: 4px 0px; 389 margin: 0px; 390 z-index:2999; 391 background:rgb(248, 19, 46); 392 color:rgba(254, 255, 238, 0.98); 393 position: fixed; top: 0; 394"> 395 396 <div style=" 397 display: flex; 398 justify-content: space-between; 399 align-items: center; 400 padding: 0px 0px; 401 border-top: 0px; 402 border-bottom: 0px; 403 border-color: transparent; 404 "> 405 <div style="height: 24px;"> 406 </div> 407 408 <ul style="flex-grow: 2; margin: 0px;"> 409 <li id="announcement_bar_0" style=" 410 display: flex; 411 justify-content: center; 412 align-items: center; 413 flex-wrap: wrap; 414 margin: 0px; 415 width: 100%; 416 word-wrap: break-word; 417 "> 418 Adopt our Butterfly! HELP our butterfly farming, let love be contagious and provide energy for all well-being! 419 <a class="announcement-bar-button" href="https://www.butterflyreptile.com/collections/adopt-a-butterfly" style="color: rgb(76, 58, 58); background: rgb(255, 255, 255);">Adopt Now!</a> 420 <input type="hidden" id="expired_at_0" name="expired_at_0" value="2021-06-26 11:00"> 421 </li> 422 </ul> 423 424 <div style="display: flex;"> 425 </div> 426 </div> 427 428 429</slider-announcement-bar-app> 430
431<script> 432 (function() { 433 434 const loadScript = function(url, callback) { 435 const script = document.createElement("script"); 436 script.type = "text/javascript"; 437 // If the browser is Internet Explorer. 438 if (script.readyState) { 439 script.onreadystatechange = function() { 440 if (script.readyState == "loaded" || script.readyState == "complete") { 441 script.onreadystatechange = null; 442 callback(); 443 } 444 }; 445 // For any other browser. 446 } else { 447 script.onload = function() { 448 callback(); 449 }; 450 } 451 script.src = url; 452 document.getElementsByTagName("head")[0].appendChild(script); 453 }; 454 455 const announcementBarAppJS = function($) { 456 457 $('#announcement-bar-top').css('height', $('#announcement-bar').outerHeight()); 458 459 $('#announcement-close-button').on('click', function() { 460 $('#announcement-bar, #announcement-bar-top').animate({ 461 marginTop: '-=' + $('#announcement-bar').outerHeight() + 'px' 462 }, 200, 'linear'); 463 }); 464 } 465 466 if (typeof jQuery === 'undefined') { 467 loadScript('//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js', function() { 468 jQuery = jQuery.noConflict(true); 469 announcementBarAppJS(jQuery); 470 }); 471 } else { 472 announcementBarAppJS(jQuery); 473 } 474 475 })(); 476 477 setInterval(function() { 478 const total_announcement = "1" 479 var total_announcement_left = $("#total_announcement_left").val(); 480 481 for (let i = 0; i <= total_announcement; i++) { 482 const startDate = new Date(); 483 const endDateStr = $("#expired_at_" + i).val(); 484 const endDate = endDateStr == undefined ? new Date() : new Date(endDateStr.replace(/-/g, "/")); 485 const seconds = (endDate.getTime() - startDate.getTime()) / 1000; 486 487 const days = parseInt(seconds / 86400); 488 const hours = parseInt((seconds % 86400) / 3600); 489 const mins = parseInt((seconds % 86400 % 3600) / 60); 490 const secs = parseInt((seconds % 86400 % 3600) % 60); 491 492 // use to translate countdown unit 493 // (translate based on the preferred language when save announcement bar setting) 494 String.prototype.translate = function() { 495 try { 496 if ($("#locale").val() == "zh_TW") { 497 if (this.toString() === 'day') { 498 return "天"; 499 } 500 if (this.toString() === 'hour') { 501 return "å°æ"; 502 } 503 if (this.toString() === 'min') { 504 return "åé"; 505 } 506 if (this.toString() === 'sec') { 507 return "ç§"; 508 } 509 } else { 510 if (this.toString() === 'day') { 511 if (days > 0) { 512 return "Days"; 513 } else { 514 return "Day"; 515 } 516 } else if (this.toString() === 'hour') { 517 if (hours > 0) { 518 return "Hours"; 519 } else { 520 return "Hour"; 521 } 522 } else if (this.toString() === 'min') { 523 if (mins > 0) { 524 return "Mins"; 525 } else { 526 return "Min"; 527 } 528 } else if (this.toString() === 'sec') { 529 if (secs > 0) { 530 return "Secs"; 531 } else { 532 return "Sec"; 533 } 534 } 535 } 536 } catch (error) { 537 console.log("Some errors heres", error); 538 } 539 }; 540 541 const announcementBar_countdown = document.getElementById("announcementBar_countdown_" + i); 542 if (announcementBar_countdown && seconds > 0) { 543 544 $(announcementBar_countdown).show() 545 announcementBar_countdown.innerHTML = ` 546 <div> 547 ${days} <small>${'day'.translate()}</small> 548 </div> 549 <div> 550 ${hours} <small>${'hour'.translate()}</small> 551 </div> 552 <div> 553 ${mins} <small>${'min'.translate()}</small> 554 </div> 555 <div> 556 ${secs} <small>${'sec'.translate()}</small> 557 </div> 558 `; 559 $('#announcement-bar-top').css('height', $('#announcement-bar').outerHeight()); 560 561 562 } else if (announcementBar_countdown && seconds <= 0) { 563 $("#announcement_bar_" + i).remove(); 564 total_announcement_left = total_announcement_left - 1; 565 $("#total_announcement_left").val(total_announcement_left); 566 } 567 } 568 569 showOrHide(total_announcement_left); 570 }, 1000); 571 572 573 function showOrHide(total_announcement_left) { 574 if (total_announcement_left <= 1) { 575 $("#previous-announcement-bar-button,#next-announcement-bar-button").hide(); 576 } else { 577 $("#previous-announcement-bar-button,#next-announcement-bar-button").show(); 578 } 579 580 if (total_announcement_left == 0) { 581 $("#announcement-close-button").hide(); 582 $("#announcement-bar").hide(); 583 $('#announcement-bar-top').hide(); 584 } 585 }; 586 587 let annoucementBarAutoMoveInterval = ''; 588 class AnnouncementBarAppSlider extends HTMLElement { 589 constructor() { 590 super(); 591 this.slider = this.querySelector('ul'); 592 this.sliderItems = this.querySelectorAll('li'); 593 this.prevButton = this.querySelector('a[name="previous"]'); 594 this.nextButton = this.querySelector('a[name="next"]'); 595 596 if (!this.slider || !this.nextButton) return; 597 598 const resizeObserver = new ResizeObserver(entries => this.initPages()); 599 resizeObserver.observe(this.slider); 600 601 this.slider.addEventListener('scroll', this.update.bind(this)); 602 this.prevButton.addEventListener('click', this.onButtonClick.bind(this)); 603 this.nextButton.addEventListener('click', this.onButtonClick.bind(this)); 604 605 606 } 607 608 initPages() { 609 const sliderItemsToShow = Array.from(this.sliderItems).filter(element => element.clientWidth > 0); 610 this.sliderLastItem = sliderItemsToShow[sliderItemsToShow.length - 1]; 611 if (sliderItemsToShow.length === 0) return; 612 this.slidesPerPage = Math.floor(this.slider.clientWidth / sliderItemsToShow[0].clientWidth); 613 this.totalPages = sliderItemsToShow.length - this.slidesPerPage + 1; 614 this.update(); 615 let self = this 616 var total_announcement_left = $("#total_announcement_left").val(); 617 annoucementBarAutoMoveInterval = setInterval(function() { 618 if (total_announcement_left > 1) { 619 self.moveSlide('next') 620 } 621 }, 5000) 622 } 623 624 update() { 625 this.currentPage = Math.round(this.slider.scrollLeft / this.sliderLastItem.clientWidth) + 1; 626 } 627 628 onButtonClick(event) { 629 event.preventDefault(); 630 let self = this; 631 self.moveSlide(event.currentTarget.name); 632 } 633 634 635 moveSlide(move_to) { 636 637 clearInterval(annoucementBarAutoMoveInterval); 638 let self = this; 639 annoucementBarAutoMoveInterval = setInterval(function() { 640 self.moveSlide('next'); 641 }, 5000) 642 643 if (move_to === 'previous' && this.currentPage === 1) { 644 this.slider.scrollTo({ 645 left: this.sliderLastItem.clientWidth * (this.totalPages - 1) 646 }); 647 } else if (move_to === 'next' && this.currentPage === this.totalPages) { 648 this.slider.scrollTo({ 649 left: 0 650 }); 651 } else { 652 const slideScrollPosition = move_to === 'next' ? this.slider.scrollLeft + this.sliderLastItem 653 .clientWidth : this.slider.scrollLeft - this.sliderLastItem.clientWidth; 654 this.slider.scrollTo({ 655 left: slideScrollPosition 656 }); 657 } 658 } 659 660 } 661 662 customElements.define('slider-announcement-bar-app', AnnouncementBarAppSlider); 663</script>
663 664 665<!-- /Snippet --> 666 667<!-- Snippet:global/body_start: Console Extension --> 668<div id='es_console' style='display: none;'>196384</div> 669<!-- /Snippet --> 670 671 672 <style> 673 header { 674 --logo-width: 230px; 675 } 676 .header-wrapper, 677 .header-wrapper .list-menu--disclosure, 678 .header-wrapper .search-modal{ 679 background-color: #FFFFFF; 680 } 681 .header-wrapper .search-modal .field__input{ 682 background-color: rgb(var(--color-background)); 683 } 684 .header-wrapper summary .icon-caret, 685 .header-wrapper .header__menu-item a, 686 .header-wrapper .list-menu__item, 687 .header-wrapper .link--text{ 688 color: #000000; 689 } 690 691 .search-modal__form{ 692 position: relative; 693 } 694 695 .dropdown { 696 display: none; 697 position: absolute; 698 top: 100%; 699 left: 0; 700 width: 100%; 701 padding: 5px 0; 702 background-color: #fff; 703 color:#000; 704 z-index: 1000; 705 border-bottom-left-radius: 15px; 706 border-bottom-right-radius: 15px; 707 border: 1px solid rgba(var(--color-foreground), 1); 708 border-top: none; 709 overflow-x: hidden; 710 overflow-y: auto; 711 max-height: 350px; 712 } 713 714 .dropdown-item { 715 padding: 0.4rem 2rem; 716 cursor: pointer; 717 line-height: 1.4; 718 overflow: hidden; 719 text-overflow: ellipsis; 720 white-space: nowrap; 721 } 722 723 .dropdown-item:hover{ 724 background-color: #f3f3f3; 725 } 726 727 .search__input.is-focus{ 728 border-radius: 15px; 729 border-bottom-left-radius: 0; 730 border-bottom-right-radius: 0; 731 border: 1px solid rgba(var(--color-foreground), 1); 732 border-bottom: none; 733 box-shadow: none; 734 } 735 736 .clear-all { 737 text-align: right; 738 padding: 0 2rem 0.2rem; 739 line-height: 1; 740 font-size: 70%; 741 margin-bottom: -2px; 742 } 743 744 .clear-all:hover{ 745 background-color: #fff; 746 } 747 748 .search-input-focus .easystore-section-header-hidden{ 749 transform: none; 750 } 751 .referral-notification { 752 position: absolute; 753 top: 100%; 754 right: 0; 755 background: white; 756 border: 1px solid #e0e0e0; 757 border-radius: 8px; 758 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); 759 width: 280px; 760 z-index: 1000; 761 padding: 16px; 762 margin-top: 8px; 763 font-size: 14px; 764 line-height: 1.4; 765 } 766 767 .referral-notification::before { 768 content: ''; 769 position: absolute; 770 top: -8px; 771 right: 20px; 772 width: 0; 773 height: 0; 774 border-left: 8px solid transparent; 775 border-right: 8px solid transparent; 776 border-bottom: 8px solid white; 777 } 778 779 .referral-notification::after { 780 content: ''; 781 position: absolute; 782 top: -9px; 783 right: 20px; 784 width: 0; 785 height: 0; 786 border-left: 8px solid transparent; 787 border-right: 8px solid transparent; 788 border-bottom: 8px solid #e0e0e0; 789 } 790 791 .referral-notification h4 { 792 margin: 0 0 8px 0; 793 color: #2196F3; 794 font-size: 16px; 795 font-weight: 600; 796 } 797 798 .referral-notification p { 799 margin: 0 0 12px 0; 800 color: #666; 801 } 802 803 .referral-notification .referral-code { 804 background: #f5f5f5; 805 padding: 8px; 806 border-radius: 4px; 807 font-family: monospace; 808 font-size: 13px; 809 text-align: center; 810 margin: 8px 0; 811 border: 1px solid #ddd; 812 } 813 814 .referral-notification .close-btn { 815 position: absolute; 816 top: 8px; 817 right: 8px; 818 background: none; 819 border: none; 820 font-size: 18px; 821 color: #999; 822 cursor: pointer; 823 padding: 0; 824 width: 20px; 825 height: 20px; 826 line-height: 1; 827 } 828 829 .referral-notification .close-btn:hover { 830 color: #333; 831 } 832 833 .referral-notification .action-btn { 834 background: #2196F3; 835 color: white; 836 border: none; 837 padding: 8px 16px; 838 border-radius: 4px; 839 cursor: pointer; 840 font-size: 12px; 841 margin-right: 8px; 842 margin-top: 8px; 843 } 844 845 .referral-notification .action-btn:hover { 846 background: #1976D2; 847 } 848 849 .referral-notification .dismiss-btn { 850 background: transparent; 851 color: #666; 852 border: 1px solid #ddd; 853 padding: 8px 16px; 854 border-radius: 4px; 855 cursor: pointer; 856 font-size: 12px; 857 margin-top: 8px; 858 } 859 860 .referral-notification .dismiss-btn:hover { 861 background: #f5f5f5; 862 } 863 .referral-modal__dialog { 864 transform: translate(-50%, 0); 865 transition: transform var(--duration-default) ease, visibility 0s; 866 z-index: 10000; 867 position: fixed; 868 top: 20vh; 869 left: 50%; 870 width: 100%; 871 max-width: 350px; 872 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); 873 border-radius: 12px; 874 background-color: #fff; 875 color: #000; 876 padding: 20px; 877 text-align: center; 878 } 879 880 .modal-overlay.referral-modal-overlay { 881 position: fixed; 882 top: 0; 883 left: 0; 884 width: 100%; 885 height: 100%; 886 background-color: rgba(0, 0, 0, 0.7); 887 z-index: 2001; 888 display: block; 889 opacity: 1;
890 transition: opacity var(--duration-default) ease, visibility 0s; 891 } 892</style> 893 894<link rel="preload" href="https://store-themes.easystore.co/196384/themes/181882/assets/section-header.css?t=1787072441" as="style" onload="this.onload=null;this.rel='stylesheet'"> 895<link rel="preload" href="https://store-themes.easystore.co/196384/themes/181882/assets/component-list-menu.css?t=1787072441" as="style" onload="this.onload=null;this.rel='stylesheet'"> 896<link rel="preload" href="https://store-themes.easystore.co/196384/themes/181882/assets/component-menu-drawer.css?t=1787072441" as="style" onload="this.onload=null;this.rel='stylesheet'"> 897<link rel="preload" href="https://store-themes.easystore.co/196384/themes/181882/assets/component-cart-notification.css?v1.1?t=1787072441" as="style" onload="this.onload=null;this.rel='stylesheet'"> 898
899<script src="https://store-themes.easystore.co/196384/themes/181882/assets/cart-notification.js?t=1787072441" defer="defer"></script>
vendor: 2 bytes, line 899
899
900<script src="https://store-themes.easystore.co/196384/themes/181882/assets/details-modal.js?t=1787072441" defer="defer"></script>
900 901 902<svg xmlns="http://www.w3.org/2000/svg" class="hidden"> 903 <symbol id="icon-search" viewbox="0 0 18 19" fill="none"> 904 <path fill-rule="evenodd" clip-rule="evenodd" d="M11.03 11.68A5.784 5.784 0 112.85 3.5a5.784 5.784 0 018.18 8.18zm.26 1.12a6.78 6.78 0 11.72-.7l5.4 5.4a.5.5 0 11-.71.7l-5.41-5.4z" fill="currentColor"/> 905 </symbol> 906 907 <symbol id="icon-close" class="icon icon-close" fill="none" viewBox="0 0 18 17"> 908 <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"> 909 </symbol> 910</svg> 911 912 913<div id="easystore-section-header"> 914 <sticky-header class="header-wrapper header-wrapper--border-bottom"> 915 <header class="header header--middle-left page-width header--has-menu" itemscope itemtype="http://schema.org/Organization"> 916 <header-drawer data-breakpoint="tablet"> 917 <details class="menu-drawer-container menu-opening"> 918 <summary class="header__icon header__icon--menu header__icon--summary link link--text focus-inset" aria-label="Menu" role="button" aria-expanded="true" aria-controls="menu-drawer"> 919 <span> 920 921 922 923 <svg class="icon icon-hamburger " data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600"><path d="M32.5,65h535a25,25,0,0,0,0-50H32.5a25,25,0,0,0,0,50Z" fill="currentColor"/><path d="M567.5,275H32.5a25,25,0,0,0,0,50h535a25,25,0,0,0,0-50Z" fill="currentColor"/><path d="M567.5,535H32.5a25,25,0,0,0,0,50h535a25,25,0,0,0,0-50Z" fill="currentColor"/></svg> 924 925 926 927 928 929 930 <svg class="icon icon-close " data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600"><path d="M335.36,300,581.87,53.48a25,25,0,0,0-35.35-35.35L300,264.64,53.48,18.13A25,25,0,0,0,18.13,53.48L264.64,300,18.13,546.52a25,25,0,0,0,35.35,35.35L300,335.36,546.52,581.87a25,25,0,0,0,35.35-35.35Z" fill="currentColor"/></svg> 931 932 933 934 </span> 935 </summary> 936 <div id="menu-drawer" class="menu-drawer motion-reduce" tabindex="-1"> 937 <div class="menu-drawer__inner-container"> 938 <div class="menu-drawer__navigation-container"> 939 <nav class="menu-drawer__navigation"> 940 <ul class="menu-drawer__menu list-menu" role="list"> 941 942 943 944 <li> 945 <a href="/" class="menu-drawer__menu-item list-menu__item link link--text focus-inset"> 946 ABOUT US 947 </a> 948 </li> 949 950 951 952 953 <li> 954 <a href="/pages/tickets-1" class="menu-drawer__menu-item list-menu__item link link--text focus-inset"> 955 Tickets 956 </a> 957 </li> 958 959 960 961 962 963 <li> 964 <details> 965 <summary class="menu-drawer__menu-item list-menu__item link link--text focus-inset" role="button" aria-expanded="false" aria-controls="link-Bags"> 966 <a href="/collections/all" class="link--text list-menu__item menu-drawer__menu-item"> 967 Adoptions & Souvenirs 968 </a> 969 970 971 972 <svg class="icon icon-arrow " data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 339.56"><path d="M31.06,196.67H504l-88.56,88.56a26.89,26.89,0,1,0,38,38L588,188.79a26.89,26.89,0,0,0,0-38L453.49,16.29a26.89,26.89,0,0,0-38,38L504,142.88H31.06a26.9,26.9,0,0,0,0,53.79Z" fill="currentColor"/></svg> 973 974 975 976 977 978 979 <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-caret " viewBox="0 0 10 6"> 980 <path fill-rule="evenodd" clip-rule="evenodd" d="M9.354.646a.5.5 0 00-.708 0L5 4.293 1.354.646a.5.5 0 00-.708.708l4 4a.5.5 0 00.708 0l4-4a.5.5 0 000-.708z" fill="currentColor"></path> 981 </svg> 982 983 984 985 </summary> 986 <div class="menu-drawer__submenu motion-reduce" tabindex="-1"> 987 <div class="menu-drawer__inner-submenu"> 988 <button class="menu-drawer__close-button link link--text focus-inset" aria-expanded="true"> 989 990 991 992 <svg class="icon icon-arrow " data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 339.56"><path d="M31.06,196.67H504l-88.56,88.56a26.89,26.89,0,1,0,38,38L588,188.79a26.89,26.89,0,0,0,0-38L453.49,16.29a26.89,26.89,0,0,0-38,38L504,142.88H31.06a26.9,26.9,0,0,0,0,53.79Z" fill="currentColor"/></svg> 993 994 995 996 Adoptions & Souvenirs 997 </button> 998 <ul class="menu-drawer__menu list-menu" role="list" tabindex="-1"> 999 1000 1001 1002 <li> 1003 <a href="/collections/adopt-a-butterfly" class="menu-drawer__menu-item link link--text list-menu__item focus-inset"> 1004 Get Butterfly 1005 </a> 1006 </li> 1007 1008 1009 1010 </ul> 1011 </div> 1012 </div> 1013 </details> 1014 </li> 1015 1016 1017 1018 1019 <li> 1020 <a href="/pages/butterfly-conservation" class="menu-drawer__menu-item list-menu__item link link--text focus-inset"> 1021 Giant Tree Nymph Butterfly 1022 </a> 1023 </li> 1024 1025 1026 1027 1028 <li> 1029 <a href="/pages/education-trips" class="menu-drawer__menu-item list-menu__item link link--text focus-inset"> 1030 Group Visits & Packages 1031 </a> 1032 </li> 1033 1034 1035 1036 1037 <li> 1038 <a href="/blogs/makmal-rama-rama-melupuskan-3000-ulat-beluncas-ketika-perintah-pkp" class="menu-drawer__menu-item list-menu__item link link--text focus-inset"> 1039 Blog 1040 </a> 1041 </li> 1042 1043 1044 </ul> 1045 </nav> 1046 1047 <div class="menu-drawer__utility-links"> 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 <a href="/account/login" class="menu-drawer__account link link--text focus-inset h5"> 1059 1060 1061 1062 <svg class="icon icon-account " data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600"><path d="M300,296.19c-70.7,0-137.11,28.74-187,80.93-49.59,51.87-76.9,120.77-76.9,194v25H563.89v-25c0-73.22-27.31-142.12-76.9-194C437.11,324.93,370.7,296.19,300,296.19ZM87.42,546.11C99.29,433.81,190.1,346.19,300,346.19s200.71,87.62,212.58,199.92Z" fill="currentColor"/><path d="M300,285.34c77.6,0,140.73-63.13,140.73-140.73S377.6,3.89,300,3.89,159.27,67,159.27,144.61,222.4,285.34,300,285.34Zm0-231.45a90.73,90.73,0,1,1-90.73,90.72A90.82,90.82,0,0,1,300,53.89Z" fill="currentColor"/></svg> 1063 1064 1065 1066 1067 Log in 1068 </a> 1069 1070 <a href="/account/register" class="menu-drawer__account link link--text focus-inset h5"> 1071 1072 1073 1074 1075 <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" role="presentation" class="icon icon-plus " fill="none" viewBox="0 0 10 10"> 1076 <path fill-rule="evenodd" clip-rule="evenodd" d="M1 4.51a.5.5 0 000 1h3.5l.01 3.5a.5.5 0 001-.01V5.5l3.5-.01a.5.5 0 00-.01-1H5.5L5.49.99a.5.5 0 00-1 .01v3.5l-3.5.01H1z" fill="currentColor"></path> 1077 </svg> 1078 1079 1080 1081 Create account 1082 </a> 1083 1084 1085 1086 </div> 1087 </div> 1088 </div> 1089 </div> 1090 </details> 1091 </header-drawer> 1092 1093 1094 <a href="/" class="header__heading-link link link--text focus-inset" itemprop="url"> 1095 <img src="https://cdn.store-assets.com/s/196384/f/16716494.png" class="header__heading-logo" alt="ButterflyReptile" loading="lazy" itemprop="logo"> 1096 </a> 1097 1098 1099 1100 <div class="header__search-input" tabindex="-1"> 1101 <form action="/search" method="get" role="search" class="search search-modal__form"> 1102 <div class="field"> 1103 <input class="search__input field__input" 1104 id="Search-In-Modal" 1105 type="search" 1106 name="q" 1107 value="" 1108 placeholder="Search" 1109 autocomplete="off" 1110 > 1111 <label class="field__label" for="Search-In-Modal">Search</label> 1112 <div class="dropdown" id="searchDropdown"></div> 1113 <input type="hidden" name="search_history" class="hidden_search_history"> 1114 <input type="hidden" name="options[prefix]" value="last"> 1115 <button class="search__button field__button" aria-label="Search"> 1116 <svg class="icon icon-search" aria-hidden="true" focusable="false" role="presentation"> 1117 <use href="#icon-search"> 1118 </svg> 1119 </button> 1120 </div> 1121 </form> 1122 </div> 1123 1124 1125 <nav class="header__inline-menu"> 1126 <ul class="list-menu list-menu--inline" role="list"> 1127 1128 1129 1130 <li> 1131 <a href="/" class="header__menu-item header__menu-item list-menu__item link link--text focus-inset"> 1132 ABOUT US 1133 </a> 1134 </li> 1135 1136 1137 1138 1139 <li> 1140 <a href="/pages/tickets-1" class="header__menu-item header__menu-item list-menu__item link link--text focus-inset"> 1141 Tickets 1142 </a> 1143 </li> 1144 1145 1146 1147 1148 1149 <li> 1150 <details-disclosure> 1151 <details> 1152 <summary class="header__menu-item list-menu__item link focus-inset"> 1153 <a href="/collections/all" >Adoptions & Souvenirs</a> 1154 1155 1156 1157 <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-caret " viewBox="0 0 10 6"> 1158 <path fill-rule="evenodd" clip-rule="evenodd" d="M9.354.646a.5.5 0 00-.708 0L5 4.293 1.354.646a.5.5 0 00-.708.708l4 4a.5.5 0 00.708 0l4-4a.5.5 0 000-.708z" fill="currentColor"></path> 1159 </svg> 1160 1161 1162 1163 </summary> 1164 <ul class="header__submenu list-menu list-menu--disclosure caption-large motion-reduce" role="list" tabindex="-1"> 1165 1166 1167 1168 1169 1170 <li> 1171 <a href="/collections/adopt-a-butterfly" class="header__menu-item list-menu__item link link--text focus-inset caption-large"> 1172 Get Butterfly 1173 </a> 1174 </li> 1175 1176 1177 </ul> 1178 </details> 1179 </details-disclosure> 1180 </li> 1181 1182 1183 1184 1185 <li> 1186 <a href="/pages/butterfly-conservation" class="header__menu-item header__menu-item list-menu__item link link--text focus-inset"> 1187 Giant Tree Nymph Butterfly 1188 </a> 1189 </li> 1190 1191 1192 1193 1194 <li> 1195 <a href="/pages/education-trips" class="header__menu-item header__menu-item list-menu__item link link--text focus-inset"> 1196 Group Visits & Packages 1197 </a> 1198 </li> 1199 1200 1201 1202 1203 <li> 1204 <a href="/blogs/makmal-rama-rama-melupuskan-3000-ulat-beluncas-ketika-perintah-pkp" class="header__menu-item header__menu-item list-menu__item link link--text focus-inset"> 1205 Blog 1206 </a> 1207 </li> 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 </ul> 1221 </nav> 1222 <div class="header__icons"> 1223 1224 1225 1226 <div class="header__icon header__icon--account link link--text focus-inset small-hide medium-hide" style="position: relative;"> 1227 <a href="/account/login" class="header__icon link link--text focus-inset p-2"> 1228 1229 1230 1231 <svg class="icon icon-account " data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600"><path d="M300,296.19c-70.7,0-137.11,28.74-187,80.93-49.59,51.87-76.9,120.77-76.9,194v25H563.89v-25c0-73.22-27.31-142.12-76.9-194C437.11,324.93,370.7,296.19,300,296.19ZM87.42,546.11C99.29,433.81,190.1,346.19,300,346.19s200.71,87.62,212.58,199.92Z" fill="currentColor"/><path d="M300,285.34c77.6,0,140.73-63.13,140.73-140.73S377.6,3.89,300,3.89,159.27,67,159.27,144.61,222.4,285.34,300,285.34Zm0-231.45a90.73,90.73,0,1,1-90.73,90.72A90.82,90.82,0,0,1,300,53.89Z" fill="currentColor"/></svg> 1232 1233 1234
1235 <span id="my-account" class="header__link-label">Login</span> 1236 </a> 1237 1238 <!-- Referral Notification Popup for Desktop --> 1239 <div id="referralNotification" class="referral-notification" style="display: none;"> 1240 <button class="close-btn" onclick="dismissReferralNotification()">×</button> 1241 <div style="text-align: center; margin-bottom: 16px;"> 1242 <div style="width: 100px; height: 100px; margin: 0 auto;"> 1243 <img src="https://resources.easystore.co/storefront/icons/channels/vector_referral_program.svg"> 1244 </div> 1245 </div> 1246 <p id="referralSignupMessage" style="text-align: center; font-size: 14px; color: #666; margin: 0 0 20px 0;"> 1247 Your friend gifted you credit! Sign up now to redeem. 1248 </p> 1249 <div style="text-align: center;"> 1250 <button class="btn" onclick="goToSignupPage()" style="width: 100%;"> 1251 Sign Up 1252 </button> 1253 </div> 1254 </div> 1255 </div> 1256 1257 1258 1259 <a href="/cart" class="header__icon link link--text focus-inset" id="cart-icon-bubble"> 1260 <span class="header__icon--cart"> 1261 1262 1263 1264 <svg class="icon icon-cart-empty " data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496.56 600"><path d="M453.52,128.63a25,25,0,0,0-24.91-22.8H364.72a117.48,117.48,0,0,0-232.89,0H67.94A25,25,0,0,0,43,128.63L8.8,515.21a72.11,72.11,0,0,0,19.05,55.6,79,79,0,0,0,58.22,25.3H410.49a79,79,0,0,0,58.22-25.3,72.11,72.11,0,0,0,19.05-55.6ZM248.28,53.89a67.58,67.58,0,0,1,65.65,51.94H182.63A67.57,67.57,0,0,1,248.28,53.89ZM431.83,537.05a28.85,28.85,0,0,1-21.34,9.06H86.07a28.85,28.85,0,0,1-21.34-9.06,22.69,22.69,0,0,1-6.13-17.43L90.82,155.83h40v51.23a25,25,0,0,0,50,0V155.83h135v51.23a25,25,0,0,0,50,0V155.83h40L438,519.62A22.68,22.68,0,0,1,431.83,537.05Z" fill="currentColor"/></svg> 1265 1266 1267 1268 <div class="cart-count-bubble hidden"> 1269 <span aria-hidden="true" class="js-content-cart-count">0</span> 1270 </div> 1271 </span> 1272 <span class="header__link-label medium-hide small-hide"> 1273 Cart 1274 </span> 1275 </a> 1276 1277 1278 1279 <!-- Referral Notification Modal for Mobile --> 1280 <details-modal class="referral-modal" id="referralMobileModal"> 1281 <details> 1282 <summary class="referral-modal__toggle" aria-haspopup="dialog" aria-label="Open referral modal" style="display: none;"> 1283 </summary> 1284 <div class="modal-overlay referral-modal-overlay"></div> 1285 <div class="referral-modal__dialog" role="dialog" aria-modal="true" aria-label="Referral notification"> 1286 <div class="referral-modal__content"> 1287 <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;"> 1288 × 1289 </button> 1290 1291 <div style="margin-bottom: 24px;"> 1292 <div style="width: 120px; height: 120px; margin: 0 auto 20px;"> 1293 <img src="https://resources.easystore.co/storefront/icons/channels/vector_referral_program.svg" style="width: 100%; height: 100%;"> 1294 </div> 1295 </div> 1296 1297 <p id="referralSignupMessageMobile" style="font-size: 16px; color: #333; margin: 0 0 30px 0; line-height: 1.5;"> 1298 Your friend gifted you credit! Sign up now to redeem. 1299 </p> 1300 1301 <button type="button" class="btn" onclick="goToSignupPageFromMobile()" style="width: 100%;"> 1302 Sign Up 1303 </button> 1304 </div> 1305 </div> 1306 </details> 1307 </details-modal> 1308 1309 1310 1311 </div> 1312 </header> 1313 </sticky-header> 1314 1315<cart-notification> 1316 <div class="cart-notification-wrapper page-width color-background-1"> 1317 <div id="cart-notification" class="cart-notification focus-inset" aria-modal="true" aria-label="Added to cart" role="dialog" tabindex="-1"> 1318 <div class="cart-notification__header"> 1319 <h2 class="cart-notification__heading caption-large"> 1320 1321 1322 <svg class="icon icon-checkmark color-foreground-text " aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 9" fill="none"> 1323 <path fill-rule="evenodd" clip-rule="evenodd" d="M11.35.643a.5.5 0 01.006.707l-6.77 6.886a.5.5 0 01-.719-.006L.638 4.845a.5.5 0 11.724-.69l2.872 3.011 6.41-6.517a.5.5 0 01.707-.006h-.001z" fill="currentColor"></path> 1324 </svg> 1325 1326 1327 Added to cart</h2> 1328 <button type="button" class="cart-notification__close modal__close-button link link--text focus-inset" aria-label="accessibility.close"> 1329 1330 1331 1332 <svg class="icon icon-close " data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600"><path d="M335.36,300,581.87,53.48a25,25,0,0,0-35.35-35.35L300,264.64,53.48,18.13A25,25,0,0,0,18.13,53.48L264.64,300,18.13,546.52a25,25,0,0,0,35.35,35.35L300,335.36,546.52,581.87a25,25,0,0,0,35.35-35.35Z" fill="currentColor"/></svg> 1333 1334 1335 1336 </button> 1337 </div> 1338 <div id="cart-notification-product" class="cart-notification-product"></div> 1339 <div class="cart-notification__links"> 1340 <a href="/cart" id="cart-notification-button" class="button button--secondary button--full-width">View cart (<span class="js-content-cart-count">0</span>)</a> 1341 <form action="/cart" method="post" id="cart-notification-form">
1342 <input type="hidden" name="_token" value="0ei2IgLqvCrtvdPaMLjrd1ineIFa3nidRL2SpuEQ"> 1343 <input type="hidden" name="current_currency" value=""> 1344 <button class="button button--primary button--full-width" name="checkout" value="true">Checkout</button> 1345 </form> 1346 <button type="button" class="link button-label">Continue shopping</button> 1347 </div> 1348 </div> 1349 </div> 1350</cart-notification> 1351<style> 1352 .cart-notification { 1353 display: none; 1354 } 1355</style>
1356<script> 1357document.getElementById('cart-notification-form').addEventListener('submit',(event)=>{ 1358 if(event.submitter) event.submitter.classList.add('loading'); 1359}) 1360 1361</script>
1361 1362 1363</div> 1364 1365
1366<script> 1367 1368 class StickyHeader extends HTMLElement { 1369 constructor() { 1370 super(); 1371 } 1372 1373 connectedCallback() { 1374 this.header = document.getElementById('easystore-section-header'); 1375 this.headerBounds = {}; 1376 this.currentScrollTop = 0; 1377 this.preventReveal = false; 1378 1379 this.onScrollHandler = this.onScroll.bind(this); 1380 this.hideHeaderOnScrollUp = () => this.preventReveal = true; 1381 1382 this.addEventListener('preventHeaderReveal', this.hideHeaderOnScrollUp); 1383 window.addEventListener('scroll', this.onScrollHandler, false); 1384 1385 this.createObserver(); 1386 } 1387 1388 disconnectedCallback() { 1389 this.removeEventListener('preventHeaderReveal', this.hideHeaderOnScrollUp); 1390 window.removeEventListener('scroll', this.onScrollHandler); 1391 } 1392 1393 createObserver() { 1394 let observer = new IntersectionObserver((entries, observer) => { 1395 this.headerBounds = entries[0].intersectionRect; 1396 observer.disconnect(); 1397 }); 1398 1399 observer.observe(this.header); 1400 } 1401 1402 onScroll() { 1403 const scrollTop = window.pageYOffset || document.documentElement.scrollTop; 1404 1405 if (scrollTop > this.currentScrollTop && scrollTop > this.headerBounds.bottom) { 1406 requestAnimationFrame(this.hide.bind(this)); 1407 } else if (scrollTop < this.currentScrollTop && scrollTop > this.headerBounds.bottom) { 1408 if (!this.preventReveal) { 1409 requestAnimationFrame(this.reveal.bind(this)); 1410 } else { 1411 window.clearTimeout(this.isScrolling); 1412 1413 this.isScrolling = setTimeout(() => { 1414 this.preventReveal = false; 1415 }, 66); 1416 1417 requestAnimationFrame(this.hide.bind(this)); 1418 } 1419 } else if (scrollTop <= this.headerBounds.top) { 1420 requestAnimationFrame(this.reset.bind(this)); 1421 } 1422 1423 1424 this.currentScrollTop = scrollTop; 1425 } 1426 1427 hide() { 1428 this.header.classList.add('easystore-section-header-hidden', 'easystore-section-header-sticky'); 1429 this.closeMenuDisclosure(); 1430 // this.closeSearchModal(); 1431 } 1432 1433 reveal() { 1434 this.header.classList.add('easystore-section-header-sticky', 'animate'); 1435 this.header.classList.remove('easystore-section-header-hidden'); 1436 } 1437 1438 reset() { 1439 this.header.classList.remove('easystore-section-header-hidden', 'easystore-section-header-sticky', 'animate'); 1440 } 1441 1442 closeMenuDisclosure() { 1443 this.disclosures = this.disclosures || this.header.querySelectorAll('details-disclosure'); 1444 this.disclosures.forEach(disclosure => disclosure.close()); 1445 } 1446 1447 // closeSearchModal() { 1448 // this.searchModal = this.searchModal || this.header.querySelector('details-modal'); 1449 // this.searchModal.close(false); 1450 // } 1451 } 1452 1453 customElements.define('sticky-header', StickyHeader); 1454 1455 1456 class DetailsDisclosure extends HTMLElement{ 1457 constructor() { 1458 super(); 1459 this.mainDetailsToggle = this.querySelector('details'); 1460 // this.mainDetailsToggle.addEventListener('focusout', this.onFocusOut.bind(this)); 1461 this.mainDetailsToggle.addEventListener('mouseover', this.open.bind(this)); 1462 this.mainDetailsToggle.addEventListener('mouseleave', this.close.bind(this)); 1463 } 1464 1465 onFocusOut() { 1466 setTimeout(() => { 1467 if (!this.contains(document.activeElement)) this.close(); 1468 }) 1469 } 1470 1471 open() { 1472 this.mainDetailsToggle.setAttribute('open',1) 1473 } 1474 1475 close() { 1476 this.mainDetailsToggle.removeAttribute('open') 1477 } 1478 } 1479 1480 customElements.define('details-disclosure', DetailsDisclosure); 1481 1482 function clearAll() { 1483 localStorage.removeItem('searchHistory'); 1484 1485 var customer = ""; 1486 if(customer) { 1487 // Your logic to clear all data or call an endpoint 1488 fetch('/account/search_histories', { 1489 method: 'DELETE', 1490 headers: { 1491 "Content-Type": "application/json", 1492 "X-Requested-With": "XMLHttpRequest" 1493 }, 1494 body: JSON.stringify({ 1495 _token: "0ei2IgLqvCrtvdPaMLjrd1ineIFa3nidRL2SpuEQ" 1496 }), 1497 }) 1498 .then(response => response.json()) 1499 } 1500 } 1501 // End - delete search history from local storage 1502 1503 // search history dropdown 1504 var searchInputs = document.querySelectorAll('.search__input'); 1505 1506 if(searchInputs.length > 0) { 1507
1508 searchInputs.forEach((searchInput)=> { 1509 1510 searchInput.addEventListener('focus', function() { 1511 var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown'); 1512 searchDropdown.innerHTML = ''; // Clear existing items 1513 1514 // retrieve data from local storage 1515 var searchHistoryData = JSON.parse(localStorage.getItem('searchHistory')) || []; 1516 1517 // Convert JSON to string 1518 var search_history_json = JSON.stringify(searchHistoryData); 1519 1520 // Set the value of the hidden input 1521 searchInput.closest('form').querySelector(".hidden_search_history").value = search_history_json; 1522 1523 // create dropdown items 1524 var clearAllItem = document.createElement('div'); 1525 clearAllItem.className = 'dropdown-item clear-all'; 1526 clearAllItem.textContent = 'Clear'; 1527 clearAllItem.addEventListener('click', function() { 1528 clearAll(); 1529 searchDropdown.style.display = 'none'; 1530 searchInput.classList.remove('is-focus'); 1531 }); 1532 searchDropdown.appendChild(clearAllItem); 1533 1534 // create dropdown items 1535 searchHistoryData.forEach(function(item) { 1536 var dropdownItem = document.createElement('div'); 1537 dropdownItem.className = 'dropdown-item'; 1538 dropdownItem.textContent = item.term; 1539 dropdownItem.addEventListener('click', function() { 1540 searchInput.value = item.term; 1541 searchInput.closest('form').submit(); 1542 searchDropdown.style.display = 'none'; 1543 }); 1544 searchDropdown.appendChild(dropdownItem); 1545 }); 1546 1547 if(searchHistoryData.length > 0){ 1548 // display the dropdown 1549 searchInput.classList.add('is-focus'); 1550 document.body.classList.add('search-input-focus'); 1551 searchDropdown.style.display = 'block'; 1552 } 1553 }); 1554 1555 searchInput.addEventListener("focusout", (event) => { 1556 var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown'); 1557 searchInput.classList.remove('is-focus'); 1558 searchDropdown.classList.add('transparent'); 1559 setTimeout(()=>{ 1560 searchDropdown.style.display = 'none'; 1561 searchDropdown.classList.remove('transparent'); 1562 document.body.classList.remove('search-input-focus'); 1563 }, 400); 1564 }); 1565 }) 1566 } 1567 // End - search history dropdown 1568 1569 // referral notification popup 1570 const referralMessageTemplate = 'Your friend gifted you __CURRENCY_CODE__ __CREDIT_AMOUNT__ credit! Sign up now to redeem.'; 1571 const shopCurrency = 'RM'; 1572 1573 function getCookie(name) { 1574 const value = `; ${document.cookie}`; 1575 const parts = value.split(`; ${name}=`); 1576 if (parts.length === 2) return parts.pop().split(';').shift(); 1577 return null; 1578 } 1579 1580 function removeCookie(name) { 1581 document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`; 1582 } 1583 1584 function showReferralNotification() { 1585 const referralCode = getCookie('customer_referral_code'); 1586 1587 1588 const customerReferralCode = null; 1589 1590 1591 const activeReferralCode = referralCode || customerReferralCode; 1592 const referralData = JSON.parse(localStorage.getItem('referral_notification_data')) || {}; 1593 1594 if (referralData.timestamp && referralData.expirationDays) { 1595 const expirationTime = referralData.timestamp + (referralData.expirationDays * 24 * 60 * 60 * 1000); 1596 if (Date.now() > expirationTime) { 1597 localStorage.removeItem('referral_notification_data'); 1598 return; 1599 } 1600 } 1601 1602 if (referralData.dismissed) return; 1603 1604 if (activeReferralCode) { 1605 if (referralData.creditAmount) { 1606 displayReferralNotification(referralData.creditAmount); 1607 } else { 1608 fetchReferralCampaignData(activeReferralCode); 1609 } 1610 } 1611 } 1612 1613 function fetchReferralCampaignData(referralCode) { 1614 fetch(`/customer/referral_program/campaigns/${referralCode}`) 1615 .then(response => { 1616 if (!response.ok) { 1617 throw new Error('Network response was not ok'); 1618 } 1619 return response.json(); 1620 }) 1621 .then(data => { 1622 let refereeCreditAmount = null; 1623 if (data.data.campaign && data.data.campaign.referral_rules) { 1624 const refereeRule = data.data.campaign.referral_rules.find(rule => 1625 rule.target_type === 'referee' && 1626 rule.event_name === 'customer/create' && 1627 rule.entitlement && 1628 rule.entitlement.type === 'credit' 1629 ); 1630 1631 if (refereeRule) { 1632 refereeCreditAmount = refereeRule.entitlement.amount; 1633 } 1634 } 1635 1636 const referralData = JSON.parse(localStorage.getItem('referral_notification_data')) || {}; 1637 referralData.creditAmount = refereeCreditAmount; 1638 referralData.dismissed = referralData.dismissed || false; 1639 referralData.timestamp = Date.now(); 1640 referralData.expirationDays = 3; 1641 localStorage.setItem('referral_notification_data', JSON.stringify(referralData)); 1642 1643 displayReferralNotification(refereeCreditAmount); 1644 }) 1645 .catch(error => { 1646 removeCookie('customer_referral_code'); 1647 }); 1648 } 1649 1650 function displayReferralNotification(creditAmount = null) { 1651 const isMobile = innerWidth <= 749; 1652 1653 if (isMobile) { 1654 const mobileModal = document.querySelector('#referralMobileModal details'); 1655 const mobileMessageElement = document.getElementById('referralSignupMessageMobile'); 1656 1657 if (mobileModal && mobileMessageElement) { 1658 if (creditAmount) {
1659 const finalMessage = referralMessageTemplate 1660 .replace('__CREDIT_AMOUNT__', creditAmount) 1661 .replace('__CURRENCY_CODE__', shopCurrency); 1662 1663 mobileMessageElement.textContent = finalMessage; 1664 } 1665 1666 mobileModal.setAttribute('open', ''); 1667 } 1668 } else { 1669 const notification = document.getElementById('referralNotification'); 1670 1671 if (notification) { 1672 if (creditAmount) { 1673 const messageElement = document.getElementById('referralSignupMessage'); 1674 if (messageElement) { 1675 const finalMessage = referralMessageTemplate 1676 .replace('__CREDIT_AMOUNT__', creditAmount) 1677 .replace('__CURRENCY_CODE__', shopCurrency); 1678 1679 messageElement.textContent = finalMessage; 1680 } 1681 } 1682 1683 notification.style.display = 'block'; 1684 } 1685 } 1686 } 1687 1688 showReferralNotification(); 1689 1690 addEventListener('beforeunload', function() { 1691 const referralData = JSON.parse(localStorage.getItem('referral_notification_data')) || {}; 1692 1693 if (referralData.creditAmount !== undefined) { 1694 referralData.creditAmount = null; 1695 localStorage.setItem('referral_notification_data', JSON.stringify(referralData)); 1696 } 1697 }); 1698 1699 function closeReferralNotification() { 1700 const notification = document.getElementById('referralNotification'); 1701 if (notification) { 1702 notification.style.display = 'none'; 1703 } 1704 } 1705 1706 function dismissReferralNotification() { 1707 const referralData = JSON.parse(localStorage.getItem('referral_notification_data')) || {}; 1708 1709 referralData.dismissed = true; 1710 referralData.timestamp = referralData.timestamp || Date.now(); 1711 referralData.expirationDays = referralData.expirationDays || 3; 1712 1713 localStorage.setItem('referral_notification_data', JSON.stringify(referralData)); 1714 1715 closeReferralNotification(); 1716 } 1717 1718 function goToSignupPage() { 1719 location.href = '/account/register'; 1720 dismissReferralNotification(); 1721 } 1722 1723 function closeMobileReferralModal() { 1724 const mobileModal = document.querySelector('#referralMobileModal details'); 1725 if (mobileModal) { 1726 mobileModal.removeAttribute('open'); 1727 } 1728 1729 const referralData = JSON.parse(localStorage.getItem('referral_notification_data')) || {}; 1730 referralData.dismissed = true; 1731 referralData.timestamp = referralData.timestamp || Date.now(); 1732 referralData.expirationDays = referralData.expirationDays || 3; 1733 localStorage.setItem('referral_notification_data', JSON.stringify(referralData)); 1734 } 1735 1736 function goToSignupPageFromMobile() { 1737 location.href = '/account/register'; 1738 closeMobileReferralModal(); 1739 } 1740 // End - referral notification popup 1741</script>
1741 1742 1743 1744 1745 <main id="MainContent" class="content-for-layout focus-none" role="main" tabindex="-1"> 1746 1747 <link rel="preload" href="https://store-themes.easystore.co/196384/themes/181882/assets/blog.css?t=1787072441" as="style" onload="this.onload=null;this.rel='stylesheet'"> 1748<link rel="preload" href="https://store-themes.easystore.co/196384/themes/181882/assets/component-card.css?t=1787072441" as="style" onload="this.onload=null;this.rel='stylesheet'"> 1749 1750<div class="main-blog page-width"> 1751 <h1 class="title--primary"> 1752 1753 Our Blog 1754 1755 </h1> 1756 <div class="blog-articles"> 1757 1758 <div class="blog-articles__article article"> 1759 <article class="article-card "> 1760 <a href="/blogs/makmal-rama-rama-melupuskan-3000-ulat-beluncas-ketika-perintah-pkp/covid-19-pembiakan-rama-rama-turut-terjejas" class="article-content motion-reduce"> 1761 1762 <div class="article-card__image-wrapper"> 1763 <div class="article-card__image media media--landscape"> 1764 <img src="https://cdn.store-assets.com/s/196384/f/4680694.png" alt="Covid-19: Pembiakan Rama-rama Turut Terjejas" class="motion-reduce"> 1765 </div> 1766 </div> 1767 1768 <div class="article-card__info"> 1769 <header class="article-card__header"> 1770 <h2 class="article-card__title"> 1771 Covid-19: Pembiakan Rama-rama Turut Terjejas 1772 </h2> 1773 <span class="circle-divider caption-with-letter-spacing"> 1774 <time datetime="2020-05-06"> May 06, 20</time> 1775 </span> 1776 1777 </header> 1778 <p class="article-card__excerpt rte-width break">Makmak Taman Rama-rama dan Reptilia Melaka lupus 3000 ulat beluncas seketika PKP </p> 1779 </div> 1780 </a> 1781 </article> 1782 </div> 1783 1784 </div> 1785</div> 1786 1787 1788 1789 1790 1791 </main> 1792 <style> 1793 .footer{ 1794 background-color: #2D2D2D; 1795 color: #FEFEFE; 1796 --color-foreground: 254,254,254; 1797 } 1798 .footer .link--text, 1799 .footer .list-menu__item--link, 1800 .footer .footer-block__details-content .list-menu__item--link{ 1801 color: #FEFEFE; 1802 } 1803 .footer-block__heading{ 1804 color: #FFFFFF; 1805 } 1806 .rounded{ 1807 border-radius: 10px; 1808 } 1809 .shopping-app-border{ 1810 border: 1px #ECECEC solid; 1811 margin-right: 3px; 1812 } 1813 .app-download-badge{ 1814 display: inline-block; 1815 margin-right: 3px; 1816 } 1817</style> 1818 1819<link rel="preload" href="https://store-themes.easystore.co/196384/themes/181882/assets/section-footer.css?t=1787072441" as="style" onload="this.onload=null;this.rel='stylesheet'"> 1820 1821<footer class="footer color-background-1"> 1822 <div class="footer__content-top page-width"> 1823 <div class="grid grid--1-col grid--4-col-tablet "> 1824 1825 1826 1827 <div class="grid__item"> 1828 1829 <h2 class="footer-block__heading">Follow us</h2> 1830 <ul class="footer__list-social list-unstyled list-social footer-block__details-content" role="list"> 1831 1832 1833 <li class="list-social__item"> 1834 <a href="https://www.facebook.com/TamanRamaramadanReptiliaMelaka/" class="link link--text list-social__link"> 1835 1836 1837 1838 <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-facebook " 1839 viewBox="0 0 18 18"> 1840 <path fill="currentColor" 1841 d="M16.42.61c.27 0 .5.1.69.28.19.2.28.42.28.7v15.44c0 .27-.1.5-.28.69a.94.94 0 01-.7.28h-4.39v-6.7h2.25l.31-2.65h-2.56v-1.7c0-.4.1-.72.28-.93.18-.2.5-.32 1-.32h1.37V3.35c-.6-.06-1.27-.1-2.01-.1-1.01 0-1.83.3-2.45.9-.62.6-.93 1.44-.93 2.53v1.97H7.04v2.65h2.24V18H.98c-.28 0-.5-.1-.7-.28a.94.94 0 01-.28-.7V1.59c0-.27.1-.5.28-.69a.94.94 0 01.7-.28h15.44z"> 1842 </path> 1843 </svg> 1844 1845 1846 1847 </a> 1848 </li> 1849 1850 1851 <li class="list-social__item"> 1852 <a href="https://www.instagram.com/butterflyreptile/?hl=en" class="link link--text list-social__link"> 1853 1854 1855 1856 <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-instagram "
1857 viewBox="0 0 18 18"> 1858 <path fill="currentColor" 1859 d="M8.77 1.58c2.34 0 2.62.01 3.54.05.86.04 1.32.18 1.63.3.41.17.7.35 1.01.66.3.3.5.6.65 1 .12.32.27.78.3 1.64.05.92.06 1.2.06 3.54s-.01 2.62-.05 3.54a4.79 4.79 0 01-.3 1.63c-.17.41-.35.7-.66 1.01-.3.3-.6.5-1.01.66-.31.12-.77.26-1.63.3-.92.04-1.2.05-3.54.05s-2.62 0-3.55-.05a4.79 4.79 0 01-1.62-.3c-.42-.16-.7-.35-1.01-.66-.31-.3-.5-.6-.66-1a4.87 4.87 0 01-.3-1.64c-.04-.92-.05-1.2-.05-3.54s0-2.62.05-3.54c.04-.86.18-1.32.3-1.63.16-.41.35-.7.66-1.01.3-.3.6-.5 1-.65.32-.12.78-.27 1.63-.3.93-.05 1.2-.06 3.55-.06zm0-1.58C6.39 0 6.09.01 5.15.05c-.93.04-1.57.2-2.13.4-.57.23-1.06.54-1.55 1.02C1 1.96.7 2.45.46 3.02c-.22.56-.37 1.2-.4 2.13C0 6.1 0 6.4 0 8.77s.01 2.68.05 3.61c.04.94.2 1.57.4 2.13.23.58.54 1.07 1.02 1.56.49.48.98.78 1.55 1.01.56.22 1.2.37 2.13.4.94.05 1.24.06 3.62.06 2.39 0 2.68-.01 3.62-.05.93-.04 1.57-.2 2.13-.41a4.27 4.27 0 001.55-1.01c.49-.49.79-.98 1.01-1.56.22-.55.37-1.19.41-2.13.04-.93.05-1.23.05-3.61 0-2.39 0-2.68-.05-3.62a6.47 6.47 0 00-.4-2.13 4.27 4.27 0 00-1.02-1.55A4.35 4.35 0 0014.52.46a6.43 6.43 0 00-2.13-.41A69 69 0 008.77 0z"> 1860 </path> 1861 <path fill="currentColor" 1862 d="M8.8 4a4.5 4.5 0 100 9 4.5 4.5 0 000-9zm0 7.43a2.92 2.92 0 110-5.85 2.92 2.92 0 010 5.85zM13.43 5a1.05 1.05 0 100-2.1 1.05 1.05 0 000 2.1z"> 1863 </path> 1864 </svg> 1865 1866 1867 1868 </a> 1869 </li> 1870 1871 1872 <li class="list-social__item"> 1873 <a href="https://www.tiktok.com/@tamanrama2reptiliamelaka" class="link link--text list-social__link"> 1874 1875 1876 1877 <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-tiktok " width="16" 1878 height="18" fill="none" xmlns="http://www.w3.org/2000/svg"> 1879 <path 1880 d="M8.02 0H11s-.17 3.82 4.13 4.1v2.95s-2.3.14-4.13-1.26l.03 6.1a5.52 5.52 0 11-5.51-5.52h.77V9.4a2.5 2.5 0 101.76 2.4L8.02 0z" 1881 fill="currentColor"> 1882 </path> 1883 </svg> 1884 1885 1886 1887 </a> 1888 </li> 1889 1890 1891 1892 1893 1894 <li class="list-social__item"> 1895 <a href="https://www.youtube.com/channel/UCyakH30IpVspheOr_yhfvrw" class="link link--text list-social__link"> 1896 1897 1898 1899 <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-youtube " 1900 viewBox="0 0 100 70"> 1901 <path 1902 d="M98 11c2 7.7 2 24 2 24s0 16.3-2 24a12.5 12.5 0 01-9 9c-7.7 2-39 2-39 2s-31.3 0-39-2a12.5 12.5 0 01-9-9c-2-7.7-2-24-2-24s0-16.3 2-24c1.2-4.4 4.6-7.8 9-9 7.7-2 39-2 39-2s31.3 0 39 2c4.4 1.2 7.8 4.6 9 9zM40 50l26-15-26-15v30z" 1903 fill="currentColor"> 1904 </path> 1905 </svg> 1906 1907 1908 1909 </a> 1910 </li> 1911 1912 1913 </ul> 1914 1915 </div> 1916 1917 1918 1919 <div class="grid__item"> 1920 1921 <h2 class="footer-block__heading"> 1922 Quick links 1923 </h2> 1924 <ul class="footer-block__details-content list-unstyled"> 1925 1926 <li> 1927 <a href="/a/contact-form" class="link link--text list-menu__item list-menu__item--link"> 1928 Contact us 1929 </a> 1930 </li> 1931 1932 <li> 1933 <a href="https://maps.app.goo.gl/QSuBPVNqPaaANCG96" target="_blank" class="link link--text list-menu__item list-menu__item--link"> 1934 Location 1935 </a> 1936 </li> 1937 1938 1939 </ul> 1940 1941 </div> 1942 1943 1944 1945 <div class="grid__item"> 1946 1947 <h2 class="footer-block__heading">Our Vision</h2> 1948 <div class="footer-block__details-content"> 1949 <p>Premier conservation, breeding, research and education center for butterflies.<br> Society with awareness and passion on wildlife</p> 1950 </div> 1951 1952 </div> 1953 1954 1955 1956 <div class="grid__item"> 1957 1958 <h2 class="footer-block__heading">We Open Everyday </h2> 1959 <div class="footer-block__details-content"> 1960 <p>9:00am to 5:30pm<br> (last entrance 4:30pm)<br>
1960 Next to Ayer Keroh Toll Plaza,<br> 75450 Ayer Keroh,<br> Melaka, Malaysia.<br> Tel: (606) 232 0033</p> 1961 </div> 1962 1963 </div> 1964 1965 </div> 1966 </div> 1967 <div class="footer__content-bottom"> 1968 <div class="footer__content-bottom-wrapper page-width"> 1969 <div class="footer__column footer__column--info"> 1970 1971 1972 1973 1974 1975 1976 1977 <div class="footer__copyright caption"> 1978 <div class="copyright__content">2021 Melaka Butterfly & Reptile Sanctuary (Taman Rama-rama & Reptilia Melaka)</div> 1979 </div> 1980 1981 <div class="footer__copyright caption"> 1982 1983 <div> 1984 1985 1986 1987 <a href="/legal/refund-policy">Delivery, Return and Private Policy</a> 1988 1989 1990 1991 </div> 1992 1993 </div> 1994 1995 </div> 1996 </div> 1997 </div> 1998</footer> 1999 2000 2001 2002 2003 2004 2005
2005<script> 2006 EasyStore.Currencies.init([{"name":"Malaysian Ringgit","code":"MYR","rate":"1.0","format_prefix":"RM","format_suffix":null,"format_decimals":2,"thousand_separator":",","is_primary":true}], 1) 2007</script>
2007 2008 2009 2010 2011
2011<script> 2012 let page_template = 'blog'; 2013 2014 if(document.querySelector('.currency-picker')) { 2015 EasyStore.Currencies.change(document.querySelector('.currency-picker').value) 2016 EasyStore.Currencies.convertAll() 2017 } 2018 2019 document.querySelectorAll('.currency-picker').forEach((el)=>{ 2020 el.addEventListener('change',(event)=>{ 2021 EasyStore.Currencies.change(event.target.value) 2022 2023 2024 if (page_template == 'cart') { 2025 const params = new URLSearchParams(window.location.search); 2026 params.set('delete_cache', 1); 2027 window.location.search = params; 2028 } else { 2029 window.location.reload(); 2030 } 2031 2032 return 2033 2034 2035 document.querySelectorAll('[name=currencies],[name=current_currency]').forEach((el)=>{ 2036 el.value = event.target.value 2037 }) 2038 2039 if(page_template == 'cart') location.reload(); 2040 }) 2041 }) 2042 </script>
2042 2043 2044 2045 2046 2047
2047<script> 2048 2049 window.variantStrings = { 2050 addToCart: `Add to Cart`, 2051 updateCart: `Update Cart`, 2052 soldOut: `Sold Out`, 2053 unavailable: `Unavailable`, 2054 } 2055 2056 window.accessibilityStrings = { 2057 shareSuccess: `Link copied to clipboard`, 2058 } 2059 2060 window.promotionStrings = { 2061 title: `Promotions`, 2062 } 2063 2064 window.productSettings = { 2065 variantOptionsDisplay: `radio`, 2066 } 2067 </script>
2067 2068 2069 <link href="https://store-themes.easystore.co/196384/themes/181882/assets/section-main-product.css?t=1787072441" rel="stylesheet" type="text/css" media="screen" /> 2070<link href="https://store-themes.easystore.co/196384/themes/181882/assets/component-loading-overlay.css?t=1787072441" rel="stylesheet" type="text/css" media="screen" /> 2071<link href="https://store-themes.easystore.co/196384/themes/181882/assets/product-quickview.css?t=1787072441" rel="stylesheet" type="text/css" media="screen" /> 2072 2073<product-quickview-modal> 2074 <div id="product-quickview-modal" class="product-quickview-modal-wrapper focus-inset" aria-modal="true" role="dialog" tabindex="-1"> 2075 <button type="button" class="product-quickview-modal__close modal__close-button link link--text focus-inset" aria-label="accessibility.close"> 2076 2077 2078 2079 <svg class="icon icon-close " data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600"><path d="M335.36,300,581.87,53.48a25,25,0,0,0-35.35-35.35L300,264.64,53.48,18.13A25,25,0,0,0,18.13,53.48L264.64,300,18.13,546.52a25,25,0,0,0,35.35,35.35L300,335.36,546.52,581.87a25,25,0,0,0,35.35-35.35Z" fill="currentColor"/></svg> 2080 2081 2082 2083 </button> 2084 2085 <div class="loading-overlay"> 2086 <div class="loading-overlay__spinner"> 2087 <svg aria-hidden="true" focusable="false" role="presentation" class="spinner" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"> 2088 <circle class="path" fill="none" stroke-width="6" cx="33" cy="33" r="30"></circle> 2089 </svg> 2090 </div> 2091 </div> 2092 2093 <div class="product-quickview-modal__body" style="display: none;"></div> 2094 </div> 2095 <div class="product-quickview-modal-backdrop"></div> 2096</product-quickview-modal> 2097
2098<script src="https://store-themes.easystore.co/196384/themes/181882/assets/product-form.js?t=1787072441" type="text/javascript" ></script>
vendor: 1 bytes, line 2098
2098
2099<script src="https://store-themes.easystore.co/196384/themes/181882/assets/product-quickview.js?t=1787072441" type="text/javascript" ></script>
2099 2100 2101<!-- Snippet:global/body_end: Product Description Tabs --> 2102<style> 2103 .product-description-tabs{ 2104 color: #000000; 2105 } 2106 .prod-desc-tab-container { 2107 padding: 15px; 2108 margin-right: auto; 2109 margin-left: auto; 2110 background-color: #ffffff; 2111 } 2112 /* Style the list */ 2113 .prod-desc-tab { 2114 list-style-type: none; 2115 margin: 0; 2116 padding: 0; 2117 border-bottom: solid 1px #ddd; 2118 /*overflow: hidden; 2119 border: 1px solid #e6e6e6; 2120 background-color: #fefefe; 2121 border-bottom: 1px solid #ddd;*/ 2122 } 2123 2124 /* Float the list items side by side */ 2125 li.tablinks { 2126 display: inline-block; 2127 border-top: 3px solid transparent; 2128 border-left: 1px solid transparent; 2129 border-right: 1px solid transparent; 2130 margin-bottom: -1px; 2131 margin-right: 3px; 2132 border-radius: 4px 4px 0 0; 2133 background-color: rgba(212,212,212,0.3); 2134 } 2135 2136 /* Style the links inside the list items */ 2137 li.tablinks a { 2138 color: #000000; 2139 cursor: pointer; 2140 margin-right: 2px; 2141 line-height: 1.42857143; 2142 display: block; 2143 padding: 10px 15px; 2144 } 2145 2146 /* Change background color of links on hover */ 2147 li.tablinks:hover { 2148 background-color: #ffffff; 2149 border-bottom-color: transparent; 2150 border-top: 3px solid #ddd; 2151 border-left: 1px solid #ddd; 2152 border-right: 1px solid #ddd; 2153 } /*rgba(212,212,212,0.3)*/ 2154 2155 /* Create an active/current tablink class */ 2156 li.tablinks a:focus, li.tablinks.active{ 2157 border-top: 3px solid #ddd; 2158 border-left: 1px solid #ddd; 2159 border-right: 1px solid #ddd; 2160 background-color: #ffffff; 2161 } 2162 2163 /* Style the tab content */ 2164 .prod-desc-tab-content { 2165 display: none; 2166 padding: 15px 15px; 2167 /*border: 1px solid #ccc;*/ 2168 border-top: none; 2169 clear: both; 2170 -webkit-animation: fadeEffect 1s; 2171 animation: fadeEffect 1s; /* Fading effect takes 1 second */ 2172 } 2173 .prod-desc-tab-content ul{ 2174 list-style-type: disc; 2175 } 2176 2177 /* if user select is_show_title is true, the title will be displayed; if not, hide the title*/ 2178 .prod-desc-tab-content > h2{ 2179 display:block; 2180 } 2181 2182 @-webkit-keyframes fadeEffect { 2183 from {opacity: 0;} 2184 to {opacity: 1;} 2185 } 2186 2187 @keyframes fadeEffect { 2188 from {opacity: 0;} 2189 to {opacity: 1;} 2190 } 2191 2192 .tab_drawer_heading { display: none; } 2193 2194 @media screen and (max-width: 480px) { 2195 .prod-desc-tab { 2196 display: none; 2197 } 2198 2199 2200 .tab_drawer_heading { 2201 background-color: transparent; 2202 color: #000000; 2203 border-bottom: 1px solid #ddd; 2204 margin: 0; 2205 padding: 6px 12px; 2206 display: block; 2207 cursor: pointer; 2208 -webkit-touch-callout: none; 2209 -webkit-user-select: none; 2210 -khtml-user-select: none; 2211 -moz-user-select: none; 2212 -ms-user-select: none; 2213 user-select: none; 2214 position: relative; 2215 } 2216 .tab_drawer_heading:after { 2217 content: ''; 2218 top: 50%; 2219 right: 40px; 2220 position: absolute; 2221 border: solid black; 2222 border-width: 0 3px 3px 0; 2223 display: inline-block; 2224 width: 10px; 2225 height: 10px; 2226 margin-top: -5px; 2227 transform: rotate(45deg); 2228 -webkit-transform: rotate(45deg); 2229 -webkit-transition: all 200ms linear; 2230 -moz-transition: all 200ms linear; 2231 -ms-transition: all 200ms linear; 2232 -o-transition: all 200ms linear; 2233 transition: all 200ms linear; 2234 } 2235 .d_active { 2236 background-color: rgba(212,212,212,0.3); 2237 } 2238 .d_active.tab_drawer_heading:after{ 2239 margin-top: -3px; 2240 transform: rotate(-135deg); 2241 -webkit-transform: rotate(-135deg); 2242 } 2243 } 2244 </style> 2245 2246
2246<script type="text/javascript"> 2247 2248 // If the page has no jquery 2249 // if(typeof jQuery == 'undefined'){ 2250 // console.log(456); 2251 // var script = document.createElement('script'); 2252 // script.type = "text/javascript"; 2253 // script.src = "https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"; 2254 // console.log(script); 2255 // document.getElementsByTagName('head')[0].appendChild(script); 2256 // } 2257 2258 2259 /* if in tab mode */ 2260 $("body").on("click", ".tablinks", function(){ 2261 var id = $(this).data("prod-desc-id"); 2262 2263 // Get all elements with class="prod-desc-tab-content" and hide them 2264 $(".prod-desc-tab-content").hide(); 2265 2266 // Get all elements with class="tablinks" and remove the class "active" 2267 $(".tablinks").removeClass("active"); 2268 2269 // Show the current tab, and add an "active" class to the link that opened the tab 2270 $("#"+id+"_desc_tab_content").show(); 2271 $(this).addClass("active"); 2272 2273 //make mobile view(drawer mode) also in same tab 2274 $(".tab_drawer_heading").removeClass("d_active"); 2275 $(".tab_drawer_heading[data-prod-desc-id='"+id+"']").addClass("d_active"); 2276 2277 }); 2278 /* if in drawer mode */ 2279 $("body").on("click", ".tab_drawer_heading", function() { 2280 var id = $(this).data("prod-desc-id"), 2281 active = $(this).hasClass("d_active") 2282 2283 $(".prod-desc-tab-content").hide(); 2284 $(".tab_drawer_heading").removeClass("d_active"); 2285 2286 if(!active){ 2287 $("#"+id+"_desc_tab_content").show(); 2288 $(this).addClass("d_active"); 2289 window.scroll({ 2290 top: $(this).offset().top - 120, 2291 left: 0, 2292 behavior: 'smooth' 2293 }); 2294 } 2295 2296 $(".tablinks").removeClass("active"); 2297 $(".tablinks[data-prod-desc-id='"+id+"']").addClass("active"); 2298 }); 2299 2300 $(function(){ 2301 var x = $(".product-description").find("h1, h2, h3, h4, h5, h6"); 2302 var title = null; 2303 var body = null; 2304 2305 if(x.length > 1){ 2306 $(".product-description").after("<link href='/assets/css/froala_style.min.css' rel='stylesheet' type='text/css'/><div class='product-description-tabs fr-view'><ul class='prod-desc-tab'></ul><div class='prod-desc-tab-container'></div></div>"); 2307 $(x).each(function(k, v){ 2308 title = $(v).text(); 2309 2310 if(k == 0){ 2311 body = $(x[0]).nextUntil(x[1]).clone(); 2312 $(".prod-desc-tab").append('<li class="tablinks active" data-prod-desc-id="'+k+'"><a>'+title+'</a></li>'); 2313 $(".prod-desc-tab-container").append('<h3 class="tab_drawer_heading d_active" data-prod-desc-id="'+k+'">'+title+'</h3><div id="'+k+'_desc_tab_content" class="prod-desc-tab-content" style="display:block"><h2>'+title+'</h2></div>'); 2314 $("#"+k+"_desc_tab_content h2").after(body); 2315 } 2316 else if(k == x.length){ 2317 body = $(x[k]).nextAll().clone(); 2318 $(".prod-desc-tab").append('<li class="tablinks" data-prod-desc-id="'+k+'"><a>'+title+'</a></li>'); 2319 $(".prod-desc-tab-container").append('<h3 class="tab_drawer_heading" data-prod-desc-id="'+k+'">'+title+'</h3><div id="'+k+'_desc_tab_content" class="prod-desc-tab-content" style="display:none"><h2>'+title+'</h2></div>'); 2320 $("#"+k+"_desc_tab_content h2").after(body); 2321 } 2322 else{ 2323 body = $(x[k]).nextUntil(x[k+1]).clone(); 2324 $(".prod-desc-tab").append('<li class="tablinks" data-prod-desc-id="'+k+'"><a>'+title+'</a></li>'); 2325 $(".prod-desc-tab-container").append('<h3 class="tab_drawer_heading" data-prod-desc-id="'+k+'">'+title+'</h3><div id="'+k+'_desc_tab_content" class="prod-desc-tab-content" style="display:none"><h2>'+title+'</h2></div>'); 2326 $("#"+k+"_desc_tab_content h2").after(body); 2327 } 2328 }); 2329 $(".product-description").hide(); 2330 } 2331 2332 }); 2333 </script>
2333 2334<!-- /Snippet --> 2335 2336<!-- Snippet:global/body_end: Product Label --> 2337<link href='https://apps.easystore.co/assets/css/product-label/main.css?v2.3' rel='stylesheet' type='text/css' media='screen' />
2337<script src='https://apps.easystore.co/product-labels/productlabelv2.js?shop=butterflyreptile.easy.co' type='text/javascript'></script>
2337 2338<!-- /Snippet -->
2339<script> 2340 2341 /* 2342 2343 ------ 2344 Events 2345 ------ 2346 2347 pages/viewed 2348 2349 customers/signup 2350 2351 customers/login 2352 2353 products/searched 2354 2355 collections/viewed 2356 2357 products/viewed 2358 2359 products/shared 2360 2361 wishlists/item_added 2362 2363 carts/items_added 2364 2365 carts/viewed 2366 2367 carts/item_removed 2368 2369 checkouts/initiated 2370 2371 checkouts/shipping_info_added 2372 2373 checkouts/payment_info_added 2374 2375 checkouts/completed 2376 2377 orders/placed 2378 2379 orders/purchased 2380 2381 payments/captured 2382 2383 payments/failed 2384 2385 */ 2386 2387 window.__latest_cart = window.__latest_cart || null; 2388 2389 const _selector = document.querySelector.bind(document), 2390 _selectorAll = document.querySelectorAll.bind(document) 2391 2392 document.addEventListener('DOMContentLoaded', (event) => { 2393 2394 const default_currency = getCookie("currency") 2395 const customer_id = window.__st.cid 2396 const template = window.__st.p 2397 2398 onPageView() 2399 2400 //-----------------------// 2401 // Configs // 2402 //-----------------------// 2403 2404 window.dataLayer = window.dataLayer || [] 2405 2406 Array.prototype.last = Array.prototype.last || function() { 2407 return this[this.length - 1] || null 2408 } 2409 2410 Array.prototype.first = Array.prototype.first || function() { 2411 return this[0] || null 2412 } 2413 2414 //----------------------// 2415 // Triggers // 2416 //----------------------// 2417 2418 const XHR = window.XMLHttpRequest 2419 2420 function xhr() { 2421 2422 const xhr = new XHR() 2423 2424 xhr.addEventListener("readystatechange", function() { 2425 2426 if(xhr.readyState != 4) return 2427 2428 try { 2429 2430 const response_url = xhr.responseURL 2431 2432 if (response_url.includes("cart/add")) { 2433 2434 window.__latest_cart = JSON.parse(xhr.response) 2435 2436 onCartItemsAdded() // ok 2437 2438 } 2439 2440 if (response_url.includes("cart/remove_item_quantity")) { 2441 2442 window.__latest_cart = JSON.parse(xhr.response) 2443 2444 onCartItemRemoved() // ok 2445 2446 } 2447 2448 if (response_url.includes("new_cart?retrieve=true")) { 2449 2450 result = JSON.parse(xhr.response) 2451 2452 if (result.cart) { 2453 window.__latest_cart = result.cart 2454 } 2455 2456 } 2457 2458 } catch(e) { 2459 2460 console.error(e) 2461 2462 } 2463 2464 }, false); 2465 2466 return xhr 2467 2468 } 2469 2470 window.XMLHttpRequest = xhr 2471 2472 switch(template) { 2473 2474 case 'cart': onCartView() // ok 2475 break 2476 case 'product': onProductView() // ok 2477 break 2478 case 'collection': onCollectionView() // ok 2479 break 2480 case 'blog': onBlogView() 2481 break 2482 case 'article': onArticleView() 2483 break 2484 case 'payment_completed': onOrderPlace() 2485 break 2486 case 'payment_fail': onPaymentFail() 2487 break 2488 2489 } 2490 2491 // _selector('form[action="/checkout/payments"]').addEventListener("submit", onPaymentInfoAdded(_selector('form[action="/checkout/payments"]'))) 2492 if (_selector('form[action="/checkout/detail"]')) _selector('form[action="/checkout/detail"]').addEventListener("submit", ()=>{onShippingInfoAdded(_selector('form[action="/checkout/detail"]'))}) // ok 2493 if (_selector('form[action="/checkout/shipping"]')) _selector('form[action="/checkout/shipping"]').addEventListener("submit", ()=>{onShippingInfoAdded(_selector('form[action="/checkout/shipping"]'))}) // ok 2494 if (_selector('form[action="/account/register"]')) _selector('form[action="/account/register"]').addEventListener("submit", onSignUp) // ok 2495 if (_selector('form[action="/account/login"]')) _selector('form[action="/account/login"]').addEventListener("submit", onLogin) // ok 2496 if (_selector('form[action="/search"]')) _selector('form[action="/search"]').addEventListener("submit", onProductSearch()) // ok 2497 if (_selector('#line-login-btn')) _selector('#line-login-btn').addEventListener('click', onLineLogin) // ok 2498 if (_selector('#PlaceOrder')) _selector('#PlaceOrder').addEventListener("click", ()=>{onCheckoutComplete(_selector('form[action="/checkout/payments"]'))}); // ok 2499 if (_selector('#add_wishlist')) _selector('#add_wishlist').addEventListener("click", onWishlistItemAdded) // ok 2500 if (_selectorAll('a[href="/account/logout"]')) _selectorAll('a[href="/account/logout"]').forEach(logoutButton => logoutButton.addEventListener("click", onLogout)) // ok 2501 if (_selector('.CartDrawerTrigger.cart-page-link')) _selector('.CartDrawerTrigger.cart-page-link').addEventListener("click", onCartView) // ok 2502 if (_selector('.CartDrawerTrigger.cart-page-link.mobile-cart-page-link')) _selector('.CartDrawerTrigger.cart-page-link.mobile-cart-page-link').addEventListener("click", onCartView) // ok 2503 if (_selectorAll('a[class^="share-"]')) _selectorAll('a[class^="share-"]').forEach(shareButton => shareButton.addEventListener("click", ()=>{onProductShare(shareButton)}) ) // ok 2504 if (_selectorAll('[name$="checkout"]')) _selectorAll('[name$="checkout"]').forEach(checkoutButton => checkoutButton.addEventListener("click", onCheckoutInitiate)) 2505 2506 // For append elements 2507 const bodyMutationObserver = new MutationObserver(() => { 2508 if (_selector('#form__spc #PlaceOrder')) _selector('#form__spc #PlaceOrder').addEventListener("click", onSinglePageCheckout) // ok 2509 if (_selectorAll('[name$="checkout"]')) _selectorAll('[name$="checkout"]').forEach(checkoutButton => checkoutButton.addEventListener("click", onCheckoutInitiate)) 2510 }); 2511 bodyMutationObserver.observe(_selector("body"), {subtree: true, childList: true}); 2512 2513 //------------------------------// 2514 // Event handlers // 2515 //------------------------------// 2516 2517 function onPageView() { 2518 2519 EasyStore.Event.dispatch('pages/viewed', { 2520 page: { 2521 type: template, 2522 title: document.title, 2523 description: _selector('meta[name=description]') ? _selector('meta[name=description]').getAttribute('content') : null, 2524 url: location.href, 2525 } 2526 }) 2527 2528 } 2529 2530 function onSignUp() { 2531 2532 const email_regex = new RegExp(/^[a-zA-Z0-9.!#$%&"*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/) 2533 const phone_regex = new RegExp(/^(\+?6?01)[0-46-9]-*[0-9]{7,8}$/) 2534 2535 const email_or_phone = _selector(`input[name="customer[email_or_phone]"]`).value.replace("+", "").replace(/\s+/, "") 2536 2537 let data = {} 2538 2539 if (email_regex.test(email_or_phone)) { 2540 data.method = 'email' 2541 data.email = email_or_phone 2542 } 2543 2544 if (phone_regex.test(email_or_phone)) { 2545 data.method = "phone" 2546 data.phone = email_or_phone 2547 } 2548 2549 if (!data.method) return 2550 2551 EasyStore.Event.dispatch('customers/signup', data) 2552 2553 } 2554 2555 function onLogin() { 2556 2557 const email_regex = new RegExp(/^[a-zA-Z0-9.!#$%&"*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/) 2558 const phone_regex = new RegExp(/^(\+?6?01)[0-46-9]-*[0-9]{7,8}$/) 2559 2560 const email_or_phone = _selector(`input[name="customer[email_or_phone]"]`).value.replace("+", "").replace(/\s+/, "") 2561 2562 let data = {} 2563 2564 if (email_regex.test(email_or_phone)) { 2565 data.method = 'email' 2566 data.email = email_or_phone 2567 } 2568 2569 if (phone_regex.test(email_or_phone)) { 2570 data.method = "phone" 2571 data.phone = email_or_phone 2572 } 2573 2574 if (!data.method) return 2575 2576 EasyStore.Event.dispatch('customers/login', data) 2577 2578 } 2579 2580 function onLineLogin() { 2581 2582 EasyStore.Event.dispatch('customers/login', { method: 'line' }) 2583 2584 } 2585 2586 function onLogout() { 2587 2588 EasyStore.Event.dispatch('customers/logout', { customer_id }) 2589 2590 } 2591 2592 function onBlogView() { 2593 2594 const blog = {"id":145295,"handle":"makmal-rama-rama-melupuskan-3000-ulat-beluncas-ketika-perintah-pkp","url":"\/blogs\/makmal-rama-rama-melupuskan-3000-ulat-beluncas-ketika-perintah-pkp","title":"Our Blog","description":"Makmal Rama-rama melupuskan 3000 ulat beluncas ketika perintah PKP","articles_count":1,"all_tags":null,"comments_enabled":null,"moderated":null,"next_article":null,"previous_article":null,"tags":null,"updated_at":"2020-05-06T20:06:23.000+08:00","articles":[{"id":27906,"title":"Covid-19: Pembiakan Rama-rama Turut Terjejas","handle":"covid-19-pembiakan-rama-rama-turut-terjejas","url":"\/blogs\/makmal-rama-rama-melupuskan-3000-ulat-beluncas-ketika-perintah-pkp\/covid-19-pembiakan-rama-rama-turut-terjejas","author":null,"description":"Makmak Taman Rama-rama dan Reptilia Melaka lupus 3000 ulat beluncas seketika PKP","image_url":"https:\/\/cdn.store-assets.com\/s\/196384\/f\/4680694.png","image":{"src":"https:\/\/cdn.store-assets.com\/s\/196384\/f\/4680694.png"},"published_at":"2020-05-06T20:08:34.000+08:00","updated_at":"2023-10-06T21:06:39.000+08:00"}]} 2595 2596 EasyStore.Event.dispatch('blogs/viewed', { blog }) 2597 2598 } 2599 2600 function onArticleView() { 2601 2602 const article = "" 2603 2604 EasyStore.Event.dispatch('articles/viewed', { article }) 2605 2606 } 2607 2608 function onProductSearch() { 2609 2610 const query = _selector('input[name=q]').value 2611 2612 if (!query) return 2613 2614 EasyStore.Event.dispatch('products/searched', { query }) 2615 2616 } 2617 2618 function onCollectionView() { 2619 2620 const collection = "" 2621 2622 EasyStore.Event.dispatch('collections/viewed', { collection }) 2623 2624 } 2625 2626 function onProductView() { 2627 2628 const product = "" 2629 2630 EasyStore.Event.dispatch("products/viewed", { product }) 2631 2632 } 2633 2634 function onProductShare(el) { 2635 2636 const product = "" 2637 2638 const channel = el.getAttribute("class").split("-").last() 2639 2640 EasyStore.Event.dispatch('products/shared', { product, channel }) 2641 2642 } 2643 2644 function onWishlistItemAdded() { 2645 2646 let product = "" 2647 const quantity = _selector("#Quantity").value 2648 2649 EasyStore.Event.dispatch('wishlists/item_added', { product }) 2650 2651 } 2652 2653 async function onCartItemsAdded() { 2654 2655 const cart = await getCart() 2656 2657 if(cart && cart.items != undefined && cart.items.length > 0) { 2658 2659 EasyStore.Event.dispatch('carts/item_added', { cart }) 2660 2661 } 2662 2663 } 2664 2665 async function onCartView() { 2666 2667 const cart = await getCart() 2668 2669 EasyStore.Event.dispatch('carts/viewed', { cart }) 2670 2671 } 2672 2673 async function onCartItemRemoved() { 2674 2675 const cart = await getCart() 2676 2677 cart.items = [] 2678 2679 if(cart) { 2680 2681 EasyStore.Event.dispatch('carts/item_removed', { cart }) 2682 2683 } 2684 2685 } 2686 2687 async function onCheckoutInitiate() { 2688 2689 const cart = await getCart() 2690 2691 EasyStore.Event.dispatch('checkouts/initiated', { cart }) 2692 2693 } 2694 2695 async function onShippingInfoAdded(form) { 2696 let checkout = getCheckout() 2697 2698 let form_data = {} 2699 new FormData(form).forEach((value, key) => form_data[key] = value) 2700 2701 let shipping_tier = null 2702 2703 if (form_data.type && form_data.type.startsWith("r_pickup")) { 2704 shipping_tier = `Pickup - ${form_data.pick_location}` 2705 } 2706 2707 if (form_data.s_id) {
2708 shipping_tier = _selector(`input[id='`+form_data.s_id+`']`).getAttribute("data-shipping-name") 2709 } 2710 2711 if (!shipping_tier) return 2712 2713 EasyStore.Event.dispatch('checkouts/shipping_info_added', { checkout, shipping_tier }) 2714 2715 } 2716 2717 async function onPaymentInfoAdded(form) { 2718 2719 let checkout = getCheckout() 2720 2721 let payment_type = new FormData(form).get('payment_method') 2722 2723 EasyStore.Event.dispatch("checkouts/payment_info_added", { checkout, payment_type }) 2724 2725 } 2726 2727 async function onOrderPlace() { 2728 2729 let cart_token = getCookie("cart_js") 2730 let previous_cart_token = getCookie("previous_cart_ga4_js") 2731 2732 if (previous_cart_token && previous_cart_token == cart_token) { 2733 // Prevent duplicate purchase tracking 2734 return 2735 } 2736 2737 let order = getOrder() 2738 2739 EasyStore.Event.dispatch('orders/placed', { order }) 2740 2741 if(order.is_manual_payment) { 2742 2743 EasyStore.Event.dispatch('orders/purchased', { order }) 2744 2745 } 2746 2747 const last_transaction = order.transactions.last() 2748 2749 if (last_transaction.status) { 2750 2751 EasyStore.Event.dispatch('orders/purchased', { order }) 2752 EasyStore.Event.dispatch('payments/captured', { order }) 2753 2754 } 2755 2756 } 2757 2758 async function onPaymentFail() { 2759 2760 const order = getOrder() 2761 2762 EasyStore.Event.dispatch('payments/failed', { order }) 2763 2764 } 2765 2766 async function onCheckoutComplete(form) { 2767 2768 onPaymentInfoAdded(form) 2769 2770 const checkout = getCheckout() 2771 2772 EasyStore.Event.dispatch('checkouts/completed', { checkout }) 2773 2774 } 2775 2776 async function onSinglePageCheckout() { 2777 2778 // let checkout = $("[data-app-checkout]").data("app-checkout") 2779 2780 let checkout = getCheckout() 2781 2782 // const payment_type = _selector("#app_spc_payment_method").find(`[class*="label-content"]`).first().find("b").first().text() 2783 const payment_type = _selector("#app_spc_payment_method").getElementsByClassName('label-content')[0].getElementsByTagName('b')[0].innerHTML 2784 2785 const shipping_method = _selector("#delivery_method").value 2786 2787 let shipping_tier = null 2788 let app_spc_customer_info_label = _selector("#app_spc_customer_info").getElementsByClassName('label-content') 2789 if (shipping_method == "shipping") { 2790 shipping_tier = app_spc_customer_info_label[app_spc_customer_info_label.length - 1].getElementsByTagName('b')[0].innerHTML 2791 } 2792 2793 if (shipping_method == "pickup") { 2794 shipping_tier = app_spc_customer_info_label[0].innerHTML 2795 } 2796 2797 if (shipping_tier) { 2798 2799 EasyStore.Event.dispatch('checkouts/shipping_info_added', { 2800 checkout, 2801 shipping_tier, 2802 }) 2803 2804 } 2805 2806 if (payment_type) { 2807 2808 EasyStore.Event.dispatch('checkouts/payment_info_added', { 2809 checkout, 2810 payment_type, 2811 }) 2812 2813 } 2814 2815 EasyStore.Event.dispatch('checkouts/completed', { checkout }) 2816 2817 } 2818 2819 }) 2820 2821 2822 //-----------------------// 2823 // Functions // 2824 //-----------------------// 2825 2826 function getCookie(name) { 2827 2828 name += "=" 2829 2830 decodedCookie = decodeURIComponent(document.cookie) 2831 2832 ca = decodedCookie.split(";") 2833 2834 for(i = 0; i < ca.length; i++) { 2835 c = ca[i] 2836 while (c.charAt(0) == " ") { 2837 c = c.substring(1) 2838 } 2839 if (c.indexOf(name) == 0) { 2840 return c.substring(name.length, c.length) 2841 } 2842 } 2843 2844 return "" 2845 2846 } 2847 2848 const parsePrice = price => { 2849 if(typeof price === 'string') { 2850 return parseFloat(price.split(',').join('')) 2851 } 2852 2853 return price 2854 } 2855 2856 const requestCart = async (method, data) => { 2857 2858 let response = await fetch('/cart.json', {method: 'GET',headers: {'Content-Type': 'application/json'}}) 2859 result = await response.json() 2860 2861 return result.cart 2862 2863 } 2864 const getCart = async (latest = false) => { 2865 2866 let cart = window.__latest_cart 2867 2868 const cart_invalid = !cart || !cart.items || (cart.total_price > 0 && !cart.items.length) 2869 2870 if(latest || cart_invalid) { 2871 cart = await requestCart() 2872 } 2873 2874 cart.items = cart.items || [] 2875 2876 return mapCart(cart) 2877 2878 } 2879 2880 const getCheckout = async () => { 2881 mapCheckout(window.__latest_cart || await requestCart()) 2882 } 2883 2884 const getOrder = async () => { 2885 mapOrder(window.__latest_cart || await requestCart()) 2886 } 2887 2888 //-----------------------// 2889 // Mappers // 2890 //-----------------------// 2891 2892 const fallbackAttribute = (object, attribute) => { 2893 2894 if(!Array.isArray(attribute)) { 2895 attribute = [attribute] 2896 } 2897 2898 let final_value = null 2899 2900 do { 2901 2902 final_value = object[attribute.shift()] 2903 2904 } while(!final_value && attribute.length) 2905 2906 return final_value 2907 2908 } 2909 2910 const map = (object, mapper) => { 2911 2912 const newObject = {} 2913 2914 for(const key in mapper) { 2915 2916 // Handle different keys between new and old format
2917 newObject[key] = fallbackAttribute(object, mapper[key]) 2918 2919 // Cast price to float 2920 if(newObject[key] && ['price', 'amount', 'discount', 'discounts'].some(x => key.endsWith(x))) { 2921 newObject[key] = parsePrice(newObject[key]) 2922 } 2923 2924 if(newObject[key] === undefined) { 2925 delete newObject[key] 2926 } 2927 2928 } 2929 2930 return newObject 2931 2932 } 2933 2934 const mapCart = cart => { 2935 2936 const oldCart = cart 2937 2938 const mapper = { 2939 id: 'id', 2940 currency: 'currency', 2941 item_count: 'item_count', 2942 items: 'items', 2943 total_price: 'total_price', 2944 latest_items: 'latest_items' 2945 } 2946 2947 cart = map(cart, mapper) 2948 2949 const discounts = (oldCart.storewide_discounts || []).concat((oldCart.voucher_discounts || [])) 2950 2951 cart.discount_applications = discounts.map(discount => ({ 2952 title: discount.voucher_code || null, 2953 value: parsePrice(discount.amount), 2954 })) 2955 2956 cart.original_total_price = cart.items.length 2957 ? cart.items 2958 .map(item => item.original_price) 2959 .reduce((sum, price) => sum + price) 2960 : 0 2961 2962 cart.total_discount = cart.discount_applications.length 2963 ? cart.discount_applications 2964 .map(discount => parsePrice(discount.value)) 2965 .reduce((sum, value) => sum + value) 2966 : 0 2967 2968 cart.items = cart.items.map(item => mapLineItem(item)) 2969 2970 return cart 2971 2972 } 2973 2974 const mapCheckout = checkout => { 2975 2976 const mapper = { 2977 note: 'note', 2978 attributes: 'note_attributes', 2979 billing_address: 'billing_address', 2980 currency: 'currency', 2981 customer_id: 'customer_id', 2982 discounts_amount: 'total_discount', 2983 id: 'id', 2984 line_items: 'order_item', 2985 order_number: 'order_number', 2986 shipping_address: 'shipping_address', 2987 shipping_price: 'shipping_tax', 2988 shipping_method: 'shipping_method_name', 2989 tax_price: 'total_tax', 2990 } 2991 2992 checkout = map(checkout, mapper) 2993 2994 checkout.requires_shipping = checkout.line_items.some(item => item.shipping_required) 2995 2996 checkout.line_items = checkout.line_items.map(item => mapLineItem(item)) 2997 2998 return checkout 2999 3000 } 3001 3002 const mapOrder = order => { 3003 3004 const mapper = { 3005 attributes: 'note_attributes', 3006 billing_address: 'billing_address', 3007 cancelled: 'is_cancelled', 3008 cancelled_at: 'cancelled_at', 3009 created_at: 'created_at', 3010 customer_id: 'customer_id', 3011 // discount_applications: 'discount_applications', 3012 email: 'email', 3013 financial_status: 'financial_status', 3014 fulfillment_status: 'fulfillment_status', 3015 line_items: 'order_item', 3016 note: 'note', 3017 order_number: 'order_number', 3018 phone: 'phone', 3019 shipping_address: 'shipping_address', 3020 shipping_methods: 'shipping_methods', 3021 shipping_price: 'total_shipping', 3022 subtotal_price: 'subtotal_price', 3023 // tax_lines: 'tax_lines', 3024 tax_price: 'total_tax', 3025 total_discounts: 'total_discount', 3026 total_net_amount: 'total_amount_include_transaction', 3027 total_price: 'total_price', 3028 transactions: 'transaction_records', 3029 is_manual_payment: 'is_manual_payment', 3030 } 3031 3032 order.email = order.billing_address.email 3033 order.phone = order.billing_address.phone 3034 order.shipping_method = order.shipping_method_name 3035 3036 order = map(order, mapper) 3037 3038 order.line_items = order.line_items.map(item => mapLineItem(item)) 3039 order.transactions = order.transactions.map(transaction => mapTransaction(transaction)) 3040 3041 return order 3042 3043 } 3044 3045 const mapLineItem = line_item => { 3046 3047 const old_line_item = line_item 3048 3049 const mapper = { 3050 final_price: 'price', 3051 image: 'img_url', 3052 message: 'message', 3053 original_line_price: 'original_line_price', 3054 original_price: 'original_price', 3055 properties: 'properties', 3056 quantity: 'quantity', 3057 requires_shipping: 'shipping_required', 3058 sku: 'sku', 3059 taxable: 'taxable', 3060 title: 'product_name', 3061 product_name: 'product_name', 3062 url: 'url', 3063 product_id: 'product_id', 3064 variant_id: 'variant_id', 3065 id: ['id', 'i_id'], 3066 } 3067 3068 line_item = map(line_item, mapper) 3069 3070 line_item.product_id = line_item.product_id || (old_line_item.product && old_line_item.product.id) || null 3071 line_item.variant_id = line_item.variant_id || (old_line_item.variant && old_line_item.variant.id) || null 3072 line_item.image = line_item.image || (old_line_item.image && old_line_item.image.url) || null 3073 3074 return line_item 3075 3076 } 3077 3078 const mapTransaction = transaction => { 3079 3080 const mapper = { 3081 amount: 'amount', 3082 created_at: 'created_at', 3083 gateway: 'gateway_type', 3084 id: 'id', 3085 status: 'status', 3086 } 3087 3088 transaction = map(transaction, mapper) 3089 3090 return transaction 3091 3092 } 3093 3094 3095</script>
3095 3096 3097</body> 3098</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.