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/1424395/f/16453365.png" /> 15 16 17 <!-- Title and description ================================================== --> 18 <title> 19 ç»å ¥ – AboutTime Tech 20 </title> 21 22 23 24 <!-- Social meta ================================================== --> 25 26 27 <meta property="og:type" content="website"> 28 <meta property="og:title" content="ç»å ¥"> 29 <meta property="og:url" content="https://abouttime-tech.com/account/login"> 30 31 <meta property="og:image" content="https://cdn.store-assets.com/s/1424395/f/16069016.png"> 32 <meta property="og:image:secure_url" content="https://cdn.store-assets.com/s/1424395/f/16069016.png"> 33 34 35 36<meta property="og:description" content="AboutTime Tech 宿¹ç·ä¸ååºï¼çºæ¨ç²¾é¸æºæ §çæ´»ç§æãæåæ¯ Herowatch å ç«¥æºæ §æé¶ï¼F3/mini ç³»åï¼åçææè ï¼ä¸¦æä¾ Hereu è¡åè¾¦å ¬é±éï¼èè½æºçéµç¤ã觸æ§çï¼å親åå ±å¸çæºç©å ·ãå¾å®è·å©åå®å ¨å°æå工使çï¼AboutTime Tech ç¨ç§æè³ªæè±å¯æ¨çæ¯ä¸å¤©ã"> 37<meta property="og:site_name" content="AboutTime Tech"> 38 39 40 41 <meta name="twitter:card" content="summary"> 42 43 44 45 <meta name="twitter:site" content="@"> 46 47 48 49 50 51 <!-- Helpers ================================================== --> 52 <link rel="canonical" href="https://abouttime-tech.com/account/login"> 53 <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"> 54 <meta name="theme-color" content="#000000"> 55 56
56<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js" type="text/javascript" ></script>
56 57 58 <!-- Header hook for plugins ================================================== --> 59 60<!-- ScriptTags -->
61<script>window.__st={p: "customers",cid: null,cem: null,cph: null,cfn: null,cln: null,cge: null,cdb: null,ccc: null};</script>
61<script src='/assets/events.js'></script>
61<script>(function(){function asyncLoad(){var urls=['/assets/facebook-pixel.js?v=1.2.1760434303','/assets/traffic.js?v=1'];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>
61 62<!-- /ScriptTags --> 63 64 65 66
66<script src="https://store-themes.easystore.co/1424395/themes/308896/assets/global.js?t=1787094029" defer="defer"></script>
66 67 68 69 70
70<script src="/assets/shop_common.js" type="text/javascript" ></script>
70 71
71<script src="/assets/customer_area.js" type="text/javascript" ></script>
71 72 73
73<script> 74 (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ 75 (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), 76 m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) 77 })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); 78 79 ga('create', '', 'auto','myTracker'); 80 ga('myTracker.send', 'pageview'); 81 82 </script>
82 83 84
84<script src="/assets/storefront.js?id=1d419de2011a5572c98b" type="text/javascript" ></script>
84 85 86 87 <!-- CSS ================================================== --> 88 <style> 89 @font-face { 90 font-family: 'Alata'; 91 font-style: normal; 92 font-weight: regular; 93 src: local('Alata regular'), local('Alata-regular'), url(https://fonts.gstatic.com/s/alata/v2/PbytFmztEwbIofe6xKcRQEOX.ttf) format('truetype'); 94 } 95 96 @font-face { 97 font-family: 'Alata'; 98 font-style: normal; 99 font-weight: regular; 100 src: local('Alata regular'), local('Alata-regular'), url(https://fonts.gstatic.com/s/alata/v2/PbytFmztEwbIofe6xKcRQEOX.ttf) format('truetype'); 101 } 102 103 :root { 104 --font-body-family: 'Alata', sans-serif; 105 --font-body-style: normal; 106 --font-body-weight: 500; 107 108 --font-heading-family: 'Alata', sans-serif; 109 --font-heading-style: normal; 110 --font-heading-weight: 700; 111 112 --color-heading-text: 0,0,0; 113 --color-base-text: 0,0,0; 114 --color-base-background-1: 255,255,255; 115 --color-base-background-2: 255,255,255; 116 117 --color-base-solid-button-labels: 255,255,255; 118 --color-base-outline-button-labels: 5,28,98; 119 120 --color-base-accent-1: 0,0,0; 121 --color-base-accent-2: 0,0,0; 122 --payment-terms-background-color: 255,255,255; 123 124 --gradient-base-background-1: 255,255,255; 125 --gradient-base-background-2: 255,255,255; 126 --gradient-base-accent-1: 0,0,0; 127 --gradient-base-accent-2: 0,0,0; 128 129 --page-width: 145rem; 130 } 131 132 *, 133 *::before, 134 *::after { 135 box-sizing: inherit; 136 } 137 138 html { 139 box-sizing: border-box; 140 font-size: 62.5%; 141 height: 100%; 142 } 143 144 body { 145 display: grid; 146 grid-template-rows: auto auto 1fr auto; 147 grid-template-columns: 100%; 148 min-height: 100%; 149 margin: 0; 150 font-size: 1.5rem; 151 letter-spacing: 0.06rem; 152 line-height: 1.8; 153 font-family: var(--font-body-family); 154 font-style: var(--font-body-style); 155 font-weight: var(--font-body-weight); 156 157 } 158 159 @media screen and (min-width: 750px) { 160 body { 161 font-size: 1.6rem; 162 } 163 } 164 </style> 165 166 <link href="https://store-themes.easystore.co/1424395/themes/308896/assets/base.css?t=1787094029" rel="stylesheet" type="text/css" media="screen" /> 167 168 169 170 171
171<script>document.documentElement.className = document.documentElement.className.replace('no-js', 'js');</script>
171 172</head> 173 174<body id="------" class="template-customers" > 175 176 177<!-- Snippet:global/body_start: Console Extension --> 178<div id='es_console' style='display: none;'>1424395</div> 179<!-- /Snippet --> 180 181 182 <style> 183 header { 184 --logo-width: 200px; 185 } 186 .header-wrapper, 187 .header-wrapper .list-menu--disclosure, 188 .header-wrapper .search-modal{ 189 background-color: #FFFFFF; 190 } 191 .header-wrapper .search-modal .field__input{ 192 background-color: rgb(var(--color-background)); 193 } 194 .header-wrapper summary .icon-caret, 195 .header-wrapper .header__menu-item a, 196 .header-wrapper .list-menu__item, 197 .header-wrapper .link--text{ 198 color: #000000; 199 } 200 201 .search-modal__form{ 202 position: relative; 203 } 204 205 .dropdown { 206 display: none; 207 position: absolute; 208 top: 100%; 209 left: 0; 210 width: 100%; 211 padding: 5px 0; 212 background-color: #fff; 213 color:#000; 214 z-index: 1000; 215 border-bottom-left-radius: 15px; 216 border-bottom-right-radius: 15px; 217 border: 1px solid rgba(var(--color-foreground), 1); 218 border-top: none; 219 overflow-x: hidden; 220 overflow-y: auto; 221 max-height: 350px; 222 } 223 224 .dropdown-item { 225 padding: 0.4rem 2rem; 226 cursor: pointer; 227 line-height: 1.4; 228 overflow: hidden; 229 text-overflow: ellipsis; 230 white-space: nowrap; 231 } 232 233 .dropdown-item:hover{ 234 background-color: #f3f3f3; 235 } 236 237 .search__input.is-focus{ 238 border-radius: 15px; 239 border-bottom-left-radius: 0; 240 border-bottom-right-radius: 0; 241 border: 1px solid rgba(var(--color-foreground), 1); 242 border-bottom: none; 243 box-shadow: none; 244 } 245 246 .clear-all { 247 text-align: right; 248 padding: 0 2rem 0.2rem; 249 line-height: 1; 250 font-size: 70%; 251 margin-bottom: -2px; 252 } 253 254 .clear-all:hover{ 255 background-color: #fff; 256 } 257 258 .search-input-focus .easystore-section-header-hidden{ 259 transform: none; 260 } 261 .referral-notification { 262 position: absolute; 263 top: 100%; 264 right: 0; 265 background: white; 266 border: 1px solid #e0e0e0; 267 border-radius: 8px; 268 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); 269 width: 280px; 270 z-index: 1000; 271 padding: 16px; 272 margin-top: 8px; 273 font-size: 14px; 274 line-height: 1.4; 275 } 276 277 .referral-notification::before { 278 content: ''; 279 position: absolute; 280 top: -8px; 281 right: 20px; 282 width: 0; 283 height: 0; 284 border-left: 8px solid transparent; 285 border-right: 8px solid transparent; 286 border-bottom: 8px solid white; 287 } 288 289 .referral-notification::after { 290 content: ''; 291 position: absolute; 292 top: -9px; 293 right: 20px; 294 width: 0; 295 height: 0; 296 border-left: 8px solid transparent; 297 border-right: 8px solid transparent; 298 border-bottom: 8px solid #e0e0e0; 299 } 300 301 .referral-notification h4 { 302 margin: 0 0 8px 0; 303 color: #2196F3; 304 font-size: 16px; 305 font-weight: 600; 306 } 307 308 .referral-notification p { 309 margin: 0 0 12px 0; 310 color: #666; 311 } 312 313 .referral-notification .referral-code { 314 background: #f5f5f5; 315 padding: 8px; 316 border-radius: 4px; 317 font-family: monospace; 318 font-size: 13px; 319 text-align: center; 320 margin: 8px 0; 321 border: 1px solid #ddd; 322 } 323 324 .referral-notification .close-btn { 325 position: absolute; 326 top: 8px; 327 right: 8px; 328 background: none; 329 border: none; 330 font-size: 18px; 331 color: #999; 332 cursor: pointer; 333 padding: 0; 334 width: 20px; 335 height: 20px; 336 line-height: 1; 337 } 338 339 .referral-notification .close-btn:hover { 340 color: #333; 341 } 342 343 .referral-notification .action-btn { 344 background: #2196F3; 345 color: white; 346 border: none; 347 padding: 8px 16px; 348 border-radius: 4px; 349 cursor: pointer; 350 font-size: 12px; 351 margin-right: 8px; 352 margin-top: 8px; 353 } 354 355 .referral-notification .action-btn:hover { 356 background: #1976D2; 357 } 358 359 .referral-notification .dismiss-btn { 360 background: transparent; 361 color: #666; 362 border: 1px solid #ddd; 363 padding: 8px 16px; 364 border-radius: 4px; 365 cursor: pointer; 366 font-size: 12px; 367 margin-top: 8px; 368 } 369 370 .referral-notification .dismiss-btn:hover { 371 background: #f5f5f5; 372 } 373 .referral-modal__dialog { 374 transform: translate(-50%, 0); 375 transition: transform var(--duration-default) ease, visibility 0s; 376 z-index: 10000; 377 position: fixed; 378 top: 20vh; 379 left: 50%; 380 width: 100%; 381 max-width: 350px; 382 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); 383 border-radius: 12px; 384 background-color: #fff; 385 color: #000; 386 padding: 20px; 387 text-align: center; 388 } 389 390 .modal-overlay.referral-modal-overlay { 391 position: fixed; 392 top: 0; 393 left: 0; 394 width: 100%; 395 height: 100%; 396 background-color: rgba(0, 0, 0, 0.7); 397 z-index: 2001; 398 display: block; 399 opacity: 1;
400 transition: opacity var(--duration-default) ease, visibility 0s; 401 } 402</style> 403 404<link rel="preload" href="https://store-themes.easystore.co/1424395/themes/308896/assets/section-header.css?t=1787094029" as="style" onload="this.onload=null;this.rel='stylesheet'"> 405<link rel="preload" href="https://store-themes.easystore.co/1424395/themes/308896/assets/component-list-menu.css?t=1787094029" as="style" onload="this.onload=null;this.rel='stylesheet'"> 406<link rel="preload" href="https://store-themes.easystore.co/1424395/themes/308896/assets/component-menu-drawer.css?t=1787094029" as="style" onload="this.onload=null;this.rel='stylesheet'"> 407<link rel="preload" href="https://store-themes.easystore.co/1424395/themes/308896/assets/component-cart-notification.css?v1.1?t=1787094029" as="style" onload="this.onload=null;this.rel='stylesheet'"> 408
409<script src="https://store-themes.easystore.co/1424395/themes/308896/assets/cart-notification.js?t=1787094029" defer="defer"></script>
vendor: 2 bytes, line 409
409
410<script src="https://store-themes.easystore.co/1424395/themes/308896/assets/details-modal.js?t=1787094029" defer="defer"></script>
410 411 412<svg xmlns="http://www.w3.org/2000/svg" class="hidden"> 413 <symbol id="icon-search" viewbox="0 0 18 19" fill="none"> 414 <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"/> 415 </symbol> 416 417 <symbol id="icon-close" class="icon icon-close" fill="none" viewBox="0 0 18 17"> 418 <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"> 419 </symbol> 420</svg> 421 422 423<div id="easystore-section-header"> 424 <sticky-header class="header-wrapper header-wrapper--border-bottom"> 425 <header class="header header--top-center page-width header--has-menu" itemscope itemtype="http://schema.org/Organization"> 426 <header-drawer data-breakpoint="tablet"> 427 <details class="menu-drawer-container menu-opening"> 428 <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"> 429 <span> 430 431 432 433 <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> 434 435 436 437 438 439 440 <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> 441 442 443 444 </span> 445 </summary> 446 <div id="menu-drawer" class="menu-drawer motion-reduce" tabindex="-1"> 447 <div class="menu-drawer__inner-container"> 448 <div class="menu-drawer__navigation-container"> 449 <nav class="menu-drawer__navigation"> 450 <ul class="menu-drawer__menu list-menu" role="list"> 451 452 453 454 <li> 455 <a href="/" class="menu-drawer__menu-item list-menu__item link link--text focus-inset"> 456 ç²¾é¸åå Selected 457 </a> 458 </li> 459 460 461 462 463 464 <li> 465 <details> 466 <summary class="menu-drawer__menu-item list-menu__item link link--text focus-inset" role="button" aria-expanded="false" aria-controls="link-Bags"> 467 <a href="/collections/all" class="link--text list-menu__item menu-drawer__menu-item"> 468 åååé¡Categories 469 </a> 470 471 472 473 <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> 474 475 476 477 478 479 480 <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-caret " viewBox="0 0 10 6"> 481 <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> 482 </svg> 483 484 485 486 </summary> 487 <div class="menu-drawer__submenu motion-reduce" tabindex="-1"> 488 <div class="menu-drawer__inner-submenu"> 489 <button class="menu-drawer__close-button link link--text focus-inset" aria-expanded="true"> 490 491 492 493 <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> 494 495 496 497 åååé¡Categories 498 </button> 499 <ul class="menu-drawer__menu list-menu" role="list" tabindex="-1"> 500 501 502 503 <li> 504 <a href="/collections/æºæ §ç©¿æ´" class="menu-drawer__menu-item link link--text list-menu__item focus-inset"> 505 æºæ §ç©¿æ´ 506 </a> 507 </li> 508 509 510 511 512 <li> 513 <a href="/collections/è¡åè¾¦å ¬" class="menu-drawer__menu-item link link--text list-menu__item focus-inset"> 514 è¡åè¾¦å ¬ 515 </a> 516 </li> 517 518 519 520 521 <li> 522 <a href="/collections/-親åå ±å¸" class="menu-drawer__menu-item link link--text list-menu__item focus-inset"> 523 親åå ±å¸ 524 </a> 525 </li> 526 527 528 529 530 <li> 531 <a href="/collections/-çæ´»æç¨" class="menu-drawer__menu-item link link--text list-menu__item focus-inset"> 532 çæ´»æç¨ 533 </a> 534 </li> 535 536 537 538 </ul> 539 </div> 540 </div> 541 </details> 542 </li> 543 544 545 546 547 <li> 548 <a href="/blogs/ææ°æ¶æ¯news" class="menu-drawer__menu-item list-menu__item link link--text focus-inset"> 549 ææ°æ¶æ¯News 550 </a> 551 </li> 552 553 554 555 556 557 <li> 558 <details> 559 <summary class="menu-drawer__menu-item list-menu__item link link--text focus-inset" role="button" aria-expanded="false" aria-controls="link-Bags"> 560 <a href="/pages/å±ç¤ºæé»" class="link--text list-menu__item menu-drawer__menu-item"> 561 å±ç¤ºæé»Locations 562 </a> 563 564 565 566 <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> 567 568 569 570 571 572 573 <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-caret " viewBox="0 0 10 6"> 574 <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> 575 </svg> 576 577 578 579 </summary> 580 <div class="menu-drawer__submenu motion-reduce" tabindex="-1"> 581 <div class="menu-drawer__inner-submenu"> 582 <button class="menu-drawer__close-button link link--text focus-inset" aria-expanded="true"> 583 584 585 586 <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> 587 588 589 590 å±ç¤ºæé»Locations 591 </button> 592 <ul class="menu-drawer__menu list-menu" role="list" tabindex="-1"> 593 594 595 596 <li> 597 <a href="/pages/hereu-è¿·ä½ å£è¢ç¸æ©" class="menu-drawer__menu-item link link--text list-menu__item focus-inset"> 598 hereu è¿·ä½ å£è¢ç¸æ© 599 </a> 600 </li> 601 602 603 604 605 <li> 606 <a href="/pages/å ç«¥æé¶" class="menu-drawer__menu-item link link--text list-menu__item focus-inset"> 607 å ç«¥æé¶ 608 </a> 609 </li> 610 611 612 613 </ul> 614 </div> 615 </div> 616 </details> 617 </li> 618 619 620 621 622 623 <li> 624 <details> 625 <summary class="menu-drawer__menu-item list-menu__item link link--text focus-inset" role="button" aria-expanded="false" aria-controls="link-Bags"> 626 <a href="/pages/å®å¾æåservice" class="link--text list-menu__item menu-drawer__menu-item"> 627 å®å¾æåService 628 </a> 629 630 631 632 <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> 633 634 635 636 637 638 639 <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-caret " viewBox="0 0 10 6"> 640 <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> 641 </svg> 642 643 644 645 </summary> 646 <div class="menu-drawer__submenu motion-reduce" tabindex="-1"> 647 <div class="menu-drawer__inner-submenu"> 648 <button class="menu-drawer__close-button link link--text focus-inset" aria-expanded="true"> 649 650 651 652 <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> 653 654 655 656 å®å¾æåService 657 </button> 658 <ul class="menu-drawer__menu list-menu" role="list" tabindex="-1"> 659 660 661 662 <li> 663 <a href="/pages/購買é ç¥" class="menu-drawer__menu-item link link--text list-menu__item focus-inset"> 664 購買é ç¥ 665 </a> 666 </li> 667 668 669 670 671 <li> 672 <a href="/pages/éæè²¨ç³è«" class="menu-drawer__menu-item link link--text list-menu__item focus-inset"> 673 éæè²¨ç³è« 674 </a> 675 </li> 676 677 678 679 680 <li> 681 <a href="/pages/æä½æå¸" class="menu-drawer__menu-item link link--text list-menu__item focus-inset"> 682 æä½æå¸ 683 </a> 684 </li> 685 686 687 688 689 <li> 690 <a href="/pages/ä¿åºèç¶ä¿®æµç¨" class="menu-drawer__menu-item link link--text list-menu__item focus-inset"> 691 ä¿åºèç¶ä¿®æµç¨ 692 </a> 693 </li> 694 695 696 697 698 <li> 699 <a href="/pages/hereu-tag-2-0ï½2-in-1-smart-tag-tracker" class="menu-drawer__menu-item link link--text list-menu__item focus-inset"> 700 hereu Tag 2.0ï½2-in-1 Smart Tag Tracker 701 </a> 702 </li> 703 704 705
705 706 </ul> 707 </div> 708 </div> 709 </details> 710 </li> 711 712 713 714 715 716 <li> 717 <details> 718 <summary class="menu-drawer__menu-item list-menu__item link link--text focus-inset" role="button" aria-expanded="false" aria-controls="link-Bags"> 719 <a href="/pages/éæ¼æå-about" class="link--text list-menu__item menu-drawer__menu-item"> 720 éæ¼æå About 721 </a> 722 723 724 725 <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> 726 727 728 729 730 731 732 <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-caret " viewBox="0 0 10 6"> 733 <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> 734 </svg> 735 736 737 738 </summary> 739 <div class="menu-drawer__submenu motion-reduce" tabindex="-1"> 740 <div class="menu-drawer__inner-submenu"> 741 <button class="menu-drawer__close-button link link--text focus-inset" aria-expanded="true"> 742 743 744 745 <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> 746 747 748 749 éæ¼æå About 750 </button> 751 <ul class="menu-drawer__menu list-menu" role="list" tabindex="-1"> 752 753 754 755 <li> 756 <a href="/pages/åçæ äº" class="menu-drawer__menu-item link link--text list-menu__item focus-inset"> 757 åçæ äº 758 </a> 759 </li> 760 761 762 763 764 <li> 765 <a href="/pages/è¯çµ¡æå" class="menu-drawer__menu-item link link--text list-menu__item focus-inset"> 766 è¯çµ¡æå 767 </a> 768 </li> 769 770 771 772 </ul> 773 </div> 774 </div> 775 </details> 776 </li> 777 778 779 780 781 <li> 782 <a href="/pages/常è¦åé¡-faqï½airpurego-淨氣é¨è¡" class="menu-drawer__menu-item list-menu__item link link--text focus-inset"> 783 常è¦åé¡ FAQï½AirPureGo 淨氣é¨è¡ 784 </a> 785 </li> 786 787 788 </ul> 789 </nav> 790 791 <div class="menu-drawer__utility-links"> 792 793 794 795 796 797 798 799 800 <a href="/account/login" class="menu-drawer__account link link--text focus-inset h5"> 801 802 803 804 <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> 805 806 807 808 809 ç»å ¥ 810 </a> 811 812 <a href="/account/register" class="menu-drawer__account link link--text focus-inset h5"> 813 814 815 816 817 <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"> 818 <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> 819 </svg> 820 821 822 823 註å帳è 824 </a> 825 826 827 828 </div> 829 </div> 830 </div> 831 </div> 832 </details> 833 </header-drawer> 834 835 836 <a href="/" class="header__heading-link link link--text focus-inset" itemprop="url"> 837 <img src="https://cdn.store-assets.com/s/1424395/f/16069016.png" class="header__heading-logo" alt="AboutTime Tech" loading="lazy" itemprop="logo"> 838 </a> 839 840 841 842 <div class="header__search-input" tabindex="-1"> 843 <form action="/search" method="get" role="search" class="search search-modal__form"> 844 <div class="field"> 845 <input class="search__input field__input" 846 id="Search-In-Modal" 847 type="search" 848 name="q" 849 value="" 850 placeholder="æå°" 851 autocomplete="off" 852 > 853 <label class="field__label" for="Search-In-Modal">æå°</label> 854 <div class="dropdown" id="searchDropdown"></div> 855 <input type="hidden" name="search_history" class="hidden_search_history"> 856 <input type="hidden" name="options[prefix]" value="last"> 857 <button class="search__button field__button" aria-label="æå°"> 858 <svg class="icon icon-search" aria-hidden="true" focusable="false" role="presentation"> 859 <use href="#icon-search"> 860 </svg> 861 </button> 862 </div> 863 </form> 864 </div> 865 866 867 <nav class="header__inline-menu"> 868 <ul class="list-menu list-menu--inline" role="list"> 869 870 871 872 <li> 873 <a href="/" class="header__menu-item header__menu-item list-menu__item link link--text focus-inset"> 874 ç²¾é¸åå Selected 875 </a> 876 </li> 877 878 879 880 881 882 <li> 883 <details-disclosure> 884 <details> 885 <summary class="header__menu-item list-menu__item link focus-inset"> 886 <a href="/collections/all" >åååé¡Categories</a> 887 888 889 890 <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-caret " viewBox="0 0 10 6"> 891 <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> 892 </svg> 893 894 895 896 </summary> 897 <ul class="header__submenu list-menu list-menu--disclosure caption-large motion-reduce" role="list" tabindex="-1"> 898 899 900 901 902 903 <li> 904 <a href="/collections/æºæ §ç©¿æ´" class="header__menu-item list-menu__item link link--text focus-inset caption-large"> 905 æºæ §ç©¿æ´ 906 </a> 907 </li> 908 909 910 911 912 913 <li> 914 <a href="/collections/è¡åè¾¦å ¬" class="header__menu-item list-menu__item link link--text focus-inset caption-large"> 915 è¡åè¾¦å ¬ 916 </a> 917 </li> 918 919 920 921 922 923 <li> 924 <a href="/collections/-親åå ±å¸" class="header__menu-item list-menu__item link link--text focus-inset caption-large"> 925 親åå ±å¸ 926 </a> 927 </li> 928 929 930 931 932 933 <li> 934 <a href="/collections/-çæ´»æç¨" class="header__menu-item list-menu__item link link--text focus-inset caption-large"> 935 çæ´»æç¨ 936 </a> 937 </li> 938 939 940 </ul> 941 </details> 942 </details-disclosure> 943 </li> 944 945 946 947 948 <li> 949 <a href="/blogs/ææ°æ¶æ¯news" class="header__menu-item header__menu-item list-menu__item link link--text focus-inset"> 950 ææ°æ¶æ¯News 951 </a> 952 </li> 953 954 955 956 957 958 <li> 959 <details-disclosure> 960 <details> 961 <summary class="header__menu-item list-menu__item link focus-inset"> 962 <a href="/pages/å±ç¤ºæé»" >å±ç¤ºæé»Locations</a> 963 964 965 966 <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-caret " viewBox="0 0 10 6"> 967 <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> 968 </svg> 969 970 971 972 </summary> 973 <ul class="header__submenu list-menu list-menu--disclosure caption-large motion-reduce" role="list" tabindex="-1"> 974 975 976 977 978 979 <li> 980 <a href="/pages/hereu-è¿·ä½ å£è¢ç¸æ©" class="header__menu-item list-menu__item link link--text focus-inset caption-large"> 981 hereu è¿·ä½ å£è¢ç¸æ© 982 </a> 983 </li> 984 985 986 987 988 989 <li> 990 <a href="/pages/å ç«¥æé¶" class="header__menu-item list-menu__item link link--text focus-inset caption-large"> 991 å ç«¥æé¶ 992 </a> 993 </li> 994 995 996 </ul> 997 </details> 998 </details-disclosure> 999 </li> 1000 1001 1002 1003 1004 1005 <li> 1006 <details-disclosure> 1007 <details> 1008 <summary class="header__menu-item list-menu__item link focus-inset"> 1009 <a href="/pages/å®å¾æåservice" >å®å¾æåService</a> 1010 1011 1012 1013 <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-caret " viewBox="0 0 10 6"> 1014 <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> 1015 </svg> 1016 1017 1018 1019 </summary> 1020 <ul class="header__submenu list-menu list-menu--disclosure caption-large motion-reduce" role="list" tabindex="-1"> 1021 1022 1023 1024 1025 1026 <li> 1027 <a href="/pages/購買é ç¥" class="header__menu-item list-menu__item link link--text focus-inset caption-large"> 1028 購買é ç¥ 1029 </a> 1030 </li> 1031 1032 1033 1034 1035 1036 <li> 1037 <a href="/pages/éæè²¨ç³è«" class="header__menu-item list-menu__item link link--text focus-inset caption-large"> 1038 éæè²¨ç³è« 1039 </a> 1040 </li> 1041 1042 1043 1044 1045 1046 <li> 1047 <a href="/pages/æä½æå¸" class="header__menu-item list-menu__item link link--text focus-inset caption-large"> 1048 æä½æå¸ 1049 </a> 1050 </li> 1051 1052 1053 1054 1055 1056 <li> 1057 <a href="/pages/ä¿åºèç¶ä¿®æµç¨" class="header__menu-item list-menu__item link link--text focus-inset caption-large"> 1058 ä¿åºèç¶ä¿®æµç¨ 1059 </a> 1060 </li> 1061 1062 1063 1064 1065 1066 <li> 1067 <a href="/pages/hereu-tag-2-0ï½2-in-1-smart-tag-tracker" class="header__menu-item list-menu__item link link--text focus-inset caption-large"> 1068 hereu Tag 2.0ï½2-in-1 Smart Tag Tracker 1069 </a> 1070 </li> 1071 1072 1073 </ul> 1074 </details> 1075 </details-disclosure> 1076 </li> 1077 1078 1079 1080 1081 1082 <li> 1083 <details-disclosure> 1084 <details> 1085
1085 <summary class="header__menu-item list-menu__item link focus-inset"> 1086 <a href="/pages/éæ¼æå-about" >éæ¼æå About</a> 1087 1088 1089 1090 <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-caret " viewBox="0 0 10 6"> 1091 <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> 1092 </svg> 1093 1094 1095 1096 </summary> 1097 <ul class="header__submenu list-menu list-menu--disclosure caption-large motion-reduce" role="list" tabindex="-1"> 1098 1099 1100 1101 1102 1103 <li> 1104 <a href="/pages/åçæ äº" class="header__menu-item list-menu__item link link--text focus-inset caption-large"> 1105 åçæ äº 1106 </a> 1107 </li> 1108 1109 1110 1111 1112 1113 <li> 1114 <a href="/pages/è¯çµ¡æå" class="header__menu-item list-menu__item link link--text focus-inset caption-large"> 1115 è¯çµ¡æå 1116 </a> 1117 </li> 1118 1119 1120 </ul> 1121 </details> 1122 </details-disclosure> 1123 </li> 1124 1125 1126 1127 1128 <li> 1129 <a href="/pages/常è¦åé¡-faqï½airpurego-淨氣é¨è¡" class="header__menu-item header__menu-item list-menu__item link link--text focus-inset"> 1130 常è¦åé¡ FAQï½AirPureGo 淨氣é¨è¡ 1131 </a> 1132 </li> 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 </ul> 1146 </nav> 1147 <div class="header__icons"> 1148 1149 1150 1151 <div class="header__icon header__icon--account link link--text focus-inset small-hide medium-hide" style="position: relative;"> 1152 <a href="/account/login" class="header__icon link link--text focus-inset p-2"> 1153 1154 1155 1156 <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> 1157 1158 1159 1160 <span id="my-account" class="header__link-label">ç»å ¥</span> 1161 </a> 1162 1163 <!-- Referral Notification Popup for Desktop --> 1164 <div id="referralNotification" class="referral-notification" style="display: none;"> 1165 <button class="close-btn" onclick="dismissReferralNotification()">×</button> 1166 <div style="text-align: center; margin-bottom: 16px;"> 1167 <div style="width: 100px; height: 100px; margin: 0 auto;"> 1168 <img src="https://resources.easystore.co/storefront/icons/channels/vector_referral_program.svg"> 1169 </div> 1170 </div> 1171 <p id="referralSignupMessage" style="text-align: center; font-size: 14px; color: #666; margin: 0 0 20px 0;"> 1172 æ¨ç好å鿍 åé¥éï¼ç«å³è¨»åé åã 1173 </p> 1174 <div style="text-align: center;"> 1175 <button class="btn" onclick="goToSignupPage()" style="width: 100%;"> 1176 註å 1177 </button> 1178 </div> 1179 </div> 1180 </div> 1181 1182 1183 1184 <a href="/cart" class="header__icon link link--text focus-inset" id="cart-icon-bubble">
1185 <span class="header__icon--cart"> 1186 1187 1188 1189 <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> 1190 1191 1192 1193 <div class="cart-count-bubble hidden"> 1194 <span aria-hidden="true" class="js-content-cart-count">0</span> 1195 </div> 1196 </span> 1197 <span class="header__link-label medium-hide small-hide"> 1198 è³¼ç©è» 1199 </span> 1200 </a> 1201 1202 1203 1204 <!-- Referral Notification Modal for Mobile --> 1205 <details-modal class="referral-modal" id="referralMobileModal"> 1206 <details> 1207 <summary class="referral-modal__toggle" aria-haspopup="dialog" aria-label="Open referral modal" style="display: none;"> 1208 </summary> 1209 <div class="modal-overlay referral-modal-overlay"></div> 1210 <div class="referral-modal__dialog" role="dialog" aria-modal="true" aria-label="Referral notification"> 1211 <div class="referral-modal__content"> 1212 <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;"> 1213 × 1214 </button> 1215 1216 <div style="margin-bottom: 24px;"> 1217 <div style="width: 120px; height: 120px; margin: 0 auto 20px;"> 1218 <img src="https://resources.easystore.co/storefront/icons/channels/vector_referral_program.svg" style="width: 100%; height: 100%;"> 1219 </div> 1220 </div> 1221 1222 <p id="referralSignupMessageMobile" style="font-size: 16px; color: #333; margin: 0 0 30px 0; line-height: 1.5;"> 1223 æ¨ç好å鿍 åé¥éï¼ç«å³è¨»åé åã 1224 </p> 1225 1226 <button type="button" class="btn" onclick="goToSignupPageFromMobile()" style="width: 100%;"> 1227 註å 1228 </button> 1229 </div> 1230 </div> 1231 </details> 1232 </details-modal> 1233 1234 1235 1236 </div> 1237 </header> 1238 </sticky-header> 1239 1240<cart-notification> 1241 <div class="cart-notification-wrapper page-width color-background-1"> 1242 <div id="cart-notification" class="cart-notification focus-inset" aria-modal="true" aria-label="å·²å å ¥è³¼ç©è»" role="dialog" tabindex="-1"> 1243 <div class="cart-notification__header"> 1244 <h2 class="cart-notification__heading caption-large"> 1245 1246 1247 <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"> 1248 <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> 1249 </svg> 1250 1251 1252 å·²å å ¥è³¼ç©è»</h2> 1253 <button type="button" class="cart-notification__close modal__close-button link link--text focus-inset" aria-label="accessibility.close"> 1254 1255 1256 1257 <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> 1258 1259 1260 1261 </button> 1262 </div> 1263 <div id="cart-notification-product" class="cart-notification-product"></div> 1264 <div class="cart-notification__links"> 1265 <a href="/cart" id="cart-notification-button" class="button button--secondary button--full-width">æ¥çè³¼ç©è» (<span class="js-content-cart-count">0</span>)</a> 1266 <form action="/cart" method="post" id="cart-notification-form"> 1267 <input type="hidden" name="_token" value="PPTke7FKkhMhDc6qRhXlP91zYAE29pCxuQ868QDx"> 1268 <input type="hidden" name="current_currency" value=""> 1269 <button class="button button--primary button--full-width" name="checkout" value="true">çµå¸³</button> 1270 </form> 1271 <a href="/collections/all" class="link button-label">ç¹¼çºè³¼ç©</a> 1272 </div> 1273 </div> 1274 </div> 1275</cart-notification> 1276<style> 1277 .cart-notification { 1278 display: none; 1279 } 1280</style>
1281<script> 1282document.getElementById('cart-notification-form').addEventListener('submit',(event)=>{ 1283 if(event.submitter) event.submitter.classList.add('loading'); 1284}) 1285 1286</script>
1286 1287 1288</div> 1289 1290
1291<script> 1292 1293 class StickyHeader extends HTMLElement { 1294 constructor() { 1295 super(); 1296 } 1297 1298 connectedCallback() { 1299 this.header = document.getElementById('easystore-section-header'); 1300 this.headerBounds = {}; 1301 this.currentScrollTop = 0; 1302 this.preventReveal = false; 1303 1304 this.onScrollHandler = this.onScroll.bind(this); 1305 this.hideHeaderOnScrollUp = () => this.preventReveal = true; 1306 1307 this.addEventListener('preventHeaderReveal', this.hideHeaderOnScrollUp); 1308 window.addEventListener('scroll', this.onScrollHandler, false); 1309 1310 this.createObserver(); 1311 } 1312 1313 disconnectedCallback() { 1314 this.removeEventListener('preventHeaderReveal', this.hideHeaderOnScrollUp); 1315 window.removeEventListener('scroll', this.onScrollHandler); 1316 } 1317 1318 createObserver() { 1319 let observer = new IntersectionObserver((entries, observer) => { 1320 this.headerBounds = entries[0].intersectionRect; 1321 observer.disconnect(); 1322 }); 1323 1324 observer.observe(this.header); 1325 } 1326 1327 onScroll() { 1328 const scrollTop = window.pageYOffset || document.documentElement.scrollTop; 1329 1330 if (scrollTop > this.currentScrollTop && scrollTop > this.headerBounds.bottom) { 1331 requestAnimationFrame(this.hide.bind(this)); 1332 } else if (scrollTop < this.currentScrollTop && scrollTop > this.headerBounds.bottom) { 1333 if (!this.preventReveal) { 1334 requestAnimationFrame(this.reveal.bind(this)); 1335 } else { 1336 window.clearTimeout(this.isScrolling); 1337 1338 this.isScrolling = setTimeout(() => { 1339 this.preventReveal = false; 1340 }, 66); 1341 1342 requestAnimationFrame(this.hide.bind(this)); 1343 } 1344 } else if (scrollTop <= this.headerBounds.top) { 1345 requestAnimationFrame(this.reset.bind(this)); 1346 } 1347 1348 1349 this.currentScrollTop = scrollTop; 1350 } 1351 1352 hide() { 1353 this.header.classList.add('easystore-section-header-hidden', 'easystore-section-header-sticky'); 1354 this.closeMenuDisclosure(); 1355 // this.closeSearchModal(); 1356 } 1357 1358 reveal() { 1359 this.header.classList.add('easystore-section-header-sticky', 'animate'); 1360 this.header.classList.remove('easystore-section-header-hidden'); 1361 } 1362 1363 reset() { 1364 this.header.classList.remove('easystore-section-header-hidden', 'easystore-section-header-sticky', 'animate'); 1365 } 1366 1367 closeMenuDisclosure() { 1368 this.disclosures = this.disclosures || this.header.querySelectorAll('details-disclosure'); 1369 this.disclosures.forEach(disclosure => disclosure.close()); 1370 } 1371 1372 // closeSearchModal() { 1373 // this.searchModal = this.searchModal || this.header.querySelector('details-modal'); 1374 // this.searchModal.close(false); 1375 // } 1376 } 1377 1378 customElements.define('sticky-header', StickyHeader); 1379 1380 1381 class DetailsDisclosure extends HTMLElement{ 1382 constructor() { 1383 super(); 1384 this.mainDetailsToggle = this.querySelector('details'); 1385 // this.mainDetailsToggle.addEventListener('focusout', this.onFocusOut.bind(this)); 1386 this.mainDetailsToggle.addEventListener('mouseover', this.open.bind(this)); 1387 this.mainDetailsToggle.addEventListener('mouseleave', this.close.bind(this)); 1388 } 1389 1390 onFocusOut() { 1391 setTimeout(() => { 1392 if (!this.contains(document.activeElement)) this.close(); 1393 }) 1394 } 1395 1396 open() { 1397 this.mainDetailsToggle.setAttribute('open',1) 1398 } 1399 1400 close() { 1401 this.mainDetailsToggle.removeAttribute('open') 1402 } 1403 } 1404 1405 customElements.define('details-disclosure', DetailsDisclosure); 1406 1407 function clearAll() { 1408 localStorage.removeItem('searchHistory'); 1409 1410 var customer = ""; 1411 if(customer) { 1412 // Your logic to clear all data or call an endpoint 1413 fetch('/account/search_histories', { 1414 method: 'DELETE', 1415 headers: { 1416 "Content-Type": "application/json", 1417 "X-Requested-With": "XMLHttpRequest" 1418 }, 1419 body: JSON.stringify({ 1420 _token: "PPTke7FKkhMhDc6qRhXlP91zYAE29pCxuQ868QDx" 1421 }), 1422 }) 1423 .then(response => response.json()) 1424 } 1425 } 1426 // End - delete search history from local storage 1427 1428 // search history dropdown 1429 var searchInputs = document.querySelectorAll('.search__input'); 1430 1431 if(searchInputs.length > 0) { 1432
1433 searchInputs.forEach((searchInput)=> { 1434 1435 searchInput.addEventListener('focus', function() { 1436 var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown'); 1437 searchDropdown.innerHTML = ''; // Clear existing items 1438 1439 // retrieve data from local storage 1440 var searchHistoryData = JSON.parse(localStorage.getItem('searchHistory')) || []; 1441 1442 // Convert JSON to string 1443 var search_history_json = JSON.stringify(searchHistoryData); 1444 1445 // Set the value of the hidden input 1446 searchInput.closest('form').querySelector(".hidden_search_history").value = search_history_json; 1447 1448 // create dropdown items 1449 var clearAllItem = document.createElement('div'); 1450 clearAllItem.className = 'dropdown-item clear-all'; 1451 clearAllItem.textContent = 'Clear'; 1452 clearAllItem.addEventListener('click', function() { 1453 clearAll(); 1454 searchDropdown.style.display = 'none'; 1455 searchInput.classList.remove('is-focus'); 1456 }); 1457 searchDropdown.appendChild(clearAllItem); 1458 1459 // create dropdown items 1460 searchHistoryData.forEach(function(item) { 1461 var dropdownItem = document.createElement('div'); 1462 dropdownItem.className = 'dropdown-item'; 1463 dropdownItem.textContent = item.term; 1464 dropdownItem.addEventListener('click', function() { 1465 searchInput.value = item.term; 1466 searchInput.closest('form').submit(); 1467 searchDropdown.style.display = 'none'; 1468 }); 1469 searchDropdown.appendChild(dropdownItem); 1470 }); 1471 1472 if(searchHistoryData.length > 0){ 1473 // display the dropdown 1474 searchInput.classList.add('is-focus'); 1475 document.body.classList.add('search-input-focus'); 1476 searchDropdown.style.display = 'block'; 1477 } 1478 }); 1479 1480 searchInput.addEventListener("focusout", (event) => { 1481 var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown'); 1482 searchInput.classList.remove('is-focus'); 1483 searchDropdown.classList.add('transparent'); 1484 setTimeout(()=>{ 1485 searchDropdown.style.display = 'none'; 1486 searchDropdown.classList.remove('transparent'); 1487 document.body.classList.remove('search-input-focus'); 1488 }, 400); 1489 }); 1490 }) 1491 } 1492 // End - search history dropdown 1493 1494 // referral notification popup 1495 const referralMessageTemplate = 'æ¨ç好å鿍 __CURRENCY_CODE__ __CREDIT_AMOUNT__ åé¥éï¼ç«å³è¨»åé åã'; 1496 const shopCurrency = 'NT$'; 1497 1498 function getCookie(name) { 1499 const value = `; ${document.cookie}`; 1500 const parts = value.split(`; ${name}=`); 1501 if (parts.length === 2) return parts.pop().split(';').shift(); 1502 return null; 1503 } 1504 1505 function removeCookie(name) { 1506 document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`; 1507 } 1508 1509 function showReferralNotification() { 1510 const referralCode = getCookie('customer_referral_code'); 1511 1512 1513 const customerReferralCode = null; 1514 1515 1516 const activeReferralCode = referralCode || customerReferralCode; 1517 const referralData = JSON.parse(localStorage.getItem('referral_notification_data')) || {}; 1518 1519 if (referralData.timestamp && referralData.expirationDays) { 1520 const expirationTime = referralData.timestamp + (referralData.expirationDays * 24 * 60 * 60 * 1000); 1521 if (Date.now() > expirationTime) { 1522 localStorage.removeItem('referral_notification_data'); 1523 return; 1524 } 1525 } 1526 1527 if (referralData.dismissed) return; 1528 1529 if (activeReferralCode) { 1530 if (referralData.creditAmount) { 1531 displayReferralNotification(referralData.creditAmount); 1532 } else { 1533 fetchReferralCampaignData(activeReferralCode); 1534 } 1535 } 1536 } 1537 1538 function fetchReferralCampaignData(referralCode) { 1539 fetch(`/customer/referral_program/campaigns/${referralCode}`) 1540 .then(response => { 1541 if (!response.ok) { 1542 throw new Error('Network response was not ok'); 1543 } 1544 return response.json(); 1545 }) 1546 .then(data => { 1547 let refereeCreditAmount = null; 1548 if (data.data.campaign && data.data.campaign.referral_rules) { 1549 const refereeRule = data.data.campaign.referral_rules.find(rule => 1550 rule.target_type === 'referee' && 1551 rule.event_name === 'customer/create' && 1552 rule.entitlement && 1553 rule.entitlement.type === 'credit' 1554 ); 1555 1556 if (refereeRule) { 1557 refereeCreditAmount = refereeRule.entitlement.amount; 1558 } 1559 } 1560 1561 const referralData = JSON.parse(localStorage.getItem('referral_notification_data')) || {}; 1562 referralData.creditAmount = refereeCreditAmount; 1563 referralData.dismissed = referralData.dismissed || false; 1564 referralData.timestamp = Date.now(); 1565 referralData.expirationDays = 3; 1566 localStorage.setItem('referral_notification_data', JSON.stringify(referralData)); 1567 1568 displayReferralNotification(refereeCreditAmount); 1569 }) 1570 .catch(error => { 1571 removeCookie('customer_referral_code'); 1572 }); 1573 } 1574 1575 function displayReferralNotification(creditAmount = null) { 1576 const isMobile = innerWidth <= 749; 1577 1578 if (isMobile) { 1579 const mobileModal = document.querySelector('#referralMobileModal details'); 1580 const mobileMessageElement = document.getElementById('referralSignupMessageMobile'); 1581 1582 if (mobileModal && mobileMessageElement) { 1583 if (creditAmount) {
1584 const finalMessage = referralMessageTemplate 1585 .replace('__CREDIT_AMOUNT__', creditAmount) 1586 .replace('__CURRENCY_CODE__', shopCurrency); 1587 1588 mobileMessageElement.textContent = finalMessage; 1589 } 1590 1591 mobileModal.setAttribute('open', ''); 1592 } 1593 } else { 1594 const notification = document.getElementById('referralNotification'); 1595 1596 if (notification) { 1597 if (creditAmount) { 1598 const messageElement = document.getElementById('referralSignupMessage'); 1599 if (messageElement) { 1600 const finalMessage = referralMessageTemplate 1601 .replace('__CREDIT_AMOUNT__', creditAmount) 1602 .replace('__CURRENCY_CODE__', shopCurrency); 1603 1604 messageElement.textContent = finalMessage; 1605 } 1606 } 1607 1608 notification.style.display = 'block'; 1609 } 1610 } 1611 } 1612 1613 showReferralNotification(); 1614 1615 addEventListener('beforeunload', function() { 1616 const referralData = JSON.parse(localStorage.getItem('referral_notification_data')) || {}; 1617 1618 if (referralData.creditAmount !== undefined) { 1619 referralData.creditAmount = null; 1620 localStorage.setItem('referral_notification_data', JSON.stringify(referralData)); 1621 } 1622 }); 1623 1624 function closeReferralNotification() { 1625 const notification = document.getElementById('referralNotification'); 1626 if (notification) { 1627 notification.style.display = 'none'; 1628 } 1629 } 1630 1631 function dismissReferralNotification() { 1632 const referralData = JSON.parse(localStorage.getItem('referral_notification_data')) || {}; 1633 1634 referralData.dismissed = true; 1635 referralData.timestamp = referralData.timestamp || Date.now(); 1636 referralData.expirationDays = referralData.expirationDays || 3; 1637 1638 localStorage.setItem('referral_notification_data', JSON.stringify(referralData)); 1639 1640 closeReferralNotification(); 1641 } 1642 1643 function goToSignupPage() { 1644 location.href = '/account/register'; 1645 dismissReferralNotification(); 1646 } 1647 1648 function closeMobileReferralModal() { 1649 const mobileModal = document.querySelector('#referralMobileModal details'); 1650 if (mobileModal) { 1651 mobileModal.removeAttribute('open'); 1652 } 1653 1654 const referralData = JSON.parse(localStorage.getItem('referral_notification_data')) || {}; 1655 referralData.dismissed = true; 1656 referralData.timestamp = referralData.timestamp || Date.now(); 1657 referralData.expirationDays = referralData.expirationDays || 3; 1658 localStorage.setItem('referral_notification_data', JSON.stringify(referralData)); 1659 } 1660 1661 function goToSignupPageFromMobile() { 1662 location.href = '/account/register'; 1663 closeMobileReferralModal(); 1664 } 1665 // End - referral notification popup 1666</script>
1666 1667 1668 1669 1670 <main id="MainContent" class="content-for-layout focus-none" role="main" tabindex="-1">
vendor: 83 bytes, lines 1670-1673
1670 1671 1672 1673<script src="https://www.recaptcha.net/recaptcha/enterprise.js?render=
16736LdMNdIqAAAAALegJp7y4weVcCIlnwmIN8TWseEF
vendor: 12 bytes, line 1673
1673"></script>
1674<link rel="preload" href="https://store-themes.easystore.co/1424395/themes/308896/assets/customer.css?t=1787094029" as="style" onload="this.onload=null;this.rel='stylesheet'"> 1675<style> 1676 main.main-content .field > label{ 1677 display: none; 1678 } 1679 .h3{ 1680 font-size: 18px; 1681 } 1682 .button--full-width{ 1683 width: 100%; 1684 } 1685 .tab-wrapper{ 1686 display: inline-flex; 1687 justify-content: center; 1688 align-items: center; 1689 margin: 10px auto 20px; 1690 background-color: #eaeaea; 1691 border-radius: 200px; 1692 padding: 5px; 1693 gap: 10px; 1694 } 1695 .tab-wrapper .tab-label { 1696 display: inline-block; 1697 min-width: 130px; 1698 padding: 8px 15px; 1699 border-radius: 100px; 1700 cursor: pointer; 1701 font-size: 17px; 1702 line-height: 1.1; 1703 user-select: none; 1704 margin: 0; 1705 color: #000; 1706 } 1707 #register-tos a { 1708 display: inline; 1709 } 1710 @media screen and (max-width: 400px){ 1711 .tab-wrapper .tab-label { 1712 min-width: 110px; 1713 } 1714 } 1715 .tab-wrapper input[type='radio']:checked + .tab-label { 1716 background-color: #fff; 1717 box-shadow: 2px 2px 25px -10px #333; 1718 } 1719 1720 @media screen and (min-width: 500px){ 1721 .large--five-twelfths{ 1722 min-width: 420px; 1723 } 1724 } 1725</style> 1726 1727 1728 1729 1730<div class="customer login section-width-control small-width large--five-twelfths text-center wrapper"> 1731 <div class="card"> 1732 <h1 id="login" tabindex="-1" class="mb-0"> 1733 æ¡è¿ 1734 </h1> 1735 <p class="h3 mt-0"> 1736 1737 註åæç»å ¥ä»¥ç¹¼çº 1738 1739 </p> 1740 <div> 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 <div class="tab-wrapper"> 1759 <div> 1760 <input type="radio" name="type" id="tab-register" class="hide hidden" checked> 1761 <label for="tab-register" class="tab-label"> 1762 註å帳è 1763 </label> 1764 </div> 1765 <div> 1766 <input type="radio" name="type" id="tab-login" class="hide hidden"> 1767 <label for="tab-login" class="tab-label"> 1768 ç»å ¥ 1769 </label> 1770 </div> 1771 </div> 1772 1773 1774 <form id="form-login" action="/account/auth" method="post" class="mt-2"> 1775 <input type="hidden" name="_token" value="PPTke7FKkhMhDc6qRhXlP91zYAE29pCxuQ868QDx"> 1776 <input type="hidden" name="location_id" value=""> 1777 <input type="hidden" name="staff_id" value=""> 1778 <input type="hidden" id="recaptchaResponse" name="g-recaptcha-response"> 1779 1780 1781 <div id="error-content"></div> 1782 1783 <div class="field"> 1784 <input 1785 type="text" 1786 name="customer[email_or_phone]" 1787 id="CustomerDetail" 1788 autocorrect="off" 1789 autocapitalize="off" 1790 placeholder="é»åéµä»¶å°å" 1791 required 1792 > 1793 <label for="CustomerDetail"> 1794 é»åéµä»¶å°å 1795 </label> 1796 </div> 1797 1798 <button 1799 type="submit" 1800 form="form-login" 1801 class="btn button--full-width g-recaptcha"> 1802 ç¹¼çº 1803 </button> 1804 1805 <div class="button-snippet"> 1806 1807 <style> 1808 #line-login-btn.btn{ 1809 background-color: #fff; 1810 color: #000; 1811 padding: 0; 1812 overflow: hidden; 1813 display: flex; 1814 justify-content: center; 1815 align-items: center; 1816 width: 100%; 1817 margin: 15px auto; 1818 font-size: 14px; 1819 border: 1px solid currentColor; 1820 box-shadow: none; 1821 } 1822 #line-login-btn.btn:hover{ 1823 background-color: #fff; 1824 } 1825 #line-login-btn.btn svg{ 1826 width: 45px; 1827 vertical-align: middle; 1828 padding: 5px; 1829 } 1830 #line-login-btn.btn .line-login-text{ 1831 padding: 13px 75px 13px 30px; 1832 display: inline-block; 1833 width: calc(100% - 52px); 1834 } 1835 @media screen and (max-width: 500px) { 1836 #line-login-btn.btn .line-login-text{ 1837 padding: 13px 25px 13px 8px; 1838 font-size: 13px; 1839 } 1840 } 1841 </style> 1842 <button type="button" onclick="location.href='/account/oauth/line'" id="line-login-btn" class="btn" style="color: #000; font-weight: normal; margin-bottom: 10px;"> 1843 <svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"> 1844 <path d="M27.91,12a8.73,8.73,0,0,0-.53-2,9.84,9.84,0,0,0-2.2-3.31A12.91,12.91,0,0,0,20.85,4a14.67,14.67,0,0,0-4-1A17.13,17.13,0,0,0,15,2.83c-.27,0-.55,0-.82,0l-.82.06a15.07,15.07,0,0,0-1.62.24,14.77,14.77,0,0,0-3,1A12.64,12.64,0,0,0,4.81,6.78a9.82,9.82,0,0,0-2.29,3.55A8.38,8.38,0,0,0,2,13a9.45,9.45,0,0,0,.1,1.5A8.52,8.52,0,0,0,2.88,17a10.52,10.52,0,0,0,3.23,3.84A13.68,13.68,0,0,0,10.5,23a14.8,14.8,0,0,0,2.36.5,2.31,2.31,0,0,1,.69.16,1,1,0,0,1,.58.72,2,2,0,0,1,0,.74c-.05.34-.12.67-.17,1a2.55,2.55,0,0,0,0,.55c0,.38.22.53.59.45a4.21,4.21,0,0,0,.63-.2A11.83,11.83,0,0,0,16.92,26a47.13,47.13,0,0,0,5.68-4c.67-.55,1.31-1.14,2-1.71a10.26,10.26,0,0,0,1.64-1.78,9.31,9.31,0,0,0,1.2-2.16,8.3,8.3,0,0,0,.59-3A9.5,9.5,0,0,0,27.91,12ZM10.26,16.52l-.18,0H7.49a.67.67,0,0,1-.67-.67v-5a.67.67,0,0,1,.66-.66.68.68,0,0,1,.71.7v4.26H10a.66.66,0,0,1,.6.31A.69.69,0,0,1,10.26,16.52Zm2.43-.58a.63.63,0,0,1-.63.6.65.65,0,0,1-.69-.46.89.89,0,0,1,0-.28V11a1.
18441,1.1,0,0,1,0-.26.68.68,0,0,1,.61-.48.64.64,0,0,1,.61.29.92.92,0,0,1,.11.29.72.72,0,0,1,0,.21v4.77A1,1,0,0,1,12.69,15.94Zm6.14,0a.64.64,0,0,1-.5.63.7.7,0,0,1-.76-.27C16.79,15.17,16,14.1,15.22,13c0,0-.06-.11-.16-.14v3a.6.6,0,0,1-.1.39.64.64,0,0,1-.52.3.79.79,0,0,1-.45-.11.66.66,0,0,1-.29-.52v-5a.67.67,0,0,1,.1-.39.7.7,0,0,1,1.14,0c.46.64.93,1.26,1.4,1.89l1,1.33.09.11c.06-.05,0-.1,0-.15V10.89a.65.65,0,0,1,.5-.65.67.67,0,0,1,.87.64v3.67C18.83,15,18.82,15.45,18.83,15.89Zm4.39.62a.93.93,0,0,1-.29,0H20.47a.76.76,0,0,1-.41-.1.62.62,0,0,1-.31-.51,1.09,1.09,0,0,1,0-.18c0-1.59,0-3.19,0-4.78a.88.88,0,0,1,0-.28.66.66,0,0,1,.63-.49H23a.63.63,0,0,1,.6.43.68.68,0,0,1-.16.76.58.58,0,0,1-.39.17H21.14a5.87,5.87,0,0,0,0,1.11h.17c.56,0,1.13,0,1.69,0a.64.64,0,0,1,.65.52.66.66,0,0,1-.66.84H21.14a6.56,6.56,0,0,0,0,1.09l.19,0h1.61a1,1,0,0,1,.24,0,.67.67,0,0,1,.5.63A.63.63,0,0,1,23.22,16.51Z" fill="#02C755"/> 1845 </svg> 1846 <span class="line-login-text">LINE ç»å ¥</span> 1847 </button> 1848 <!-- <p style="font-size: 12px; color: grey;">æåä½¿ç¨æ¨çLINEé»åéµä»¶åµå»ºå®¢æ¶å¸³æ¶</p> --> 1849 1850 </div> 1851 1852 1853 1854 <div id="register-tos"> 1855 䏿¦é»æè¨»åï¼å³è¡¨ç¤ºä½ åæAboutTime Techç <a target="_blank" href="/pages/æåæ¢æ¬¾">æåæ¢æ¬¾ </a>, <a target="_blank" href="/legal/privacy-policy">é±ç§æ¿ç</a>, <a target="_blank" href="/legal/refund-policy">鿬¾æ¿ç</a> å <a target="_blank" href="/legal/ç¨æ¶åè°">ç¨æ¶åè°</a>ã 1856 </div> 1857 1858 </form> 1859 </div> 1860 </div> 1861 1862</div> 1863 1864 1865
1866<script> 1867 const register_tab = document.querySelector('#tab-register'); 1868 const login_tab = document.querySelector('#tab-login'); 1869 const register_tos = document.querySelector('#register-tos'); 1870 const isRegistrationEnabled = "1"; 1871 1872 if (register_tab) { 1873 register_tab.addEventListener('click', function() { 1874 if (register_tos) { 1875 register_tos.style.display = 'block'; 1876 } 1877 }); 1878 } 1879 if (login_tab) { 1880 login_tab.addEventListener('click', function() { 1881 if (register_tos) { 1882 register_tos.style.display = 'none'; 1883 } 1884 }); 1885 } 1886 1887 const methodSwitchBtn = document.getElementById('phone-login-btn'); 1888 if (methodSwitchBtn) { 1889 methodSwitchBtn.onclick = function () { 1890 var type = (register_tab && register_tab.checked) ? 'register' : 'login'; 1891 window.location.href = '/account/login?method=phone&type=' + type; 1892 }; 1893 } 1894 1895 let lastPathSegment = window.location.pathname.split('/').filter(segment => segment.length > 0).pop(); 1896 1897 // Redirect to login if trying to access register when self registration is disabled 1898 if (!isRegistrationEnabled) { 1899 if (lastPathSegment === 'register') { 1900 window.location.href = '/account/login'; 1901 } else if (lastPathSegment === 'login' || lastPathSegment === 'auth') { 1902 if (register_tos) { 1903 register_tos.style.display = 'none'; 1904 } 1905 } 1906 } else { 1907 // Only proceed with tab logic if not redirecting 1908 if(lastPathSegment === 'login') { 1909 if (login_tab) { 1910 login_tab.checked = true; 1911 } 1912 if (register_tos) { 1913 register_tos.style.display = 'none'; 1914 } 1915 } else { 1916 if (register_tos) { 1917 register_tos.style.display = 'block'; 1918 } 1919 } 1920 } 1921 1922 const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; 1923 const phonePattern = /^(?:\+?\d{1,3}[\s-]?)?(?:\d{1,14}[\s-]?){1,5}$/; 1924 1925 let form = document.querySelector('#form-login'), 1926 input = document.querySelector('#CustomerDetail'), 1927 error_content = document.querySelector('#error-content'); 1928 1929 1930 // One attempt at a time: the reCAPTCHA wait below is async, so without 1931 // this a double-click starts two continuations and posts the form twice. 1932 var submitting = false; 1933 1934 form.addEventListener('submit', async function (event) { 1935 // preventDefault FIRST: a re-entrant submit must still be cancelled, or the 1936 // browser performs a native post with no captcha token. 1937 event.preventDefault(); 1938 if (submitting) return; 1939 1940 let input_value = input.value 1941 error_content.innerHTML = ''; 1942 if (!input_value.match(emailPattern) && !input_value.match(phonePattern)) { 1943 error_content.innerHTML = `<div class="errors note">Invalid Email or Phone</div>`; 1944 return false; 1945 } 1946 1947 submitting = true; 1948 document.querySelector('#form-login .btn').classList.add('btn--loading','loading'); 1949 1950 // reCAPTCHA is unreachable from some regions (google.com is blocked in 1951 // mainland China). Fail open the same way checkout and forgot-password do: 1952 // submit without a token rather than leave the button spinning forever. 1953 try { 1954 if (window.grecaptcha && typeof window.grecaptcha.enterprise === 'object') { 1955 // The loader defines a stub {ready} synchronously and fetches the real 1956 // implementation asynchronously, so execute() may not exist yet. 1957 // ready() queues until it does; the timeout stops a bundle that never 1958 // arrives from hanging the button. 1959 await new Promise(function (resolve) { 1960 setTimeout(resolve, 3000); 1961 try { grecaptcha.enterprise.ready(resolve); } catch (e) { resolve(); } 1962 }); 1963 1964 const token = await grecaptcha.enterprise.execute('6LdMNdIqAAAAALegJp7y4weVcCIlnwmIN8TWseEF', { action: 'LOGIN' }); 1965 document.getElementById('recaptchaResponse').value = token; 1966 } 1967 } catch (e) { /* fail open */ } 1968 1969 document.getElementById('form-login').submit(); 1970 }); 1971 1972 1973</script>
1973 1974 1975 1976 </main> 1977 <style> 1978 .footer{ 1979 background-color: #FFFFFF; 1980 color: #000000; 1981 --color-foreground: 0,0,0; 1982 } 1983 .footer .link--text, 1984 .footer .list-menu__item--link, 1985 .footer .footer-block__details-content .list-menu__item--link{ 1986 color: #000000; 1987 } 1988 .footer-block__heading{ 1989 color: #000000; 1990 } 1991 .rounded{ 1992 border-radius: 10px; 1993 } 1994 .shopping-app-border{ 1995 border: 1px #ECECEC solid; 1996 margin-right: 3px; 1997 } 1998 .app-download-badge{ 1999 display: inline-block; 2000 margin-right: 3px; 2001 } 2002</style> 2003 2004<link rel="preload" href="https://store-themes.easystore.co/1424395/themes/308896/assets/section-footer.css?t=1787094029" as="style" onload="this.onload=null;this.rel='stylesheet'"> 2005 2006<footer class="footer color-background-1"> 2007 <div class="footer__content-top page-width"> 2008 <div class="grid grid--1-col grid--4-col-tablet "> 2009 2010 2011 2012 <div class="grid__item"> 2013 2014 <h2 class="footer-block__heading">éæ¼æéç§æè¡ä»½æéå ¬å¸ About Time Technologies Limited</h2> 2015 <div class="footer-block__details-content"> 2016 <p>æåå°ç·ï¼02-2697-5818<br>è¯çµ¡å°åï¼æ°å叿±æ¢åæ°å°äºè·¯ä¸æ®µ97è14æ¨ä¹12<br>å使´½è©¢ï¼[email protected]<br>LINE ç·ä¸å®¢æï¼ï¼ abouttime<br>æåæéï¼é±ä¸è³é±äº 09:00 - 12:00 / 13:00 - 17:30<br>(ä¾åæ¥/åå®ä¼åæ¥ä¼æ¯)</p> 2017 </div> 2018 2019 </div> 2020 2021 2022 2023 <div class="grid__item"> 2024 2025 <h2 class="footer-block__heading"></h2> 2026 <ul class="footer__list-social list-unstyled list-social footer-block__details-content" role="list"> 2027 2028 2029 <li class="list-social__item"> 2030 <a href="https://www.facebook.com/abouttimetw" class="link link--text list-social__link"> 2031 2032 2033 2034 <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-facebook " 2035 viewBox="0 0 18 18"> 2036 <path fill="currentColor" 2037 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"> 2038 </path> 2039 </svg> 2040 2041 2042 2043 </a> 2044 </li> 2045 2046 2047 <li class="list-social__item"> 2048 <a href="https://www.instagram.com/herowatch_tw/" class="link link--text list-social__link"> 2049 2050 2051 2052 <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-instagram " 2053 viewBox="0 0 18 18"> 2054 <path fill="currentColor" 2055 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"> 2056 </path> 2057 <path fill="currentColor" 2058 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"> 2059 </path> 2060 </svg> 2061 2062 2063 2064 </a> 2065 </li> 2066 2067 2068 2069 2070 <li class="list-social__item"> 2071 <a href="liff.line.me/1645278921-kWRPP32q/?accountId=abouttime" class="link link--text list-social__link"> 2072 2073 2074 2075 <svg class="icon icon-line-footer " fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 750 750"><path d="M375,.5C168.17.5.5,168.17.5,375S168.17,749.5,375,749.5,749.5,581.83,749.5,375,581.83.5,375,.5ZM570.75,476.9
20751C518.48,537.06,401.6,610.33,375,621.53s-22.66-7.13-21.57-13.42c.63-3.76,3.55-21.33,3.55-21.33.83-6.36,1.66-16.23-.83-22.52-2.81-7-13.83-10.54-21.95-12.29C214.51,536.14,125.9,452.45,125.9,352.53,125.9,241,237.64,150.38,375,150.38s249.1,90.68,249.1,202.15h0C624.14,397.14,606.85,437.32,570.75,476.91Z"/><polygon points="324.38 298.65 324.38 298.65 324.38 298.65 324.38 298.65"/><path d="M324.38,298.65H306.91a4.86,4.86,0,0,0-4.86,4.85V412a4.86,4.86,0,0,0,4.86,4.85h17.47a4.86,4.86,0,0,0,4.85-4.85V303.5A4.86,4.86,0,0,0,324.38,298.65Z"/><path d="M444.67,298.65h-17.5a4.85,4.85,0,0,0-4.85,4.85V368l-49.73-67.17a4.57,4.57,0,0,0-.38-.49,2.76,2.76,0,0,0-.29-.3l-.09-.09a2.65,2.65,0,0,0-.26-.21l-.12-.1-.25-.18-.15-.08-.26-.14-.15-.08-.28-.12-.16,0-.28-.1-.18,0-.27-.06H351.08a4.85,4.85,0,0,0-4.85,4.84V412a4.85,4.85,0,0,0,4.85,4.85h17.48a4.85,4.85,0,0,0,4.85-4.85V347.54l49.81,67.26a5.15,5.15,0,0,0,1.22,1.2h.06l.29.18.14.07.24.12.23.1.15,0,.32.11H426a4.69,4.69,0,0,0,1.24.16h17.48a4.85,4.85,0,0,0,4.86-4.84h0V303.5A4.87,4.87,0,0,0,444.67,298.65Z"/><path d="M282.26,389.67h0l0,0H234.79V303.5a4.85,4.85,0,0,0-4.83-4.85H212.47a4.84,4.84,0,0,0-4.85,4.84h0V412a4.74,4.74,0,0,0,1.35,3.32.27.27,0,0,0,.07.08l.07.07a4.81,4.81,0,0,0,3.33,1.35h69.81a4.84,4.84,0,0,0,4.84-4.84h0V394.52A4.84,4.84,0,0,0,282.26,389.67Z"/><path d="M541.16,371.34a4.85,4.85,0,0,0,4.85-4.85h0V349a4.85,4.85,0,0,0-4.84-4.85H493.72V325.84l47.42,0A4.83,4.83,0,0,0,546,321V303.5a4.85,4.85,0,0,0-4.84-4.86H471.34A4.81,4.81,0,0,0,468,300l-.05.05-.08.09a4.82,4.82,0,0,0-1.34,3.33V412a4.77,4.77,0,0,0,1.35,3.33l.07.07.07.07a4.8,4.8,0,0,0,3.32,1.36h69.81A4.85,4.85,0,0,0,546,412h0V394.5a4.85,4.85,0,0,0-4.84-4.85H493.72V371.34Z"/></svg> 2076 2077 2078 2079 </a> 2080 </li> 2081 2082 2083 2084 <li class="list-social__item"> 2085 <a href="https://www.youtube.com/@abouttimetech" class="link link--text list-social__link"> 2086 2087 2088 2089 <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-youtube " 2090 viewBox="0 0 100 70"> 2091 <path 2092 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" 2093 fill="currentColor"> 2094 </path> 2095 </svg> 2096 2097 2098 2099 </a> 2100 </li> 2101 2102 2103 </ul> 2104 2105 </div> 2106 2107 </div> 2108 </div> 2109 <div class="footer__content-bottom"> 2110 <div class="footer__content-bottom-wrapper page-width"> 2111 <div class="footer__column footer__column--info"> 2112 2113 2114 2115 2116 2117 <div class="footer__copyright caption"> 2118 <div class="copyright__content">© 2026 About time Technologies Limited</div> 2119 </div> 2120 2121 <div class="footer__copyright caption"> 2122 2123 <div> 2124 2125 2126 2127 <a href="/pages/æåæ¢æ¬¾">æåæ¢æ¬¾ </a> 2128 2129 2130 2131 2132 | <a href="/legal/privacy-policy">é±ç§æ¿ç</a> 2133 2134 2135 2136 2137 | <a href="/legal/refund-policy">鿬¾æ¿ç</a> 2138 2139 2140 2141 2142 | <a href="/legal/ç¨æ¶åè°">ç¨æ¶åè°</a> 2143 2144 2145 2146 </div> 2147 2148 </div> 2149 2150 </div> 2151 </div> 2152 </div> 2153</footer> 2154 2155 2156 2157 2158 2159 2160
2160<script> 2161 EasyStore.Currencies.init([{"name":"New Taiwan Dollar","code":"TWD","rate":"1.0","format_prefix":"NT$","format_suffix":null,"format_decimals":0,"thousand_separator":",","is_primary":true}], 1) 2162</script>
2162 2163 2164 2165 2166
2166<script> 2167 let page_template = 'customers'; 2168 2169 if(document.querySelector('.currency-picker')) { 2170 EasyStore.Currencies.change(document.querySelector('.currency-picker').value) 2171 EasyStore.Currencies.convertAll() 2172 } 2173 2174 document.querySelectorAll('.currency-picker').forEach((el)=>{ 2175 el.addEventListener('change',(event)=>{ 2176 EasyStore.Currencies.change(event.target.value) 2177 2178 2179 if (page_template == 'cart') { 2180 const params = new URLSearchParams(window.location.search); 2181 params.set('delete_cache', 1); 2182 window.location.search = params; 2183 } else { 2184 window.location.reload(); 2185 } 2186 2187 return 2188 2189 2190 document.querySelectorAll('[name=currencies],[name=current_currency]').forEach((el)=>{ 2191 el.value = event.target.value 2192 }) 2193 2194 if(page_template == 'cart') location.reload(); 2195 }) 2196 }) 2197 </script>
2197 2198 2199 2200 2201 2202
2202<script> 2203 2204 window.variantStrings = { 2205 addToCart: `å å ¥è³¼ç©è»`, 2206 updateCart: `æ´æ°è³¼ç©è»`, 2207 soldOut: `<span style='font-size:14px;'>å®å®</span>`, 2208 unavailable: `æ«ç¡ä¾æ`, 2209 } 2210 2211 window.accessibilityStrings = { 2212 shareSuccess: `éæ¥å·²å¾©è£½å°åªè²¼æ¿`, 2213 } 2214 2215 window.promotionStrings = { 2216 title: `é©ç¨åªæ `, 2217 } 2218 2219 window.productSettings = { 2220 variantOptionsDisplay: `radio-img`, 2221 } 2222 </script>
2222 2223 2224 <link href="https://store-themes.easystore.co/1424395/themes/308896/assets/section-main-product.css?t=1787094029" rel="stylesheet" type="text/css" media="screen" /> 2225<link href="https://store-themes.easystore.co/1424395/themes/308896/assets/component-loading-overlay.css?t=1787094029" rel="stylesheet" type="text/css" media="screen" /> 2226<link href="https://store-themes.easystore.co/1424395/themes/308896/assets/product-quickview.css?t=1787094029" rel="stylesheet" type="text/css" media="screen" /> 2227 2228<product-quickview-modal> 2229 <div id="product-quickview-modal" class="product-quickview-modal-wrapper focus-inset" aria-modal="true" role="dialog" tabindex="-1"> 2230 <button type="button" class="product-quickview-modal__close modal__close-button link link--text focus-inset" aria-label="accessibility.close"> 2231 2232 2233 2234 <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> 2235 2236 2237 2238 </button> 2239 2240 <div class="loading-overlay"> 2241 <div class="loading-overlay__spinner"> 2242 <svg aria-hidden="true" focusable="false" role="presentation" class="spinner" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"> 2243 <circle class="path" fill="none" stroke-width="6" cx="33" cy="33" r="30"></circle> 2244 </svg> 2245 </div> 2246 </div> 2247 2248 <div class="product-quickview-modal__body" style="display: none;"></div> 2249 </div> 2250 <div class="product-quickview-modal-backdrop"></div> 2251</product-quickview-modal> 2252
2253<script src="https://store-themes.easystore.co/1424395/themes/308896/assets/product-form.js?t=1787094029" type="text/javascript" ></script>
vendor: 1 bytes, line 2253
2253
2254<script src="https://store-themes.easystore.co/1424395/themes/308896/assets/product-quickview.js?t=1787094029" type="text/javascript" ></script>
2254 2255
2255<script> 2256 2257 /* 2258 2259 ------ 2260 Events 2261 ------ 2262 2263 pages/viewed 2264 2265 customers/signup 2266 2267 customers/login 2268 2269 products/searched 2270 2271 collections/viewed 2272 2273 products/viewed 2274 2275 products/shared 2276 2277 wishlists/item_added 2278 2279 carts/items_added 2280 2281 carts/viewed 2282 2283 carts/item_removed 2284 2285 checkouts/initiated 2286 2287 checkouts/shipping_info_added 2288 2289 checkouts/payment_info_added 2290 2291 checkouts/completed 2292 2293 orders/placed 2294 2295 orders/purchased 2296 2297 payments/captured 2298 2299 payments/failed 2300 2301 */ 2302 2303 window.__latest_cart = window.__latest_cart || null; 2304 2305 const _selector = document.querySelector.bind(document), 2306 _selectorAll = document.querySelectorAll.bind(document) 2307 2308 document.addEventListener('DOMContentLoaded', (event) => { 2309 2310 const default_currency = getCookie("currency") 2311 const customer_id = window.__st.cid 2312 const template = window.__st.p 2313 2314 onPageView() 2315 2316 //-----------------------// 2317 // Configs // 2318 //-----------------------// 2319 2320 window.dataLayer = window.dataLayer || [] 2321 2322 Array.prototype.last = Array.prototype.last || function() { 2323 return this[this.length - 1] || null 2324 } 2325 2326 Array.prototype.first = Array.prototype.first || function() { 2327 return this[0] || null 2328 } 2329 2330 //----------------------// 2331 // Triggers // 2332 //----------------------// 2333 2334 const XHR = window.XMLHttpRequest 2335 2336 function xhr() { 2337 2338 const xhr = new XHR() 2339 2340 xhr.addEventListener("readystatechange", function() { 2341 2342 if(xhr.readyState != 4) return 2343 2344 try { 2345 2346 const response_url = xhr.responseURL 2347 2348 if (response_url.includes("cart/add")) { 2349 2350 window.__latest_cart = JSON.parse(xhr.response) 2351 2352 onCartItemsAdded() // ok 2353 2354 } 2355 2356 if (response_url.includes("cart/remove_item_quantity")) { 2357 2358 window.__latest_cart = JSON.parse(xhr.response) 2359 2360 onCartItemRemoved() // ok 2361 2362 } 2363 2364 if (response_url.includes("new_cart?retrieve=true")) { 2365 2366 result = JSON.parse(xhr.response) 2367 2368 if (result.cart) { 2369 window.__latest_cart = result.cart 2370 } 2371 2372 } 2373 2374 } catch(e) { 2375 2376 console.error(e) 2377 2378 } 2379 2380 }, false); 2381 2382 return xhr 2383 2384 } 2385 2386 window.XMLHttpRequest = xhr 2387 2388 switch(template) { 2389 2390 case 'cart': onCartView() // ok 2391 break 2392 case 'product': onProductView() // ok 2393 break 2394 case 'collection': onCollectionView() // ok 2395 break 2396 case 'blog': onBlogView() 2397 break 2398 case 'article': onArticleView() 2399 break 2400 case 'payment_completed': onOrderPlace() 2401 break 2402 case 'payment_fail': onPaymentFail() 2403 break 2404 2405 } 2406 2407 // _selector('form[action="/checkout/payments"]').addEventListener("submit", onPaymentInfoAdded(_selector('form[action="/checkout/payments"]'))) 2408 if (_selector('form[action="/checkout/detail"]')) _selector('form[action="/checkout/detail"]').addEventListener("submit", ()=>{onShippingInfoAdded(_selector('form[action="/checkout/detail"]'))}) // ok 2409 if (_selector('form[action="/checkout/shipping"]')) _selector('form[action="/checkout/shipping"]').addEventListener("submit", ()=>{onShippingInfoAdded(_selector('form[action="/checkout/shipping"]'))}) // ok 2410 if (_selector('form[action="/account/register"]')) _selector('form[action="/account/register"]').addEventListener("submit", onSignUp) // ok 2411 if (_selector('form[action="/account/login"]')) _selector('form[action="/account/login"]').addEventListener("submit", onLogin) // ok 2412 if (_selector('form[action="/search"]')) _selector('form[action="/search"]').addEventListener("submit", onProductSearch()) // ok 2413 if (_selector('#line-login-btn')) _selector('#line-login-btn').addEventListener('click', onLineLogin) // ok 2414 if (_selector('#PlaceOrder')) _selector('#PlaceOrder').addEventListener("click", ()=>{onCheckoutComplete(_selector('form[action="/checkout/payments"]'))}); // ok 2415 if (_selector('#add_wishlist')) _selector('#add_wishlist').addEventListener("click", onWishlistItemAdded) // ok 2416 if (_selectorAll('a[href="/account/logout"]')) _selectorAll('a[href="/account/logout"]').forEach(logoutButton => logoutButton.addEventListener("click", onLogout)) // ok 2417 if (_selector('.CartDrawerTrigger.cart-page-link')) _selector('.CartDrawerTrigger.cart-page-link').addEventListener("click", onCartView) // ok 2418 if (_selector('.CartDrawerTrigger.cart-page-link.mobile-cart-page-link')) _selector('.CartDrawerTrigger.cart-page-link.mobile-cart-page-link').addEventListener("click", onCartView) // ok 2419 if (_selectorAll('a[class^="share-"]')) _selectorAll('a[class^="share-"]').forEach(shareButton => shareButton.addEventListener("click", ()=>{onProductShare(shareButton)}) ) // ok 2420 if (_selectorAll('[name$="checkout"]')) _selectorAll('[name$="checkout"]').forEach(checkoutButton => checkoutButton.addEventListener("click", onCheckoutInitiate)) 2421 2422 // For append elements 2423 const bodyMutationObserver = new MutationObserver(() => { 2424 if (_selector('#form__spc #PlaceOrder')) _selector('#form__spc #PlaceOrder').addEventListener("click", onSinglePageCheckout) // ok 2425 if (_selectorAll('[name$="checkout"]')) _selectorAll('[name$="checkout"]').forEach(checkoutButton => checkoutButton.addEventListener("click", onCheckoutInitiate)) 2426 }); 2427 bodyMutationObserver.observe(_selector("body"), {subtree: true, childList: true}); 2428 2429 //------------------------------// 2430 // Event handlers // 2431 //------------------------------// 2432 2433 function onPageView() { 2434 2435 EasyStore.Event.dispatch('pages/viewed', { 2436 page: { 2437 type: template, 2438 title: document.title, 2439 description: _selector('meta[name=description]') ? _selector('meta[name=description]').getAttribute('content') : null, 2440 url: location.href, 2441 } 2442 }) 2443 2444 } 2445 2446 function onSignUp() { 2447 2448 const email_regex = new RegExp(/^[a-zA-Z0-9.!#$%&"*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/) 2449 const phone_regex = new RegExp(/^(\+?6?01)[0-46-9]-*[0-9]{7,8}$/) 2450 2451 const email_or_phone = _selector(`input[name="customer[email_or_phone]"]`).value.replace("+", "").replace(/\s+/, "") 2452 2453 let data = {} 2454 2455 if (email_regex.test(email_or_phone)) { 2456 data.method = 'email' 2457 data.email = email_or_phone 2458 } 2459 2460 if (phone_regex.test(email_or_phone)) { 2461 data.method = "phone" 2462 data.phone = email_or_phone 2463 } 2464 2465 if (!data.method) return 2466 2467 EasyStore.Event.dispatch('customers/signup', data) 2468 2469 } 2470 2471 function onLogin() { 2472 2473 const email_regex = new RegExp(/^[a-zA-Z0-9.!#$%&"*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/) 2474 const phone_regex = new RegExp(/^(\+?6?01)[0-46-9]-*[0-9]{7,8}$/) 2475 2476 const email_or_phone = _selector(`input[name="customer[email_or_phone]"]`).value.replace("+", "").replace(/\s+/, "") 2477 2478 let data = {} 2479 2480 if (email_regex.test(email_or_phone)) { 2481 data.method = 'email' 2482 data.email = email_or_phone 2483 } 2484 2485 if (phone_regex.test(email_or_phone)) { 2486 data.method = "phone" 2487 data.phone = email_or_phone 2488 } 2489 2490 if (!data.method) return 2491 2492 EasyStore.Event.dispatch('customers/login', data) 2493 2494 } 2495 2496 function onLineLogin() { 2497 2498 EasyStore.Event.dispatch('customers/login', { method: 'line' }) 2499 2500 } 2501 2502 function onLogout() { 2503 2504 EasyStore.Event.dispatch('customers/logout', { customer_id }) 2505 2506 } 2507 2508 function onBlogView() { 2509 2510 const blog = "" 2511 2512 EasyStore.Event.dispatch('blogs/viewed', { blog }) 2513 2514 } 2515 2516 function onArticleView() { 2517 2518 const article = "" 2519 2520 EasyStore.Event.dispatch('articles/viewed', { article }) 2521 2522 } 2523 2524 function onProductSearch() { 2525 2526 const query = _selector('input[name=q]').value 2527 2528 if (!query) return 2529 2530 EasyStore.Event.dispatch('products/searched', { query }) 2531 2532 } 2533 2534 function onCollectionView() { 2535 2536 const collection = "" 2537 2538 EasyStore.Event.dispatch('collections/viewed', { collection }) 2539 2540 } 2541 2542 function onProductView() { 2543 2544 const product = "" 2545 2546 EasyStore.Event.dispatch("products/viewed", { product }) 2547 2548 } 2549 2550 function onProductShare(el) { 2551 2552 const product = "" 2553 2554 const channel = el.getAttribute("class").split("-").last() 2555 2556 EasyStore.Event.dispatch('products/shared', { product, channel }) 2557 2558 } 2559 2560 function onWishlistItemAdded() { 2561 2562 let product = "" 2563 const quantity = _selector("#Quantity").value 2564 2565 EasyStore.Event.dispatch('wishlists/item_added', { product }) 2566 2567 } 2568 2569 async function onCartItemsAdded() { 2570 2571 const cart = await getCart() 2572 2573 if(cart && cart.items != undefined && cart.items.length > 0) { 2574 2575 EasyStore.Event.dispatch('carts/item_added', { cart }) 2576 2577 } 2578 2579 } 2580 2581 async function onCartView() { 2582 2583 const cart = await getCart() 2584 2585 EasyStore.Event.dispatch('carts/viewed', { cart }) 2586 2587 } 2588 2589 async function onCartItemRemoved() { 2590 2591 const cart = await getCart() 2592 2593 cart.items = [] 2594 2595 if(cart) { 2596 2597 EasyStore.Event.dispatch('carts/item_removed', { cart }) 2598 2599 } 2600 2601 } 2602 2603 async function onCheckoutInitiate() { 2604 2605 const cart = await getCart() 2606 2607 EasyStore.Event.dispatch('checkouts/initiated', { cart }) 2608 2609 } 2610 2611 async function onShippingInfoAdded(form) { 2612 let checkout = getCheckout() 2613 2614 let form_data = {} 2615 new FormData(form).forEach((value, key) => form_data[key] = value) 2616 2617 let shipping_tier = null 2618 2619 if (form_data.type && form_data.type.startsWith("r_pickup")) { 2620 shipping_tier = `Pickup - ${form_data.pick_location}` 2621 } 2622 2623 if (form_data.s_id) {
2624 shipping_tier = _selector(`input[id='`+form_data.s_id+`']`).getAttribute("data-shipping-name") 2625 } 2626 2627 if (!shipping_tier) return 2628 2629 EasyStore.Event.dispatch('checkouts/shipping_info_added', { checkout, shipping_tier }) 2630 2631 } 2632 2633 async function onPaymentInfoAdded(form) { 2634 2635 let checkout = getCheckout() 2636 2637 let payment_type = new FormData(form).get('payment_method') 2638 2639 EasyStore.Event.dispatch("checkouts/payment_info_added", { checkout, payment_type }) 2640 2641 } 2642 2643 async function onOrderPlace() { 2644 2645 let cart_token = getCookie("cart_js") 2646 let previous_cart_token = getCookie("previous_cart_ga4_js") 2647 2648 if (previous_cart_token && previous_cart_token == cart_token) { 2649 // Prevent duplicate purchase tracking 2650 return 2651 } 2652 2653 let order = getOrder() 2654 2655 EasyStore.Event.dispatch('orders/placed', { order }) 2656 2657 if(order.is_manual_payment) { 2658 2659 EasyStore.Event.dispatch('orders/purchased', { order }) 2660 2661 } 2662 2663 const last_transaction = order.transactions.last() 2664 2665 if (last_transaction.status) { 2666 2667 EasyStore.Event.dispatch('orders/purchased', { order }) 2668 EasyStore.Event.dispatch('payments/captured', { order }) 2669 2670 } 2671 2672 } 2673 2674 async function onPaymentFail() { 2675 2676 const order = getOrder() 2677 2678 EasyStore.Event.dispatch('payments/failed', { order }) 2679 2680 } 2681 2682 async function onCheckoutComplete(form) { 2683 2684 onPaymentInfoAdded(form) 2685 2686 const checkout = getCheckout() 2687 2688 EasyStore.Event.dispatch('checkouts/completed', { checkout }) 2689 2690 } 2691 2692 async function onSinglePageCheckout() { 2693 2694 // let checkout = $("[data-app-checkout]").data("app-checkout") 2695 2696 let checkout = getCheckout() 2697 2698 // const payment_type = _selector("#app_spc_payment_method").find(`[class*="label-content"]`).first().find("b").first().text() 2699 const payment_type = _selector("#app_spc_payment_method").getElementsByClassName('label-content')[0].getElementsByTagName('b')[0].innerHTML 2700 2701 const shipping_method = _selector("#delivery_method").value 2702 2703 let shipping_tier = null 2704 let app_spc_customer_info_label = _selector("#app_spc_customer_info").getElementsByClassName('label-content') 2705 if (shipping_method == "shipping") { 2706 shipping_tier = app_spc_customer_info_label[app_spc_customer_info_label.length - 1].getElementsByTagName('b')[0].innerHTML 2707 } 2708 2709 if (shipping_method == "pickup") { 2710 shipping_tier = app_spc_customer_info_label[0].innerHTML 2711 } 2712 2713 if (shipping_tier) { 2714 2715 EasyStore.Event.dispatch('checkouts/shipping_info_added', { 2716 checkout, 2717 shipping_tier, 2718 }) 2719 2720 } 2721 2722 if (payment_type) { 2723 2724 EasyStore.Event.dispatch('checkouts/payment_info_added', { 2725 checkout, 2726 payment_type, 2727 }) 2728 2729 } 2730 2731 EasyStore.Event.dispatch('checkouts/completed', { checkout }) 2732 2733 } 2734 2735 }) 2736 2737 2738 //-----------------------// 2739 // Functions // 2740 //-----------------------// 2741 2742 function getCookie(name) { 2743 2744 name += "=" 2745 2746 decodedCookie = decodeURIComponent(document.cookie) 2747 2748 ca = decodedCookie.split(";") 2749 2750 for(i = 0; i < ca.length; i++) { 2751 c = ca[i] 2752 while (c.charAt(0) == " ") { 2753 c = c.substring(1) 2754 } 2755 if (c.indexOf(name) == 0) { 2756 return c.substring(name.length, c.length) 2757 } 2758 } 2759 2760 return "" 2761 2762 } 2763 2764 const parsePrice = price => { 2765 if(typeof price === 'string') { 2766 return parseFloat(price.split(',').join('')) 2767 } 2768 2769 return price 2770 } 2771 2772 const requestCart = async (method, data) => { 2773 2774 let response = await fetch('/cart.json', {method: 'GET',headers: {'Content-Type': 'application/json'}}) 2775 result = await response.json() 2776 2777 return result.cart 2778 2779 } 2780 const getCart = async (latest = false) => { 2781 2782 let cart = window.__latest_cart 2783 2784 const cart_invalid = !cart || !cart.items || (cart.total_price > 0 && !cart.items.length) 2785 2786 if(latest || cart_invalid) { 2787 cart = await requestCart() 2788 } 2789 2790 cart.items = cart.items || [] 2791 2792 return mapCart(cart) 2793 2794 } 2795 2796 const getCheckout = async () => { 2797 mapCheckout(window.__latest_cart || await requestCart()) 2798 } 2799 2800 const getOrder = async () => { 2801 mapOrder(window.__latest_cart || await requestCart()) 2802 } 2803 2804 //-----------------------// 2805 // Mappers // 2806 //-----------------------// 2807 2808 const fallbackAttribute = (object, attribute) => { 2809 2810 if(!Array.isArray(attribute)) { 2811 attribute = [attribute] 2812 } 2813 2814 let final_value = null 2815 2816 do { 2817 2818 final_value = object[attribute.shift()] 2819 2820 } while(!final_value && attribute.length) 2821 2822 return final_value 2823 2824 } 2825 2826 const map = (object, mapper) => { 2827 2828 const newObject = {} 2829 2830 for(const key in mapper) { 2831 2832 // Handle different keys between new and old format
2833 newObject[key] = fallbackAttribute(object, mapper[key]) 2834 2835 // Cast price to float 2836 if(newObject[key] && ['price', 'amount', 'discount', 'discounts'].some(x => key.endsWith(x))) { 2837 newObject[key] = parsePrice(newObject[key]) 2838 } 2839 2840 if(newObject[key] === undefined) { 2841 delete newObject[key] 2842 } 2843 2844 } 2845 2846 return newObject 2847 2848 } 2849 2850 const mapCart = cart => { 2851 2852 const oldCart = cart 2853 2854 const mapper = { 2855 id: 'id', 2856 currency: 'currency', 2857 item_count: 'item_count', 2858 items: 'items', 2859 total_price: 'total_price', 2860 latest_items: 'latest_items' 2861 } 2862 2863 cart = map(cart, mapper) 2864 2865 const discounts = (oldCart.storewide_discounts || []).concat((oldCart.voucher_discounts || [])) 2866 2867 cart.discount_applications = discounts.map(discount => ({ 2868 title: discount.voucher_code || null, 2869 value: parsePrice(discount.amount), 2870 })) 2871 2872 cart.original_total_price = cart.items.length 2873 ? cart.items 2874 .map(item => item.original_price) 2875 .reduce((sum, price) => sum + price) 2876 : 0 2877 2878 cart.total_discount = cart.discount_applications.length 2879 ? cart.discount_applications 2880 .map(discount => parsePrice(discount.value)) 2881 .reduce((sum, value) => sum + value) 2882 : 0 2883 2884 cart.items = cart.items.map(item => mapLineItem(item)) 2885 2886 return cart 2887 2888 } 2889 2890 const mapCheckout = checkout => { 2891 2892 const mapper = { 2893 note: 'note', 2894 attributes: 'note_attributes', 2895 billing_address: 'billing_address', 2896 currency: 'currency', 2897 customer_id: 'customer_id', 2898 discounts_amount: 'total_discount', 2899 id: 'id', 2900 line_items: 'order_item', 2901 order_number: 'order_number', 2902 shipping_address: 'shipping_address', 2903 shipping_price: 'shipping_tax', 2904 shipping_method: 'shipping_method_name', 2905 tax_price: 'total_tax', 2906 } 2907 2908 checkout = map(checkout, mapper) 2909 2910 checkout.requires_shipping = checkout.line_items.some(item => item.shipping_required) 2911 2912 checkout.line_items = checkout.line_items.map(item => mapLineItem(item)) 2913 2914 return checkout 2915 2916 } 2917 2918 const mapOrder = order => { 2919 2920 const mapper = { 2921 attributes: 'note_attributes', 2922 billing_address: 'billing_address', 2923 cancelled: 'is_cancelled', 2924 cancelled_at: 'cancelled_at', 2925 created_at: 'created_at', 2926 customer_id: 'customer_id', 2927 // discount_applications: 'discount_applications', 2928 email: 'email', 2929 financial_status: 'financial_status', 2930 fulfillment_status: 'fulfillment_status', 2931 line_items: 'order_item', 2932 note: 'note', 2933 order_number: 'order_number', 2934 phone: 'phone', 2935 shipping_address: 'shipping_address', 2936 shipping_methods: 'shipping_methods', 2937 shipping_price: 'total_shipping', 2938 subtotal_price: 'subtotal_price', 2939 // tax_lines: 'tax_lines', 2940 tax_price: 'total_tax', 2941 total_discounts: 'total_discount', 2942 total_net_amount: 'total_amount_include_transaction', 2943 total_price: 'total_price', 2944 transactions: 'transaction_records', 2945 is_manual_payment: 'is_manual_payment', 2946 } 2947 2948 order.email = order.billing_address.email 2949 order.phone = order.billing_address.phone 2950 order.shipping_method = order.shipping_method_name 2951 2952 order = map(order, mapper) 2953 2954 order.line_items = order.line_items.map(item => mapLineItem(item)) 2955 order.transactions = order.transactions.map(transaction => mapTransaction(transaction)) 2956 2957 return order 2958 2959 } 2960 2961 const mapLineItem = line_item => { 2962 2963 const old_line_item = line_item 2964 2965 const mapper = { 2966 final_price: 'price', 2967 image: 'img_url', 2968 message: 'message', 2969 original_line_price: 'original_line_price', 2970 original_price: 'original_price', 2971 properties: 'properties', 2972 quantity: 'quantity', 2973 requires_shipping: 'shipping_required', 2974 sku: 'sku', 2975 taxable: 'taxable', 2976 title: 'product_name', 2977 product_name: 'product_name', 2978 url: 'url', 2979 product_id: 'product_id', 2980 variant_id: 'variant_id', 2981 id: ['id', 'i_id'], 2982 } 2983 2984 line_item = map(line_item, mapper) 2985 2986 line_item.product_id = line_item.product_id || (old_line_item.product && old_line_item.product.id) || null 2987 line_item.variant_id = line_item.variant_id || (old_line_item.variant && old_line_item.variant.id) || null 2988 line_item.image = line_item.image || (old_line_item.image && old_line_item.image.url) || null 2989 2990 return line_item 2991 2992 } 2993 2994 const mapTransaction = transaction => { 2995 2996 const mapper = { 2997 amount: 'amount', 2998 created_at: 'created_at', 2999 gateway: 'gateway_type', 3000 id: 'id', 3001 status: 'status', 3002 } 3003 3004 transaction = map(transaction, mapper) 3005 3006 return transaction 3007 3008 } 3009 3010 3011</script>
3011 3012 3013</body> 3014</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.