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 <!-- Facebook Pixel Code -->
9<script>
vendor: 399 bytes, lines 9-18
9 10!function(f,b,e,v,n,t,s) 11{if(f.fbq)return;n=f.fbq=function(){n.callMethod? 12n.callMethod.apply(n,arguments):n.queue.push(arguments)}; 13if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0'; 14n.queue=[];t=b.createElement(e);t.async=!0; 15t.src=v;s=b.getElementsByTagName(e)[0]; 16s.parentNode.insertBefore(t,s)}(window, document,'script', 17'https://connect.facebook.net/en_US/fbevents.js'); 18fbq('init', '
18388838182692732
vendor: 30 bytes, lines 18-19
18'); 19fbq('track', 'PageView');
20</script>
20 21<noscript><img height="1" width="1" style="display:none" 22src="https://www.facebook.com/tr?id=388838182692732&ev=PageView&noscript=1" 23/></noscript> 24<!-- End Facebook Pixel Code --> 25 <!-- Global site tag (gtag.js) - Google Ads: 793750852 -->
vendor: 64 bytes, lines 25-26
25 26<script async src="https://www.googletagmanager.com/gtag/js?id=
26AW-793750852
vendor: 12 bytes, line 26
26"></script>
27<script> 28
vendor: 134 bytes, lines 28-32
28window.dataLayer = window.dataLayer || []; 29 function gtag(){dataLayer.push(arguments);} 30 gtag('js', new Date()); 31 32 gtag('config', '
32AW-793750852
vendor: 4 bytes, line 32
32');
33</script>
33 34 35 <!-- Global site tag (gtag.js) - Google Analytics -->
vendor: 64 bytes, lines 35-36
35 36<script async src="https://www.googletagmanager.com/gtag/js?id=
36UA-124909880-1
vendor: 12 bytes, line 36
36"></script>
37<script> 38
vendor: 134 bytes, lines 38-42
38window.dataLayer = window.dataLayer || []; 39 function gtag(){dataLayer.push(arguments);} 40 gtag('js', new Date()); 41 42 gtag('config', '
42UA-124909880-1
vendor: 4 bytes, line 42
42');
43</script>
43 44 <meta name="google-site-verification" content="UZPxBQ89kGZH-0esLepNMLEBLhYCy5AXEnplB7eQzRA" /> 45 46 <!-- Basic page needs ================================================== --> 47 <meta charset="utf-8"> 48 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 49 50 51 <link rel="icon" href="https://cdn.store-assets.com/s/227019/f/3850237.png" /> 52 53 54 <!-- Title and description ================================================== --> 55 <title> 56 æ±ç³è¡ç«_æ¸æ³ä½å – ä¸å鼿¨¡å½«å»å·¥è社 57 </title> 58 59 60 <meta name="description" content="ä¸å鼿¨¡å·¥è社åµå§äºº:æ±ç³è¡ç«_æ¸æ³ä½å"> 61 62 63 <!-- Social meta ================================================== --> 64 65 66 <meta property="og:type" content="blog"> 67 <meta property="og:title" content="æ±ç³è¡ç«_æ¸æ³ä½å"> 68 <meta property="og:url" content="https://www.sunyours.com.tw/blogs/tsaifu-calligraphy"> 69 70 71<meta property="og:description" content="ä¸å鼿¨¡å·¥è社åµå§äºº:æ±ç³è¡ç«_æ¸æ³ä½å"> 72<meta property="og:site_name" content="ä¸å鼿¨¡å½«å»å·¥è社"> 73 74 75 76 <meta name="twitter:card" content="summary"> 77 78 79 80 81 <meta name="twitter:title" content="æ±ç³è¡ç«_æ¸æ³ä½å"> 82 <meta name="twitter:description" content="ä¸å鼿¨¡å·¥è社åµå§äºº:æ±ç³è¡ç«_æ¸æ³ä½å"> 83 84 85 86 87 <!-- Helpers ================================================== --> 88 <link rel="canonical" href="https://www.sunyours.com.tw/blogs/tsaifu-calligraphy"> 89 <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> 90 <meta name="theme-color" content=""> 91 92 <!-- CSS ================================================== --> 93 <link href="https://store-themes.easystore.co/227019/themes/1592/assets/timber.css?v2?t=1787072457" rel="stylesheet" type="text/css" media="screen" /> 94 <link href="https://store-themes.easystore.co/227019/themes/1592/assets/theme.css?v2?t=1787072457" rel="stylesheet" type="text/css" media="screen" /> 95 96 97 98 99 100 101
101<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js" type="text/javascript" ></script>
101 102 <!-- Header hook for plugins ================================================== --> 103 104<!-- ScriptTags -->
105<script>window.__st={p: "blog",cid: null,cem: null,cph: null,cfn: null,cln: null,cge: null,cdb: null,ccc: null};</script>
105<script src='/assets/events.js'></script>
105<script>(function(){function asyncLoad(){var urls=['/assets/facebook-pixel.js?v=1.2.1724319536','/assets/traffic.js?v=1','https://apps.easystore.co/facebook-login/script.js?shop=staysunyours.easy.co&t=1724319481','https://apps.easystore.co/instagram-feed/script.js?shop=staysunyours.easy.co'];for(var i=0;i<urls.length;i++){var s=document.createElement('script');s.type='text/javascript';s.async=true;s.src=urls[i];var x=document.getElementsByTagName('script')[0];x.parentNode.insertBefore(s, x);}}window.attachEvent ? window.attachEvent('onload', asyncLoad) : window.addEventListener('load', asyncLoad, false);})();</script>
105 106<!-- /ScriptTags --> 107 108 109 110<!--[if lt IE 9]>
111<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.2/html5shiv.min.js" type="text/javascript" ></script>
vendor: 2 bytes, line 111
111
112<script src="https://store-themes.easystore.co/227019/themes/1592/assets/respond.min.js?t=1787072457" type="text/javascript" ></script>
112 113<link href="https://store-themes.easystore.co/227019/themes/1592/assets/respond-proxy.html" id="respond-proxy" rel="respond-proxy" /> 114<link href="//www.sunyours.com.tw/search?q=828ebd0ff12b4859ae7dfa681bd42716" id="respond-redirect" rel="respond-redirect" />
115<script src="//www.sunyours.com.tw/search?q=828ebd0ff12b4859ae7dfa681bd42716" type="text/javascript"></script>
115 116<![endif]--> 117 118 119 120
120<script src="https://store-themes.easystore.co/227019/themes/1592/assets/modernizr.min.js?t=1787072457" type="text/javascript" ></script>
120 121 122 123 124
124<script> 125 (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ 126 (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), 127 m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) 128 })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); 129 130 ga('create', '', 'auto','myTracker'); 131 ga('myTracker.send', 'pageview'); 132 133 </script>
133 134 135<!-- Snippet:global/head: Instagram Feed --> 136<link rel="stylesheet" href="https://apps.easystore.co/assets/css/instagram-feed/insta-feed-style.css"> 137<!-- /Snippet --> 138 139</head> 140 141<body id="-------------------------" class="template-blog" > 142<!-- Live Chat Widget powered by https://keyreply.com/chat/ --> 143<!-- Advanced options: --> 144<!-- data-align="left" --> 145<!-- data-overlay="true" -->
146<script data-align="right" data-overlay="false" id="keyreply-script" src="//keyreply.com/chat/widget.js" data-color="#03A9F4" data-apps="JTdCJTIybGluZSUyMjolMjJodHRwczovL2xpbmUubWUvUi90aS9wLyUyNTQwdHZpNDQ1NWglMjIsJTIycGhvbmUlMjI6JTIyMDIyOTU4MzIyMyUyMiwlMjJmYWNlYm9vayUyMjolMjJAc3VueW91cnMlMjIsJTIyZW1haWwlMjI6JTIyc3RheXN1bnlvdXJzQGdtYWlsLmNvbSUyMiU3RA=="></script>
146 147 <ul id="MobileNav" class="mobile-nav large--hide"> 148 149 150 151 <li class="mobile-nav__link" aria-haspopup="true"> 152 153 <a href="/" > 154 ææ°æ¶æ¯ 155 </a> 156 157 </li> 158 159 160 <li class="mobile-nav__link" aria-haspopup="true"> 161 162 163 <a href="/pages/å·¥è社ä»ç´¹" class="mobile-nav__parent-link"> 164 åµå§äººä»ç´¹ 165 </a> 166 <span class="mobile-nav__sublist-trigger"> 167 <span class="icon-fallback-text mobile-nav__sublist-expand"> 168 <span class="icon icon-plus" aria-hidden="true"></span> 169 <span class="fallback-text">+</span> 170</span> 171<span class="icon-fallback-text mobile-nav__sublist-contract"> 172 <span class="icon icon-minus" aria-hidden="true"></span> 173 <span class="fallback-text">-</span> 174</span> 175 176 </span> 177 <ul class="mobile-nav__sublist"> 178 179 180 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 181 182 <a href="/pages/ç«è墨æ¨" > 183 ç«èå¢¨æ¨ 184 </a> 185 186 </li> 187 188 189 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 190 191 <a href="/blogs/tsaifu-calligraphy" > 192 æ±ç³è¡ç«æ¸æ³ä½å 193 </a> 194 195 </li> 196 197 </ul> 198 199 </li> 200 201 202 <li class="mobile-nav__link" aria-haspopup="true"> 203 204 205 <a href="/collections/all" class="mobile-nav__parent-link"> 206 ç¢åä»ç´¹ 207 </a> 208 <span class="mobile-nav__sublist-trigger"> 209 <span class="icon-fallback-text mobile-nav__sublist-expand"> 210 <span class="icon icon-plus" aria-hidden="true"></span> 211 <span class="fallback-text">+</span> 212</span> 213<span class="icon-fallback-text mobile-nav__sublist-contract"> 214 <span class="icon icon-minus" aria-hidden="true"></span> 215 <span class="fallback-text">-</span> 216</span> 217 218 </span> 219 <ul class="mobile-nav__sublist"> 220 221 222 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 223 224 <a href="/collections/é¼å°" > 225 èæ¸é¼å° 226 </a> 227 228 </li> 229 230 231 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 232 233 <a href="/collections/ææé¼å°" > 234 ææé¼å° 235 </a> 236 237 </li> 238 239 240 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 241 242 <a href="/collections/æå·¥é屬å°ç« " > 243 æå·¥é屬å°ç« 244 </a> 245 246 </li> 247 248 249 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 250 251 <a href="/collections/branding-iron" > 252 è¨è£½çå°ç³»åç¢å 253 </a> 254 255 </li> 256 257 </ul> 258 259 </li> 260 261 262 <li class="mobile-nav__link" aria-haspopup="true"> 263 264 <a href="/blogs/blog" > 265 æåå享 266 </a> 267 268 </li> 269 270 271 <li class="mobile-nav__link" aria-haspopup="true"> 272 273 <a href="/pages/ï½å好實å»ï½" > 274 ï½å好實å»ï½ 275 </a> 276 277 </li> 278 279 280 <li class="mobile-nav__link" aria-haspopup="true"> 281 282 <a href="/pages/location" > 283 å·¥å» ä½ç½® 284 </a> 285 286 </li> 287 288 289 290 291 292 293 294 <li class="mobile-nav__link"> 295 <a href="/account/login">ç»å ¥</a> 296 </li> 297 298 <li class="mobile-nav__link"> 299 <a href="/account/register">å å ¥æå¡</a> 300 </li> 301 302 303 304 305 306 <li class="mobile-nav__link"> 307 308 309 310<label class="currency-picker__wrapper"> 311 <!-- <span class="currency-picker__label">Pick a currency</span> --> 312 <select class="currency-picker" name="currencies" style="display: inline; width: auto; vertical-align: inherit;"> 313 <option value="TWD" selected="selected">TWD</option> 314 315 316 317 318 <option value="HKD">HKD</option> 319 320 321 322 323 </select> 324</label> 325 326 327 328 329 330 </li> 331 332 333 <li class="mobile-nav__link header-bar__search-wrapper"> 334 335 <div class="header-bar__module header-bar__search"> 336 337 <a class="popup-with-form medium-down--hide" href="#test-form"> 338 <span class="icon icon-search" aria-hidden="true"></span> 339 </a> 340 <form action="/search" method="get" class="header-bar__search-form clearfix large--hide" role="search"> 341 342 <button type="submit" class="btn icon-fallback-text header-bar__search-submit">
343 <span class="icon icon-search" aria-hidden="true"></span> 344 <span class="fallback-text">æå°</span> 345 </button> 346 <input type="search" name="q" value="" aria-label="æå°" class="header-bar__search-input" placeholder="æå°" autocomplete="off"> 347 <div class="dropdown" id="searchDropdown"></div> 348 <input type="hidden" name="search_history" id="search_history"> 349 </form> 350 351 352 353<!-- form itself --> 354<div id="test-form" class="white-popup-block mfp-hide popup-search"> 355 <div class="popup-search-content"> 356 <form action="/search" method="get" class="input-group search-bar" role="search"> 357 358 <input type="search" name="q" value="" placeholder="æå°" class="input-group-field" aria-label="æå°" placeholder="æå°" autocomplete="off"> 359 <div class="dropdown" id="searchDropdown"></div> 360 <input type="hidden" name="search_history" id="search_history"> 361 <span class="input-group-btn"> 362 <button type="submit" class="btn icon-fallback-text"> 363 <span class="icon icon-search" aria-hidden="true"></span> 364 <span class="fallback-text">æå°</span> 365 </button> 366 </span> 367 </form> 368 </div> 369</div> 370
371<script src="https://store-themes.easystore.co/227019/themes/1592/assets/magnific-popup.min.js?t=1787072457" type="text/javascript" ></script>
vendor: 1 bytes, line 371
371
372<script> 373$(document).ready(function() { 374 $('.popup-with-form').magnificPopup({ 375 type: 'inline', 376 preloader: false, 377 focus: '#name', 378 mainClass: 'popup-search-bg-wrapper', 379 380 // When elemened is focused, some mobile browsers in some cases zoom in 381 // It looks not nice, so we disable it: 382 callbacks: { 383 beforeOpen: function() { 384 if($(window).width() < 700) { 385 this.st.focus = false; 386 } else { 387 this.st.focus = '#name'; 388 } 389 } 390 } 391 }); 392}); 393</script>
393 394 395
396<script> 397 var _search_history_listings = "" 398 if(_search_history_listings != "") localStorage.setItem('searchHistory', JSON.stringify(_search_history_listings)); 399 400 function clearAll() { 401 localStorage.removeItem('searchHistory'); 402 403 var customer = ""; 404 if(customer) { 405 // Your logic to clear all data or call an endpoint 406 fetch('/account/search_histories', { 407 method: 'DELETE', 408 headers: { 409 "Content-Type": "application/json", 410 "X-Requested-With": "XMLHttpRequest" 411 }, 412 body: JSON.stringify({ 413 _token: "7ZKuJSqc8S2mL6uu3u1Im8DzJfNgAS8dk72D4zRQ" 414 }), 415 }) 416 .then(response => response.json()) 417 } 418 } 419 // End - store view history in local storage 420 421 // search history dropdown 422 var searchInputs = document.querySelectorAll('input[type=search]'); 423 424 if(searchInputs.length > 0) { 425 426 searchInputs.forEach((searchInput)=>{ 427 428 searchInput.addEventListener('focus', function() { 429 var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown'); 430 searchDropdown.innerHTML = ''; // Clear existing items 431 432 // retrieve data from local storage 433 var searchHistoryData = JSON.parse(localStorage.getItem('searchHistory')) || []; 434 435 // Convert JSON to string 436 var search_history_json = JSON.stringify(searchHistoryData); 437 438 // Set the value of the hidden input 439 searchInput.closest('form').querySelector("#search_history").value = search_history_json; 440 441 // create dropdown items 442 var clearAllItem = document.createElement('div'); 443 clearAllItem.className = 'dropdown-item clear-all'; 444 clearAllItem.textContent = 'Clear'; 445 clearAllItem.addEventListener('click', function() { 446 clearAll(); 447 searchDropdown.style.display = 'none'; 448 searchInput.classList.remove('is-focus'); 449 }); 450 searchDropdown.appendChild(clearAllItem); 451 452 // create dropdown items 453 searchHistoryData.forEach(function(item) { 454 var dropdownItem = document.createElement('div'); 455 dropdownItem.className = 'dropdown-item'; 456 dropdownItem.textContent = item.term; 457 dropdownItem.addEventListener('click', function() { 458 searchInput.value = item.term; 459 searchDropdown.style.display = 'none'; 460 }); 461 searchDropdown.appendChild(dropdownItem); 462 }); 463 464 if(searchHistoryData.length > 0){ 465 // display the dropdown 466 searchInput.classList.add('is-focus'); 467 document.body.classList.add('search-input-focus'); 468 searchDropdown.style.display = 'block'; 469 } 470 }); 471 472 searchInput.addEventListener("focusout", (event) => { 473 var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown'); 474 searchInput.classList.remove('is-focus'); 475 searchDropdown.classList.add('transparent'); 476 setTimeout(()=>{ 477 searchDropdown.style.display = 'none'; 478 searchDropdown.classList.remove('transparent'); 479 document.body.classList.remove('search-input-focus'); 480 }, 400); 481 }); 482 }) 483 } 484 // End - search history dropdown 485</script>
485 486 </div> 487 488 </li> 489 490 491</ul> 492<div id="MobileNavOutside" class="mobile-nav-outside"></div> 493 494 495<div id="PageContainer" class="page-container"> 496 497<!-- Snippet:global/body_start: Console Extension --> 498<div id='es_console' style='display: none;'>227019</div> 499<!-- /Snippet --> 500 501 502 <style> 503 .search-modal__form{ 504 position: relative; 505 } 506 507 .dropdown-wrapper { 508 position: relative; 509 } 510 511 .dropdown-wrapper:hover .dropdown { 512 display: block; 513 } 514 515 .header-icon-nav .dropdown { 516 left: -80px; 517 } 518 519 .dropdown { 520 display: none; 521 position: absolute; 522 top: 100%; 523 left: 0px; 524 width: 100%; 525 padding: 8px; 526 background-color: #fff; 527 z-index: 1000; 528 border-radius: 5px; 529 border: 1px solid rgba(var(--color-foreground), 1); 530 border-top: none; 531 overflow-x: hidden; 532 overflow-y: auto; 533 max-height: 350px; 534 min-width: 150px; 535 box-shadow: 0 0 5px rgba(0,0,0,0.1); 536 } 537 538 .dropdown a{ 539 text-decoration: none; 540 color: #000 !important; 541 } 542 543 .dropdown-item { 544 padding: 0.4rem 2rem; 545 cursor: pointer; 546 line-height: 1.4; 547 overflow: hidden; 548 text-overflow: ellipsis; 549 white-space: nowrap; 550 } 551 552 .dropdown-item:hover{ 553 background-color: #f3f3f3; 554 } 555 556 .search__input.is-focus{ 557 border-radius: 15px; 558 border-bottom-left-radius: 0; 559 border-bottom-right-radius: 0; 560 border: 1px solid rgba(var(--color-foreground), 1); 561 border-bottom: none; 562 box-shadow: none; 563 } 564 565 .clear-all { 566 text-align: right; 567 padding: 0 2rem 0.2rem; 568 line-height: 1; 569 font-size: 70%; 570 margin-bottom: -2px; 571 } 572 573 .clear-all:hover{ 574 background-color: #fff; 575 } 576 577 .referral-notification { 578 position: absolute; 579 top: 100%; 580 right: -12px; 581 background: white; 582 border: 1px solid #e0e0e0; 583 border-radius: 8px; 584 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); 585 width: 280px; 586 z-index: 1000; 587 padding: 16px; 588 margin-top: 8px; 589 font-size: 14px; 590 line-height: 1.4; 591 } 592 593 .referral-notification::before { 594 content: ''; 595 position: absolute; 596 top: -8px; 597 right: 20px; 598 width: 0; 599 height: 0; 600 border-left: 8px solid transparent; 601 border-right: 8px solid transparent; 602 border-bottom: 8px solid white; 603 } 604 605 .referral-notification::after { 606 content: ''; 607 position: absolute; 608 top: -9px; 609 right: 20px; 610 width: 0; 611 height: 0; 612 border-left: 8px solid transparent; 613 border-right: 8px solid transparent; 614 border-bottom: 8px solid #e0e0e0; 615 } 616 617 .referral-notification h4 { 618 margin: 0 0 8px 0; 619 color: #2196F3; 620 font-size: 16px; 621 font-weight: 600; 622 } 623 624 .referral-notification p { 625 margin: 0 0 12px 0; 626 color: #666; 627 } 628 629 .referral-notification .referral-code { 630 background: #f5f5f5; 631 padding: 8px; 632 border-radius: 4px; 633 font-family: monospace; 634 font-size: 13px; 635 text-align: center; 636 margin: 8px 0; 637 border: 1px solid #ddd; 638 } 639 640 .referral-notification .close-btn { 641 position: absolute; 642 top: 8px; 643 right: 8px; 644 background: none; 645 border: none; 646 font-size: 18px; 647 color: #999; 648 cursor: pointer; 649 padding: 0; 650 width: 20px; 651 height: 20px; 652 line-height: 1; 653 } 654 655 .referral-notification .close-btn:hover { 656 color: #333; 657 } 658 659 .referral-notification .action-btn { 660 background: #2196F3; 661 color: white; 662 border: none; 663 padding: 8px 16px; 664 border-radius: 4px; 665 cursor: pointer; 666 font-size: 12px; 667 margin-right: 8px; 668 margin-top: 8px; 669 } 670 671 .referral-notification .action-btn:hover { 672 background: #1976D2; 673 } 674 675 .referral-notification .dismiss-btn { 676 background: transparent; 677 color: #666; 678 border: 1px solid #ddd; 679 padding: 8px 16px; 680 border-radius: 4px; 681 cursor: pointer; 682 font-size: 12px; 683 margin-top: 8px; 684 } 685 686 .referral-notification .dismiss-btn:hover { 687 background: #f5f5f5; 688 } 689 .referral-modal__dialog { 690 transform: translate(-50%, 0); 691 transition: transform var(--duration-default) ease, visibility 0s; 692 z-index: 10000; 693 position: fixed; 694 top: 20vh; 695 left: 50%; 696 width: 100%; 697 max-width: 350px; 698 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); 699 border-radius: 12px; 700 background-color: #fff; 701 color: #000; 702 padding: 20px; 703 text-align: center; 704 } 705 .modal-overlay.referral-modal-overlay { 706 position: fixed; 707 top: 0; 708 left: 0; 709 width: 100%; 710 height: 100%; 711 background-color: rgba(0, 0, 0, 0.7); 712 z-index: 2001; 713 display: block; 714 opacity: 1; 715 transition: opacity var(--duration-default) ease, visibility 0s; 716 } 717</style> 718 719<header class="header-bar"> 720 <div class="header-wrapper wrapper"> 721 722 <!-- Mobile hamburger --> 723 <div class="large--hide"> 724 <button type="button" class="mobile-nav-trigger" id="MobileNavTrigger">
725 <span class="icon icon-hamburger" aria-hidden="true"></span> 726 </button> 727 </div> 728 729 <div class="logo-header" role="banner"> 730 731 732 <div class="h1 site-header__logo" itemscope itemtype="http://schema.org/Organization"> 733 734 735 736 737 738 <a href="/" class="logo-wrapper" itemprop="url"> 739 <img src="https://cdn.store-assets.com/s/227019/f/3850260.png?width=350&format=webp" alt="ä¸å鼿¨¡å½«å»å·¥è社" itemprop="logo"> 740 </a> 741 742 743 744 745 746 </div> 747 748 749 </div> 750 751 <div class="desktop-header-nav medium-down--hide"> 752 753 <div class="header-nav-bar"> 754 755<ul class="site-nav" id="AccessibleNav"> 756 757 758 759 <li > 760 <a href="/" class="site-nav__link">ææ°æ¶æ¯</a> 761 </li> 762 763 764 765 766 767 <li class="site-nav--has-dropdown" aria-haspopup="true"> 768 <a href="/pages/å·¥è社ä»ç´¹" class="site-nav__link"> 769 åµå§äººä»ç´¹ 770 <span class="icon-fallback-text"> 771 <span class="icon icon-arrow-down" aria-hidden="true"></span> 772 </span> 773 </a> 774 <ul class="site-nav__dropdown"> 775 776 777 778 <li > 779 <a href="/pages/ç«è墨æ¨" class="site-nav__link">ç«è墨æ¨</a> 780 </li> 781 782 783 784 785 <li > 786 <a href="/blogs/tsaifu-calligraphy" class="site-nav__link">æ±ç³è¡ç«æ¸æ³ä½å</a> 787 </li> 788 789 790 </ul> 791 </li> 792 793 794 795 796 797 <li class="site-nav--has-dropdown" aria-haspopup="true"> 798 <a href="/collections/all" class="site-nav__link"> 799 ç¢åä»ç´¹ 800 <span class="icon-fallback-text"> 801 <span class="icon icon-arrow-down" aria-hidden="true"></span> 802 </span> 803 </a> 804 <ul class="site-nav__dropdown"> 805 806 807 808 <li > 809 <a href="/collections/é¼å°" class="site-nav__link">èæ¸é¼å°</a> 810 </li> 811 812 813 814 815 <li > 816 <a href="/collections/ææé¼å°" class="site-nav__link">ææé¼å°</a> 817 </li> 818 819 820 821 822 <li > 823 <a href="/collections/æå·¥é屬å°ç« " class="site-nav__link">æå·¥é屬å°ç« </a> 824 </li> 825 826 827 828 829 <li > 830 <a href="/collections/branding-iron" class="site-nav__link">è¨è£½çå°ç³»åç¢å</a> 831 </li> 832 833 834 </ul> 835 </li> 836 837 838 839 840 <li > 841 <a href="/blogs/blog" class="site-nav__link">æåå享</a> 842 </li> 843 844 845 846 847 <li > 848 <a href="/pages/ï½å好實å»ï½" class="site-nav__link">ï½å好實å»ï½</a> 849 </li> 850 851 852 853 854 <li > 855 <a href="/pages/location" class="site-nav__link">å·¥å» ä½ç½®</a> 856 </li> 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871</ul> 872 873 </div> 874 875 <div class="header-subnav"> 876 877 878 879<label class="currency-picker__wrapper"> 880 <!-- <span class="currency-picker__label">Pick a currency</span> --> 881 <select class="currency-picker" name="currencies" style="display: inline; width: auto; vertical-align: inherit;"> 882 <option value="TWD" selected="selected">TWD</option> 883 884 885 886 887 <option value="HKD">HKD</option> 888 889 890 891 892 </select> 893</label> 894 895 896 897 898 899 900 901 <div class="header-icon-nav"> 902 903 904 905 906 907 908 909 910 <div class="header-bar__module"> 911 912 <a class="popup-with-form medium-down--hide" href="#test-form"> 913 <span class="icon icon-search" aria-hidden="true"></span> 914 </a> 915 <form action="/search" method="get" class="header-bar__search-form clearfix large--hide" role="search"> 916 917 <button type="submit" class="btn icon-fallback-text header-bar__search-submit">
918 <span class="icon icon-search" aria-hidden="true"></span> 919 <span class="fallback-text">æå°</span> 920 </button> 921 <input type="search" name="q" value="" aria-label="æå°" class="header-bar__search-input" placeholder="æå°" autocomplete="off"> 922 <div class="dropdown" id="searchDropdown"></div> 923 <input type="hidden" name="search_history" id="search_history"> 924 </form> 925 926 927 928<!-- form itself --> 929<div id="test-form" class="white-popup-block mfp-hide popup-search"> 930 <div class="popup-search-content"> 931 <form action="/search" method="get" class="input-group search-bar" role="search"> 932 933 <input type="search" name="q" value="" placeholder="æå°" class="input-group-field" aria-label="æå°" placeholder="æå°" autocomplete="off"> 934 <div class="dropdown" id="searchDropdown"></div> 935 <input type="hidden" name="search_history" id="search_history"> 936 <span class="input-group-btn"> 937 <button type="submit" class="btn icon-fallback-text"> 938 <span class="icon icon-search" aria-hidden="true"></span> 939 <span class="fallback-text">æå°</span> 940 </button> 941 </span> 942 </form> 943 </div> 944</div> 945
946<script src="https://store-themes.easystore.co/227019/themes/1592/assets/magnific-popup.min.js?t=1787072457" type="text/javascript" ></script>
vendor: 1 bytes, line 946
946
947<script> 948$(document).ready(function() { 949 $('.popup-with-form').magnificPopup({ 950 type: 'inline', 951 preloader: false, 952 focus: '#name', 953 mainClass: 'popup-search-bg-wrapper', 954 955 // When elemened is focused, some mobile browsers in some cases zoom in 956 // It looks not nice, so we disable it: 957 callbacks: { 958 beforeOpen: function() { 959 if($(window).width() < 700) { 960 this.st.focus = false; 961 } else { 962 this.st.focus = '#name'; 963 } 964 } 965 } 966 }); 967}); 968</script>
968 969 970
971<script> 972 var _search_history_listings = "" 973 if(_search_history_listings != "") localStorage.setItem('searchHistory', JSON.stringify(_search_history_listings)); 974 975 function clearAll() { 976 localStorage.removeItem('searchHistory'); 977 978 var customer = ""; 979 if(customer) { 980 // Your logic to clear all data or call an endpoint 981 fetch('/account/search_histories', { 982 method: 'DELETE', 983 headers: { 984 "Content-Type": "application/json", 985 "X-Requested-With": "XMLHttpRequest" 986 }, 987 body: JSON.stringify({ 988 _token: "7ZKuJSqc8S2mL6uu3u1Im8DzJfNgAS8dk72D4zRQ" 989 }), 990 }) 991 .then(response => response.json()) 992 } 993 } 994 // End - store view history in local storage 995 996 // search history dropdown 997 var searchInputs = document.querySelectorAll('input[type=search]'); 998 999 if(searchInputs.length > 0) { 1000 1001 searchInputs.forEach((searchInput)=>{ 1002 1003 searchInput.addEventListener('focus', function() { 1004 var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown'); 1005 searchDropdown.innerHTML = ''; // Clear existing items 1006 1007 // retrieve data from local storage 1008 var searchHistoryData = JSON.parse(localStorage.getItem('searchHistory')) || []; 1009 1010 // Convert JSON to string 1011 var search_history_json = JSON.stringify(searchHistoryData); 1012 1013 // Set the value of the hidden input 1014 searchInput.closest('form').querySelector("#search_history").value = search_history_json; 1015 1016 // create dropdown items 1017 var clearAllItem = document.createElement('div'); 1018 clearAllItem.className = 'dropdown-item clear-all'; 1019 clearAllItem.textContent = 'Clear'; 1020 clearAllItem.addEventListener('click', function() { 1021 clearAll(); 1022 searchDropdown.style.display = 'none'; 1023 searchInput.classList.remove('is-focus'); 1024 }); 1025 searchDropdown.appendChild(clearAllItem); 1026 1027 // create dropdown items 1028 searchHistoryData.forEach(function(item) { 1029 var dropdownItem = document.createElement('div'); 1030 dropdownItem.className = 'dropdown-item'; 1031 dropdownItem.textContent = item.term; 1032 dropdownItem.addEventListener('click', function() { 1033 searchInput.value = item.term; 1034 searchDropdown.style.display = 'none'; 1035 }); 1036 searchDropdown.appendChild(dropdownItem); 1037 }); 1038 1039 if(searchHistoryData.length > 0){ 1040 // display the dropdown 1041 searchInput.classList.add('is-focus'); 1042 document.body.classList.add('search-input-focus'); 1043 searchDropdown.style.display = 'block'; 1044 } 1045 }); 1046 1047 searchInput.addEventListener("focusout", (event) => { 1048 var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown'); 1049 searchInput.classList.remove('is-focus'); 1050 searchDropdown.classList.add('transparent'); 1051 setTimeout(()=>{ 1052 searchDropdown.style.display = 'none'; 1053 searchDropdown.classList.remove('transparent'); 1054 document.body.classList.remove('search-input-focus'); 1055 }, 400); 1056 }); 1057 }) 1058 } 1059 // End - search history dropdown 1060</script>
1060 1061 </div> 1062 1063 1064 1065 1066 <div class="header-bar__module dropdown-wrapper"> 1067 1068 <a href="/account/login"> 1069 1070 1071 1072 <svg class="svg-icon" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><title>icon-profile</title><path d="M50,51.8A24.4,24.4,0,1,0,25.6,27.4,24.43,24.43,0,0,0,50,51.8ZM50,10A17.4,17.4,0,1,1,32.6,27.4,17.43,17.43,0,0,1,50,10Z"/><path d="M62.66,57.66H37.34a30.54,30.54,0,0,0-30.5,30.5V93.5a3.5,3.5,0,0,0,3.5,3.5H89.66a3.5,3.5,0,0,0,3.5-3.5V88.16A30.54,30.54,0,0,0,62.66,57.66ZM86.16,90H13.84V88.16a23.53,23.53,0,0,1,23.5-23.5H62.66a23.53,23.53,0,0,1,23.5,23.5Z"/></svg> 1073 1074 1075</a> 1076 1077 1078 <!-- Referral Notification Popup for Desktop --> 1079 <div id="referralNotification" class="referral-notification" style="display: none;"> 1080 <button class="close-btn" onclick="dismissReferralNotification()">×</button> 1081 <div style="text-align: center; margin-bottom: 16px;"> 1082 <div style="width: 100px; height: 100px; margin: 0 auto;"> 1083 <img src="https://resources.easystore.co/storefront/icons/channels/vector_referral_program.svg"> 1084 </div> 1085 </div> 1086 <p id="referralSignupMessage" style="text-align: center; font-size: 14px; color: #666; margin: 0 0 20px 0;"> 1087 æ¨ç好å鿍 åé¥éï¼ç«å³è¨»åé åã 1088 </p> 1089 <div style="text-align: center;"> 1090 <button class="btn" onclick="goToSignupPage()" style="width: 100%; color: #fff;"> 1091 註å 1092 </button> 1093 </div> 1094 </div> 1095 </div> 1096 1097 1098 <div class="header-bar__module cart-page-link-wrapper"> 1099 <span class="header-bar__sep" aria-hidden="true"></span> 1100 <a href="/cart" class="cart-page-link"> 1101 <span class="icon icon-cart header-bar__cart-icon" aria-hidden="true"></span> 1102 <span class="cart-count header-bar__cart-count hidden-count">0</span> 1103 </a> 1104 </div> 1105 1106 1107 1108 1109 1110 1111 1112 </div> 1113 </div> 1114 1115 1116 1117 </div> 1118 1119 1120 1121 <!-- Mobile cart --> 1122 <div class="large--hide"> 1123 <a href="/cart" class="cart-page-link mobile-cart-page-link"> 1124 <span class="icon icon-cart header-bar__cart-icon" aria-hidden="true"></span> 1125 <span class="cart-count hidden-count">0</span> 1126 </a> 1127 </div> 1128 1129 </div> 1130 1131 1132 1133</header> 1134 1135 1136 1137 1138 1139 <main class="wrapper main-content" role="main"> 1140 <div class="grid"> 1141 <div class="grid__item"> 1142 1143 1144 <!-- paginate blog.articles by 5 %} --> 1145 1146<div class="grid"> 1147 1148 <div class="grid__item large--four-fifths"> 1149 1150 <div class="grid"> 1151 <div class="grid__item large--ten-twelfths"> 1152 1153 1154 <header class="section-header"> 1155 <h1 class="section-header__title h3"> 1156 1157 æ±ç³è¡ç«_æ¸æ³ä½å 1158 1159 </h1> 1160 </header> 1161 1162 1163 1164 1165 1166 1167 <div class="article"> 1168 1169 <h2><a href="/blogs/tsaifu-calligraphy/è¡ç«æ¸æ³">è¡ç«æ¸æ³</a></h2> 1170 <p class="blog-date"> 1171 <time datetime="2024-09-24">Sep 24, 24</time> 1172 1173 <span class="meta-sep">•</span> 1174 è¡ç« 1175 1176 </p> 1177 1178 1179 <div><a href="/blogs/tsaifu-calligraphy/è¡ç«æ¸æ³"><img src="https://cdn.store-assets.com/s/227019/f/14013488.jpg?width=1200&format=webp" alt="è¡ç«æ¸æ³" class="article__image" /></a></div> 1180 1181 <p>02 </p> 1182 1183 1184 <div class="rte"> 1185 1186 <p></p> 1187 1188 </div> 1189 1190 <p><a href="/blogs/tsaifu-calligraphy/è¡ç«æ¸æ³">é±è®æ´å¤ →</a></p> 1191 1192 </div> 1193 1194 1195<!-- --> 1196 1197 1198 1199 <hr> 1200 1201 1202 1203 <div class="article"> 1204 1205 <h2><a href="/blogs/tsaifu-calligraphy/æ±ç³è¡ç«-ç¥æ¸ æ°£ç½-èæ¸ä½å">æ±ç³è¡ç«-ç¥æ¸ æ°£ç½ èæ¸ä½å</a></h2> 1206 <p class="blog-date"> 1207 <time datetime="2024-09-23">Sep 23, 24</time> 1208
1209 <span class="meta-sep">•</span> 1210 MOMO 1211 1212 </p> 1213 1214 1215 <div><a href="/blogs/tsaifu-calligraphy/æ±ç³è¡ç«-ç¥æ¸ æ°£ç½-èæ¸ä½å"><img src="https://cdn.store-assets.com/s/227019/f/14006481.jpg?width=1200&format=webp" alt="æ±ç³è¡ç«-ç¥æ¸ æ°£ç½ èæ¸ä½å" class="article__image" /></a></div> 1216 1217 <p>ç¥æ¸ æ°£ç½ 2024.9.23</p> 1218 1219 1220 <div class="rte"> 1221 1222 <p></p> 1223 1224 </div> 1225 1226 <p><a href="/blogs/tsaifu-calligraphy/æ±ç³è¡ç«-ç¥æ¸ æ°£ç½-èæ¸ä½å">é±è®æ´å¤ →</a></p> 1227 1228 </div> 1229 1230 1231<!-- <hr> --> 1232 1233 1234 1235 1236 </div> 1237 </div> 1238 </div> 1239 1240 <aside class="sidebar grid__item large--one-fifth"> 1241 <h4>ææ°æç« </h4> 1242 1243 <p> 1244 <a href="/blogs/tsaifu-calligraphy/è¡ç«æ¸æ³">è¡ç«æ¸æ³</a> 1245 <br> 1246 <time pubdate datetime="2024-09-24"> 1247 <em class="text-light">Sep 24, 24</em> 1248 </time> 1249 </p> 1250 1251 <p> 1252 <a href="/blogs/tsaifu-calligraphy/æ±ç³è¡ç«-ç¥æ¸ æ°£ç½-èæ¸ä½å">æ±ç³è¡ç«-ç¥æ¸ æ°£ç½ èæ¸ä½å</a> 1253 <br> 1254 <time pubdate datetime="2024-09-23"> 1255 <em class="text-light">Sep 23, 24</em> 1256 </time> 1257 </p> 1258 1259 1260 1261 1262 </aside> 1263 1264</div> 1265 1266 <!-- endpaginate %} --> 1267 1268 1269 1270 </div> 1271 </div> 1272 1273 </main> 1274 1275 <footer class="site-footer small--text-center" role="contentinfo"> 1276 1277 <div class="wrapper"> 1278 1279 <div class="grid-uniform"> 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 <div class="grid__item large--one-half medium--one-half"> 1302 1303 <h4>å¿«éé£çµ</h4> 1304 1305 <ul class="site-footer__links"> 1306 1307 <li><a href="https://www.facebook.com/sunyours/" target="_blank" >ä¸å Facebook ç²çµ²é </a></li> 1308 1309 <li><a href="/a/contact-form" >填坫坿¬¾è³æ</a></li> 1310 1311 <li><a href="/pages/terms-of-service" >é±ç§æ¿ç</a></li> 1312 1313 <li><a href="/pages/return-policy" >éè²¨éæ¬¾é ç¥ Return policy</a></li> 1314 1315 1316 </ul> 1317 </div> 1318 1319 1320 1321 <div class="grid__item large--one-half medium--one-half"> 1322 <h4>éæ³¨æå</h4> 1323 1324 <ul class="inline-list social-icons"> 1325 1326 1327 <li> 1328 <a class="icon-fallback-text" href="https://www.facebook.com/sunyours/" title="ä¸å鼿¨¡å½«å»å·¥è社å¨Facebookä¸" target="_blank"> 1329 1330 1331 1332 1333 <svg xmlns="http://www.w3.org/2000/svg" class="facebook-icon-svg social-icon-svg" viewBox="0 0 1024 1024"> 1334 <title>icon-facebook</title> 1335 <path d="M837.66,223.9a33.73,33.73,0,0,0-3.11-15c-6.78-13.85-17.87-21.09-33.37-21.09q-288.46,0-576.91,0c-.62,0-1.24,0-1.85,0a34.51,34.51,0,0,0-25.88,12.11c-6.31,7.13-8.85,15.57-8.85,25.07q.08,287.7,0,575.4c0,1,0,1.9,0,2.86A32.93,32.93,0,0,0,190,814.71c4.45,11.79,16.3,23.11,35,23.1q153.61-.1,307.24,0c2.36,0,2.36,0,2.36-2.37q0-123.3,0-246.6c0-2.55,0-2.55-2.53-2.55H452.27c-2.26,0-2.26,0-2.26-2.17v-96.3h84.63v-2.46c0-22.12-.11-44.24.06-66.36.07-8.29.57-16.59,1.28-24.85a129.58,129.58,0,0,1,7.43-33c10.86-30,30.59-51.74,60-64.51A133.44,133.44,0,0,1,653,285.82c12.45-.37,24.93,0,37.38.34,9.64.27,19.27.95,28.9,1.6,5.36.36,10.7,1.07,16.06,1.5,1.46.12,1.65.75,1.65,2q0,42.2,0,84.39c0,.59-.06,1.18-.09,1.85h-2.39c-16.28,0-32.56,0-48.84.05-7.63,0-15.23.54-22.65,2.61-11.61,3.23-19.86,10.09-23.65,21.78a55.66,55.66,0,0,0-2.74,16.86c-.14,22.23-.1,44.47-.13,66.7,0,2.25,0,2.25,2.31,2.25h94.66a15.13,15.13,0,0,1,0,1.54c-.38,2.94-.81,5.88-1.18,8.82-1.17,9.16-2.3,18.33-3.48,27.5-1.29,10-2.63,20-3.94,30-1.23,9.44-2.43,18.88-3.67,28.32-.31,2.32-.35,2.32-2.78,2.32h-79a4.62,4.62,0,0,0-1.67,0,2.5,2.5,0,0,0-1.2,1.16,3.68,3.68,0,0,0,0,1.49V835.21c0,2.56,0,2.56,2.53,2.56H797.83c2.13,0,4.27-.07,6.39-.21,11.56-.78,20.61-6.07,27.23-15.48,4.66-6.6,6.24-14.09,6.24-22.11q-.06-287.19,0-574.38Z" fill="#999"/> 1336 </svg> 1337 1338 1339
1340 <span class="fallback-text">Facebook</span> 1341 </a> 1342 </li> 1343 1344 1345 <li> 1346 <a class="icon-fallback-text" href="/" title="ä¸å鼿¨¡å½«å»å·¥è社å¨Pinterestä¸" target="_blank"> 1347 1348 1349 1350 1351 <svg xmlns="http://www.w3.org/2000/svg" class="pinterest-icon-svg social-icon-svg" viewBox="0 0 1024 1024"> 1352 <title>icon-pinterest</title> 1353 <path d="M787.12,295.62a346.51,346.51,0,0,0-113.57-94.17A342,342,0,0,0,564.26,166c-11.07-1.63-22.29-2.24-33.44-3.34-1.28-.13-2.54-.42-3.82-.63H497c-4.12.4-8.24.88-12.36,1.19a341.51,341.51,0,0,0-84.22,17.08A351,351,0,0,0,179.12,403.9a338.83,338.83,0,0,0-15.93,80.74c-.31,4.12-.79,8.24-1.19,12.36v30c.4,4.23.88,8.44,1.2,12.67a343.46,343.46,0,0,0,30.9,118.86A351.6,351.6,0,0,0,367.73,831c1.09.49,2.21.92,3.47,1.45,0-3.85.08-7.39,0-10.93-.81-29.78,3.57-58.84,10.64-87.73,13.78-56.39,26.84-113,40.16-169.46a7.16,7.16,0,0,0-.06-4.13,139.39,139.39,0,0,1-10.34-48.77c-.82-22.4,3.24-43.66,14.94-63,9.35-15.48,22-27.2,40.11-31.32S501,416,513.88,430.31c7.49,8.32,10.75,18.59,12,29.56,1.73,15.4-1.28,30.32-5.37,45-6.57,23.53-13.84,46.87-20.57,70.36-2.83,9.86-6.05,19.69-6.08,30.16-.07,26.81,18.3,48.76,44.77,53.23,24,4,44.94-3.17,63.34-18.43C618.64,626.31,630,608.5,638.86,589c10.39-22.91,16.49-47,19.79-71.92a298.29,298.29,0,0,0,2.8-47.58c-1-34.14-11.28-64.73-35.48-89.64-15.55-16-34.53-26.45-55.82-32.8-22.86-6.81-46.22-8.56-69.91-6.81-31.57,2.34-60.78,11.65-86.75,30-35.94,25.37-57.85,60-66.35,103a186.22,186.22,0,0,0-3.44,33.39c-.38,26.17,6.25,50.28,24,70.37,4.93,5.58,6.11,11.53,4,18.68-2.63,8.88-4.64,17.94-6.9,26.93-2.46,9.74-9.3,13.23-18.54,9.33-25.82-10.91-43.45-30.07-55.21-55.07-8.33-17.72-12.86-36.47-14.65-55.89-6.26-67.88,17.3-124.76,64.82-172.21,31.05-31,69-50.2,111.44-60.63a303.41,303.41,0,0,1,61.72-8.24c38.59-1.41,75.89,4.33,111.14,20.42,54.54,24.88,92.86,65,112.39,122.18,7.6,22.26,9.88,45.26,9.12,68.72-1,30.24-5.47,59.85-14.85,88.64-11,33.93-27.81,64.58-53.14,90C653,696.1,621.75,712.66,585,718.24c-20.28,3.08-40.44,3.26-60.21-3.2-18.27-6-34.52-15.13-46.79-30.36-1.83-2.27-3.38-4.77-5.32-7.54-2.33,9.24-4.55,18.1-6.82,26.94-5.75,22.5-11.32,45-17.34,67.47-7.05,26.23-19.43,50.08-33.58,73.07-.48.79-1,1.56-1.44,2.36a7.1,7.1,0,0,0-.27,1c7,1.77,13.93,3.67,20.95,5.29a336.64,336.64,0,0,0,57.13,8.15,17.33,17.33,0,0,1,2.63.55h36.75c3.61-.39,7.21-.85,10.82-1.17q120.79-10.68,209.65-93.21c52.05-48.53,85.94-107.86,102.13-177.21a330.52,330.52,0,0,0,8.17-57.73,17.08,17.08,0,0,1,.55-2.61V493.93c-.39-3.6-.84-7.21-1.15-10.82Q852,378.35,787.12,295.62Z" fill="#999"/><path d="M37.33,757.51l1.14.06a4.6,4.6,0,0,0-.65-.74Z" fill="#999"/> 1354 </svg> 1355 1356 1357 1358 <span class="fallback-text">Pinterest</span> 1359 </a> 1360 </li> 1361 1362 1363 1364 <li> 1365 <a class="icon-fallback-text" href="https://instagram.com/staysunyours/?hl=zh-tw" title="ä¸å鼿¨¡å½«å»å·¥è社å¨Instagramä¸" target="_blank"> 1366 1367 1368 1369 1370 <svg xmlns="http://www.w3.org/2000/svg" class="instagram-icon-svg social-icon-svg" viewBox="0 0 1024 1024"> 1371 <title>icon-instagram</title> 1372 <path d="M834.35,341.22a231.23,231.23,0,0,0-9.59-46.45,166.71,166.71,0,0,0-52.17-78.33c-17-14.41-36.33-24.44-57.44-31.3-21.52-7-43.69-10.21-66.19-11.12-22.28-.9-44.58-1.73-66.87-1.85-47.68-.26-95.37-.16-143.06,0-27.47.11-54.95.69-82.32,3.39a220.7,220.7,0,0,0-37.43,6.95c-26.2,7.26-50,19-70.24,37.45-18.06,16.4-32.3,35.52-41.87,58.05-9.89,23.29-15.13,47.68-16.69,72.82-1.23,19.78-2.06,39.6-2.32,59.41-.38,28.91-.1,57.82-.1,86.73-.23,39.92-.67,79.85,1,119.76.72,17.66,1.57,35.3,4.6,52.76,3.22,18.52,8.32,36.51,16.71,53.34C232.83,768,268.81,797,317.12,811a246.28,246.28,0,0,0,59.24,9.11c25.3.95,50.63,1.78,75.95,1.94,43.83.28,87.66.1,131.5,0,26-.08,52.08-.72,78.06-2.74a234.52,234.52,0,0,0,45.76-8c24.54-6.92,46.82-18.12,66.22-34.79,24.65-21.17,41.5-47.44,51.3-78.36,6.7-21.14,9.83-42.88,10.73-64.94.9-21.84,1.73-43.69,1.82-65.55q.33-78.21-.15-156.44C837.42,387.82,836.72,364.47,834.35,341.22Zm-55.3,232.84c-.12,20.41-1,40.84-2,61.24-1,19.2-4.13,38.08-11.74,55.92q-18.43,43.24-62.47,60c-14.36,5.48-29.3,8.3-44.55,9.53-27.07,2.18-54.21,2.63-81.36,2.73-21.31.07-42.62,0-63.93,0v-.16c-28.47,0-56.94.22-85.4-.09-17.5-.18-35-1-52.49-1.89-19.94-1-39.51-4.31-57.95-12.38q-41.6-18.2-58-60.68a162.37,162.37,0,0,1-9.95-45.62c-2-24.66-2.62-49.38-2.66-74.1-.09-50.88-.16-101.77.12-152.65.11-19,1-38.09,2-57.11a180,180,0,0,1,8.78-48.23c8.32-24.84,23.63-44.14,45.66-58.12,11.78-7.48,24.85-11.91,38.36-15,15.57-3.61,31.43-4.65,47.34-5.32,54.32-2.28,108.68-1.46,163-1.5,18.67,0,37.34.12,56,.56,15.84.38,31.7,1,47.51,2,18.33,1.18,36.27,4.59,53.19,12q41.67,18.25,58.1,60.83c5.67,14.7,8.64,30,9.91,45.63,2,25,2.63,50,2.67,75.09C779.25,475.82,779.35,524.94,779.05,574.06Z" fill="#999"/><path d="M513,330.12c-92-.34-167,74.55-167.08,166.87s74.71,167,167,167A166.86,166.86,0,0,0,679.77,497.12C679.87,405,605.46,330.45,513,330.12Zm-.29,275.31A108.38,108.38,0,1,1,621.21,497.15,108.38,108.38,0,0,1,512.7,605.43Z" fill="#999"/><path d="M686.47,284.5a39,39,0,1,0,38.92,39.14A39,39,0,0,0,686.47,284.5Z" fill="#999"/> 1373 </svg> 1374 1375 1376
1377 <span class="fallback-text">Instagram</span> 1378 </a> 1379 </li> 1380 1381 1382 1383 1384 1385 1386 1387 <li> 1388 <a class="icon-fallback-text" href="http://line.me/ti/p/%40tvi4455h" title="ä¸å鼿¨¡å½«å»å·¥è社å¨Lineä¸" target="_blank"> 1389 1390 1391 1392 1393 <svg xmlns="http://www.w3.org/2000/svg" class="line-icon-svg social-icon-svg" viewBox="0 0 1024 1024"> 1394 <title>icon-line</title> 1395 <path d="M837.58,237.47c-15.8-26.86-38.14-46.42-66.73-58.78A128.73,128.73,0,0,0,734,168.78c-4.2-.47-8.42-.74-12.62-1.15a26.81,26.81,0,0,1-2.93-.63H306.1a21,21,0,0,1-3.19.65A141,141,0,0,0,193.7,227.18a136.92,136.92,0,0,0-24.4,60.54c-.5,3.45-.7,6.94-1.18,10.39a21.46,21.46,0,0,1-1.12,3.58V719.55a23.91,23.91,0,0,1,1.1,4.45,132.12,132.12,0,0,0,14.49,54.45c20.58,39.69,52.66,64.84,96.28,75.07a118.63,118.63,0,0,0,21.81,2.91,24.16,24.16,0,0,1,3.22.57H720.66a27.33,27.33,0,0,1,3.21-.57c39.53-2.53,72.32-18.87,98.47-48.43a136.51,136.51,0,0,0,32-65.32c1-4.85,1.26-9.82,1.91-14.73a24.25,24.25,0,0,1,.72-2.88V301.69a15.08,15.08,0,0,1-.69-2.9C855.25,276.76,848.7,256.38,837.58,237.47ZM753.76,544.74a189.6,189.6,0,0,1-23.32,42.11,208.16,208.16,0,0,1-32.15,34.76c-12.76,11.12-25.31,22.48-38.38,33.23-35.07,28.83-71.7,55.51-110.67,78.87-11.12,6.67-22.46,13-34.55,17.76a84.7,84.7,0,0,1-12.35,3.8c-7.29,1.65-11.22-1.26-11.62-8.72a53.45,53.45,0,0,1,.91-10.68c1-6.62,2.39-13.19,3.34-19.83a39.31,39.31,0,0,0-.35-14.26,19.77,19.77,0,0,0-11.3-14.11c-4.23-2-8.76-2.63-13.32-3.21a290.39,290.39,0,0,1-46-9.72c-31.07-9.18-59.84-23-85.77-42.53-26.73-20.1-48.32-44.61-63-74.85a170.66,170.66,0,0,1-17.05-78.18,163.09,163.09,0,0,1,10.07-52c9.7-26.44,25-49.27,44.73-69.19,21.9-22.09,47.44-38.86,75.76-51.51a289.28,289.28,0,0,1,59.46-19.08,260.46,260.46,0,0,1,31.59-4.72c5.31-.44,10.62-.92,15.94-1.22s10.65-.38,16-.56a339.27,339.27,0,0,1,36.88,2.27,290.8,290.8,0,0,1,77.23,19.51c31.72,12.85,60.21,30.74,84.43,55.11,18.57,18.67,33.22,40,43,64.52a172,172,0,0,1,12.08,63.78A164.42,164.42,0,0,1,753.76,544.74Z" fill="#999"/><path d="M569.52,425.37c-6,1.41-9.73,6.4-9.81,12.73-.08,5.62,0,11.23,0,16.84q0,18.63,0,37.26c0,.91.35,2-.72,2.89-.65-.81-1.25-1.5-1.79-2.22L537.86,467c-9.12-12.25-18.3-24.45-27.31-36.77-5.3-7.26-17.63-7.11-22.37.83a14.49,14.49,0,0,0-1.94,7.63q0,47.9,0,95.77c0,.55,0,1.11,0,1.66A13,13,0,0,0,492,546.28a13.78,13.78,0,0,0,8.7,2,12.25,12.25,0,0,0,10.14-5.75A13.27,13.27,0,0,0,513,535q0-26.91,0-53.82v-4a6,6,0,0,1,3,2.76q23,31.39,45.93,62.82c3.87,5.34,9.24,6.5,14.87,5.26a12.45,12.45,0,0,0,9.68-12.22c-.12-8.73,0-17.47,0-26.21,0-23.83-.07-47.66,0-71.49C586.46,430.63,580.05,422.88,569.52,425.37Z" fill="#999"/><path d="M634.92,451.78q15.18,0,30.35,0c1.28,0,2.57,0,3.86-.11a11.71,11.71,0,0,0,7.64-3.38c4.29-4.21,5-9.34,3.15-14.75s-6.18-8-11.81-8.46c-.91-.08-1.83,0-2.75,0h-45.8c-.83,0-1.66,0-2.48,0-6.18.33-11,4-12.41,9.55a23.69,23.69,0,0,0-.41,5.47q0,46.62,0,93.24c0,1.2,0,2.4.07,3.59a12.1,12.1,0,0,0,6.14,9.88,14.75,14.75,0,0,0,7.94,1.92q24,.06,48,0a22,22,0,0,0,5.69-.84c4.58-1.28,9.06-6.21,8.69-13.24-.3-5.93-4-10.89-9.7-12.24a20.57,20.57,0,0,0-4.65-.36c-10.48,0-21,0-31.45,0-1.25,0-2.49-.19-3.65-.28-.6-3.33-.48-19.09.17-21.34,1-.05,2.08-.15,3.16-.15,10.94,0,21.89-.12,32.83,0,7.09.1,15.12-5.73,13-16.47a12.57,12.57,0,0,0-12.66-10.21c-11-.05-22.07,0-33.1,0h-3.35c-.63-3.48-.52-19.31.12-21.54C632.58,451.93,633.75,451.78,634.92,451.78Z" fill="#999"/><path d="M414.9,521.65c-10.76,0-21.52,0-32.29,0h-3.84v-4.26c0-26.3,0-52.61,0-78.92a13.36,13.36,0,0,0-26.72-.65q.1,48.72,0,97.42a13,13,0,0,0,13,13.11c16.83-.14,33.67,0,50.5-.06a13.53,13.53,0,0,0,3.54-.38c10.55-2.9,11.23-14.46,7.49-20.26C423.89,523.39,419.8,521.66,414.9,521.65Z" fill="#999"/><path d="M466.59,436.12a18.43,18.43,0,0,0-2.09-5.59c-2.75-4.22-6.9-5.79-11.87-5.59a12.74,12.74,0,0,0-11.93,9.37,20.25,20.25,0,0,0-.41,4.93q0,23.6,0,47.19t0,47.47a19.84,19.84,0,0,0,.54,5.45c1.7,6,6.6,9.1,13.56,8.94a12.4,12.4,0,0,0,12.32-11.73c.07-1.1.06-2.21.06-3.31q0-46.5,0-93A17.09,17.09,0,0,0,466.59,436.12Z" fill="#999"/> 1396 </svg> 1397 1398 1399 1400 <span class="fallback-text">Line</span> 1401 </a> 1402 </li> 1403 1404 1405 1406</ul> 1407 1408 </div> 1409 1410 </div> 1411 1412 <hr class="hr--small hr--clear"> 1413 1414 1415 1416 <div class="grid"> 1417 <div class="grid__item text-center"> 1418 <p class="site-footer__links">
1418ç«å §ææåçççºä¸åèä½è²¡ç¢ï¼å¦æªç¶å 許æ·è²è¤è£½ï¼æåå°è¡ä½¿æ³å¾éå¾ 2026 ä¸å鼿¨¡</p> 1419 1420 <p class="site-footer__links"> 1421 1422 1423 1424 <a href="/legal/terms-of-service">é±ç§æ¿ç PRIVACY POLICY</a> 1425 1426 1427 1428 1429 | <a href="/legal/return-policy">éè²¨éæ¬¾é ç¥ Return policy</a> 1430 1431 1432 1433 </p> 1434 1435 </div> 1436 </div> 1437 1438 </div> 1439 </footer> 1440 1441 1442 1443
1443<script src="https://store-themes.easystore.co/227019/themes/1592/assets/fastclick.min.js?t=1787072457" type="text/javascript" ></script>
1443 1444
1444<script src="https://store-themes.easystore.co/227019/themes/1592/assets/timber.js?t=1787072457" type="text/javascript" ></script>
1444 1445
1445<script src="https://store-themes.easystore.co/227019/themes/1592/assets/theme.js?t=1787072457" type="text/javascript" ></script>
1445 1446 1447 1448 1449 1450 1451 1452
1453<script src="/assets/currencies.js" type="text/javascript" ></script>
vendor: 2 bytes, line 1453
1453
1454<script src="/assets/jquery.currencies.min.js" type="text/javascript" ></script>
vendor: 2 bytes, line 1454
1454
1455<script src="/assets/currencies_format.js" type="text/javascript" ></script>
1455 1456
1457<script> 1458Currency.format = "money_with_currency_format"; 1459var shopCurrency = 'TWD'; 1460var selectedCurrency = ''; 1461 1462 1463 Currency.convert = function(amount, from, to) { 1464 return amount; 1465 }; 1466 1467 1468if( $.cookie("currency") == null ){ 1469 1470 if( selectedCurrency != false ) { 1471 1472 Currency.convertAll(shopCurrency, selectedCurrency); 1473 jQuery('.selected-currency').text(Currency.currentCurrency); 1474 1475 } 1476 1477} 1478 1479/* Sometimes merchants change their shop currency, let's tell our JavaScript file */ 1480// Currency.moneyFormats[shopCurrency].money_with_currency_format = ""; 1481// Currency.moneyFormats[shopCurrency].money_format = "NT$ {{amount}} "; 1482 1483/* Default currency */ 1484var defaultCurrency = 'TWD'; 1485 1486/* Cookie currency */ 1487var cookieCurrency = Currency.cookie.read(); 1488 1489$("input[name=current_currency]").val(cookieCurrency); 1490if(cookieCurrency == null){ 1491 cookieCurrency = shopCurrency; 1492 Currency.cookie.write(shopCurrency); 1493} 1494/* Fix for customer account pages */ 1495jQuery('span.money span.money').each(function() { 1496 jQuery(this).parents('span.money').removeClass('money'); 1497}); 1498/* Saving the current price */ 1499jQuery('span.money').each(function() { 1500 jQuery(this).attr('data-currency-TWD', jQuery(this).html()); 1501}); 1502// If there's no cookie. 1503if (cookieCurrency == null) { 1504 if (shopCurrency !== defaultCurrency) { 1505 Currency.convertAll(shopCurrency, defaultCurrency); 1506 } 1507 else { 1508 Currency.currentCurrency = defaultCurrency; 1509 } 1510} 1511// If the cookie value does not correspond to any value in the currency dropdown. 1512else if (jQuery('[name=currencies]').size() && jQuery('[name=currencies] option[value=' + cookieCurrency + ']').size() === 0) { 1513 Currency.currentCurrency = shopCurrency; 1514 Currency.cookie.write(shopCurrency); 1515} 1516else if (cookieCurrency === shopCurrency) { 1517 Currency.currentCurrency = shopCurrency; 1518 Currency.convertAll(shopCurrency, cookieCurrency); 1519} 1520else { 1521 Currency.convertAll(shopCurrency, cookieCurrency); 1522} 1523jQuery('[name=currencies]').val(Currency.currentCurrency).change(function() { 1524 var newCurrency = jQuery(this).val(); 1525 1526 1527 Currency.cookie.write(newCurrency) 1528 if ('blog' == 'cart') { 1529 const params = new URLSearchParams(window.location.search); 1530 params.set('delete_cache', 1); 1531 window.location.search = params; 1532 } else { 1533 window.location.reload(); 1534 } 1535 1536}); 1537var original_selectCallback = window.selectCallback; 1538var selectCallback = function(variant, selector) { 1539 var currencies = null; 1540 original_selectCallback(variant, selector); 1541 if(typeof jQuery('[name=currencies]').val() == "undefined"){ 1542 currencies = shopCurrency; 1543 } 1544 else{ 1545 currencies = jQuery('[name=currencies]').val(); 1546 } 1547 Currency.convertAll(shopCurrency, currencies); 1548 jQuery('.selected-currency').text(Currency.currentCurrency); 1549}; 1550$('body').on('ajaxCart.afterCartLoad', function(cart) { 1551 Currency.convertAll(shopCurrency, jQuery('[name=currencies]').val()); 1552 jQuery('.selected-currency').text(Currency.currentCurrency); 1553}); 1554jQuery('.selected-currency').text(Currency.currentCurrency); 1555</script>
1555 1556 1557 1558 1559<!-- Snippet:global/body_end: Omnichat --> 1560<!-- Start of Omnichat code -->
1560<script>var a=document.createElement('a');a.setAttribute('href','javascript:;');a.setAttribute('id','easychat-floating-button');var img=document.createElement('img');img.src='https://chat-plugin.easychat.co/icon.svg';a.appendChild(img);var span=document.createElement('span');span.setAttribute('id', 'easychat-unread-badge');span.setAttribute('style','display: none');var d1=document.createElement('div');d1.setAttribute('id','easychat-close-btn');d1.setAttribute('class','easychat-close-btn-close');var d2=document.createElement('div');d2.setAttribute('id','easychat-chat-dialog');d2.setAttribute('class','easychat-chat-dialog-close');var ifrm=document.createElement('iframe');ifrm.setAttribute('id','easychat-chat-dialog-iframe');ifrm.setAttribute('src','https://client-chat.easychat.co/?appkey=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0ZWFtTmFtZSI6IuS4iuWPi-mLvOaooSJ9.IO-XWOIyBCYK9ItlF6HDMryy_NaJlAUOZGwqy8b-QrM&lang=zh-Hant');ifrm.style.width='100%';ifrm.style.height='100%';ifrm.style.frameborder='0';ifrm.style.scrolling='on';d2.appendChild(ifrm);document.body.appendChild(a);document.body.appendChild(span);document.body.appendChild(d1);document.body.appendChild(d2);</script>
1560<script src='https://chat-plugin.easychat.co/easychat.js'></script>
1560 <!-- End of Omnichat code --> 1561<!-- /Snippet --> 1562 1563<!-- Snippet:global/body_end: Insert Code --> 1564 1565<!--Cal-->
1566<script> 1567(function() { 1568 // ========================================== 1569 // âï¸ å¹æ ¼èéå¶è¨å®å (æ¹ä¾¿æ¥å¾ä¿®æ¹) 1570 // ========================================== 1571 const PRICE_PER_Y = 330; // æ¯ Y çå®å¹ (å ) 1572 const MAX_Y_LIMIT = 14; // æå¤§ææ¸éå¶ (Y) 1573 const MIN_Y_LIMIT = 3; // æä½åºæ¬è²»ææ¸ (Y) 1574 // ========================================== 1575 1576 // è¨å®è¨æå¨ï¼çå¾ é é¢è¼å ¥ä¸¦å°æ¾è¨ç®æ©å ç´ 1577 let checkAttempts = 0; 1578 let checkExist = setInterval(function() { 1579 checkAttempts++; 1580 const calcBtn = document.getElementById("webCalcBtn"); 1581 const widthInput = document.getElementById("webMoldWidth"); 1582 const heightInput = document.getElementById("webMoldHeight"); 1583 1584 // 妿æ¾å°äºæéï¼ä»£è¡¨éé æ¯è¨ç®æ©é é¢ï¼éå§ç¶å®åè½ 1585 if (calcBtn && widthInput && heightInput) { 1586 clearInterval(checkExist); // 忢尿¾ 1587 1588 const moldBox = document.getElementById("webMoldBox"); 1589 const boxLabel = document.getElementById("webBoxLabel"); 1590 const resultPanel = document.getElementById("webResultPanel"); 1591 const resDetail = document.getElementById("webResDetail"); 1592 const resTitle = document.getElementById("webResTitle"); 1593 1594 function updatePreview() { 1595 const w = parseFloat(widthInput.value) || 0; 1596 const h = parseFloat(heightInput.value) || 0; 1597 boxLabel.textContent = w + " x " + h + " cm"; 1598 1599 const scale = 15; 1600 let displayW = w * scale; 1601 let displayH = h * scale; 1602 1603 if (displayH > 160) { displayH = 160; displayW = (w / h) * 160; } 1604 if (displayW > 300) { displayW = 300; displayH = (h / w) * 300; } 1605 1606 moldBox.style.width = displayW + "px"; 1607 moldBox.style.height = displayH + "px"; 1608 } 1609 1610 widthInput.addEventListener("input", updatePreview); 1611 heightInput.addEventListener("input", updatePreview); 1612 1613 calcBtn.addEventListener("click", function() { 1614 const w = parseFloat(widthInput.value) || 0; 1615 const h = parseFloat(heightInput.value) || 0; 1616 1617 if (w <= 0 || h <= 0) { 1618 resultPanel.style.display = "block"; 1619 resultPanel.className = "output-panel alert-mode"; 1620 resTitle.textContent = "æç¤º / Notice"; 1621 resDetail.textContent = "è«è¼¸å ¥å¤§æ¼ 0 çææå°ºå¯¸ã"; 1622 return; 1623 } 1624 1625 const sum = w + h; 1626 let roundedY = Math.round(sum); 1627 1628 // è¶ éæå¤§ææ¸éå¶ï¼æç¤ºè¯ç¹«å®¢æ 1629 if (roundedY > MAX_Y_LIMIT) { 1630 resultPanel.style.display = "block"; 1631 resultPanel.className = "output-panel alert-mode"; 1632 resTitle.textContent = "è¶ éç·ä¸ä¼°ç®ç¯å"; 1633 resDetail.innerHTML = "é·å¯¬ç¸½å (L+W)ï¼" + sum.toFixed(2) + " cm<br>è¨è²»å®ä½ (ææ¸)ï¼" + roundedY + " Y<br><span class='contact-notice'>
1633è«ç´æ¥èä¸åè¯ç¹«ï¼çºæ¨å ±å¹</span>"; 1634 return; 1635 } 1636 1637 // 使¼æä½èµ·ç®ææ¸ï¼å以æä½ææ¸è¨ç® 1638 if (roundedY < MIN_Y_LIMIT) { 1639 roundedY = MIN_Y_LIMIT; 1640 } 1641 1642 // è¨ç®è²»ç¨ 1643 const calculatedPrice = roundedY * PRICE_PER_Y; 1644 1645 resultPanel.style.display = "block"; 1646 resultPanel.className = "output-panel"; 1647 resTitle.textContent = "è¨ç®çµæ / Calculation Result"; 1648 resDetail.innerHTML = "é·å¯¬ç¸½å (L+W)ï¼" + sum.toFixed(2) + " cm<br>è¨è²»å®ä½ (ææ¸)ï¼" + roundedY + " Y<br><span class='price-display'>NT$ " + calculatedPrice.toLocaleString() + "</span>"; 1649 }); 1650 1651 // ååç¬¬ä¸æ¬¡é 覽 1652 updatePreview(); 1653 1654 } else if (checkAttempts > 20) { 1655 // 妿æ¾äº 20 次 (ç´ 6 ç§) 齿²æ¾å°ï¼ä»£è¡¨é䏿¯è¨ç®æ©é é¢ï¼ç´æ¥æ¾æçµæ 1656 clearInterval(checkExist); 1657 } 1658 }, 300); 1659})(); 1660</script>
1660 1661<!-- /Snippet -->
1662<script> 1663 1664 /* 1665 1666 ------ 1667 Events 1668 ------ 1669 1670 pages/viewed 1671 1672 customers/signup 1673 1674 customers/login 1675 1676 products/searched 1677 1678 collections/viewed 1679 1680 products/viewed 1681 1682 products/shared 1683 1684 wishlists/item_added 1685 1686 carts/items_added 1687 1688 carts/viewed 1689 1690 carts/item_removed 1691 1692 checkouts/initiated 1693 1694 checkouts/shipping_info_added 1695 1696 checkouts/payment_info_added 1697 1698 checkouts/completed 1699 1700 orders/placed 1701 1702 orders/purchased 1703 1704 payments/captured 1705 1706 payments/failed 1707 1708 */ 1709 1710 window.__latest_cart = window.__latest_cart || null; 1711 1712 const _selector = document.querySelector.bind(document), 1713 _selectorAll = document.querySelectorAll.bind(document) 1714 1715 document.addEventListener('DOMContentLoaded', (event) => { 1716 1717 const default_currency = getCookie("currency") 1718 const customer_id = window.__st.cid 1719 const template = window.__st.p 1720 1721 onPageView() 1722 1723 //-----------------------// 1724 // Configs // 1725 //-----------------------// 1726 1727 window.dataLayer = window.dataLayer || [] 1728 1729 Array.prototype.last = Array.prototype.last || function() { 1730 return this[this.length - 1] || null 1731 } 1732 1733 Array.prototype.first = Array.prototype.first || function() { 1734 return this[0] || null 1735 } 1736 1737 //----------------------// 1738 // Triggers // 1739 //----------------------// 1740 1741 const XHR = window.XMLHttpRequest 1742 1743 function xhr() { 1744 1745 const xhr = new XHR() 1746 1747 xhr.addEventListener("readystatechange", function() { 1748 1749 if(xhr.readyState != 4) return 1750 1751 try { 1752 1753 const response_url = xhr.responseURL 1754 1755 if (response_url.includes("cart/add")) { 1756 1757 window.__latest_cart = JSON.parse(xhr.response) 1758 1759 onCartItemsAdded() // ok 1760 1761 } 1762 1763 if (response_url.includes("cart/remove_item_quantity")) { 1764 1765 window.__latest_cart = JSON.parse(xhr.response) 1766 1767 onCartItemRemoved() // ok 1768 1769 } 1770 1771 if (response_url.includes("new_cart?retrieve=true")) { 1772 1773 result = JSON.parse(xhr.response) 1774 1775 if (result.cart) { 1776 window.__latest_cart = result.cart 1777 } 1778 1779 } 1780 1781 } catch(e) { 1782 1783 console.error(e) 1784 1785 } 1786 1787 }, false); 1788 1789 return xhr 1790 1791 } 1792 1793 window.XMLHttpRequest = xhr 1794 1795 switch(template) { 1796 1797 case 'cart': onCartView() // ok 1798 break 1799 case 'product': onProductView() // ok 1800 break 1801 case 'collection': onCollectionView() // ok 1802 break 1803 case 'blog': onBlogView() 1804 break 1805 case 'article': onArticleView() 1806 break 1807 case 'payment_completed': onOrderPlace() 1808 break 1809 case 'payment_fail': onPaymentFail() 1810 break 1811 1812 } 1813 1814 // _selector('form[action="/checkout/payments"]').addEventListener("submit", onPaymentInfoAdded(_selector('form[action="/checkout/payments"]'))) 1815 if (_selector('form[action="/checkout/detail"]')) _selector('form[action="/checkout/detail"]').addEventListener("submit", ()=>{onShippingInfoAdded(_selector('form[action="/checkout/detail"]'))}) // ok 1816 if (_selector('form[action="/checkout/shipping"]')) _selector('form[action="/checkout/shipping"]').addEventListener("submit", ()=>{onShippingInfoAdded(_selector('form[action="/checkout/shipping"]'))}) // ok 1817 if (_selector('form[action="/account/register"]')) _selector('form[action="/account/register"]').addEventListener("submit", onSignUp) // ok 1818 if (_selector('form[action="/account/login"]')) _selector('form[action="/account/login"]').addEventListener("submit", onLogin) // ok 1819 if (_selector('form[action="/search"]')) _selector('form[action="/search"]').addEventListener("submit", onProductSearch()) // ok 1820 if (_selector('#line-login-btn')) _selector('#line-login-btn').addEventListener('click', onLineLogin) // ok 1821 if (_selector('#PlaceOrder')) _selector('#PlaceOrder').addEventListener("click", ()=>{onCheckoutComplete(_selector('form[action="/checkout/payments"]'))}); // ok 1822 if (_selector('#add_wishlist')) _selector('#add_wishlist').addEventListener("click", onWishlistItemAdded) // ok 1823 if (_selectorAll('a[href="/account/logout"]')) _selectorAll('a[href="/account/logout"]').forEach(logoutButton => logoutButton.addEventListener("click", onLogout)) // ok 1824 if (_selector('.CartDrawerTrigger.cart-page-link')) _selector('.CartDrawerTrigger.cart-page-link').addEventListener("click", onCartView) // ok 1825 if (_selector('.CartDrawerTrigger.cart-page-link.mobile-cart-page-link')) _selector('.CartDrawerTrigger.cart-page-link.mobile-cart-page-link').addEventListener("click", onCartView) // ok 1826 if (_selectorAll('a[class^="share-"]')) _selectorAll('a[class^="share-"]').forEach(shareButton => shareButton.addEventListener("click", ()=>{onProductShare(shareButton)}) ) // ok 1827 if (_selectorAll('[name$="checkout"]')) _selectorAll('[name$="checkout"]').forEach(checkoutButton => checkoutButton.addEventListener("click", onCheckoutInitiate)) 1828 1829 // For append elements 1830 const bodyMutationObserver = new MutationObserver(() => { 1831 if (_selector('#form__spc #PlaceOrder')) _selector('#form__spc #PlaceOrder').addEventListener("click", onSinglePageCheckout) // ok 1832 if (_selectorAll('[name$="checkout"]')) _selectorAll('[name$="checkout"]').forEach(checkoutButton => checkoutButton.addEventListener("click", onCheckoutInitiate)) 1833 }); 1834 bodyMutationObserver.observe(_selector("body"), {subtree: true, childList: true}); 1835 1836 //------------------------------// 1837 // Event handlers // 1838 //------------------------------// 1839 1840 function onPageView() { 1841 1842 EasyStore.Event.dispatch('pages/viewed', { 1843 page: { 1844 type: template, 1845 title: document.title, 1846 description: _selector('meta[name=description]') ? _selector('meta[name=description]').getAttribute('content') : null, 1847 url: location.href, 1848 } 1849 }) 1850 1851 } 1852 1853 function onSignUp() { 1854 1855 const email_regex = new RegExp(/^[a-zA-Z0-9.!#$%&"*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/) 1856 const phone_regex = new RegExp(/^(\+?6?01)[0-46-9]-*[0-9]{7,8}$/) 1857 1858 const email_or_phone = _selector(`input[name="customer[email_or_phone]"]`).value.replace("+", "").replace(/\s+/, "") 1859 1860 let data = {} 1861 1862 if (email_regex.test(email_or_phone)) { 1863 data.method = 'email' 1864 data.email = email_or_phone 1865 } 1866 1867 if (phone_regex.test(email_or_phone)) { 1868 data.method = "phone" 1869 data.phone = email_or_phone 1870 } 1871 1872 if (!data.method) return 1873 1874 EasyStore.Event.dispatch('customers/signup', data) 1875 1876 } 1877 1878 function onLogin() { 1879 1880 const email_regex = new RegExp(/^[a-zA-Z0-9.!#$%&"*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/) 1881 const phone_regex = new RegExp(/^(\+?6?01)[0-46-9]-*[0-9]{7,8}$/) 1882 1883 const email_or_phone = _selector(`input[name="customer[email_or_phone]"]`).value.replace("+", "").replace(/\s+/, "") 1884 1885 let data = {} 1886 1887 if (email_regex.test(email_or_phone)) { 1888 data.method = 'email' 1889 data.email = email_or_phone 1890 } 1891 1892 if (phone_regex.test(email_or_phone)) { 1893 data.method = "phone" 1894 data.phone = email_or_phone 1895 } 1896 1897 if (!data.method) return 1898 1899 EasyStore.Event.dispatch('customers/login', data) 1900 1901 } 1902 1903 function onLineLogin() { 1904 1905 EasyStore.Event.dispatch('customers/login', { method: 'line' }) 1906 1907 } 1908 1909 function onLogout() { 1910 1911 EasyStore.Event.dispatch('customers/logout', { customer_id }) 1912 1913 } 1914 1915 function onBlogView() { 1916 1917 const blog = {"id":1049984,"handle":"tsaifu-calligraphy","url":"\/blogs\/tsaifu-calligraphy","title":"\u6771\u77f3\u8521\u752b_\u66f8\u6cd5\u4f5c\u54c1","description":"\u4e0a\u53cb\u92fc\u6a21\u5de5\u85dd\u793e\u5275\u59cb\u4eba:\u6771\u77f3\u8521\u752b_\u66f8\u6cd5\u4f5c\u54c1","articles_count":2,"all_tags":null,"comments_enabled":null,"moderated":null,"next_article":null,"previous_article":null,"tags":null,"updated_at":"2024-09-23T09:51:06.000+08:00","articles":[{"id":550280,"title":"\u8521\u752b\u66f8\u6cd5","handle":"\u8521\u752b\u66f8\u6cd5","url":"\/blogs\/tsaifu-calligraphy\/\u8521\u752b\u66f8\u6cd5","author":"\u8521\u752b","description":"02 ","image_url":"https:\/\/cdn.store-assets.com\/s\/227019\/f\/14013488.jpg","image":{"src":"https:\/\/cdn.store-assets.com\/s\/227019\/f\/14013488.jpg"}
1917,"published_at":"2024-09-24T10:00:51.000+08:00","updated_at":"2024-09-24T10:54:47.000+08:00"},{"id":550253,"title":"\u6771\u77f3\u8521\u752b-\u795e\u6e05\u6c23\u723d \u8349\u66f8\u4f5c\u54c1","handle":"\u6771\u77f3\u8521\u752b-\u795e\u6e05\u6c23\u723d-\u8349\u66f8\u4f5c\u54c1","url":"\/blogs\/tsaifu-calligraphy\/\u6771\u77f3\u8521\u752b-\u795e\u6e05\u6c23\u723d-\u8349\u66f8\u4f5c\u54c1","author":"MOMO","description":"\u795e\u6e05\u6c23\u723d 2024.9.23","image_url":"https:\/\/cdn.store-assets.com\/s\/227019\/f\/14006481.jpg","image":{"src":"https:\/\/cdn.store-assets.com\/s\/227019\/f\/14006481.jpg"},"published_at":"2024-09-23T09:54:24.000+08:00","updated_at":"2024-09-23T09:56:07.000+08:00"}]} 1918 1919 EasyStore.Event.dispatch('blogs/viewed', { blog }) 1920 1921 } 1922 1923 function onArticleView() { 1924 1925 const article = "" 1926 1927 EasyStore.Event.dispatch('articles/viewed', { article }) 1928 1929 } 1930 1931 function onProductSearch() { 1932 1933 const query = _selector('input[name=q]').value 1934 1935 if (!query) return 1936 1937 EasyStore.Event.dispatch('products/searched', { query }) 1938 1939 } 1940 1941 function onCollectionView() { 1942 1943 const collection = "" 1944 1945 EasyStore.Event.dispatch('collections/viewed', { collection }) 1946 1947 } 1948 1949 function onProductView() { 1950 1951 const product = "" 1952 1953 EasyStore.Event.dispatch("products/viewed", { product }) 1954 1955 } 1956 1957 function onProductShare(el) { 1958 1959 const product = "" 1960 1961 const channel = el.getAttribute("class").split("-").last() 1962 1963 EasyStore.Event.dispatch('products/shared', { product, channel }) 1964 1965 } 1966 1967 function onWishlistItemAdded() { 1968 1969 let product = "" 1970 const quantity = _selector("#Quantity").value 1971 1972 EasyStore.Event.dispatch('wishlists/item_added', { product }) 1973 1974 } 1975 1976 async function onCartItemsAdded() { 1977 1978 const cart = await getCart() 1979 1980 if(cart && cart.items != undefined && cart.items.length > 0) { 1981 1982 EasyStore.Event.dispatch('carts/item_added', { cart }) 1983 1984 } 1985 1986 } 1987 1988 async function onCartView() { 1989 1990 const cart = await getCart() 1991 1992 EasyStore.Event.dispatch('carts/viewed', { cart }) 1993 1994 } 1995 1996 async function onCartItemRemoved() { 1997 1998 const cart = await getCart() 1999 2000 cart.items = [] 2001 2002 if(cart) { 2003 2004 EasyStore.Event.dispatch('carts/item_removed', { cart }) 2005 2006 } 2007 2008 } 2009 2010 async function onCheckoutInitiate() { 2011 2012 const cart = await getCart() 2013 2014 EasyStore.Event.dispatch('checkouts/initiated', { cart }) 2015 2016 } 2017 2018 async function onShippingInfoAdded(form) { 2019 let checkout = getCheckout() 2020 2021 let form_data = {} 2022 new FormData(form).forEach((value, key) => form_data[key] = value) 2023 2024 let shipping_tier = null 2025 2026 if (form_data.type && form_data.type.startsWith("r_pickup")) { 2027 shipping_tier = `Pickup - ${form_data.pick_location}` 2028 } 2029 2030 if (form_data.s_id) { 2031 shipping_tier = _selector(`input[id='`+form_data.s_id+`']`).getAttribute("data-shipping-name") 2032 } 2033 2034 if (!shipping_tier) return 2035 2036 EasyStore.Event.dispatch('checkouts/shipping_info_added', { checkout, shipping_tier }) 2037 2038 } 2039 2040 async function onPaymentInfoAdded(form) { 2041 2042 let checkout = getCheckout() 2043 2044 let payment_type = new FormData(form).get('payment_method') 2045 2046 EasyStore.Event.dispatch("checkouts/payment_info_added", { checkout, payment_type }) 2047 2048 } 2049 2050 async function onOrderPlace() { 2051 2052 let cart_token = getCookie("cart_js") 2053 let previous_cart_token = getCookie("previous_cart_ga4_js") 2054 2055 if (previous_cart_token && previous_cart_token == cart_token) { 2056 // Prevent duplicate purchase tracking 2057 return 2058 } 2059 2060 let order = getOrder() 2061 2062 EasyStore.Event.dispatch('orders/placed', { order }) 2063 2064 if(order.is_manual_payment) { 2065 2066 EasyStore.Event.dispatch('orders/purchased', { order }) 2067 2068 } 2069 2070 const last_transaction = order.transactions.last() 2071 2072 if (last_transaction.status) { 2073 2074 EasyStore.Event.dispatch('orders/purchased', { order }) 2075 EasyStore.Event.dispatch('payments/captured', { order }) 2076 2077 } 2078 2079 } 2080 2081 async function onPaymentFail() { 2082 2083 const order = getOrder() 2084 2085 EasyStore.Event.dispatch('payments/failed', { order }) 2086 2087 } 2088 2089 async function onCheckoutComplete(form) { 2090 2091 onPaymentInfoAdded(form) 2092 2093 const checkout = getCheckout() 2094 2095 EasyStore.Event.dispatch('checkouts/completed', { checkout }) 2096 2097 } 2098 2099 async function onSinglePageCheckout() { 2100 2101 // let checkout = $("[data-app-checkout]").data("app-checkout") 2102 2103 let checkout = getCheckout() 2104 2105 // const payment_type = _selector("#app_spc_payment_method").find(`[class*="label-content"]`).first().find("b").first().text() 2106 const payment_type = _selector("#app_spc_payment_method").getElementsByClassName('label-content')[0].getElementsByTagName('b')[0].innerHTML 2107 2108 const shipping_method = _selector("#delivery_method").value 2109 2110 let shipping_tier = null 2111 let app_spc_customer_info_label = _selector("#app_spc_customer_info").getElementsByClassName('label-content') 2112 if (shipping_method == "shipping") { 2113 shipping_tier = app_spc_customer_info_label[app_spc_customer_info_label.length - 1].getElementsByTagName('b')[0].innerHTML 2114 } 2115 2116 if (shipping_method == "pickup") { 2117 shipping_tier = app_spc_customer_info_label[0].innerHTML 2118 } 2119 2120 if (shipping_tier) { 2121 2122 EasyStore.Event.dispatch('checkouts/shipping_info_added', { 2123 checkout, 2124 shipping_tier, 2125 }) 2126 2127 } 2128 2129 if (payment_type) { 2130 2131 EasyStore.Event.dispatch('checkouts/payment_info_added', { 2132 checkout, 2133 payment_type, 2134 }) 2135 2136 } 2137 2138 EasyStore.Event.dispatch('checkouts/completed', { checkout }) 2139 2140 } 2141 2142 }) 2143 2144 2145 //-----------------------// 2146 // Functions // 2147 //-----------------------// 2148 2149 function getCookie(name) { 2150 2151 name += "=" 2152 2153 decodedCookie = decodeURIComponent(document.cookie) 2154 2155 ca = decodedCookie.split(";") 2156 2157 for(i = 0; i < ca.length; i++) { 2158 c = ca[i] 2159 while (c.charAt(0) == " ") { 2160 c = c.substring(1) 2161 } 2162 if (c.indexOf(name) == 0) { 2163 return c.substring(name.length, c.length) 2164 } 2165 } 2166 2167 return "" 2168 2169 } 2170 2171 const parsePrice = price => { 2172 if(typeof price === 'string') { 2173 return parseFloat(price.split(',').join('')) 2174 } 2175 2176 return price 2177 } 2178 2179 const requestCart = async (method, data) => { 2180 2181 let response = await fetch('/cart.json', {method: 'GET',headers: {'Content-Type': 'application/json'}}) 2182 result = await response.json() 2183 2184 return result.cart 2185 2186 } 2187 const getCart = async (latest = false) => { 2188
2189 let cart = window.__latest_cart 2190 2191 const cart_invalid = !cart || !cart.items || (cart.total_price > 0 && !cart.items.length) 2192 2193 if(latest || cart_invalid) { 2194 cart = await requestCart() 2195 } 2196 2197 cart.items = cart.items || [] 2198 2199 return mapCart(cart) 2200 2201 } 2202 2203 const getCheckout = async () => { 2204 mapCheckout(window.__latest_cart || await requestCart()) 2205 } 2206 2207 const getOrder = async () => { 2208 mapOrder(window.__latest_cart || await requestCart()) 2209 } 2210 2211 //-----------------------// 2212 // Mappers // 2213 //-----------------------// 2214 2215 const fallbackAttribute = (object, attribute) => { 2216 2217 if(!Array.isArray(attribute)) { 2218 attribute = [attribute] 2219 } 2220 2221 let final_value = null 2222 2223 do { 2224 2225 final_value = object[attribute.shift()] 2226 2227 } while(!final_value && attribute.length) 2228 2229 return final_value 2230 2231 } 2232 2233 const map = (object, mapper) => { 2234 2235 const newObject = {} 2236 2237 for(const key in mapper) { 2238 2239 // Handle different keys between new and old format 2240 newObject[key] = fallbackAttribute(object, mapper[key]) 2241 2242 // Cast price to float 2243 if(newObject[key] && ['price', 'amount', 'discount', 'discounts'].some(x => key.endsWith(x))) { 2244 newObject[key] = parsePrice(newObject[key]) 2245 } 2246 2247 if(newObject[key] === undefined) { 2248 delete newObject[key] 2249 } 2250 2251 } 2252 2253 return newObject 2254 2255 } 2256 2257 const mapCart = cart => { 2258 2259 const oldCart = cart 2260 2261 const mapper = { 2262 id: 'id', 2263 currency: 'currency', 2264 item_count: 'item_count', 2265 items: 'items', 2266 total_price: 'total_price', 2267 latest_items: 'latest_items' 2268 } 2269 2270 cart = map(cart, mapper) 2271 2272 const discounts = (oldCart.storewide_discounts || []).concat((oldCart.voucher_discounts || [])) 2273 2274 cart.discount_applications = discounts.map(discount => ({ 2275 title: discount.voucher_code || null, 2276 value: parsePrice(discount.amount), 2277 })) 2278 2279 cart.original_total_price = cart.items.length 2280 ? cart.items 2281 .map(item => item.original_price) 2282 .reduce((sum, price) => sum + price) 2283 : 0 2284 2285 cart.total_discount = cart.discount_applications.length 2286 ? cart.discount_applications 2287 .map(discount => parsePrice(discount.value)) 2288 .reduce((sum, value) => sum + value) 2289 : 0 2290 2291 cart.items = cart.items.map(item => mapLineItem(item)) 2292 2293 return cart 2294 2295 } 2296 2297 const mapCheckout = checkout => { 2298 2299 const mapper = { 2300 note: 'note', 2301 attributes: 'note_attributes', 2302 billing_address: 'billing_address', 2303 currency: 'currency', 2304 customer_id: 'customer_id', 2305 discounts_amount: 'total_discount', 2306 id: 'id', 2307 line_items: 'order_item', 2308 order_number: 'order_number', 2309 shipping_address: 'shipping_address', 2310 shipping_price: 'shipping_tax', 2311 shipping_method: 'shipping_method_name', 2312 tax_price: 'total_tax', 2313 } 2314 2315 checkout = map(checkout, mapper) 2316 2317 checkout.requires_shipping = checkout.line_items.some(item => item.shipping_required) 2318 2319 checkout.line_items = checkout.line_items.map(item => mapLineItem(item)) 2320 2321 return checkout 2322 2323 } 2324 2325 const mapOrder = order => { 2326 2327 const mapper = { 2328 attributes: 'note_attributes', 2329 billing_address: 'billing_address', 2330 cancelled: 'is_cancelled', 2331 cancelled_at: 'cancelled_at', 2332 created_at: 'created_at', 2333 customer_id: 'customer_id', 2334 // discount_applications: 'discount_applications', 2335 email: 'email', 2336 financial_status: 'financial_status', 2337 fulfillment_status: 'fulfillment_status', 2338 line_items: 'order_item', 2339 note: 'note', 2340 order_number: 'order_number', 2341 phone: 'phone', 2342 shipping_address: 'shipping_address', 2343 shipping_methods: 'shipping_methods', 2344 shipping_price: 'total_shipping', 2345 subtotal_price: 'subtotal_price', 2346 // tax_lines: 'tax_lines', 2347 tax_price: 'total_tax', 2348 total_discounts: 'total_discount', 2349 total_net_amount: 'total_amount_include_transaction', 2350 total_price: 'total_price', 2351 transactions: 'transaction_records', 2352 is_manual_payment: 'is_manual_payment', 2353 } 2354 2355 order.email = order.billing_address.email 2356 order.phone = order.billing_address.phone 2357 order.shipping_method = order.shipping_method_name 2358 2359 order = map(order, mapper) 2360 2361 order.line_items = order.line_items.map(item => mapLineItem(item)) 2362 order.transactions = order.transactions.map(transaction => mapTransaction(transaction)) 2363 2364 return order 2365 2366 } 2367 2368 const mapLineItem = line_item => { 2369 2370 const old_line_item = line_item 2371 2372 const mapper = { 2373 final_price: 'price', 2374 image: 'img_url', 2375 message: 'message', 2376 original_line_price: 'original_line_price', 2377 original_price: 'original_price', 2378 properties: 'properties', 2379 quantity: 'quantity', 2380 requires_shipping: 'shipping_required', 2381 sku: 'sku', 2382 taxable: 'taxable', 2383 title: 'product_name', 2384 product_name: 'product_name', 2385 url: 'url', 2386 product_id: 'product_id', 2387 variant_id: 'variant_id', 2388 id: ['id', 'i_id'], 2389 } 2390 2391 line_item = map(line_item, mapper) 2392 2393 line_item.product_id = line_item.product_id || (old_line_item.product && old_line_item.product.id) || null 2394 line_item.variant_id = line_item.variant_id || (old_line_item.variant && old_line_item.variant.id) || null 2395 line_item.image = line_item.image || (old_line_item.image && old_line_item.image.url) || null 2396 2397 return line_item 2398 2399 } 2400 2401 const mapTransaction = transaction => { 2402 2403 const mapper = { 2404 amount: 'amount', 2405 created_at: 'created_at', 2406 gateway: 'gateway_type', 2407 id: 'id', 2408 status: 'status', 2409 } 2410 2411 transaction = map(transaction, mapper) 2412 2413 return transaction 2414 2415 } 2416 2417 2418</script>
2418 2419 2420</div> 2421</body> 2422</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.